8 typedef struct traffic_node traffic_node
;
9 typedef struct traffic_driver traffic_driver
;
17 struct{ traffic_node
*next
, *next1
; };
18 struct{ mdl_node
*mn_next
, *mn_next1
; };
26 traffic_node
*current
;
31 static void eval_bezier_time( v3f p0
, v3f p1
, v3f h0
, v3f h1
, float t
, v3f p
)
36 v3_muls( p1
, ttt
, p
);
37 v3_muladds( p
, h1
, 3.0f
*tt
-3.0f
*ttt
, p
);
38 v3_muladds( p
, h0
, 3.0f
*ttt
-6.0f
*tt
+3.0f
*t
, p
);
39 v3_muladds( p
, p0
, 3.0f
*tt
-ttt
-3.0f
*t
+1.0f
, p
);
42 static float eval_bezier_length( v3f p0
, v3f p1
, v3f h0
, v3f h1
, int res
)
44 float length
= 0.0f
, m
= 1.0f
/(float)res
;
48 for( int i
=0; i
<res
; i
++ )
50 float t
= (float)(i
+1)*m
;
51 eval_bezier_time(p0
,p1
,h0
,h1
,t
,p
);
52 length
+= v3_dist( p
,l
);
59 static void traffic_finalize( traffic_node
*system
, int count
)
61 for( int i
=0; i
<count
; i
++ )
63 traffic_node
*tn
= &system
[i
];
66 tn
->next
= &system
[ tn
->mn_next
->sub_uid
];
68 tn
->next1
= &system
[ tn
->mn_next1
->sub_uid
];
72 static void traffic_visualize_link( traffic_node
*ta
, traffic_node
*tb
)
74 v3f p0
, p1
, h0
, h1
, p
, l
;
78 v3_copy( ta
->co
, p0
);
79 v3_muladds( ta
->co
, ta
->h
, 1.0f
, h0
);
80 v3_copy( tb
->co
, p1
);
81 v3_muladds( tb
->co
, tb
->h
, -1.0f
, h1
);
84 vg_line_pt3( h0
, 0.2f
, 0xff00ff00 );
85 vg_line_pt3( h1
, 0.2f
, 0xffff00ff );
86 vg_line( p0
, h0
, 0xff000000 );
87 vg_line( p1
, h1
, 0xff000000 );
89 for( int i
=0; i
<5; i
++ )
91 float t
= (float)(i
+1)/5.0f
;
92 eval_bezier_time( p0
, p1
, h0
, h1
, t
, p
);
94 vg_line( p
, l
, 0xffffffff );
99 static void sample_wheel_floor( v3f pos
)
102 v3_copy( pos
, ground
);
108 if( ray_world( ground
, (v3f
){0.0f
,-1.0f
,0.0f
}, &hit
))
110 v3_copy( hit
.pos
, pos
);
114 static void traffic_drive( traffic_driver
*driver
)
116 traffic_node
*next
, *current
= driver
->current
;
118 if( !current
) return;
119 next
= driver
->option
==0? current
->next
: current
->next1
;
121 if( driver
->t
> 1.0f
)
123 driver
->t
= driver
->t
- floorf( driver
->t
);
124 driver
->current
= driver
->option
==0? current
->next
: current
->next1
;
127 current
= driver
->current
;
131 if( current
->next
&& current
->next1
)
132 if( vg_randf() > 0.5f
)
136 traffic_visualize_link( current
, next
);
139 * Calculate the speed of the curve at the current point. On the reference
140 * curve the rate should come out to be exactly 1 ktimestep traveled.
141 * Dividing this distance by ktimestep gives us the modifier to use.
143 v3f p0
,p1
,h0
,h1
,pc
,pn
;
145 v3_copy( current
->co
, p0
);
146 v3_muladds( current
->co
, current
->h
, 1.0f
, h0
);
147 v3_copy( next
->co
, p1
);
148 v3_muladds( next
->co
, next
->h
, -1.0f
, h1
);
150 eval_bezier_time( p0
,p1
,h0
,h1
, driver
->t
, pc
);
151 eval_bezier_time( p0
,p1
,h0
,h1
, driver
->t
+ ktimestep
, pn
);
153 float mod
= ktimestep
/ v3_dist( pc
, pn
);
155 v3_sub( pn
, pc
, dir
);
159 * Stick the car on the ground by casting rays where the wheels are
167 v3_muladds( pc
, dir
, 2.0f
, fr
);
168 v3_muladds( pc
, dir
, 2.0f
, fl
);
169 v3_muladds( pc
, dir
, -2.0f
, bc
);
170 v3_muladds( fr
, side
, 1.0f
, fr
);
171 v3_muladds( fl
, side
, -1.0f
, fl
);
173 sample_wheel_floor( fl
);
174 sample_wheel_floor( fr
);
175 sample_wheel_floor( bc
);
177 vg_line( fl
, fr
, 0xff00ffff );
178 vg_line( fr
, bc
, 0xff00ffff );
179 vg_line( bc
, fl
, 0xff00ffff );
183 v3_sub( fr
, fl
, v0
);
184 v3_sub( bc
, fl
, v1
);
185 v3_cross( v1
, v0
, norm
);
186 v3_normalize( norm
);
189 * Jesus take the wheel
191 float steer_penalty
= 1.0f
-v3_dot( dir
, driver
->transform
[0] );
192 steer_penalty
/= ktimestep
;
193 steer_penalty
*= 30.0f
;
195 float target_speed
= vg_maxf( 16.0f
* (1.0f
-steer_penalty
), 0.1f
),
196 accel
= target_speed
- driver
->speed
;
197 driver
->speed
= stable_force( driver
->speed
, accel
*ktimestep
*2.0f
);
198 driver
->t
+= driver
->speed
*mod
*ktimestep
;
203 v3_cross( dir
, norm
, side
);
204 v3_copy( dir
, driver
->transform
[0] );
205 v3_copy( norm
, driver
->transform
[1] );
206 v3_copy( side
, driver
->transform
[2] );
208 v3_add( fl
, fr
, pc
);
209 v3_add( bc
, pc
, pc
);
210 v3_muls( pc
, 1.0f
/3.0f
, pc
);
211 v3_copy( pc
, driver
->transform
[3] );
214 static void traffic_visualize( traffic_node
*system
, int count
)
216 for( int i
=0; i
<count
; i
++ )
218 traffic_node
*tn
= &system
[i
];
220 traffic_visualize_link( tn
, tn
->next
);
221 traffic_visualize_link( tn
, tn
->next1
);
225 static void traffic_visualize_car( traffic_driver
*driver
)
227 vg_line_boxf_transformed( driver
->transform
,
228 (boxf
){{-1.0f
,0.0f
,-0.5f
},
229 { 1.0f
,0.0f
, 0.5f
}}, 0xff00ff00 );
232 #endif /* TRAFFIC_H */