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 float eval_bezier_length( v3f p0
, v3f p1
, v3f h0
, v3f h1
, int res
)
33 float length
= 0.0f
, m
= 1.0f
/(float)res
;
37 for( int i
=0; i
<res
; i
++ )
39 float t
= (float)(i
+1)*m
;
40 eval_bezier_time(p0
,p1
,h0
,h1
,t
,p
);
41 length
+= v3_dist( p
,l
);
48 static void traffic_finalize( traffic_node
*system
, int count
)
50 for( int i
=0; i
<count
; i
++ )
52 traffic_node
*tn
= &system
[i
];
55 tn
->next
= &system
[ tn
->mn_next
->sub_uid
];
57 tn
->next1
= &system
[ tn
->mn_next1
->sub_uid
];
61 static void traffic_visualize_link( traffic_node
*ta
, traffic_node
*tb
)
63 v3f p0
, p1
, h0
, h1
, p
, l
;
67 v3_copy( ta
->co
, p0
);
68 v3_muladds( ta
->co
, ta
->h
, 1.0f
, h0
);
69 v3_copy( tb
->co
, p1
);
70 v3_muladds( tb
->co
, tb
->h
, -1.0f
, h1
);
73 vg_line_pt3( h0
, 0.2f
, 0xff00ff00 );
74 vg_line_pt3( h1
, 0.2f
, 0xffff00ff );
75 vg_line( p0
, h0
, 0xff000000 );
76 vg_line( p1
, h1
, 0xff000000 );
78 for( int i
=0; i
<5; i
++ )
80 float t
= (float)(i
+1)/5.0f
;
81 eval_bezier_time( p0
, p1
, h0
, h1
, t
, p
);
83 vg_line( p
, l
, 0xffffffff );
88 static void sample_wheel_floor( v3f pos
)
91 v3_copy( pos
, ground
);
97 if( ray_world( ground
, (v3f
){0.0f
,-1.0f
,0.0f
}, &hit
))
99 v3_copy( hit
.pos
, pos
);
103 static void traffic_drive( traffic_driver
*driver
)
105 traffic_node
*next
, *current
= driver
->current
;
107 if( !current
) return;
108 next
= driver
->option
==0? current
->next
: current
->next1
;
110 if( driver
->t
> 1.0f
)
112 driver
->t
= driver
->t
- floorf( driver
->t
);
113 driver
->current
= driver
->option
==0? current
->next
: current
->next1
;
116 current
= driver
->current
;
120 if( current
->next
&& current
->next1
)
121 if( vg_randf() > 0.5f
)
125 traffic_visualize_link( current
, next
);
128 * Calculate the speed of the curve at the current point. On the reference
129 * curve the rate should come out to be exactly 1 ktimestep traveled.
130 * Dividing this distance by ktimestep gives us the modifier to use.
132 v3f p0
,p1
,h0
,h1
,pc
,pn
;
134 v3_copy( current
->co
, p0
);
135 v3_muladds( current
->co
, current
->h
, 1.0f
, h0
);
136 v3_copy( next
->co
, p1
);
137 v3_muladds( next
->co
, next
->h
, -1.0f
, h1
);
139 eval_bezier_time( p0
,p1
,h0
,h1
, driver
->t
, pc
);
140 eval_bezier_time( p0
,p1
,h0
,h1
, driver
->t
+ ktimestep
, pn
);
142 float mod
= ktimestep
/ v3_dist( pc
, pn
);
144 v3_sub( pn
, pc
, dir
);
148 * Stick the car on the ground by casting rays where the wheels are
156 v3_muladds( pc
, dir
, 2.0f
, fr
);
157 v3_muladds( pc
, dir
, 2.0f
, fl
);
158 v3_muladds( pc
, dir
, -2.0f
, bc
);
159 v3_muladds( fr
, side
, 1.0f
, fr
);
160 v3_muladds( fl
, side
, -1.0f
, fl
);
162 sample_wheel_floor( fl
);
163 sample_wheel_floor( fr
);
164 sample_wheel_floor( bc
);
166 vg_line( fl
, fr
, 0xff00ffff );
167 vg_line( fr
, bc
, 0xff00ffff );
168 vg_line( bc
, fl
, 0xff00ffff );
172 v3_sub( fr
, fl
, v0
);
173 v3_sub( bc
, fl
, v1
);
174 v3_cross( v1
, v0
, norm
);
175 v3_normalize( norm
);
178 * Jesus take the wheel
180 float steer_penalty
= 1.0f
-v3_dot( dir
, driver
->transform
[0] );
181 steer_penalty
/= ktimestep
;
182 steer_penalty
*= 30.0f
;
184 float target_speed
= vg_maxf( 16.0f
* (1.0f
-steer_penalty
), 0.1f
),
185 accel
= target_speed
- driver
->speed
;
186 driver
->speed
= stable_force( driver
->speed
, accel
*ktimestep
*2.0f
);
187 driver
->t
+= driver
->speed
*mod
*ktimestep
;
192 v3_cross( dir
, norm
, side
);
193 v3_copy( dir
, driver
->transform
[0] );
194 v3_copy( norm
, driver
->transform
[1] );
195 v3_copy( side
, driver
->transform
[2] );
197 v3_add( fl
, fr
, pc
);
198 v3_add( bc
, pc
, pc
);
199 v3_muls( pc
, 1.0f
/3.0f
, pc
);
200 v3_copy( pc
, driver
->transform
[3] );
203 static void traffic_visualize( traffic_node
*system
, int count
)
205 for( int i
=0; i
<count
; i
++ )
207 traffic_node
*tn
= &system
[i
];
209 traffic_visualize_link( tn
, tn
->next
);
210 traffic_visualize_link( tn
, tn
->next1
);
214 static void traffic_visualize_car( traffic_driver
*driver
)
216 vg_line_boxf_transformed( driver
->transform
,
217 (boxf
){{-1.0f
,0.0f
,-0.5f
},
218 { 1.0f
,0.0f
, 0.5f
}}, 0xff00ff00 );
221 #endif /* TRAFFIC_H */