Пример #1
0
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;
	}
}
Пример #2
0
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);
}
Пример #3
0
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;
	}
}
Пример #4
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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;
	}
}
Пример #9
0
		//--------------------------------------------------------------------------------
		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));
		}