// ---------------------------------------------------------------- // From Game Programming in C++ by Sanjay Madhav // Copyright (C) 2017 Sanjay Madhav. All rights reserved. // // Released under the BSD License // See LICENSE in root directory for full details. // ---------------------------------------------------------------- #include "FollowCamera.h" #include "Actor.h" FollowCamera::FollowCamera(Actor* owner) :CameraComponent(owner) ,mHorzDist(350.0f) ,mVertDist(250.0f) ,mTargetDist(100.0f) ,mSpringConstant(128.0f) { } void FollowCamera::Update(float deltaTime) { CameraComponent::Update(deltaTime); // Compute dampening from spring constant float dampening = 2.0f * Math::Sqrt(mSpringConstant); // Compute ideal position Vector3 idealPos = ComputeCameraPos(); // Compute difference between actual and ideal Vector3 diff = mActualPos - idealPos; // Compute acceleration of spring Vector3 acel = -mSpringConstant * diff - dampening * mVelocity; // Update velocity mVelocity += acel * deltaTime; // Update actual camera position mActualPos += mVelocity * deltaTime; // Target is target dist in front of owning actor Vector3 target = mOwner->GetPosition() + mOwner->GetForward() * mTargetDist; // Use actual position here, not ideal Matrix4 view = Matrix4::CreateLookAt(mActualPos, target, Vector3::UnitZ); SetViewMatrix(view); } void FollowCamera::SnapToIdeal() { // Set actual position to ideal mActualPos = ComputeCameraPos(); // Zero velocity mVelocity = Vector3::Zero; // Compute target and view Vector3 target = mOwner->GetPosition() + mOwner->GetForward() * mTargetDist; // Use actual position here, not ideal Matrix4 view = Matrix4::CreateLookAt(mActualPos, target, Vector3::UnitZ); SetViewMatrix(view); } Vector3 FollowCamera::ComputeCameraPos() const { // Set camera position behind and above owner Vector3 cameraPos = mOwner->GetPosition(); cameraPos -= mOwner->GetForward() * mHorzDist; cameraPos += Vector3::UnitZ * mVertDist; return cameraPos; }