void CCameraView::RunModeTransition(SViewParams &viewParams) { if(!m_bModeTransition) return; //update time-limit m_fTransitionTimeout -= m_fFrameTime; if(m_fTransitionTimeout < 0.1f) m_fTransitionTimeout = 0.1f; //compute transition speed float fDist = max(0.01f, (m_lastViewParams.position - viewParams.position).len()); float fTransitionTime = 1.0f - clamp(fDist / 5.0f, 0.0f, 1.0f); fTransitionTime = max(g_fModeTransitionFast, g_fModeTransitionSlow * fTransitionTime); //after timeout, catch up instantly (0 transition time) fTransitionTime *= m_fTransitionTimeout; //fade values viewParams.position = InterpolateTo(m_lastViewParams.position, viewParams.position, fTransitionTime); viewParams.dist = (m_vTargetPosition - viewParams.position).len(); //fov is always interpolated (on update) //viewParams.fov = InterpolateTo(m_lastViewParams.fov, viewParams.fov, fTransitionTime); //terminate if(fDist < 0.02f) { m_bModeTransition = false; return; } }
void CCameraView::UpdateSettings(SViewParams &viewParams) { //cache some values for interpolation //float fLastDistance = m_curSettings.dist; ECamTypes eOldType = m_curSettings.camType; //get camera settings CCameraManager *pCamMan = g_pGame->GetCameraManager(); CameraID iCurCam = pCamMan->GetActiveCameraId(); pCamMan->GetCameraSettings(iCurCam, m_curSettings); if(eOldType != m_curSettings.camType) { m_bModeTransition = true; m_fTransitionTimeout = 1.0f; } //pre-calculations viewParams.fov = InterpolateTo(m_lastViewParams.fov, DEG2RAD(m_curSettings.FOV), 0.5f); //get frame time m_fFrameTime = max(gEnv->pTimer->GetFrameTime(), 0.0001f); // add cam offsets m_curSettings.dist = g_pGameCVars->cl_cam_orbit_distance; // Vec3 camOffset(Vec3Constants<float>::fVec3_Zero); Vec3 camOffset = viewParams.rotation.GetColumn1().Cross(Vec3Constants<float>::fVec3_OneZ); camOffset.NormalizeFast(); camOffset *= g_pGameCVars->cl_cam_orbit_offsetX; camOffset.z = g_pGameCVars->cl_cam_orbit_offsetZ; //update/interpolation position m_vTargetPosition = m_pTarget->GetWorldPos() + m_vTargetOffset + camOffset; //InterpolateTo(m_vTargetPosition, m_pTarget->GetWorldPos() + m_vTargetOffset, 0.1f); }
void CCameraTracking::UpdateAutoFollow(const SViewParams &viewParams, const CPlayer &hero) { if(g_pGameCVars->cl_cam_auto_follow_rate > 0.0f) //auto-tracking { //if there is an obstacle nearby, don't try to rotate into it float lastObstacleDist = (m_vLastObstaclePos - viewParams.position).len(); if(lastObstacleDist < g_fAutoTrackObstacleDistance) return; if(hero.GetActorStats()->speedFlat < g_pGameCVars->cl_cam_auto_follow_movement_speed) { //only rotate when player moves m_fAutoRotateSpeed = 0.0f; return; } //get camera direction Vec3 camDir = -m_pCamRayScan->GetRayDir(eRAY_CENTER); camDir.z = 0.0f; camDir.Normalize(); //get Player direction Vec3 heroDirection = (hero.GetAnimatedCharacter()->GetAnimLocation().q * FORWARD_DIRECTION); //compute angle between directions float dt = camDir.Dot(heroDirection); dt = clamp(dt, -1.0f, 1.0f); float angle = cry_acosf(dt); //check angle being bigger than threshold if(angle > g_pGameCVars->cl_cam_auto_follow_threshold) { float moveSpeed = max(0.002f, gf_PI*m_fFrameTime*g_pGameCVars->cl_cam_auto_follow_rate); m_fAutoRotateSpeed = InterpolateTo(max(0.002f, m_fAutoRotateSpeed), moveSpeed, 0.2f); //compute rotation direction by taking height part of cross-prod float dirVal = camDir.x * heroDirection.y - camDir.y * heroDirection.x; CCameraInputHelper *const pCamHelper = hero.GetCameraInputHelper(); CRY_ASSERT(pCamHelper); if(dirVal > 0) //rotate right pCamHelper->SetTrackingDelta(-m_fAutoRotateSpeed, 0.0f); else //rotate left pCamHelper->SetTrackingDelta(m_fAutoRotateSpeed, 0.0f); } else m_fAutoRotateSpeed = 0.0f; } }
void CCameraView::UpdateFollowMode() { //get direction from user input //Vec3 vDir = SphericalToCartesian(m_pCamHelper->GetYaw(), m_pCamHelper->GetPitch(), 1.0f); //get ideal distance and compute new distance float fIdealDistance = (m_curSettings.dist + m_curSettings.maxDist) * 0.5f; float fDistTolerance = max(m_curSettings.maxDist - m_curSettings.dist, 0.01f) * 0.3f; float fMinDistance = (m_curSettings.dist < m_lastViewParams.dist)? m_curSettings.dist : m_lastViewParams.dist; //Dir to target Vec3 vDir = m_vTargetPosition - m_lastViewParams.position; float fFollowDistance = vDir.len(); if(fFollowDistance < g_fCamError) { fFollowDistance = 1.0f; vDir = Vec3Constants<float>::fVec3_OneY; } vDir /= fFollowDistance; //normalize fFollowDistance = m_curSettings.dist; //compute and interpolate follow distance if(fabsf(fFollowDistance - fIdealDistance) > fDistTolerance) { fFollowDistance = InterpolateTo(fFollowDistance, fIdealDistance, 0.5f); fFollowDistance = clamp(fFollowDistance, fMinDistance, m_curSettings.maxDist); } //interpolate rotation //m_curPolar //add user input if(m_pCamHelper) m_curPolar.Set(m_curPolar.GetYaw() + m_pCamHelper->RetrieveYawDelta(), m_curPolar.GetPitch() + m_pCamHelper->RetrievePitchDelta()); }
void CCameraInputHelper::UpdatePitchYawDriver(float stickMag, float frameTimeNormalised) { SCVars* pGameCVars = g_pGameCVars; //normal update CCameraManager *pCamMan = g_pGame->GetCameraManager(); SCamModeSettings settings; pCamMan->GetCameraSettings(pCamMan->GetActiveCameraId(), settings); if (m_pHero->m_stats.flyMode == 0) { m_pHeroInput->m_deltaMovement=Vec3(0,1,0)*stickMag; } //camera flights overwrite everything CCameraFlight *pFlight = CCameraFlight::GetInstance(); bool bFlightActive = pFlight->IsCameraFlightActive() || (pFlight->GetPaused() && pFlight->GetState() != eCFS_NONE); if(bFlightActive && !(pFlight->GetState() == eCFS_FADE_OUT && pFlight->GetFadeProgress() > 0.8f)) return; //force settings overwrite inputs if(m_fForceSettings > 0.0f) { m_fYaw = m_fForceYaw; m_fPitch = m_fForcePitch; m_fForceSettings -= gEnv->pTimer->GetFrameTime(); return; } // nav stick: static float g_fYawRotSpeed = 0.0f; static float g_fPitchRotSpeed = 0.0f; float fNewYawSpeed = m_pHeroInput->m_cameraStickLR * gf_PI * g_pGameCVars->cl_cam_rotation_speed; float fNewPitchSpeed = m_pHeroInput->m_cameraStickUD * gf_PI * g_pGameCVars->cl_cam_rotation_speed; //interpolate rotation acceleration if(g_pGameCVars->cl_cam_rotation_enable_acceleration) { if(fNewYawSpeed == 0.0f) g_fYawRotSpeed = 0.0f; else { g_fYawRotSpeed = InterpolateTo(g_fYawRotSpeed, fNewYawSpeed, g_pGameCVars->cl_cam_rotation_acceleration_time_yaw); if(g_fYawRotSpeed < 0.0f) g_fYawRotSpeed = min(g_fYawRotSpeed, -0.01f); else g_fYawRotSpeed = max(g_fYawRotSpeed, 0.01f); } if(fNewPitchSpeed == 0.0f) g_fPitchRotSpeed = 0.0f; else { g_fPitchRotSpeed = InterpolateTo(g_fPitchRotSpeed, fNewPitchSpeed, g_pGameCVars->cl_cam_rotation_acceleration_time_pitch); if(g_fPitchRotSpeed < 0.0f) g_fPitchRotSpeed = min(g_fPitchRotSpeed, -0.002f); else g_fPitchRotSpeed = max(g_fPitchRotSpeed, 0.002f); } } else { g_fYawRotSpeed = fNewYawSpeed; g_fPitchRotSpeed = fNewPitchSpeed; } //set delta yaw/pitch float deltaYawBase = g_fYawRotSpeed * frameTimeNormalised; deltaYawBase *= settings.m_fYawApplyRate; //apply yaw rate modifier float deltaPitchBase = g_fPitchRotSpeed * frameTimeNormalised; deltaPitchBase *= settings.m_fPitchApplyRate; //apply pitch rate modifier bool bHasYaw = abs(m_pHeroInput->m_cameraStickLR)>0.001f; bool bHasPitch = abs(m_pHeroInput->m_cameraStickUD)>0.001f; bool bAutoTracking = false; if(bHasYaw || bHasPitch) m_fLastUserInput = gEnv->pTimer->GetFrameStartTime().GetSeconds(); //interpolate camera to target *************** if(UpdateTargetInterpolation()) return; //if(settings.camType != ECT_CamFollow) { //handle auto rotation (simulated input) if(!bHasYaw && fabsf(m_fTrackingYawDelta) > 0.001f) { deltaYawBase = m_fTrackingYawDelta; m_fTrackingYawDelta = 0.0f; bAutoTracking = true; } if(!bHasPitch && fabsf(m_fTrackingPitchDelta) > 0.001f) { deltaPitchBase = m_fTrackingPitchDelta; m_fTrackingPitchDelta = 0.0f; bAutoTracking = true; } } if(g_pGameCVars->cl_cam_orbit != 0) { CCameraView *pCamView = g_pGame->GetCameraManager()->GetCamView(); ECamTypes eLastType = pCamView->GetLastMode()->camType; if(eLastType != ECT_CamRear && eLastType != ECT_CamFirstPerson) { SetYawDelta(RetrieveYawDelta() - deltaYawBase); SetPitchDelta(RetrievePitchDelta() - deltaPitchBase); } } else if(!CCameraManager::ChangedCamera()) { const float frameTime = max(gEnv->pTimer->GetFrameTime(),FLT_EPSILON); //add dampening to the rotation input static float yawDeltaDamped = 0.0f; float dampeningStrength = max(1.0f, pGameCVars->cl_cam_yaw_input_inertia / frameTime); yawDeltaDamped = yawDeltaDamped * (dampeningStrength-1.0f) + deltaYawBase; yawDeltaDamped /= dampeningStrength; if(bAutoTracking || bAutoTracking != m_bAutoTracking || fabsf(yawDeltaDamped) < fabsf(deltaYawBase)) yawDeltaDamped = deltaYawBase; //wait for pull if(!m_bYawModified) m_fInputYawDelta = yawDeltaDamped; else m_fInputYawDelta += yawDeltaDamped; m_fYaw += yawDeltaDamped; if(fabsf(yawDeltaDamped) > 0.002f) m_bYawModified = true; //else // m_bYawModified = false; //add dampening to the rotation input static float pitchDamped = 0.0f; dampeningStrength = max(1.0f, pGameCVars->cl_cam_pitch_input_inertia / frameTime); pitchDamped = pitchDamped * (dampeningStrength-1.0f) + deltaPitchBase; pitchDamped /= dampeningStrength; if(bAutoTracking != m_bAutoTracking || fabsf(pitchDamped) < fabsf(deltaPitchBase)) pitchDamped = deltaPitchBase; //compute new pitch if(!m_bPitchModified) m_fInputPitchDelta = pitchDamped; else m_fInputPitchDelta += pitchDamped; if(fabsf(pitchDamped) > 0.002f) m_bPitchModified = true; //else // m_bPitchModified = false; m_fPitch += pitchDamped; //clamp yaw to -pi .. pi ClampPiRange(m_fYaw); //clamp pitch m_fPitch = clamp(m_fPitch, pGameCVars->cl_cam_PitchMin, pGameCVars->cl_cam_PitchMax); } m_bAutoTracking = bAutoTracking; }
bool CCameraTracking::Update(SViewParams &viewParams, float &fHOffObstacleStrength, const SCamModeSettings &camMode, const CPlayer &hero, bool bObstacleFound /* = false */) { if(!g_pGameCVars->cl_cam_tracking || !m_pCamRayScan) return false; m_fFrameTime = max(g_fCamError, gEnv->pTimer->GetFrameTime()); //in combat mode this function doesn't really avoid obstacles, it avoids clipping float fCombatModeWeight = 5.0f; //default angle and minimum const float fNow = gEnv->pTimer->GetFrameStartTime().GetSeconds(); CCameraInputHelper *pCamHelper = hero.GetCameraInputHelper(); CRY_ASSERT(pCamHelper); float fLastUserInput = pCamHelper->GetLastUserInputTime(); //user input overrides auto-follow if(fNow - fLastUserInput < 0.5f) return false; bool bTrackingActive = camMode.camType == ECT_CamFollow && (camMode.collisionType == ECCT_CollisionTrack || camMode.collisionType == ECCT_CollisionTrackOrCut); //get current values Vec3 curCamDir = viewParams.position-viewParams.targetPos; m_curCamOrientation.Set(0.0f, 0.0f, 0.0f); CartesianToSpherical(curCamDir, m_curCamOrientation); curCamDir.Normalize(); if(m_curCamOrientation.m_fDist < g_pGameCVars->cl_cam_min_distance) m_curCamOrientation.m_fDist = g_pGameCVars->cl_cam_min_distance; //work in 0 .. 2PI m_curCamOrientation.m_fYaw += gf_PI; //if there is something in the way if(bObstacleFound) { //re-start fadeout m_fTimeCovered = 0.5f; //set last obstacle pos m_vLastObstaclePos = viewParams.position; //scan obstacle if(!IdentifyObstacle(curCamDir, hero)) return false; } else if(fabsf(m_fYawDelta) > g_fCamError || fabsf(m_fPitchDelta) > g_fCamError) { //if there is nothing in the way, fade out the movement //time based fade if(m_fTimeCovered > 0) { m_fTimeCovered = max(m_fTimeCovered - m_fFrameTime, 0.0f); //these interpolators should be time and not frame based m_fYawDelta = (g_fInterpolationRate * m_fYawDelta) * g_fInterpolationWeight; m_fPitchDelta = (g_fInterpolationRate * m_fPitchDelta) * g_fInterpolationWeight; m_fSpeed = (g_fInterpolationRate * m_fSpeed) * g_fInterpolationWeight; } else { m_fYawDelta = 0.0f; m_fPitchDelta = 0.0f; m_fSpeed = 0.0f; } } //apply delta rotation for obstacle avoidance if(fabsf(m_fYawDelta) > g_fCamError || fabsf(m_fPitchDelta) > g_fCamError) { if(bTrackingActive) { //set new yaw float newYaw = m_curCamOrientation.m_fYaw + m_fYawDelta; //re-align yaw //the camera direction is 90 degrees off and flipped compared to entity space newYaw = (newYaw - gf_PI * 0.5f) * -1.0f; //set new pitch float newPitch = m_curCamOrientation.m_fPitch + m_fPitchDelta; if(g_pGameCVars->cl_cam_orbit != 0) { //pCamHelper->SetTrackingDelta(-m_fYawDelta, m_fPitchDelta); pCamHelper->SetYawDelta(-m_fYawDelta); pCamHelper->SetPitchDelta(m_fPitchDelta); } else { //apply yaw/pitch on camera //pCamHelper->SetInterpolationTarget(newYaw, newPitch, gf_PI, 0.1f, 0.0f); //this will always reset follow cam interpolation pCamHelper->SetYawDelta(m_fYawDelta); pCamHelper->SetPitchDelta(m_fPitchDelta); } } else { //in orbit mode we basically simulate user input //pCamHelper->SetTrackingDelta(-fCombatModeWeight*g_fYawDelta, fCombatModeWeight*g_fPitchDelta); //in cutting mode we offset the camera to avoid clipping float offsetStrength = 0.0f; float offsetSpeed = 2.0f; if(bObstacleFound) { offsetStrength = (m_fYawDelta < 0.0f)?-g_fOffsetTrackingDistance:g_fOffsetTrackingDistance; offsetSpeed = 0.5f; } fHOffObstacleStrength = InterpolateTo(fHOffObstacleStrength, offsetStrength, offsetSpeed); } //CryLogAlways("new yaw %f, yawDelta %f", newYaw, g_yawDelta); return true; } else UpdateAutoFollow(viewParams, hero); return false; }
bool CCameraTracking::IdentifyObstacle(const Vec3 &vCamDir, const CPlayer &hero) { //check player direction Vec3 newDir = -hero.GetEntity()->GetForwardDir(); newDir.z += vCamDir.z; newDir.normalize(); //compute rotation speed const float fHeroSpeedModifier = clamp(hero.GetActorStats()->speedFlat / 4.0f, 0.3f, 1.0f); const float fNewSpeed = g_pGameCVars->cl_cam_tracking_rotation_speed * m_fFrameTime * fHeroSpeedModifier; m_fSpeed = InterpolateTo(m_fSpeed, fNewSpeed, (fNewSpeed>m_fSpeed)?0.1f:0.3f); //m_fSpeed = (g_fInterpolationRate * m_fSpeed + speed) * g_fInterpolationWeight; //get ray data from camera ray tests ray_hit *pRayHit = m_pCamRayScan->GetHit(eRAY_TOP_RIGHT); if(!pRayHit || pRayHit->dist == 0.0f) pRayHit = m_pCamRayScan->GetHit(eRAY_BOTTOM_RIGHT); bool bHitsRight = (pRayHit && pRayHit->dist > 0.0f); Vec3 dirRight = (pRayHit)?-(m_pCamRayScan->GetRayDir(eRAY_TOP_RIGHT)):Vec3(ZERO); //ray data left side pRayHit = m_pCamRayScan->GetHit(eRAY_TOP_LEFT); if(!pRayHit || pRayHit->dist == 0.0f) pRayHit = m_pCamRayScan->GetHit(eRAY_BOTTOM_LEFT); bool bHitsLeft = (pRayHit && pRayHit->dist > 0.0f); Vec3 dirLeft = (pRayHit)?-(m_pCamRayScan->GetRayDir(eRAY_TOP_LEFT)):Vec3(ZERO); //left or right if(bHitsRight ^ bHitsLeft) { //find rotation direction if(!bHitsRight && !bHitsLeft) { if(m_eLastDirYaw == eTD_LEFT) //continue last direction newDir = dirLeft; else newDir = dirRight; } else if(!bHitsRight) { m_eLastDirYaw = eTD_RIGHT; newDir = dirRight; } else { m_eLastDirYaw = eTD_LEFT; newDir = dirLeft; } //compute yaw/pitch for target position float newYaw = 0.0f; float newPitch = 0.0f; float newDist = 0.0f; CartesianToSpherical(newDir * m_curCamOrientation.m_fDist, newYaw, newPitch, newDist); newYaw += gf_PI; //now interpolate to target //compute delta yaw m_fYawDelta = (newYaw - m_curCamOrientation.m_fYaw) * m_fSpeed; if(m_eLastDirYaw == eTD_RIGHT && m_fYawDelta < 0.0f || m_eLastDirYaw == eTD_LEFT && m_fYawDelta > 0.0f) m_fYawDelta *= -1.0f; } //compute top/bottom rotation //ray data top side pRayHit = m_pCamRayScan->GetHit(eRAY_TOP_CENTER); bool bHitsTop = (pRayHit && pRayHit->dist > 0.0f)?true:false; Vec3 vDirTop = (pRayHit)?-(m_pCamRayScan->GetRayDir(eRAY_TOP_CENTER)):Vec3(ZERO); //ray data bottom side pRayHit = m_pCamRayScan->GetHit(eRAY_BOTTOM_CENTER); bool bHitsBottom = (pRayHit && pRayHit->dist > 0.0f)?true:false; Vec3 vDirBottom = (pRayHit)?-(m_pCamRayScan->GetRayDir(eRAY_BOTTOM_CENTER)):Vec3(ZERO); //top or bottom (if not left or right) if(g_pGameCVars->cl_cam_tracking_allow_pitch && (bHitsTop ^ bHitsBottom) && !(bHitsRight ^ bHitsLeft)) { //find rotation direction if(!bHitsTop && !bHitsBottom) { if(m_eLastDirPitch == eTD_TOP) //continue last direction newDir = vDirTop; else newDir = vDirBottom; } else if(!bHitsBottom) { m_eLastDirPitch = eTD_BOTTOM; newDir = vDirBottom; } else { m_eLastDirPitch = eTD_TOP; newDir = vDirTop; } //compute yaw/pitch for target position float newYaw = 0.0f; float newPitch = 0.0f; float newDist = 0.0f; //newdist (raydist) will be ignored CartesianToSpherical(newDir, newYaw, newPitch, newDist); //compute delta pitch m_fPitchDelta = (newPitch - m_curCamOrientation.m_fPitch) * m_fSpeed * 10.0f; } //if all rays hit - don't bother! //this is a termination condition when the camera is pulled through geometry if(bHitsLeft & bHitsRight & bHitsBottom & bHitsTop) { if(m_bViewCovered) { //if obstacle behind player //if(g_rHit.dist > 0.0f) //this is a strange fix, but it's working better and is much cheaper than a raycast if(fabsf(m_fYawDelta) < 0.01f && fabsf(m_fPitchDelta) > 0.001f) return false; } m_bViewCovered = true; } else m_bViewCovered = false; return true; }
void CCameraFlight::UpdateFlight(SViewParams &viewParams) { if(m_eMovementMode != eCFM_FREE_FLIGHT && (m_fFlightProgress >= 1.0f || m_eMovementMode == eCFM_NONE || m_cameraCourse.size() < 3)) { //update free fly point while not in free fly m_freeFlyPoint.m_vCamPos = viewParams.position; m_freeFlyPoint.m_vCamLookAt = viewParams.position + Vec3Constants<float>::fVec3_OneY; m_eState = eCFS_NONE; //nothing else to do return; } m_eState = eCFS_RUNNING; //update ref pos if(m_pRefEnt) m_vRefPos = m_pRefEnt->GetWorldPos(); //if refPos2 is set, find middle if(m_vRefPos2.len2() > 0.0f) m_vRefPos = (m_vRefPos + m_vRefPos2) * 0.5f; //find target SCameraFlightPoint targetPoint = SCameraFlightPoint(); switch(m_eMovementMode) { case eCFM_FREE_FLIGHT: targetPoint = m_freeFlyPoint; break; case eCFM_SPLINE: targetPoint = GetSplinePoint(m_fFlightProgress); break; case eCFM_LINE: targetPoint = GetTrackPoint(m_fFlightProgress); break; default: break; } //compute new dir/pos m_vLookingDirection = targetPoint.m_vCamLookAt - targetPoint.m_vCamPos; if(m_bUseRefDir) { m_vLookingDirection = m_vRefDir; m_qFadeOrientation = Quat::CreateRotationVDir(m_vLookingDirection, 0.0f); } m_vLookingDirection.NormalizeSafe(); Quat qTempDirection = Quat::CreateRotationVDir(m_vLookingDirection, 0.0f); Vec3 vTempPos = targetPoint.m_vCamPos; bool bFading = false; //compute fading if(m_eMovementMode != eCFM_FREE_FLIGHT) { if(m_fFlightProgress > m_fFadeOutTime && (m_eFadeMode == eCFFM_OUT || m_eFadeMode == eCFFM_INOUT)) { //fade position m_fFadeProgress = InterpolateTo(m_fFadeProgress, 1.0f, m_fFadeTime); m_vTargetFadePos = vTempPos * (1.0f - m_fFadeProgress) + viewParams.position * m_fFadeProgress; //fade orientation qTempDirection = Quat_tpl<float>::CreateNlerp(m_qFadeOrientation, viewParams.rotation, m_fFadeProgress); if(m_fFadeProgress < 0.998f) { bFading = true; m_eState = eCFS_FADE_OUT; } } else if(m_fFlightProgress < m_fFadeInTime && (m_eFadeMode == eCFFM_IN || m_eFadeMode == eCFFM_INOUT)) { //fade position m_fFadeProgress = InterpolateTo(m_fFadeProgress, 1.0f, m_fFadeTime); m_vTargetFadePos = viewParams.position * (1.0f - m_fFadeProgress) + vTempPos * m_fFadeProgress; //fade orientation qTempDirection = Quat_tpl<float>::CreateNlerp(viewParams.rotation, qTempDirection, m_fFadeProgress); if(m_fFadeProgress < 0.998f) { bFading = true; m_eState = eCFS_FADE_IN; } } else { m_vTargetFadePos = vTempPos; //m_vTargetFadeLookAt = targetPoint.m_vCamLookAt; m_qFadeOrientation = qTempDirection; m_fFadeProgress = 0.0f; m_eState = eCFS_RUNNING; } } else { m_vTargetFadePos = vTempPos; } //update dir m_vLookingDirection = qTempDirection.GetColumn1(); //raycast to prevent clipping during flight if(m_eMovementMode != eCFM_FREE_FLIGHT) DetectCollisions(); //set position and rotation to viewparams viewParams.rotation = qTempDirection; viewParams.position = m_vTargetFadePos;//InterpolateTo(m_vTargetFadePos, viewParams.position, 1.0f); //progress flight if(m_eMovementMode != eCFM_FREE_FLIGHT && !bFading) { if(m_bPaused && m_fFlightProgress < 0.2f) { m_fFlightProgress += gEnv->pTimer->GetFrameTime() * m_fFlightSpeed; m_fFlightProgress = min(0.2f, m_fFlightProgress); } else if (!m_bPaused) m_fFlightProgress += gEnv->pTimer->GetFrameTime() * m_fFlightSpeed; } }
//-------------------------------------------------------------------------------- void Session::HandlePlayerMoveAndLook(Packet& data) { auto player = Mod::GetInstance().GetCharacterManager().Get(data.Int(0)); player->InterpolateTo(data.Float(0), data.Float(1), data.Float(2), data.Float(3), data.Float(4), data.Float(5), data.Float(6)); }