00001
00002 #include "revolt.h"
00003 #ifdef _N64
00004 #include "gfx.h"
00005 #endif
00006 #include "geom.h"
00007 #include "model.h"
00008 #ifdef _PC
00009 #include "play.h"
00010 #endif
00011 #include "particle.h"
00012 #include "aerial.h"
00013 #include "NewColl.h"
00014 #include "Body.h"
00015 #ifdef _PC
00016 #include "input.h"
00017 #endif
00018 #include "main.h"
00019 #include "camera.h"
00020 #include "ctrlread.h"
00021 #include "object.h"
00022 #include "player.h"
00023 #include "level.h"
00024 #ifdef _PC
00025 #include "ghost.h"
00026 #endif
00027 #include "visibox.h"
00028 #ifdef _PC
00029 #include "EditCam.h"
00030 #endif
00031
00032
00033 void SetCameraFollow(CAMERA *camera, OBJECT *object, long type);
00034 void SetCameraAttached(CAMERA *camera, OBJECT *object, long type);
00035 void SetCameraFreedom(CAMERA *camera, OBJECT *object, long unUsed);
00036 void SetCameraRail(CAMERA *camera, OBJECT *object, long unUsed);
00037 void SetCameraNewFollow(CAMERA *camera, OBJECT *object, long type);
00038 #ifdef _PC
00039 void SetCameraEdit(CAMERA *camera, OBJECT *object, long unUsed);
00040 #endif
00041
00042
00043 void CameraAwayLook(CAMERA *camera);
00044 void CameraMouseLook(CAMERA *camera);
00045 void CameraNullLook(CAMERA *camera);
00046 void CameraForwardLook(CAMERA *camera);
00047 void CameraRearLook(CAMERA *camera);
00048
00049
00050 void InitCamPos(CAMERA *camera);
00051 void CameraFollowPos(CAMERA *camera);
00052 void CameraRotatePos(CAMERA *camera);
00053
00054 void CameraFreedomPos(CAMERA *camera);
00055 void CameraRelativePos(CAMERA *camera);
00056 void CameraNewFollowPos(CAMERA *camera);
00057 void CameraNearestNodePos(CAMERA *camera);
00058 void CameraDynamicNodePos(CAMERA *camera);
00059 #ifdef _PC
00060 void CameraEditPos(CAMERA *camera);
00061 #endif
00062
00063
00064 void CameraWorldColls(CAMERA *camera);
00065 void CalcCamZoom(CAMERA *camera);
00066 void CalcCameraCollPoly(CAMERA *camera);
00067 CAMNODE *NearestNode(long type, VEC *pos);
00068 bool CameraStartEndNodes(CAMERA *camera);
00069 void TriggerCamera(PLAYER *player, long flag, long n, VEC *vec);
00070
00071
00072
00073
00074 char CameraCount;
00075 REAL CameraHomeHeight;
00076 MAT ViewMatrixScaled, ViewMatrix, ViewCameraMatrix, ViewMatrixScaledMirrorY;
00077 VEC ViewTransScaled, ViewTrans, ViewCameraPos;
00078 #ifdef _N64
00079 REAL ViewAngle;
00080 #endif
00081 float MouseXpos = REAL_SCREEN_XHALF, MouseYpos = REAL_SCREEN_YHALF, MouseXrel, MouseYrel;
00082 float CameraEditXrel, CameraEditYrel, CameraEditZrel;
00083 char MouseLeft, MouseRight, MouseLastLeft, MouseLastRight;
00084 PLANE CameraPlaneLeft, CameraPlaneRight, CameraPlaneTop, CameraPlaneBottom;
00085 CAMERA Camera[MAX_CAMERAS];
00086 #ifdef _PC
00087 D3DRECT ViewportRect;
00088 #endif
00089
00090 static VEC LastPoleVector, LastPoleVectorGhost;
00091
00092 CAMERA *CAM_MainCamera;
00093
00094 CAMNODE CAM_CameraNode[CAMERA_MAX_NODES];
00095 long CAM_NCameraNodes = 0;
00096
00097 CAMNODE *CAM_StartNode = NULL;
00098 CAMNODE *CAM_EndNode = NULL;
00099
00100 VEC CAM_NodeCamPos = {ZERO, ZERO, ZERO};
00101 VEC CAM_NodeCamOldPos = {ZERO, ZERO, ZERO};
00102 VEC CAM_NodeCamDir = {ONE, ZERO, ZERO};
00103 REAL CAM_NodeCamPoleLen = ZERO;
00104 bool CAM_NodeCamDoColls = TRUE;
00105 bool CAM_LineOfSight = TRUE;
00106
00107 static REAL OuterRadius = 120.0f;
00108 static REAL InnerRadius = 65.0f;
00109
00110 static CAMFOLLOWDATA CamFollowData[CAM_FOLLOW_NTYPES] = {
00111 {
00112 TRUE,
00113 {0, -150, -460},
00114 {0, -200, 0}
00115 },
00116 {
00117 FALSE,
00118 {0, -70, -210},
00119 {0, -200, 0}
00120 },
00121 {
00122 FALSE,
00123 {-210, -95, 0},
00124 {0, -50, 0}
00125 },
00126 {
00127 FALSE,
00128 {210, -95, 0},
00129 {0, -50, 0}
00130 },
00131 {
00132 FALSE,
00133 {0, -90, 210},
00134 {0, -50, 0}
00135 },
00136 {
00137 FALSE,
00138 {0, -120, -280},
00139 {0, -150, 0}
00140 },
00141
00142 };
00143
00144 static CAMATTACHEDDATA CamAttachedData[CAM_ATTACHED_NTYPES] = {
00145 {
00146 {0, -44, 0},
00147 TRUE
00148 },
00149 {
00150 {60, -40, -190},
00151 TRUE
00152 },
00153 {
00154 {-60, -40, -190},
00155 TRUE
00156 },
00157 {
00158 {0, -44, 0},
00159 FALSE
00160 },
00161 };
00162
00163
00165
00166
00167
00168
00170
00171 void UpdateCamera(CAMERA *camera)
00172 {
00173 REAL flag, dist;
00174 VEC out;
00175 MAT mat, mat2, mat3;
00176 #ifdef _N64
00177 long JoyX, JoyY;
00178 BUTTONS Buttons;
00179
00180
00181 CRD_GetNewButtons(1, &Buttons);
00182 CRD_GetJoyXY(1, &JoyX, &JoyY);
00183 #endif
00184
00185
00186 #ifdef _PC
00187 if (Keys[DIK_TAB] && !LastKeys[DIK_TAB]) {
00188 #endif
00189 #ifdef _N64
00190 if (Buttons & BUT_R) {
00191 #endif
00192 camera->Zoom = !camera->Zoom;
00193 camera->ZoomMod = LENS_DIST_MOD;
00194 camera->Lens = ZERO;
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 camera->Timer += TimeStep;
00250
00251
00252 if (camera->CalcCamPos != NULL) {
00253 camera->CalcCamPos(camera);
00254 }
00255
00256 if (camera->Zoom && (camera->Object != NULL)) {
00257 CalcCamZoom(camera);
00258 }
00259
00260 if (camera->CalcCamLook != NULL) {
00261 camera->CalcCamLook(camera);
00262 }
00263
00264
00265 CalcCameraCollPoly(camera);
00266
00267
00268 if (camera->Shake)
00269 {
00270 camera->Shake -= TimeStep;
00271 if (camera->Shake < 0.0f)
00272 camera->Shake = 0.0f;
00273 }
00274 }
00275
00276
00278
00279
00280
00282
00283 void InitCamPos(CAMERA *camera)
00284 {
00285 MAT mat;
00286
00287
00288 SetVecZero(&camera->Vel);
00289
00290 switch (camera->Type) {
00291
00292 case CAM_FOLLOW:
00293
00294 mat.m[RX] = camera->Object->body.Centre.WMatrix.m[LZ];
00295 mat.m[RY] = ZERO;
00296 mat.m[RZ] = -camera->Object->body.Centre.WMatrix.m[LX];
00297
00298 if (!mat.m[RX] && !mat.m[RZ])
00299 mat.m[RX] = ONE;
00300
00301 NormalizeVector(&mat.mv[R]);
00302
00303 mat.m[UX] = ZERO;
00304 mat.m[UY] = ONE;
00305 mat.m[UZ] = ZERO;
00306
00307 CrossProduct(&mat.mv[R], &mat.mv[U], &mat.mv[L]);
00308
00309
00310 RotVector(&mat, &camera->PosOffset, &camera->WorldPosOffset);
00311 VecPlusVec(&camera->WorldPosOffset, &camera->Object->body.Centre.Pos, &camera->WPos);
00312 CopyVec(&camera->WPos, &camera->OldWPos);
00313
00314
00315 CameraAwayLook(camera);
00316 break;
00317
00318 case CAM_ATTACHED:
00319 VecMulMat(&camera->PosOffset, &camera->Object->body.Centre.WMatrix, &camera->WPos);
00320 VecPlusEqVec(&camera->WPos, &camera->Object->body.Centre.Pos);
00321 MatToQuat(&camera->Object->body.Centre.WMatrix, &camera->Quat);
00322 CopyMat(&camera->Object->body.Centre.WMatrix, &camera->WMatrix);
00323 break;
00324
00325 case CAM_RAIL:
00326 switch (camera->SubType) {
00327 case CAM_RAIL_DYNAMIC_MONO:
00328 break;
00329 case CAM_RAIL_STATIC_NEAREST:
00330 break;
00331 default:
00332 break;
00333 }
00334
00335 default:
00336 break;
00337
00338 }
00339 }
00340
00341
00343
00344
00345
00347
00348 void SetCameraNewFollow(CAMERA *camera, OBJECT *object, long followType)
00349 {
00350 Assert(followType < CAM_FOLLOW_NTYPES);
00351
00352 camera->Type = CAM_NEWFOLLOW;
00353 camera->SubType = followType;
00354 camera->CalcCamPos = CameraNewFollowPos;
00355 camera->CalcCamLook = CameraAwayLook;
00356 camera->Object = object;
00357 camera->Collide = CamFollowData[followType].Collide;
00358 camera->Zoom = FALSE;
00359 camera->ZoomMod = LENS_DIST_MOD;
00360 camera->Lens = ZERO;
00361 camera->Timer = ZERO;
00362
00363 CopyVec(&CamFollowData[followType].PosOffset, &camera->DestOffset);
00364 CopyVec(&CamFollowData[followType].LookOffset, &camera->LookOffset);
00365 CopyVec(&CamFollowData[followType].LookOffset, &camera->OldLookOffset);
00366 InitCamPos(camera);
00367 }
00368
00369 void SetCameraFollow(CAMERA *camera, OBJECT *object, long followType)
00370 {
00371 Assert(followType < CAM_FOLLOW_NTYPES);
00372
00373 camera->Type = CAM_FOLLOW;
00374 camera->SubType = followType;
00375 if (followType != CAM_FOLLOW_ROTATE) {
00376 camera->CalcCamPos = CameraFollowPos;
00377 } else {
00378 camera->CalcCamPos = CameraRotatePos;
00379 }
00380 camera->CalcCamLook = CameraAwayLook;
00381 camera->Object = object;
00382 camera->Collide = CamFollowData[followType].Collide;
00383 camera->Zoom = FALSE;
00384 camera->ZoomMod = LENS_DIST_MOD;
00385 camera->Lens = ZERO;
00386 camera->Timer = ZERO;
00387
00388 CopyVec(&CamFollowData[followType].PosOffset, &camera->DestOffset);
00389 CopyVec(&CamFollowData[followType].LookOffset, &camera->LookOffset);
00390 CopyVec(&CamFollowData[followType].LookOffset, &camera->OldLookOffset);
00391 InitCamPos(camera);
00392 }
00393
00394 void SetCameraAttached(CAMERA *camera, OBJECT *object, long attachedType)
00395 {
00396 Assert(attachedType < CAM_ATTACHED_NTYPES);
00397
00398 camera->Type = CAM_ATTACHED;
00399 camera->SubType = attachedType;
00400 camera->CalcCamPos = CameraRelativePos;
00401 if (CamAttachedData[attachedType].Forward) {
00402 camera->CalcCamLook = CameraForwardLook;
00403 } else {
00404 camera->CalcCamLook = CameraRearLook;
00405 }
00406 camera->Object = object;
00407 camera->Collide = FALSE;
00408 camera->Zoom = FALSE;
00409 camera->ZoomMod = LENS_DIST_MOD;
00410 camera->Lens = ZERO;
00411 camera->Timer = ZERO;
00412
00413 CopyVec(&CamAttachedData[attachedType].PosOffset, &camera->DestOffset);
00414 CopyVec(&CamAttachedData[attachedType].PosOffset, &camera->WorldPosOffset);
00415 InitCamPos(camera);
00416 }
00417
00418 void SetCameraRail(CAMERA *camera, OBJECT *object, long type)
00419 {
00420 CAMNODE *node;
00421
00422 Assert(type < CAM_RAIL_NTYPES);
00423
00424 camera->Type = CAM_RAIL;
00425 camera->SubType = type;
00426 camera->CalcCamLook = CameraAwayLook;
00427 camera->Object = object;
00428 camera->Collide = TRUE;
00429 camera->Timer = ZERO;
00430
00431
00432 node = NearestNode(-1, &object->body.Centre.Pos);
00433 if (node == NULL) return;
00434
00435
00436 switch (type) {
00437 case CAM_RAIL_DYNAMIC_MONO:
00438 camera->Zoom = TRUE;
00439 camera->ZoomMod = LENS_DIST_MOD;
00440 camera->CalcCamPos = CameraDynamicNodePos;
00441 break;
00442 case CAM_RAIL_STATIC_NEAREST:
00443 camera->CalcCamPos = CameraNearestNodePos;
00444 camera->Zoom = TRUE;
00445 camera->ZoomMod = LENS_DIST_MOD;
00446 break;
00447 default:
00448 break;
00449 }
00450
00451
00452 }
00453
00454 void SetCameraFreedom(CAMERA *camera, OBJECT *object, long unUsed)
00455 {
00456 camera->Type = CAM_FREEDOM;
00457 camera->SubType = 0;
00458 camera->CalcCamPos = CameraFreedomPos;
00459 if (object == NULL) {
00460 camera->CalcCamLook = CameraMouseLook;
00461 camera->Object = NULL;
00462 } else {
00463 camera->CalcCamLook = CameraAwayLook;
00464 camera->Object = object;
00465 SetVecZero(&camera->LookOffset);
00466 SetVecZero(&camera->OldLookOffset);
00467 }
00468 camera->Collide = FALSE;
00469 camera->Zoom = TRUE;
00470 camera->Timer = ZERO;
00471
00472 }
00473
00474 #ifdef _PC
00475 void SetCameraEdit(CAMERA *camera, OBJECT *object, long unUsed)
00476 {
00477 camera->Type = CAM_EDIT;
00478 camera->SubType = 0;
00479 camera->CalcCamPos = CameraEditPos;
00480 camera->CalcCamLook = CameraNullLook;
00481 camera->Object = NULL;
00482 camera->Timer = ZERO;
00483 }
00484 #endif
00485
00487
00488
00489
00491
00492 void CameraForwardLook(CAMERA *camera)
00493 {
00494 QUATERNION quat;
00495
00496 SLerpQuat(&camera->Quat, &camera->Object->body.Centre.Quat, TimeStep * 10, &quat);
00497 NormalizeQuat(&quat);
00498
00499 CopyQuat(&quat, &camera->Quat);
00500 QuatToMat(&quat, &camera->WMatrix);
00501 }
00502
00503 void CameraRearLook(CAMERA *camera)
00504 {
00505 QUATERNION quat;
00506
00507 SLerpQuat(&camera->Quat, &camera->Object->body.Centre.Quat, TimeStep * 10, &quat);
00508 NormalizeQuat(&quat);
00509
00510 CopyQuat(&quat, &camera->Quat);
00511 QuatToMat(&quat, &camera->WMatrix);
00512 NegateVec(&camera->WMatrix.mv[L]);
00513 NegateVec(&camera->WMatrix.mv[R]);
00514
00515 }
00516
00517
00519
00520
00521
00522
00524
00525 void CameraRelativePos(CAMERA *camera)
00526 {
00527 VEC dR;
00528 VEC xyOff;
00529 VEC xyWorld;
00530
00531 CopyVec(&camera->WPos, &camera->OldWPos);
00532
00533 VecMinusVec(&camera->DestOffset, &camera->PosOffset, &dR);
00534 VecPlusEqScalarVec(&camera->PosOffset, ONE / 8, &dR);
00535
00536 SetVec(&xyOff, camera->PosOffset.v[X], ZERO, camera->PosOffset.v[Z]);
00537 VecMulMat(&xyOff, &camera->Object->body.Centre.WMatrix, &xyWorld);
00538 xyWorld.v[Y] = camera->PosOffset.v[Y];
00539 VecPlusVec(&xyWorld, &camera->Object->body.Centre.Pos, &camera->WPos);
00540
00541 if (TimeStep > SMALL_REAL) {
00542 VecMinusVec(&camera->WPos, &camera->OldWPos, &camera->Vel);
00543 VecDivScalar(&camera->Vel, TimeStep);
00544 } else {
00545 SetVecZero(&camera->Vel);
00546 }
00547 }
00548
00550
00551
00552
00553
00555
00556 void CameraAwayLook(CAMERA *camera)
00557 {
00558 REAL dRLen;
00559 VEC lookPos, lookOff, dR;
00560
00561 VecMinusVec(&camera->Object->body.Centre.Pos, &camera->WPos, &dR);
00562 dRLen = VecLen(&dR);
00563
00564 if (dRLen < 50) {
00565 CopyMat(&camera->Object->body.Centre.WMatrix, &camera->WMatrix);
00566 return;
00567 }
00568
00569 if (dRLen < 1000) {
00570 VecEqScalarVec(&lookOff, dRLen / 1000, &camera->LookOffset);
00571 } else {
00572 CopyVec(&camera->LookOffset, &lookOff);
00573 }
00574
00575
00576
00577 VecPlusVec(&camera->Object->body.Centre.Pos, &lookOff, &lookPos);
00578 BuildLookMatrixForward(&camera->WPos, &lookPos, &camera->WMatrix);
00579
00580 }
00581
00583
00584
00585
00586
00588
00589 void CameraNewFollowPos(CAMERA *camera)
00590 {
00591 QUATERNION q;
00592 VEC *objPos;
00593 MAT *objMat;
00594 QUATERNION *objQuat;
00595
00596 objQuat = &camera->Object->body.Centre.Quat;
00597 objMat = &camera->Object->body.Centre.WMatrix;
00598 objPos = &camera->Object->body.Centre.Pos;
00599
00600 CopyVec(&camera->WPos, &camera->OldWPos);
00601
00602
00603 SLerpQuat(&camera->Quat, objQuat, TimeStep * 3, &q);
00604 CopyQuat(&q, &camera->Quat);
00605 QuatRotVec(&camera->Quat, &camera->PosOffset, &camera->WorldPosOffset);
00606
00607 VecPlusVec(&camera->WorldPosOffset, objPos, &camera->WPos);
00608
00609 CameraWorldColls(camera);
00610
00611 VecMinusVec(&camera->WPos, objPos, &camera->WorldPosOffset);
00612 CopyVec(&camera->CollPos, &camera->OldCollPos);
00613
00614 if (TimeStep > SMALL_REAL) {
00615 VecMinusVec(&camera->WPos, &camera->OldWPos, &camera->Vel);
00616 VecDivScalar(&camera->Vel, TimeStep);
00617 } else {
00618 SetVecZero(&camera->Vel);
00619 }
00620 }
00621
00622 void CameraFollowPos(CAMERA *camera)
00623 {
00624 VEC newPole, delta, *objPos;
00625 MAT mat, *objMat;
00626 REAL poleLen, homeLen;
00627
00628 objMat = &camera->Object->body.Centre.WMatrix;
00629 objPos = &camera->Object->body.Centre.Pos;
00630
00631 CopyVec(&camera->WPos, &camera->OldWPos);
00632
00633
00634 mat.m[RX] = objMat->m[LZ];
00635 mat.m[RY] = ZERO;
00636 mat.m[RZ] = -objMat->m[LX];
00637
00638 if (!mat.m[RX] && !mat.m[RZ])
00639 mat.m[RX] = ONE;
00640
00641 NormalizeVector(&mat.mv[R]);
00642
00643 mat.m[UX] = ZERO;
00644 mat.m[UY] = ONE;
00645 mat.m[UZ] = ZERO;
00646
00647 CrossProduct(&mat.mv[R], &mat.mv[U], &mat.mv[L]);
00648
00649
00650 VecMinusVec(&camera->DestOffset, &camera->PosOffset, &newPole);
00651 VecPlusEqScalarVec(&camera->PosOffset, ONE / 8, &newPole);
00652
00653 RotVector(&mat, &camera->PosOffset, &newPole);
00654 homeLen = Length(&camera->PosOffset);
00655 if (homeLen > SMALL_REAL) {
00656 VecDivScalar(&newPole, homeLen);
00657 }
00658
00659
00660 poleLen = VecLen(&camera->WorldPosOffset);
00661 if (poleLen > SMALL_REAL) {
00662 VecDivScalar(&camera->WorldPosOffset, poleLen);
00663 }
00664
00665
00666 SubVector(&newPole, &camera->WorldPosOffset, &delta);
00667 VecPlusScalarVec(&camera->WorldPosOffset, TimeStep / 0.25f, &delta, &newPole);
00668 if ((abs(newPole.v[X]) > SMALL_REAL) || (abs(newPole.v[Y]) > SMALL_REAL) || (abs(newPole.v[Z]) > SMALL_REAL)) {
00669 NormalizeVec(&newPole);
00670 }
00671
00672
00673 poleLen = poleLen + (homeLen - poleLen) * TimeStep / 0.30f;
00674
00675
00676 VecMulScalar(&newPole, poleLen);
00677
00678
00679 VecPlusVec(objPos, &newPole, &camera->WPos);
00680 CameraWorldColls(camera);
00681
00682
00683
00684 VecMinusVec(&camera->WPos, objPos, &camera->WorldPosOffset);
00685 CopyVec(&camera->CollPos, &camera->OldCollPos);
00686
00687 if (TimeStep > SMALL_REAL) {
00688 VecMinusVec(&camera->WPos, &camera->OldWPos, &camera->Vel);
00689 VecDivScalar(&camera->Vel, TimeStep);
00690 } else {
00691 SetVecZero(&camera->Vel);
00692 }
00693 }
00694
00695 void CameraRotatePos(CAMERA *camera)
00696 {
00697 VEC newPole, delta, *objPos;
00698 MAT mat, *objMat;
00699 REAL poleLen, homeLen, theta, sinTheta, cosTheta;
00700
00701 objMat = &camera->Object->body.Centre.WMatrix;
00702 objPos = &camera->Object->body.Centre.Pos;
00703
00704 CopyVec(&camera->WPos, &camera->OldWPos);
00705
00706
00707 theta = camera->Timer * 2 * PI / 5.0f;
00708 sinTheta = (REAL)sin(theta);
00709 cosTheta = (REAL)cos(theta);
00710
00711
00712 mat.m[RX] = objMat->m[LZ] * cosTheta + objMat->m[LX] * sinTheta;
00713 mat.m[RY] = ZERO;
00714 mat.m[RZ] = -objMat->m[LX] * cosTheta + objMat->m[LZ] * sinTheta;
00715
00716 if (!mat.m[RX] && !mat.m[RZ])
00717 mat.m[RX] = ONE;
00718
00719 NormalizeVector(&mat.mv[R]);
00720
00721 mat.m[UX] = ZERO;
00722 mat.m[UY] = ONE;
00723 mat.m[UZ] = ZERO;
00724
00725 CrossProduct(&mat.mv[R], &mat.mv[U], &mat.mv[L]);
00726
00727
00728 RotVector(&mat, &camera->PosOffset, &newPole);
00729 homeLen = Length(&camera->PosOffset);
00730 VecDivScalar(&newPole, homeLen);
00731
00732
00733 poleLen = VecLen(&camera->WorldPosOffset);
00734 VecDivScalar(&camera->WorldPosOffset, poleLen);
00735
00736
00737 SubVector(&newPole, &camera->WorldPosOffset, &delta);
00738 VecPlusScalarVec(&camera->WorldPosOffset, TimeStep / 0.25f, &delta, &newPole);
00739 NormalizeVec(&newPole);
00740
00741
00742 poleLen = poleLen + (homeLen - poleLen) * TimeStep / 0.30f;
00743
00744
00745 VecMulScalar(&newPole, poleLen);
00746
00747
00748 VecPlusVec(objPos, &newPole, &camera->WPos);
00749 CameraWorldColls(camera);
00750
00751
00752 VecMinusVec(&camera->WPos, objPos, &camera->WorldPosOffset);
00753 CopyVec(&camera->CollPos, &camera->OldCollPos);
00754
00755 if (TimeStep > SMALL_REAL) {
00756 VecMinusVec(&camera->WPos, &camera->OldWPos, &camera->Vel);
00757 VecDivScalar(&camera->Vel, TimeStep);
00758 } else {
00759 SetVecZero(&camera->Vel);
00760 }
00761 }
00762
00764
00765
00766
00768
00769 void CameraWorldColls(CAMERA *camera)
00770 {
00771
00772
00773 int iPoly;
00774 REAL depth, time, objCamDist, newObjCamDist;
00775 VEC shift, relPos, worldPos, objCamVec;
00776 PLANE collPlane;
00777 COLLGRID *collGrid;
00778 NEWCOLLPOLY *poly;
00779
00780
00781 if (!camera->Collide) return;
00782
00783
00784 SetVecZero(&shift);
00785
00786
00787 VecMinusVec(&camera->Object->body.Centre.Pos, &camera->WPos, &objCamVec);
00788 objCamDist = VecLen(&objCamVec);
00789 if (objCamDist > SMALL_REAL) {
00790 VecDivScalar(&objCamVec, objCamDist);
00791 } else {
00792 SetVecZero(&objCamVec);
00793 }
00794
00795
00796 VecPlusScalarVec(&camera->WPos, RenderSettings.NearClip, &objCamVec, &camera->CollPos);
00797
00798
00799 collGrid = PosToCollGrid(&camera->CollPos);
00800 if (collGrid == NULL) return;
00801
00802
00803 #ifdef _PC
00804 for (iPoly = 0; iPoly < collGrid->NWorldPolys; iPoly++) {
00805 #endif
00806 #ifdef _N64
00807 for (iPoly = 0; iPoly < collGrid->NCollPolys; iPoly++) {
00808 #endif
00809 poly = collGrid->CollPolyPtr[iPoly];
00810
00811 if (PolyObjectOnly(poly)) continue;
00812 if (SphereCollPoly(&camera->OldCollPos, &camera->CollPos, InnerRadius, poly, &collPlane, &relPos, &worldPos, &depth, &time)) {
00813
00814 ModifyShift(&shift, -depth, PlaneNormal(&collPlane));
00815
00816 }
00817 }
00818
00819
00820 VecPlusEqVec(&camera->CollPos, &shift);
00821
00822
00823 VecMinusVec(&camera->Object->body.Centre.Pos, &camera->CollPos, &objCamVec);
00824 newObjCamDist = VecLen(&objCamVec);
00825 if (newObjCamDist > SMALL_REAL) {
00826 VecDivScalar(&objCamVec, newObjCamDist);
00827 if (newObjCamDist > objCamDist - RenderSettings.NearClip) {
00828 VecPlusScalarVec(&camera->Object->body.Centre.Pos, -objCamDist + RenderSettings.NearClip, &objCamVec, &camera->CollPos);
00829 }
00830 }
00831
00832
00833 VecPlusScalarVec(&camera->CollPos, - RenderSettings.NearClip, &objCamVec, &camera->WPos);
00834
00835 }
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00910
00911
00912
00914
00915 void CameraDynamicNodePos(CAMERA *camera)
00916 {
00917 REAL dRLen, velDot;
00918 VEC dR, dR2;
00919
00920
00921 if (camera->Object->player->ValidRailCamNode == -1) {
00922 CameraNearestNodePos(camera);
00923 return;
00924 }
00925
00926
00927 if (camera->Object->player->ValidRailCamNode != camera->Object->player->LastValidRailCamNode) {
00928
00929 CAMNODE *node1, *node2;
00930 node1 = &CAM_CameraNode[camera->Object->player->ValidRailCamNode];
00931 node2 = &CAM_CameraNode[node1->Link];
00932 VecMinusVec(&node1->Pos, &camera->Object->body.Centre.Pos, &dR);
00933 VecMinusVec(&node2->Pos, &camera->Object->body.Centre.Pos, &dR2);
00934 if (VecDotVec(&dR, &dR) < VecDotVec(&dR2, &dR2)) {
00935 camera->Object->player->ValidRailCamNode = camera->Object->player->LastValidRailCamNode = node1->Link;
00936 }
00937 CopyVec(&CAM_CameraNode[camera->Object->player->ValidRailCamNode].Pos, &camera->WPos);
00938 camera->ZoomMod = CAM_CameraNode[camera->Object->player->ValidRailCamNode].ZoomMod;
00939 }
00940 CAM_StartNode = &CAM_CameraNode[camera->Object->player->ValidRailCamNode];
00941 CAM_EndNode = &CAM_CameraNode[CAM_CameraNode[camera->Object->player->ValidRailCamNode].Link];
00942
00943
00944 CopyVec(&camera->WPos, &camera->OldWPos);
00945
00946
00947 VecMinusVec(&CAM_EndNode->Pos, &CAM_StartNode->Pos, &dR);
00948 dRLen = VecLen(&dR);
00949 if (dRLen < SMALL_REAL) {
00950 return;
00951 }
00952 VecDivScalar(&dR, dRLen);
00953
00954
00955 velDot = VecDotVec(&camera->Object->body.Centre.Vel, &dR);
00956
00957
00958 VecPlusEqScalarVec(&camera->WPos, -velDot * TimeStep, &dR);
00959
00960
00961 camera->ZoomMod = CAM_StartNode->ZoomMod;
00962
00963
00964 VecMinusVec(&camera->WPos, &CAM_EndNode->Pos, &dR2);
00965
00966
00967
00968
00969
00970 if (TimeStep > SMALL_REAL) {
00971 VecMinusVec(&camera->WPos, &camera->OldWPos, &camera->Vel);
00972 VecDivScalar(&camera->Vel, TimeStep);
00973 } else {
00974 SetVecZero(&camera->Vel);
00975 }
00976 }
00977
00979
00980
00981
00983
00984 bool CameraStartEndNodes(CAMERA *camera)
00985 {
00986
00987
00988 CAM_EndNode = NearestNode(CAMNODE_MONORAIL, &camera->Object->body.Centre.Pos);
00989 if (CAM_EndNode == NULL) {
00990 return FALSE;
00991 }
00992
00993
00994 if (CAM_EndNode->Link == -1) {
00995 return FALSE;
00996 }
00997
00998
00999 CAM_StartNode = &CAM_CameraNode[CAM_EndNode->Link];
01000
01001 return TRUE;
01002 }
01003
01005
01007
01008 void CameraFreedomPos(CAMERA *camera)
01009 {
01010 VEC vec, vec2;
01011 REAL add;
01012 #ifdef _N64
01013 BUTTONS Buttons;
01014
01015
01016 CRD_GetButtons(1, &Buttons);
01017 #endif
01018
01019 CopyVec(&camera->WPos, &camera->OldWPos);
01020
01021
01022 add = 16 * TimeFactor;
01023 #ifdef _PC
01024 if (GetKeyState(VK_SCROLL) & 1) add *= 4;
01025 #endif
01026 if (CAMERA_RIGHT) vec.v[X] = add;
01027 else if (CAMERA_LEFT) vec.v[X] = -add;
01028 else vec.v[X] = 0;
01029
01030 if (CAMERA_DOWN) vec.v[Y] = add;
01031 else if (CAMERA_UP) vec.v[Y] = -add;
01032 else vec.v[Y] = 0;
01033
01034 #ifdef _PC
01035 if (CAMERA_FORWARDS || Mouse.rgbButtons[0]) vec.v[Z] = add;
01036 else if (CAMERA_BACKWARDS || Mouse.rgbButtons[1]) vec.v[Z] = -add;
01037 #endif
01038 #ifdef _N64
01039 if (CAMERA_FORWARDS) vec.v[Z] = add;
01040 else if (CAMERA_BACKWARDS) vec.v[Z] = -add;
01041 #endif
01042 else vec.v[Z] = 0;
01043
01044 RotVector(&camera->WMatrix, &vec, &vec2);
01045 AddVector(&camera->WPos, &vec2, &camera->WPos);
01046
01047 if (TimeStep > SMALL_REAL) {
01048 VecMinusVec(&camera->WPos, &camera->OldWPos, &camera->Vel);
01049 VecDivScalar(&camera->Vel, TimeStep);
01050 } else {
01051 SetVecZero(&camera->Vel);
01052 }
01053 }
01054
01055 void CameraMouseLook(CAMERA *camera)
01056 {
01057 MAT mat, mat2;
01058 #ifdef _N64
01059 long JoyX, JoyY;
01060
01061
01062 CRD_GetJoyXY(1, &JoyX, &JoyY);
01063 RotMatrixZYX(&mat, (REAL)-JoyY / 3072, -(REAL)JoyX / 3072, 0);
01064 #endif
01065
01066 #ifdef _PC
01067 RotMatrixZYX(&mat, (REAL)-Mouse.lY / 3072, -(REAL)Mouse.lX / 3072, 0);
01068 #endif
01069 MulMatrix(&camera->WMatrix, &mat, &mat2);
01070 CopyMatrix(&mat2, &camera->WMatrix);
01071
01072 camera->WMatrix.m[RY] = 0;
01073 NormalizeVector(&camera->WMatrix.mv[X]);
01074 CrossProduct(&camera->WMatrix.mv[Z], &camera->WMatrix.mv[X], &camera->WMatrix.mv[Y]);
01075 NormalizeVector(&camera->WMatrix.mv[Y]);
01076 CrossProduct(&camera->WMatrix.mv[X], &camera->WMatrix.mv[Y], &camera->WMatrix.mv[Z]);
01077 }
01078
01080
01082 #ifdef _PC
01083 void CameraEditPos(CAMERA *camera)
01084 {
01085 REAL add;
01086 VEC vec, vec2;
01087
01088
01089
01090 MouseXrel = (REAL)Mouse.lX / 3;
01091 MouseYrel = (REAL)Mouse.lY / 3;
01092 MouseXpos += MouseXrel;
01093 MouseYpos += MouseYrel;
01094 if (MouseXpos < 0) MouseXpos = 0, MouseXrel = 0;
01095 if (MouseXpos > 639) MouseXpos = 639, MouseXrel = 0;
01096 if (MouseYpos < 0) MouseYpos = 0, MouseYrel = 0;
01097 if (MouseYpos > 479) MouseYpos = 479, MouseYrel = 0;
01098
01099
01100
01101 MouseLastLeft = MouseLeft;
01102 MouseLastRight = MouseRight;
01103
01104 MouseLeft = Mouse.rgbButtons[0];
01105 MouseRight = Mouse.rgbButtons[1];
01106
01107
01108
01109 add = 16 * TimeFactor;
01110 if (GetKeyState(VK_SCROLL) & 1) add *= 4;
01111
01112 if (CAMERA_RIGHT) vec.v[X] = add;
01113 else if (CAMERA_LEFT) vec.v[X] = -add;
01114 else vec.v[X] = 0;
01115
01116 if (CAMERA_DOWN) vec.v[Y] = add;
01117 else if (CAMERA_UP) vec.v[Y] = -add;
01118 else vec.v[Y] = 0;
01119
01120 if (CAMERA_FORWARDS) vec.v[Z] = add;
01121 else if (CAMERA_BACKWARDS) vec.v[Z] = -add;
01122 else vec.v[Z] = 0;
01123
01124 CameraEditXrel = vec.v[X];
01125 CameraEditYrel = vec.v[Y];
01126 CameraEditZrel = vec.v[Z];
01127
01128 RotVector(&camera->WMatrix, &vec, &vec2);
01129 AddVector(&camera->WPos, &vec2, &camera->WPos);
01130 }
01131 #endif
01132
01133 void CameraNullLook(CAMERA *camera)
01134 {
01135 }
01136
01138
01140
01141 void SetCameraView(MAT *cammat, VEC *campos, REAL shake)
01142 {
01143 VEC vec, tl, tr, bl, br;
01144 MAT mat, mat2;
01145 #ifdef _N64
01146 u16 perspNorm;
01147 #endif
01148
01149
01150 CopyVec(campos, &ViewCameraPos);
01151 CopyMatrix(cammat, &ViewCameraMatrix);
01152
01153
01154
01155 if (shake)
01156 {
01157 RotMatrixZYX(&mat2, (frand(0.01f) - 0.005f) * shake, (frand(0.01f) - 0.005f) * shake, (frand(0.01f) - 0.005f) * shake);
01158 MulMatrix(cammat, &mat2, &mat);
01159 }
01160 else
01161 {
01162 CopyMatrix(cammat, &mat);
01163 }
01164
01165 mat.m[RX] *= RenderSettings.MatScaleX;
01166 mat.m[RY] *= RenderSettings.MatScaleX;
01167 mat.m[RZ] *= RenderSettings.MatScaleX;
01168 mat.m[UX] *= RenderSettings.MatScaleY;
01169 mat.m[UY] *= RenderSettings.MatScaleY;
01170 mat.m[UZ] *= RenderSettings.MatScaleY;
01171
01172 if (GameSettings.Mirrored)
01173 {
01174 mat.m[RX] = -mat.m[RX];
01175 mat.m[RY] = -mat.m[RY];
01176 mat.m[RZ] = -mat.m[RZ];
01177 }
01178
01179 TransposeMatrix(&mat, &ViewMatrixScaled);
01180
01181 SetVector(&vec, -campos->v[X], -campos->v[Y], -campos->v[Z]);
01182 RotVector(&ViewMatrixScaled, &vec, &ViewTransScaled);
01183
01184
01185
01186 TransposeMatrix(cammat, &ViewMatrix);
01187 RotVector(&ViewMatrix, &vec, &ViewTrans);
01188
01189
01190
01191 #ifdef _PC
01192 SetVector(&vec, -REAL_SCREEN_XHALF, -REAL_SCREEN_YHALF, RenderSettings.GeomPers);
01193 RotVector(cammat, &vec, &tl);
01194 AddVector(&tl, campos, &tl);
01195 SetVector(&vec, REAL_SCREEN_XHALF, -REAL_SCREEN_YHALF, RenderSettings.GeomPers);
01196 RotVector(cammat, &vec, &tr);
01197 AddVector(&tr, campos, &tr);
01198 SetVector(&vec, -REAL_SCREEN_XHALF, REAL_SCREEN_YHALF, RenderSettings.GeomPers);
01199 RotVector(cammat, &vec, &bl);
01200 AddVector(&bl, campos, &bl);
01201 SetVector(&vec, REAL_SCREEN_XHALF, REAL_SCREEN_YHALF, RenderSettings.GeomPers);
01202 RotVector(cammat, &vec, &br);
01203 AddVector(&br, campos, &br);
01204 #endif
01205 #ifdef _N64
01206 SetVector(&vec, -GFX_ScrInfo.XCentre, -GFX_ScrInfo.YCentre, RenderSettings.GeomPers);
01207 RotVector(cammat, &vec, &tl);
01208 AddVector(&tl, campos, &tl);
01209 SetVector(&vec, GFX_ScrInfo.XCentre, -GFX_ScrInfo.YCentre, RenderSettings.GeomPers);
01210 RotVector(cammat, &vec, &tr);
01211 AddVector(&tr, campos, &tr);
01212 SetVector(&vec, -GFX_ScrInfo.XCentre, GFX_ScrInfo.YCentre, RenderSettings.GeomPers);
01213 RotVector(cammat, &vec, &bl);
01214 AddVector(&bl, campos, &bl);
01215 SetVector(&vec, GFX_ScrInfo.XCentre, GFX_ScrInfo.YCentre, RenderSettings.GeomPers);
01216 RotVector(cammat, &vec, &br);
01217 AddVector(&br, campos, &br);
01218 #endif
01219
01220 BuildPlane(campos, &tl, &bl, &CameraPlaneLeft);
01221 BuildPlane(campos, &tr, &tl, &CameraPlaneTop);
01222 BuildPlane(campos, &br, &tr, &CameraPlaneRight);
01223 BuildPlane(campos, &bl, &br, &CameraPlaneBottom);
01224
01225
01226
01227 CopyMatrix(&ViewMatrixScaled, &ViewMatrixScaledMirrorY);
01228 ViewMatrixScaledMirrorY.m[UX] = -ViewMatrixScaledMirrorY.m[UX];
01229 ViewMatrixScaledMirrorY.m[UY] = -ViewMatrixScaledMirrorY.m[UY];
01230 ViewMatrixScaledMirrorY.m[UZ] = -ViewMatrixScaledMirrorY.m[UZ];
01231
01232 #ifdef _N64
01233
01234 guPerspective(projlistp, &perspNorm, RenderSettings.PersAngle - ViewAngle, 1.3333333, RenderSettings.NearClip, RenderSettings.FarClip, 0.5);
01235 gSPPerspNormalize(glistp++, perspNorm);
01236 gSPMatrix(glistp++, OS_K0_TO_PHYSICAL(projlistp++),G_MTX_PROJECTION|G_MTX_LOAD|G_MTX_NOPUSH);
01237 guScale(mlistp, 1.0, 1.0, 1.0);
01238 gSPMatrix(glistp++, OS_K0_TO_PHYSICAL(mlistp++), G_MTX_PROJECTION|G_MTX_MUL|G_MTX_NOPUSH);
01239 GEM_NegateMatYZ(&ViewMatrix, &mat);
01240 GEM_ConvF3toS4(&mat, viewlistp);
01241 gSPMatrix(glistp++, OS_K0_TO_PHYSICAL(viewlistp++),G_MTX_PROJECTION|G_MTX_MUL|G_MTX_NOPUSH);
01242 guTranslate(mlistp, -campos->v[0], -campos->v[1], -campos->v[2]);
01243 gSPMatrix(glistp++, OS_K0_TO_PHYSICAL(mlistp++), G_MTX_PROJECTION|G_MTX_MUL|G_MTX_NOPUSH);
01244 #endif
01245
01246 }
01247
01248 #ifdef _PC
01250 // set viewport vars //
01252
01253 void SetViewport(REAL x, REAL y, REAL xsize, REAL ysize, REAL pers)
01254 {
01255 HRESULT r;
01256 D3DVIEWPORT2 vd;
01257
01258
01259
01260 RenderSettings.GeomPers = pers;
01261 RenderSettings.GeomCentreX = x + xsize / 2;
01262 RenderSettings.GeomCentreY = y + ysize / 2;
01263 RenderSettings.GeomScaleX = xsize / REAL_SCREEN_XSIZE;
01264 RenderSettings.GeomScaleY = ysize / REAL_SCREEN_YSIZE;
01265 RenderSettings.MatScaleX = RenderSettings.GeomScaleX * RenderSettings.GeomPers;
01266 RenderSettings.MatScaleY = RenderSettings.GeomScaleY * RenderSettings.GeomPers;
01267
01268
01269
01270 ScreenLeftClip = ScreenLeftClipGuard = x;
01271 ScreenRightClip = ScreenRightClipGuard = x + xsize - 1;
01272 ScreenTopClip = ScreenTopClipGuard = y;
01273 ScreenBottomClip = ScreenBottomClipGuard = y + ysize - 1;
01274
01275
01276
01277
01278
01279
01280
01281
01282 FTOL(x, ViewportRect.x1);
01283 FTOL(y, ViewportRect.y1);
01284 FTOL(x + xsize, ViewportRect.x2);
01285 FTOL(y + ysize, ViewportRect.y2);
01286
01287
01288
01289 ZeroMemory(&vd, sizeof(vd));
01290 vd.dwSize = sizeof(vd);
01291
01292 FTOL(x, vd.dwX);
01293 FTOL(y, vd.dwY);
01294 FTOL(xsize, vd.dwWidth);
01295 FTOL(ysize, vd.dwHeight);
01296
01297 vd.dvClipX = x;
01298 vd.dvClipY = y;
01299 vd.dvClipWidth = xsize;
01300 vd.dvClipHeight = ysize;
01301 vd.dvMinZ = 0;
01302 vd.dvMaxZ = 1;
01303
01304 r = D3Dviewport->SetViewport2(&vd);
01305 if (r != DD_OK)
01306 {
01307 ErrorDX(r, "Can't set viewport");
01308 QuitGame = TRUE;
01309 }
01310 }
01311 #endif
01312
01314
01316
01317 CAMERA *AddCamera(REAL x, REAL y, REAL xsize, REAL ysize, long flag)
01318 {
01319 long i;
01320 REAL scalex, scaley;
01321
01322
01323
01324 for (i = 0 ; i < MAX_CAMERAS ; i++) if (Camera[i].Flag == CAMERA_FLAG_FREE)
01325 {
01326
01327
01328
01329 #ifdef _PC
01330 scalex = (REAL)ScreenXsize / REAL_SCREEN_XSIZE;
01331 scaley = (REAL)ScreenYsize / REAL_SCREEN_YSIZE;
01332 Camera[i].X = x * scalex;
01333 Camera[i].Y = y * scaley;
01334 if (!xsize) Camera[i].Xsize = (REAL)ScreenXsize;
01335 else Camera[i].Xsize = xsize * scalex;
01336 if (!ysize) Camera[i].Ysize = (REAL)ScreenYsize;
01337 else Camera[i].Ysize = ysize * scaley;
01338 #endif
01339 #ifdef _N64
01340 Camera[i].X = x;
01341 Camera[i].Y = y;
01342 Camera[i].Xsize = xsize;
01343 Camera[i].Ysize = ysize;
01344 #endif
01345 Camera[i].Flag = flag;
01346
01347 Camera[i].Shake = 0.0f;
01348
01349
01350
01351 return &Camera[i];
01352 }
01353
01354
01355
01356 return NULL;
01357 }
01358
01360
01362
01363 void RemoveCamera(CAMERA *camera)
01364 {
01365 camera->Flag = CAMERA_FLAG_FREE;
01366 }
01367
01369
01371
01372 void InitCameras(void)
01373 {
01374 long i;
01375
01376 for (i = 0 ; i < MAX_CAMERAS ; i++)
01377 {
01378 Camera[i].Type = -1;
01379 Camera[i].SubType = -1;
01380 Camera[i].Flag = CAMERA_FLAG_FREE;
01381 SetVecZero(&Camera[i].WPos);
01382 SetMatUnit(&Camera[i].WMatrix);
01383 Camera[i].Lens = ZERO;
01384
01385 SetVecZero(&Camera[i].PosOffset);
01386 SetVecZero(&Camera[i].WorldPosOffset);
01387 SetVecZero(&Camera[i].Vel);
01388
01389 Camera[i].CalcCamPos = NULL;
01390 Camera[i].CalcCamLook = NULL;
01391 }
01392 }
01393
01395
01397 #ifdef _PC
01398 void SetProjMatrix(REAL n, REAL f, REAL fov)
01399 {
01400 REAL c, s, q;
01401 D3DMATRIX mat;
01402
01403 fov = fov * PI / 180;
01404
01405 c = (REAL)cos(fov * 0.5f);
01406 s = (REAL)sin(fov * 0.5f);
01407 q = s / (1.0f - n / f);
01408
01409 mat._11 = c;
01410 mat._12 = 0;
01411 mat._13 = 0;
01412 mat._14 = 0;
01413
01414 mat._21 = 0;
01415 mat._22 = -c;
01416 mat._23 = 0;
01417 mat._24 = 0;
01418
01419 mat._31 = 0;
01420 mat._32 = 0;
01421 mat._33 = q;
01422 mat._34 = s;
01423
01424 mat._41 = 0;
01425 mat._42 = 0;
01426 mat._43 = -q * n;
01427 mat._44 = 0;
01428
01429 D3Ddevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &mat);
01430 }
01431 #endif
01432
01434
01435
01436
01438
01439 #ifdef _PC
01440 long LoadCameraNodes(FILE *fp)
01441 {
01442 long iNode, nNodes;
01443 size_t nRead;
01444 CAMNODE *cameraNode;
01445 FILE_CAM_NODE fnode;
01446 BOUNDING_BOX bbox;
01447 Assert(fp != NULL);
01448
01449
01450 nRead = fread(&nNodes, sizeof(long), 1, fp);
01451 if (nRead < 1) {
01452 return -1;
01453 }
01454
01455 Assert((nNodes >= 0) && (nNodes < CAMERA_MAX_NODES));
01456
01457
01458 for (iNode = 0; iNode < nNodes; iNode++) {
01459 cameraNode = &CAM_CameraNode[iNode];
01460
01461 nRead = fread(&fnode, sizeof(fnode), 1, fp);
01462 if (nRead < 1) {
01463 return -1;
01464 }
01465
01466 cameraNode->Type = fnode.Type;
01467 cameraNode->Pos.v[X] = fnode.x / 65536.0f;
01468 cameraNode->Pos.v[Y] = fnode.y / 65536.0f;
01469 cameraNode->Pos.v[Z] = fnode.z / 65536.0f;
01470 cameraNode->ZoomMod = MulScalar(Real(0.001), fnode.ZoomFactor);
01471 cameraNode->Link = fnode.Link;
01472 cameraNode->ID = fnode.ID;
01473
01474
01475 bbox.Xmin = bbox.Xmax = cameraNode->Pos.v[X];
01476 bbox.Ymin = bbox.Ymax = cameraNode->Pos.v[Y];
01477 bbox.Zmin = bbox.Zmax = cameraNode->Pos.v[Z];
01478 cameraNode->VisiMask = SetObjectVisiMask(&bbox);
01479 }
01480
01481 return nNodes;
01482 }
01483 #endif
01484
01486
01487
01488
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01569
01570
01571
01572
01574
01575 void TriggerCamera(PLAYER *player, long flag, long n, VEC *vec)
01576 {
01577 long iNode;
01578 CAR *car;
01579
01580 car = &player->car;
01581
01582 if ((player->LastValidRailCamNode != -1) &&
01583 ((CAM_CameraNode[player->LastValidRailCamNode].ID == n) || (CAM_CameraNode[CAM_CameraNode[player->LastValidRailCamNode].Link].ID == n)))
01584 {
01585 player->ValidRailCamNode = player->LastValidRailCamNode;
01586 return;
01587 }
01588
01589 for (iNode = 0; iNode < CAM_NCameraNodes; iNode++) {
01590 if (CAM_CameraNode[iNode].ID == n) {
01591 player->ValidRailCamNode = iNode;
01592 return;
01593 }
01594 }
01595
01596 }
01597
01599
01600
01601
01603
01604 void CalcCamZoom(CAMERA *camera)
01605 {
01606 VEC dR;
01607 REAL dRLen;
01608
01609 VecMinusVec(&camera->WPos, &camera->Object->body.Centre.Pos, &dR);
01610 dRLen = VecLen(&dR);
01611
01612 camera->Lens = camera->ZoomMod * (dRLen - BaseGeomPers);
01613 if (camera->Lens < MIN_LENS) camera->Lens = MIN_LENS;
01614
01615 }
01616
01617
01619
01620
01621
01623
01624 CAMNODE *NearestNode(long type, VEC *pos)
01625 {
01626 int iNode;
01627 REAL dist, nearDist;
01628 VEC dR;
01629 CAMNODE *node, *nearNode;
01630 VISIMASK tempmask;
01631
01632 nearNode = NULL;
01633 nearDist = LARGEDIST;
01634
01635 tempmask = CamVisiMask;
01636 SetCameraVisiMask(pos);
01637
01638 for (iNode = 0; iNode < CAM_NCameraNodes; iNode++) {
01639 node = &CAM_CameraNode[iNode];
01640
01641
01642 if (CamVisiMask & node->VisiMask) continue;
01643
01644
01645 if ((type != -1) && (node->Type != type)) continue;
01646
01647
01648 VecMinusVec(pos, &node->Pos, &dR);
01649 dist = VecLen(&dR);
01650
01651
01652 if (dist < nearDist) {
01653 nearDist = dist;
01654 nearNode = node;
01655 }
01656 }
01657
01658 CamVisiMask = tempmask;
01659
01660 return nearNode;
01661 }
01662
01663
01665
01666
01667
01669
01670 void CameraNearestNodePos(CAMERA *camera)
01671 {
01672 static CAMNODE *node, *oldNode;
01673
01674
01675
01676 if (camera->Object == NULL) {
01677 return;
01678 }
01679
01680
01681 oldNode = node;
01682 node = NearestNode(CAMNODE_STATIC, &camera->Object->body.Centre.Pos);
01683 if (node == NULL) {
01684 return;
01685 }
01686 if (node != oldNode) {
01687 node = node;
01688 }
01689
01690
01691 CopyVec(&node->Pos, &camera->WPos);
01692 CopyVec(&node->Pos, &camera->OldWPos);
01693
01694
01695 camera->ZoomMod = node->ZoomMod;
01696
01697 }
01698
01699
01701
01702
01703
01705
01706 void CalcCameraCollPoly(CAMERA *camera)
01707 {
01708 VEC screenPos, cPos;
01709
01710
01711 VecPlusScalarVec(&camera->WPos, RenderSettings.NearClip + 20, &camera->WMatrix.mv[L], &screenPos);
01712
01713
01714 SetPlane(&camera->CollPoly.Plane,
01715 camera->WMatrix.m[LX],
01716 camera->WMatrix.m[LY],
01717 camera->WMatrix.m[LZ],
01718 -VecDotVec(&screenPos, &camera->WMatrix.mv[L]));
01719
01720
01721 VecPlusScalarVec(&screenPos, -REAL_SCREEN_XHALF, &camera->WMatrix.mv[R], &cPos);
01722 SetPlane(&camera->CollPoly.EdgePlane[0],
01723 -camera->WMatrix.m[RX],
01724 -camera->WMatrix.m[RY],
01725 -camera->WMatrix.m[RZ],
01726 VecDotVec(&cPos, &camera->WMatrix.mv[R]));
01727
01728 VecPlusScalarVec(&screenPos, -REAL_SCREEN_YHALF, &camera->WMatrix.mv[U], &cPos);
01729 SetPlane(&camera->CollPoly.EdgePlane[1],
01730 -camera->WMatrix.m[UX],
01731 -camera->WMatrix.m[UY],
01732 -camera->WMatrix.m[UZ],
01733 VecDotVec(&cPos, &camera->WMatrix.mv[U]));
01734
01735 VecPlusScalarVec(&screenPos, REAL_SCREEN_XHALF, &camera->WMatrix.mv[R], &cPos);
01736 SetPlane(&camera->CollPoly.EdgePlane[2],
01737 camera->WMatrix.m[RX],
01738 camera->WMatrix.m[RY],
01739 camera->WMatrix.m[RZ],
01740 -VecDotVec(&cPos, &camera->WMatrix.mv[R]));
01741
01742 VecPlusScalarVec(&screenPos, REAL_SCREEN_YHALF, &camera->WMatrix.mv[U], &cPos);
01743 SetPlane(&camera->CollPoly.EdgePlane[3],
01744 camera->WMatrix.m[UX],
01745 camera->WMatrix.m[UY],
01746 camera->WMatrix.m[UZ],
01747 -VecDotVec(&cPos, &camera->WMatrix.mv[U]));
01748
01749
01750 camera->CollPoly.Type = QUAD;
01751 camera->CollPoly.Material = MATERIAL_GLASS;
01752
01753 SetBBox(&camera->CollPoly.BBox,
01754 camera->WPos.v[X] - REAL_SCREEN_XHALF,
01755 camera->WPos.v[X] + REAL_SCREEN_XHALF,
01756 camera->WPos.v[Y] - REAL_SCREEN_XHALF,
01757 camera->WPos.v[Y] + REAL_SCREEN_XHALF,
01758 camera->WPos.v[Z] - REAL_SCREEN_XHALF,
01759 camera->WPos.v[Z] + REAL_SCREEN_XHALF);
01760
01761 }
01762
01763
01764