Rev 18 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | pmbaty | 1 | #include "finteray.h" |
20 | pmbaty | 2 | #include "brender/brender.h" |
1 | pmbaty | 3 | #include "brucetrk.h" |
4 | #include "car.h" |
||
5 | #include "globvars.h" |
||
6 | #include "harness/trace.h" |
||
7 | #include "raycast.h" |
||
8 | #include "world.h" |
||
9 | #include <math.h> |
||
10 | #include <stdlib.h> |
||
11 | |||
12 | int gPling_materials = 1; |
||
13 | br_material* gSub_material; |
||
14 | br_material* gReal_material; |
||
15 | int gNfaces; |
||
16 | br_matrix34 gPick_model_to_view__finteray; // suffix added to avoid duplicate symbol |
||
17 | int gTemp_group; |
||
18 | br_model* gNearest_model; |
||
19 | br_model* gSelected_model; |
||
20 | int gNearest_face_group; |
||
21 | int gNearest_face; |
||
22 | br_scalar gNearest_T; |
||
23 | tFace_ref* gPling_face; |
||
24 | |||
25 | // IDA: int __cdecl BadDiv(br_scalar a, br_scalar b) |
||
26 | // Suffix added to avoid duplicate symbol |
||
27 | int BadDiv__finteray(br_scalar a, br_scalar b) { |
||
28 | // LOG_TRACE("(%f, %f)", a, b); |
||
29 | |||
30 | return fabsf(b) < 1.0f && fabsf(a) > fabsf(b) * BR_SCALAR_MAX; |
||
31 | } |
||
32 | |||
33 | // IDA: void __usercall DRVector2AccumulateScale(br_vector2 *a@<EAX>, br_vector2 *b@<EDX>, br_scalar s) |
||
34 | // Suffix added to avoid duplicate symbol |
||
35 | void DRVector2AccumulateScale__finteray(br_vector2* a, br_vector2* b, br_scalar s) { |
||
36 | LOG_TRACE("(%p, %p, %f)", a, b, s); |
||
37 | |||
38 | a->v[0] = b->v[0] * s + a->v[0]; |
||
39 | a->v[1] = b->v[1] * s + a->v[1]; |
||
40 | } |
||
41 | |||
42 | // IDA: int __usercall PickBoundsTestRay@<EAX>(br_bounds *b@<EAX>, br_vector3 *rp@<EDX>, br_vector3 *rd@<EBX>, br_scalar t_near, br_scalar t_far, br_scalar *new_t_near, br_scalar *new_t_far) |
||
43 | // Suffix added to avoid duplicate symbol |
||
44 | int PickBoundsTestRay__finteray(br_bounds* b, br_vector3* rp, br_vector3* rd, br_scalar t_near, br_scalar t_far, br_scalar* new_t_near, br_scalar* new_t_far) { |
||
45 | int i; |
||
46 | float s; |
||
47 | float t; |
||
48 | LOG_TRACE("(%p, %p, %p, %f, %f, %p, %p)", b, rp, rd, t_near, t_far, new_t_near, new_t_far); |
||
49 | |||
50 | for (i = 0; i < 3; i++) { |
||
51 | if (rd->v[i] >= -0.00000023841858) { |
||
52 | if (rd->v[i] <= 0.00000023841858) { |
||
53 | if (b->max.v[i] < rp->v[i] || rp->v[i] < b->min.v[i]) { |
||
54 | return 0; |
||
55 | } |
||
56 | } else { |
||
57 | s = (-1.0f / rd->v[i]) * (rp->v[i] - b->max.v[i]); |
||
58 | if (s >= BR_SCALAR_MIN) { |
||
59 | if (s < t_far) { |
||
60 | t_far = (-1.0f / rd->v[i]) * (rp->v[i] - b->max.v[i]); |
||
61 | } |
||
62 | } else { |
||
63 | t_far = BR_SCALAR_MIN; |
||
64 | } |
||
65 | t = (-1.0f / rd->v[i]) * (rp->v[i] - b->min.v[i]); |
||
66 | if (t <= BR_SCALAR_MAX) { |
||
67 | if (t > t_near) { |
||
68 | t_near = (-1.0f / rd->v[i]) * (rp->v[i] - b->min.v[i]); |
||
69 | } |
||
70 | } else { |
||
71 | t_near = BR_SCALAR_MAX; |
||
72 | } |
||
73 | } |
||
74 | } else { |
||
75 | s = (-1.0f / rd->v[i]) * (rp->v[i] - b->max.v[i]); |
||
76 | if (s <= BR_SCALAR_MAX) { |
||
77 | if (s > t_near) { |
||
78 | t_near = (-1.0f / rd->v[i]) * (rp->v[i] - b->max.v[i]); |
||
79 | } |
||
80 | } else { |
||
81 | t_near = BR_SCALAR_MAX; |
||
82 | } |
||
83 | t = (-1.0f / rd->v[i]) * (rp->v[i] - b->min.v[i]); |
||
84 | if (t >= BR_SCALAR_MIN) { |
||
85 | if (t < t_far) { |
||
86 | t_far = (-1.0f / rd->v[i]) * (rp->v[i] - b->min.v[i]); |
||
87 | } |
||
88 | } else { |
||
89 | t_far = BR_SCALAR_MIN; |
||
90 | } |
||
91 | } |
||
92 | } |
||
93 | if (t_far < t_near) { |
||
94 | return 0; |
||
95 | } |
||
96 | *new_t_near = t_near; |
||
97 | *new_t_far = t_far; |
||
98 | return 1; |
||
99 | } |
||
100 | |||
101 | // IDA: int __usercall ActorRayPick2D@<EAX>(br_actor *ap@<EAX>, br_vector3 *pPosition@<EDX>, br_vector3 *pDir@<EBX>, br_model *model@<ECX>, br_material *material, dr_pick2d_cbfn *callback) |
||
102 | int ActorRayPick2D(br_actor* ap, br_vector3* pPosition, br_vector3* pDir, br_model* model, br_material* material, dr_pick2d_cbfn* callback) { |
||
103 | br_actor* a; |
||
104 | br_model* this_model; |
||
105 | br_material* this_material; |
||
106 | br_scalar t_near; |
||
107 | br_scalar t_far; |
||
108 | int r; |
||
109 | br_matrix34 mat; |
||
110 | br_matrix34 invmat; |
||
111 | br_vector3 pos; |
||
112 | br_vector3 dir; |
||
113 | void* arg; |
||
114 | LOG_TRACE("(%p, %p, %p, %p, %p, %p)", ap, pPosition, pDir, model, material, callback); |
||
115 | |||
116 | t_near = 0.0; |
||
117 | t_far = 1.0; |
||
118 | r = 0; |
||
119 | arg = NULL; |
||
120 | if (ap->model != NULL) { |
||
121 | this_model = ap->model; |
||
122 | } else { |
||
123 | this_model = model; |
||
124 | } |
||
125 | if (ap->material != NULL) { |
||
126 | this_material = ap->material; |
||
127 | } else { |
||
128 | this_material = material; |
||
129 | } |
||
130 | if (ap->render_style == BR_RSTYLE_NONE) { |
||
131 | return 0; |
||
132 | } |
||
133 | if (ap->identifier != NULL && ap->identifier[0] == '&') { |
||
134 | BrTransformToMatrix34(&mat, &ap->t); |
||
135 | BrMatrix34Inverse(&invmat, &mat); |
||
136 | BrMatrix34ApplyP(&pos, pPosition, &invmat); |
||
137 | BrMatrix34ApplyV(&dir, pDir, &invmat); |
||
138 | pPosition = &pos; |
||
139 | pDir = &dir; |
||
140 | } |
||
141 | if (ap->type == BR_ACTOR_MODEL) { |
||
142 | if (PickBoundsTestRay__finteray(&this_model->bounds, pPosition, pDir, t_near, t_far, &t_near, &t_far)) { |
||
143 | t_near = 0.0; |
||
144 | t_far = MIN(1.f, gNearest_T); |
||
145 | r = callback(ap, this_model, this_material, pPosition, pDir, t_near, t_far, arg); |
||
146 | if (r) { |
||
147 | return r; |
||
148 | } |
||
149 | } |
||
150 | if (r) { |
||
151 | return r; |
||
152 | } |
||
153 | } else if (ap->type >= BR_ACTOR_BOUNDS && ap->type <= BR_ACTOR_BOUNDS_CORRECT) { |
||
154 | if (PickBoundsTestRay__finteray((br_bounds*)ap->type_data, pPosition, pDir, t_near, t_far, &t_near, &t_far)) { |
||
155 | for (a = ap->children; a != NULL; a = a->next) { |
||
156 | r = ActorRayPick2D(a, pPosition, pDir, this_model, this_material, callback); |
||
157 | if (r) { |
||
158 | break; |
||
159 | } |
||
160 | } |
||
161 | } |
||
162 | return r; |
||
163 | } |
||
164 | for (a = ap->children; a != NULL; a = a->next) { |
||
165 | r = ActorRayPick2D(a, pPosition, pDir, this_model, this_material, callback); |
||
166 | if (r) { |
||
167 | break; |
||
168 | } |
||
169 | } |
||
170 | return r; |
||
171 | } |
||
172 | |||
173 | // IDA: int __usercall DRSceneRayPick2D@<EAX>(br_actor *world@<EAX>, br_vector3 *pPosition@<EDX>, br_vector3 *pDir@<EBX>, dr_pick2d_cbfn *callback@<ECX>) |
||
174 | int DRSceneRayPick2D(br_actor* world, br_vector3* pPosition, br_vector3* pDir, dr_pick2d_cbfn* callback) { |
||
175 | LOG_TRACE("(%p, %p, %p, %p)", world, pPosition, pDir, callback); |
||
176 | |||
177 | BrMatrix34Inverse(&gPick_model_to_view__finteray, &world->t.t.mat); |
||
178 | LOG_WARN_ONCE("Missing material and model pointers to ActorRayPick2D"); |
||
179 | return ActorRayPick2D(world, pPosition, pDir, NULL, NULL, callback); |
||
180 | } |
||
181 | |||
182 | // IDA: int __usercall DRModelPick2D@<EAX>(br_model *model@<EAX>, br_material *material@<EDX>, br_vector3 *ray_pos@<EBX>, br_vector3 *ray_dir@<ECX>, br_scalar t_near, br_scalar t_far, dr_modelpick2d_cbfn *callback, void *arg) |
||
183 | // Suffix added to avoid duplicate symbol |
||
184 | int DRModelPick2D__finteray(br_model* model, br_material* material, br_vector3* ray_pos, br_vector3* ray_dir, br_scalar t_near, br_scalar t_far, dr_modelpick2d_cbfn* callback, void* arg) { |
||
20 | pmbaty | 185 | DR_FACE* fp; |
1 | pmbaty | 186 | int f; |
187 | int axis_m; |
||
188 | int axis_0; |
||
189 | int axis_1; |
||
190 | br_scalar t; |
||
20 | pmbaty | 191 | //br_scalar n; // Pierre-Marie Baty -- unused variable |
1 | pmbaty | 192 | br_scalar d; |
193 | br_vector3 p; |
||
194 | float u0; |
||
195 | float u1; |
||
196 | float u2; |
||
197 | float v0; |
||
198 | float v1; |
||
199 | float v2; |
||
200 | br_scalar v0i1; |
||
201 | br_scalar v0i2; |
||
202 | float alpha; |
||
203 | float beta; |
||
204 | float f_d; |
||
205 | float f_n; |
||
206 | br_scalar s_alpha; |
||
207 | br_scalar s_beta; |
||
208 | br_vector2 map; |
||
209 | int v; |
||
210 | int e; |
||
211 | int r; |
||
212 | br_material* this_material; |
||
213 | br_scalar numerator; |
||
20 | pmbaty | 214 | //float f_numerator; // Pierre-Marie Baty -- unused variable |
1 | pmbaty | 215 | int group; |
216 | LOG_TRACE("(%p, %p, %p, %p, %f, %f, %p, %p)", model, material, ray_pos, ray_dir, t_near, t_far, callback, arg); |
||
217 | |||
218 | t_near -= 0.00001f; |
||
219 | t_far += 0.00001f; |
||
220 | for (group = 0; group < V11MODEL(model)->ngroups; group++) { |
||
221 | for (f = 0; f < V11MODEL(model)->groups[group].nfaces; f++) { |
||
20 | pmbaty | 222 | fp = &V11MODEL(model)->groups[group].faces[f]; |
223 | if (V11MODEL(model)->groups[group].face_colours_material) { |
||
224 | this_material = V11MODEL(model)->groups[group].face_colours_material; |
||
1 | pmbaty | 225 | } else { |
226 | this_material = material; |
||
227 | } |
||
20 | pmbaty | 228 | d = fp->eqn.v[1] * ray_dir->v[1] + fp->eqn.v[2] * ray_dir->v[2] + fp->eqn.v[0] * ray_dir->v[0]; |
1 | pmbaty | 229 | if (fabs(d) >= 0.00000023841858 && (!this_material || !this_material->identifier || *this_material->identifier != '!' || !gPling_materials) |
230 | && (!this_material || (this_material->flags & 0x1800) != 0 || d <= 0.0)) { |
||
20 | pmbaty | 231 | numerator = fp->eqn.v[1] * ray_pos->v[1] |
232 | + fp->eqn.v[2] * ray_pos->v[2] |
||
233 | + fp->eqn.v[0] * ray_pos->v[0] |
||
234 | - fp->eqn.v[3]; |
||
1 | pmbaty | 235 | if (!BadDiv__finteray(numerator, d)) { |
236 | t = -(numerator / d); |
||
237 | if (t >= t_near && t <= t_far) { |
||
238 | BrVector3Scale(&p, ray_dir, t); |
||
239 | BrVector3Accumulate(&p, ray_pos); |
||
20 | pmbaty | 240 | axis_m = fabsf(fp->eqn.v[0]) < fabsf(fp->eqn.v[1]); |
241 | if (fabsf(fp->eqn.v[2]) > fabsf(fp->eqn.v[axis_m])) { |
||
1 | pmbaty | 242 | axis_m = 2; |
243 | } |
||
244 | if (axis_m) { |
||
245 | axis_0 = 0; |
||
246 | if (axis_m == 1) { |
||
247 | axis_1 = 2; |
||
248 | } else { |
||
249 | axis_1 = 1; |
||
250 | } |
||
251 | } else { |
||
252 | axis_0 = 1; |
||
253 | axis_1 = 2; |
||
254 | } |
||
255 | |||
20 | pmbaty | 256 | v0 = V11MODEL(model)->groups[group].vertices[fp->vertices[0]].p.v[axis_0]; |
257 | u0 = V11MODEL(model)->groups[group].vertices[fp->vertices[0]].p.v[axis_1]; |
||
258 | v1 = V11MODEL(model)->groups[group].vertices[fp->vertices[1]].p.v[axis_0] - v0; |
||
259 | u1 = V11MODEL(model)->groups[group].vertices[fp->vertices[1]].p.v[axis_1] - u0; |
||
260 | v2 = V11MODEL(model)->groups[group].vertices[fp->vertices[2]].p.v[axis_0] - v0; |
||
261 | u2 = V11MODEL(model)->groups[group].vertices[fp->vertices[2]].p.v[axis_1] - u0; |
||
1 | pmbaty | 262 | |
263 | v0i1 = p.v[axis_0] - v0; |
||
264 | v0i2 = p.v[axis_1] - u0; |
||
265 | if (fabs(v1) > 0.0000002384185791015625) { |
||
266 | f_n = u2 * v1 - u1 * v2; |
||
267 | f_d = v0i2 * v1 - u1 * v0i1; |
||
268 | if (fabs(f_n) < fabs(f_d)) { |
||
269 | continue; |
||
270 | } |
||
271 | if (f_n == 0) { |
||
272 | continue; |
||
273 | } |
||
274 | beta = f_d / f_n; |
||
275 | if (beta < 0.0 || beta > 1.0 || v1 == 0.0) { |
||
276 | continue; |
||
277 | } |
||
278 | alpha = (v0i1 - beta * v2) / v1; |
||
279 | } else { |
||
280 | if (fabsf(v2) < fabsf(v0i1)) { |
||
281 | continue; |
||
282 | } |
||
283 | if (v2 == 0) { |
||
284 | continue; |
||
285 | } |
||
286 | |||
287 | beta = v0i1 / v2; |
||
288 | if (beta < 0.0 || beta > 1.0 || u1 == 0.0) { |
||
289 | continue; |
||
290 | } |
||
291 | alpha = (v0i2 - beta * u2) / u1; |
||
292 | } |
||
293 | |||
294 | if (alpha >= 0.0 && beta + alpha <= 1.0) { |
||
295 | s_alpha = alpha; |
||
296 | s_beta = beta; |
||
20 | pmbaty | 297 | map.v[0] = V11MODEL(model)->groups[group].vertices[fp->vertices[1]].map.v[0] * s_alpha; |
298 | map.v[1] = V11MODEL(model)->groups[group].vertices[fp->vertices[1]].map.v[1] * s_alpha; |
||
1 | pmbaty | 299 | DRVector2AccumulateScale__finteray( |
300 | &map, |
||
20 | pmbaty | 301 | &V11MODEL(model)->groups[group].vertices[fp->vertices[2]].map, |
1 | pmbaty | 302 | s_beta); |
303 | DRVector2AccumulateScale__finteray( |
||
304 | &map, |
||
20 | pmbaty | 305 | &V11MODEL(model)->groups[group].vertices[fp->vertices[0]].map, |
1 | pmbaty | 306 | 1.0 - (s_alpha + s_beta)); |
307 | v = 0; |
||
308 | e = 1; |
||
309 | if (s_alpha <= s_beta) { |
||
310 | if (0.5 - s_beta / 2.0 > s_alpha) { |
||
311 | e = 0; |
||
312 | } |
||
313 | if (1.0 - s_beta * 2.0 < s_alpha) { |
||
314 | v = 1; |
||
315 | } |
||
316 | } else { |
||
317 | if (1.0 - s_beta * 2.0 > s_alpha) { |
||
318 | e = 2; |
||
319 | } |
||
320 | if (0.5 - s_beta / 2.0 < s_alpha) { |
||
321 | v = 2; |
||
322 | } |
||
323 | } |
||
324 | gTemp_group = group; |
||
325 | r = callback(model, this_material, ray_pos, ray_dir, t, f, e, v, &p, &map, arg); |
||
326 | if (r) { |
||
327 | return r; |
||
328 | } |
||
329 | } |
||
330 | } |
||
331 | } |
||
332 | } |
||
333 | } |
||
334 | } |
||
335 | return 0; |
||
336 | } |
||
337 | |||
338 | // IDA: int __cdecl FindHighestPolyCallBack(br_model *pModel, br_material *pMaterial, br_vector3 *pRay_pos, br_vector3 *pRay_dir, br_scalar pT, int pF, int pE, int pV, br_vector3 *pPoint, br_vector2 *pMap, void *pArg) |
||
339 | // Suffix added to avoid duplicate symbol |
||
340 | int FindHighestPolyCallBack__finteray(br_model* pModel, br_material* pMaterial, br_vector3* pRay_pos, br_vector3* pRay_dir, br_scalar pT, int pF, int pE, int pV, br_vector3* pPoint, br_vector2* pMap, void* pArg) { |
||
341 | LOG_TRACE("(%p, %p, %p, %p, %f, %d, %d, %d, %p, %p, %p)", pModel, pMaterial, pRay_pos, pRay_dir, pT, pF, pE, pV, pPoint, pMap, pArg); |
||
342 | |||
343 | if (pT < (double)gNearest_T) { |
||
344 | gNearest_T = pT; |
||
345 | gNearest_model = pModel; |
||
346 | gNearest_face = pF; |
||
347 | gNearest_face_group = gTemp_group; |
||
348 | } |
||
349 | return 0; |
||
350 | } |
||
351 | |||
352 | // IDA: int __cdecl FindHighestCallBack(br_actor *pActor, br_model *pModel, br_material *pMaterial, br_vector3 *pRay_pos, br_vector3 *pRay_dir, br_scalar pT_near, br_scalar pT_far, void *pArg) |
||
353 | // Suffix added to avoid duplicate symbol |
||
354 | int FindHighestCallBack__finteray(br_actor* pActor, br_model* pModel, br_material* pMaterial, br_vector3* pRay_pos, br_vector3* pRay_dir, br_scalar pT_near, br_scalar pT_far, void* pArg) { |
||
355 | LOG_TRACE("(%p, %p, %p, %p, %p, %f, %f, %p)", pActor, pModel, pMaterial, pRay_pos, pRay_dir, pT_near, pT_far, pArg); |
||
356 | |||
357 | if (gProgram_state.current_car.current_car_actor < 0 |
||
358 | || gProgram_state.current_car.car_model_actors[gProgram_state.current_car.current_car_actor].actor != pActor) { |
||
359 | DRModelPick2D__finteray(pModel, pMaterial, pRay_pos, pRay_dir, pT_near, pT_far, FindHighestPolyCallBack__finteray, pArg); |
||
360 | } |
||
361 | return 0; |
||
362 | } |
||
363 | |||
364 | // IDA: void __usercall FindFace(br_vector3 *pPosition@<EAX>, br_vector3 *pDir@<EDX>, br_vector3 *nor@<EBX>, br_scalar *t@<ECX>, br_material **material) |
||
365 | void FindFace(br_vector3* pPosition, br_vector3* pDir, br_vector3* nor, br_scalar* t, br_material** material) { |
||
366 | int group; |
||
367 | LOG_TRACE("(%p, %p, %p, %p, %p)", pPosition, pDir, nor, t, material); |
||
368 | |||
369 | gNearest_T = 100.0f; |
||
370 | DRSceneRayPick2D(gTrack_actor, pPosition, pDir, FindHighestCallBack__finteray); |
||
371 | *t = gNearest_T; |
||
372 | if (*t < 100.0f) { |
||
373 | group = gNearest_face_group; |
||
20 | pmbaty | 374 | nor->v[0] = V11MODEL(gNearest_model)->groups[group].faces[gNearest_face].eqn.v[0]; |
375 | nor->v[1] = V11MODEL(gNearest_model)->groups[group].faces[gNearest_face].eqn.v[1]; |
||
376 | nor->v[2] = V11MODEL(gNearest_model)->groups[group].faces[gNearest_face].eqn.v[2]; |
||
377 | *material = V11MODEL(gNearest_model)->groups[group].face_colours_material; |
||
1 | pmbaty | 378 | } |
379 | } |
||
380 | |||
381 | // IDA: void __cdecl EnablePlingMaterials() |
||
382 | void EnablePlingMaterials(void) { |
||
383 | LOG_TRACE("()"); |
||
384 | |||
385 | gPling_materials = 1; |
||
386 | } |
||
387 | |||
388 | // IDA: void __cdecl DisablePlingMaterials() |
||
389 | void DisablePlingMaterials(void) { |
||
390 | LOG_TRACE("()"); |
||
391 | |||
392 | gPling_materials = 0; |
||
393 | } |
||
394 | |||
395 | // IDA: void __usercall CheckSingleFace(tFace_ref *pFace@<EAX>, br_vector3 *ray_pos@<EDX>, br_vector3 *ray_dir@<EBX>, br_vector3 *normal@<ECX>, br_scalar *rt) |
||
396 | void CheckSingleFace(tFace_ref* pFace, br_vector3* ray_pos, br_vector3* ray_dir, br_vector3* normal, br_scalar* rt) { |
||
397 | br_scalar t; |
||
398 | br_scalar numerator; |
||
399 | br_scalar d; |
||
400 | br_vector3 p; |
||
401 | br_vector3 tv; |
||
402 | int axis_m; |
||
403 | int axis_0; |
||
404 | int axis_1; |
||
405 | double u0; |
||
406 | double u1; |
||
407 | double u2; |
||
408 | double v0; |
||
409 | double v1; |
||
410 | double v2; |
||
411 | br_scalar v0i1; |
||
412 | br_scalar v0i2; |
||
413 | double alpha; |
||
414 | double beta; |
||
415 | double f_d; |
||
416 | //double f_n; // Pierre-Marie Baty -- unused variable |
||
417 | //double f_numerator; // Pierre-Marie Baty -- unused variable |
||
418 | br_material* this_material; |
||
419 | LOG_TRACE("(%p, %p, %p, %p, %p)", pFace, ray_pos, ray_dir, normal, rt); |
||
420 | |||
421 | this_material = pFace->material; |
||
422 | *rt = 100.0; |
||
423 | |||
424 | d = pFace->normal.v[1] * ray_dir->v[1] + ray_dir->v[2] * pFace->normal.v[2] + ray_dir->v[0] * pFace->normal.v[0]; |
||
20 | pmbaty | 425 | if ((this_material == NULL || (this_material->flags & (BR_MATF_TWO_SIDED | BR_MATF_ALWAYS_VISIBLE )) != 0 || d <= 0.0) |
1 | pmbaty | 426 | && (!this_material || !this_material->identifier || *this_material->identifier != '!' || !gPling_materials) |
427 | && fabs(d) >= 0.00000023841858) { |
||
428 | BrVector3Sub(&p, ray_pos, &pFace->v[0]); |
||
429 | numerator = BrVector3Dot(&pFace->normal, &p); |
||
430 | if (!BadDiv__finteray(numerator, d)) { |
||
431 | if (d > 0.0) { |
||
432 | if (-numerator < -0.001 || -numerator > d + 0.003) { |
||
433 | return; |
||
434 | } |
||
435 | } else if (numerator < -0.001 || 0.003 - d < numerator) { |
||
436 | return; |
||
437 | } |
||
438 | t = -(numerator / d); |
||
439 | if (t > 1.0) { |
||
440 | t = 1.0; |
||
441 | } |
||
442 | BrVector3Scale(&tv, ray_dir, t); |
||
443 | BrVector3Accumulate(&tv, ray_pos); |
||
444 | axis_m = fabs(pFace->normal.v[0]) < fabs(pFace->normal.v[1]); |
||
445 | if (fabs(pFace->normal.v[2]) > fabs(pFace->normal.v[axis_m])) { |
||
446 | axis_m = 2; |
||
447 | } |
||
448 | if (axis_m) { |
||
449 | axis_0 = 0; |
||
450 | if (axis_m == 1) { |
||
451 | axis_1 = 2; |
||
452 | } else { |
||
453 | axis_1 = 1; |
||
454 | } |
||
455 | } else { |
||
456 | axis_0 = 1; |
||
457 | axis_1 = 2; |
||
458 | } |
||
459 | v0i1 = pFace->v[0].v[axis_0]; |
||
460 | v0i2 = pFace->v[0].v[axis_1]; |
||
461 | u0 = pFace->v[1].v[axis_0] - v0i1; |
||
462 | u1 = pFace->v[1].v[axis_1] - v0i2; |
||
463 | v0 = pFace->v[2].v[axis_0] - v0i1; |
||
464 | v1 = pFace->v[2].v[axis_1] - v0i2; |
||
465 | u2 = tv.v[axis_0] - v0i1; |
||
466 | v2 = tv.v[axis_1] - v0i2; |
||
467 | if (fabs(u0) > 0.0000002384185791015625) { |
||
468 | f_d = v1 * u0 - u1 * v0; |
||
469 | if (f_d == 0) { |
||
470 | return; |
||
471 | } |
||
472 | alpha = (v2 * u0 - u1 * u2) / f_d; |
||
473 | beta = (u2 - alpha * v0) / u0; |
||
474 | } else { |
||
475 | alpha = u2 / v0; |
||
476 | beta = (v2 - alpha * v1) / u1; |
||
477 | } |
||
478 | if (beta >= -0.0001 && alpha >= -0.0001 && alpha + beta <= 1.0001) { |
||
479 | *rt = t; |
||
480 | *normal = pFace->normal; |
||
481 | if (d > 0.0) { |
||
482 | BrVector3Negate(normal, normal); |
||
483 | } |
||
484 | } |
||
485 | } |
||
486 | } |
||
487 | } |
||
488 | |||
489 | // IDA: void __usercall MultiRayCheckSingleFace(int pNum_rays@<EAX>, tFace_ref *pFace@<EDX>, br_vector3 *ray_pos@<EBX>, br_vector3 *ray_dir@<ECX>, br_vector3 *normal, br_scalar *rt) |
||
490 | void MultiRayCheckSingleFace(int pNum_rays, tFace_ref* pFace, br_vector3* ray_pos, br_vector3* ray_dir, br_vector3* normal, br_scalar* rt) { |
||
491 | int i; |
||
492 | br_scalar t[4]; |
||
493 | br_scalar numerator; |
||
494 | br_scalar d; |
||
495 | br_vector3 p[4]; |
||
496 | br_vector3 tv; |
||
497 | int axis_m; |
||
498 | int axis_0; |
||
499 | int axis_1; |
||
500 | double u0[4]; |
||
501 | double u1; |
||
502 | double u2; |
||
503 | double v0[4]; |
||
504 | double v1; |
||
505 | double v2; |
||
506 | br_scalar v0i1; |
||
507 | br_scalar v0i2; |
||
508 | double alpha; |
||
509 | double beta; |
||
510 | double f_d; |
||
511 | double f_n; |
||
512 | double f_numerator; |
||
513 | br_material* this_material; |
||
514 | LOG_TRACE("(%d, %p, %p, %p, %p, %p)", pNum_rays, pFace, ray_pos, ray_dir, normal, rt); |
||
515 | |||
516 | this_material = pFace->material; |
||
517 | d = ray_dir->v[2] * pFace->normal.v[2] + ray_dir->v[1] * pFace->normal.v[1] + ray_dir->v[0] * pFace->normal.v[0]; |
||
518 | for (i = 0; i < pNum_rays; ++i) { |
||
519 | rt[i] = 100.0; |
||
520 | } |
||
521 | if ((!this_material || (this_material->flags & 0x1800) != 0 || d <= 0.0) |
||
522 | && (!this_material || !this_material->identifier || *this_material->identifier != '!' || !gPling_materials) |
||
523 | && fabs(d) >= 0.00000023841858) { |
||
524 | for (i = 0;; ++i) { |
||
525 | if (i >= pNum_rays) { |
||
526 | axis_m = fabs(pFace->normal.v[0]) < fabs(pFace->normal.v[1]); |
||
527 | if (fabs(pFace->normal.v[2]) > fabs(pFace->normal.v[axis_m])) { |
||
528 | axis_m = 2; |
||
529 | } |
||
530 | if (axis_m) { |
||
531 | axis_0 = 0; |
||
532 | if (axis_m == 1) { |
||
533 | axis_1 = 2; |
||
534 | } else { |
||
535 | axis_1 = 1; |
||
536 | } |
||
537 | } else { |
||
538 | axis_0 = 1; |
||
539 | axis_1 = 2; |
||
540 | } |
||
541 | v0i1 = pFace->v[0].v[axis_0]; |
||
542 | v0i2 = pFace->v[0].v[axis_1]; |
||
543 | u1 = pFace->v[1].v[axis_0] - v0i1; |
||
544 | v1 = pFace->v[1].v[axis_1] - v0i2; |
||
545 | u2 = pFace->v[2].v[axis_0] - v0i1; |
||
546 | v2 = pFace->v[2].v[axis_1] - v0i2; |
||
547 | i = 0; |
||
548 | while (1) { |
||
549 | if (i >= pNum_rays) { |
||
550 | return; |
||
551 | } |
||
552 | if (t[i] != 100.0) { |
||
553 | u0[i] = p[i].v[axis_0] - v0i1; |
||
554 | v0[i] = p[i].v[axis_1] - v0i2; |
||
555 | if (fabs(u1) <= 0.0000002384185791015625) { |
||
556 | alpha = u0[i] / u2; |
||
557 | beta = v0[i] - alpha * v2; |
||
558 | f_d = beta / v1; |
||
559 | goto LABEL_43; |
||
560 | } |
||
561 | f_numerator = v0[i] * u1 - u0[i] * v1; |
||
562 | f_n = v2 * u1 - v1 * u2; |
||
563 | if (f_n != 0) { |
||
564 | alpha = f_numerator / f_n; |
||
565 | beta = u0[i] - alpha * u2; |
||
566 | f_d = beta / u1; |
||
567 | LABEL_43: |
||
568 | if (f_d >= -0.0001 && alpha >= -0.0001 && alpha + f_d <= 1.0001) { |
||
569 | rt[i] = t[i]; |
||
570 | *normal = pFace->normal; |
||
571 | if (d > 0.0) { |
||
572 | normal->v[0] = -pFace->normal.v[0]; |
||
573 | normal->v[1] = -pFace->normal.v[1]; |
||
574 | normal->v[2] = -pFace->normal.v[2]; |
||
575 | } |
||
576 | } |
||
577 | } |
||
578 | } |
||
579 | ++i; |
||
580 | continue; |
||
581 | } |
||
582 | } |
||
583 | tv.v[0] = ray_pos[i].v[0] - pFace->v[0].v[0]; |
||
584 | tv.v[1] = ray_pos[i].v[1] - pFace->v[0].v[1]; |
||
585 | tv.v[2] = ray_pos[i].v[2] - pFace->v[0].v[2]; |
||
586 | numerator = pFace->normal.v[2] * tv.v[2] + pFace->normal.v[1] * tv.v[1] + pFace->normal.v[0] * tv.v[0]; |
||
587 | if (BadDiv__finteray(numerator, d)) { |
||
588 | return; |
||
589 | } |
||
590 | if (d > 0.0) { |
||
591 | if (-numerator < -0.001 || -numerator > d + 0.003) { |
||
592 | t[i] = 100.0; |
||
593 | continue; |
||
594 | } |
||
595 | } else if (numerator < -0.001 || 0.003 - d < numerator) { |
||
596 | t[i] = 100.0; |
||
597 | continue; |
||
598 | } |
||
599 | t[i] = -(numerator / d); |
||
600 | if (t[i] > 1.0) { |
||
601 | t[i] = 1.0; |
||
602 | } |
||
603 | p[i].v[0] = t[i] * ray_dir->v[0]; |
||
604 | p[i].v[1] = t[i] * ray_dir->v[1]; |
||
605 | p[i].v[2] = t[i] * ray_dir->v[2]; |
||
606 | p[i].v[0] = ray_pos[i].v[0] + p[i].v[0]; |
||
607 | p[i].v[1] = ray_pos[i].v[1] + p[i].v[1]; |
||
608 | p[i].v[2] = ray_pos[i].v[2] + p[i].v[2]; |
||
609 | } |
||
610 | } |
||
611 | } |
||
612 | |||
613 | // IDA: void __usercall GetNewBoundingBox(br_bounds *b2@<EAX>, br_bounds *b1@<EDX>, br_matrix34 *m@<EBX>) |
||
614 | void GetNewBoundingBox(br_bounds* b2, br_bounds* b1, br_matrix34* m) { |
||
615 | br_vector3 a; |
||
616 | br_vector3 c[3]; |
||
617 | int j; |
||
618 | LOG_TRACE("(%p, %p, %p)", b2, b1, m); |
||
619 | |||
620 | BrMatrix34ApplyP(&b2->min, &b1->min, m); |
||
621 | BrVector3Copy(&b2->max, &b2->min); |
||
622 | BrVector3Sub(&a, &b1->max, &b1->min); |
||
623 | for (j = 0; j < 3; j++) { |
||
624 | BrVector3Scale(&c[j], (br_vector3*)m->m[j], a.v[j]); |
||
625 | } |
||
626 | for (j = 0; j < 3; ++j) { |
||
627 | b2->min.v[j] = (float)(c[2].v[j] < 0.f) * c[2].v[j] |
||
628 | + (float)(c[1].v[j] < 0.f) * c[1].v[j] |
||
629 | + (float)(c[0].v[j] < 0.f) * c[0].v[j] |
||
630 | + b2->min.v[j]; |
||
631 | b2->max.v[j] = (float)(c[0].v[j] > 0.f) * c[0].v[j] |
||
632 | + (float)(c[2].v[j] > 0.f) * c[2].v[j] |
||
633 | + (float)(c[1].v[j] > 0.f) * c[1].v[j] |
||
634 | + b2->max.v[j]; |
||
635 | } |
||
636 | } |
||
637 | |||
638 | // IDA: int __usercall FindFacesInBox@<EAX>(tBounds *bnds@<EAX>, tFace_ref *face_list@<EDX>, int max_face@<EBX>) |
||
639 | int FindFacesInBox(tBounds* bnds, tFace_ref* face_list, int max_face) { |
||
640 | br_vector3 a; |
||
641 | br_vector3 b; |
||
642 | br_vector3 c[3]; |
||
643 | int i; |
||
644 | int j; |
||
645 | int x; |
||
646 | int z; |
||
647 | tU8 cx_min; |
||
648 | tU8 cx_max; |
||
649 | tU8 cz_min; |
||
650 | tU8 cz_max; |
||
651 | tTrack_spec* track_spec; |
||
652 | LOG_TRACE("(%p, %p, %d)", bnds, face_list, max_face); |
||
653 | |||
654 | j = 0; |
||
655 | track_spec = &gProgram_state.track_spec; |
||
656 | BrVector3Add(&a, &bnds->original_bounds.min, &bnds->original_bounds.max); |
||
657 | BrVector3Scale(&a, &a, 0.5f); |
||
658 | BrMatrix34ApplyP(&bnds->box_centre, &a, bnds->mat); |
||
659 | BrVector3Sub(&b, &bnds->original_bounds.max, &bnds->original_bounds.min); |
||
660 | bnds->radius = BrVector3Length(&b) / 2.f; |
||
661 | BrMatrix34ApplyP(&bnds->real_bounds.min, &bnds->original_bounds.min, bnds->mat); |
||
662 | BrVector3Copy(&bnds->real_bounds.max, &bnds->real_bounds.min); |
||
663 | for (i = 0; i < 3; ++i) { |
||
664 | c[i].v[0] = bnds->mat->m[i][0] * b.v[i]; |
||
665 | c[i].v[1] = bnds->mat->m[i][1] * b.v[i]; |
||
666 | c[i].v[2] = bnds->mat->m[i][2] * b.v[i]; |
||
667 | } |
||
668 | for (i = 0; i < 3; ++i) { |
||
669 | bnds->real_bounds.min.v[i] += MIN(c[0].v[i], 0.f) |
||
670 | + MIN(c[1].v[i], 0.f) |
||
671 | + MIN(c[2].v[i], 0.f); |
||
672 | bnds->real_bounds.max.v[i] += MAX(c[0].v[i], 0.f) |
||
673 | + MAX(c[1].v[i], 0.f) |
||
674 | + MAX(c[2].v[i], 0.f); |
||
675 | } |
||
676 | XZToColumnXZ(&cx_min, &cz_min, bnds->real_bounds.min.v[0], bnds->real_bounds.min.v[2], track_spec); |
||
677 | XZToColumnXZ(&cx_max, &cz_max, bnds->real_bounds.max.v[0], bnds->real_bounds.max.v[2], track_spec); |
||
678 | if (cx_min != 0) { |
||
679 | cx_min--; |
||
680 | } |
||
681 | if (cz_min != 0) { |
||
682 | cz_min--; |
||
683 | } |
||
684 | if (cx_max + 1 < track_spec->ncolumns_x) { |
||
685 | cx_max++; |
||
686 | } |
||
687 | if (cz_max + 1 < track_spec->ncolumns_z) { |
||
688 | cz_max++; |
||
689 | } |
||
690 | for (x = cx_min; x <= cx_max; x++) { |
||
691 | for (z = cz_min; z <= cz_max; z++) { |
||
692 | if (track_spec->columns[z][x] != NULL) { |
||
693 | if (track_spec->blends[z][x] != NULL) { |
||
694 | track_spec->blends[z][x]->render_style = BR_RSTYLE_FACES; |
||
695 | } |
||
696 | j = max_face - ActorBoxPick(bnds, track_spec->columns[z][x], model_unk1, material_unk1, &face_list[j], max_face - j, NULL); |
||
697 | if (track_spec->blends[z][x] != NULL) { |
||
698 | track_spec->blends[z][x]->render_style = BR_RSTYLE_NONE; |
||
699 | } |
||
700 | } |
||
701 | if (track_spec->lollipops[z][x] != NULL) { |
||
702 | j = max_face - ActorBoxPick(bnds, track_spec->lollipops[z][x], model_unk1, material_unk1, &face_list[j], max_face - j, NULL); |
||
703 | } |
||
704 | } |
||
705 | } |
||
706 | return j; |
||
707 | } |
||
708 | |||
709 | // IDA: int __usercall FindFacesInBox2@<EAX>(tBounds *bnds@<EAX>, tFace_ref *face_list@<EDX>, int max_face@<EBX>) |
||
710 | int FindFacesInBox2(tBounds* bnds, tFace_ref* face_list, int max_face) { |
||
20 | pmbaty | 711 | //br_vector3 a; // Pierre-Marie Baty -- unused variable |
712 | //br_vector3 b; // Pierre-Marie Baty -- unused variable |
||
713 | //br_vector3 c[3]; // Pierre-Marie Baty -- unused variable |
||
714 | //int i; // Pierre-Marie Baty -- unused variable |
||
715 | //int j; // Pierre-Marie Baty -- unused variable |
||
1 | pmbaty | 716 | LOG_TRACE("(%p, %p, %d)", bnds, face_list, max_face); |
20 | pmbaty | 717 | NOT_IMPLEMENTED(); |
1 | pmbaty | 718 | } |
719 | |||
720 | // IDA: int __usercall ActorBoxPick@<EAX>(tBounds *bnds@<EAX>, br_actor *ap@<EDX>, br_model *model@<EBX>, br_material *material@<ECX>, tFace_ref *face_list, int max_face, br_matrix34 *pMat) |
||
721 | int ActorBoxPick(tBounds* bnds, br_actor* ap, br_model* model, br_material* material, tFace_ref* face_list, int max_face, br_matrix34* pMat) { |
||
722 | br_model* this_model; |
||
723 | br_material* this_material; |
||
724 | int i; |
||
725 | int n; |
||
726 | int test_children; |
||
727 | br_actor* a; |
||
728 | br_actor* next_a; |
||
729 | br_matrix34 mat; |
||
730 | br_matrix34 mat2; |
||
731 | br_matrix34 invmat; |
||
732 | br_matrix34 box_to_actor; |
||
733 | tBounds new_bounds; |
||
734 | br_bounds br_bnds; |
||
735 | LOG_TRACE("(%p, %p, %p, %p, %p, %d, %p)", bnds, ap, model, material, face_list, max_face, pMat); |
||
736 | |||
737 | i = 0; |
||
738 | test_children = 1; |
||
739 | if (ap->model != NULL) { |
||
740 | this_model = ap->model; |
||
741 | } else { |
||
742 | this_model = model; |
||
743 | } |
||
744 | if (ap->material != NULL) { |
||
745 | this_material = ap->material; |
||
746 | } else { |
||
747 | this_material = material; |
||
748 | } |
||
749 | if (ap->render_style == BR_RSTYLE_NONE) { |
||
750 | return max_face; |
||
751 | } |
||
752 | if (ap->identifier != NULL && ap->identifier[0] == '&') { |
||
753 | if (ap->children == NULL) { |
||
754 | if (ap->type != BR_ACTOR_MODEL) { |
||
755 | return max_face; |
||
756 | } |
||
757 | if (!BoundsTransformTest(&this_model->bounds, &bnds->real_bounds, &ap->t.t.mat)) { |
||
758 | return max_face; |
||
759 | } |
||
760 | } |
||
761 | if (pMat != NULL) { |
||
762 | BrMatrix34Mul(&mat, &ap->t.t.mat, pMat); |
||
763 | pMat = &mat; |
||
764 | } else { |
||
765 | pMat = &ap->t.t.mat; |
||
766 | } |
||
767 | BrMatrix34LPInverse(&invmat, &ap->t.t.mat); |
||
768 | BrMatrix34Mul(&mat2, bnds->mat, &invmat); |
||
769 | new_bounds.mat = &mat2; |
||
770 | BrVector3Copy(&new_bounds.original_bounds.min, &bnds->original_bounds.min); |
||
771 | BrVector3Copy(&new_bounds.original_bounds.max, &bnds->original_bounds.max); |
||
772 | BrMatrix34ApplyP(&new_bounds.box_centre, &bnds->box_centre, &invmat); |
||
773 | new_bounds.radius = bnds->radius; |
||
774 | GetNewBoundingBox(&new_bounds.real_bounds, &new_bounds.original_bounds, new_bounds.mat); |
||
775 | if (ap->identifier[1] >= '0' && ap->identifier[1] <= '9') { |
||
776 | if (!BoundsOverlapTest__finteray(&new_bounds.real_bounds, &this_model->bounds)) { |
||
777 | return max_face; |
||
778 | } |
||
779 | BrMatrix34LPInverse(&invmat, bnds->mat); |
||
780 | BrMatrix34Mul(&box_to_actor, &ap->t.t.mat, &invmat); |
||
781 | GetNewBoundingBox(&br_bnds, &ap->model->bounds, &box_to_actor); |
||
782 | if (!BoundsOverlapTest__finteray(&br_bnds, &bnds->original_bounds)) { |
||
783 | return max_face; |
||
784 | } |
||
785 | if (PullActorFromWorld(ap)) { |
||
786 | return max_face; |
||
787 | } |
||
788 | } |
||
789 | bnds = &new_bounds; |
||
790 | } |
||
791 | if (ap->type == BR_ACTOR_MODEL) { |
||
792 | if (BoundsOverlapTest__finteray(&bnds->real_bounds, &this_model->bounds)) { |
||
793 | n = ModelPickBox(ap, bnds, this_model, this_material, &face_list[i], max_face, pMat); |
||
794 | if (pMat && max_face != n) { |
||
795 | StopGroovidelic(ap); |
||
796 | } |
||
797 | i += max_face - n; |
||
798 | max_face = n; |
||
799 | } |
||
800 | } else if (ap->type == BR_ACTOR_BOUNDS || ap->type == BR_ACTOR_BOUNDS_CORRECT) { |
||
801 | test_children = BoundsOverlapTest__finteray(&bnds->real_bounds, (br_bounds*)ap->type_data); |
||
802 | } |
||
803 | if (test_children) { |
||
804 | for (a = ap->children; a != NULL; a = next_a) { |
||
805 | next_a = a->next; |
||
806 | n = ActorBoxPick(bnds, a, this_model, this_material, &face_list[i], max_face, pMat); |
||
807 | i += max_face - n; |
||
808 | max_face = n; |
||
809 | } |
||
810 | } |
||
811 | return max_face; |
||
812 | } |
||
813 | |||
814 | // IDA: int __usercall ModelPickBox@<EAX>(br_actor *actor@<EAX>, tBounds *bnds@<EDX>, br_model *model@<EBX>, br_material *model_material@<ECX>, tFace_ref *face_list, int max_face, br_matrix34 *pMat) |
||
815 | int ModelPickBox(br_actor* actor, tBounds* bnds, br_model* model, br_material* model_material, tFace_ref* face_list, int max_face, br_matrix34* pMat) { |
||
816 | int f; |
||
817 | int i; |
||
818 | int n; |
||
819 | int group; |
||
20 | pmbaty | 820 | DR_FACE* fp; |
1 | pmbaty | 821 | int v1; |
822 | int v2; |
||
823 | int v3; |
||
824 | br_vector3 polygon[12]; |
||
825 | br_vector3 a; |
||
826 | br_vector3 tv; |
||
827 | br_scalar t; |
||
20 | pmbaty | 828 | v11model* prepared; |
1 | pmbaty | 829 | LOG_TRACE("(%p, %p, %p, %p, %p, %d, %p)", actor, bnds, model, model_material, face_list, max_face, pMat); |
830 | |||
831 | prepared = model->prepared; |
||
832 | if (max_face <= 0) { |
||
833 | return 0; |
||
834 | } |
||
835 | for (group = 0; prepared->ngroups > group; group++) { |
||
836 | for (f = 0; f < prepared->groups[group].nfaces; f++) { |
||
20 | pmbaty | 837 | fp = &prepared->groups[group].faces[f]; |
838 | v1 = fp->vertices[0]; |
||
839 | BrVector3Sub(&a, &prepared->groups[group].vertices[v1].p, &bnds->box_centre); |
||
840 | t = BrVector3Dot((br_vector3*)&fp->eqn, &a); |
||
1 | pmbaty | 841 | if (fabsf(t) > bnds->radius) { |
842 | continue; |
||
843 | } |
||
20 | pmbaty | 844 | v2 = fp->vertices[1]; |
845 | v3 = fp->vertices[2]; |
||
1 | pmbaty | 846 | |
847 | t = bnds->real_bounds.min.v[0]; |
||
20 | pmbaty | 848 | if (t > prepared->groups[group].vertices[v1].p.v[0] |
849 | && t > prepared->groups[group].vertices[v2].p.v[0] |
||
850 | && t > prepared->groups[group].vertices[v3].p.v[0]) { |
||
1 | pmbaty | 851 | continue; |
852 | } |
||
853 | t = bnds->real_bounds.max.v[0]; |
||
20 | pmbaty | 854 | if (t < prepared->groups[group].vertices[v1].p.v[0] |
855 | && t < prepared->groups[group].vertices[v2].p.v[0] |
||
856 | && t < prepared->groups[group].vertices[v3].p.v[0]) { |
||
1 | pmbaty | 857 | continue; |
858 | } |
||
859 | t = bnds->real_bounds.min.v[1]; |
||
20 | pmbaty | 860 | if (t > prepared->groups[group].vertices[v1].p.v[1] |
861 | && t > prepared->groups[group].vertices[v2].p.v[1] |
||
862 | && t > prepared->groups[group].vertices[v3].p.v[1]) { |
||
1 | pmbaty | 863 | continue; |
864 | } |
||
865 | t = bnds->real_bounds.max.v[1]; |
||
20 | pmbaty | 866 | if (t < prepared->groups[group].vertices[v1].p.v[1] |
867 | && t < prepared->groups[group].vertices[v2].p.v[1] |
||
868 | && t < prepared->groups[group].vertices[v3].p.v[1]) { |
||
1 | pmbaty | 869 | continue; |
870 | } |
||
871 | t = bnds->real_bounds.min.v[2]; |
||
20 | pmbaty | 872 | if (t > prepared->groups[group].vertices[v1].p.v[2] |
873 | && t > prepared->groups[group].vertices[v2].p.v[2] |
||
874 | && t > prepared->groups[group].vertices[v3].p.v[2]) { |
||
1 | pmbaty | 875 | continue; |
876 | } |
||
877 | t = bnds->real_bounds.max.v[2]; |
||
20 | pmbaty | 878 | if (t < prepared->groups[group].vertices[v1].p.v[2] |
879 | && t < prepared->groups[group].vertices[v2].p.v[2] |
||
880 | && t < prepared->groups[group].vertices[v3].p.v[2]) { |
||
1 | pmbaty | 881 | continue; |
882 | } |
||
20 | pmbaty | 883 | BrVector3Sub(&polygon[1], &prepared->groups[group].vertices[v1].p, (br_vector3*)bnds->mat->m[3]); |
884 | BrVector3Sub(&polygon[2], &prepared->groups[group].vertices[v2].p, (br_vector3*)bnds->mat->m[3]); |
||
885 | BrVector3Sub(&polygon[3], &prepared->groups[group].vertices[v3].p, (br_vector3*)bnds->mat->m[3]); |
||
1 | pmbaty | 886 | BrMatrix34TApplyV(&polygon[0], &polygon[1], bnds->mat); |
887 | BrMatrix34TApplyV(&polygon[1], &polygon[2], bnds->mat); |
||
888 | BrMatrix34TApplyV(&polygon[2], &polygon[3], bnds->mat); |
||
889 | n = 3; |
||
890 | for (i = 0; i < 3; i++) { |
||
891 | ClipToPlaneGE(&polygon[0], &n, i, bnds->original_bounds.min.v[i]); |
||
892 | if (n < 3) { |
||
893 | break; |
||
894 | } |
||
895 | ClipToPlaneLE(&polygon[0], &n, i, bnds->original_bounds.max.v[i]); |
||
896 | if (n < 3) { |
||
897 | break; |
||
898 | } |
||
899 | } |
||
900 | if (n >= 3) { |
||
901 | if (pMat != NULL) { |
||
20 | pmbaty | 902 | BrMatrix34ApplyP(&face_list->v[0], &prepared->groups[group].vertices[v1].p, pMat); |
903 | BrMatrix34ApplyP(&face_list->v[1], &prepared->groups[group].vertices[v2].p, pMat); |
||
904 | BrMatrix34ApplyP(&face_list->v[2], &prepared->groups[group].vertices[v3].p, pMat); |
||
905 | BrVector3Copy(&tv, (br_vector3*)&fp->eqn); |
||
1 | pmbaty | 906 | BrMatrix34ApplyV(&face_list->normal, &tv, pMat); |
907 | } else { |
||
20 | pmbaty | 908 | BrVector3Copy(&face_list->v[0], &prepared->groups[group].vertices[v1].p); |
909 | BrVector3Copy(&face_list->v[1], &prepared->groups[group].vertices[v2].p); |
||
910 | BrVector3Copy(&face_list->v[2], &prepared->groups[group].vertices[v3].p); |
||
911 | BrVector3Copy(&face_list->normal, (br_vector3*)&fp->eqn); |
||
1 | pmbaty | 912 | } |
20 | pmbaty | 913 | if (prepared->groups[group].face_colours_material != NULL) { |
914 | face_list->material = prepared->groups[group].face_colours_material; |
||
1 | pmbaty | 915 | } else { |
916 | face_list->material = model_material; |
||
917 | } |
||
918 | face_list->flags = 0; |
||
919 | if (face_list->material != NULL && (face_list->material->flags & (BR_MATF_TWO_SIDED | BR_MATF_ALWAYS_VISIBLE)) == 0) { |
||
920 | face_list->flags |= (v1 < v2) | (v2 < v3) << 1 | (v3 < v1) << 2; |
||
921 | } |
||
922 | if (pMat != NULL) { |
||
923 | face_list->d = BrVector3LengthSquared(&face_list->v[0]); |
||
924 | } else { |
||
20 | pmbaty | 925 | face_list->d = fp->eqn.v[3]; |
1 | pmbaty | 926 | } |
20 | pmbaty | 927 | face_list->map[0] = &prepared->groups[group].vertices[v1].map; |
928 | face_list->map[1] = &prepared->groups[group].vertices[v2].map; |
||
929 | face_list->map[2] = &prepared->groups[group].vertices[v3].map; |
||
930 | if (face_list->material!= NULL |
||
1 | pmbaty | 931 | && face_list->material->identifier != NULL |
932 | && face_list->material->identifier[0] == '!') { |
||
933 | gPling_face = face_list; |
||
934 | } |
||
935 | face_list++; |
||
936 | max_face--; |
||
937 | if (max_face == 0) { |
||
938 | break; |
||
939 | } |
||
940 | } |
||
941 | } |
||
942 | if (max_face == 0) { |
||
943 | break; |
||
944 | } |
||
945 | } |
||
946 | return max_face; |
||
947 | } |
||
948 | |||
949 | // IDA: void __usercall ClipToPlaneGE(br_vector3 *p@<EAX>, int *nv@<EDX>, int i@<EBX>, br_scalar limit) |
||
950 | void ClipToPlaneGE(br_vector3* p, int* nv, int i, br_scalar limit) { |
||
951 | int last_vertex; |
||
952 | int j; |
||
953 | int vertex; |
||
954 | int k; |
||
955 | br_vector3 p2[12]; |
||
956 | LOG_TRACE("(%p, %p, %d, %f)", p, nv, i, limit); |
||
957 | |||
958 | last_vertex = *nv - 1; |
||
959 | j = 0; |
||
960 | for (vertex = 0; *nv > vertex; ++vertex) { |
||
961 | if ((p[last_vertex].v[i] > limit) != (p[vertex].v[i] > limit)) { |
||
962 | for (k = 0; k < 3; ++k) { |
||
963 | if (i != k) { |
||
964 | p2[j].v[k] = (p[vertex].v[k] - p[last_vertex].v[k]) |
||
965 | * (limit - p[last_vertex].v[i]) |
||
966 | / (p[vertex].v[i] - p[last_vertex].v[i]) |
||
967 | + p[last_vertex].v[k]; |
||
968 | } |
||
969 | } |
||
970 | p2[j++].v[i] = limit; |
||
971 | } |
||
972 | if (p[vertex].v[i] >= limit) { |
||
973 | BrVector3Copy(&p2[j], &p[vertex]); |
||
974 | j++; |
||
975 | } |
||
976 | last_vertex = vertex; |
||
977 | } |
||
978 | *nv = j; |
||
979 | for (k = 0; k < j; k++) { |
||
980 | BrVector3Copy(&p[k], &p2[k]); |
||
981 | } |
||
982 | } |
||
983 | |||
984 | // IDA: void __usercall ClipToPlaneLE(br_vector3 *p@<EAX>, int *nv@<EDX>, int i@<EBX>, br_scalar limit) |
||
985 | void ClipToPlaneLE(br_vector3* p, int* nv, int i, br_scalar limit) { |
||
986 | int last_vertex; |
||
987 | int j; |
||
988 | int vertex; |
||
989 | int k; |
||
990 | br_vector3 p2[12]; |
||
991 | LOG_TRACE("(%p, %p, %d, %f)", p, nv, i, limit); |
||
992 | |||
993 | last_vertex = *nv - 1; |
||
994 | j = 0; |
||
995 | for (vertex = 0; *nv > vertex; ++vertex) { |
||
996 | if ((p[vertex].v[i] > limit) != (p[last_vertex].v[i] > limit)) { |
||
997 | for (k = 0; k < 3; ++k) { |
||
998 | if (k != i) { |
||
999 | p2[j].v[k] = (p[vertex].v[k] - p[last_vertex].v[k]) |
||
1000 | * (limit - p[last_vertex].v[i]) |
||
1001 | / (p[vertex].v[i] - p[last_vertex].v[i]) |
||
1002 | + p[last_vertex].v[k]; |
||
1003 | } |
||
1004 | } |
||
1005 | p2[j++].v[i] = limit; |
||
1006 | } |
||
1007 | if (p[vertex].v[i] <= (double)limit) { |
||
1008 | BrVector3Copy(&p2[j], &p[vertex]); |
||
1009 | j++; |
||
1010 | } |
||
1011 | last_vertex = vertex; |
||
1012 | } |
||
1013 | *nv = j; |
||
1014 | for (k = 0; k < j; k++) { |
||
1015 | BrVector3Copy(&p[k], &p2[k]); |
||
1016 | } |
||
1017 | } |
||
1018 | |||
1019 | // IDA: int __usercall BoundsOverlapTest@<EAX>(br_bounds *b1@<EAX>, br_bounds *b2@<EDX>) |
||
1020 | // Suffix added to avoid duplicate symbol |
||
1021 | int BoundsOverlapTest__finteray(br_bounds* b1, br_bounds* b2) { |
||
1022 | LOG_TRACE("(%p, %p)", b1, b2); |
||
1023 | |||
1024 | return b1->min.v[0] <= b2->max.v[0] |
||
1025 | && b2->min.v[0] <= b1->max.v[0] |
||
1026 | && b1->min.v[1] <= b2->max.v[1] |
||
1027 | && b2->min.v[1] <= b1->max.v[1] |
||
1028 | && b1->min.v[2] <= b2->max.v[2] |
||
1029 | && b2->min.v[2] <= b1->max.v[2]; |
||
1030 | } |
||
1031 | |||
1032 | // IDA: int __usercall BoundsTransformTest@<EAX>(br_bounds *b1@<EAX>, br_bounds *b2@<EDX>, br_matrix34 *M@<EBX>) |
||
1033 | int BoundsTransformTest(br_bounds* b1, br_bounds* b2, br_matrix34* M) { |
||
1034 | br_scalar val; |
||
1035 | br_vector3 o; |
||
1036 | LOG_TRACE("(%p, %p, %p)", b1, b2, M); |
||
1037 | |||
1038 | BrVector3Sub(&o, &b1->max, &b1->min); |
||
1039 | val = M->m[0][0] * b1->min.v[0] + M->m[1][0] * b1->min.v[1] + M->m[2][0] * b1->min.v[2] + M->m[3][0]; |
||
1040 | |||
1041 | if ((M->m[0][0] <= 0.0f ? 0.0f : M->m[0][0] * o.v[0]) |
||
1042 | + (M->m[1][0] <= 0.0f ? 0.0f : M->m[1][0] * o.v[1]) |
||
1043 | + (M->m[2][0] <= 0.0f ? 0.0f : M->m[2][0] * o.v[2]) |
||
1044 | + val |
||
1045 | < b2->min.v[0]) { |
||
1046 | return 0; |
||
1047 | } |
||
1048 | if ((M->m[0][0] < 0.0f ? M->m[0][0] * o.v[0] : 0.0f) |
||
1049 | + (M->m[1][0] < 0.0f ? M->m[1][0] * o.v[1] : 0.0f) |
||
1050 | + (M->m[2][0] < 0.0f ? M->m[2][0] * o.v[2] : 0.0f) |
||
1051 | + val |
||
1052 | > b2->max.v[0]) { |
||
1053 | return 0; |
||
1054 | } |
||
1055 | |||
1056 | val = M->m[0][2] * b1->min.v[0] + M->m[1][2] * b1->min.v[1] + M->m[2][2] * b1->min.v[2] + M->m[3][2]; |
||
1057 | if ((M->m[0][2] <= 0.0f ? 0.0f : M->m[0][2] * o.v[0]) |
||
1058 | + (M->m[1][2] <= 0.0f ? 0.0f : M->m[1][2] * o.v[1]) |
||
1059 | + (M->m[2][2] <= 0.0f ? 0.0f : M->m[2][2] * o.v[2]) |
||
1060 | + val |
||
1061 | < b2->min.v[2]) { |
||
1062 | return 0; |
||
1063 | } |
||
1064 | if ((M->m[0][2] < 0.0f ? M->m[0][2] * o.v[0] : 0.0f) |
||
1065 | + (M->m[1][2] < 0.0f ? M->m[1][2] * o.v[1] : 0.0f) |
||
1066 | + (M->m[2][2] < 0.0f ? M->m[2][2] * o.v[2] : 0.0f) |
||
1067 | + val |
||
1068 | > b2->max.v[2]) { |
||
1069 | return 0; |
||
1070 | } |
||
1071 | |||
1072 | val = M->m[0][1] * b1->min.v[0] + M->m[1][1] * b1->min.v[1] + M->m[2][1] * b1->min.v[2] + M->m[3][1]; |
||
1073 | if ((M->m[0][1] <= 0.0f ? 0.0f : M->m[0][1] * o.v[0]) |
||
1074 | + (M->m[1][1] <= 0.0f ? 0.0f : M->m[1][1] * o.v[1]) |
||
1075 | + (M->m[2][1] <= 0.0f ? 0.0f : M->m[2][1] * o.v[2]) |
||
1076 | + val |
||
1077 | < b2->min.v[1]) { |
||
1078 | return 0; |
||
1079 | } |
||
1080 | if ((M->m[0][1] < 0.0 ? M->m[0][1] * o.v[0] : 0.0) |
||
1081 | + (M->m[1][1] < 0.0 ? M->m[1][1] * o.v[1] : 0.0) |
||
1082 | + (M->m[2][1] < 0.0 ? M->m[2][1] * o.v[2] : 0.0) |
||
1083 | + val |
||
1084 | > b2->max.v[1]) { |
||
1085 | return 0; |
||
1086 | } |
||
1087 | |||
1088 | return 1; |
||
1089 | } |
||
1090 | |||
1091 | // IDA: int __usercall LineBoxColl@<EAX>(br_vector3 *o@<EAX>, br_vector3 *p@<EDX>, br_bounds *pB@<EBX>, br_vector3 *pHit_point@<ECX>) |
||
1092 | int LineBoxColl(br_vector3* o, br_vector3* p, br_bounds* pB, br_vector3* pHit_point) { |
||
1093 | br_vector3 dir; |
||
1094 | int inside; |
||
1095 | int quad[3]; |
||
1096 | int i; |
||
1097 | int which_plane; |
||
1098 | br_scalar max_t[3]; |
||
1099 | br_scalar cp[3]; |
||
1100 | LOG_TRACE("(%p, %p, %p, %p)", o, p, pB, pHit_point); |
||
1101 | |||
1102 | inside = 1; |
||
1103 | BrVector3Sub(&dir, p, o); |
||
1104 | for (i = 0; i < 3; ++i) { |
||
1105 | if (pB->min.v[i] <= o->v[i]) { |
||
1106 | if (pB->max.v[i] >= o->v[i]) { |
||
1107 | quad[i] = 2; |
||
1108 | } else { |
||
1109 | quad[i] = 0; |
||
1110 | max_t[i] = pB->max.v[i]; |
||
1111 | inside = 0; |
||
1112 | } |
||
1113 | } else { |
||
1114 | quad[i] = 1; |
||
1115 | max_t[i] = pB->min.v[i]; |
||
1116 | inside = 0; |
||
1117 | } |
||
1118 | } |
||
1119 | if (inside) { |
||
1120 | BrVector3Copy(pHit_point, o); |
||
1121 | return 8; |
||
1122 | } else { |
||
1123 | for (i = 0; i < 3; ++i) { |
||
1124 | if (quad[i] == 2 || dir.v[i] == 0.0) { |
||
1125 | cp[i] = -1.0; |
||
1126 | } else { |
||
1127 | cp[i] = (max_t[i] - o->v[i]) / dir.v[i]; |
||
1128 | } |
||
1129 | } |
||
1130 | which_plane = 0; |
||
1131 | for (i = 1; i < 3; ++i) { |
||
1132 | if (cp[which_plane] < cp[i]) { |
||
1133 | which_plane = i; |
||
1134 | } |
||
1135 | } |
||
1136 | if (cp[which_plane] >= 0.0 && cp[which_plane] <= 1.0) { |
||
1137 | for (i = 0; i < 3; ++i) { |
||
1138 | if (which_plane == i) { |
||
1139 | pHit_point->v[i] = max_t[i]; |
||
1140 | } else { |
||
1141 | pHit_point->v[i] = dir.v[i] * cp[which_plane] + o->v[i]; |
||
1142 | if (pHit_point->v[i] < pB->min.v[i] || pB->max.v[i] < pHit_point->v[i]) { |
||
1143 | return 0; |
||
1144 | } |
||
1145 | } |
||
1146 | } |
||
1147 | return which_plane + 4 * quad[which_plane] + 1; |
||
1148 | } else { |
||
1149 | return 0; |
||
1150 | } |
||
1151 | } |
||
1152 | } |
||
1153 | |||
1154 | // IDA: int __usercall SphereBoxIntersection@<EAX>(br_bounds *pB@<EAX>, br_vector3 *pC@<EDX>, br_scalar pR_squared, br_vector3 *pHit_point) |
||
1155 | int SphereBoxIntersection(br_bounds* pB, br_vector3* pC, br_scalar pR_squared, br_vector3* pHit_point) { |
||
1156 | int i; |
||
1157 | br_scalar d; |
||
1158 | LOG_TRACE("(%p, %p, %f, %p)", pB, pC, pR_squared, pHit_point); |
||
1159 | |||
1160 | d = 0.f; |
||
1161 | for (i = 0; i < 3; i++) { |
||
1162 | if (pC->v[i] <= pB->min.v[i]) { |
||
1163 | pHit_point->v[i] = pB->min.v[i]; |
||
1164 | } else if (pC->v[i] > pB->max.v[i]) { |
||
1165 | pHit_point->v[i] = pB->max.v[i]; |
||
1166 | } else { |
||
1167 | pHit_point->v[i] = pC->v[i]; |
||
1168 | } |
||
1169 | d += (pC->v[i] - pHit_point->v[i]) * (pC->v[i] - pHit_point->v[i]); |
||
1170 | } |
||
1171 | return d <= pR_squared; |
||
1172 | } |
||
1173 | |||
1174 | // IDA: int __usercall LineBoxCollWithSphere@<EAX>(br_vector3 *o@<EAX>, br_vector3 *p@<EDX>, br_bounds *pB@<EBX>, br_vector3 *pHit_point@<ECX>) |
||
1175 | int LineBoxCollWithSphere(br_vector3* o, br_vector3* p, br_bounds* pB, br_vector3* pHit_point) { |
||
1176 | int i; |
||
1177 | int plane; |
||
1178 | LOG_TRACE("(%p, %p, %p, %p)", o, p, pB, pHit_point); |
||
1179 | |||
1180 | plane = LineBoxColl(o, p, pB, pHit_point); |
||
1181 | |||
1182 | if (plane != 0) { |
||
1183 | return plane; |
||
1184 | } |
||
1185 | if (!SphereBoxIntersection(pB, p, 2.5e-5f, pHit_point)) { |
||
1186 | return 0; |
||
1187 | } |
||
1188 | for (i = 0; i < 3; i++) { |
||
1189 | if (pB->max.v[i] == pHit_point->v[i] && p->v[i] <= o->v[i]) { |
||
1190 | return i + 1; |
||
1191 | } |
||
1192 | if (pHit_point->v[i] == pB->min.v[i] && p->v[i] >= o->v[i]) { |
||
1193 | return i + 5; |
||
1194 | } |
||
1195 | } |
||
1196 | return 0; |
||
1197 | } |
||
1198 | |||
1199 | // IDA: int __usercall CompVert@<EAX>(int v1@<EAX>, int v2@<EDX>) |
||
1200 | int CompVert(int v1, int v2) { |
||
20 | pmbaty | 1201 | //br_vertex* vl; // Pierre-Marie Baty -- unused variable |
1202 | //br_vector3 tv; // Pierre-Marie Baty -- unused variable |
||
1203 | //br_vector2 tv2; // Pierre-Marie Baty -- unused variable |
||
1 | pmbaty | 1204 | LOG_TRACE("(%d, %d)", v1, v2); |
20 | pmbaty | 1205 | NOT_IMPLEMENTED(); |
1 | pmbaty | 1206 | } |
1207 | |||
1208 | // IDA: void __usercall SetFacesGroup(int pFace@<EAX>) |
||
1209 | void SetFacesGroup(int pFace) { |
||
1210 | //int f; // Pierre-Marie Baty -- unused variable |
||
1211 | //int v; // Pierre-Marie Baty -- unused variable |
||
1212 | //int i; // Pierre-Marie Baty -- unused variable |
||
1213 | LOG_TRACE("(%d)", pFace); |
||
1214 | NOT_IMPLEMENTED(); |
||
1215 | } |
||
1216 | |||
1217 | // IDA: void __usercall SelectFace(br_vector3 *pDir@<EAX>) |
||
1218 | void SelectFace(br_vector3* pDir) { |
||
1219 | //tCar_spec* c; // Pierre-Marie Baty -- unused variable |
||
1220 | //br_vector3 dir; // Pierre-Marie Baty -- unused variable |
||
1221 | //br_vector3 normal; // Pierre-Marie Baty -- unused variable |
||
1222 | //br_scalar t; // Pierre-Marie Baty -- unused variable |
||
1223 | //br_model* old_model; // Pierre-Marie Baty -- unused variable |
||
1224 | //int i; // Pierre-Marie Baty -- unused variable |
||
1225 | LOG_TRACE("(%p)", pDir); |
||
1226 | NOT_IMPLEMENTED(); |
||
1227 | } |
||
1228 | |||
1229 | // IDA: void __usercall GetTilingLimits(br_vector2 *min@<EAX>, br_vector2 *max@<EDX>) |
||
1230 | void GetTilingLimits(br_vector2* min, br_vector2* max) { |
||
20 | pmbaty | 1231 | //int f; // Pierre-Marie Baty -- unused variable |
1232 | //int i; // Pierre-Marie Baty -- unused variable |
||
1233 | //int j; // Pierre-Marie Baty -- unused variable |
||
1234 | //br_vertex* verts; // Pierre-Marie Baty -- unused variable |
||
1235 | //br_face* faces; // Pierre-Marie Baty -- unused variable |
||
1 | pmbaty | 1236 | LOG_TRACE("(%p, %p)", min, max); |
20 | pmbaty | 1237 | NOT_IMPLEMENTED(); |
1 | pmbaty | 1238 | } |
1239 | |||
1240 | // IDA: void __usercall Scale(int pD@<EAX>, int factor@<EDX>) |
||
1241 | void Scale(int pD, int factor) { |
||
20 | pmbaty | 1242 | //br_vector2 min; // Pierre-Marie Baty -- unused variable |
1243 | //br_vector2 max; // Pierre-Marie Baty -- unused variable |
||
1244 | //int f; // Pierre-Marie Baty -- unused variable |
||
1245 | //int v; // Pierre-Marie Baty -- unused variable |
||
1246 | //br_scalar d; // Pierre-Marie Baty -- unused variable |
||
1247 | //br_vertex* verts; // Pierre-Marie Baty -- unused variable |
||
1248 | //br_face* faces; // Pierre-Marie Baty -- unused variable |
||
1 | pmbaty | 1249 | LOG_TRACE("(%d, %d)", pD, factor); |
20 | pmbaty | 1250 | NOT_IMPLEMENTED(); |
1 | pmbaty | 1251 | } |
1252 | |||
1253 | // IDA: void __cdecl ScaleUpX() |
||
1254 | void ScaleUpX(void) { |
||
1255 | LOG_TRACE("()"); |
||
20 | pmbaty | 1256 | NOT_IMPLEMENTED(); |
1 | pmbaty | 1257 | } |
1258 | |||
1259 | // IDA: void __cdecl ScaleDnX() |
||
1260 | void ScaleDnX(void) { |
||
1261 | LOG_TRACE("()"); |
||
20 | pmbaty | 1262 | NOT_IMPLEMENTED(); |
1 | pmbaty | 1263 | } |
1264 | |||
1265 | // IDA: void __cdecl ScaleUpY() |
||
1266 | void ScaleUpY(void) { |
||
1267 | LOG_TRACE("()"); |
||
20 | pmbaty | 1268 | NOT_IMPLEMENTED(); |
1 | pmbaty | 1269 | } |
1270 | |||
1271 | // IDA: void __cdecl ScaleDnY() |
||
1272 | void ScaleDnY(void) { |
||
1273 | LOG_TRACE("()"); |
||
20 | pmbaty | 1274 | NOT_IMPLEMENTED(); |
1 | pmbaty | 1275 | } |
1276 | |||
1277 | // IDA: void __cdecl SelectFaceForward() |
||
1278 | void SelectFaceForward(void) { |
||
20 | pmbaty | 1279 | //br_vector3 dir; // Pierre-Marie Baty -- unused variable |
1 | pmbaty | 1280 | LOG_TRACE("()"); |
20 | pmbaty | 1281 | NOT_IMPLEMENTED(); |
1 | pmbaty | 1282 | } |
1283 | |||
1284 | // IDA: void __cdecl SelectFaceDown() |
||
1285 | void SelectFaceDown(void) { |
||
20 | pmbaty | 1286 | //br_vector3 dir; // Pierre-Marie Baty -- unused variable |
1 | pmbaty | 1287 | LOG_TRACE("()"); |
20 | pmbaty | 1288 | NOT_IMPLEMENTED(); |
1 | pmbaty | 1289 | } |