forked from gameprogcpp/code
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSplineCamera.cpp
More file actions
90 lines (83 loc) · 2.23 KB
/
SplineCamera.cpp
File metadata and controls
90 lines (83 loc) · 2.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// ----------------------------------------------------------------
// 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 "SplineCamera.h"
#include "Actor.h"
Vector3 Spline::Compute(size_t startIdx, float t) const
{
// Check if startIdx is out of bounds
if (startIdx >= mControlPoints.size())
{
return mControlPoints.back();
}
else if (startIdx == 0)
{
return mControlPoints[startIdx];
}
else if (startIdx + 2 >= mControlPoints.size())
{
return mControlPoints[startIdx];
}
// Get p0 through p3
Vector3 p0 = mControlPoints[startIdx - 1];
Vector3 p1 = mControlPoints[startIdx];
Vector3 p2 = mControlPoints[startIdx + 1];
Vector3 p3 = mControlPoints[startIdx + 2];
// Compute position according to Catmull-Rom equation
Vector3 position = 0.5f * ((2.0f * p1) + (-1.0f * p0 + p2) * t +
(2.0f * p0 - 5.0f * p1 + 4.0f * p2 - p3) * t * t +
(-1.0f * p0 + 3.0f * p1 - 3.0f * p2 + p3) * t * t * t);
return position;
}
SplineCamera::SplineCamera(Actor* owner)
:CameraComponent(owner)
,mIndex(1)
,mT(0.0f)
,mSpeed(0.5f)
,mPaused(true)
{
}
void SplineCamera::Update(float deltaTime)
{
CameraComponent::Update(deltaTime);
// Update t value
if (!mPaused)
{
mT += mSpeed * deltaTime;
// Advance to the next control point if needed.
// This assumes speed isn't so fast that you jump past
// multiple control points in one frame.
if (mT >= 1.0f)
{
// Make sure we have enough points to advance the path
if (mIndex < mPath.GetNumPoints() - 3)
{
mIndex++;
mT = mT - 1.0f;
}
else
{
// Path's done, so pause
mPaused = true;
}
}
}
// Camera position is the spline at the current t/index
Vector3 cameraPos = mPath.Compute(mIndex, mT);
// Target point is just a small delta ahead on the spline
Vector3 target = mPath.Compute(mIndex, mT + 0.01f);
// Assume spline doesn't flip upside-down
const Vector3 up = Vector3::UnitZ;
Matrix4 view = Matrix4::CreateLookAt(cameraPos, target, up);
SetViewMatrix(view);
}
void SplineCamera::Restart()
{
mIndex = 1;
mT = 0.0f;
mPaused = false;
}