-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCameraComponent.cpp
More file actions
92 lines (72 loc) · 3.78 KB
/
CameraComponent.cpp
File metadata and controls
92 lines (72 loc) · 3.78 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
91
92
#include "CameraComponent.h"
#include "PositionComponent.h"
CameraComponent::CameraComponent(float verticalFOV, float aspectRatio, float nearDistance, float farDistance, PositionComponent *positionComponent, const XMFLOAT3 &relativePosition, const XMFLOAT3 &relativeOrientationEulerAngles)
: mPositionComponent(positionComponent), mRelativePosition(relativePosition), mRelativeOrientationEulerAngles(relativeOrientationEulerAngles)
{
// set perspective projection matrix
SetLens(verticalFOV, aspectRatio, nearDistance, farDistance);
// calculate offset matrix
XMMATRIX relativeRotationMatrix = XMMatrixRotationRollPitchYaw(mRelativeOrientationEulerAngles.x, mRelativeOrientationEulerAngles.y, mRelativeOrientationEulerAngles.z);
XMMATRIX relativeTranslationMatrix = XMMatrixTranslation(mRelativePosition.x, mRelativePosition.y, mRelativePosition.z);
XMMATRIX offsetMatrix = XMMatrixInverse(nullptr, XMMatrixMultiply(relativeRotationMatrix, relativeTranslationMatrix));
XMStoreFloat4x4(&mOffsetMatrix, offsetMatrix);
}
void CameraComponent::SetLens(float verticalFOV, float aspectRatio, float nearDistance, float farDistance)
{
// set camera frustum parameters
mVerticalFOV = verticalFOV;
mAspectRatio = aspectRatio;
mNearDistance = nearDistance;
mFarDistance = farDistance;
// update perspective projection matrix
XMStoreFloat4x4(&mProjectionMatrix, XMMatrixPerspectiveFovLH(mVerticalFOV, mAspectRatio, mNearDistance, mFarDistance));
}
const XMFLOAT3 CameraComponent::GetPosition() const
{
XMFLOAT3 targetPosition = mPositionComponent->GetPosition();
XMVECTOR relativePosition = XMVector3Transform(XMLoadFloat3(&mRelativePosition), XMLoadFloat4x4(&mPositionComponent->GetWorldMatrix()));
XMFLOAT3 cameraPosition;
XMStoreFloat3(&cameraPosition, relativePosition);
return cameraPosition;
}
const XMFLOAT4X4 CameraComponent::GetViewMatrix() const
{
XMMATRIX targetInverseWorldMatrix = XMLoadFloat4x4(&mPositionComponent->GetInverseWorldMatrix());
XMMATRIX offsetMatrix = XMLoadFloat4x4(&mOffsetMatrix);
XMFLOAT4X4 viewMatrix;
XMStoreFloat4x4(&viewMatrix, XMMatrixMultiply(targetInverseWorldMatrix, offsetMatrix));
return viewMatrix;
}
const XMFLOAT4X4 CameraComponent::GetInverseViewMatrix() const
{
XMMATRIX targetWorldMatrix = XMLoadFloat4x4(&mPositionComponent->GetWorldMatrix());
XMMATRIX inverseOffsetMatrix = XMMatrixInverse(nullptr, XMLoadFloat4x4(&mOffsetMatrix));
XMFLOAT4X4 inverseViewMatrix;
XMStoreFloat4x4(&inverseViewMatrix, XMMatrixMultiply(inverseOffsetMatrix, targetWorldMatrix));
return inverseViewMatrix;
}
// parameter defines the frustum depth (1.0 = real frustum depth)
CameraComponent::Frustum const CameraComponent::GetFrustum(float maxDistance) const
{
Frustum frustum;
float nearHeight = 2.0f * mNearDistance * tan(mVerticalFOV / 2.0f);
float nearWidth = mAspectRatio * nearHeight;
float farHeight = 2.0f * mFarDistance * tan(mVerticalFOV / 2.0f);
float farWidth = mAspectRatio * farHeight;
float farDistance = mFarDistance;
if (maxDistance < mFarDistance)
{
farDistance = maxDistance;
farHeight = 2.0f * farDistance * tan(mVerticalFOV / 2.0f);
farWidth = mAspectRatio * farHeight;
}
frustum.nearTopLeft = XMFLOAT3(-nearWidth / 2.0f, nearHeight / 2.0f, mNearDistance);
frustum.nearTopRight = XMFLOAT3(nearWidth / 2.0f, nearHeight / 2.0f, mNearDistance);
frustum.nearBottomLeft = XMFLOAT3(-nearWidth / 2.0f, -nearHeight / 2.0f, mNearDistance);
frustum.nearBottomRight = XMFLOAT3(nearWidth / 2.0f, -nearHeight / 2.0f, mNearDistance);
frustum.farTopLeft = XMFLOAT3(-farWidth / 2.0f, farHeight / 2.0f, farDistance);
frustum.farTopRight = XMFLOAT3(farWidth / 2.0f, farHeight / 2.0f, farDistance);
frustum.farBottomLeft = XMFLOAT3(-farWidth / 2.0f, -farHeight / 2.0f, farDistance);
frustum.farBottomRight = XMFLOAT3(farWidth / 2.0f, -farHeight / 2.0f, farDistance);
return frustum;
}