FollowCamera.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // ----------------------------------------------------------------
  2. // From Game Programming in C++ by Sanjay Madhav
  3. // Copyright (C) 2017 Sanjay Madhav. All rights reserved.
  4. //
  5. // Released under the BSD License
  6. // See LICENSE in root directory for full details.
  7. // ----------------------------------------------------------------
  8. #include "FollowCamera.h"
  9. #include "Actor.h"
  10. #include "LevelLoader.h"
  11. FollowCamera::FollowCamera(Actor* owner)
  12. :CameraComponent(owner)
  13. ,mHorzDist(350.0f)
  14. ,mVertDist(250.0f)
  15. ,mTargetDist(100.0f)
  16. ,mSpringConstant(128.0f)
  17. {
  18. }
  19. void FollowCamera::Update(float deltaTime)
  20. {
  21. CameraComponent::Update(deltaTime);
  22. // Compute dampening from spring constant
  23. float dampening = 2.0f * Math::Sqrt(mSpringConstant);
  24. // Compute ideal position
  25. Vector3 idealPos = ComputeCameraPos();
  26. // Compute difference between actual and ideal
  27. Vector3 diff = mActualPos - idealPos;
  28. // Compute acceleration of spring
  29. Vector3 acel = -mSpringConstant * diff -
  30. dampening * mVelocity;
  31. // Update velocity
  32. mVelocity += acel * deltaTime;
  33. // Update actual camera position
  34. mActualPos += mVelocity * deltaTime;
  35. // Target is target dist in front of owning actor
  36. Vector3 target = mOwner->GetPosition() +
  37. mOwner->GetForward() * mTargetDist;
  38. // Use actual position here, not ideal
  39. Matrix4 view = Matrix4::CreateLookAt(mActualPos, target,
  40. Vector3::UnitZ);
  41. SetViewMatrix(view);
  42. }
  43. void FollowCamera::SnapToIdeal()
  44. {
  45. // Set actual position to ideal
  46. mActualPos = ComputeCameraPos();
  47. // Zero velocity
  48. mVelocity = Vector3::Zero;
  49. // Compute target and view
  50. Vector3 target = mOwner->GetPosition() +
  51. mOwner->GetForward() * mTargetDist;
  52. // Use actual position here, not ideal
  53. Matrix4 view = Matrix4::CreateLookAt(mActualPos, target,
  54. Vector3::UnitZ);
  55. SetViewMatrix(view);
  56. }
  57. void FollowCamera::LoadProperties(const rapidjson::Value& inObj)
  58. {
  59. CameraComponent::LoadProperties(inObj);
  60. JsonHelper::GetVector3(inObj, "actualPos", mActualPos);
  61. JsonHelper::GetVector3(inObj, "velocity", mVelocity);
  62. JsonHelper::GetFloat(inObj, "horzDist", mHorzDist);
  63. JsonHelper::GetFloat(inObj, "vertDist", mVertDist);
  64. JsonHelper::GetFloat(inObj, "targetDist", mTargetDist);
  65. JsonHelper::GetFloat(inObj, "springConstant", mSpringConstant);
  66. }
  67. void FollowCamera::SaveProperties(rapidjson::Document::AllocatorType& alloc, rapidjson::Value& inObj) const
  68. {
  69. CameraComponent::SaveProperties(alloc, inObj);
  70. JsonHelper::AddVector3(alloc, inObj, "actualPos", mActualPos);
  71. JsonHelper::AddVector3(alloc, inObj, "velocity", mVelocity);
  72. JsonHelper::AddFloat(alloc, inObj, "horzDist", mHorzDist);
  73. JsonHelper::AddFloat(alloc, inObj, "vertDist", mVertDist);
  74. JsonHelper::AddFloat(alloc, inObj, "targetDist", mTargetDist);
  75. JsonHelper::AddFloat(alloc, inObj, "springConstant", mSpringConstant);
  76. }
  77. Vector3 FollowCamera::ComputeCameraPos() const
  78. {
  79. // Set camera position behind and above owner
  80. Vector3 cameraPos = mOwner->GetPosition();
  81. cameraPos -= mOwner->GetForward() * mHorzDist;
  82. cameraPos += Vector3::UnitZ * mVertDist;
  83. return cameraPos;
  84. }