-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathTransform.cpp
142 lines (114 loc) · 3.69 KB
/
Transform.cpp
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
#define _USE_MATH_DEFINES
#include <math.h>
#include "Transform.h"
// public
Transform::Transform() : Transform(0, 0, 0, 1, 1) { }
Transform::Transform(float xPos=0, float yPos=0, float rot=0, float xScale=1, float yScale=1) {
position = {
xPos,
yPos
};
rotation = rot;
scale = {
xScale,
yScale
};
interpolX = nullptr;
interpolY = nullptr;
generateModelMatrix();
}
Position Transform::getPosition() const {
return position;
}
// most commonly used function => will optimized
// by translating the modelMatrix only
void Transform::setPosition(float x, float y) {
position = {
x, y
};
changed = true;
}
void Transform::translate(float x, float y) {
position.x += x;
position.y += y;
changed = true;
}
void Transform::setPhysicsBody(b2Body* newBody) {
body = newBody;
}
b2Body* Transform::getPhysicsBody() {
return body;
}
Scale Transform::getScale() const {
return scale;
}
void Transform::setScale(float x, float y) {
scale = {
x, y
};
changed = true;
}
Rotation Transform::getRotation() {
// Convert from radians to degrees then return
return (rotation * (180.0f/M_PI));
}
void Transform::setRotation(float r) {
// Convert the degree value to radians so openGL can use it
r = r * (M_PI / 180.0f);
rotation = r;
changed = true;
}
void Transform::rotate(float rDelta) {
rotation += rDelta;
changed = true;
}
// create a new model matrix only when we are needed.
// contains optimization so we only need to do matrix
// math when necessary
glm::mat4 Transform::getModelMatrix() {
if (changed) {
generateModelMatrix();
// reset for next call
changed = false;
}
return modelMatrix;
}
// private
// Generate the model matrix based on the current
// transforms at the time of call.
// Doesn't do rotation at the current moment.
void Transform::generateModelMatrix() {
glm::mat4 model = glm::mat4(1);
float positionX = interpolX != nullptr ? interpolX->interpolate(position.x) : position.x;
float positionY = interpolY != nullptr ? interpolY->interpolate(position.y) : position.y;
// proper math orders is scale first, then rotate, then translate.
// However, matrix multiplication order is apply right to left, so we are
// (codewise) translating, then rotating, then scaling.
model = glm::translate(model, glm::vec3(positionX, positionY, 0));
// has to specify a rotation axis => need a review
// do I need a quaternion? do I need to shift to accomodate
// for whether x and y is top left or center?
//if you want to rotate an object in-place about a local axis,
//you have to translate the object to the origin, perform the rotation,
//and then translate the object back to its original location.
//model = glm::rotate(model, rotation, rotAxis);
// Make sure to offset according to scale
//model = glm::translate(model, glm::vec3(scale.x, 0));
// translate rotated matrix back to transform's position after rotation
//model = glm::translate(model, glm::vec3(position.x, position.y, 0));
// rotate about z-axis at the origin to avoid orbiting then translate back
// specify the axis to be z since we're in 2-d
// Positive angle in degrees rotates counter clockwise
model = glm::rotate(model, rotation, glm::vec3(0, 0, 1));
// apply a scale if there is any
model = glm::scale(model, glm::vec3(scale.x, scale.y, 1));
modelMatrix = model;
}
void Transform::setInterpolatorX(Interpolator* interpol) {
interpolX = interpol;
changed = true;
}
void Transform::setInterpolatorY(Interpolator* interpol) {
interpolY = interpol;
changed = true;
}