2020-04-15 02:03:56 +02:00
|
|
|
#include "Transform.h"
|
2021-01-19 15:30:00 +01:00
|
|
|
#include <glm/gtx/quaternion.hpp>
|
2020-04-15 02:03:56 +02:00
|
|
|
|
|
|
|
|
using namespace Seele;
|
2022-11-15 12:19:11 +01:00
|
|
|
using namespace Seele::Math;
|
2020-04-15 02:03:56 +02:00
|
|
|
|
|
|
|
|
Transform::Transform()
|
2022-03-19 22:45:30 +01:00
|
|
|
: position(Vector4(0, 0, 0, 0)), rotation(Quaternion(1, 0, 0, 0)), scale(Vector4(1, 1, 1, 0))
|
2020-04-15 02:03:56 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-05 01:51:13 +02:00
|
|
|
Transform::Transform(Transform &&other)
|
2020-10-23 01:47:56 +02:00
|
|
|
: position(other.position), rotation(other.rotation), scale(other.scale)
|
2020-05-05 01:51:13 +02:00
|
|
|
{
|
|
|
|
|
other.position = Vector4(0, 0, 0, 0);
|
2022-03-19 22:45:30 +01:00
|
|
|
other.rotation = Quaternion(1, 0, 0, 0);
|
2020-05-05 01:51:13 +02:00
|
|
|
other.scale = Vector4(0, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Transform::Transform(const Transform &other)
|
2020-10-23 01:47:56 +02:00
|
|
|
: position(other.position), rotation(other.rotation), scale(other.scale)
|
2020-05-05 01:51:13 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-15 02:03:56 +02:00
|
|
|
Transform::Transform(Vector position)
|
2022-03-19 22:45:30 +01:00
|
|
|
: position(Vector4(position, 0)), rotation(Quaternion(1, 0, 0, 0)), scale(Vector4(1, 1, 1, 0))
|
2020-04-15 02:03:56 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
Transform::Transform(Vector position, Quaternion rotation)
|
|
|
|
|
: position(Vector4(position, 0)), rotation(rotation), scale(Vector4(1, 1, 1, 0))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
Transform::Transform(Vector position, Quaternion rotation, Vector scale)
|
|
|
|
|
: position(Vector4(position, 0)), rotation(rotation), scale(Vector4(scale, 0))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
Transform::Transform(Quaternion rotation, Vector scale)
|
|
|
|
|
: position(Vector4(0, 0, 0, 0)), rotation(rotation), scale(Vector4(scale, 0))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
Transform::~Transform()
|
|
|
|
|
{
|
|
|
|
|
}
|
2020-05-05 01:51:13 +02:00
|
|
|
Vector Transform::inverseTransformPosition(const Vector &v) const
|
2020-04-15 02:03:56 +02:00
|
|
|
{
|
|
|
|
|
return (unrotateVector(rotation, v - Vector(position))) * getSafeScaleReciprocal(scale);
|
|
|
|
|
}
|
2022-11-15 12:19:11 +01:00
|
|
|
Matrix4 Transform::toMatrix() const
|
2020-05-05 01:51:13 +02:00
|
|
|
{
|
2021-01-19 15:30:00 +01:00
|
|
|
Matrix4 mat;
|
2020-04-15 02:03:56 +02:00
|
|
|
|
2020-05-05 01:51:13 +02:00
|
|
|
mat[3][0] = position.x;
|
|
|
|
|
mat[3][1] = position.y;
|
|
|
|
|
mat[3][2] = position.z;
|
|
|
|
|
|
|
|
|
|
const float x2 = rotation.x + rotation.x;
|
|
|
|
|
const float y2 = rotation.y + rotation.y;
|
|
|
|
|
const float z2 = rotation.z + rotation.z;
|
|
|
|
|
{
|
|
|
|
|
const float xx2 = rotation.x * x2;
|
|
|
|
|
const float yy2 = rotation.y * y2;
|
|
|
|
|
const float zz2 = rotation.z * z2;
|
|
|
|
|
|
|
|
|
|
mat[0][0] = (1.0f - (yy2 + zz2)) * scale.x;
|
|
|
|
|
mat[1][1] = (1.0f - (xx2 + zz2)) * scale.y;
|
|
|
|
|
mat[2][2] = (1.0f - (xx2 + yy2)) * scale.z;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
const float yz2 = rotation.y * z2;
|
|
|
|
|
const float wx2 = rotation.w * x2;
|
|
|
|
|
|
|
|
|
|
mat[2][1] = (yz2 - wx2) * scale.z;
|
|
|
|
|
mat[1][2] = (yz2 + wx2) * scale.y;
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const float xy2 = rotation.x * y2;
|
|
|
|
|
const float wz2 = rotation.w * z2;
|
|
|
|
|
|
|
|
|
|
mat[1][0] = (xy2 - wz2) * scale.y;
|
|
|
|
|
mat[0][1] = (xy2 + wz2) * scale.x;
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
const float xz2 = rotation.x * z2;
|
|
|
|
|
const float wy2 = rotation.w * y2;
|
|
|
|
|
|
|
|
|
|
mat[2][0] = (xz2 + wy2) * scale.z;
|
|
|
|
|
mat[0][2] = (xz2 - wy2) * scale.x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mat[0][3] = 0.0f;
|
|
|
|
|
mat[1][3] = 0.0f;
|
|
|
|
|
mat[2][3] = 0.0f;
|
|
|
|
|
mat[3][3] = 1.0f;
|
|
|
|
|
|
|
|
|
|
return mat;
|
|
|
|
|
}
|
|
|
|
|
Vector Transform::getSafeScaleReciprocal(const Vector4 &inScale, float tolerance)
|
2020-04-15 02:03:56 +02:00
|
|
|
{
|
|
|
|
|
Vector safeReciprocalScale;
|
|
|
|
|
if (abs(inScale.x) <= tolerance)
|
|
|
|
|
{
|
|
|
|
|
safeReciprocalScale.x = 0.f;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
safeReciprocalScale.x = 1 / inScale.x;
|
|
|
|
|
}
|
|
|
|
|
if (abs(inScale.y) <= tolerance)
|
|
|
|
|
{
|
|
|
|
|
safeReciprocalScale.y = 0.f;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
safeReciprocalScale.y = 1 / inScale.y;
|
|
|
|
|
}
|
|
|
|
|
if (abs(inScale.z) <= tolerance)
|
|
|
|
|
{
|
|
|
|
|
safeReciprocalScale.z = 0.f;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
safeReciprocalScale.z = 1 / inScale.z;
|
|
|
|
|
}
|
|
|
|
|
return safeReciprocalScale;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-19 15:30:00 +01:00
|
|
|
Vector Transform::transformPosition(const Vector &v) const
|
|
|
|
|
{
|
|
|
|
|
return Vector(glm::toMat4(rotation) * Vector4(v, 1));
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-05 01:51:13 +02:00
|
|
|
Vector Transform::getPosition() const
|
2020-04-15 02:03:56 +02:00
|
|
|
{
|
|
|
|
|
return Vector(position);
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-05 01:51:13 +02:00
|
|
|
Quaternion Transform::getRotation() const
|
2020-04-15 02:03:56 +02:00
|
|
|
{
|
|
|
|
|
return rotation;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-05 01:51:13 +02:00
|
|
|
Vector Transform::getScale() const
|
2020-04-15 02:03:56 +02:00
|
|
|
{
|
|
|
|
|
return Vector(scale);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-21 18:43:21 +01:00
|
|
|
void Transform::setPosition(Vector pos)
|
2022-11-29 16:34:42 +01:00
|
|
|
{
|
|
|
|
|
position = Vector4(pos, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-21 18:43:21 +01:00
|
|
|
void Transform::setRotation(Quaternion quat)
|
2022-11-29 16:34:42 +01:00
|
|
|
{
|
|
|
|
|
rotation = quat;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-21 18:43:21 +01:00
|
|
|
void Transform::setScale(Vector s)
|
2022-11-29 16:34:42 +01:00
|
|
|
{
|
|
|
|
|
scale = Vector4(s, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-19 22:45:30 +01:00
|
|
|
Vector Transform::getForward() const
|
|
|
|
|
{
|
2022-03-26 12:55:04 +01:00
|
|
|
return glm::normalize(Vector(0, 0, 1) * rotation);
|
2022-03-19 22:45:30 +01:00
|
|
|
}
|
2022-11-29 16:34:42 +01:00
|
|
|
|
2022-03-19 22:45:30 +01:00
|
|
|
Vector Transform::getRight() const
|
|
|
|
|
{
|
2022-03-26 12:55:04 +01:00
|
|
|
return glm::normalize(Vector(1, 0, 0) * rotation);
|
2022-03-19 22:45:30 +01:00
|
|
|
}
|
2022-11-29 16:34:42 +01:00
|
|
|
|
2022-03-19 22:45:30 +01:00
|
|
|
Vector Transform::getUp() const
|
|
|
|
|
{
|
2022-03-26 12:55:04 +01:00
|
|
|
return glm::normalize(Vector(0, 1, 0) * rotation);
|
2022-03-19 22:45:30 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-05 01:51:13 +02:00
|
|
|
bool Transform::equals(const Transform &other, float tolerance)
|
|
|
|
|
{
|
|
|
|
|
if (abs(position - other.position).length() > tolerance)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2021-10-16 12:59:11 +02:00
|
|
|
if ((abs(rotation.x - other.rotation.x) <= tolerance
|
|
|
|
|
&& abs(rotation.y - other.rotation.y) <= tolerance
|
|
|
|
|
&& abs(rotation.z - other.rotation.z) <= tolerance
|
|
|
|
|
&& abs(rotation.w - other.rotation.w) <= tolerance)
|
|
|
|
|
|| (abs(rotation.x + other.rotation.x) <= tolerance
|
|
|
|
|
&& abs(rotation.y + other.rotation.y) <= tolerance
|
|
|
|
|
&& abs(rotation.z + other.rotation.z) <= tolerance
|
|
|
|
|
&& abs(rotation.w + other.rotation.w) <= tolerance))
|
2020-05-05 01:51:13 +02:00
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (abs(scale - other.scale).length() > tolerance)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Transform::multiply(Transform *outTransform, const Transform *a, const Transform *b)
|
2020-04-15 02:03:56 +02:00
|
|
|
{
|
|
|
|
|
outTransform->rotation = b->rotation * a->rotation;
|
2021-01-19 15:30:00 +01:00
|
|
|
outTransform->position = b->rotation * (b->scale * a->position) + b->position;
|
2020-04-15 02:03:56 +02:00
|
|
|
outTransform->scale = b->scale * a->scale;
|
|
|
|
|
}
|
2022-03-19 22:45:30 +01:00
|
|
|
void Transform::add(Transform *outTransform, const Transform *a, const Transform *b)
|
|
|
|
|
{
|
|
|
|
|
outTransform->position = a->position + b->position;
|
|
|
|
|
outTransform->rotation = a->rotation + b->rotation;
|
|
|
|
|
outTransform->scale = a->scale + b->scale;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-05 01:51:13 +02:00
|
|
|
|
|
|
|
|
Transform &Transform::operator=(const Transform &other)
|
|
|
|
|
{
|
2022-11-15 12:19:11 +01:00
|
|
|
if(&other != this)
|
|
|
|
|
{
|
|
|
|
|
position = other.position;
|
|
|
|
|
rotation = other.rotation;
|
|
|
|
|
scale = other.scale;
|
|
|
|
|
}
|
2020-05-05 01:51:13 +02:00
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Transform &Transform::operator=(Transform &&other)
|
|
|
|
|
{
|
2022-11-15 12:19:11 +01:00
|
|
|
if(&other != this)
|
|
|
|
|
{
|
|
|
|
|
position = other.position;
|
|
|
|
|
rotation = other.rotation;
|
|
|
|
|
scale = other.scale;
|
|
|
|
|
other.position = Vector4(0, 0, 0, 0);
|
|
|
|
|
other.rotation = Quaternion(1, 0, 0, 0);
|
|
|
|
|
other.scale = Vector4(0, 0, 0, 0);
|
|
|
|
|
}
|
2020-05-05 01:51:13 +02:00
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-19 22:45:30 +01:00
|
|
|
Transform Transform::operator+(const Transform & other) const
|
|
|
|
|
{
|
|
|
|
|
Transform outTransform;
|
|
|
|
|
add(&outTransform, this, &other);
|
|
|
|
|
return outTransform;
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-19 15:30:00 +01:00
|
|
|
Transform Transform::operator*(const Transform &other) const
|
2020-05-05 01:51:13 +02:00
|
|
|
{
|
|
|
|
|
Transform outTransform;
|
|
|
|
|
multiply(&outTransform, this, &other);
|
2021-10-16 12:59:11 +02:00
|
|
|
return outTransform;
|
2020-05-05 01:51:13 +02:00
|
|
|
}
|