9 typedef struct traffic_node traffic_node
;
10 typedef struct traffic_driver traffic_driver
;
18 struct{ traffic_node
*next
, *next1
; };
19 struct{ mdl_node
*mn_next
, *mn_next1
; };
27 traffic_node
*current
;
32 static float eval_bezier_length( v3f p0
, v3f p1
, v3f h0
, v3f h1
, int res
)
34 float length
= 0.0f
, m
= 1.0f
/(float)res
;
38 for( int i
=0; i
<res
; i
++ )
40 float t
= (float)(i
+1)*m
;
41 eval_bezier_time(p0
,p1
,h0
,h1
,t
,p
);
42 length
+= v3_dist( p
,l
);
49 static void traffic_finalize( traffic_node
*system
, int count
)
51 for( int i
=0; i
<count
; i
++ )
53 traffic_node
*tn
= &system
[i
];
56 tn
->next
= &system
[ tn
->mn_next
->sub_uid
];
58 tn
->next1
= &system
[ tn
->mn_next1
->sub_uid
];
62 static void traffic_visualize_link( traffic_node
*ta
, traffic_node
*tb
)
64 v3f p0
, p1
, h0
, h1
, p
, l
;
68 v3_copy( ta
->co
, p0
);
69 v3_muladds( ta
->co
, ta
->h
, 1.0f
, h0
);
70 v3_copy( tb
->co
, p1
);
71 v3_muladds( tb
->co
, tb
->h
, -1.0f
, h1
);
74 vg_line_pt3( h0
, 0.2f
, 0xff00ff00 );
75 vg_line_pt3( h1
, 0.2f
, 0xffff00ff );
76 vg_line( p0
, h0
, 0xff000000 );
77 vg_line( p1
, h1
, 0xff000000 );
79 for( int i
=0; i
<5; i
++ )
81 float t
= (float)(i
+1)/5.0f
;
82 eval_bezier_time( p0
, p1
, h0
, h1
, t
, p
);
84 vg_line( p
, l
, 0xffffffff );
89 static void sample_wheel_floor( v3f pos
)
92 v3_copy( pos
, ground
);
98 if( ray_world( ground
, (v3f
){0.0f
,-1.0f
,0.0f
}, &hit
))
100 v3_copy( hit
.pos
, pos
);
104 static void traffic_drive( traffic_driver
*driver
)
106 traffic_node
*next
, *current
= driver
->current
;
108 if( !current
) return;
109 next
= driver
->option
==0? current
->next
: current
->next1
;
111 if( driver
->t
> 1.0f
)
113 driver
->t
= driver
->t
- floorf( driver
->t
);
114 driver
->current
= driver
->option
==0? current
->next
: current
->next1
;
117 current
= driver
->current
;
121 if( current
->next
&& current
->next1
)
122 if( vg_randf() > 0.5f
)
126 traffic_visualize_link( current
, next
);
129 * Calculate the speed of the curve at the current point. On the reference
130 * curve the rate should come out to be exactly 1 ktimestep traveled.
131 * Dividing this distance by ktimestep gives us the modifier to use.
133 v3f p0
,p1
,h0
,h1
,pc
,pn
;
135 v3_copy( current
->co
, p0
);
136 v3_muladds( current
->co
, current
->h
, 1.0f
, h0
);
137 v3_copy( next
->co
, p1
);
138 v3_muladds( next
->co
, next
->h
, -1.0f
, h1
);
140 eval_bezier_time( p0
,p1
,h0
,h1
, driver
->t
, pc
);
141 eval_bezier_time( p0
,p1
,h0
,h1
, driver
->t
+ vg
.time_delta
, pn
);
143 float mod
= vg
.time_delta
/ v3_dist( pc
, pn
);
145 v3_sub( pn
, pc
, dir
);
149 * Stick the car on the ground by casting rays where the wheels are
157 v3_muladds( pc
, dir
, 2.0f
, fr
);
158 v3_muladds( pc
, dir
, 2.0f
, fl
);
159 v3_muladds( pc
, dir
, -2.0f
, bc
);
160 v3_muladds( fr
, side
, 1.0f
, fr
);
161 v3_muladds( fl
, side
, -1.0f
, fl
);
163 sample_wheel_floor( fl
);
164 sample_wheel_floor( fr
);
165 sample_wheel_floor( bc
);
167 vg_line( fl
, fr
, 0xff00ffff );
168 vg_line( fr
, bc
, 0xff00ffff );
169 vg_line( bc
, fl
, 0xff00ffff );
173 v3_sub( fr
, fl
, v0
);
174 v3_sub( bc
, fl
, v1
);
175 v3_cross( v1
, v0
, norm
);
176 v3_normalize( norm
);
179 * Jesus take the wheel
181 float steer_penalty
= 1.0f
-v3_dot( dir
, driver
->transform
[0] );
182 steer_penalty
/= vg
.time_delta
;
183 steer_penalty
*= 30.0f
;
185 float target_speed
= vg_maxf( 16.0f
* (1.0f
-steer_penalty
), 0.1f
),
186 accel
= target_speed
- driver
->speed
;
187 driver
->speed
= stable_force( driver
->speed
, accel
*vg
.time_delta
*2.0f
);
188 driver
->t
+= driver
->speed
*mod
*vg
.time_delta
;
193 v3_cross( dir
, norm
, side
);
194 v3_copy( dir
, driver
->transform
[0] );
195 v3_copy( norm
, driver
->transform
[1] );
196 v3_copy( side
, driver
->transform
[2] );
198 v3_add( fl
, fr
, pc
);
199 v3_add( bc
, pc
, pc
);
200 v3_muls( pc
, 1.0f
/3.0f
, pc
);
201 v3_copy( pc
, driver
->transform
[3] );
204 static void traffic_visualize( traffic_node
*system
, int count
)
206 for( int i
=0; i
<count
; i
++ )
208 traffic_node
*tn
= &system
[i
];
210 traffic_visualize_link( tn
, tn
->next
);
211 traffic_visualize_link( tn
, tn
->next1
);
215 static void traffic_visualize_car( traffic_driver
*driver
)
217 vg_line_boxf_transformed( driver
->transform
,
218 (boxf
){{-1.0f
,0.0f
,-0.5f
},
219 { 1.0f
,0.0f
, 0.5f
}}, 0xff00ff00 );
222 #endif /* TRAFFIC_H */