1 ! Copyright (C) 2008 Jeff Bigot
\r
2 ! See http://factorcode.org/license.txt for BSD license.
\r
41 ui.gadgets.scrollers
\r
49 4DNav.space-file-decoder
\r
55 QUALIFIED-WITH: ui.pens.solid s
\r
56 QUALIFIED-WITH: ui.gadgets.wrappers w
\r
60 VALUE: selected-file
\r
61 VALUE: translation-step
\r
62 VALUE: rotation-step
\r
64 3 to: translation-step
\r
67 VAR: selected-file-model
\r
75 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\r
77 ! namespace utilities
\r
79 : make* ( seq -- seq ) [ dup quotation? [ call ] [ ] if ] map ;
\r
81 : closed-quot ( quot -- quot )
\r
82 namestack swap '[ namestack [ _ set-namestack @ ] dip set-namestack ] ;
\r
84 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\r
85 ! waiting for deep-cleave-quots
\r
87 : 4D-Rxy ( angle -- Rx ) deg>rad
\r
88 [ 1.0 , 0.0 , 0.0 , 0.0 ,
\r
89 0.0 , 1.0 , 0.0 , 0.0 ,
\r
90 0.0 , 0.0 , dup cos , dup sin neg ,
\r
91 0.0 , 0.0 , dup sin , dup cos , ] 4 make-matrix nip ;
\r
93 : 4D-Rxz ( angle -- Ry ) deg>rad
\r
94 [ 1.0 , 0.0 , 0.0 , 0.0 ,
\r
95 0.0 , dup cos , 0.0 , dup sin neg ,
\r
96 0.0 , 0.0 , 1.0 , 0.0 ,
\r
97 0.0 , dup sin , 0.0 , dup cos , ] 4 make-matrix nip ;
\r
99 : 4D-Rxw ( angle -- Rz ) deg>rad
\r
100 [ 1.0 , 0.0 , 0.0 , 0.0 ,
\r
101 0.0 , dup cos , dup sin neg , 0.0 ,
\r
102 0.0 , dup sin , dup cos , 0.0 ,
\r
103 0.0 , 0.0 , 0.0 , 1.0 , ] 4 make-matrix nip ;
\r
105 : 4D-Ryz ( angle -- Rx ) deg>rad
\r
106 [ dup cos , 0.0 , 0.0 , dup sin neg ,
\r
107 0.0 , 1.0 , 0.0 , 0.0 ,
\r
108 0.0 , 0.0 , 1.0 , 0.0 ,
\r
109 dup sin , 0.0 , 0.0 , dup cos , ] 4 make-matrix nip ;
\r
111 : 4D-Ryw ( angle -- Ry ) deg>rad
\r
112 [ dup cos , 0.0 , dup sin neg , 0.0 ,
\r
113 0.0 , 1.0 , 0.0 , 0.0 ,
\r
114 dup sin , 0.0 , dup cos , 0.0 ,
\r
115 0.0 , 0.0 , 0.0 , 1.0 , ] 4 make-matrix nip ;
\r
117 : 4D-Rzw ( angle -- Rz ) deg>rad
\r
118 [ dup cos , dup sin neg , 0.0 , 0.0 ,
\r
119 dup sin , dup cos , 0.0 , 0.0 ,
\r
120 0.0 , 0.0 , 1.0 , 0.0 ,
\r
121 0.0 , 0.0 , 0.0 , 1.0 , ] 4 make-matrix nip ;
\r
123 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\r
125 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\r
127 : button* ( string quot -- button )
\r
128 closed-quot <repeat-button> ;
\r
130 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\r
132 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\r
134 : model-projection-chooser ( -- gadget )
\r
135 observer3d> projection-mode>>
\r
136 { { 1 "perspective" } { 0 "orthogonal" } }
\r
139 : collision-detection-chooser ( -- gadget )
\r
140 observer3d> collision-mode>>
\r
141 { { t "on" } { f "off" } } <radio-buttons> ;
\r
143 : model-projection ( x -- space )
\r
144 present-space> swap space-project ;
\r
146 : update-observer-projections ( -- )
\r
150 view4> relayout-1 ;
\r
152 : update-model-projections ( -- )
\r
153 0 model-projection <model> view1> (>>model)
\r
154 1 model-projection <model> view2> (>>model)
\r
155 2 model-projection <model> view3> (>>model)
\r
156 3 model-projection <model> view4> (>>model) ;
\r
158 : camera-action ( quot -- quot )
\r
159 [ drop [ ] observer3d>
\r
160 with-self update-observer-projections ]
\r
161 make* closed-quot ;
\r
163 : win3D ( text gadget -- )
\r
164 "navigateur 4D : " rot append open-window ;
\r
166 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\r
167 ! 4D object manipulation
\r
168 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\r
170 : (mvt-4D) ( quot -- )
\r
172 swap call space-ensure-solids
\r
174 update-model-projections
\r
175 update-observer-projections ;
\r
177 : rotation-4D ( m -- )
\r
178 '[ _ [ [ middle-of-space dup vneg ] keep
\r
179 swap space-translate ] dip
\r
181 swap space-translate
\r
184 : translation-4D ( v -- ) '[ _ space-translate ] (mvt-4D) ;
\r
186 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\r
188 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\r
190 : menu-rotations-4D ( -- gadget )
\r
192 { 1 1 } >>filled-cell
\r
194 "XY +" [ drop rotation-step 4D-Rxy rotation-4D ]
\r
196 "XY -" [ drop rotation-step neg 4D-Rxy rotation-4D ]
\r
197 button* add-gadget
\r
198 @top-left grid-add
\r
200 "XZ +" [ drop rotation-step 4D-Rxz rotation-4D ]
\r
202 "XZ -" [ drop rotation-step neg 4D-Rxz rotation-4D ]
\r
203 button* add-gadget
\r
206 "YZ +" [ drop rotation-step 4D-Ryz rotation-4D ]
\r
208 "YZ -" [ drop rotation-step neg 4D-Ryz rotation-4D ]
\r
209 button* add-gadget
\r
212 "XW +" [ drop rotation-step 4D-Rxw rotation-4D ]
\r
214 "XW -" [ drop rotation-step neg 4D-Rxw rotation-4D ]
\r
215 button* add-gadget
\r
216 @top-right grid-add
\r
218 "YW +" [ drop rotation-step 4D-Ryw rotation-4D ]
\r
220 "YW -" [ drop rotation-step neg 4D-Ryw rotation-4D ]
\r
221 button* add-gadget
\r
224 "ZW +" [ drop rotation-step 4D-Rzw rotation-4D ]
\r
226 "ZW -" [ drop rotation-step neg 4D-Rzw rotation-4D ]
\r
227 button* add-gadget
\r
228 @bottom-right grid-add
\r
231 : menu-translations-4D ( -- gadget )
\r
233 { 1 1 } >>filled-cell
\r
236 "X+" [ drop { 1 0 0 0 } translation-step v*n
\r
239 "X-" [ drop { -1 0 0 0 } translation-step v*n
\r
241 button* add-gadget
\r
243 "YZW" <label> add-gadget
\r
244 @bottom-right grid-add
\r
246 "XZW" <label> add-gadget
\r
248 "Y+" [ drop { 0 1 0 0 } translation-step v*n
\r
251 "Y-" [ drop { 0 -1 0 0 } translation-step v*n
\r
253 button* add-gadget
\r
255 @top-right grid-add
\r
257 "XYW" <label> add-gadget
\r
259 "Z+" [ drop { 0 0 1 0 } translation-step v*n
\r
262 "Z-" [ drop { 0 0 -1 0 } translation-step v*n
\r
264 button* add-gadget
\r
266 @top-left grid-add
\r
269 "W+" [ drop { 0 0 0 1 } translation-step v*n
\r
272 "W-" [ drop { 0 0 0 -1 } translation-step v*n
\r
274 button* add-gadget
\r
276 "XYZ" <label> add-gadget
\r
277 @bottom-left grid-add
\r
278 "X" <label> @center grid-add
\r
281 : menu-4D ( -- gadget )
\r
283 "rotations" <label> add-gadget
\r
284 menu-rotations-4D add-gadget
\r
285 "translations" <label> add-gadget
\r
286 menu-translations-4D add-gadget
\r
292 ! ------------------------------------------------------
\r
294 : redraw-model ( space -- )
\r
296 update-model-projections
\r
297 update-observer-projections ;
\r
299 : load-model-file ( -- )
\r
300 selected-file dup selected-file-model> set-model
\r
304 : mvt-3D-X ( turn pitch -- quot )
\r
305 '[ turtle-pos> norm neg reset-turtle
\r
310 : mvt-3D-1 ( -- quot ) 90 0 mvt-3D-X ; inline
\r
311 : mvt-3D-2 ( -- quot ) 0 90 mvt-3D-X ; inline
\r
312 : mvt-3D-3 ( -- quot ) 0 0 mvt-3D-X ; inline
\r
313 : mvt-3D-4 ( -- quot ) 45 45 mvt-3D-X ; inline
\r
315 : camera-button ( string quot -- button )
\r
316 [ <label> ] dip camera-action <repeat-button> ;
\r
318 ! ----------------------------------------------------------
\r
320 ! ----------------------------------------------------------
\r
321 : <run-file-button> ( file-name -- button )
\r
322 dup '[ drop _ \ selected-file set-value load-model-file
\r
324 closed-quot <roll-button> { 0 0 } >>align ;
\r
326 : <list-runner> ( -- gadget )
\r
327 "resource:extra/4DNav"
\r
329 over dup directory-files
\r
330 [ ".xml" tail? ] filter
\r
331 [ append-path ] with map
\r
332 [ <run-file-button> add-gadget ] each
\r
333 swap <labeled-gadget> ;
\r
335 ! -----------------------------------------------------
\r
337 : menu-rotations-3D ( -- gadget )
\r
339 { 1 1 } >>filled-cell
\r
340 "Turn\n left" [ rotation-step turn-left ]
\r
341 camera-button @left grid-add
\r
342 "Turn\n right" [ rotation-step turn-right ]
\r
343 camera-button @right grid-add
\r
344 "Pitch down" [ rotation-step pitch-down ]
\r
345 camera-button @bottom grid-add
\r
346 "Pitch up" [ rotation-step pitch-up ]
\r
347 camera-button @top grid-add
\r
349 "Roll left\n (ctl)" [ rotation-step roll-left ]
\r
350 camera-button add-gadget
\r
351 "Roll right\n(ctl)" [ rotation-step roll-right ]
\r
352 camera-button add-gadget
\r
356 : menu-translations-3D ( -- gadget )
\r
358 { 1 1 } >>filled-cell
\r
359 "left\n(alt)" [ translation-step strafe-left ]
\r
360 camera-button @left grid-add
\r
361 "right\n(alt)" [ translation-step strafe-right ]
\r
362 camera-button @right grid-add
\r
363 "Strafe up \n (alt)" [ translation-step strafe-up ]
\r
364 camera-button @top grid-add
\r
365 "Strafe down\n (alt)" [ translation-step strafe-down ]
\r
366 camera-button @bottom grid-add
\r
368 "Forward (ctl)" [ translation-step step-turtle ]
\r
369 camera-button add-gadget
\r
371 [ translation-step neg step-turtle ]
\r
372 camera-button add-gadget
\r
376 : menu-quick-views ( -- gadget )
\r
378 "View 1 (1)" mvt-3D-1 camera-button add-gadget
\r
379 "View 2 (2)" mvt-3D-2 camera-button add-gadget
\r
380 "View 3 (3)" mvt-3D-3 camera-button add-gadget
\r
381 "View 4 (4)" mvt-3D-4 camera-button add-gadget
\r
384 : menu-3D ( -- gadget )
\r
387 menu-rotations-3D add-gadget
\r
388 menu-translations-3D add-gadget
\r
392 menu-quick-views add-gadget ;
\r
394 TUPLE: handler < w:wrapper table ;
\r
396 : <handler> ( child -- handler ) handler w:new-wrapper ;
\r
398 M: handler handle-gesture ( gesture gadget -- ? )
\r
399 tuck table>> at dup [ call( gadget -- ) f ] [ 2drop t ] if ;
\r
401 : add-keyboard-delegate ( obj -- obj )
\r
404 { T{ key-down f f "LEFT" }
\r
405 [ [ rotation-step turn-left ] camera-action ] }
\r
406 { T{ key-down f f "RIGHT" }
\r
407 [ [ rotation-step turn-right ] camera-action ] }
\r
408 { T{ key-down f f "UP" }
\r
409 [ [ rotation-step pitch-down ] camera-action ] }
\r
410 { T{ key-down f f "DOWN" }
\r
411 [ [ rotation-step pitch-up ] camera-action ] }
\r
413 { T{ key-down f { C+ } "UP" }
\r
414 [ [ translation-step step-turtle ] camera-action ] }
\r
415 { T{ key-down f { C+ } "DOWN" }
\r
416 [ [ translation-step neg step-turtle ]
\r
418 { T{ key-down f { C+ } "LEFT" }
\r
419 [ [ rotation-step roll-left ] camera-action ] }
\r
420 { T{ key-down f { C+ } "RIGHT" }
\r
421 [ [ rotation-step roll-right ] camera-action ] }
\r
423 { T{ key-down f { A+ } "LEFT" }
\r
424 [ [ translation-step strafe-left ] camera-action ] }
\r
425 { T{ key-down f { A+ } "RIGHT" }
\r
426 [ [ translation-step strafe-right ] camera-action ] }
\r
427 { T{ key-down f { A+ } "UP" }
\r
428 [ [ translation-step strafe-up ] camera-action ] }
\r
429 { T{ key-down f { A+ } "DOWN" }
\r
430 [ [ translation-step strafe-down ] camera-action ] }
\r
433 { T{ key-down f f "1" } [ mvt-3D-1 camera-action ] }
\r
434 { T{ key-down f f "2" } [ mvt-3D-2 camera-action ] }
\r
435 { T{ key-down f f "3" } [ mvt-3D-3 camera-action ] }
\r
436 { T{ key-down f f "4" } [ mvt-3D-4 camera-action ] }
\r
438 } [ make* ] map >hashtable >>table
\r
441 ! --------------------------------------------
\r
443 ! --------------------------------------------
\r
446 GENERIC: adsoda-display-model ( x -- )
\r
448 M: light adsoda-display-model
\r
451 [ direction>> "direction : " pprint . ]
\r
452 [ color>> "color : " pprint . ]
\r
456 M: face adsoda-display-model
\r
458 [ halfspace>> "halfspace : " pprint . ]
\r
459 [ touching-corners>> "touching corners : " pprint . ]
\r
462 M: solid adsoda-display-model
\r
464 [ name>> "solid called : " pprint . ]
\r
465 [ color>> "color : " pprint . ]
\r
466 [ dimension>> "dimension : " pprint . ]
\r
467 [ faces>> "composed of faces : " pprint
\r
468 [ adsoda-display-model ] each ]
\r
471 M: space adsoda-display-model
\r
473 [ dimension>> "dimension : " pprint . ]
\r
474 [ ambient-color>> "ambient-color : " pprint . ]
\r
475 [ solids>> "composed of solids : " pprint
\r
476 [ adsoda-display-model ] each ]
\r
477 [ lights>> "composed of lights : " pprint
\r
478 [ adsoda-display-model ] each ]
\r
482 ! ----------------------------------------------
\r
483 : menu-bar ( -- gadget )
\r
485 "reinit" [ drop load-model-file ] button* add-gadget
\r
486 selected-file-model> <label-control> add-gadget
\r
490 : controller-window* ( -- gadget )
\r
492 menu-bar f track-add
\r
497 "Projection mode : " <label> add-gadget
\r
498 model-projection-chooser add-gadget
\r
501 "Collision detection (slow and buggy ) : "
\r
503 collision-detection-chooser add-gadget
\r
507 menu-4D add-gadget
\r
508 COLOR: purple s:<solid> >>interior
\r
509 "4D movements" <labeled-gadget>
\r
515 COLOR: purple s:<solid> >>interior
\r
516 "Camera 3D" <labeled-gadget>
\r
518 COLOR: gray s:<solid> >>interior
\r
521 : viewer-windows* ( -- )
\r
522 "YZW" view1> win3D
\r
523 "XZW" view2> win3D
\r
524 "XYW" view3> win3D
\r
525 "XYZ" view4> win3D
\r
528 : navigator-window* ( -- )
\r
531 add-keyboard-delegate
\r
532 "navigateur 4D" open-window
\r
535 : windows ( -- ) [ [ navigator-window* ] with-scope ] with-ui ;
\r
538 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
\r
540 : init-variables ( -- )
\r
541 "choose a file" <model> >selected-file-model
\r
542 <observer> >observer3d
\r
543 [ observer3d> >self
\r
553 : init-models ( -- )
\r
554 0 model-projection observer3d> <window3D> >view1
\r
555 1 model-projection observer3d> <window3D> >view2
\r
556 2 model-projection observer3d> <window3D> >view3
\r
557 3 model-projection observer3d> <window3D> >view4
\r
562 selected-file read-model-file >present-space
\r