diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/Cam.cpp | 1501 | ||||
-rw-r--r-- | src/core/Camera.cpp | 324 | ||||
-rw-r--r-- | src/core/Camera.h | 48 |
3 files changed, 991 insertions, 882 deletions
diff --git a/src/core/Cam.cpp b/src/core/Cam.cpp index fd45a374..954e8282 100644 --- a/src/core/Cam.cpp +++ b/src/core/Cam.cpp @@ -26,10 +26,14 @@ #include "Camera.h" #include "DMAudio.h" #include "Bike.h" +#include "Pickups.h" bool PrintDebugCode = false; int16 DebugCamMode; +extern float fRangePlayerRadius; +extern float fCloseNearClipLimit; + #ifdef FREE_CAM bool CCamera::bFreeCam; int nPreviousMode = -1; @@ -41,11 +45,11 @@ CCam::Init(void) Mode = MODE_FOLLOWPED; Front = CVector(0.0f, 0.0f, -1.0f); Up = CVector(0.0f, 0.0f, 1.0f); - Rotating = 0; + Rotating = false; m_iDoCollisionChecksOnFrameNum = 1; m_iDoCollisionCheckEveryNumOfFrames = 9; m_iFrameNumWereAt = 0; - m_bCollisionChecksOn = 1; + m_bCollisionChecksOn = false; m_fRealGroundDist = 0.0f; BetaSpeed = 0.0f; AlphaSpeed = 0.0f; @@ -53,21 +57,23 @@ CCam::Init(void) f_max_role_angle = DEGTORAD(5.0f); Distance = 30.0f; DistanceSpeed = 0.0f; - m_pLastCarEntered = 0; - m_pLastPedLookedAt = 0; - ResetStatics = 1; + m_pLastCarEntered = nil; + m_pLastPedLookedAt = nil; + ResetStatics = true; Beta = 0.0f; - m_bFixingBeta = 0; + m_fTilt = 0.0f; + m_fTiltSpeed = 0.0f; + m_bFixingBeta = false; CA_MIN_DISTANCE = 0.0f; CA_MAX_DISTANCE = 0.0f; - LookingBehind = 0; - LookingLeft = 0; - LookingRight = 0; + LookingBehind = false; + LookingLeft = false; + LookingRight = false; m_fPlayerInFrontSyphonAngleOffSet = DEGTORAD(20.0f); m_fSyphonModeTargetZOffSet = 0.5f; m_fRadiusForDead = 1.5f; DirectionWasLooking = LOOKING_FORWARD; - LookBehindCamWasInFront = 0; + LookBehindCamWasInFront = false; f_Roll = 0.0f; f_rollSpeed = 0.0f; m_fCloseInPedHeightOffset = 0.0f; @@ -231,7 +237,7 @@ CCam::Process(void) ProcessArrestCamTwo(); break; case MODE_M16_1STPERSON: - case MODE_HELICANNON_1STPERSON: // miami + case MODE_HELICANNON_1STPERSON: Process_M16_1stPerson(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar); break; case MODE_SPECIAL_FIXED_FOR_SYPHON: @@ -897,10 +903,10 @@ CCam::PrintMode(void) "Blood on the tracks", "Passenger", "Syphon Crim in Front", "Dead Baby", "Pillow Paps", "Look at Cars", "Arrest One", "Arrest Two", "M16", "Special fixed for Syphon", "Fight", - "Top Down Ped", + "Top Down Ped", "Lighthouse", "Sniper run about", "Rocket run about", "1st Person run about", "M16 run about", "Fight run about", - "Editor" + "Editor", "Helicannon", "Camera" }; sprintf(buf, "Cam: %s", modes[TheCamera.Cams[TheCamera.ActiveCam].Mode]); CDebug::PrintAt(buf, 2, 5); @@ -994,97 +1000,89 @@ CCam::GetPedBetaAngleForClearView(const CVector &Target, float Dist, float BetaO return 0.0f; } -static float DefaultAcceleration = 0.045f; -static float DefaultMaxStep = 0.15f; +float DefaultAcceleration = 0.045f; +float DefaultMaxStep = 0.15f; +float fDefaultSpeedStep = 0.025f; +float fDefaultSpeedMultiplier = 0.09f; +float fDefaultSpeedLimit = 0.15f; +float fDefaultSpeedStep4Avoid = 0.02f; +float fDefaultSpeedMultiplier4Avoid = 0.05f; +float fDefaultSpeedLimit4Avoid = 0.25f; +float fAvoidGeomThreshhold = 1.5f; +float fMiniGunBetaOffset = 0.3f; void CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, float, float) { - const float GroundDist = 1.85f; + if(!CamTargetEntity->IsPed()) + return; CVector TargetCoors, Dist, IdealSource; float Length = 0.0f; - float LateralLeft = 0.0f; - float LateralRight = 0.0f; - float Center = 0.0f; - static bool PreviouslyObscured; static bool PickedASide; static float FixedTargetOrientation = 0.0f; float AngleToGoTo = 0.0f; - float BetaOffsetAvoidBuildings = 0.45f; // ~25 deg - float BetaOffsetGoingBehind = 0.45f; - bool GoingBehind = false; - bool Obscured = false; - bool BuildingCheckObscured = false; - bool HackPlayerOnStoppingTrain = false; + bool StandingInTrain = false; + float ZoomGroundTarget = 0.0f; + float ZoomZTarget = 0.0f; static int TimeIndicatedWantedToGoDown = 0; static bool StartedCountingForGoDown = false; + static float ZoomGround = 0.0f; + static float ZoomGroundSpeed = 0.0f; + static float ZoomZ = 0.0f; + static float ZoomZSpeed = 0.0f; float DeltaBeta; m_bFixingBeta = false; bBelowMinDist = false; bBehindPlayerDesired = false; -#ifdef FIX_BUGS - if(!CamTargetEntity->IsPed()) - return; -#endif - assert(CamTargetEntity->IsPed()); - - // CenterDist should be > LateralDist because we don't have an angle for safety in this case - float CenterDist, LateralDist; - float AngleToGoToSpeed; - if(m_fCloseInPedHeightOffset > 0.00001f){ - LateralDist = 0.55f; - CenterDist = 1.25f; - BetaOffsetAvoidBuildings = 0.9f; // ~50 deg - BetaOffsetGoingBehind = 0.9f; - AngleToGoToSpeed = 0.88254666f; - }else{ - LateralDist = 0.8f; - CenterDist = 1.35f; - if(TheCamera.PedZoomIndicator == CAM_ZOOM_1 || TheCamera.PedZoomIndicator == CAM_ZOOM_TOPDOWN){ - LateralDist = 1.25f; - CenterDist = 1.6f; - } - AngleToGoToSpeed = 0.43254671f; - } - FOV = DefaultFOV; if(ResetStatics){ Rotating = false; m_bCollisionChecksOn = true; FixedTargetOrientation = 0.0f; - PreviouslyObscured = false; PickedASide = false; StartedCountingForGoDown = false; AngleToGoTo = 0.0f; - // unused LastAngleWithNoPickedASide + ZoomGround = 0.0f; + ZoomGroundSpeed = 0.0f; + ZoomZ = 0.0f; + ZoomZSpeed = 0.0f; + Distance = 500.0f; } TargetCoors = CameraTarget; + + // Take speed of thing we're standing on into account + CVector GroundMovement(0.0f, 0.0f, 0.0f); + CPhysical *ground = (CPhysical*)((CPed*)CamTargetEntity)->m_pCurSurface; + if(ground && (ground->IsVehicle() || ground->IsObject())) + GroundMovement += ground->GetSpeed(CamTargetEntity->GetPosition() - ground->GetPosition()) * CTimer::GetTimeStep(); + + Source += GroundMovement; IdealSource = Source; TargetCoors.z += m_fSyphonModeTargetZOffSet; - TargetCoors = DoAverageOnVector(TargetCoors); - TargetCoors.z += m_fRoadOffSet; + TargetCoors.z = DoAverageOnVector(TargetCoors).z; Dist.x = IdealSource.x - TargetCoors.x; Dist.y = IdealSource.y - TargetCoors.y; Length = Dist.Magnitude2D(); // Cam on a string. With a fixed distance. Zoom in/out is done later. - if(Length != 0.0f) - IdealSource = TargetCoors + CVector(Dist.x, Dist.y, 0.0f)/Length * GroundDist; - else + if(Length != 0.0f){ + IdealSource = TargetCoors + CVector(Dist.x, Dist.y, 0.0f)/Length * m_fMinRealGroundDist; + IdealSource.z += GroundMovement.z; + }else IdealSource = TargetCoors + CVector(1.0f, 1.0f, 0.0f); if(TheCamera.m_bUseTransitionBeta && ResetStatics){ CVector VecDistance; - IdealSource.x = TargetCoors.x + GroundDist*Cos(m_fTransitionBeta); - IdealSource.y = TargetCoors.y + GroundDist*Sin(m_fTransitionBeta); + IdealSource.x = TargetCoors.x + m_fMinRealGroundDist*Cos(m_fTransitionBeta); + IdealSource.y = TargetCoors.y + m_fMinRealGroundDist*Sin(m_fTransitionBeta); Beta = CGeneral::GetATanOfXY(IdealSource.x - TargetCoors.x, IdealSource.y - TargetCoors.y); }else Beta = CGeneral::GetATanOfXY(Source.x - TargetCoors.x, Source.y - TargetCoors.y); @@ -1096,7 +1094,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl if(FindPlayerVehicle()) if(FindPlayerVehicle()->m_vehType == VEHICLE_TYPE_TRAIN) - HackPlayerOnStoppingTrain = true; + StandingInTrain = true; if(TheCamera.m_bCamDirectlyInFront){ m_bCollisionChecksOn = true; @@ -1106,24 +1104,30 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl while(Beta >= PI) Beta -= 2.0f * PI; while(Beta < -PI) Beta += 2.0f * PI; - // BUG? is this ever used? - // The values seem to be roughly m_fPedZoomValueSmooth + 1.85 + if(TheCamera.PedZoomIndicator == CAM_ZOOM_1 && + ((CPed*)CamTargetEntity)->GetPedState() != PED_ENTER_CAR && + ((CPed*)CamTargetEntity)->GetPedState() != PED_CARJACK){ + ZoomGroundTarget = m_fTargetZoomGroundOne; + ZoomZTarget = m_fTargetZoomOneZExtra; + }else if(TheCamera.PedZoomIndicator == CAM_ZOOM_2 || TheCamera.PedZoomIndicator == CAM_ZOOM_1){ + ZoomGroundTarget = m_fTargetZoomGroundTwo; + ZoomZTarget = m_fTargetZoomTwoZExtra; + }else if(TheCamera.PedZoomIndicator == CAM_ZOOM_3){ + ZoomGroundTarget = m_fTargetZoomGroundThree; + ZoomZTarget = m_fTargetZoomThreeZExtra; + } + if(m_fCloseInPedHeightOffset > 0.00001f){ + ZoomGroundTarget = m_fTargetCloseInDist; + ZoomZTarget = m_fTargetZoomZCloseIn; + } if(ResetStatics){ - if(TheCamera.PedZoomIndicator == CAM_ZOOM_1) m_fRealGroundDist = 2.090556f; - if(TheCamera.PedZoomIndicator == CAM_ZOOM_2) m_fRealGroundDist = 3.34973f; - if(TheCamera.PedZoomIndicator == CAM_ZOOM_3) m_fRealGroundDist = 4.704914f; - if(TheCamera.PedZoomIndicator == CAM_ZOOM_TOPDOWN) m_fRealGroundDist = 2.090556f; + ZoomGround = ZoomGroundTarget; + ZoomZ = ZoomZTarget; } - // And what is this? It's only used for collision and rotation it seems - float RealGroundDist; - if(TheCamera.PedZoomIndicator == CAM_ZOOM_1) RealGroundDist = 2.090556f; - if(TheCamera.PedZoomIndicator == CAM_ZOOM_2) RealGroundDist = 3.34973f; - if(TheCamera.PedZoomIndicator == CAM_ZOOM_3) RealGroundDist = 4.704914f; - if(TheCamera.PedZoomIndicator == CAM_ZOOM_TOPDOWN) RealGroundDist = 2.090556f; - if(m_fCloseInPedHeightOffset > 0.00001f) - RealGroundDist = 1.7016f; - + float SpeedStep = fDefaultSpeedStep; + float SpeedMultiplier = fDefaultSpeedMultiplier; + float SpeedLimit = fDefaultSpeedLimit; bool Shooting = false; CPed *ped = (CPed*)CamTargetEntity; if(ped->GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) @@ -1134,166 +1138,52 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl Shooting = false; - if(m_fCloseInPedHeightOffset > 0.00001f) - TargetCoors.z -= m_fRoadOffSet; - // Figure out if and where we want to rotate - if(CPad::GetPad(0)->ForceCameraBehindPlayer() || Shooting){ + if(CPad::GetPad(0)->ForceCameraBehindPlayer() && !CPickups::PlayerOnWeaponPickup || Shooting){ // Center cam behind player - GoingBehind = true; - m_bCollisionChecksOn = true; - float OriginalBeta = Beta; - // Set Beta behind player - Beta = TargetOrientation + PI; - TargetCoors.z -= 0.1f; - - AngleToGoTo = GetPedBetaAngleForClearView(TargetCoors, CenterDist * RealGroundDist, 0.0f, true, false, false, true, false); - if(AngleToGoTo != 0.0f){ - if(AngleToGoTo < 0.0f) - AngleToGoTo -= AngleToGoToSpeed; - else - AngleToGoTo += AngleToGoToSpeed; - }else{ - float LateralLeft = GetPedBetaAngleForClearView(TargetCoors, LateralDist * RealGroundDist, BetaOffsetGoingBehind, true, false, false, true, false); - float LateralRight = GetPedBetaAngleForClearView(TargetCoors, LateralDist * RealGroundDist, -BetaOffsetGoingBehind, true, false, false, true, false); - if(LateralLeft == 0.0f && LateralRight != 0.0f) - AngleToGoTo += LateralRight; - else if(LateralLeft != 0.0f && LateralRight == 0.0f) - AngleToGoTo += LateralLeft; - } - - TargetCoors.z += 0.1f; - Beta = OriginalBeta; - if(PickedASide){ - if(AngleToGoTo == 0.0f) + if(AngleToGoTo == 0.0f){ FixedTargetOrientation = TargetOrientation + PI; + if(Shooting && ped->GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN) + FixedTargetOrientation -= fMiniGunBetaOffset; + } Rotating = true; }else{ - FixedTargetOrientation = TargetOrientation + PI + AngleToGoTo; + FixedTargetOrientation = TargetOrientation + PI; Rotating = true; PickedASide = true; + if(Shooting && ped->GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN) + FixedTargetOrientation -= fMiniGunBetaOffset; } - }else{ - - // Rotate cam to avoid clipping into buildings - - TargetCoors.z -= 0.1f; - - Center = GetPedBetaAngleForClearView(TargetCoors, CenterDist * RealGroundDist, 0.0f, true, false, false, true, false); - if(m_bCollisionChecksOn || PreviouslyObscured || Center != 0.0f || m_fCloseInPedHeightOffset > 0.00001f){ - if(Center != 0.0f){ - AngleToGoTo = Center; - }else{ - LateralLeft = GetPedBetaAngleForClearView(TargetCoors, LateralDist * RealGroundDist, BetaOffsetAvoidBuildings, true, false, false, true, false); - LateralRight = GetPedBetaAngleForClearView(TargetCoors, LateralDist * RealGroundDist, -BetaOffsetAvoidBuildings, true, false, false, true, false); - if(LateralLeft == 0.0f && LateralRight != 0.0f){ - AngleToGoTo += LateralRight; - if(m_fCloseInPedHeightOffset > 0.0f) - RwCameraSetNearClipPlane(Scene.camera, 0.7f); - }else if(LateralLeft != 0.0f && LateralRight == 0.0f){ - AngleToGoTo += LateralLeft; - if(m_fCloseInPedHeightOffset > 0.0f) - RwCameraSetNearClipPlane(Scene.camera, 0.7f); - } - } - if(LateralLeft != 0.0f || LateralRight != 0.0f || Center != 0.0f) - BuildingCheckObscured = true; - } - - TargetCoors.z += 0.1f; - } - - if(m_fCloseInPedHeightOffset > 0.00001f) - TargetCoors.z += m_fRoadOffSet; - - - // Have to fix to avoid collision - - if(AngleToGoTo != 0.0f){ - Obscured = true; - Rotating = true; - if(CPad::GetPad(0)->ForceCameraBehindPlayer() || Shooting){ - if(!PickedASide) - FixedTargetOrientation = Beta + AngleToGoTo; // can this even happen? - }else - FixedTargetOrientation = Beta + AngleToGoTo; - - // This calculation is only really used to figure out how fast to rotate out of collision - - m_fAmountFractionObscured = 1.0f; - CVector PlayerPos = FindPlayerPed()->GetPosition(); - float RotationDist = (AngleToGoTo == Center ? CenterDist : LateralDist) * RealGroundDist; - // What's going on here? - AngleToGoTo? - CVector RotatedSource = PlayerPos + CVector(Cos(Beta - AngleToGoTo), Sin(Beta - AngleToGoTo), 0.0f) * RotationDist; - - CColPoint colpoint; - CEntity *entity; - if(CWorld::ProcessLineOfSight(PlayerPos, RotatedSource, colpoint, entity, true, false, false, true, false, false, false)){ - if((PlayerPos - RotatedSource).Magnitude() != 0.0f) - m_fAmountFractionObscured = (PlayerPos - colpoint.point).Magnitude() / (PlayerPos - RotatedSource).Magnitude(); - else - m_fAmountFractionObscured = 1.0f; - } - } - if(m_fAmountFractionObscured < 0.0f) m_fAmountFractionObscured = 0.0f; - if(m_fAmountFractionObscured > 1.0f) m_fAmountFractionObscured = 1.0f; - + }else if(Abs(TheCamera.m_fAvoidTheGeometryProbsTimer) > fAvoidGeomThreshhold && !Rotating ){ - - // Figure out speed values for Beta rotation - - float Acceleration, MaxSpeed; - static float AccelerationMult = 0.35f; - static float MaxSpeedMult = 0.85f; - static float AccelerationMultClose = 0.7f; - static float MaxSpeedMultClose = 1.6f; - float BaseAcceleration = 0.025f; - float BaseMaxSpeed = 0.09f; - if(m_fCloseInPedHeightOffset > 0.00001f){ - if(AngleToGoTo == 0.0f){ - BaseAcceleration = 0.022f; - BaseMaxSpeed = 0.04f; - }else{ - BaseAcceleration = DefaultAcceleration; - BaseMaxSpeed = DefaultMaxStep; - } - } - if(AngleToGoTo == 0.0f){ - Acceleration = BaseAcceleration; - MaxSpeed = BaseMaxSpeed; - }else if(CPad::GetPad(0)->ForceCameraBehindPlayer() && !Shooting){ - Acceleration = 0.051f; - MaxSpeed = 0.18f; - }else if(m_fCloseInPedHeightOffset > 0.00001f){ - Acceleration = BaseAcceleration + AccelerationMultClose*sq(m_fAmountFractionObscured - 1.05f); - MaxSpeed = BaseMaxSpeed + MaxSpeedMultClose*sq(m_fAmountFractionObscured - 1.05f); - }else{ - Acceleration = DefaultAcceleration + AccelerationMult*sq(m_fAmountFractionObscured - 1.05f); - MaxSpeed = DefaultMaxStep + MaxSpeedMult*sq(m_fAmountFractionObscured - 1.05f); + if(TheCamera.m_fAvoidTheGeometryProbsTimer < 0.0f) + FixedTargetOrientation = TargetOrientation; + else + FixedTargetOrientation = TargetOrientation + PI; + float dist = (Source - TargetCoors).Magnitude(); + float mult = dist > 0.1f ? 1.0f/dist : 10.0f; + SpeedStep = mult * fDefaultSpeedStep4Avoid; + SpeedMultiplier = mult * fDefaultSpeedMultiplier4Avoid; + SpeedLimit = mult * fDefaultSpeedLimit4Avoid; } - static float AccelerationLimit = 0.3f; - static float MaxSpeedLimit = 0.65f; - if(Acceleration > AccelerationLimit) Acceleration = AccelerationLimit; - if(MaxSpeed > MaxSpeedLimit) MaxSpeed = MaxSpeedLimit; - int MoveState = ((CPed*)CamTargetEntity)->m_nMoveState; if(MoveState != PEDMOVE_NONE && MoveState != PEDMOVE_STILL && - !CPad::GetPad(0)->ForceCameraBehindPlayer() && !Obscured && !Shooting){ + !(CPad::GetPad(0)->ForceCameraBehindPlayer() && !CPickups::PlayerOnWeaponPickup) && !Shooting){ Rotating = false; - BetaSpeed = 0.0f; + if(TheCamera.m_fAvoidTheGeometryProbsTimer <= fAvoidGeomThreshhold) + BetaSpeed = 0.0f; } // Now do the Beta rotation - float RotDistance = (IdealSource - TargetCoors).Magnitude2D(); - m_fDistanceBeforeChanges = RotDistance; + float RotDistance = m_fMinRealGroundDist; - if(Rotating){ + if(Rotating || TheCamera.m_fAvoidTheGeometryProbsTimer > fAvoidGeomThreshhold){ m_bFixingBeta = true; while(FixedTargetOrientation >= PI) FixedTargetOrientation -= 2*PI; @@ -1303,13 +1193,23 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl while(Beta < -PI) Beta += 2*PI; -/* - // This is inlined WellBufferMe + // This is inlined WellBufferMe - unfortunately modified so we can't just call it + { DeltaBeta = FixedTargetOrientation - Beta; while(DeltaBeta >= PI) DeltaBeta -= 2*PI; while(DeltaBeta < -PI) DeltaBeta += 2*PI; - float ReqSpeed = DeltaBeta * MaxSpeed; + // this is the added bit + if(!Rotating){ + if(TheCamera.m_nAvoidTheGeometryProbsDirn == -1 && DeltaBeta > 0.0f || + TheCamera.m_nAvoidTheGeometryProbsDirn == 1 && DeltaBeta < 0.0f) + DeltaBeta *= -1.0f; + } + + float ReqSpeed = DeltaBeta * SpeedMultiplier; + // this is also added + ReqSpeed = clamp(ReqSpeed, -SpeedLimit, SpeedLimit); + // Add or subtract absolute depending on sign, genius! if(ReqSpeed - BetaSpeed > 0.0f) BetaSpeed += SpeedStep * Abs(ReqSpeed - BetaSpeed) * CTimer::GetTimeStep(); @@ -1324,8 +1224,7 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl BetaSpeed = ReqSpeed; Beta += BetaSpeed * Min(10.0f, CTimer::GetTimeStep()); -*/ - WellBufferMe(FixedTargetOrientation, &Beta, &BetaSpeed, MaxSpeed, Acceleration, true); + } if(ResetStatics){ Beta = FixedTargetOrientation; @@ -1349,7 +1248,14 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl if(TheCamera.m_bCamDirectlyBehind || TheCamera.m_bCamDirectlyInFront || - HackPlayerOnStoppingTrain || Rotating){ + StandingInTrain || Rotating || + TheCamera.m_bUseTransitionBeta && ResetStatics || + Abs(TheCamera.m_fAvoidTheGeometryProbsTimer) > fAvoidGeomThreshhold){ + if(TheCamera.m_bUseTransitionBeta){ + Beta = m_fTransitionBeta; + Source.x = TargetCoors.x + RotDistance * Cos(m_fTransitionBeta); + Source.y = TargetCoors.y + RotDistance * Sin(m_fTransitionBeta); + } if(TheCamera.m_bCamDirectlyBehind){ Beta = TargetOrientation + PI; Source.x = TargetCoors.x + RotDistance * Cos(Beta); @@ -1360,7 +1266,15 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl Source.x = TargetCoors.x + RotDistance * Cos(Beta); Source.y = TargetCoors.y + RotDistance * Sin(Beta); } - if(HackPlayerOnStoppingTrain){ + if(StandingInTrain){ + Beta = TargetOrientation + PI; + Source.x = TargetCoors.x + RotDistance * Cos(Beta); + Source.y = TargetCoors.y + RotDistance * Sin(Beta); + m_fDimensionOfHighestNearCar = 0.0f; + m_fCamBufferedHeight = 0.0f; + m_fCamBufferedHeightSpeed = 0.0f; + } + if(StandingInTrain){ Beta = TargetOrientation + PI; Source.x = TargetCoors.x + RotDistance * Cos(Beta); Source.y = TargetCoors.y + RotDistance * Sin(Beta); @@ -1368,59 +1282,34 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl m_fCamBufferedHeight = 0.0f; m_fCamBufferedHeightSpeed = 0.0f; } + // Beta and Source already set in the rotation code }else{ Source = IdealSource; BetaSpeed = 0.0f; } + Source.z = IdealSource.z; - // Subtract m_fRoadOffSet from both? - TargetCoors.z -= m_fRoadOffSet; - Source.z = IdealSource.z - m_fRoadOffSet; - - // Apply zoom now - // m_fPedZoomValueSmooth makes the cam go down the further out it is - // 0.25 -> 0.20 for nearest dist - // 1.50 -> -0.05 for mid dist - // 2.90 -> -0.33 for far dist - Source.z += (2.5f - TheCamera.m_fPedZoomValueSmooth)*0.2f - 0.25f; // Zoom out camera Front = TargetCoors - Source; Front.Normalise(); - Source -= Front * TheCamera.m_fPedZoomValueSmooth; - // and then we move up again - // -0.375 - // 0.25 - // 0.95 - Source.z += (TheCamera.m_fPedZoomValueSmooth - 1.0f)*0.5f + m_fCloseInPedHeightOffset; + WellBufferMe(ZoomGroundTarget, &ZoomGround, &ZoomGroundSpeed, 0.2f, 0.07f, false); + WellBufferMe(ZoomZTarget, &ZoomZ, &ZoomZSpeed, 0.2f, 0.07f, false); + Source.x -= Front.x*ZoomGround; + Source.y -= Front.y*ZoomGround; + Source.z += ZoomZ; // Process height offset to avoid peds and cars - float TargetZOffSet = m_fRoadOffSet + m_fDimensionOfHighestNearCar; - TargetZOffSet = Max(TargetZOffSet, m_fPedBetweenCameraHeightOffset); + float TargetZOffSet = Max(m_fDimensionOfHighestNearCar, m_fPedBetweenCameraHeightOffset); float TargetHeight = CameraTarget.z + TargetZOffSet - Source.z; if(TargetHeight > m_fCamBufferedHeight){ // Have to go up if(TargetZOffSet == m_fPedBetweenCameraHeightOffset && TargetZOffSet > m_fCamBufferedHeight) WellBufferMe(TargetHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.2f, 0.04f, false); - else if(TargetZOffSet == m_fRoadOffSet && TargetZOffSet > m_fCamBufferedHeight){ - // TODO: figure this out - bool foo = false; - switch(((CPhysical*)CamTargetEntity)->m_nSurfaceTouched) - case SURFACE_GRASS: - case SURFACE_GRAVEL: - case SURFACE_PAVEMENT: - case SURFACE_THICK_METAL_PLATE: - case SURFACE_RUBBER: - case SURFACE_STEEP_CLIFF: - foo = true; - if(foo) - WellBufferMe(TargetHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.4f, 0.05f, false); - else - WellBufferMe(TargetHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.2f, 0.025f, false); - }else + else WellBufferMe(TargetHeight, &m_fCamBufferedHeight, &m_fCamBufferedHeightSpeed, 0.2f, 0.025f, false); StartedCountingForGoDown = false; }else{ @@ -1439,24 +1328,24 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl } Source.z += m_fCamBufferedHeight; - - - // Clip Source if necessary - - bool ClipSource = m_fCloseInPedHeightOffset > 0.00001f && m_fCamBufferedHeight > 0.001f; - if(GoingBehind || ResetStatics || ClipSource){ - CColPoint colpoint; - CEntity *entity; - if(CWorld::ProcessLineOfSight(TargetCoors, Source, colpoint, entity, true, false, false, true, false, true, true)){ - Source = colpoint.point; - if((TargetCoors - Source).Magnitude2D() < 1.0f) - RwCameraSetNearClipPlane(Scene.camera, 0.05f); - } - } - TargetCoors.z += Min(1.0f, m_fCamBufferedHeight/2.0f); m_cvecTargetCoorsForFudgeInter = TargetCoors; + CVector OrigSource = Source; + TheCamera.AvoidTheGeometry(OrigSource, TargetCoors, Source, FOV); + float TargetDist = (TargetCoors - Source).Magnitude(); + if(TargetDist < Distance) + Distance = TargetDist; + else{ + float f = Pow(0.97f, CTimer::GetTimeStep()); + Distance = (1.0f - f)*TargetDist + f*Distance; + if(TargetDist > 0.05f) + Source = TargetCoors + (Source-TargetCoors)*Distance/TargetDist; + float clip = Distance-fRangePlayerRadius; + if(clip < RwCameraGetNearClipPlane(Scene.camera)) + RwCameraSetNearClipPlane(Scene.camera, Max(clip, fCloseNearClipLimit)); + } + Front = TargetCoors - Source; m_fRealGroundDist = Front.Magnitude2D(); m_fMinDistAwayFromCamWhenInterPolating = m_fRealGroundDist; @@ -1464,19 +1353,19 @@ CCam::Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, fl GetVectorsReadyForRW(); TheCamera.m_bCamDirectlyBehind = false; TheCamera.m_bCamDirectlyInFront = false; - PreviouslyObscured = BuildingCheckObscured; ResetStatics = false; } -static float fBaseDist = 1.7f; -static float fAngleDist = 2.0f; -static float fFalloff = 3.0f; -static float fStickSens = 0.01f; -static float fTweakFOV = 1.05f; -static float fTranslateCamUp = 0.8f; -static int16 nFadeControlThreshhold = 45; -static float fDefaultAlphaOrient = -0.22f; +float fBaseDist = 1.7f; +float fAngleDist = 2.0f; +float fFalloff = 3.0f; +float fStickSens = 0.01f; +float fTweakFOV = 1.1f; +float fTranslateCamUp = 0.8f; +int16 nFadeControlThreshhold = 45; +float fDefaultAlphaOrient = -0.22f; +float fMouseAvoidGeomReturnRate = 0.92f; void CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrientation, float, float) @@ -1500,30 +1389,44 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient bool OnTrain = FindPlayerVehicle() && FindPlayerVehicle()->IsTrain(); - // Look around - bool UseMouse = false; - float MouseX = CPad::GetPad(0)->GetMouseX(); - float MouseY = CPad::GetPad(0)->GetMouseY(); - float LookLeftRight, LookUpDown; - if((MouseX != 0.0f || MouseY != 0.0f) && !CPad::GetPad(0)->ArePlayerControlsDisabled()){ - UseMouse = true; - LookLeftRight = -2.5f*MouseX; - LookUpDown = 4.0f*MouseY; - }else{ - LookLeftRight = -CPad::GetPad(0)->LookAroundLeftRight(); - LookUpDown = CPad::GetPad(0)->LookAroundUpDown(); - } + TargetCoors = CameraTarget; + TargetCoors.z += fTranslateCamUp; + float AlphaOffset, BetaOffset; - if(UseMouse){ - BetaOffset = LookLeftRight * TheCamera.m_fMouseAccelHorzntl * FOV/80.0f; - AlphaOffset = LookUpDown * TheCamera.m_fMouseAccelVertical * FOV/80.0f; + if(CPad::GetPad(0)->IsPlayerControlsDisabledBy(PLAYERCONTROL_DISABLED_20)){ + CVector ToCam = Source - TargetCoors; + ToCam.Normalise(); + if(ToCam.z < -0.9f) + BetaOffset = TargetOrientation + PI; + else + BetaOffset = Atan2(ToCam.y, ToCam.x); + AlphaOffset = 0.0f; }else{ - BetaOffset = LookLeftRight * fStickSens * (0.5f/7.0f) * FOV/80.0f * CTimer::GetTimeStep(); - AlphaOffset = LookUpDown * fStickSens * (0.3f/7.0f) * FOV/80.0f * CTimer::GetTimeStep(); + // Look around + bool UseMouse = false; + float MouseX = CPad::GetPad(0)->GetMouseX(); + float MouseY = CPad::GetPad(0)->GetMouseY(); + float LookLeftRight, LookUpDown; + if((MouseX != 0.0f || MouseY != 0.0f) && !CPad::GetPad(0)->ArePlayerControlsDisabled()){ + UseMouse = true; + LookLeftRight = -2.5f*MouseX; + LookUpDown = 4.0f*MouseY; + }else{ + LookLeftRight = -CPad::GetPad(0)->LookAroundLeftRight(); + LookUpDown = CPad::GetPad(0)->LookAroundUpDown(); + } + if(UseMouse){ + BetaOffset = LookLeftRight * TheCamera.m_fMouseAccelHorzntl * FOV/80.0f; + AlphaOffset = LookUpDown * TheCamera.m_fMouseAccelVertical * FOV/80.0f; + }else{ + BetaOffset = LookLeftRight * fStickSens * (1.0f/14.0f) * FOV/80.0f * CTimer::GetTimeStep(); + AlphaOffset = LookUpDown * fStickSens * (0.6f/14.0f) * FOV/80.0f * CTimer::GetTimeStep(); + } } if(TheCamera.GetFading() && TheCamera.GetFadingDirection() == FADE_IN && nFadeControlThreshhold < CDraw::FadeValue || - CDraw::FadeValue > 200){ + CDraw::FadeValue > 200 || + CPad::GetPad(0)->IsPlayerControlsDisabledBy(PLAYERCONTROL_DISABLED_20)){ if(Alpha < fDefaultAlphaOrient-0.05f) AlphaOffset = 0.05f; else if(Alpha < fDefaultAlphaOrient) @@ -1541,11 +1444,7 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; if(Alpha > DEGTORAD(45.0f)) Alpha = DEGTORAD(45.0f); - if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); - - TargetCoors = CameraTarget; - TargetCoors.z += fTranslateCamUp; - TargetCoors = DoAverageOnVector(TargetCoors); + else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); // SA code #ifdef FREE_CAM @@ -1558,12 +1457,12 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient CamDist = fBaseDist + Cos(Alpha)*fAngleDist; if(TheCamera.m_bUseTransitionBeta) - Beta = CGeneral::GetATanOfXY(-Cos(m_fTransitionBeta), -Sin(m_fTransitionBeta)); + Beta = m_fTransitionBeta; if(TheCamera.m_bCamDirectlyBehind) - Beta = TheCamera.m_PedOrientForBehindOrInFront; - if(TheCamera.m_bCamDirectlyInFront) Beta = TheCamera.m_PedOrientForBehindOrInFront + PI; + if(TheCamera.m_bCamDirectlyInFront) + Beta = TheCamera.m_PedOrientForBehindOrInFront; if(OnTrain) Beta = TargetOrientation; @@ -1579,7 +1478,7 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, true, true, true, false, false, true)){ float PedColDist = (TargetCoors - colPoint.point).Magnitude(); float ColCamDist = CamDist - PedColDist; - if(entity->IsPed() && ColCamDist > 1.0f){ + if(entity->IsPed() && ColCamDist > DEFAULT_NEAR + 0.1f){ // Ped in the way but not clipping through if(CWorld::ProcessLineOfSight(colPoint.point, Source, colPoint, entity, true, true, true, true, false, false, true)){ PedColDist = (TargetCoors - colPoint.point).Magnitude(); @@ -1617,9 +1516,12 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient if(dist == 0.1f) Source += (TargetCoors - Source)*0.3f; + Near = RwCameraGetNearClipPlane(Scene.camera); #ifndef FIX_BUGS - // this is totally wrong... - radius = Tan(FOV / 2.0f) * Near; + // this is wrong...DEGTORAD missing + radius = Tan(FOV / 2.0f) * CDraw::CalculateAspectRatio() * fTweakFOV * Near; +#else + radius = ViewPlaneWidth*Near; #endif // Keep testing entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, false); @@ -1629,13 +1531,27 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient entity = nil; } + float TargetDist = (TargetCoors - Source).Magnitude(); + if(TargetDist < Distance) + Distance = TargetDist; + else{ + float f = Pow(fMouseAvoidGeomReturnRate, CTimer::GetTimeStep()); + Distance = (1.0f - f)*TargetDist + f*Distance; + if(TargetDist > 0.05f) + Source = TargetCoors + (Source-TargetCoors)*Distance/TargetDist; + float clip = Distance-fRangePlayerRadius; + if(clip < RwCameraGetNearClipPlane(Scene.camera)) + RwCameraSetNearClipPlane(Scene.camera, Max(clip, fCloseNearClipLimit)); + } + TheCamera.m_bCamDirectlyInFront = false; TheCamera.m_bCamDirectlyBehind = false; GetVectorsReadyForRW(); if(((CPed*)CamTargetEntity)->CanStrafeOrMouseControl() && CDraw::FadeValue < 250 && - (TheCamera.GetFadingDirection() != FADE_OUT || CDraw::FadeValue <= 100)){ + (TheCamera.GetFadingDirection() != FADE_OUT || CDraw::FadeValue <= 100) && + !CPad::GetPad(0)->IsPlayerControlsDisabledBy(PLAYERCONTROL_DISABLED_20)){ float Heading = Front.Heading(); ((CPed*)TheCamera.pTargetEntity)->m_fRotationCur = Heading; ((CPed*)TheCamera.pTargetEntity)->m_fRotationDest = Heading; @@ -1644,6 +1560,7 @@ CCam::Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrient } } +//--MIAMI: done void CCam::Process_BehindCar(const CVector &CameraTarget, float TargetOrientation, float, float) { @@ -1672,300 +1589,173 @@ CCam::Process_BehindCar(const CVector &CameraTarget, float TargetOrientation, fl } TargetCoors.z += 0.8f; - WorkOutCamHeightWeeCar(TargetCoors, TargetOrientation); + Alpha = DEGTORAD(25.0f); + Source.z = TargetCoors.z + CA_MAX_DISTANCE*Sin(Alpha); + RotCamIfInFrontCar(TargetCoors, TargetOrientation); - FixCamIfObscured(TargetCoors, 1.2f, TargetOrientation); + m_cvecTargetCoorsForFudgeInter = TargetCoors; + CVector OrigSource = Source; + TheCamera.AvoidTheGeometry(OrigSource, m_cvecTargetCoorsForFudgeInter, Source, FOV); Front = TargetCoors - Source; - m_cvecTargetCoorsForFudgeInter = TargetCoors; ResetStatics = false; GetVectorsReadyForRW(); } -void -CCam::WorkOutCamHeightWeeCar(CVector &TargetCoors, float TargetOrientation) -{ - CColPoint colpoint; - CEntity *ent; - float TargetZOffSet = 0.0f; - static bool PreviouslyFailedRoadHeightCheck = false; - static float RoadHeightFix = 0.0f; - static float RoadHeightFixSpeed = 0.0f; - - if(ResetStatics){ - RoadHeightFix = 0.0f; - RoadHeightFixSpeed = 0.0f; - Alpha = DEGTORAD(25.0f); - AlphaSpeed = 0.0f; - } - float AlphaTarget = DEGTORAD(25.0f); - if(CCullZones::CamNoRain() || CCullZones::PlayerNoRain()) - AlphaTarget = DEGTORAD(14.0f); - WellBufferMe(AlphaTarget, &Alpha, &AlphaSpeed, 0.1f, 0.05f, true); - Source.z = TargetCoors.z + CA_MAX_DISTANCE*Sin(Alpha); - - if(FindPlayerVehicle()){ - m_fRoadOffSet = 0.0f; - bool FoundRoad = false; - bool FoundRoof = false; - float RoadZ = 0.0f; - float RoofZ = 0.0f; - - if(CWorld::ProcessVerticalLine(Source, -1000.0f, colpoint, ent, true, false, false, false, false, false, nil) && - ent->IsBuilding()){ - FoundRoad = true; - RoadZ = colpoint.point.z; - } - - if(FoundRoad){ - if(Source.z - RoadZ < 0.9f){ - PreviouslyFailedRoadHeightCheck = true; - TargetZOffSet = RoadZ + 0.9f - Source.z; - }else{ - if(m_bCollisionChecksOn) - PreviouslyFailedRoadHeightCheck = false; - else - TargetZOffSet = 0.0f; - } - }else{ - if(CWorld::ProcessVerticalLine(Source, 1000.0f, colpoint, ent, true, false, false, false, false, false, nil) && - ent->IsBuilding()){ - FoundRoof = true; - RoofZ = colpoint.point.z; - } - if(FoundRoof){ - if(Source.z - RoofZ < 0.9f){ - PreviouslyFailedRoadHeightCheck = true; - TargetZOffSet = RoofZ + 0.9f - Source.z; - }else{ - if(m_bCollisionChecksOn) - PreviouslyFailedRoadHeightCheck = false; - else - TargetZOffSet = 0.0f; - } - } - } - } - - if(TargetZOffSet > RoadHeightFix) - RoadHeightFix = TargetZOffSet; - else - WellBufferMe(TargetZOffSet, &RoadHeightFix, &RoadHeightFixSpeed, 0.27f, 0.1f, false); - - if((colpoint.surfaceB == SURFACE_DEFAULT || colpoint.surfaceB >= SURFACE_CAR) && - colpoint.surfaceB != SURFACE_THICK_METAL_PLATE && colpoint.surfaceB != SURFACE_STEEP_CLIFF && - RoadHeightFix > 1.4f) - RoadHeightFix = 1.4f; - - Source.z += RoadHeightFix; -} +float ZmOneAlphaOffset[] = { -0.01f, 0.1f, 0.125f, -0.1f, -0.06f }; +float ZmTwoAlphaOffset[] = { 0.045f, 0.12f, 0.045f, 0.045f, -0.035f }; +float ZmThreeAlphaOffset[] = { 0.005f, 0.005f, 0.15f, 0.005f, 0.12f }; +float INIT_RC_HELI_HORI_EXTRA = 6.0f; +float INIT_RC_PLANE_HORI_EXTRA = 9.5f; +float INIT_RC_HELI_ALPHA_EXTRA = 0.2f; +float INIT_RC_PLANE_ALPHA_EXTRA = 0.295f; +//--MIAMI: done void CCam::WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, float TargetHeight) { - static float LastTargetAlphaWithCollisionOn = 0.0f; - static float LastTopAlphaSpeed = 0.0f; - static float LastAlphaSpeedStep = 0.0f; - static bool PreviousNearCheckNearClipSmall = false; + if(!CamTargetEntity->IsVehicle()) + return; - bool CamClear = true; - float ModeAlpha = 0.0f; + static float AlphaOffset = 0.0; + static float AlphaOffsetSpeed = 0.0; + static float AlphaDec = 0.0f; + + bool isHeli = false; + bool isBike = false; + int appearance = ((CVehicle*)CamTargetEntity)->GetVehicleAppearance(); + if(appearance == VEHICLE_APPEARANCE_BIKE) + isBike = true; + if(appearance == VEHICLE_APPEARANCE_HELI) + isHeli = true; + int index = 0; + TheCamera.GetArrPosForVehicleType(appearance, index); + + float ExtraOffset = 0.0f; + int id = CamTargetEntity->GetModelIndex(); + if(id == MI_RCRAIDER || id == MI_RCGOBLIN) + ExtraOffset = INIT_RC_HELI_ALPHA_EXTRA; + else if(id == MI_RCBARON) + ExtraOffset = INIT_RC_PLANE_ALPHA_EXTRA; if(ResetStatics){ - LastTargetAlphaWithCollisionOn = 0.0f; - LastTopAlphaSpeed = 0.0f; - LastAlphaSpeedStep = 0.0f; - PreviousNearCheckNearClipSmall = false; - } + AlphaOffset = 0.0f; + AlphaOffsetSpeed = 0.0f; + AlphaDec = 0.0f; - float TopAlphaSpeed = 0.15f; - float AlphaSpeedStep = 0.015f; + if(TheCamera.CarZoomIndicator == CAM_ZOOM_1) + AlphaOffset = ZmOneAlphaOffset[index] + ExtraOffset; + else if(TheCamera.CarZoomIndicator == CAM_ZOOM_2) + AlphaOffset = ZmTwoAlphaOffset[index] + ExtraOffset; + else if(TheCamera.CarZoomIndicator == CAM_ZOOM_3) + AlphaOffset = ZmThreeAlphaOffset[index] + ExtraOffset; + } - float zoomvalue = TheCamera.CarZoomValueSmooth; - if(zoomvalue < 0.1f) - zoomvalue = 0.1f; if(TheCamera.CarZoomIndicator == CAM_ZOOM_1) - ModeAlpha = CGeneral::GetATanOfXY(23.0f, zoomvalue); // near + WellBufferMe(ZmOneAlphaOffset[index] + ExtraOffset, &AlphaOffset, &AlphaOffsetSpeed, 0.17f, 0.08f, false); else if(TheCamera.CarZoomIndicator == CAM_ZOOM_2) - ModeAlpha = CGeneral::GetATanOfXY(10.8f, zoomvalue); // mid + WellBufferMe(ZmTwoAlphaOffset[index] + ExtraOffset, &AlphaOffset, &AlphaOffsetSpeed, 0.17f, 0.08f, false); else if(TheCamera.CarZoomIndicator == CAM_ZOOM_3) - ModeAlpha = CGeneral::GetATanOfXY(7.0f, zoomvalue); // far - + WellBufferMe(ZmThreeAlphaOffset[index] + ExtraOffset, &AlphaOffset, &AlphaOffsetSpeed, 0.17f, 0.08f, false); float Length = (Source - TargetCoors).Magnitude2D(); - if(m_bCollisionChecksOn){ // there's another variable (on PC) but it's uninitialised - CVector Forward = CamTargetEntity->GetForward(); - float CarAlpha = CGeneral::GetATanOfXY(Forward.Magnitude2D(), Forward.z); - // this shouldn't be necessary.... - while(CarAlpha >= PI) CarAlpha -= 2*PI; - while(CarAlpha < -PI) CarAlpha += 2*PI; - while(Beta >= PI) Beta -= 2*PI; - while(Beta < -PI) Beta += 2*PI; + CVector Forward = CamTargetEntity->GetForward(); + float CarAlpha = CGeneral::GetATanOfXY(Forward.Magnitude2D(), Forward.z); + // this shouldn't be necessary.... + while(CarAlpha >= PI) CarAlpha -= 2*PI; + while(CarAlpha < -PI) CarAlpha += 2*PI; - float deltaBeta = Beta - TargetOrientation; - while(deltaBeta >= PI) deltaBeta -= 2*PI; - while(deltaBeta < -PI) deltaBeta += 2*PI; - - float BehindCarNess = Cos(deltaBeta); // 1 if behind car, 0 if side, -1 if in front - CarAlpha = -CarAlpha * BehindCarNess; - if(CarAlpha < -0.01f) - CarAlpha = -0.01f; - - float DeltaAlpha = CarAlpha - Alpha; - while(DeltaAlpha >= PI) DeltaAlpha -= 2*PI; - while(DeltaAlpha < -PI) DeltaAlpha += 2*PI; - // What's this?? wouldn't it make more sense to clamp? - float AngleLimit = DEGTORAD(1.8f); - if(DeltaAlpha < -AngleLimit) - DeltaAlpha += AngleLimit; - else if(DeltaAlpha > AngleLimit) - DeltaAlpha -= AngleLimit; - else - DeltaAlpha = 0.0f; - - // Now the collision - - float TargetAlpha = 0.0f; - bool FoundRoofCenter = false; - bool FoundRoofSide1 = false; - bool FoundRoofSide2 = false; - bool FoundCamRoof = false; - bool FoundCamGround = false; - float CamRoof = 0.0f; - float CarBottom = TargetCoors.z - TargetHeight/2.0f; - - // Check car center - float CarRoof = CWorld::FindRoofZFor3DCoord(TargetCoors.x, TargetCoors.y, CarBottom, &FoundRoofCenter); - - // Check sides of the car - Forward = CamTargetEntity->GetForward(); // we actually still have that... - Forward.Normalise(); // shouldn't be necessary - float CarSideAngle = CGeneral::GetATanOfXY(Forward.x, Forward.y) + PI/2.0f; - float SideX = 2.5f * Cos(CarSideAngle); - float SideY = 2.5f * Sin(CarSideAngle); - CWorld::FindRoofZFor3DCoord(TargetCoors.x + SideX, TargetCoors.y + SideY, CarBottom, &FoundRoofSide1); - CWorld::FindRoofZFor3DCoord(TargetCoors.x - SideX, TargetCoors.y - SideY, CarBottom, &FoundRoofSide2); - - // Now find out at what height we'd like to place the camera - float CamGround = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, TargetCoors.z + Length*Sin(Alpha + ModeAlpha) + m_fCloseInCarHeightOffset, &FoundCamGround); - float CamTargetZ = 0.0f; - if(FoundCamGround){ - // This is the normal case - CamRoof = CWorld::FindRoofZFor3DCoord(Source.x, Source.y, CamGround + TargetHeight, &FoundCamRoof); - CamTargetZ = CamGround + TargetHeight*1.5f + 0.1f; - }else{ - FoundCamRoof = false; - CamTargetZ = TargetCoors.z; - } - - if(FoundRoofCenter && !FoundCamRoof && (FoundRoofSide1 || FoundRoofSide2)){ - // Car is under something but camera isn't - // This seems weird... - TargetAlpha = CGeneral::GetATanOfXY(CA_MAX_DISTANCE, CarRoof - CamTargetZ - 1.5f); - CamClear = false; - } - if(FoundCamRoof){ - // Camera is under something - float roof = FoundRoofCenter ? Min(CamRoof, CarRoof) : CamRoof; - // Same weirdness again? - TargetAlpha = CGeneral::GetATanOfXY(CA_MAX_DISTANCE, roof - CamTargetZ - 1.5f); - CamClear = false; - } - while(TargetAlpha >= PI) TargetAlpha -= 2*PI; - while(TargetAlpha < -PI) TargetAlpha += 2*PI; - if(TargetAlpha < DEGTORAD(-7.0f)) - TargetAlpha = DEGTORAD(-7.0f); - - // huh? - if(TargetAlpha > ModeAlpha) - CamClear = true; - // Camera is contrained by collision in some way - PreviousNearCheckNearClipSmall = false; - if(!CamClear){ - PreviousNearCheckNearClipSmall = true; - RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR); - - DeltaAlpha = TargetAlpha - (Alpha + ModeAlpha); - while(DeltaAlpha >= PI) DeltaAlpha -= 2*PI; - while(DeltaAlpha < -PI) DeltaAlpha += 2*PI; + while(Beta >= PI) Beta -= 2*PI; + while(Beta < -PI) Beta += 2*PI; - TopAlphaSpeed = 0.3f; - AlphaSpeedStep = 0.03f; - } + float DeltaBeta = Beta - TargetOrientation; + while(DeltaBeta >= PI) DeltaBeta -= 2*PI; + while(DeltaBeta < -PI) DeltaBeta += 2*PI; - // Now do things if CamClear...but what is that anyway? - float CamZ = TargetCoors.z + Length*Sin(Alpha + DeltaAlpha + ModeAlpha) + m_fCloseInCarHeightOffset; - bool FoundGround, FoundRoof; - float CamGround2 = CWorld::FindGroundZFor3DCoord(Source.x, Source.y, CamZ, &FoundGround); - if(FoundGround){ - if(CamClear) - if(CamZ - CamGround2 < 1.5f){ - PreviousNearCheckNearClipSmall = true; - RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR); - - float a; - if(Length == 0.0f || CamGround2 + 1.5f - TargetCoors.z == 0.0f) - a = Alpha; - else - a = CGeneral::GetATanOfXY(Length, CamGround2 + 1.5f - TargetCoors.z); - while(a > PI) a -= 2*PI; - while(a < -PI) a += 2*PI; - DeltaAlpha = a - Alpha; - } - }else{ - if(CamClear){ - float CamRoof2 = CWorld::FindRoofZFor3DCoord(Source.x, Source.y, CamZ, &FoundRoof); - if(FoundRoof && CamZ - CamRoof2 < 1.5f){ - PreviousNearCheckNearClipSmall = true; - RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR); - - if(CamRoof2 > TargetCoors.z + 3.5f) - CamRoof2 = TargetCoors.z + 3.5f; - - float a; - if(Length == 0.0f || CamRoof2 + 1.5f - TargetCoors.z == 0.0f) - a = Alpha; - else - a = CGeneral::GetATanOfXY(Length, CamRoof2 + 1.5f - TargetCoors.z); - while(a > PI) a -= 2*PI; - while(a < -PI) a += 2*PI; - DeltaAlpha = a - Alpha; - } - } - } + float BehindCarNess = Cos(DeltaBeta); // 1 if behind car, 0 if side, -1 if in front + CarAlpha = -CarAlpha * BehindCarNess; + + float fwdSpeed = DotProduct(((CPhysical*)CamTargetEntity)->m_vecMoveSpeed, CamTargetEntity->GetForward())*180.0f; + if(CamTargetEntity->GetModelIndex() == MI_FIRETRUCK && CPad::GetPad(0)->GetCarGunFired()){ + CarAlpha = DEGTORAD(10.0f); + }else if(isHeli){ + CarAlpha = 0.0f; + float heliFwdZ = CamTargetEntity->GetForward().z; + float heliFwdXY = CamTargetEntity->GetForward().Magnitude2D(); + float alphaAmount = Min(Abs(fwdSpeed/90.0f), 1.0f); + if(heliFwdXY != 0.0f || heliFwdZ != 0.0f) + CarAlpha = CGeneral::GetATanOfXY(heliFwdXY, Abs(heliFwdZ)) * alphaAmount; + + CColPoint point; + CEntity *entity = nil; + CVector Test = Source; + Test.z = TargetCoors.z + 0.2f + Length*Sin(CarAlpha+AlphaOffset) + m_fCloseInCarHeightOffset; + if(CWorld::ProcessVerticalLine(Test, CamTargetEntity->GetPosition().z, point, entity, true, false, false, false, false, false, nil)){ + float sin = (point.point.z - TargetCoors.z - 0.2f - m_fCloseInCarHeightOffset)/Length; + CarAlpha = Asin(clamp(sin, -1.0f, 1.0f)) - AlphaOffset; + if(CarAlpha < 0.0f) + AlphaOffset += CarAlpha; + } + } + + CarAlpha = CGeneral::LimitRadianAngle(CarAlpha); + if(CarAlpha < 0.0f) CarAlpha = 0.0f; + if(CarAlpha > DEGTORAD(89.0f)) CarAlpha = DEGTORAD(89.0f); - LastTargetAlphaWithCollisionOn = DeltaAlpha + Alpha; - LastTopAlphaSpeed = TopAlphaSpeed; - LastAlphaSpeedStep = AlphaSpeedStep; - }else{ - if(PreviousNearCheckNearClipSmall) - RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR); - } + if(ResetStatics) + Alpha = CarAlpha; - WellBufferMe(LastTargetAlphaWithCollisionOn, &Alpha, &AlphaSpeed, LastTopAlphaSpeed, LastAlphaSpeedStep, true); + float TargetAlpha = Alpha; + float DeltaAlpha = CarAlpha - TargetAlpha; + while(DeltaAlpha >= PI) DeltaAlpha -= 2*PI; + while(DeltaAlpha < -PI) DeltaAlpha += 2*PI; + if(Abs(DeltaAlpha) > 0.0f && !TheCamera.m_bVehicleSuspenHigh) + TargetAlpha = CarAlpha; + + if(isBike) + WellBufferMe(TargetAlpha, &Alpha, &AlphaSpeed, 0.09f, 0.04f, true); + else if(isHeli) + WellBufferMe(TargetAlpha, &Alpha, &AlphaSpeed, 0.09f, 0.04f, true); + else + WellBufferMe(TargetAlpha, &Alpha, &AlphaSpeed, 0.15f, 0.07f, true); - Source.z = TargetCoors.z + Sin(Alpha + ModeAlpha)*Length + m_fCloseInCarHeightOffset; + Source.z = TargetCoors.z + Sin(Alpha + AlphaOffset)*Length + m_fCloseInCarHeightOffset; + AlphaOffset -= AlphaDec; } +//--MIAMI: done // Rotate cam behind the car when the car is moving forward bool CCam::RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation) { + float BetaMaxSpeed = 0.15f; + float BetaAcceleration = 0.007f; bool MovingForward = false; + float MaxDiffBeta = DEGTORAD(160.0f); CPhysical *phys = (CPhysical*)CamTargetEntity; float ForwardSpeed = DotProduct(phys->GetForward(), phys->GetSpeed(CVector(0.0f, 0.0f, 0.0f))); if(ForwardSpeed > 0.02f) MovingForward = true; + if(phys->IsVehicle() && (phys->GetModelIndex() == MI_SPARROW || phys->GetModelIndex() == MI_HUNTER)){ + MaxDiffBeta = DEGTORAD(160.0f); + BetaMaxSpeed = 0.1f; + BetaAcceleration = 0.003f; + CVector speed = phys->GetSpeed(CVector(0.0f, 0.0f, 0.0f)); + speed.z = 0.0f; + if(50.0f*speed.Magnitude() > 3.13f) + TargetOrientation = CGeneral::GetATanOfXY(speed.x, speed.y); + } + float Dist = (Source - TargetCoors).Magnitude2D(); float DeltaBeta = TargetOrientation - Beta; while(DeltaBeta >= PI) DeltaBeta -= 2*PI; while(DeltaBeta < -PI) DeltaBeta += 2*PI; - if(Abs(DeltaBeta) > DEGTORAD(20.0f) && MovingForward && TheCamera.m_uiTransitionState == 0) + if(Abs(DeltaBeta) > PI-MaxDiffBeta && MovingForward && TheCamera.m_uiTransitionState == 0) m_bFixingBeta = true; CPad *pad = CPad::GetPad(0); @@ -1982,7 +1772,7 @@ CCam::RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation) SetBeta = true; if(m_bFixingBeta || SetBeta){ - WellBufferMe(TargetOrientation, &Beta, &BetaSpeed, 0.15f, 0.007f, true); + WellBufferMe(TargetOrientation, &Beta, &BetaSpeed, BetaMaxSpeed, BetaAcceleration, true); if(TheCamera.m_bCamDirectlyBehind && &TheCamera.Cams[TheCamera.ActiveCam] == this) Beta = TargetOrientation; @@ -2006,132 +1796,157 @@ CCam::RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation) return true; } -// Move the cam to avoid clipping through buildings -bool -CCam::FixCamIfObscured(CVector &TargetCoors, float TargetHeight, float TargetOrientation) -{ - CVector Target = TargetCoors; - bool UseEntityPos = false; - CVector EntityPos; - static CColPoint colPoint; - static bool LastObscured = false; - - if(Mode == MODE_BEHINDCAR) - Target.z += TargetHeight/2.0f; - if(Mode == MODE_CAM_ON_A_STRING){ - UseEntityPos = true; - Target.z += TargetHeight/2.0f; - EntityPos = CamTargetEntity->GetPosition(); - } - - CVector TempSource = Source; - - bool Obscured1 = false; - bool Obscured2 = false; - bool Fix1 = false; - float Dist1 = 0.0f; - float Dist2 = 0.0f; - CEntity *ent; - if(m_bCollisionChecksOn || LastObscured){ - Obscured1 = CWorld::ProcessLineOfSight(Target, TempSource, colPoint, ent, true, false, false, true, false, true, true); - if(Obscured1){ - Dist1 = (Target - colPoint.point).Magnitude2D(); - Fix1 = true; - if(UseEntityPos) - Obscured1 = CWorld::ProcessLineOfSight(EntityPos, TempSource, colPoint, ent, true, false, false, true, false, true, true); - }else if(m_bFixingBeta){ - float d = (TempSource - Target).Magnitude(); - TempSource.x = Target.x - d*Cos(TargetOrientation); - TempSource.y = Target.y - d*Sin(TargetOrientation); - - // same check again - Obscured2 = CWorld::ProcessLineOfSight(Target, TempSource, colPoint, ent, true, false, false, true, false, true, true); - if(Obscured2){ - Dist2 = (Target - colPoint.point).Magnitude2D(); - if(UseEntityPos) - Obscured2 = CWorld::ProcessLineOfSight(EntityPos, TempSource, colPoint, ent, true, false, false, true, false, true, true); - } - } - LastObscured = Obscured1 || Obscured2; - } - - // nothing to do - if(!LastObscured) - return false; - - if(Fix1){ - Source.x = Target.x - Cos(Beta)*Dist1; - Source.y = Target.y - Sin(Beta)*Dist1; - if(Mode == MODE_BEHINDCAR) - Source = colPoint.point; - }else{ - WellBufferMe(Dist2, &m_fDistanceBeforeChanges, &DistanceSpeed, 0.2f, 0.025f, false); - Source.x = Target.x - Cos(Beta)*m_fDistanceBeforeChanges; - Source.y = Target.y - Sin(Beta)*m_fDistanceBeforeChanges; - } - - if(ResetStatics){ - m_fDistanceBeforeChanges = (Source - Target).Magnitude2D(); - DistanceSpeed = 0.0f; - Source.x = colPoint.point.x; - Source.y = colPoint.point.y; - } - return true; -} +float FIRETRUCK_TRACKING_MULT = 0.1f; +float fTestShiftHeliCamTarget = 0.6f; +float TiltTopSpeed[] = { 0.035f, 0.035f, 0.001f, 0.005f, 0.035f }; +float TiltSpeedStep[] = { 0.016f, 0.016f, 0.0002f, 0.0014f, 0.016f }; +float TiltOverShoot[] = { 1.05f, 1.05f, 0.0f, 0.0f, 1.0f }; +//--MIAMI: done void CCam::Process_Cam_On_A_String(const CVector &CameraTarget, float TargetOrientation, float, float) { if(!CamTargetEntity->IsVehicle()) return; + // unused + // ((CVehicle*)CamTargetEntity)->GetVehicleAppearance(); + FOV = DefaultFOV; if(ResetStatics){ AlphaSpeed = 0.0f; - if(TheCamera.m_bIdleOn) - TheCamera.m_uiTimeWeEnteredIdle = CTimer::GetTimeInMilliseconds(); + m_fTilt = 0.0f; + m_fTiltSpeed = 0.0; } CBaseModelInfo *mi = CModelInfo::GetModelInfo(CamTargetEntity->GetModelIndex()); CVector Dimensions = mi->GetColModel()->boundingBox.max - mi->GetColModel()->boundingBox.min; - float BaseDist = Dimensions.Magnitude2D(); - CVector TargetCoors = CameraTarget; - TargetCoors.z += Dimensions.z - 0.1f; // final + float BaseDist = Dimensions.Magnitude(); + + if(((CVehicle*)CamTargetEntity)->IsBike()) + BaseDist *= 1.45f; + if(((CVehicle*)CamTargetEntity)->GetVehicleAppearance() == VEHICLE_APPEARANCE_HELI && + CamTargetEntity->GetStatus() != STATUS_PLAYER_REMOTE) + TargetCoors += fTestShiftHeliCamTarget * CamTargetEntity->GetUp() * Dimensions.z; + else + TargetCoors.z += 0.8f*Dimensions.z; + Beta = CGeneral::GetATanOfXY(TargetCoors.x - Source.x, TargetCoors.y - Source.y); - while(Alpha >= PI) Alpha -= 2*PI; - while(Alpha < -PI) Alpha += 2*PI; - while(Beta >= PI) Beta -= 2*PI; - while(Beta < -PI) Beta += 2*PI; + Alpha = CGeneral::LimitRadianAngle(Alpha); + Beta = CGeneral::LimitRadianAngle(Beta); + + if(CamTargetEntity->GetModelIndex() == MI_FIRETRUCK && CPad::GetPad(0)->GetCarGunFired() && + ((CVehicle*)CamTargetEntity)->m_vecMoveSpeed.Magnitude2D() < 0.01f){ + float TargetBeta = CamTargetEntity->GetForward().Heading() - ((CAutomobile*)CamTargetEntity)->m_fCarGunLR + HALFPI; + TargetBeta = CGeneral::LimitRadianAngle(TargetBeta); + float DeltaBeta = TargetBeta - Beta; + if(DeltaBeta > PI) DeltaBeta -= TWOPI; + else if(DeltaBeta < -PI) DeltaBeta += TWOPI; + float dist = (TargetCoors - Source).Magnitude(); + dist = FIRETRUCK_TRACKING_MULT*dist*clamp(DeltaBeta, -0.8f, 0.8f); + Source += dist*CrossProduct(Front, CVector(0.0f, 0.0f, 1.0f)); + } m_fDistanceBeforeChanges = (Source - TargetCoors).Magnitude2D(); Cam_On_A_String_Unobscured(TargetCoors, BaseDist); WorkOutCamHeight(TargetCoors, TargetOrientation, Dimensions.z); RotCamIfInFrontCar(TargetCoors, TargetOrientation); - FixCamIfObscured(TargetCoors, Dimensions.z, TargetOrientation); FixCamWhenObscuredByVehicle(TargetCoors); m_cvecTargetCoorsForFudgeInter = TargetCoors; + CVector OrigSource = Source; + if(CWorld::GetIsLineOfSightClear(CamTargetEntity->GetPosition(), m_cvecTargetCoorsForFudgeInter, true, false, false, true, false, false, true)) + TheCamera.AvoidTheGeometry(OrigSource, m_cvecTargetCoorsForFudgeInter, Source, FOV); + else + TheCamera.AvoidTheGeometry(OrigSource, CamTargetEntity->GetPosition(), Source, FOV); + Front = TargetCoors - Source; Front.Normalise(); - GetVectorsReadyForRW(); + + int appearance = ((CVehicle*)CamTargetEntity)->GetVehicleAppearance(); + int index = 0; + TheCamera.GetArrPosForVehicleType(appearance, index); + + if(appearance == VEHICLE_APPEARANCE_HELI){ + float TargetTilt = DotProduct(Front, ((CVehicle*)CamTargetEntity)->GetSpeed(CVector(0.0f, 0.0f, 0.0f))); + CVector UpTarget = CamTargetEntity->GetUp(); + UpTarget.Normalise(); + int dir = TargetTilt < 0.0f ? -1 : 1; + if(m_fTilt != 0.0f) + TargetTilt += TiltOverShoot[index]*TargetTilt/m_fTilt * dir; + WellBufferMe(TargetTilt, &m_fTilt, &m_fTiltSpeed, TiltTopSpeed[index], TiltSpeedStep[index], false); + + Up = CVector(0.0f, 0.0f, 1.0f) - (CVector(0.0f, 0.0f, 1.0f) - UpTarget)*m_fTilt; + Up.Normalise(); + Front.Normalise(); + CVector Left = CrossProduct(Up, Front); + Up = CrossProduct(Front, Left); + Up.Normalise(); + }else{ + float TargetRoll; + if(CPad::GetPad(0)->GetDPadLeft() || CPad::GetPad(0)->GetDPadRight()){ + float fwdSpeed = 180.0f*DotProduct(((CVehicle*)CamTargetEntity)->m_vecMoveSpeed, CamTargetEntity->GetForward()); + if(fwdSpeed > 210.0f) fwdSpeed = 210.0f; + if(CPad::GetPad(0)->GetDPadLeft()) + TargetRoll = DEGTORAD(10.0f)*TiltOverShoot[index] + f_max_role_angle; + else + TargetRoll = -(DEGTORAD(10.0f)*TiltOverShoot[index] + f_max_role_angle); + CVector FwdTarget = CamTargetEntity->GetForward(); + FwdTarget.Normalise(); + float AngleDiff = DotProduct(FwdTarget, Front); + AngleDiff = Acos(Min(Abs(AngleDiff), 1.0f)); + TargetRoll *= fwdSpeed/210.0f * Sin(AngleDiff); + }else{ + float fwdSpeed = 180.0f*DotProduct(((CVehicle*)CamTargetEntity)->m_vecMoveSpeed, CamTargetEntity->GetForward()); + if(fwdSpeed > 210.0f) fwdSpeed = 210.0f; + TargetRoll = CPad::GetPad(0)->GetLeftStickX()/128.0f * fwdSpeed/210.0f; + CVector FwdTarget = CamTargetEntity->GetForward(); + FwdTarget.Normalise(); + float AngleDiff = DotProduct(FwdTarget, Front); + AngleDiff = Acos(Min(Abs(AngleDiff), 1.0f)); + TargetRoll *= (DEGTORAD(10.0f)*TiltOverShoot[index] + f_max_role_angle) * Sin(AngleDiff); + } + + WellBufferMe(TargetRoll, &f_Roll, &f_rollSpeed, 0.15f, 0.07f, false); + Up = CVector(Cos(f_Roll + HALFPI), 0.0f, Sin(f_Roll + HALFPI)); + Up.Normalise(); + Front.Normalise(); + CVector Left = CrossProduct(Up, Front); + Left.Normalise(); + Up = CrossProduct(Front, Left); + Up.Normalise(); + } + ResetStatics = false; } +//--MIAMI: done // Basic Cam on a string algorithm void CCam::Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist) { - CA_MAX_DISTANCE = BaseDist + 0.1f + TheCamera.CarZoomValueSmooth; + int id = CamTargetEntity->GetModelIndex(); + float ExtraDist = 0.0f; + if(id == MI_RCRAIDER || id == MI_RCGOBLIN) + ExtraDist = INIT_RC_HELI_HORI_EXTRA; + else if(id == MI_RCBARON) + ExtraDist = INIT_RC_PLANE_HORI_EXTRA; + + CA_MAX_DISTANCE = BaseDist + 0.1f + TheCamera.CarZoomValueSmooth + ExtraDist; CA_MIN_DISTANCE = Min(BaseDist*0.6f, 3.5f); + if(CA_MIN_DISTANCE > CA_MAX_DISTANCE) + CA_MIN_DISTANCE = CA_MAX_DISTANCE - 0.05f; CVector Dist = Source - TargetCoors; if(ResetStatics) Source = TargetCoors + Dist*(CA_MAX_DISTANCE + 1.0f); + Dist = Source - TargetCoors; + float Length = Dist.Magnitude2D(); if(Length < 0.001f){ // This probably shouldn't happen. reset view @@ -2152,6 +1967,7 @@ CCam::Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist) } } +//--MIAMI: done void CCam::FixCamWhenObscuredByVehicle(const CVector &TargetCoors) { @@ -2159,7 +1975,7 @@ CCam::FixCamWhenObscuredByVehicle(const CVector &TargetCoors) static float HeightFixerCarsObscuring = 0.0f; static float HeightFixerCarsObscuringSpeed = 0.0f; CColPoint colPoint; - CEntity *entity; + CEntity *entity = nil; float HeightTarget = 0.0f; if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, false, true, false, false, false, false, false)){ @@ -2406,7 +2222,6 @@ CCam::Process_TopDownPed(const CVector &CameraTarget, float TargetOrientation, f ResetStatics = false; } -// Identical to M16 void CCam::Process_Rocket(const CVector &CameraTarget, float, float, float) { @@ -2456,8 +2271,8 @@ CCam::Process_Rocket(const CVector &CameraTarget, float, float, float) }else{ float xdir = LookLeftRight < 0.0f ? -1.0f : 1.0f; float ydir = LookUpDown < 0.0f ? -1.0f : 1.0f; - Beta += SQR(LookLeftRight/100.0f)*xdir/17.5 * FOV/80.0f * CTimer::GetTimeStep(); - Alpha += SQR(LookUpDown/150.0f)*ydir/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Beta += SQR(LookLeftRight/100.0f)*xdir*0.8f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Alpha += SQR(LookUpDown/150.0f)*ydir*1.0f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); } while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; @@ -2506,22 +2321,31 @@ CCam::Process_Rocket(const CVector &CameraTarget, float, float, float) ((CPed*)TheCamera.pTargetEntity)->m_fRotationDest = Rotation; } -// Identical to Rocket +float fDuckingBackOffset = 0.5f; +float fDuckingRightOffset = 0.18f; + +//--MIAMI: done void CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) { if(!CamTargetEntity->IsPed()) return; + float BackOffset = 0.3f; static bool FailedTestTwelveFramesAgo = false; RwV3d HeadPos; CVector TargetCoors; + bool isAttached = ((CPed*)CamTargetEntity)->IsPlayer() && ((CPed*)CamTargetEntity)->m_attachedTo; + FOV = DefaultFOV; TargetCoors = CameraTarget; if(ResetStatics){ - Beta = ((CPed*)CamTargetEntity)->m_fRotationCur + HALFPI; + if(isAttached) + Beta = 0.0f; + else + Beta = ((CPed*)CamTargetEntity)->m_fRotationCur + HALFPI; Alpha = 0.0f; m_fInitialPlayerOrientation = ((CPed*)CamTargetEntity)->m_fRotationCur + HALFPI; FailedTestTwelveFramesAgo = false; @@ -2531,14 +2355,6 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) ResetStatics = false; } -#ifndef GTA3_1_1_PATCH - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&HeadPos, PED_HEAD); - Source = HeadPos; - Source.z += 0.1f; - Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation); - Source.y -= 0.19f*Sin(m_fInitialPlayerOrientation); -#endif - // Look around bool UseMouse = false; float MouseX = CPad::GetPad(0)->GetMouseX(); @@ -2555,73 +2371,151 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float) if(UseMouse){ Beta += TheCamera.m_fMouseAccelHorzntl * LookLeftRight * FOV/80.0f; Alpha += TheCamera.m_fMouseAccelVertical * LookUpDown * FOV/80.0f; + }else if(Mode == MODE_HELICANNON_1STPERSON){ + LookLeftRight /= 128.0f; + LookUpDown /= 128.0f; + Beta += LookLeftRight*Abs(LookLeftRight)*0.56f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Alpha += LookUpDown*Abs(LookUpDown)*0.48f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); }else{ float xdir = LookLeftRight < 0.0f ? -1.0f : 1.0f; float ydir = LookUpDown < 0.0f ? -1.0f : 1.0f; - Beta += SQR(LookLeftRight/100.0f)*xdir/17.5 * FOV/80.0f * CTimer::GetTimeStep(); - Alpha += SQR(LookUpDown/150.0f)*ydir/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Beta += SQR(LookLeftRight/100.0f)*xdir*0.8f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Alpha += SQR(LookUpDown/150.0f)*ydir*1.0f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); } while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f); if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); -#ifdef GTA3_1_1_PATCH - HeadPos.x = 0.0f; - HeadPos.y = 0.0f; - HeadPos.z = 0.0f; - ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); - Source = HeadPos; - Source.z += 0.1f; - Source.x -= 0.19f * Cos(m_fInitialPlayerOrientation); - Source.y -= 0.19f * Sin(m_fInitialPlayerOrientation); -#endif + if(((CPed*)CamTargetEntity)->bIsDucking) + BackOffset = 0.8f; + if(isAttached){ + CMatrix mat, rot; + CPed *TargetPed = (CPed*)CamTargetEntity; + TargetPed->PositionAttachedPed(); + CamTargetEntity->GetMatrix().UpdateRW(); + CamTargetEntity->UpdateRwFrame(); + CamTargetEntity->UpdateRpHAnim(); + + HeadPos.x = 0.0f; + HeadPos.y = 0.0f; + HeadPos.z = 0.0f; + TargetPed->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); + Source = HeadPos; + Source += 0.1f*CamTargetEntity->GetUp(); + Source -= BackOffset*CamTargetEntity->GetForward(); + + if(TargetPed->m_attachRotStep < PI){ + if(Beta > TargetPed->m_attachRotStep){ + Beta = TargetPed->m_attachRotStep; + CAutomobile *heli = (CAutomobile*)TargetPed->m_attachedTo; + if(heli->IsVehicle() && heli->IsCar() && heli->IsRealHeli() && heli->m_fHeliOrientation > 0.0f){ + float heliOrient = heli->m_fHeliOrientation + CTimer::GetTimeStep()*0.01f; + if(heliOrient < 0.0f) heliOrient += TWOPI; + else if(heliOrient > TWOPI) heliOrient -= TWOPI; + heli->SetHeliOrientation(heliOrient); + } + }else if(Beta < -TargetPed->m_attachRotStep){ + Beta = -TargetPed->m_attachRotStep; + CAutomobile *heli = (CAutomobile*)TargetPed->m_attachedTo; + if(heli->IsVehicle() && heli->IsCar() && heli->IsRealHeli() && heli->m_fHeliOrientation > 0.0f){ + float heliOrient = heli->m_fHeliOrientation - CTimer::GetTimeStep()*0.01f; + if(heliOrient < 0.0f) heliOrient += TWOPI; + else if(heliOrient > TWOPI) heliOrient -= TWOPI; + heli->SetHeliOrientation(heliOrient); + } + } + }else{ + while(Beta < -PI) Beta += 2*PI; + while(Beta >= PI) Beta -= 2*PI; + } - TargetCoors.x = 3.0f * Cos(Alpha) * Cos(Beta) + Source.x; - TargetCoors.y = 3.0f * Cos(Alpha) * Sin(Beta) + Source.y; - TargetCoors.z = 3.0f * Sin(Alpha) + Source.z; - Front = TargetCoors - Source; - Front.Normalise(); - Source += Front*0.4f; + mat = TargetPed->m_attachedTo->GetMatrix(); + rot.SetRotateX(Alpha); + switch(TargetPed->m_attachType){ + case 1: rot.RotateZ(Beta + HALFPI); break; + case 2: rot.RotateZ(Beta + PI); break; + case 3: rot.RotateZ(Beta - HALFPI); break; + } + mat = mat * rot; + Front = mat.GetForward(); + Up = mat.GetUp(); + TargetCoors = Source + 3.0f*Front; + RwCameraSetNearClipPlane(Scene.camera, 0.4f); - if(m_bCollisionChecksOn){ - if(!CWorld::GetIsLineOfSightClear(TargetCoors, Source, true, true, false, true, false, true, true)){ - RwCameraSetNearClipPlane(Scene.camera, 0.4f); - FailedTestTwelveFramesAgo = true; + float Rotation = CGeneral::GetATanOfXY(Front.x, Front.y) - HALFPI; + ((CPed*)TheCamera.pTargetEntity)->m_fRotationCur = Rotation; + ((CPed*)TheCamera.pTargetEntity)->m_fRotationDest = Rotation; + }else{ + CamTargetEntity->GetMatrix().UpdateRW(); + CamTargetEntity->UpdateRwFrame(); + CamTargetEntity->UpdateRpHAnim(); + HeadPos.x = 0.0f; + HeadPos.y = 0.0f; + HeadPos.z = 0.0f; + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); + Source = HeadPos; + Source.z += 0.1f; + if(((CPed*)CamTargetEntity)->bIsDucking){ + Source.x -= fDuckingBackOffset*CamTargetEntity->GetForward().x; + Source.y -= fDuckingBackOffset*CamTargetEntity->GetForward().y; + Source.x -= fDuckingRightOffset*CamTargetEntity->GetRight().x; + Source.y -= fDuckingRightOffset*CamTargetEntity->GetRight().y; }else{ - CVector TestPoint; - TestPoint.x = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Cos(Beta + DEGTORAD(35.0f)) + Source.x; - TestPoint.y = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Sin(Beta + DEGTORAD(35.0f)) + Source.y; - TestPoint.z = 3.0f * Sin(Alpha - DEGTORAD(20.0f)) + Source.z; - if(!CWorld::GetIsLineOfSightClear(TestPoint, Source, true, true, false, true, false, true, true)){ + Source.x -= BackOffset*CamTargetEntity->GetForward().x; + Source.y -= BackOffset*CamTargetEntity->GetForward().y; + } + + TargetCoors.x = 3.0f * Cos(Alpha) * Cos(Beta) + Source.x; + TargetCoors.y = 3.0f * Cos(Alpha) * Sin(Beta) + Source.y; + TargetCoors.z = 3.0f * Sin(Alpha) + Source.z; + Front = TargetCoors - Source; + Front.Normalise(); + Source += Front*0.4f; + + if(m_bCollisionChecksOn){ + if(!CWorld::GetIsLineOfSightClear(TargetCoors, Source, true, true, false, true, false, true, true)){ RwCameraSetNearClipPlane(Scene.camera, 0.4f); FailedTestTwelveFramesAgo = true; }else{ - TestPoint.x = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Cos(Beta - DEGTORAD(35.0f)) + Source.x; - TestPoint.y = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Sin(Beta - DEGTORAD(35.0f)) + Source.y; + CVector TestPoint; + TestPoint.x = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Cos(Beta + DEGTORAD(35.0f)) + Source.x; + TestPoint.y = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Sin(Beta + DEGTORAD(35.0f)) + Source.y; TestPoint.z = 3.0f * Sin(Alpha - DEGTORAD(20.0f)) + Source.z; if(!CWorld::GetIsLineOfSightClear(TestPoint, Source, true, true, false, true, false, true, true)){ RwCameraSetNearClipPlane(Scene.camera, 0.4f); FailedTestTwelveFramesAgo = true; - }else - FailedTestTwelveFramesAgo = false; + }else{ + TestPoint.x = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Cos(Beta - DEGTORAD(35.0f)) + Source.x; + TestPoint.y = 3.0f * Cos(Alpha - DEGTORAD(20.0f)) * Sin(Beta - DEGTORAD(35.0f)) + Source.y; + TestPoint.z = 3.0f * Sin(Alpha - DEGTORAD(20.0f)) + Source.z; + if(!CWorld::GetIsLineOfSightClear(TestPoint, Source, true, true, false, true, false, true, true)){ + RwCameraSetNearClipPlane(Scene.camera, 0.4f); + FailedTestTwelveFramesAgo = true; + }else + FailedTestTwelveFramesAgo = false; + } } } - } - if(FailedTestTwelveFramesAgo) - RwCameraSetNearClipPlane(Scene.camera, 0.4f); - Source -= Front*0.4f; + if(FailedTestTwelveFramesAgo) + RwCameraSetNearClipPlane(Scene.camera, 0.4f); + Source -= Front*0.4f; - GetVectorsReadyForRW(); - float Rotation = CGeneral::GetATanOfXY(Front.x, Front.y) - HALFPI; - ((CPed*)TheCamera.pTargetEntity)->m_fRotationCur = Rotation; - ((CPed*)TheCamera.pTargetEntity)->m_fRotationDest = Rotation; + GetVectorsReadyForRW(); + float Rotation = CGeneral::GetATanOfXY(Front.x, Front.y) - HALFPI; + ((CPed*)TheCamera.pTargetEntity)->m_fRotationCur = Rotation; + ((CPed*)TheCamera.pTargetEntity)->m_fRotationDest = Rotation; + } } +float fBike1stPersonOffsetZ = 0.15f; + +//--MIAMI: done void -CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, float, float) +CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, float SpeedVar, float TargetSpeedVar) { + float BackOffset = 0.3f; static float DontLookThroughWorldFixer = 0.0f; CVector TargetCoors; @@ -2639,6 +2533,7 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl Alpha = 0.0f; m_fInitialPlayerOrientation = ((CPed*)CamTargetEntity)->m_fRotationCur + HALFPI; } + TheCamera.m_fAvoidTheGeometryProbsTimer = 0.0f; DontLookThroughWorldFixer = 0.0f; } @@ -2659,23 +2554,34 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl ResetStatics = false; } + CamTargetEntity->GetMatrix().UpdateRW(); + CamTargetEntity->UpdateRwFrame(); + CamTargetEntity->UpdateRpHAnim(); + ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(HeadPos, PED_HEAD); Source = HeadPos; Source.z += 0.1f; - Source.x -= 0.19f*Cos(m_fInitialPlayerOrientation); - Source.y -= 0.19f*Sin(m_fInitialPlayerOrientation); + if(((CPed*)CamTargetEntity)->bIsDucking){ + Source.x -= fDuckingBackOffset*CamTargetEntity->GetForward().x; + Source.y -= fDuckingBackOffset*CamTargetEntity->GetForward().y; + Source.x -= fDuckingRightOffset*CamTargetEntity->GetRight().x; + Source.y -= fDuckingRightOffset*CamTargetEntity->GetRight().y; + }else{ + Source.x -= BackOffset*CamTargetEntity->GetForward().x; + Source.y -= BackOffset*CamTargetEntity->GetForward().y; + } float LookLeftRight, LookUpDown; LookLeftRight = -CPad::GetPad(0)->LookAroundLeftRight(); LookUpDown = CPad::GetPad(0)->LookAroundUpDown(); float xdir = LookLeftRight < 0.0f ? -1.0f : 1.0f; float ydir = LookUpDown < 0.0f ? -1.0f : 1.0f; - Beta += SQR(LookLeftRight/100.0f)*xdir/17.5 * FOV/80.0f * CTimer::GetTimeStep(); - Alpha += SQR(LookUpDown/150.0f)*ydir/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Beta += SQR(LookLeftRight/100.0f)*xdir*0.8f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Alpha += SQR(LookUpDown/150.0f)*ydir*1.0f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; if(Alpha > DEGTORAD(60.0f)) Alpha = DEGTORAD(60.0f); - if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); + else if(Alpha < -DEGTORAD(89.5f)) Alpha = -DEGTORAD(89.5f); TargetCoors.x = 3.0f * Cos(Alpha) * Cos(Beta) + Source.x; TargetCoors.y = 3.0f * Cos(Alpha) * Sin(Beta) + Source.y; @@ -2719,16 +2625,48 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl ((CPed*)TheCamera.pTargetEntity)->m_fRotationDest = Rotation; }else{ assert(CamTargetEntity->IsVehicle()); + + if(((CVehicle*)CamTargetEntity)->IsBike() && + (((CBike*)CamTargetEntity)->bWheelieCam || TheCamera.m_fAvoidTheGeometryProbsTimer > 0.0f)){ + if(CPad::GetPad(0)->GetLeftShoulder2() || CPad::GetPad(0)->GetRightShoulder2()){ + TheCamera.m_fAvoidTheGeometryProbsTimer = 0.0f; + ((CBike*)CamTargetEntity)->bWheelieCam = false; + }else if(Process_WheelCam(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar)){ + if(((CBike*)CamTargetEntity)->bWheelieCam) + TheCamera.m_fAvoidTheGeometryProbsTimer = 50.0f; + else{ + TheCamera.m_fAvoidTheGeometryProbsTimer -= CTimer::GetTimeStep(); + ((CBike*)CamTargetEntity)->bWheelieCam = true; + } + return; + }else{ + TheCamera.m_fAvoidTheGeometryProbsTimer = 0.0f; + ((CBike*)CamTargetEntity)->bWheelieCam = false; + } + } + + CMatrix *matrix = &CamTargetEntity->GetMatrix(); + if(((CVehicle*)CamTargetEntity)->IsBike()){ + ((CBike*)CamTargetEntity)->CalculateLeanMatrix(); + matrix = &((CBike*)CamTargetEntity)->m_leanMatrix; + } + CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(CamTargetEntity->GetModelIndex()); CVector CamPos = mi->GetFrontSeatPosn(); CamPos.x = 0.0f; - CamPos.y += -0.08f; + CamPos.y += 0.08f; CamPos.z += 0.62f; FOV = 60.0f; - Source = Multiply3x3(CamTargetEntity->GetMatrix(), CamPos); + Source = Multiply3x3(*matrix, CamPos); Source += CamTargetEntity->GetPosition(); if(((CVehicle*)CamTargetEntity)->IsBoat()) Source.z += 0.5f; + else if(((CVehicle*)CamTargetEntity)->IsBike() && ((CVehicle*)CamTargetEntity)->pDriver){ + CVector Neck(0.0f, 0.0f, 0.0f); + ((CVehicle*)CamTargetEntity)->pDriver->m_pedIK.GetComponentPosition(*(RwV3d*)&Neck, PED_NECK); + Neck += ((CVehicle*)CamTargetEntity)->m_vecMoveSpeed * CTimer::GetTimeStep(); + Source.z = Neck.z + fBike1stPersonOffsetZ; + } if(((CVehicle*)CamTargetEntity)->IsUpsideDown()){ if(DontLookThroughWorldFixer < 0.5f) @@ -2746,9 +2684,9 @@ CCam::Process_1stPerson(const CVector &CameraTarget, float TargetOrientation, fl DontLookThroughWorldFixer = 0.0f; } Source.z += DontLookThroughWorldFixer; - Front = CamTargetEntity->GetForward(); + Front = matrix->GetForward(); Front.Normalise(); - Up = CamTargetEntity->GetUp(); + Up = matrix->GetUp(); Up.Normalise(); CVector Right = CrossProduct(Front, Up); Right.Normalise(); @@ -2849,8 +2787,8 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float, }else{ float xdir = LookLeftRight < 0.0f ? -1.0f : 1.0f; float ydir = LookUpDown < 0.0f ? -1.0f : 1.0f; - Beta += SQR(LookLeftRight/100.0f)*xdir/17.5 * FOV/80.0f * CTimer::GetTimeStep(); - Alpha += SQR(LookUpDown/150.0f)*ydir/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Beta += SQR(LookLeftRight/100.0f)*xdir*0.8f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Alpha += SQR(LookUpDown/150.0f)*ydir*1.0f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); } while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; @@ -2952,8 +2890,8 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float }else{ float xdir = LookLeftRight < 0.0f ? -1.0f : 1.0f; float ydir = LookUpDown < 0.0f ? -1.0f : 1.0f; - Beta += SQR(LookLeftRight/100.0f)*xdir/17.5 * FOV/80.0f * CTimer::GetTimeStep(); - Alpha += SQR(LookUpDown/150.0f)*ydir/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Beta += SQR(LookLeftRight/100.0f)*xdir*0.8f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); + Alpha += SQR(LookUpDown/150.0f)*ydir*1.0f/14.0f * FOV/80.0f * CTimer::GetTimeStep(); } while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; @@ -3043,6 +2981,13 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float ((CPed*)TheCamera.pTargetEntity)->m_fRotationDest = Rotation; } +float INIT_SYPHON_GROUND_DIST = 2.419f; +float INIT_SYPHON_ALPHA_OFFSET = -DEGTORAD(3.0f); +float INIT_SYPHON_DEGREE_OFFSET = -DEGTORAD(30.0f); +float FrontOffsetSyphon = -DEGTORAD(25.5f); // unused +float INIT_SYPHON_Z_OFFSET = -0.5f; + +//--MIAMI: done void CCam::Process_Syphon(const CVector &CameraTarget, float, float, float) { @@ -3053,82 +2998,123 @@ CCam::Process_Syphon(const CVector &CameraTarget, float, float, float) static bool CameraObscured = false; // unused FailedClippingTestPrevously - static float BetaOffset = DEGTORAD(18.0f); + static float BetaOffset = INIT_SYPHON_DEGREE_OFFSET; // unused AngleToGoTo // unused AngleToGoToSpeed // unused DistBetweenPedAndPlayerPreviouslyOn - static float HeightDown = -0.5f; - static float PreviousDistForInter; + static float HeightDown = INIT_SYPHON_Z_OFFSET; + static float AlphaOffset = INIT_SYPHON_ALPHA_OFFSET; + static bool NegateBetaOffset = true; CVector TargetCoors; - CVector2D vDist; - float fDist, fAimingDist; + float fAimingDist; float TargetAlpha; - CColPoint colPoint; - CEntity *entity; + bool StandingOnMovingThing = false; TargetCoors = CameraTarget; + AlphaOffset = INIT_SYPHON_ALPHA_OFFSET; + float GroundDist = INIT_SYPHON_GROUND_DIST; - if(TheCamera.Cams[TheCamera.ActiveCam].Mode != MODE_SYPHON) - return; - - vDist = Source - TargetCoors; - fDist = vDist.Magnitude(); - if(fDist == 0.0f) - Source = TargetCoors + CVector(1.0f, 1.0f, 0.0f); - else - Source = TargetCoors + CVector(vDist.x/fDist * 1.7f, vDist.y/fDist * 1.7f, 0.0f); - if(fDist > 1.7f) - fDist = 1.7f; - - Beta = CGeneral::GetATanOfXY(Source.x - TargetCoors.x, Source.y - TargetCoors.y); while(Beta >= PI) Beta -= 2*PI; while(Beta < -PI) Beta += 2*PI; float NewBeta = CGeneral::GetATanOfXY(TheCamera.m_cvecAimingTargetCoors.x - TargetCoors.x, TheCamera.m_cvecAimingTargetCoors.y - TargetCoors.y) + PI; if(ResetStatics){ - CameraObscured = false; - float TestBeta1 = NewBeta - BetaOffset - Beta; - float TestBeta2 = NewBeta + BetaOffset - Beta; - MakeAngleLessThan180(TestBeta1); - MakeAngleLessThan180(TestBeta2); - if(Abs(TestBeta1) < Abs(TestBeta2)) - BetaOffset = -BetaOffset; + BetaOffset = INIT_SYPHON_DEGREE_OFFSET; + Beta = CGeneral::GetATanOfXY(Source.x - TargetCoors.x, Source.y - TargetCoors.y); // some unuseds ResetStatics = false; } + if(NegateBetaOffset) + BetaOffset = -INIT_SYPHON_DEGREE_OFFSET; Beta = NewBeta + BetaOffset; Source = TargetCoors; - Source.x += 1.7f*Cos(Beta); - Source.y += 1.7f*Sin(Beta); + Source.x += GroundDist*Cos(Beta); + Source.y += GroundDist*Sin(Beta); + CPhysical *ground = (CPhysical*)((CPed*)CamTargetEntity)->m_pCurSurface; + if(ground && (ground->IsVehicle() || ground->IsObject())) + StandingOnMovingThing = true; TargetCoors.z += m_fSyphonModeTargetZOffSet; + + bool PlayerTooClose = false; fAimingDist = (TheCamera.m_cvecAimingTargetCoors - TargetCoors).Magnitude2D(); - if(fAimingDist < 6.5f) + if(fAimingDist < 6.5f){ fAimingDist = 6.5f; + PlayerTooClose = true; + } TargetAlpha = CGeneral::GetATanOfXY(fAimingDist, TheCamera.m_cvecAimingTargetCoors.z - TargetCoors.z); + if(ResetStatics) // BUG: can never happen + Alpha = -TargetAlpha; while(TargetAlpha >= PI) TargetAlpha -= 2*PI; while(TargetAlpha < -PI) TargetAlpha += 2*PI; + while(Alpha >= PI) Alpha -= 2*PI; + while(Alpha < -PI) Alpha += 2*PI; // inlined - WellBufferMe(-TargetAlpha, &Alpha, &AlphaSpeed, 0.07f, 0.015f, true); + if(StandingOnMovingThing) + WellBufferMe(-TargetAlpha, &Alpha, &AlphaSpeed, 0.07f/2.0f, 0.015f/2.0f, true); + else + WellBufferMe(-TargetAlpha, &Alpha, &AlphaSpeed, 0.07f, 0.015f, true); - Source.z += fDist*Sin(Alpha) + fDist*0.2f; + Source.z += GroundDist*Sin(Alpha+AlphaOffset) + GroundDist*0.2f; if(Source.z < TargetCoors.z + HeightDown) Source.z = TargetCoors.z + HeightDown; - CameraObscured = CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, false, false, true, false, true, true); - // PreviousDistForInter unused - if(CameraObscured){ - PreviousDistForInter = (TargetCoors - colPoint.point).Magnitude2D(); - Source = colPoint.point; - }else - PreviousDistForInter = 1.7f; + if(!PlayerTooClose){ + CColPoint point; + CEntity *entity = nil; + CWorld::pIgnoreEntity = CamTargetEntity; + if(CWorld::ProcessLineOfSight(TheCamera.m_cvecAimingTargetCoors, Source, point, entity, true, false, false, true, false, false, true)){ + CVector TestFront = TheCamera.m_cvecAimingTargetCoors - Source; + TestFront.Normalise(); + CVector CamToPlayer = CameraTarget - Source; + CVector CamToCol = point.point - Source; + if(DotProduct(TestFront, CamToCol) > DotProduct(TestFront, CamToPlayer)){ + // collision is beyond player + float ColDist = (TheCamera.m_cvecAimingTargetCoors - point.point).Magnitude(); + CVector PlayerToTarget = TheCamera.m_cvecAimingTargetCoors - CameraTarget; + float PlayerToTargetDist = PlayerToTarget.Magnitude(); + PlayerToTarget.Normalise(); + CVector Center = TheCamera.m_cvecAimingTargetCoors - ColDist*PlayerToTarget; + float Radius = (point.point - Center).Magnitude(); + if(CWorld::TestSphereAgainstWorld(Center, Radius, nil, true, false, false, true, false, true)){ + CVector LineToCol = gaTempSphereColPoints[0].point - Center; + LineToCol -= DotProduct(LineToCol, PlayerToTarget)*PlayerToTarget; + // unused + CVector LineToPrevCol = point.point - Center; + LineToPrevCol -= DotProduct(LineToPrevCol, PlayerToTarget)*PlayerToTarget; + float LineDist = LineToCol.Magnitude(); + float NewBetaOffset = 0.0f; + if(LineDist > 0.0f && ColDist > 0.1f){ + // scale offset at center to offset at player + float DistOffset = LineDist/ColDist * PlayerToTargetDist; + // turn into an angle + NewBetaOffset = 0.9f*Asin(Min(DistOffset/GroundDist, 1.0f)); + } + if(NewBetaOffset < BetaOffset){ + float Ratio = NewBetaOffset / BetaOffset; + BetaOffset = NewBetaOffset; + Beta = NewBeta + NewBetaOffset; + GroundDist *= Max(Ratio, 0.5f); + Source.x = TargetCoors.x + GroundDist*Cos(Beta); + Source.y = TargetCoors.y + GroundDist*Sin(Beta); + Source.z += (1.0f-Ratio)*0.5f; + } + } + } + } + CWorld::pIgnoreEntity = nil; + } - m_cvecTargetCoorsForFudgeInter = TargetCoors; - Front = TargetCoors - Source; - m_fMinDistAwayFromCamWhenInterPolating = Front.Magnitude2D(); - if(m_fMinDistAwayFromCamWhenInterPolating < 1.1f) - RwCameraSetNearClipPlane(Scene.camera, Max(m_fMinDistAwayFromCamWhenInterPolating - 0.35f, 0.05f)); + Front = TheCamera.m_cvecAimingTargetCoors - Source; + float TargetDistGround = Front.Magnitude2D(); Front.Normalise(); + m_cvecTargetCoorsForFudgeInter = Source + TargetDistGround*Front; + m_cvecTargetCoorsForFudgeInter.z = TargetCoors.z; + + CVector OrigSource = Source; + TheCamera.AvoidTheGeometry(OrigSource, CameraTarget + CVector(0.0f, 0.0f, 0.75f), Source, FOV); + Source.z = OrigSource.z; + GetVectorsReadyForRW(); } @@ -3589,7 +3575,7 @@ CCam::Process_FlyBy(const CVector&, float, float, float) } } -void +bool CCam::Process_WheelCam(const CVector&, float, float, float) { FOV = DefaultFOV; @@ -3612,6 +3598,7 @@ CCam::Process_WheelCam(const CVector&, float, float, float) float Roll = Cos((CTimer::GetTimeInMilliseconds()&0x1FFFF)/(float)0x1FFFF * TWOPI); Up = Cos(Roll*0.4f)*NewUp + Sin(Roll*0.4f)*Left; + return true; } void @@ -4481,8 +4468,8 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient BetaOffset = LookLeftRight * TheCamera.m_fMouseAccelHorzntl * FOV/80.0f; AlphaOffset = LookUpDown * TheCamera.m_fMouseAccelVertical * FOV/80.0f; }else{ - BetaOffset = LookLeftRight * fStickSens * (0.5f/10.0f) * FOV/80.0f * CTimer::GetTimeStep(); - AlphaOffset = LookUpDown * fStickSens * (0.3f/10.0f) * FOV/80.0f * CTimer::GetTimeStep(); + BetaOffset = LookLeftRight * fStickSens * (1.0f/20.0f) * FOV/80.0f * CTimer::GetTimeStep(); + AlphaOffset = LookUpDown * fStickSens * (0.6f/20.0f) * FOV/80.0f * CTimer::GetTimeStep(); } // Stop centering once stick has been touched @@ -4556,7 +4543,7 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, true, true, true, false, false, true)){ float PedColDist = (TargetCoors - colPoint.point).Magnitude(); float ColCamDist = CamDist - PedColDist; - if(entity->IsPed() && ColCamDist > 1.0f){ + if(entity->IsPed() && ColCamDist > DEFAULT_NEAR + 0.1f){ // Ped in the way but not clipping through if(CWorld::ProcessLineOfSight(colPoint.point, Source, colPoint, entity, true, true, true, true, false, false, true)){ PedColDist = (TargetCoors - colPoint.point).Magnitude(); @@ -4595,6 +4582,8 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient Source += (TargetCoors - Source)*0.3f; // Keep testing + Near = RwCameraGetNearClipPlane(Scene.camera); + radius = ViewPlaneWidth*Near; entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, false); i++; diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp index 9ebec1a6..423a3da6 100644 --- a/src/core/Camera.cpp +++ b/src/core/Camera.cpp @@ -20,6 +20,7 @@ #include "Replay.h" #include "CutsceneMgr.h" #include "Renderer.h" +#include "Timecycle.h" #include "MBlur.h" #include "Text.h" #include "Hud.h" @@ -61,6 +62,8 @@ enum CCamera TheCamera; bool CCamera::m_bUseMouse3rdPerson = true; bool bDidWeProcessAnyCinemaCam; +float CCamera::m_fMouseAccelHorzntl; +float CCamera::m_fMouseAccelVertical; float CCamera::m_f3rdPersonCHairMultX; float CCamera::m_f3rdPersonCHairMultY; @@ -75,26 +78,16 @@ float CCamera::m_f3rdPersonCHairMultY; CCamera::CCamera(void) { -#ifdef GTA3_1_1_PATCH - m_fMouseAccelHorzntl = 0.0025f; - m_fMouseAccelVertical = 0.003f; -#endif Init(); } +//--MIAMI: done void CCamera::Init(void) { -#ifdef GTA3_1_1_PATCH - float fMouseAccelHorzntl = m_fMouseAccelHorzntl; - float fMouseAccelVertical = m_fMouseAccelVertical; -#endif memset(this, 0, sizeof(CCamera)); // this is fine, no vtable -#ifdef GTA3_1_1_PATCH - m_fMouseAccelHorzntl = fMouseAccelHorzntl; - m_fMouseAccelVertical = fMouseAccelVertical; -#endif m_pRwCamera = nil; + m_bPlayerWasOnBike = false; m_1rstPersonRunCloseToAWall = false; m_fPositionAlongSpline = 0.0f; m_bCameraJustRestored = false; @@ -103,8 +96,22 @@ CCamera::Init(void) Cams[2].Init(); Cams[0].Mode = CCam::MODE_FOLLOWPED; Cams[1].Mode = CCam::MODE_FOLLOWPED; - unknown = 0; - m_bJustJumpedOutOf1stPersonBecauseOfTarget = 0; + m_bEnable1rstPersonCamCntrlsScript = false; + m_bAllow1rstPersonWeaponsCamera = false; + m_bVehicleSuspenHigh = false; + Cams[0].m_fMinRealGroundDist = 1.85f; + // TODO: what weird value is this? + Cams[0].m_fTargetCloseInDist = 2.0837801f - Cams[0].m_fMinRealGroundDist; + Cams[0].m_fTargetZoomGroundOne = 0.25f; + Cams[0].m_fTargetZoomGroundTwo = 1.5f; + Cams[0].m_fTargetZoomGroundThree = 4.0f; + Cams[0].m_fTargetZoomOneZExtra = -0.14f; + Cams[0].m_fTargetZoomTwoZExtra = 0.16f; + Cams[0].m_fTargetZoomThreeZExtra = 0.25f; + // TODO: another weird value + Cams[0].m_fTargetZoomZCloseIn = 0.90040702f; + m_bMoveCamToAvoidGeom = false; + SetMotionBlur(CTimeCycle::GetBlurRed(), CTimeCycle::GetBlurGreen(), CTimeCycle::GetBlurBlue(), m_motionBlur, MBLUR_NORMAL); ClearPlayerWeaponMode(); m_bInATunnelAndABigVehicle = false; m_iModeObbeCamIsInForCar = OBBE_INVALID; @@ -122,8 +129,8 @@ CCamera::Init(void) Cams[1].m_fPlayerVelocity = 0.0f; Cams[2].m_fPlayerVelocity = 0.0f; m_bHeadBob = false; - m_fFractionInterToStopMovingTarget = 0.25f; - m_fFractionInterToStopCatchUpTarget = 0.75f; + m_fFractionInterToStopMoving = 0.25f; + m_fFractionInterToStopCatchUp = 0.75f; m_fGaitSwayBuffer = 0.85f; m_bScriptParametersSetForInterPol = false; m_uiCamShakeStart = 0; @@ -168,10 +175,11 @@ CCamera::Init(void) m_bMusicFading = false; m_fTimeToFadeMusic = 0.0f; m_fFLOATingFadeMusic = 0.0f; + m_fMouseAccelHorzntl = 0.003f; + m_fMouseAccelVertical = 0.0025f; } - m_bMoveCamToAvoidGeom = false; if(FrontEndMenuManager.m_bWantToRestart) - m_bMoveCamToAvoidGeom = true; + m_fTimeToFadeMusic = 0.0f; m_bStartingSpline = false; m_iTypeOfSwitch = INTERPOLATION; m_bUseScriptZoomValuePed = false; @@ -190,6 +198,8 @@ CCamera::Init(void) m_uiTimeLastChange = 0; m_uiTimeWeEnteredIdle = 0; m_bIdleOn = false; + m_uiTimeWeLeftIdle_StillNoInput = 0; + m_uiTimeWeEnteredIdle = 0; LODDistMultiplier = 1.0f; m_bCamDirectlyBehind = false; m_bCamDirectlyInFront = false; @@ -209,12 +219,10 @@ CCamera::Init(void) m_uiTransitionState = 0; m_uiTimeTransitionStart = 0; m_bLookingAtPlayer = true; -#ifndef GTA3_1_1_PATCH - m_fMouseAccelHorzntl = 0.0025f; - m_fMouseAccelVertical = 0.003f; -#endif m_f3rdPersonCHairMultX = 0.53f; m_f3rdPersonCHairMultY = 0.4f; + m_fAvoidTheGeometryProbsTimer = 0.0f; + m_nAvoidTheGeometryProbsDirn = 0; } void @@ -322,12 +330,12 @@ CCamera::Process(void) currentTime = m_uiTransitionDuration; float fractionInter = (float) currentTime / m_uiTransitionDuration; - if(fractionInter <= m_fFractionInterToStopMovingTarget){ + if(fractionInter <= m_fFractionInterToStopMoving){ float inter; - if(m_fFractionInterToStopMovingTarget == 0.0f) + if(m_fFractionInterToStopMoving == 0.0f) inter = 0.0f; else - inter = (m_fFractionInterToStopMovingTarget - fractionInter)/m_fFractionInterToStopMovingTarget; + inter = (m_fFractionInterToStopMoving - fractionInter)/m_fFractionInterToStopMoving; inter = 0.5f - 0.5*Cos(inter*PI); // smooth it m_vecSourceWhenInterPol = m_cvecStartingSourceForInterPol + inter*m_cvecSourceSpeedAtStartInter; @@ -381,12 +389,12 @@ CCamera::Process(void) } CamUp.Normalise(); FOV = m_fFOVWhenInterPol; - }else if(fractionInter > m_fFractionInterToStopMovingTarget && fractionInter <= 1.0f){ + }else if(fractionInter > m_fFractionInterToStopMoving && fractionInter <= 1.0f){ float inter; - if(m_fFractionInterToStopCatchUpTarget == 0.0f) + if(m_fFractionInterToStopCatchUp == 0.0f) inter = 0.0f; else - inter = (fractionInter - m_fFractionInterToStopMovingTarget)/m_fFractionInterToStopCatchUpTarget; + inter = (fractionInter - m_fFractionInterToStopMoving)/m_fFractionInterToStopCatchUp; inter = 0.5f - 0.5*Cos(inter*PI); // smooth it CamSource = m_vecSourceWhenInterPol + inter*(Cams[ActiveCam].Source - m_vecSourceWhenInterPol); @@ -1610,7 +1618,7 @@ CCamera::UpdateSoundDistances(void) } f = (n + 1) / 6.0f; SoundDistUp = (1.0f-f)*SoundDistUpAsReadOld + f*SoundDistUpAsRead; - +/* // check left n = (CTimer::GetFrameCounter()+2) % 12; if(n == 0){ @@ -1637,6 +1645,7 @@ CCamera::UpdateSoundDistances(void) } f = (n + 1) / 6.0f; SoundDistRight = (1.0f-f)*SoundDistRightAsReadOld + f*SoundDistRightAsRead; +*/ } void @@ -1681,6 +1690,129 @@ CamShakeNoPos(CCamera *cam, float strength) } } +bool bAvoidTest1 = false; +bool bAvoidTest2 = false; // unused +bool bAvoidTest3 = false; // unused +float fRangePlayerRadius = 0.5f; +float fCloseNearClipLimit = 0.15f; +float fAvoidTweakFOV = 1.15f; +float fAvoidProbTimerDamp = 0.9f; + +//--MIAMI: done +void +CCamera::AvoidTheGeometry(const CVector &Source, const CVector &TargetPos, CVector &NewSource, float FOV) +{ + float Beta = 0.0f; + float Alpha = 0.0f; + + CVector vDist = TargetPos - Source; + m_vecClearGeometryVec = CVector(0.0f, 0.0f, 0.0f); + float fDist = vDist.Magnitude(); + float fDistOnGround = vDist.Magnitude2D(); + if(vDist.x == 0.0f && vDist.y == 0.0f) + Beta = CGeneral::GetATanOfXY(GetForward().x, GetForward().y); + else + Beta = CGeneral::GetATanOfXY(vDist.x, vDist.y); + if(fDistOnGround != 0.0f || vDist.z != 0.0f) + Alpha = CGeneral::GetATanOfXY(fDistOnGround, vDist.z); + CVector Front(Cos(Alpha)*Cos(Beta), Cos(Alpha)*Sin(Beta), Sin(Alpha)); + NewSource = TargetPos - Front*fDist; + Front.Normalise(); + + // Clip camera source + CColPoint point; + CEntity *entity = nil; + CWorld::pIgnoreEntity = pTargetEntity; + if(CWorld::ProcessLineOfSight(TargetPos, NewSource, point, entity, true, false, false, true, false, false, true)){ + CVector ClipPoint1 = point.point; + NewSource = point.point; + if(!bAvoidTest1){ + if(CWorld::ProcessLineOfSight(NewSource, TargetPos, point, entity, false, true, true, true, false, false, true)){ + if((NewSource - point.point).Magnitude() < RwCameraGetNearClipPlane(Scene.camera)) + NewSource = point.point; + else if((NewSource - ClipPoint1).Magnitude() < RwCameraGetNearClipPlane(Scene.camera)) + NewSource = ClipPoint1; + } + } + } + CWorld::pIgnoreEntity = nil; + + + vDist = TargetPos - NewSource; + fDist = vDist.Magnitude(); + if(FindPlayerPed()) + if(fDist - fRangePlayerRadius < RwCameraGetNearClipPlane(Scene.camera)) + RwCameraSetNearClipPlane(Scene.camera, Max(fDist - fRangePlayerRadius, fCloseNearClipLimit)); + + + static float fClearGeomAmount; + static float fClearGeomAmountSpeed; + float Near = RwCameraGetNearClipPlane(Scene.camera); + float ViewPlaneHeight = Tan(DEGTORAD(FOV) / 2.0f); + float ViewPlaneWidth = ViewPlaneHeight * CDraw::CalculateAspectRatio() * fAvoidTweakFOV; + CVector Center = NewSource + Front*Near; + float fClearGeomTarget = 0.0f; + if(CWorld::TestSphereAgainstWorld(Center, ViewPlaneWidth, nil, true, false, false, true, false, true)){ + CVector CamToCol = gaTempSphereColPoints[0].point - NewSource; + float FrontDist = DotProduct(CamToCol, Front); + CVector CenterToCol = gaTempSphereColPoints[0].point - Center; + if(FrontDist < DEFAULT_NEAR && FrontDist > fCloseNearClipLimit){ + if(FrontDist < RwCameraGetNearClipPlane(Scene.camera)) + RwCameraSetNearClipPlane(Scene.camera, FrontDist); + }else if(FrontDist < fCloseNearClipLimit) + RwCameraSetNearClipPlane(Scene.camera, fCloseNearClipLimit); + + float ColDepth = ViewPlaneWidth - CenterToCol.Magnitude(); // amount of radius in collision + CenterToCol.Normalise(); + CVector Normal = gaTempSphereColPoints[0].normal; + Normal.Normalise(); + if(-DotProduct(CenterToCol, Normal) < 0.0f) + Normal = -Normal; // always push away from col surface + float DistToMove = DotProduct(-ColDepth*CenterToCol, Normal); + m_vecClearGeometryVec = DistToMove*Normal; // move source so this point is out of collision + + if(pTargetEntity && pTargetEntity->IsPed() && RwCameraGetNearClipPlane(Scene.camera) < 2.0f*fCloseNearClipLimit){ + float TargetNormalDir = DotProduct(Normal, pTargetEntity->GetForward()); + if(TargetNormalDir < 0.0f){ + // target looking towards collision + if(m_fAvoidTheGeometryProbsTimer < 0.0f) + m_fAvoidTheGeometryProbsTimer = 0.0f; + m_fAvoidTheGeometryProbsTimer += CTimer::GetTimeStep(); + }else if(TargetNormalDir > 0.5f){ + // target looking away from collision + if(m_fAvoidTheGeometryProbsTimer > 0.0f) + m_fAvoidTheGeometryProbsTimer = 0.0f; + m_fAvoidTheGeometryProbsTimer -= CTimer::GetTimeStep(); + } + + if(m_nAvoidTheGeometryProbsDirn == 0){ + if(CrossProduct(pTargetEntity->GetPosition() - NewSource, Normal).z > 0.0f) + m_nAvoidTheGeometryProbsDirn = -1; + else + m_nAvoidTheGeometryProbsDirn = 1; + } + } + + fClearGeomTarget = 1.0f; + } + + m_fAvoidTheGeometryProbsTimer *= Pow(fAvoidProbTimerDamp, CTimer::GetTimeStep()); + WellBufferMe(fClearGeomTarget, &fClearGeomAmount, &fClearGeomAmountSpeed, 0.2f, 0.05f, false); + m_vecClearGeometryVec *= fClearGeomAmount; + m_bMoveCamToAvoidGeom = true; +} + +void +CCamera::GetArrPosForVehicleType(int apperance, int &index) +{ + switch(apperance){ + case VEHICLE_APPEARANCE_CAR: index = 0; break; + case VEHICLE_APPEARANCE_BIKE: index = 1; break; + case VEHICLE_APPEARANCE_HELI: index = 2; break; + case VEHICLE_APPEARANCE_PLANE: index = 3; break; + case VEHICLE_APPEARANCE_BOAT: index = 4; break; + } +} void @@ -1828,28 +1960,25 @@ CCamera::SetCamPositionForFixedMode(const CVector &Source, const CVector &UpOffS } - -/* - * On PS2 the transition happens between Cams[1] and Cams[2]. - * On PC the whole system has been changed. - */ +//--MIAMI: done void CCamera::StartTransition(int16 newMode) { - bool foo = false; + bool switchFromFixedSyphon = false; bool switchSyphonMode = false; - bool switchPedToCar = false; bool switchPedMode = false; + bool switchPedToCar = false; + bool switchFromFight = false; + bool switchBikeToPed = false; bool switchFromFixed = false; bool switch1stPersonToVehicle = false; float betaOffset, targetBeta, camBeta, deltaBeta; int door; bool vehicleVertical; -// missing on PS2 m_bItsOkToLookJustAtThePlayer = false; - m_fFractionInterToStopMovingTarget = 0.25f; - m_fFractionInterToStopCatchUpTarget = 0.75f; + m_fFractionInterToStopMoving = 0.25f; + m_fFractionInterToStopCatchUp = 0.75f; if(Cams[ActiveCam].Mode == CCam::MODE_SYPHON_CRIM_IN_FRONT || Cams[ActiveCam].Mode == CCam::MODE_FOLLOWPED || @@ -1859,16 +1988,19 @@ CCamera::StartTransition(int16 newMode) newMode == CCam::MODE_FOLLOWPED || newMode == CCam::MODE_SYPHON || newMode == CCam::MODE_SPECIAL_FIXED_FOR_SYPHON) - m_bItsOkToLookJustAtThePlayer = true; + switchPedMode = true; if(newMode == CCam::MODE_CAM_ON_A_STRING) switchPedToCar = true; } -// + if(Cams[ActiveCam].Mode == CCam::MODE_SPECIAL_FIXED_FOR_SYPHON) + switchFromFixedSyphon = true; + if(Cams[ActiveCam].Mode == CCam::MODE_CAM_ON_A_STRING && newMode == CCam::MODE_FOLLOWPED && m_bPlayerWasOnBike) + switchBikeToPed = true; if(Cams[ActiveCam].Mode == CCam::MODE_SYPHON_CRIM_IN_FRONT && newMode == CCam::MODE_SYPHON) switchSyphonMode = true; if(Cams[ActiveCam].Mode == CCam::MODE_FIGHT_CAM && newMode == CCam::MODE_FOLLOWPED) - switchPedMode = true; + switchFromFight = true; if(Cams[ActiveCam].Mode == CCam::MODE_FIXED) switchFromFixed = true; @@ -1889,12 +2021,6 @@ CCamera::StartTransition(int16 newMode) ((CPed*)pTargetEntity)->m_fRotationDest = angle; } -/* // PS2 - ActiveCam = (ActiveCam+1)%2; - Cams[ActiveCam].Init(); - Cams[ActiveCam].Mode = newMode; - */ - Cams[ActiveCam].m_cvecCamFixedModeVector = m_vecFixedModeVector; Cams[ActiveCam].CamTargetEntity = pTargetEntity; Cams[ActiveCam].m_cvecCamFixedModeSource = m_vecFixedModeSource; @@ -1909,16 +2035,17 @@ CCamera::StartTransition(int16 newMode) newMode == CCam::MODE_1STPERSON_RUNABOUT || newMode == CCam::MODE_M16_1STPERSON_RUNABOUT || newMode == CCam::MODE_FIGHT_CAM_RUNABOUT || - newMode == CCam::MODE_HELICANNON_1STPERSON) + newMode == CCam::MODE_HELICANNON_1STPERSON || + newMode == CCam::MODE_CAMERA) Cams[ActiveCam].Alpha = 0.0f; - // PS2 also copies values to ActiveCam here switch(Cams[ActiveCam].Mode) case CCam::MODE_SNIPER_RUNABOUT: case CCam::MODE_ROCKETLAUNCHER_RUNABOUT: case CCam::MODE_1STPERSON_RUNABOUT: case CCam::MODE_M16_1STPERSON_RUNABOUT: case CCam::MODE_FIGHT_CAM_RUNABOUT: + case CCam::MODE_CAMERA: if(newMode == CCam::MODE_CAM_ON_A_STRING || newMode == CCam::MODE_BEHINDBOAT) switch1stPersonToVehicle = true; @@ -1932,16 +2059,6 @@ CCamera::StartTransition(int16 newMode) betaOffset = DEGTORAD(55.0f); if(m_bJustCameOutOfGarage){ m_bUseTransitionBeta = true; -/* - // weird logic... - if(CMenuManager::m_ControlMethod == CONTROL_CLASSIC) - Cams[ActiveCam].m_fTransitionBeta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y) + PI; - else if(Cams[ActiveCam].Front.x != 0.0f && Cams[ActiveCam].Front.y != 0.0f) // && is wrong here - Cams[ActiveCam].m_fTransitionBeta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y) + PI; - else - Cams[ActiveCam].m_fTransitionBeta = 0.0f; -*/ - // this is better: if(Cams[ActiveCam].Front.x != 0.0f || Cams[ActiveCam].Front.y != 0.0f) Cams[ActiveCam].m_fTransitionBeta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y) + PI; else @@ -2010,6 +2127,7 @@ CCamera::StartTransition(int16 newMode) case CCam::MODE_M16_1STPERSON_RUNABOUT: case CCam::MODE_FIGHT_CAM_RUNABOUT: case CCam::MODE_HELICANNON_1STPERSON: + case CCam::MODE_CAMERA: if(FindPlayerVehicle()) Cams[ActiveCam].Beta = Atan2(FindPlayerVehicle()->GetForward().x, FindPlayerVehicle()->GetForward().y); else @@ -2027,42 +2145,7 @@ CCamera::StartTransition(int16 newMode) if(!m_bLookingAtPlayer || m_bJustCameOutOfGarage) break; m_bUseTransitionBeta = true; - targetBeta = CGeneral::GetATanOfXY(pTargetEntity->GetForward().x, pTargetEntity->GetForward().y); - camBeta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y); - deltaBeta = targetBeta - camBeta; - while(deltaBeta >= PI) deltaBeta -= 2*PI; - while(deltaBeta < -PI) deltaBeta += 2*PI; - deltaBeta = Abs(deltaBeta); - // switchFromFixed logic again here, skipped - if(switchFromFixed){ - Cams[ActiveCam].m_fTransitionBeta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y); - break; - } - - door = FindPlayerPed()->m_vehEnterType; - if(deltaBeta > HALFPI){ - if(((CVehicle*)pTargetEntity)->IsUpsideDown()){ - if(door == CAR_DOOR_LF || door == CAR_DOOR_LR) // BUG: game checks LF twice - betaOffset = -DEGTORAD(57.0f); - }else{ - if(door == CAR_DOOR_RF || door == CAR_DOOR_RR) - betaOffset = -DEGTORAD(57.0f); - } - Cams[ActiveCam].m_fTransitionBeta = targetBeta + betaOffset + PI; - }else{ - if(((CVehicle*)pTargetEntity)->IsUpsideDown()){ - if(door == CAR_DOOR_RF || door == CAR_DOOR_RR) - betaOffset = -DEGTORAD(57.0f); - else if(door == CAR_DOOR_LF || door == CAR_DOOR_LR) - betaOffset = DEGTORAD(57.0f); - }else{ - if(door == CAR_DOOR_LF || door == CAR_DOOR_LR) - betaOffset = -DEGTORAD(57.0f); - else if(door == CAR_DOOR_RF || door == CAR_DOOR_RR) - betaOffset = DEGTORAD(57.0f); - } - Cams[ActiveCam].m_fTransitionBeta = targetBeta + betaOffset; - } + Cams[ActiveCam].m_fTransitionBeta = CGeneral::GetATanOfXY(Cams[ActiveCam].Front.x, Cams[ActiveCam].Front.y); break; case CCam::MODE_BEHINDBOAT: @@ -2087,27 +2170,34 @@ CCamera::StartTransition(int16 newMode) m_uiTransitionDuration = 1350; if(switchSyphonMode) m_uiTransitionDuration = 1800; - else if(switchPedMode) + else if(switchFromFight) m_uiTransitionDuration = 750; -// not on PS2 else if(switchPedToCar){ - m_fFractionInterToStopMovingTarget = 0.2f; - m_fFractionInterToStopCatchUpTarget = 0.8f; - m_uiTransitionDuration = 950; + m_fFractionInterToStopMoving = 0.1f; + m_fFractionInterToStopCatchUp = 0.9f; + m_uiTransitionDuration = 750; + }else if(switchFromFixedSyphon){ + m_fFractionInterToStopMoving = 0.0f; + m_fFractionInterToStopCatchUp = 1.0f; + m_uiTransitionDuration = 600; }else if(switchFromFixed){ - m_fFractionInterToStopMovingTarget = 0.05f; - m_fFractionInterToStopCatchUpTarget = 0.95f; + m_fFractionInterToStopMoving = 0.05f; + m_fFractionInterToStopCatchUp = 0.95f; + }else if(switchBikeToPed){ + m_uiTransitionDuration = 800; }else if(switch1stPersonToVehicle){ - m_fFractionInterToStopMovingTarget = 0.0f; - m_fFractionInterToStopCatchUpTarget = 1.0f; + m_fFractionInterToStopMoving = 0.0f; + m_fFractionInterToStopCatchUp = 1.0f; m_uiTransitionDuration = 1; + }else if(switchPedMode){ + m_fFractionInterToStopMoving = 0.5f; + m_fFractionInterToStopCatchUp = 0.5f; + m_uiTransitionDuration = 350; }else m_uiTransitionDuration = 1350; // already set above -// m_uiTransitionState = 1; m_uiTimeTransitionStart = CTimer::GetTimeInMilliseconds(); m_uiTransitionJUSTStarted = 1; -// PS2 returns here if(m_vecDoingSpecialInterPolation){ m_cvecStartingSourceForInterPol = SourceDuringInter; m_cvecStartingTargetForInterPol = TargetDuringInter; @@ -2138,10 +2228,22 @@ CCamera::StartTransition(int16 newMode) m_fBetaSpeedAtStartInter = Cams[ActiveCam].m_fBetaSpeedOverOneFrame; m_fFOVSpeedAtStartInter = Cams[ActiveCam].m_fFovSpeedOverOneFrame; Cams[ActiveCam].ResetStatics = true; - if(!m_bLookingAtPlayer && m_bScriptParametersSetForInterPol){ - m_fFractionInterToStopMovingTarget = m_fScriptPercentageInterToStopMoving; - m_fFractionInterToStopCatchUpTarget = m_fScriptPercentageInterToCatchUp; - m_uiTransitionDuration = m_fScriptTimeForInterPolation; + if(m_bLookingAtPlayer){ + if(switchPedMode) + m_uiTransitionDurationTargetCoors = 350; + else + m_uiTransitionDurationTargetCoors = 600; + m_fFractionInterToStopMovingTarget = 0.0f; + m_fFractionInterToStopCatchUpTarget = 1.0f; + }else{ + if(m_bScriptParametersSetForInterPol){ + m_fFractionInterToStopMoving = m_fScriptPercentageInterToStopMoving; + m_fFractionInterToStopCatchUp = m_fScriptPercentageInterToCatchUp; + m_uiTransitionDuration = m_fScriptTimeForInterPolation; + } + m_uiTransitionDurationTargetCoors = m_uiTransitionDuration; + m_fFractionInterToStopMovingTarget = m_fFractionInterToStopMoving; + m_fFractionInterToStopCatchUpTarget = m_fFractionInterToStopCatchUp; } } diff --git a/src/core/Camera.h b/src/core/Camera.h index 669ac740..9cb35636 100644 --- a/src/core/Camera.h +++ b/src/core/Camera.h @@ -121,7 +121,7 @@ public: float f_max_role_angle; //=DEGTORAD(5.0f); float f_Roll; //used for adding a slight roll to the camera in the - float f_rollSpeed; + float f_rollSpeed; //TODO(MIAMI): remove float m_fSyphonModeTargetZOffSet; float m_fRoadOffSet; float m_fAmountFractionObscured; @@ -146,7 +146,8 @@ public: float m_fRealGroundDist; //used for follow ped mode float m_fTargetBeta; float m_fTimeElapsedFloat; - + float m_fTilt; + float m_fTiltSpeed; float m_fTransitionBeta; float m_fTrueBeta; float m_fTrueAlpha; @@ -164,6 +165,16 @@ public: float CA_MAX_DISTANCE; float SpeedVar; + float m_fTargetZoomGroundOne; + float m_fTargetZoomGroundTwo; + float m_fTargetZoomGroundThree; + float m_fTargetZoomOneZExtra; + float m_fTargetZoomTwoZExtra; + float m_fTargetZoomThreeZExtra; + float m_fTargetZoomZCloseIn; + float m_fMinRealGroundDist; + float m_fTargetCloseInDist; + CVector m_cvecSourceSpeedOverOneFrame; CVector m_cvecTargetSpeedOverOneFrame; CVector m_cvecUpOverOneFrame; @@ -198,10 +209,8 @@ public: void GetVectorsReadyForRW(void); CVector DoAverageOnVector(const CVector &vec); float GetPedBetaAngleForClearView(const CVector &Target, float Dist, float BetaOffset, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies); - void WorkOutCamHeightWeeCar(CVector &TargetCoors, float TargetOrientation); void WorkOutCamHeight(const CVector &TargetCoors, float TargetOrientation, float TargetHeight); bool RotCamIfInFrontCar(CVector &TargetCoors, float TargetOrientation); - bool FixCamIfObscured(CVector &TargetCoors, float TargetHeight, float TargetOrientation); void Cam_On_A_String_Unobscured(const CVector &TargetCoors, float BaseDist); void FixCamWhenObscuredByVehicle(const CVector &TargetCoors); void LookBehind(void); @@ -234,7 +243,7 @@ public: void Process_BehindBoat(const CVector &CameraTarget, float TargetOrientation, float, float); void Process_Fight_Cam(const CVector &CameraTarget, float TargetOrientation, float, float); void Process_FlyBy(const CVector&, float, float, float); - void Process_WheelCam(const CVector&, float, float, float); + bool Process_WheelCam(const CVector&, float, float, float); void Process_Fixed(const CVector &CameraTarget, float, float, float); void Process_Player_Fallen_Water(const CVector &CameraTarget, float TargetOrientation, float, float); void Process_Circle(const CVector &CameraTarget, float, float, float); @@ -263,8 +272,6 @@ public: void Process_FollowCar_SA(const CVector &CameraTarget, float TargetOrientation, float, float); }; -VALIDATE_SIZE(CCam, 0x1A4); - class CCamPathSplines { public: @@ -358,6 +365,7 @@ public: bool m_bInitialNoNodeStaticsSet; bool m_bIgnoreFadingStuffForMusic; bool m_bPlayerIsInGarage; + bool m_bPlayerWasOnBike; bool m_bJustCameOutOfGarage; bool m_bJustInitalised; bool m_bJust_Switched; @@ -383,6 +391,8 @@ public: bool m_1rstPersonRunCloseToAWall; bool m_bHeadBob; bool m_bVehicleSuspenHigh; + bool m_bEnable1rstPersonCamCntrlsScript; + bool m_bAllow1rstPersonWeaponsCamera; bool m_bFailedCullZoneTestPreviously; bool m_FadeTargetIsSplashScreen; @@ -398,15 +408,16 @@ public: uint8 m_uiTransitionState; // 0:one mode 1:transition uint32 m_uiTimeLastChange; + uint32 m_uiTimeWeLeftIdle_StillNoInput; uint32 m_uiTimeWeEnteredIdle; uint32 m_uiTimeTransitionStart; uint32 m_uiTransitionDuration; + uint32 m_uiTransitionDurationTargetCoors; int m_BlurBlue; int m_BlurGreen; int m_BlurRed; int m_BlurType; - uint32 unknown; // some counter having to do with music int m_iWorkOutSpeedThisNumFrames; int m_iNumFramesSoFar; @@ -466,15 +477,16 @@ public: float PedZoomIndicator; #endif float PlayerExhaustion; - float SoundDistUp, SoundDistLeft, SoundDistRight; - float SoundDistUpAsRead, SoundDistLeftAsRead, SoundDistRightAsRead; - float SoundDistUpAsReadOld, SoundDistLeftAsReadOld, SoundDistRightAsReadOld; + float SoundDistUp; + float SoundDistUpAsRead; + float SoundDistUpAsReadOld; + float m_fAvoidTheGeometryProbsTimer; + int16 m_nAvoidTheGeometryProbsDirn; float m_fWideScreenReductionAmount; float m_fStartingFOVForInterPol; - // not static yet - float m_fMouseAccelHorzntl;// acceleration multiplier for 1st person controls - float m_fMouseAccelVertical;// acceleration multiplier for 1st person controls + static float m_fMouseAccelHorzntl;// acceleration multiplier for 1st person controls + static float m_fMouseAccelVertical;// acceleration multiplier for 1st person controls static float m_f3rdPersonCHairMultX; static float m_f3rdPersonCHairMultY; @@ -501,7 +513,7 @@ public: CVector m_vecSourceWhenInterPol; CVector m_vecTargetWhenInterPol; CVector m_vecUpWhenInterPol; - + CVector m_vecClearGeometryVec; CVector m_vecGameCamPos; CVector SourceDuringInter; CVector TargetDuringInter; @@ -509,7 +521,9 @@ public: RwCamera *m_pRwCamera; CEntity *pTargetEntity; CCamPathSplines m_arrPathArray[MAX_NUM_OF_SPLINETYPES]; +#ifdef GTA_TRAIN CTrainCamNode m_arrTrainCamNode[MAX_NUM_OF_NODES]; +#endif CMatrix m_cameraMatrix; bool m_bGarageFixedCamPositionSet; bool m_vecDoingSpecialInterPolation; @@ -527,6 +541,8 @@ public: float m_fFLOATingFadeMusic; float m_fTimeToFadeOut; float m_fTimeToFadeMusic; + float m_fFractionInterToStopMoving; + float m_fFractionInterToStopCatchUp; float m_fFractionInterToStopMovingTarget; float m_fFractionInterToStopCatchUpTarget; float m_fGaitSwayBuffer; @@ -560,6 +576,8 @@ public: void InitialiseCameraForDebugMode(void); void CamShake(float strength, float x, float y, float z); bool Get_Just_Switched_Status() { return m_bJust_Switched; } + void AvoidTheGeometry(const CVector &Source, const CVector &TargetPos, CVector &NewSource, float FOV); + void GetArrPosForVehicleType(int apperance, int &index); // Who's in control void TakeControl(CEntity *target, int16 mode, int16 typeOfSwitch, int32 controller); |