Mario Kart 64
Loading...
Searching...
No Matches
path_calc.inc.c
Go to the documentation of this file.
1// @arg index from 0 to 3.
2
3// Processes course path by index.
4// @arg index from 0 to 3.
5// Each course can have 1-4 course paths.
6void load_track_path(s32 pathIndex) {
7
9 TrackPathPoint* pathDest;
10 TrackPathPoint* path;
11 s32 var_v0;
12 s32 sp24;
13 UNUSED s32 pad[2];
14 s16 bInvalidPath;
15 s32 i;
16
17 // cast required
19 pathDest = gTrackPaths[pathIndex];
20 bInvalidPath = 1;
22 var_v0 = process_path_data(pathDest, GET_COURSE_PathTable2(pathIndex));
23 gPathCountByPathIndex[pathIndex] = (u16) var_v0;
24 } else {
25 // Course path included in course_data which has already been loaded into memory.
26 // This is how we get the addr to our path data.
27 path = GET_COURSE_PathTable(pathIndex);
28 ptr = path;
29
30 for (i = 0; i < 3000; i++, ptr++) {
31 if ((u16) ptr->posX == 0x8000) {
32 sp24 = i - 1;
33 bInvalidPath = 0;
34 break;
35 }
36 }
37
38 // If path data higher than 3000 something has gone wrong.
39 // Skip processing the data.
41 if (!bInvalidPath) {
42 var_v0 = func_80011014(pathDest, path, sp24, pathIndex);
43 gPathCountByPathIndex[pathIndex] = (u16) var_v0;
44 }
45 }
46 }
47}
48
50 f32 pathPointWidth;
51 f32 x1;
52 f32 y1;
53 f32 z1;
54 f32 x2;
55 f32 y2;
56 f32 z2;
57 f32 x_dist;
58 f32 z_dist;
59 f32 neg_x_dist;
60 f32 neg_z_dist;
61 f32 xz_dist;
62 s32 temp_f16;
63 s32 pathPointIndex;
64 TrackPathPoint* pathPoint;
65 TrackPathPoint* nextPathPoint;
66 TrackPathPoint* var_s1;
67 TrackPathPoint* var_s2;
68
70 pathPointWidth = GET_COURSE_AIMaximumSeparation;
71 pathPoint = &gTrackPaths[pathIndex][0];
72 var_s1 = &gTrackLeftPaths[pathIndex][0];
73 var_s2 = &gTrackRightPaths[pathIndex][0];
74 for (pathPointIndex = 0; pathPointIndex < gPathCountByPathIndex[pathIndex];
75 pathPointIndex++, var_s1++, var_s2++) {
76 x1 = pathPoint->posX;
77 y1 = pathPoint->posY;
78 z1 = pathPoint->posZ;
79 pathPoint++;
80 nextPathPoint = &gTrackPaths[pathIndex][(pathPointIndex + 1) % ((s32) gPathCountByPathIndex[pathIndex])];
81 x2 = nextPathPoint->posX;
82 y2 = nextPathPoint->posY;
83 z2 = nextPathPoint->posZ;
84 x_dist = x2 - x1;
85 z_dist = z2 - z1;
86 neg_x_dist = x1 - x2;
87 neg_z_dist = z1 - z2;
88 xz_dist = sqrtf((x_dist * x_dist) + (z_dist * z_dist));
89 temp_f16 = (f32) ((y1 + y2) * 0.5);
90
91 // Calculate left boundary position
92 // Uses perpendicular vector (Z, -X) normalized by segment length
93 var_s1->posX = ((pathPointWidth * z_dist) / xz_dist) + x1;
94 var_s1->posY = temp_f16;
95 var_s1->posZ = ((pathPointWidth * neg_x_dist) / xz_dist) + z1;
96
97 // Calculate right boundary position
98 // Uses opposite perpendicular vector (-Z, X)
99 var_s2->posX = ((pathPointWidth * neg_z_dist) / xz_dist) + x1;
100 var_s2->posY = temp_f16;
101 var_s2->posZ = ((pathPointWidth * x_dist) / xz_dist) + z1;
102 }
103 }
104}
105
117f32 calculate_track_curvature(s32 pathIndex, u16 pathPointIndex) {
118 f32 secondVectorX;
119 f32 secondVectorZ;
120 UNUSED f32 pad;
121 TrackPathPoint* pathPathPoints;
122 f32 x1;
123 f32 z1;
124 f32 x2;
125 f32 z2;
126 f32 x3;
127 f32 z3;
128 f32 firstVectorX;
129 f32 firstVectorZ;
130 s32 pathPointCount;
131 TrackPathPoint* pathPoint3;
132 TrackPathPoint* pathPoint2;
133 TrackPathPoint* pathPoint1;
134 f32 secondLength;
135 f32 firstLength;
136
138 return 0.0f;
139 }
140 pathPointCount = gPathCountByPathIndex[pathIndex];
141 pathPathPoints = gTrackPaths[pathIndex];
142
143 pathPoint1 = &pathPathPoints[pathPointIndex];
144 pathPoint2 = &pathPathPoints[(pathPointIndex + 1) % pathPointCount];
145 pathPoint3 = &pathPathPoints[(pathPointIndex + 2) % pathPointCount];
146
147 x1 = pathPoint1->posX;
148 z1 = pathPoint1->posZ;
149 x2 = pathPoint2->posX;
150 z2 = pathPoint2->posZ;
151 x3 = pathPoint3->posX;
152 z3 = pathPoint3->posZ;
153
154 firstVectorX = (((x2 + x3) * 0.5) - x1);
155 firstVectorZ = (((z2 + z3) * 0.5) - z1);
156
157 pathPoint1 = &pathPathPoints[(pathPointIndex + 3) % pathPointCount];
158 pathPoint2 = &pathPathPoints[(pathPointIndex + 4) % pathPointCount];
159 pathPoint3 = &pathPathPoints[(pathPointIndex + 5) % pathPointCount];
160
161 x1 = pathPoint1->posX;
162 z1 = pathPoint1->posZ;
163 x2 = pathPoint2->posX;
164 z2 = pathPoint2->posZ;
165 x3 = pathPoint3->posX;
166 z3 = pathPoint3->posZ;
167
168 secondVectorX = (((x2 + x3) * 0.5) - x1);
169 secondVectorZ = (((z2 + z3) * 0.5) - z1);
170
171 firstLength = sqrtf((firstVectorZ * firstVectorZ) + (firstVectorX * firstVectorX));
172 secondLength = sqrtf((secondVectorX * secondVectorX) + (secondVectorZ * secondVectorZ));
173 return -((firstVectorZ * secondVectorX) - (firstVectorX * secondVectorZ)) / (secondLength * firstLength);
174}
175
176void analize_track_section(s32 pathIndex) {
177 f64 sectionCurvature;
178 UNUSED s32 pad;
179 s32 k;
180 s32 i;
181 s32 j;
182 s16* currentSection;
183 s32 pathPointCount;
184 s16* nextSection;
185
187 pathPointCount = gPathCountByPathIndex[pathIndex];
188 currentSection = gTrackSectionTypes[pathIndex];
189 for (i = 0; i < pathPointCount; i++, currentSection++) {
190 sectionCurvature = calculate_track_curvature(pathIndex, i);
191 *currentSection = STRAIGHT;
192 if (sectionCurvature > 0.1) {
193 *currentSection = RIGHT_CURVE;
194 }
195 if (sectionCurvature < -0.1) {
196 *currentSection = LEFT_CURVE;
197 }
198 }
199 currentSection = gTrackSectionTypes[pathIndex];
200 for (i = 0; i < pathPointCount; i++, currentSection++) {
201 if (*currentSection == STRAIGHT) {
202 // Look ahead for next curved section
203 for (j = 1; j < pathPointCount; j++) {
204 nextSection = &gTrackSectionTypes[pathIndex][(i + j) % pathPointCount];
205 switch (*nextSection) {
207 case RIGHT_CURVE:
208 for (k = 0; k < j; k++) {
209 gTrackSectionTypes[pathIndex][(i + k) % pathPointCount] = RIGHT_LEANING_CURVE;
210 }
211 i += j;
212 currentSection += j;
213 j = pathPointCount;
214 break;
216 case LEFT_CURVE:
217 for (k = 0; k < j; k++) {
218 gTrackSectionTypes[pathIndex][(i + k) % pathPointCount] = LEFT_LEANING_CURVE;
219 }
220 i += j;
221 currentSection += j;
222 j = pathPointCount;
223 break;
224 }
225 }
226 }
227 }
228 }
229}
230
231// Seemingly calculates the atan2 angle between a pathPoint and its forward neighbor
232s16 calculate_angle_path(s32 pathIndex, s32 pathPointIndex) {
233 s16 ret;
234 Vec3f sp30;
235 Vec3f sp24;
236 TrackPathPoint* temp_v0;
237
238 temp_v0 = &gTrackPaths[pathIndex][pathPointIndex];
239 sp30[0] = temp_v0->posX;
240 sp30[1] = temp_v0->posY;
241 sp30[2] = temp_v0->posZ;
242 temp_v0 = &gTrackPaths[pathIndex][(pathPointIndex + 1) % gPathCountByPathIndex[pathIndex]];
243 sp24[0] = temp_v0->posX;
244 sp24[1] = temp_v0->posY;
245 sp24[2] = temp_v0->posZ;
246 ret = get_angle_between_two_vectors(sp30, sp24);
247 return -ret;
248}
249
250// Populates gPathExpectedRotation
251void analyse_angle_path(s32 pathIndex) {
252 s32 pathPointIndex;
253 u16* angle;
254
256 for (angle = (u16*) &gPathExpectedRotation[pathIndex][0], pathPointIndex = 0;
257 pathPointIndex < gPathCountByPathIndex[pathIndex]; pathPointIndex++, angle++) {
258 *angle = calculate_angle_path(pathIndex, pathPointIndex);
259 }
260 }
261}
262
263void analisze_curved_path(s32 pathIndex) {
264 s16* trackCurveCount;
265 s16 curveCount;
266 s16 temp_t0;
267 s32 pathPointCount;
268 s16* trackSectionType;
269 s32 i, j;
270
271 pathPointCount = gPathCountByPathIndex[pathIndex];
272 trackSectionType = gTrackSectionTypes[pathIndex];
273 trackCurveCount = gTrackConsecutiveCurveCounts[pathIndex];
274
275 for (i = 0; i < pathPointCount; i++) {
276 curveCount = 0;
277 for (j = 0; j < pathPointCount; j++) {
278 temp_t0 = trackSectionType[(i + j) % pathPointCount];
279 if ((temp_t0 == LEFT_LEANING_CURVE) || (temp_t0 == RIGHT_LEANING_CURVE)) {
280 curveCount += 1;
281 } else {
282 break;
283 }
285 break;
286 }
287 }
288 *trackCurveCount = curveCount;
289 trackCurveCount++;
290 }
291}
292
293f32 func_80010F40(f32 arg0, f32 arg1, f32 arg2, UNUSED s32 arg3, UNUSED s32 arg4) {
294 arg1 = get_surface_height(arg0, 2000.0f, arg2);
295 check_bounding_collision(&D_80162E70, 1.0f, arg0, arg1, arg2);
296 return arg1;
297}
298
299f32 func_80010FA0(f32 arg0, f32 arg1, f32 arg2, UNUSED s32 arg3, UNUSED s32 arg4) {
300 arg1 = get_surface_height(arg0, (f32) ((f64) arg1 + 30.0), arg2);
301 check_bounding_collision(&D_80162E70, 10.0f, arg0, arg1, arg2);
302 return arg1;
303}
304
308s32 func_80011014(TrackPathPoint* pathDest, TrackPathPoint* path, s32 numPathPoints, UNUSED s32 pathIndex) {
309 f32 temp_f24_2;
310 f32 temp_f2_3;
311 f32 var_f20_2;
312 f32 x1;
313 f32 z1;
314 f32 x2;
315 f32 z2;
316 f32 x3;
317 f32 z3;
318 f32 x1_2;
319 f32 z1_3;
320 f32 temp_f20;
321 f32 var_f30;
322 f32 temp_f22;
323 f32 temp_f16;
324 s32 i;
325
326 f32 j;
327 s32 var_s0;
328 f32 var_f28;
329
330 TrackPathPoint* point1;
331 TrackPathPoint* point2;
332 TrackPathPoint* point3;
333 f32 temp;
335 var_f30 = 0.0f;
336 var_s0 = 0;
337 temp_f20 = (f32) path[0].posX;
338 temp_f22 = (f32) path[0].posZ;
339 var_f28 = func_80010F40(temp_f20, 2000.0f, temp_f22, gCurrentCourseId, 0);
340
341 for (i = 0; i < numPathPoints; i++) {
342 point1 = &path[i % numPathPoints];
343 point2 = &path[(i + 1) % numPathPoints];
344 point3 = &path[(s32) (i + 2) % numPathPoints];
345 x1 = (f32) point1->posX;
346 z1 = (f32) point1->posZ;
347 x2 = (f32) point2->posX;
348 z2 = (f32) point2->posZ;
349 x3 = (f32) point3->posX;
350 z3 = (f32) point3->posZ;
351
352 temp = 0.05 / (sqrtf(((x2 - x1) * (x2 - x1)) + ((z2 - z1) * (z2 - z1))) +
353 (sqrtf(((x3 - x2) * (x3 - x2)) + ((z3 - z2) * (z3 - z2)))));
354
355 for (j = 0.0f; j <= 1.0; j += temp) {
356
357 temp_f2_3 = (f32) ((1.0 - j) * 0.5 * (1.0 - j));
358 z1_3 = (f32) (((1.0 - j) * j) + 0.5);
359 temp_f16 = (f32) (j * 0.5 * j);
360
361 temp_f24_2 = (temp_f2_3 * x1) + (z1_3 * x2) + (temp_f16 * x3);
362 x1_2 = (temp_f2_3 * z1) + (z1_3 * z2) + (temp_f16 * z3);
363
364 var_f30 +=
365 sqrtf(((temp_f24_2 - temp_f20) * (temp_f24_2 - temp_f20)) + ((x1_2 - temp_f22) * (x1_2 - temp_f22)));
366
367 temp_f20 = temp_f24_2;
368 temp_f22 = x1_2;
369
370 if ((var_f30 > 20.0f) || ((i == 0) && (j == 0.0))) {
371 if (gIsMirrorMode) {
372 // temp_f12 = -temp_f24_2;
373 pathDest->posX = (s16) -temp_f24_2;
374 var_f20_2 = func_80010FA0(-temp_f24_2, var_f28, x1_2, gCurrentCourseId, var_s0);
375 } else {
376 pathDest->posX = (s16) temp_f24_2;
377 var_f20_2 = func_80010FA0(temp_f24_2, var_f28, x1_2, gCurrentCourseId, var_s0);
378 }
379
380 pathDest->posZ = (s16) temp_f22;
382
383 if (var_f20_2 < -500.0) {
384 var_f20_2 = var_f28;
385 } else {
386
387 switch (gCurrentCourseId) {
389 if (var_f20_2 < (var_f28 - 15.0)) {
390 var_f20_2 = (f32) var_f28 - 15.0;
391 }
392 break;
394 if ((var_s0 >= 1140) && (var_s0 <= 1152)) {
395 var_f20_2 = var_f28;
396 } else {
397 if (var_f20_2 < (var_f28 - 10.0)) {
398 var_f20_2 = (f32) (var_f28 - 4.0);
399 }
400 }
401 break;
402 case COURSE_DK_JUNGLE:
403 if ((var_s0 > 204) && (var_s0 < 220)) {
404 var_f20_2 = var_f28;
405 } else {
406 if (var_f20_2 < (var_f28 - 10.0)) {
407 var_f20_2 = (f32) (var_f28 - 4.0);
408 }
409 }
410 break;
411 default:
412 if (var_f20_2 < (var_f28 - 10.0)) {
413 var_f20_2 = (f32) var_f28 - 10.0;
414 }
415 break;
416 }
417 }
418 var_f28 = var_f20_2;
419 pathDest->posY = (s16) (s32) var_f20_2;
420 var_f30 = 0.0f;
421 pathDest++;
422 var_s0 += 1;
423 }
424 }
425 }
426 return var_s0;
427}
428
429// Returns number of path processed.
431 s16 temp_a0;
432 s16 temp_a2;
433 s16 temp_a3;
434 s32 var_v0;
435 s32 var_v1;
436 u16 temp_t0;
437
438 var_v1 = 0;
439 for (var_v0 = 0; var_v0 < 0x7D0; var_v0++) {
440 temp_a0 = src->posX;
441 temp_a2 = src->posY;
442 temp_a3 = src->posZ;
443 temp_t0 = src->trackSectionId;
444 src++;
445 if (((temp_a0 & 0xFFFF) == 0x8000) && ((temp_a2 & 0xFFFF) == 0x8000) && ((temp_a3 & 0xFFFF) == 0x8000)) {
446 break;
447 }
448 if (gIsMirrorMode != 0) {
449 dest->posX = -temp_a0;
450 } else {
451 dest->posX = temp_a0;
452 }
453 var_v1++;
454 dest->posY = temp_a2;
455 dest->posZ = temp_a3;
456 dest->trackSectionId = temp_t0;
457 dest++;
458 }
459 return var_v1;
460}
461
462s32 generate_2d_path(Path2D* pathDest, TrackPathPoint* pathSrc, s32 numPathPoints) {
463 f32 temp_f14_3;
464 f32 temp_f16_2;
465 UNUSED s32 pad;
466
467 f32 x1;
468 f32 z1;
469 f32 x2;
470 f32 z2;
471 f32 x3;
472 f32 z3;
473
474 UNUSED s32 pad2;
475 f32 temp_f24;
476
477 f32 spA8;
478 f32 temp_f26;
479 f32 spA0;
480
481 f32 temp_f2_3;
482
483 TrackPathPoint* point1;
484 f32 j;
485 TrackPathPoint* point2;
486 TrackPathPoint* point3;
487 s32 i;
488 f32 temp_f6 = 0.0f;
489 s32 nbElement;
490 f32 sp7C;
491
492 spA8 = pathSrc[0].posX;
493 spA0 = pathSrc[0].posZ;
494 nbElement = 0;
495
496 for (i = 0; i < numPathPoints; i++) {
497 point1 = &pathSrc[((i % numPathPoints))];
498 point2 = &pathSrc[(((i + 1) % numPathPoints))];
499 point3 = &pathSrc[(((i + 2) % numPathPoints))];
500 x1 = point1->posX;
501 z1 = point1->posZ;
502 x2 = point2->posX;
503 z2 = point2->posZ;
504 x3 = point3->posX;
505 z3 = point3->posZ;
506
507 sp7C = 0.05 / (sqrtf(((x2 - x1) * (x2 - x1)) + ((z2 - z1) * (z2 - z1))) +
508 sqrtf(((x3 - x2) * (x3 - x2)) + ((z3 - z2) * (z3 - z2))));
509
510 for (j = 0.0f; j <= 1.0; j += sp7C) {
511 temp_f2_3 = (1.0 - j) * 0.5 * (1.0 - j);
512 temp_f14_3 = ((1.0 - j) * j) + 0.5;
513 temp_f16_2 = j * 0.5 * j;
514
515 temp_f24 = (temp_f2_3 * x1) + (temp_f14_3 * x2) + (temp_f16_2 * x3);
516 temp_f26 = (temp_f2_3 * z1) + (temp_f14_3 * z2) + (temp_f16_2 * z3);
517 temp_f6 += sqrtf(((temp_f24 - spA8) * (temp_f24 - spA8)) + ((temp_f26 - spA0) * (temp_f26 - spA0)));
518 spA8 = temp_f24;
519 spA0 = temp_f26;
520 if ((temp_f6 > 20.0f) || ((i == 0) && (j == 0.0))) {
521 if (gIsMirrorMode) {
522 pathDest->x = (s16) -spA8;
523 } else {
524 pathDest->x = (s16) spA8;
525 }
526 pathDest->z = spA0;
527 nbElement += 1;
528 pathDest++;
529 temp_f6 = 0.0f;
530 }
531 }
532 }
533 return nbElement;
534}
s16 gCurrentCourseId
Definition code_800029B0.c:30
s32 gIsMirrorMode
Definition code_800029B0.c:64
s16 get_track_section_id(u16 index)
Definition collision.c:509
u16 check_bounding_collision(Collision *collision, f32 boundingBoxSize, f32 posX, f32 posY, f32 posZ)
Definition collision.c:1358
f32 get_surface_height(f32 posX, f32 posY, f32 posZ)
Returns the height of the surface below the provided position. Used to set actors onto the course mes...
Definition collision.c:1470
f32 Vec3f[3]
Definition common_structs.h:6
#define GET_COURSE_PathTable2(p)
Definition course.h:97
@ COURSE_WARIO_STADIUM
Definition course.h:45
@ COURSE_RAINBOW_ROAD
Definition course.h:44
@ COURSE_DK_JUNGLE
Definition course.h:49
@ COURSE_AWARD_CEREMONY
Definition course.h:51
#define GET_COURSE_AIMaximumSeparation
Definition course.h:87
#define GET_COURSE_PathTable(p)
Definition course.h:95
Collision D_80162E70
Definition cpu_vehicles_camera_path.c:36
u16 gPathCountByPathIndex[4]
Definition cpu_vehicles_camera_path.c:181
s16 * gTrackSectionTypes[4]
Definition cpu_vehicles_camera_path.c:177
s16 * gPathExpectedRotation[4]
Definition cpu_vehicles_camera_path.c:178
TrackPathPoint * gTrackPaths[4]
Definition cpu_vehicles_camera_path.c:174
TrackPathPoint * gTrackRightPaths[4]
Definition cpu_vehicles_camera_path.c:176
s16 * gTrackConsecutiveCurveCounts[4]
Definition cpu_vehicles_camera_path.c:179
TrackPathPoint * gTrackLeftPaths[4]
Definition cpu_vehicles_camera_path.c:175
#define j
#define UNUSED
Definition macros.h:23
float sqrtf(float)
s32 get_angle_between_two_vectors(Vec3f arg0, Vec3f arg1)
Definition math_util.c:84
@ STRAIGHT
Definition path.h:18
@ RIGHT_LEANING_CURVE
Definition path.h:14
@ RIGHT_CURVE
Definition path.h:16
@ LEFT_LEANING_CURVE
Definition path.h:15
@ LEFT_CURVE
Definition path.h:17
s16 calculate_angle_path(s32 pathIndex, s32 pathPointIndex)
Definition path_calc.inc.c:232
void analize_track_section(s32 pathIndex)
Definition path_calc.inc.c:176
void analisze_curved_path(s32 pathIndex)
Definition path_calc.inc.c:263
s32 process_path_data(TrackPathPoint *dest, TrackPathPoint *src)
Definition path_calc.inc.c:430
void calculate_track_boundaries(s32 pathIndex)
Definition path_calc.inc.c:49
s32 generate_2d_path(Path2D *pathDest, TrackPathPoint *pathSrc, s32 numPathPoints)
Definition path_calc.inc.c:462
f32 func_80010F40(f32 arg0, f32 arg1, f32 arg2, UNUSED s32 arg3, UNUSED s32 arg4)
Definition path_calc.inc.c:293
s32 func_80011014(TrackPathPoint *pathDest, TrackPathPoint *path, s32 numPathPoints, UNUSED s32 pathIndex)
Definition path_calc.inc.c:308
f32 calculate_track_curvature(s32 pathIndex, u16 pathPointIndex)
Definition path_calc.inc.c:117
f32 func_80010FA0(f32 arg0, f32 arg1, f32 arg2, UNUSED s32 arg3, UNUSED s32 arg4)
Definition path_calc.inc.c:299
void load_track_path(s32 pathIndex)
Definition path_calc.inc.c:6
void analyse_angle_path(s32 pathIndex)
Definition path_calc.inc.c:251
u16 meshIndexZX
Definition common_structs.h:139
Definition cpu_vehicles_camera_path.h:47
s16 z
Definition cpu_vehicles_camera_path.h:49
s16 x
Definition cpu_vehicles_camera_path.h:48
Definition path.h:6
s16 posX
Definition path.h:7
u16 trackSectionId
Definition path.h:10
s16 posZ
Definition path.h:9
s16 posY
Definition path.h:8
signed int s32
Definition ultratypes.h:15
signed short int s16
Definition ultratypes.h:13
float f32
Definition ultratypes.h:34
double f64
Definition ultratypes.h:35
unsigned short int u16
Definition ultratypes.h:14