Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
cam_mode_zone_interp.c File Reference

Go to the source code of this file.

Macros

#define CAM_INTERP(field)
 

Enumerations

enum  CameraSettingsPtrType { CAMERA_SETTINGS_PTR_MINUS_2 = -2 , CAMERA_SETTINGS_PTR_MINUS_1 = -1 , CAMERA_SETTINGS_PTR_NULL = 0 }
 

Functions

CameraControlSettingstest_ray_zone_aabb (f32 x, f32 y, f32 z)
 
void apply_fixed_orientation (CameraControlSettings *controller, CameraRig *configuration, f32 x, f32 y, f32 z)
 
void update_camera_from_controller (Camera *camera, CameraRig *prevRig, CameraControlSettings **prevSettingsPtr, CameraRig *newRig, CameraControlSettings **curSettingsPtr, f32 x1, f32 y1, f32 z1, f32 x2, f32 y2, f32 z2, f32 *interpAlpha, b32 changingMap, b32 changingZone)
 
void interp_camera_y_position (Camera *camera, f32 targetY)
 
f32 get_maximum_interp_delta (Camera *camera)
 
void set_camera_from_rig (Camera *camera, CameraRig *rig)
 
void update_camera_zone_interp (Camera *camera)
 

Variables

BSS CameraRig CurrentCamRig
 
BSS f32 D_800A08DC
 
BSS f32 D_800A08E0
 
BSS f32 D_800A08E4
 
BSS f32 D_800A08E8
 
BSS f32 D_800A08EC
 

Macro Definition Documentation

◆ CAM_INTERP

#define CAM_INTERP ( field)
Value:
CurrentCamRig.field = \
(camera->prevRig.field * (1.0f - camera->interpAlpha)) + (camera->nextRig.field * camera->interpAlpha)
BSS CameraRig CurrentCamRig

Enumeration Type Documentation

◆ CameraSettingsPtrType

Enumerator
CAMERA_SETTINGS_PTR_MINUS_2 
CAMERA_SETTINGS_PTR_MINUS_1 
CAMERA_SETTINGS_PTR_NULL 

Definition at line 23 of file cam_mode_zone_interp.c.

23 {
27};
@ CAMERA_SETTINGS_PTR_MINUS_1
@ CAMERA_SETTINGS_PTR_MINUS_2
@ CAMERA_SETTINGS_PTR_NULL

Function Documentation

◆ test_ray_zone_aabb()

CameraControlSettings * test_ray_zone_aabb ( f32 x,
f32 y,
f32 z )

Definition at line 10 of file cam_mode_zone_interp.c.

10 {
11 f32 hitX, hitY, hitZ;
12 f32 hitDepth = 32767.0f;
13 f32 nx, ny, nz;
14 s32 zoneID = test_ray_zones(x, y, z, 0.0f, -1.0f, 0.0f, &hitX, &hitY, &hitZ, &hitDepth, &nx, &ny, &nz);
15
16 if (zoneID <= NO_COLLIDER) {
17 return NULL;
18 }
19
20 return gZoneCollisionData.colliderList[zoneID].camSettings;
21}
Collider * colliderList
s32 test_ray_zones(f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ, f32 *hitX, f32 *hitY, f32 *hitZ, f32 *hitDepth, f32 *nx, f32 *ny, f32 *nz)
Definition collision.c:866
#define NO_COLLIDER
Definition macros.h:156
CollisionData gZoneCollisionData
Definition collision.c:36

Referenced by update_camera_zone_interp().

◆ apply_fixed_orientation()

void apply_fixed_orientation ( CameraControlSettings * controller,
CameraRig * configuration,
f32 x,
f32 y,
f32 z )

Definition at line 29 of file cam_mode_zone_interp.c.

30{
31 f32 Ax = controller->points.two.Ax;
32 f32 Az = controller->points.two.Az;
33 f32 Bx = controller->points.two.Bx;
34 f32 Bz = controller->points.two.Bz;
35
36 f32 ABx = (Bx - Ax);
37 f32 ABz = (Bz - Az);
38
39 if (controller->flag) {
40 f32 perpdot = ABx * (z - Bz) - ABz * (x - Bx);
41 f32 dist2 = SQ(ABx) + SQ(ABz);
42
43 // only move camera along the line perpendicular to AB passing through B
44 configuration->targetPos.x = Bx - ABz * (perpdot / dist2);
45 configuration->targetPos.y = y;
46 configuration->targetPos.z = Bz + ABx * (perpdot / dist2);
47 } else {
48 configuration->targetPos.x = x;
49 configuration->targetPos.y = y;
50 configuration->targetPos.z = z;
51 }
52}
union CameraControlSettings::@14 points
#define SQ(x)
Definition macros.h:166

◆ update_camera_from_controller()

void update_camera_from_controller ( Camera * camera,
CameraRig * prevRig,
CameraControlSettings ** prevSettingsPtr,
CameraRig * newRig,
CameraControlSettings ** curSettingsPtr,
f32 x1,
f32 y1,
f32 z1,
f32 x2,
f32 y2,
f32 z2,
f32 * interpAlpha,
b32 changingMap,
b32 changingZone )

Definition at line 54 of file cam_mode_zone_interp.c.

61{
62 CameraControlSettings* prevSettings;
63 CameraControlSettings* curSettings;
64 CameraRig* curRig;
65 f32 dx, dz;
66 f32 x, y, z;
67
68 curRig = prevRig;
69 curSettings = *prevSettingsPtr;
70 x = x1;
71 y = y1;
72 z = z1;
73
74 if ((s32)curSettings != CAMERA_SETTINGS_PTR_MINUS_2 && (s32)curSettings != CAMERA_SETTINGS_PTR_MINUS_1) {
75 if (curSettings == CAMERA_SETTINGS_PTR_NULL) {
76 curRig->targetPos.x = x;
77 curRig->targetPos.y = y;
78 curRig->targetPos.z = z;
79 } else {
80 switch (curSettings->type) {
82 curRig->targetPos.x = x;
83 curRig->targetPos.y = y;
84 curRig->targetPos.z = z;
85 break;
87 break;
89 if (curSettings->flag) {
90 f32 Ax = curSettings->points.two.Ax;
91 f32 Az = curSettings->points.two.Az;
92 f32 Bx = curSettings->points.two.Bx;
93 f32 Bz = curSettings->points.two.Bz;
94
95 f32 ABx = (Bx - Ax);
96 f32 ABz = (Bz - Az);
97
98 f32 perpdot = ABx * (z - Bz) - ABz * (x - Bx);
99 f32 dist2 = SQ(ABx) + SQ(ABz);
100
101 // only move camera along the line perpendicular to AB passing through B
102 curRig->targetPos.x = Bx - ABz * (perpdot / dist2);
103 curRig->targetPos.y = y;
104 curRig->targetPos.z = Bz + ABx * (perpdot / dist2);
105 } else {
106 curRig->targetPos.x = x;
107 curRig->targetPos.y = y;
108 curRig->targetPos.z = z;
109 }
110 break;
112 {
113 f32 Ax = curSettings->points.two.Ax;
114 f32 Az = curSettings->points.two.Az;
115 f32 Bx = curSettings->points.two.Bx;
116 f32 Bz = curSettings->points.two.Bz;
117
118 f32 ABx = Bx - Ax;
119 f32 ABz = Bz - Az;
120
121 // project point onto line
122 f32 t = (ABx * (x - Ax) + ABz * (z - Az)) / (SQ(ABx) + SQ(ABz));
123 f32 Px = Ax + t * ABx;
124 f32 Pz = Az + t * ABz;
125
126 // vector giving orthogonal part (i.e., x = orthoX + Px)
127 f32 orthoX = x - Px;
128 f32 orthoZ = z - Pz;
129
130 // clamp to end points
131 if (t < 0.0f) {
132 Px = Ax;
133 Pz = Az;
134 } else if (t > 1.0f) {
135 Px = Bx;
136 Pz = Bz;
137 }
138 if (!curSettings->flag) {
139 Px += orthoX;
140 Pz += orthoZ;
141 }
142
143 curRig->targetPos.x = Px;
144 curRig->targetPos.y = y;
145 curRig->targetPos.z = Pz;
146 }
147 break;
149 if (curSettings->flag) {
150 f32 Ax = curSettings->points.two.Ax;
151 f32 Az = curSettings->points.two.Az;
152 f32 Bx = curSettings->points.two.Bx;
153 f32 Bz = curSettings->points.two.Bz;
154
155 f32 ABx = Bx - Ax;
156 f32 ABz = Bz - Az;
157 f32 camRadius = sqrtf(SQ(ABx) + SQ(ABz));
158
159 // find radius of a circle containing the sample point centered on point A
160 f32 dx = x - Ax;
161 f32 dz = z - Az;
162 f32 curRadius = sqrtf(SQ(dx) + SQ(dz));
163
164 if (curRadius != 0.0f) {
165 // rescale the radius to equal the length of segment AB
166 curRig->targetPos.x = Ax + dx * (camRadius / curRadius);
167 curRig->targetPos.y = y;
168 curRig->targetPos.z = Az + dz * (camRadius / curRadius);
169 }
170 } else {
171 curRig->targetPos.x = x;
172 curRig->targetPos.y = y;
173 curRig->targetPos.z = z;
174 }
175 break;
179 break;
180 }
181 }
182 }
183
184 curRig = newRig;
185 curSettings = *curSettingsPtr;
186 x = x2;
187 y = y2;
188 z = z2;
189
190 if (curSettings == NULL) {
191 curRig->targetPos.x = x;
192 curRig->targetPos.y = y;
193 curRig->targetPos.z = z;
194 } else {
195 switch (curSettings->type) {
197 curRig->targetPos.x = x;
198 curRig->targetPos.y = y;
199 curRig->targetPos.z = z;
200 break;
202 {
203 f32 Ax = curSettings->points.two.Ax;
204 f32 Az = curSettings->points.two.Az;
205 f32 Bx = curSettings->points.two.Bx;
206 f32 By = curSettings->points.two.By;
207 f32 Bz = curSettings->points.two.Bz;
208
209 f32 ABx = Bx - Ax;
210 f32 ABz = Bz - Az;
211
212 curRig->boomLength = fabsf(curSettings->boomLength);
213 curRig->boomYaw = atan2(0.0f, 0.0f, ABx, ABz);
214 curRig->boomPitch = curSettings->boomPitch;
215 curRig->viewPitch = curSettings->viewPitch;
216 curRig->targetPos.x = Bx;
217 curRig->targetPos.y = By;
218 curRig->targetPos.z = Bz;
220 }
221 break;
223 dx = curSettings->points.two.Bx - curSettings->points.two.Ax;
224 dz = curSettings->points.two.Bz - curSettings->points.two.Az;
225 curRig->boomLength = fabsf(curSettings->boomLength);
226 curRig->boomYaw = atan2(0.0f, 0.0f, dx, dz);
227 curRig->boomPitch = curSettings->boomPitch;
228 curRig->viewPitch = curSettings->viewPitch;
229
230 if (curSettings->flag) {
231 f32 Ax = curSettings->points.two.Ax;
232 f32 Az = curSettings->points.two.Az;
233 f32 Bx = curSettings->points.two.Bx;
234 f32 Bz = curSettings->points.two.Bz;
235
236 f32 ABx = Bx - Ax;
237 f32 ABz = Bz - Az;
238
239 f32 perpdot = ABx * (z - Bz) - ABz * (x - Bx);
240 f32 dist2 = SQ(ABx) + SQ(ABz);
241
242 // only move camera along the line perpendicular to AB passing through B
243 curRig->targetPos.x = Bx - ABz * (perpdot / dist2);
244 curRig->targetPos.y = y;
245 curRig->targetPos.z = Bz + ABx * (perpdot / dist2);
246 } else {
247 curRig->targetPos.x = x;
248 curRig->targetPos.y = y;
249 curRig->targetPos.z = z;
250 }
251
252 if (changingZone) {
253 if (*interpAlpha != 1.0f) {
254 prevSettings = *prevSettingsPtr;
255 if (((s32)prevSettings != CAMERA_SETTINGS_PTR_MINUS_2
256 && (s32)prevSettings != CAMERA_SETTINGS_PTR_MINUS_1
257 && (s32)prevSettings != CAMERA_SETTINGS_PTR_NULL)
258 && prevSettings->type == curSettings->type
259 && prevSettings->boomLength == curSettings->boomLength
260 && prevSettings->boomPitch == curSettings->boomPitch
261 && prevSettings->viewPitch == curSettings->viewPitch
262 && prevSettings->flag != curSettings->flag
263 ) {
264 *interpAlpha = 1.0f;
265 }
266 }
267 }
268 break;
270 {
271 f32 Ax = curSettings->points.two.Ax;
272 f32 Az = curSettings->points.two.Az;
273 f32 Bx = curSettings->points.two.Bx;
274 f32 Bz = curSettings->points.two.Bz;
275
276 f32 ABx = Bx - Ax;
277 f32 ABz = Bz - Az;
278
279 curRig->boomLength = fabsf(curSettings->boomLength);
280 curRig->boomYaw = atan2(0.0f, 0.0f, ABz, -ABx);
281 curRig->boomPitch = curSettings->boomPitch;
282 curRig->viewPitch = curSettings->viewPitch;
283
284 // project point onto line
285 f32 t = (ABx * (x - Ax) + ABz * (z - Az)) / (SQ(ABx) + SQ(ABz));
286 f32 Px = Ax + t * ABx;
287 f32 Pz = Az + t * ABz;
288
289 // vector giving orthogonal part (i.e., x = orthoX + Px)
290 f32 orthoX = x - Px;
291 f32 orthoZ = z - Pz;
292
293 // clamp to end points
294 if (t < 0.0f) {
295 Px = Ax;
296 Pz = Az;
297 } else if (t > 1.0f) {
298 Px = Bx;
299 Pz = Bz;
300 }
301 if (!curSettings->flag) {
302 Px += orthoX;
303 Pz += orthoZ;
304 }
305
306 curRig->targetPos.x = Px;
307 curRig->targetPos.y = y;
308 curRig->targetPos.z = Pz;
309
310 if (changingZone) {
311 if (*interpAlpha != 1.0f) {
312 prevSettings = *prevSettingsPtr;
313 if (((s32)prevSettings != CAMERA_SETTINGS_PTR_MINUS_2
314 && (s32)prevSettings != CAMERA_SETTINGS_PTR_MINUS_1
315 && (s32)prevSettings != CAMERA_SETTINGS_PTR_NULL)
316 && (prevSettings->type == curSettings->type)
317 && (prevSettings->boomLength == curSettings->boomLength)
318 && (prevSettings->boomPitch == curSettings->boomPitch)
319 && (prevSettings->viewPitch == curSettings->viewPitch)
320 && (prevSettings->flag != curSettings->flag)
321 ) {
322 *interpAlpha = 1.0f;
323 }
324 }
325 }
326 }
327 break;
329 {
330 f32 Ax = curSettings->points.two.Ax;
331 f32 Az = curSettings->points.two.Az;
332 f32 Bx = curSettings->points.two.Bx;
333 f32 Bz = curSettings->points.two.Bz;
334
335 f32 ABx = Bx - Ax;
336 f32 ABz = Bz - Az;
337 f32 camRadius = sqrtf(SQ(ABx) + SQ(ABz));
338 f32 curRadius, dx, dz;
339
340 if (curSettings->boomLength < 0.0f) {
341 // negative boom length means look *away* from point
342 dx = x - Ax;
343 dz = z - Az;
344 curRig->boomLength = -curSettings->boomLength;
345 } else {
346 dx = Ax - x;
347 dz = Az - z;
348 curRig->boomLength = curSettings->boomLength;
349 }
350 curRig->boomYaw = atan2(0.0f, 0.0f, dx, dz);
351 curRig->boomPitch = curSettings->boomPitch;
352 curRig->viewPitch = curSettings->viewPitch;
353
354 if (curSettings->flag) {
355 // find radius of a circle containing the sample point centered on point A
356 dx = x - Ax;
357 dz = z - Az;
358 curRadius = sqrtf(SQ(dx) + SQ(dz));
359
360 if (curRadius != 0.0f) {
361 // rescale the radius to equal the length of segment AB
362 curRig->targetPos.x = Ax + dx * (camRadius / curRadius);
363 curRig->targetPos.y = y;
364 curRig->targetPos.z = Az + dz * (camRadius / curRadius);
365 }
366 } else {
367 curRig->targetPos.x = x;
368 curRig->targetPos.y = y;
369 curRig->targetPos.z = z;
370 }
371
372 if (changingZone) {
373 if (*interpAlpha != 1.0f) {
374 prevSettings = *prevSettingsPtr;
375 if (((s32)prevSettings != CAMERA_SETTINGS_PTR_MINUS_2
376 && (s32)prevSettings != CAMERA_SETTINGS_PTR_MINUS_1
377 && (s32)prevSettings != CAMERA_SETTINGS_PTR_NULL)
378 && (prevSettings->type == curSettings->type)
379 && (prevSettings->boomLength == curSettings->boomLength)
380 && (prevSettings->boomPitch == curSettings->boomPitch)
381 && (prevSettings->viewPitch == curSettings->viewPitch)
382 && (prevSettings->flag != curSettings->flag)
383 && (prevSettings->points.two.Ax == curSettings->points.two.Ax)
384 && (prevSettings->points.two.Az == curSettings->points.two.Az)
385 ) {
386 *interpAlpha = 1.0f;
387 }
388 }
389 }
390 }
391 break;
393 {
394 f32 Ax = curSettings->points.three.Ax;
395 f32 Az = curSettings->points.three.Az;
396 f32 Bx = curSettings->points.three.Bx;
397 f32 Bz = curSettings->points.three.Bz;
398 f32 Cx = curSettings->points.three.Cx;
399 f32 Cz = curSettings->points.three.Cz;
400
401 if (!curSettings->flag) {
402 f32 Tx, Tz;
403
404 if (Ax == Bx && Az == Bz) {
405 Ax = Cx;
406 Az = Cz;
407 }
408
409 f32 ABx = Bx - Ax;
410 f32 BAz = Az - Bz;
411 f32 CBx = Bx - Cx;
412 f32 CBz = Bz - Cz;
413
414 if (CBx == 0.0f) {
415 f32 Q = CBx * ABx / CBz + BAz;
416 f32 V = (x - Bx) - (z - Bz) * CBx / CBz;
417
418 Tx = x - BAz * V / Q;
419 Tz = z + ABx * V / Q;
420 } else {
421 f32 Q = BAz * CBz / CBx + ABx;
422 f32 V = (z - Bz) - (x - Bx) * CBz / CBx;
423
424 Tx = x + BAz * V / Q;
425 Tz = z + ABx * V / Q;
426 }
427
428 curRig->targetPos.x = Tx;
429 curRig->targetPos.y = y;
430 curRig->targetPos.z = Tz;
431
432 if (changingMap) {
433 dx = Bx - Ax;
434 dz = Bz - Az;
435 curRig->boomLength = fabsf(curSettings->boomLength);
436 curRig->boomYaw = atan2(0.0f, 0.0f, dx, dz);
437 curRig->boomPitch = curSettings->boomPitch;
438 curRig->viewPitch = curSettings->viewPitch;
439 }
440 } else {
441 if (changingMap) {
442 dx = Bx - Ax;
443 dz = Bz - Az;
444 curRig->boomLength = fabsf(curSettings->boomLength);
445 curRig->boomYaw = atan2(0.0f, 0.0f, dx, dz);
446 curRig->boomPitch = curSettings->boomPitch;
447 curRig->viewPitch = curSettings->viewPitch;
448 curRig->targetPos.x = Bx;
449 curRig->targetPos.y = y;
450 curRig->targetPos.z = Bz;
451 } else if (changingZone) {
452 curRig->targetPos.x = prevRig->targetPos.x;
453 curRig->targetPos.y = y;
454 curRig->targetPos.z = prevRig->targetPos.z;
455 }
456 }
458 }
459 break;
461 {
462 // camera position is projected onto a line defined by BC, while the yaw faces point A
463 f32 Ax = curSettings->points.three.Ax;
464 f32 Az = curSettings->points.three.Az;
465 f32 Bx = curSettings->points.three.Bx;
466 f32 Bz = curSettings->points.three.Bz;
467 f32 Cx = curSettings->points.three.Cx;
468 f32 Cz = curSettings->points.three.Cz;
469
470 if (!curSettings->flag) {
471 f32 CBx = Bx - Cx;
472 f32 CBz = Bz - Cz;
473 f32 dist2 = SQ(CBx) + SQ(CBz);
474 dist2 = (CBx * (x - Cx) + CBz * (z - Cz)) / dist2;
475 f32 Px = Cx + dist2 * CBx;
476 f32 Pz = Cz + dist2 * CBz;
477
478 curRig->targetPos.x = Px;
479 curRig->targetPos.y = y;
480 curRig->targetPos.z = Pz;
481
482 if (curSettings->boomLength < 0.0f) {
483 dx = Px - Ax;
484 dz = Pz - Az;
485 curRig->boomLength = -curSettings->boomLength;
486 } else {
487 dx = Ax - Px;
488 dz = Az - Pz;
489 curRig->boomLength = curSettings->boomLength;
490 }
491 curRig->boomYaw = atan2(0.0f, 0.0f, dx, dz);
492 curRig->boomPitch = curSettings->boomPitch;
493 curRig->viewPitch = curSettings->viewPitch;
494 } else {
495 if (changingMap) {
496 if (curSettings->boomLength < 0.0f) {
497 dx = Bx - Ax;
498 dz = Bz - Az;
499 curRig->boomLength = -curSettings->boomLength;
500 } else {
501 dx = Ax - Bx;
502 dz = Az - Bz;
503 curRig->boomLength = curSettings->boomLength;
504 }
505 curRig->boomYaw = atan2(0.0f, 0.0f, dx, dz);
506 curRig->boomPitch = curSettings->boomPitch;
507 curRig->viewPitch = curSettings->viewPitch;
508 curRig->targetPos.x = Bx;
509 curRig->targetPos.y = y;
510 curRig->targetPos.z = Bz;
511 } else if (changingZone) {
512 curRig->targetPos.x = Bx;
513 curRig->targetPos.y = y;
514 curRig->targetPos.z = Bz;
515 }
516 }
518 }
519 break;
520 }
521
522 if (changingZone
523 && ((curSettings->type == CAM_CONTROL_LOOK_AT_POINT_CONSTAIN_TO_LINE) || (prevRig->boomYaw != newRig->boomYaw))
524 && (fabsf(prevRig->boomYaw - newRig->boomYaw) < 3.0f)
525 && (fabsf(prevRig->boomLength - newRig->boomLength) < 10.0f)
526 && (fabsf(prevRig->boomPitch - newRig->boomPitch) < 1.0f)
527 && (fabsf(prevRig->viewPitch - newRig->viewPitch) < 1.0f)
528 && (fabsf(prevRig->targetPos.x - newRig->targetPos.x) < 10.0f)
529 && (fabsf(prevRig->targetPos.y - newRig->targetPos.y) < 10.0f)
530 && (fabsf(prevRig->targetPos.z - newRig->targetPos.z) < 10.0f)
531 ) {
532 *interpAlpha = 1.0f;
533 }
534 }
535
536 if (*prevSettingsPtr == (CameraControlSettings*) CAMERA_SETTINGS_PTR_MINUS_1) {
537 if (changingZone) {
538 D_800A08E4 = prevRig->targetPos.x - newRig->targetPos.x;
539 D_800A08E8 = prevRig->targetPos.y - newRig->targetPos.y;
540 D_800A08EC = prevRig->targetPos.z - newRig->targetPos.z;
541 }
542 prevRig->targetPos.x = newRig->targetPos.x + D_800A08E4;
543 prevRig->targetPos.y = newRig->targetPos.y + D_800A08E8;
544 prevRig->targetPos.z = newRig->targetPos.z + D_800A08EC;
545 }
546}
BSS f32 D_800A08EC
BSS f32 D_800A08E4
BSS f32 D_800A08E8
#define sqrtf
#define atan2
@ CAM_CONTROL_FIXED_ORIENTATION
Definition enums.h:4790
@ CAM_CONTROL_FIXED_POS_AND_ORIENTATION
Definition enums.h:4810
@ CAM_CONTROL_CONSTRAIN_TO_LINE
Definition enums.h:4804
@ CAM_CONTROL_FOLLOW_PLAYER
Definition enums.h:4807
@ CAM_CONTROL_CONSTAIN_BETWEEN_POINTS
Definition enums.h:4818
@ CAM_CONTROL_LOOK_AT_POINT
Definition enums.h:4795
@ CAM_CONTROL_LOOK_AT_POINT_CONSTAIN_TO_LINE
Definition enums.h:4814
f32 fabsf(f32 f)

Referenced by update_camera_zone_interp().

◆ interp_camera_y_position()

void interp_camera_y_position ( Camera * camera,
f32 targetY )

Definition at line 548 of file cam_mode_zone_interp.c.

548 {
550 camera->yinterpAlpha = 0.0f;
551 } else if (camera->yinterpGoal != targetY) {
552 camera->yinterpGoal = targetY;
553 camera->yinterpAlpha = 0.0f;
554 }
555
556 // always follow player moving down with no interp
557 if (targetY < camera->yinterpGoal && targetY <= camera->yinterpCur) {
558 camera->yinterpGoal = targetY;
559 camera->yinterpAlpha = 1.0f;
560 }
561
562 camera->yinterpAlpha += (1.01f - camera->yinterpAlpha) / camera->yinterpRate;
563
564 if (camera->yinterpAlpha > 1.0f) {
565 camera->yinterpAlpha = 1.0f;
566 }
567
569 camera->yinterpAlpha += 0.3f;
570 if (camera->yinterpAlpha >= 1.0f) {
571 camera->yinterpAlpha = 1.0f;
572 }
573 }
574
575 if (!(camera->moveFlags & CAMERA_MOVE_NO_INTERP_Y)) {
576 camera->yinterpCur += (camera->yinterpGoal - camera->yinterpCur) * camera->yinterpAlpha;
577 }
578}
@ CAMERA_MOVE_IGNORE_PLAYER_Y
Definition enums.h:4732
@ CAMERA_MOVE_ACCEL_INTERP_Y
Definition enums.h:4734
@ CAMERA_MOVE_NO_INTERP_Y
Definition enums.h:4733
f32 yinterpRate
f32 yinterpGoal
f32 yinterpAlpha

Referenced by update_camera_zone_interp().

◆ get_maximum_interp_delta()

f32 get_maximum_interp_delta ( Camera * camera)

Definition at line 581 of file cam_mode_zone_interp.c.

581 {
582 f32 maxDelta;
583 f32 curDelta;
584 f32 deltaX, deltaY, deltaZ;
585
586 curDelta = fabsf(camera->prevRig.boomYaw - camera->nextRig.boomYaw);
587 if (curDelta > 180.0f) {
588 curDelta = 360.0f - curDelta;
589 }
590 maxDelta = curDelta;
591
592 curDelta = fabsf(camera->prevRig.boomPitch - camera->nextRig.boomPitch);
593 if (curDelta > 180.0f) {
594 curDelta = 360.0f - curDelta;
595 }
596 if (maxDelta < curDelta) {
597 maxDelta = curDelta;
598 }
599
600 curDelta = fabsf(camera->prevRig.viewPitch - camera->nextRig.viewPitch);
601 if (curDelta > 180.0f) {
602 curDelta = 360.0f - curDelta;
603 }
604 if (maxDelta < curDelta) {
605 maxDelta = curDelta;
606 }
607
608 curDelta = fabsf(camera->prevRig.boomLength - camera->nextRig.boomLength);
609 if (maxDelta < curDelta) {
610 maxDelta = curDelta;
611 }
612
613 deltaX = camera->prevRig.targetPos.x - camera->nextRig.targetPos.x;
614 deltaY = camera->prevRig.targetPos.y - camera->nextRig.targetPos.y;
615 deltaZ = camera->prevRig.targetPos.z - camera->nextRig.targetPos.z;
616 curDelta = SQ(deltaX) + SQ(deltaY) + SQ(deltaZ);
617 if (curDelta != 0.0f) {
618 // reduce this delta to avoid over-weighting changes in target pos
619 curDelta = sqrtf(curDelta) * 0.2;
620 }
621 if (maxDelta < curDelta) {
622 maxDelta = curDelta;
623 }
624
625 // clamp maxDelta to the interval [20.0, 90.0]
626 if (maxDelta > 90.0f) {
627 maxDelta = 90.0f;
628 }
629 if (maxDelta < 20.0f) {
630 maxDelta = 20.0f;
631 }
632
633 return maxDelta;
634}
CameraRig nextRig
CameraRig prevRig

Referenced by update_camera_zone_interp().

◆ set_camera_from_rig()

void set_camera_from_rig ( Camera * camera,
CameraRig * rig )

Definition at line 636 of file cam_mode_zone_interp.c.

636 {
639 camera->curYaw = camera->curBoomYaw;
640 camera->targetOffsetY = 0.0f;
641
642 f32 sinBoomYaw = sin_deg(camera->curBoomYaw);
643 f32 cosBoomYaw = cos_deg(camera->curBoomYaw);
644 f32 cosBoomPitch = cos_deg(CurrentCamRig.boomPitch + D_800A08DC);
645 f32 sinBoomPitch = sin_deg(CurrentCamRig.boomPitch + D_800A08DC);
646
647 if (!(camera->moveFlags & CAMERA_MOVE_NO_INTERP_Y)) {
648 camera->lookAt_eye.y = CurrentCamRig.targetPos.y + (CurrentCamRig.boomLength * sinBoomPitch);
649 }
650
651 camera->lookAt_eye.x = CurrentCamRig.targetPos.x - (sinBoomYaw * CurrentCamRig.boomLength * cosBoomPitch);
652 camera->lookAt_eye.z = CurrentCamRig.targetPos.z + (cosBoomYaw * CurrentCamRig.boomLength * cosBoomPitch);
653 f32 cosViewPitch = cos_deg(CurrentCamRig.viewPitch);
654 f32 sinViewPitch = sin_deg(CurrentCamRig.viewPitch);
655
656 f32 dx = CurrentCamRig.targetPos.x - camera->lookAt_eye.x;
657 f32 dy = CurrentCamRig.targetPos.y - camera->lookAt_eye.y;
658 f32 dz = CurrentCamRig.targetPos.z - camera->lookAt_eye.z;
659 f32 dr = SQ(dx) + SQ(dz);
660 if (dr != 0.0f) {
661 dr = sqrtf(dr);
662 }
663 if (!(camera->moveFlags & CAMERA_MOVE_NO_INTERP_Y)) {
664 camera->lookAt_obj.y = camera->lookAt_eye.y + (dy * cosViewPitch) - (dr * sinViewPitch);
665 }
666 f32 projectedRadius = (dy * sinViewPitch) + (dr * cosViewPitch);
667 camera->lookAt_obj.x = camera->lookAt_eye.x + (sinBoomYaw * projectedRadius);
668 camera->lookAt_obj.z = camera->lookAt_eye.z - (cosBoomYaw * projectedRadius);
669
672
673 camera->lookAt_obj_target.x = camera->lookAt_obj.x;
674 camera->lookAt_obj_target.y = camera->lookAt_obj.y;
675 camera->lookAt_obj_target.z = camera->lookAt_obj.z;
676}
BSS f32 D_800A08DC
BSS f32 D_800A08E0
#define sin_deg
#define cos_deg
Vec3f lookAt_obj
f32 targetOffsetY
Vec3f lookAt_obj_target
f32 lookAt_pitch
f32 curBoomLength
Vec3f lookAt_eye

Referenced by update_camera_zone_interp().

◆ update_camera_zone_interp()

void update_camera_zone_interp ( Camera * camera)

Definition at line 688 of file cam_mode_zone_interp.c.

688 {
689 CameraControlSettings* curSettings;
690 CameraControlSettings* nextSettings;
691 f32 targetX;
692 f32 targetY;
693 f32 targetZ;
694 f32 maxDelta;
695 f32 panPhase;
696 f32 panRad;
697 f32 cosAngle;
698 f32 temp_f24;
699 f64 temp_f22_2;
700 b32 allParamsMatch;
701 s32 changingZone;
702 f32 dist;
703
704 targetX = camera->targetPos.x;
705 targetY = camera->targetPos.y;
706 targetZ = camera->targetPos.z;
707 changingZone = FALSE;
708
709 if (camera->needsReinit) {
710 camera->curSettings = NULL;
711 camera->prevSettings = NULL;
712 camera->linearInterp = 0.0f;
713 camera->yinterpAlpha = 1.0f;
714 camera->yinterpGoal = 0.0f;
715 camera->yinterpCur = targetY;
716
717 camera->interpEasingParameter = 0.0f;
718 camera->interpAlpha = 1.0f;
719 camera->linearInterpRate = 1.0f;
720
721 camera->prevTargetPos.x = 0.0f;
722 camera->prevTargetPos.y = 0.0f;
723 camera->prevTargetPos.z = 0.0f;
724 camera->prevUseOverride = FALSE;
725 camera->prevPrevUseOverride = FALSE;
726 D_800A08DC = 0.0f;
727 D_800A08E0 = 0.0f;
728 }
729
730 // determine current y-position
731 interp_camera_y_position(camera, targetY);
732
733 if (camera->panActive
734 || camera->prevTargetPos.x != targetX
735 || camera->prevTargetPos.y != targetY
736 || camera->prevTargetPos.z != targetZ
737 || camera->needsReinit
738 ) {
739 if (camera->useOverrideSettings) {
740 nextSettings = &camera->overrideSettings;
741 } else {
742 nextSettings = test_ray_zone_aabb(targetX, targetY + 10.0f, targetZ);
743 }
744
745 allParamsMatch = FALSE;
746 curSettings = camera->curSettings;
747 if (nextSettings != NULL
748 && curSettings != NULL
749 && nextSettings->type == curSettings->type
750 && nextSettings->flag == curSettings->flag
751 && nextSettings->boomLength == curSettings->boomLength
752 && nextSettings->boomPitch == curSettings->boomPitch
753 && nextSettings->viewPitch == curSettings->viewPitch
754 ) {
755 switch (nextSettings->type) {
757 if (nextSettings->points.two.Ax == curSettings->points.two.Ax
758 && nextSettings->points.two.Az == curSettings->points.two.Az
759 && nextSettings->points.two.Bx == curSettings->points.two.Bx
760 && nextSettings->points.two.Bz == curSettings->points.two.Bz
761 ) {
762 allParamsMatch = TRUE;
763 }
764 break;
766 if (nextSettings->flag) {
767 if (nextSettings->points.two.Ax == curSettings->points.two.Ax
768 && nextSettings->points.two.Az == curSettings->points.two.Az
769 && nextSettings->points.two.Bx == curSettings->points.two.Bx
770 && nextSettings->points.two.Bz == curSettings->points.two.Bz
771 ) {
772 allParamsMatch = TRUE;
773 }
774 } else {
775 if (nextSettings->points.two.Ax == curSettings->points.two.Ax
776 && nextSettings->points.two.Az == curSettings->points.two.Az
777 ) {
778 allParamsMatch = TRUE;
779 }
780 }
781 break;
782 default:
783 if (nextSettings->points.two.Ax == curSettings->points.two.Ax
784 && nextSettings->points.two.Az == curSettings->points.two.Az
785 && nextSettings->points.two.Ay == curSettings->points.two.Ay
786 && nextSettings->points.two.By == curSettings->points.two.By
787 && nextSettings->points.two.Bx == curSettings->points.two.Bx
788 && nextSettings->points.two.Bz == curSettings->points.two.Bz
789 ) {
790 allParamsMatch = TRUE;
791 }
792 break;
793 }
794 }
795
796 if (camera->panActive || (nextSettings != curSettings && !allParamsMatch)) {
797 if (camera->interpAlpha == 1.0f) {
798 camera->prevSettings = camera->curSettings;
799 } else {
801 }
802 camera->panActive = FALSE;
803 changingZone = TRUE;
804 camera->prevRig = CurrentCamRig;
805 camera->curSettings = nextSettings;
806
807 camera->interpAlpha = 0.0f;
808 camera->linearInterp = 0.0f;
809 camera->linearInterpRate = camera->moveSpeed;
810
811 camera->prevPrevUseOverride = camera->prevUseOverride;
812 camera->prevUseOverride = camera->useOverrideSettings;
813
814 camera->prevPrevMovePos.x = camera->prevMovePos.x;
815 camera->prevPrevMovePos.y = camera->prevMovePos.y;
816 camera->prevPrevMovePos.z = camera->prevMovePos.z;
817
818 camera->prevMovePos.x = camera->movePos.x;
819 camera->prevMovePos.y = camera->movePos.y;
820 camera->prevMovePos.z = camera->movePos.z;
821 }
822 }
823
824 camera->prevTargetPos.x = targetX;
825 camera->prevTargetPos.y = targetY;
826 camera->prevTargetPos.z = targetZ;
827
828 f32 posX;
829 f32 posY;
830 f32 posZ;
831 f32 tX;
832 f32 tY;
833 f32 tZ;
834
835 if (camera->prevPrevUseOverride) {
836 posX = camera->prevPrevMovePos.x;
837 posY = camera->prevPrevMovePos.y;
838 posZ = camera->prevPrevMovePos.z;
839 } else {
840 posX = targetX;
841 posY = camera->yinterpCur;
842 posZ = targetZ;
843 }
844
845 if (camera->prevUseOverride) {
846 tX = camera->prevMovePos.x;
847 tY = camera->prevMovePos.y;
848 tZ = camera->prevMovePos.z;
849 camera->yinterpCur = tY;
850 } else {
851 tX = targetX;
852 tY = camera->yinterpCur;
853 tZ = targetZ;
854 }
855
857 &camera->prevRig, &camera->prevSettings, &camera->nextRig, &camera->curSettings,
858 posX, posY, posZ, tX, tY, tZ,
859 &camera->interpAlpha, camera->needsReinit, changingZone);
860
861 if (camera->needsReinit) {
862 camera->prevRig = camera->nextRig;
863 camera->needsReinit = FALSE;
864 camera->interpAlpha = 1.0f;
865 }
866
867 if (camera->prevRig.boomYaw - camera->nextRig.boomYaw > 180.0f) {
868 camera->prevRig.boomYaw -= 360.0f;
869 }
870 if (camera->prevRig.boomYaw - camera->nextRig.boomYaw < -180.0f) {
871 camera->prevRig.boomYaw += 360.0f;
872 }
873
874 maxDelta = get_maximum_interp_delta(camera);
875
876 camera->linearInterp += (1.0f / maxDelta) * camera->linearInterpRate;
877 if (camera->linearInterp > 1.0f) {
878 camera->linearInterp = 1.0f;
879 }
880
881 if (camera->interpAlpha < 1.0f) {
882 // this phi parameter controls whether the easing will be cosine in/out or quadratic out
883 // when phi = 0, this expression reduces to cos(PI_D * alpha) and the easing is cosine in and out
884 // when phi = 1, gamma 'blows up' as the denominator goes to zero, so this value is not valid.
885 // however, as phi approaches 1, the formula for interpAlpha approaches 1 - SQ(1 - alpha)
886 // intermediate values smoothly produce intermediate easing functions
887 // in practice, only 0 and 0.5 are ever used, and 0.5 is extremely rare
888 f32 phi = camera->interpEasingParameter;
889 f32 plusCos = (1.0f + cos_rad(PI_D * phi)) * 0.5f;
890 f32 minusCos = (1.0f - cos_rad(PI_D * phi)) * 0.5f;
891 f32 alpha = camera->linearInterp;
892 f32 beta = cos_rad(PI_D * (alpha * (1.0f - phi) + phi));
893 f32 gamma = (beta + minusCos) / plusCos;
894 // the range of gamma is [1,-1] so we must remap it to [0,1] before assigning interpAlpha
895 camera->interpAlpha = (1.0f - gamma) * 0.5001;
896 }
897
898 if (camera->interpAlpha >= 1.0f) {
899 camera->interpAlpha = 1.0f;
900 camera->linearInterp = 0.0f;
901 }
902
903 // interpolate rig parameters between prevRig and nextRig, storing them in CurrentCamRig
904
905 #define CAM_INTERP(field) CurrentCamRig.field = \
906 (camera->prevRig.field * (1.0f - camera->interpAlpha)) + (camera->nextRig.field * camera->interpAlpha)
907
908 CAM_INTERP(boomYaw);
909 CAM_INTERP(boomLength);
910 CAM_INTERP(boomPitch);
911 CAM_INTERP(viewPitch);
912 CAM_INTERP(targetPos.x);
913 CAM_INTERP(targetPos.y);
914 CAM_INTERP(targetPos.z);
915
916 #undef CAM_INTERP
917
918 CurrentCamRig.boomLength *= (camera->params.world.zoomPercent / 100.0f);
919
920 // calculate camera position and orientation based on CurrentCamRig
922}
void interp_camera_y_position(Camera *camera, f32 targetY)
f32 get_maximum_interp_delta(Camera *camera)
void update_camera_from_controller(Camera *camera, CameraRig *prevRig, CameraControlSettings **prevSettingsPtr, CameraRig *newRig, CameraControlSettings **curSettingsPtr, f32 x1, f32 y1, f32 z1, f32 x2, f32 y2, f32 z2, f32 *interpAlpha, b32 changingMap, b32 changingZone)
CameraControlSettings * test_ray_zone_aabb(f32 x, f32 y, f32 z)
void set_camera_from_rig(Camera *camera, CameraRig *rig)
#define CAM_INTERP(field)
s32 b32
f32 cos_rad(f32 x)
Definition 43F0.c:717
#define PI_D
Definition macros.h:127
f32 linearInterpRate
Vec3f movePos
b16 needsReinit
Vec3f prevTargetPos
b16 prevUseOverride
CameraControlSettings * curSettings
Vec3f prevPrevMovePos
f32 interpEasingParameter
CameraControlSettings * prevSettings
b16 useOverrideSettings
union Camera::@17 params
CameraControlSettings overrideSettings
Vec3f targetPos
f32 linearInterp
b16 prevPrevUseOverride
Vec3f prevMovePos
f32 interpAlpha

Referenced by update_cameras().

Variable Documentation

◆ CurrentCamRig

BSS CameraRig CurrentCamRig

Definition at line 3 of file cam_mode_zone_interp.c.

Referenced by set_camera_from_rig(), and update_camera_zone_interp().

◆ D_800A08DC

BSS f32 D_800A08DC

Definition at line 4 of file cam_mode_zone_interp.c.

Referenced by set_camera_from_rig(), and update_camera_zone_interp().

◆ D_800A08E0

BSS f32 D_800A08E0

Definition at line 5 of file cam_mode_zone_interp.c.

Referenced by set_camera_from_rig(), and update_camera_zone_interp().

◆ D_800A08E4

BSS f32 D_800A08E4

Definition at line 6 of file cam_mode_zone_interp.c.

Referenced by update_camera_from_controller().

◆ D_800A08E8

BSS f32 D_800A08E8

Definition at line 7 of file cam_mode_zone_interp.c.

Referenced by update_camera_from_controller().

◆ D_800A08EC

BSS f32 D_800A08EC

Definition at line 8 of file cam_mode_zone_interp.c.

Referenced by update_camera_from_controller().