// ************************************************************************************* // ! DayZPlayerCamera1stPersonVehicle - first person in vehicle // ************************************************************************************* class DayZPlayerCamera1stPersonVehicle extends DayZPlayerCamera1stPerson { override void OnUpdate(float pDt, out DayZPlayerCameraResult pOutResult) { super.OnUpdate(pDt, pOutResult); pOutResult.m_fUseHeading = 0.0; pOutResult.m_bUpdateEveryFrame = GetGame().IsPhysicsExtrapolationEnabled(); } } // ************************************************************************************* // ! DayZPlayerCamera3rdPersonVehicle - 3rd person in vehicle (generic) // ************************************************************************************* class DayZPlayerCamera3rdPersonVehicle extends DayZPlayerCameraBase { static const float CONST_UD_MIN = -85.0; //!< down limit static const float CONST_UD_MAX = 85.0; //!< up limit const float UP_ANGLE_CAP = 10; // max up angle, doesnt require gamecode sync static const float CONST_LR_MIN = -160.0; //!< down limit static const float CONST_LR_MAX = 160.0; //!< up limit const float CONST_LINEAR_VELOCITY_STRENGTH = 0.025; const float CONST_ANGULAR_VELOCITY_STRENGTH = 0.025; const float CONST_ANGULAR_LAG_YAW_STRENGTH = 4.0; const float CONST_ANGULAR_LAG_PITCH_STRENGTH = 1.5; const float CONST_ANGULAR_LAG_ROLL_STRENGTH = 0.5; void DayZPlayerCamera3rdPersonVehicle( DayZPlayer pPlayer, HumanInputController pInput ) { //Print("new camera: DayZPlayerCamera3rdPersonVehicle"); m_fDistance = 4.0; m_CameraOffsetMS = "0.0 1.3 0.0"; HumanCommandVehicle vehicleCommand = pPlayer.GetCommand_Vehicle(); if ( vehicleCommand ) { Transport transport = vehicleCommand.GetTransport(); if ( transport ) { m_Transport = transport; m_fDistance = transport.GetTransportCameraDistance(); m_CameraOffsetMS = transport.GetTransportCameraOffset(); } } } override void OnActivate( DayZPlayerCamera pPrevCamera, DayZPlayerCameraResult pPrevCameraResult ) { if (pPrevCamera) { vector baseAngles = pPrevCamera.GetBaseAngles(); m_fUpDownAngle = baseAngles[0]; m_fLeftRightAngle = baseAngles[1]; vector addAngles = pPrevCamera.GetAdditiveAngles(); m_fUpDownAngleAdd = addAngles[0]; m_fLeftRightAngleAdd = addAngles[1]; } m_LagOffsetPosition = vector.Zero; m_fLagOffsetVelocityX[0] = 0; m_fLagOffsetVelocityY[0] = 0; m_fLagOffsetVelocityZ[0] = 0; m_fLagOffsetVelocityYaw[0] = 0; m_fLagOffsetVelocityPitch[0] = 0; m_fLagOffsetVelocityRoll[0] = 0; m_LagOffsetOrientation[0] = 0; m_LagOffsetOrientation[1] = 0; m_LagOffsetOrientation[2] = 0; if (m_pPlayer) { vector rotDiffLS = m_pPlayer.GetOrientation() * Math.DEG2RAD; m_LagOffsetOrientation[0] = rotDiffLS[0]; m_LagOffsetOrientation[1] = rotDiffLS[1]; m_LagOffsetOrientation[2] = rotDiffLS[2]; } } override void OnUpdate( float pDt, out DayZPlayerCameraResult pOutResult ) { //! get player transform vector playerTransformWS[4]; m_pPlayer.GetTransform(playerTransformWS); //! get vehicle and set it as ignore entity for camera collision solver IEntity vehicle = m_Transport; pOutResult.m_CollisionIgnoreEntity = vehicle; //! update camera offset vector cameraPosition = vector.Zero; if ( vehicle ) { vector vehiclePositionWS = vehicle.GetOrigin(); vector vehiclePositionMS = vehiclePositionWS.InvMultiply4(playerTransformWS); cameraPosition = vehiclePositionMS + m_CameraOffsetMS; } //! orientation LS m_CurrentCameraYaw = UpdateLRAngleUnlocked(m_fLeftRightAngle, m_fLeftRightAngleAdd, CONST_LR_MIN, CONST_LR_MAX, pDt); m_CurrentCameraPitch = UpdateUDAngleUnlocked(m_fUpDownAngle, m_fUpDownAngleAdd, CONST_UD_MIN, CONST_UD_MAX, pDt); m_CurrentCameraRoll = 0; //! create LS lag from vehicle velocities vector posDiffLS = vector.Zero; vector rotDiffLS = vector.Zero; vector rotWS = m_pPlayer.GetOrientation(); float maxRoll = 10; rotWS[2] = Math.Clamp(rotWS[2], -maxRoll, maxRoll) / maxRoll; rotWS[2] = rotWS[2] * rotWS[2] * rotWS[2]; rotWS[2] = rotWS[2] * maxRoll; rotWS[2] = 0; rotWS = rotWS * Math.DEG2RAD; vector velocity = GetVelocity(vehicle); if (vehicle) { vector posDiffWS = velocity * CONST_LINEAR_VELOCITY_STRENGTH; posDiffLS = posDiffLS + posDiffWS.InvMultiply3(playerTransformWS); vector rotDiffWS = dBodyGetAngularVelocity(vehicle) * CONST_ANGULAR_VELOCITY_STRENGTH; rotDiffLS = rotDiffLS + rotDiffWS.InvMultiply3(playerTransformWS); vector tempRot1 = rotDiffLS; rotDiffLS[0] = tempRot1[1]; rotDiffLS[1] = tempRot1[2]; rotDiffLS[2] = tempRot1[0]; rotWS[0] = rotWS[0] + rotDiffLS[0]; rotWS[1] = rotWS[1] + rotDiffLS[1]; rotWS[2] = rotWS[2] + rotDiffLS[2]; } //! smooth it! m_LagOffsetPosition[0] = Math.SmoothCD(m_LagOffsetPosition[0], posDiffLS[0], m_fLagOffsetVelocityX, 0.3, 1000, pDt); m_LagOffsetPosition[1] = Math.SmoothCD(m_LagOffsetPosition[1], posDiffLS[1], m_fLagOffsetVelocityY, 0.3, 1000, pDt); m_LagOffsetPosition[2] = Math.SmoothCD(m_LagOffsetPosition[2], posDiffLS[2], m_fLagOffsetVelocityZ, 0.3, 1000, pDt); m_LagOffsetOrientation[0] = Math.SmoothCDPI2PI(m_LagOffsetOrientation[0], rotWS[0], m_fLagOffsetVelocityYaw, 0.3, 1000, pDt); m_LagOffsetOrientation[1] = Math.SmoothCDPI2PI(m_LagOffsetOrientation[1], rotWS[1], m_fLagOffsetVelocityPitch, 0.3, 1000, pDt); m_LagOffsetOrientation[2] = Math.SmoothCDPI2PI(m_LagOffsetOrientation[2], rotWS[2], m_fLagOffsetVelocityRoll, 0.3, 1000, pDt); //! setup orientation vector rot = m_LagOffsetOrientation * Math.RAD2DEG; if (vehicle) { vector rotTM[3]; Math3D.YawPitchRollMatrix(rot, rotTM); Math3D.MatrixInvMultiply3(playerTransformWS, rotTM, rotTM); // because we don't have m_fIgnoreParentYaw set vector tempRot = Math3D.MatrixToAngles(rotTM); rot[0] = tempRot[0]; } rot[0] = rot[0] * (1.0 + (Math.InverseLerp(0.0, 1.0 + CONST_ANGULAR_LAG_YAW_STRENGTH, Math.AbsFloat(rotDiffLS[0])) * CONST_ANGULAR_LAG_YAW_STRENGTH)); rot[1] = rot[1] * (1.0 + (Math.InverseLerp(0.0, 1.0 + CONST_ANGULAR_LAG_PITCH_STRENGTH, Math.AbsFloat(rotDiffLS[1])) * CONST_ANGULAR_LAG_PITCH_STRENGTH)); rot[2] = rot[2] * (1.0 + (Math.InverseLerp(0.0, 1.0 + CONST_ANGULAR_LAG_ROLL_STRENGTH, Math.AbsFloat(rotDiffLS[2])) * CONST_ANGULAR_LAG_ROLL_STRENGTH)); rot = GetCurrentOrientation() + rot; float distance = m_fDistance; distance -= (2 * Math.Clamp(Math.InverseLerp(UP_ANGLE_CAP * 0.5, CONST_UD_MAX, rot[1]), 0, 1)); if (rot[1] > UP_ANGLE_CAP) { rot[1] = UP_ANGLE_CAP; } Math3D.YawPitchRollMatrix(rot, pOutResult.m_CameraTM); //! setup position pOutResult.m_CameraTM[3] = cameraPosition - m_LagOffsetPosition; //! setup rest pOutResult.m_fDistance = distance; pOutResult.m_fUseHeading = 0.0; pOutResult.m_fInsideCamera = 0.0; pOutResult.m_fIgnoreParentRoll = 1.0; pOutResult.m_fIgnoreParentPitch = 1.0; //pOutResult.m_fIgnoreParentYaw = 1.0; pOutResult.m_bUpdateEveryFrame = GetGame().IsPhysicsExtrapolationEnabled(); StdFovUpdate(pDt, pOutResult); super.OnUpdate(pDt, pOutResult); } override vector GetBaseAngles() { vector a; a[0] = m_fUpDownAngle; a[1] = m_fLeftRightAngle; a[2] = 0; return a; } override vector GetAdditiveAngles() { vector a; a[0] = m_fUpDownAngleAdd; a[1] = m_fLeftRightAngleAdd; a[2] = 0; return a; } //! runtime config protected vector m_CameraOffsetMS; //!< model space offset protected float m_fDistance; //!< distance from start //! runtime values protected float m_fUpDownAngle; //!< up down angle in rad protected float m_fUpDownAngleAdd; //!< up down angle in rad protected float m_fLeftRightAngle; //!< left right angle in rad protected float m_fLeftRightAngleAdd; //!< left right angle in rad //! lag offsets protected vector m_LagOffsetPosition; protected vector m_LagOffsetOrientation; protected float m_fLagOffsetVelocityX[1]; protected float m_fLagOffsetVelocityY[1]; protected float m_fLagOffsetVelocityZ[1]; protected float m_fLagOffsetVelocityYaw[1]; protected float m_fLagOffsetVelocityPitch[1]; protected float m_fLagOffsetVelocityRoll[1]; //! cache protected Transport m_Transport; }