1- import { mat4 , vec3 } from "./math/types" ;
2- import { perspective , identity , look_at , rotate , translate } from "./math/transformations" ;
3- import { create_3d_ngon , create_antiprism , create_sphere , create_torus } from "./rendering/utils/primitives" ;
4- import { build_mesh , render_scene } from "./rendering/render" ;
5- import { StringBuffer } from "./utils/string_buffer" ;
6- import { Mesh } from "./rendering/types/mesh" ;
7- import { Scene } from "./rendering/types/scene" ;
8- import { mul_mat4 } from "./math/matrix_operators" ;
9- import { build_scene } from "./to_html" ;
10- import { process_world_coordinates } from "./rendering/process_lighting" ;
11- import { Light } from "./rendering/types/light" ;
12- import { parse_obj } from "./utils/parser" ;
13- import type { Geometry } from "./rendering/types/geometry" ;
14-
15-
16- function generate_random_lights ( LIGHT_COUNT :number , scene :Scene ) {
17- const lights = [ ] ;
18- for ( let i = 0 ; i < LIGHT_COUNT ; i ++ ) {
19- const color = vec3 ( Math . random ( ) , Math . random ( ) , Math . random ( ) ) ;
20- const l = new Light ( vec3 ( 0 , 0 , 0 ) , color , 4.0 , 12.0 ) ;
21- scene . add_light ( l ) ;
22-
23- const mesh = create_sphere ( 0.15 , 8 , 8 ) ;
24- const mesh_idx = scene . meshes . length ;
25- scene . add_mesh ( mesh ) ;
26- lights . push ( {
27- light : l ,
28- mesh_idx : mesh_idx ,
29- orbit : {
30- speed : 0.4 + Math . random ( ) * 0.8 ,
31- radius : 2.5 + Math . random ( ) * 2.0 ,
32- phase : Math . random ( ) * Math . PI * 2 ,
33- y_offset : ( Math . random ( ) - 0.5 ) * 4
34- }
35- } ) ;
36- }
37- return lights ;
38- }
39-
40- let animation_id :number | null = null ;
41-
42- const frame_max = 1000 ;
43- let frame_count = 0 ;
44-
45- export function main_3d ( ) {
46- if ( animation_id !== null ) {
47- cancelAnimationFrame ( animation_id ) ;
48- }
49- const target = document . getElementById ( 'container' ) ;
50- if ( ! target ) return ;
51- const wireframe_el = document . getElementById ( 'wireframe-mode' ) as HTMLInputElement ;
52-
53- const RESOLUTION = 32 ;
54-
55- const sun_geo = create_antiprism ( RESOLUTION , 1 , 1 )
56- const planet_geo = create_sphere ( 0.5 , RESOLUTION / 2 , RESOLUTION / 2 ) ;
57- const bulb_geo = create_sphere ( 0.15 , 8 , 8 ) ;
58-
59- const scene : Scene = new Scene ( sun_geo . indices . length + planet_geo . indices . length + bulb_geo . indices . length * 32 ) ;
60- scene . add_mesh ( sun_geo , vec3 ( 0.4 , 0.3 , 0.6 ) , 0.7 ) ;
61- scene . add_mesh ( planet_geo , vec3 ( 0.7 , 0.6 , 0.8 ) ) ;
62-
63- const camera_pos :vec3 = vec3 ( 0 , 2 , 6.5 ) ;
64-
65- const y = vec3 ( 0 , 1 , 0 ) ;
66- const view : mat4 = look_at ( camera_pos , vec3 ( 0 , 0 , 0 ) , y ) ;
67- const projection = perspective ( 60 * Math . PI / 180 , 400 / 300 , 0.1 , 100 ) ;
68- const vp = mul_mat4 ( projection , view ) ;
69- let time = 0 ;
70- const string_buffer = new StringBuffer ( scene . scene_buffer . length * 50 ) ;
71-
72- const sun_light = new Light ( vec3 ( 10 , 10 , 10 ) , vec3 ( 1.0 , 0.95 , 0.9 ) , 3.0 , 200.0 ) ;
73-
74- const point_light = new Light (
75- vec3 ( 0 , 0 , 0 ) ,
76- vec3 ( 1.0 , 1.0 , 0.5 ) ,
77- 5.0 ,
78- 15.0
79- ) ;
80-
81- const lights = generate_random_lights ( 0 , scene ) ;
82-
83- scene . add_light ( sun_light ) ;
84- scene . add_light ( point_light ) ;
85- const do_wireframe : boolean = wireframe_el ?. checked ;
86-
87-
88- let start = performance . now ( ) ;
89-
90-
91- const loop = ( ) => {
92- time += 0.01 ;
93- frame_count ++ ;
94- if ( frame_count > frame_max ) {
95- const end = performance . now ( ) ;
96- console . log ( end - start ) ;
97- frame_count = 0 ;
98- }
99-
100- const lx = Math . cos ( time * 2 ) * 2.5 ;
101- const ly = Math . sin ( time * 2 ) * 2.5 ;
102- const lz = Math . sin ( time ) * 1.5 ;
103-
104- let rotate_matrix = rotate ( identity ( ) , time , y ) ;
105- rotate_matrix = rotate ( identity ( ) , time * 2 , vec3 ( 1 , 0 , 0 ) ) ;
106-
107- let sun_model = rotate ( identity ( ) , time * 0.5 , y ) ;
108-
109- let planet_model = rotate ( identity ( ) , time , y ) ;
110- planet_model = translate ( planet_model , vec3 ( 3.5 , 0 , 0 ) ) ;
111- planet_model = rotate ( planet_model , time * 3 , vec3 ( 1 , 0 , 1 ) ) ;
112-
113- let bulb_model = translate ( identity ( ) , vec3 ( lx , ly , lz ) ) ;
114-
115- const models = [ sun_model , planet_model , bulb_model ] ;
116-
117- point_light . position [ 0 ] = lx ;
118- point_light . position [ 1 ] = ly ;
119- point_light . position [ 2 ] = lz ;
120-
121- lights . forEach ( entity => {
122- const { light, orbit } = entity ;
123-
124- const x = Math . cos ( time * orbit . speed + orbit . phase ) * orbit . radius ;
125- const z = Math . sin ( time * orbit . speed + orbit . phase ) * orbit . radius ;
126- const y_pos = orbit . y_offset ;
127-
128- light . position [ 0 ] = x ;
129- light . position [ 1 ] = y_pos ;
130- light . position [ 2 ] = z ;
131- const bulb_model = mul_mat4 ( translate ( identity ( ) , vec3 ( x , y_pos , z ) ) , rotate_matrix ) ;
132- models . push ( bulb_model ) ;
133- } ) ;
134- const mvps = models . map ( m => mul_mat4 ( vp , m ) ) ;
135-
136- for ( let i = 0 ; i < scene . meshes . length ; ++ i ) {
137- scene . meshes [ i ] . update_normals ( models [ i ] ) ;
138- }
139-
140- process_world_coordinates ( scene , models , camera_pos ) ;
141- render_scene ( scene , mvps , true ) ;
142-
143- const frame_html = build_scene ( scene , do_wireframe , string_buffer ) ;
144- target ! . innerHTML = frame_html ;
145- animation_id = requestAnimationFrame ( loop ) ;
146- }
147- animation_id = requestAnimationFrame ( loop ) ;
148- }
149-
150- export function load_file ( ) {
151-
152- }
153-
154- document . getElementById ( 'render' ) ?. addEventListener ( 'click' , main_3d ) ;
155-
156- const file_content = document . getElementById ( 'file-picker' ) ;
157-
158- export async function handle_file ( event :Event ) {
159- const target = event . target as HTMLInputElement ;
160- if ( ! target . files ) return ;
161- const file = target . files [ 0 ] ;
162- const geometry = parse_obj ( await file . text ( ) ) ;
163- render_preview ( geometry ) ;
164- }
165-
166- let preview_animation_id :number | null = null ;
167- let zoom_distance = 1.0 ;
168-
169- function render_preview ( geo : Geometry ) {
170- if ( preview_animation_id !== null ) {
171- cancelAnimationFrame ( preview_animation_id ) ;
172- }
173- console . log ( geo . vertices ) ;
174- const target = document . getElementById ( 'model-preview-container' ) ;
175- if ( ! target ) return ;
176-
177- target . onwheel = ( e : WheelEvent ) => {
178- e . preventDefault ( ) ;
179- const zoomSpeed = 1.0 ;
180- zoom_distance += e . deltaY > 0 ? zoomSpeed : - zoomSpeed ;
181- zoom_distance = Math . max ( 1.0 , Math . min ( zoom_distance , 200.0 ) ) ;
182- } ;
183-
184- const scene = new Scene ( geo . indices . length ) ;
185- const mesh_ref = scene . add_mesh ( geo , vec3 ( 0.5 , 0.8 , 0.5 ) , 0.8 ) ;
186-
187- const preview_light = new Light ( vec3 ( 100 , 100 , 100 ) , vec3 ( 1 , 1 , 1 ) , 120.0 , 5000.0 ) ;
188- scene . add_light ( preview_light ) ;
189-
190- const string_buffer = new StringBuffer ( scene . scene_buffer . length * 60 ) ;
191- let rotation_time = 0 ;
192-
193- const preview_loop = ( ) => {
194- rotation_time += 0.02 ;
195-
196- const camera_pos = vec3 ( 0 , 0 , zoom_distance ) ;
197- const view = look_at ( camera_pos , vec3 ( 0 , 0 , 0 ) , vec3 ( 0 , 1 , 0 ) ) ;
198- const projection = perspective ( 45 * Math . PI / 180 , 1 , 0.1 , 100 ) ;
199- const vp = mul_mat4 ( projection , view ) ;
200-
201- const rotation_matrix = rotate ( identity ( ) , rotation_time , vec3 ( 0 , 1 , 0 ) ) ;
202-
203- let model_matrix = rotation_matrix ;
204-
205- mesh_ref . update_normals ( model_matrix ) ;
206- process_world_coordinates ( scene , [ model_matrix ] , camera_pos ) ;
207-
208- render_scene ( scene , [ mul_mat4 ( vp , model_matrix ) ] , true ) ;
209-
210- target . innerHTML = build_scene ( scene , false , string_buffer ) ;
211- preview_animation_id = requestAnimationFrame ( preview_loop ) ;
212- } ;
213-
214- preview_loop ( ) ;
215- }
216-
217- file_content ?. addEventListener ( 'change' , handle_file ) ;
1+ import { SceneManager } from "./ui/scene_manager" ;
2+
3+ const manager = new SceneManager (
4+ "container" ,
5+ "primitive-toolbar" ,
6+ "primitive-options" ,
7+ "inspector-panel" ,
8+ "wireframe-mode" ,
9+ "poly-count"
10+ ) ;
11+
12+ manager . start ( ) ;
0 commit comments