1 ! See http://factorcode.org/license.txt for BSD license.
2 USING: accessors alien.enums arrays classes.struct combinators.short-circuit
3 continuations destructors formatting grouping io.backend io.pathnames kernel math
4 math.functions.private math.vectors namespaces raylib sequences threads
7 IN: raylib.demo.mesh-picking
9 CONSTANT: screen-width 800
10 CONSTANT: screen-height 800
12 screen-width screen-height "raylib [models] example - mesh-picking" init-window ;
14 : make-camera ( -- camera )
16 20 30 20 <Vector3> >>position
17 0 10 0 <Vector3> >>target
18 0 1.6 0 <Vector3> >>up
20 CAMERA_PERSPECTIVE >>projection ;
22 : resource ( fname -- path )
23 "raylib.demo.mesh-picking" "_resources" vocab-file-path swap append-path normalize-path ;
26 :: vector3-barycenter ( p a b c -- v3 )
35 d00 d11 * d01 d01 * - :> denom
37 d11 d20 * d01 d21 * - denom / :> y
38 d00 d21 * d01 d20 * - denom / :> z
40 x y z <Vector3> ; inline
42 : update-hit? ( nearest-hit-info hit-info -- nearest-hit-info ? )
43 2dup { [ nip hit>> ] [ swap [ distance>> ] bi@ < ] } 2&&
44 [ nip t ] [ drop f ] if ;
46 TUPLE: hit-state name color nearest-hit ;
47 : <hit-state> ( -- obj )
50 most-positive-finite-float >>distance
54 : reset-hit-state ( hit-state -- )
56 most-positive-finite-float >>distance
59 : handle-ground-hit ( hit-state ray -- hit-state )
61 ! FIXME: raylib 4.0 doesn't have GetCollisionRayGround
62 ! 0 get-collision-ray-ground
63 ! over nearest-hit>> swap update-hit?
64 ! [ >>nearest-hit ] dip
65 ! [ GREEN >>color "Ground" >>name ] when ;
67 : handle-triangle-hit ( hit-state ray ta tb tc -- hit-state ? )
68 get-ray-collision-triangle
69 over nearest-hit>> swap update-hit?
70 [ [ >>nearest-hit ] dip
71 [ PURPLE >>color "Triangle" >>name ] when ] keep ;
73 : handle-mesh-hit ( hit-state ray model bbox -- hit-state ? )
74 pick swap get-ray-collision-box
76 get-ray-collision-model
77 over nearest-hit>> swap update-hit?
79 [ ORANGE >>color "Mesh" >>name ] when
84 TUPLE: tower model bbox position ;
86 "turret.obj" resource load-model &unload-model
87 "turret_diffuse.png" resource load-texture &unload-texture
88 over materials>> first maps>> MATERIAL_MAP_DIFFUSE enum>number swap nth texture<<
89 dup meshes>> first get-mesh-bounding-box
90 0 0 0 <Vector3> tower boa ;
92 : init-assets ( -- tower triangle )
96 -8 6.5 0 <Vector3> 3array ;
98 : draw-objects ( bbox? tower triangle -- )
99 2 <circular-clumps> [ first2 PURPLE draw-line-3d ] each
100 [ [ model>> ] [ position>> ] bi 1.0 WHITE draw-model ] keep
101 swap [ bbox>> LIME draw-bounding-box ] [ drop ] if ;
103 : draw-cursor ( hit-state -- )
104 dup nearest-hit>> hit>> [
106 [ nearest-hit>> point>> ] [ color>> ] bi
107 '[ 0.3 0.3 0.3 _ draw-cube ]
108 [ 0.3 0.3 0.3 RED draw-cube-wires ] bi
112 [ point>> dup ] [ normal>> ] bi v+ RED draw-line-3d
118 : while-raylib-window ( quot -- )
119 [ window-should-close not ] swap while ; inline
121 : with-window ( quot -- )
122 [ make-window ] prepose [ with-destructors ] curry
123 [ close-window ] [ ] cleanup ; inline
125 SYMBOL: mesh-picking-frame
127 ! LOG_ALL set-trace-log-level
129 make-camera :> camera
131 init-assets :> ( tower triangle )
134 camera CAMERA_FREE set-camera-mode
137 0 mesh-picking-frame set-global
138 <hit-state> :> the-hit-state
141 ! NOTE: This doesn't work, probably because GL context is not handled correctly for switching?
142 ! mesh-picking-frame counter 100 mod 0 = [ yield ] when
146 get-mouse-position camera get-mouse-ray :> ray
148 the-hit-state dup reset-hit-state
149 ray handle-ground-hit
151 ray triangle first3 handle-triangle-hit
152 [ dup nearest-hit>> point>> triangle first3 vector3-barycenter bary! ] [ f bary! ] if
154 ray tower [ model>> ] [ bbox>> ] bi handle-mesh-hit hit-mesh-bbox!
158 RAYWHITE clear-background
160 hit-mesh-bbox tower triangle draw-objects
170 dup name>> "Hit Object: %s" sprintf 10 30 10 BLACK draw-text
171 nearest-hit>> dup hit>> [
173 [ distance>> "Distance: %3.2f" sprintf 10 ypos 10 BLACK draw-text ]
174 [ point>> first3 "Hit Pos: %3.2f %3.2f %3.2f" sprintf 10 ypos 15 + 10 BLACK draw-text ]
175 [ normal>> first3 "Hit Norm: %3.2f %3.2f %3.2f" sprintf 10 ypos 30 + 10 BLACK draw-text ]
178 "Barycenter: %3.2f %3.2f %3.2f" sprintf 10 ypos 45 + 10 BLACK draw-text
182 "Use Mouse to Move Camera" 10 screen-height 20 - 10 GRAY draw-text
183 "(c) Turret 3D model by Alberto Cano" screen-width 200 - screen-height 20 - 10 GRAY draw-text
187 ] while-raylib-window