forked from vixorien/D3D11Starter
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTransform.cpp
More file actions
224 lines (186 loc) · 5.14 KB
/
Copy pathTransform.cpp
File metadata and controls
224 lines (186 loc) · 5.14 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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#include "Transform.h"
#include "Material.h"
using namespace DirectX;
Transform::Transform() :
position(0, 0, 0),
pitchYawRoll(0, 0, 0),
scale(1, 1, 1),
forward(0, 0, 1),
right(1, 0, 0),
up(0, 1, 0),
matrixDirty(true),
vectorDirty(true)
{
XMStoreFloat4x4(&world, XMMatrixIdentity());
XMStoreFloat4x4(&worldInverseTranspose, XMMatrixIdentity());
}
void Transform::SetPosition(float x, float y, float z)
{
SetPosition(XMFLOAT3(x, y, z));
}
void Transform::SetPosition(DirectX::XMFLOAT3 position)
{
// Load the position into an XMVECTOR and store it back in the XMFLOAT3
XMStoreFloat3(&this->position, XMLoadFloat3(&position));
matrixDirty = true;
}
void Transform::SetRotation(float pitch, float yaw, float roll)
{
SetRotation(XMFLOAT3(pitch, yaw, roll));
}
void Transform::SetRotation(DirectX::XMFLOAT3 rotation)
{
// Load the rotation into an XMVECTOR and store it back in the XMFLOAT3
XMStoreFloat3(&this->pitchYawRoll, XMLoadFloat3(&rotation));
matrixDirty = true;
vectorDirty = true;
}
void Transform::SetScale(float x, float y, float z)
{
SetScale(XMFLOAT3(x, y, z));
}
void Transform::SetScale(DirectX::XMFLOAT3 scale)
{
// Load the scale into an XMVECTOR and store it back in the XMFLOAT3
XMStoreFloat3(&this->scale, XMLoadFloat3(&scale));
matrixDirty = true;
}
DirectX::XMFLOAT3 Transform::GetPosition()
{
return position;
}
DirectX::XMFLOAT3 Transform::GetPitchYawRoll()
{
return pitchYawRoll;
}
DirectX::XMFLOAT3 Transform::GetScale()
{
return scale;
}
DirectX::XMFLOAT3 Transform::GetForward()
{
if (vectorDirty) CalculateVectors();
return forward;
}
DirectX::XMFLOAT3 Transform::GetRight()
{
if (vectorDirty) CalculateVectors();
return right;
}
DirectX::XMFLOAT3 Transform::GetUp()
{
if (vectorDirty) CalculateVectors();
return up;
}
DirectX::XMFLOAT4X4 Transform::GetWorldMatrix()
{
if (matrixDirty) CalculateWorldMatrix();
return world;
}
DirectX::XMFLOAT4X4 Transform::GetWorldInverseTransposeMatrix()
{
if (matrixDirty) CalculateWorldMatrix();
return worldInverseTranspose;
}
void Transform::MoveAbsolute(float x, float y, float z)
{
MoveAbsolute(XMFLOAT3(x, y, z));
}
void Transform::MoveAbsolute(DirectX::XMFLOAT3 offset)
{
// Load the current position into an XMVECTOR,
// add the offset to it
// and store it back in the XMFLOAT3
XMStoreFloat3(
&this->position,
XMVectorAdd(
XMLoadFloat3(&this->position),
XMLoadFloat3(&offset)
)
);
matrixDirty = true;
}
void Transform::MoveRelative(float x, float y, float z)
{
MoveRelative(XMFLOAT3(x, y, z));
}
void Transform::MoveRelative(DirectX::XMFLOAT3 offset)
{
// Create a quaternion representing the current rotation
XMVECTOR rotQuat = XMQuaternionRotationRollPitchYawFromVector(XMLoadFloat3(&pitchYawRoll));
// Rotate the offset with the rotation quaternion
XMVECTOR rotatedOffset = XMVector3Rotate(XMLoadFloat3(&offset), rotQuat);
// Add the rotated offset to the current position
// and store back in the position vector
XMStoreFloat3(
&position,
XMVectorAdd(
XMLoadFloat3(&position),
rotatedOffset
)
);
}
void Transform::Rotate(float pitch, float yaw, float roll)
{
Rotate(XMFLOAT3(pitch, yaw, roll));
}
void Transform::Rotate(DirectX::XMFLOAT3 rotation)
{
// Load the current rotation into an XMVECTOR,
// add the rotation to it
// and store it back in the XMFLOAT3
XMStoreFloat3(
&this->pitchYawRoll,
XMVectorAdd(
XMLoadFloat3(&this->pitchYawRoll),
XMLoadFloat3(&rotation)
)
);
matrixDirty = true;
vectorDirty = true;
}
void Transform::Scale(float x, float y, float z)
{
Scale(XMFLOAT3(x, y, z));
}
void Transform::Scale(DirectX::XMFLOAT3 scale)
{
// Load the current scale into an XMVECTOR,
// multiply it with the scale
// and store it back in the XMFLOAT3
XMStoreFloat3(
&this->scale,
XMVectorMultiply(
XMLoadFloat3(&this->scale),
XMLoadFloat3(&scale)
)
);
matrixDirty = true;
}
void Transform::CalculateWorldMatrix()
{
// Create translation, rotation and scale matrices from corresponding vectors
XMMATRIX t = XMMatrixTranslationFromVector(XMLoadFloat3(&position));
XMMATRIX r = XMMatrixRotationRollPitchYawFromVector(XMLoadFloat3(&pitchYawRoll));
XMMATRIX s = XMMatrixScalingFromVector(XMLoadFloat3(&scale));
// Combine the above matrices to get the world matrix
XMMATRIX w = XMMatrixMultiply(XMMatrixMultiply(s, r), t);
// Store the result in the world matrix
XMStoreFloat4x4(&world, w);
// Calculate the inverse transpose of the world matrix and store it
XMStoreFloat4x4(&worldInverseTranspose, XMMatrixInverse(0, XMMatrixTranspose(w)));
// Reset the dirty flag
matrixDirty = false;
}
void Transform::CalculateVectors()
{
// Create a quaternion representing the current rotation
XMVECTOR rotQuat = XMQuaternionRotationRollPitchYawFromVector(XMLoadFloat3(&pitchYawRoll));
// Throw away the rotated vectors and recalculate them from the rotation quaternion
// Rotate each of the default forward, right and up vectors with the rotation quaternion
XMStoreFloat3(&forward, XMVector3Rotate(XMVectorSet(0, 0, 1, 0), rotQuat));
XMStoreFloat3(&right, XMVector3Rotate(XMVectorSet(1, 0, 0, 0), rotQuat));
XMStoreFloat3(&up, XMVector3Rotate(XMVectorSet(0, 1, 0, 0), rotQuat));
// Reset the dirty flag
vectorDirty = false;
}