-
Notifications
You must be signed in to change notification settings - Fork 0
/
VQS.cpp
120 lines (99 loc) · 2.95 KB
/
VQS.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
#include "VQS.h"
#include <iostream>
#include "Libraries/include/glm/gtx/transform.hpp"
#include "Libraries/include/glm/gtx/quaternion.hpp"
#include <glm/gtx/string_cast.hpp>
std::ostream& operator<<(std::ostream& out, VQS vqs)
{
std::cout << "pos : (" << vqs.position.x << "," << vqs.position.y << "," << vqs.position.z << ")" << std::endl;
std::cout << "quat : (" << vqs.quaternion.s << "(" << vqs.quaternion.v.x << "," << vqs.quaternion.v.y << "," << vqs.quaternion.v.z << ")" << std::endl;
std::cout << "scale : " << vqs.scale << std::endl;
return out;
}
std::ostream& operator<<(std::ostream& out, glm::vec3 vqs)
{
std::cout << "vec3 : (" << vqs.x << "," << vqs.y << "," << vqs.z << ")" << std::endl;
return out;
}
VQS::VQS()
{
position = glm::vec3(0);
quaternion = Quaternion(1.0f, glm::vec3(0.0f)).Normalized();
scale = 1.0f;
}
VQS::VQS(glm::vec3 _position,Quaternion _quaternion,float _scale)
{
position = _position;
quaternion = _quaternion.Normalized();
scale = _scale;
}
VQS VQS::operator*(VQS rhs)
{
VQS result;
result.scale = scale * rhs.scale;
result.quaternion = (quaternion * rhs.quaternion).Normalized();
result.position = *this * (rhs.position);
return result;
}
glm::vec3 VQS::operator*(glm::vec3 rhs)
{
return (quaternion * (rhs * scale) * quaternion.Inverse()).v + position;
}
glm::mat4 VQS::VQStoMatrix()
{
glm::mat4 matPos, matRot, matScl;
matScl = glm::scale(glm::mat4(1.0f) , glm::vec3(scale, scale, scale));
matPos = glm::translate(glm::mat4(1.0f), position);
glm::quat rotation = glm::normalize(glm::quat(quaternion.s, quaternion.v.x, quaternion.v.y, quaternion.v.z));
matRot = glm::toMat4(rotation);
glm::mat4 output = matPos * matRot * matScl;
//std::cout<< glm::to_string(output) << std::endl;
return output;
}
VQS VQS::Inverse()
{
VQS temp(glm::vec3(0), quaternion.Inverse(), 1.0f / scale);
glm::vec3 invPos = -(temp * position);
return VQS(invPos, quaternion.Inverse(), 1.0f / scale);
}
void VQS::decomposeMtx(const glm::mat4& m)
{
position = m[3];
glm::vec3 tscale;
for (int i = 0; i < 3; i++)
{
tscale[i] = glm::length(glm::vec3(m[i]));
}
scale = tscale[0];
const glm::mat3 rotMtx(
glm::vec3(m[0]) / tscale[0],
glm::vec3(m[1]) / tscale[1],
glm::vec3(m[2]) / tscale[2]);
glm::quat rot = glm::quat_cast(rotMtx);
quaternion.s = rot.w;
quaternion.v = glm::vec3(rot.x, rot.y, rot.z);
}
void VQS::Decompose(aiMatrix4x4 aiMat)
{
aiVector3D v;
aiVector3D s;
aiQuaternion q;
aiMat.Decompose(s, q, v);
position.x = v.x;
position.y = v.y;
position.z = v.z;
quaternion.s = q.w;
quaternion.v = glm::vec3(q.x, q.y, q.z);
scale = s.x;
//std::cout << *this << std::endl;
}
void VQStest()
{
VQS vqs1;
VQS vqs2(glm::vec3(1.0f, 8.7f, 9.5f), Quaternion(3.0f, glm::vec3(2.7f, 9.9f, 5.4f)), 2.1f);
std::cout << vqs1 << std::endl;
std::cout << vqs2 << std::endl;
std::cout << vqs2.Inverse() << std::endl;
std::cout << vqs2.Inverse() * vqs2 << std::endl;
std::cout << vqs1 * vqs2.Inverse().position << std::endl;
}