85 lines
2.3 KiB
C++
85 lines
2.3 KiB
C++
#pragma once
|
|
|
|
#include <Orange/Math/Transformation.h>
|
|
|
|
namespace orange
|
|
{
|
|
|
|
struct Transform
|
|
{
|
|
vec3 position{ 0.0f };
|
|
quat orientation{}; // my orientation is gay
|
|
vec3 scale{ 1.0f };
|
|
};
|
|
|
|
// World = Parent * Local
|
|
inline Transform operator*(const Transform& parent, const Transform& local)
|
|
{
|
|
return Transform
|
|
{
|
|
.position = parent.position + parent.orientation * (parent.scale * local.position),
|
|
.orientation = parent.orientation * local.orientation,
|
|
.scale = parent.scale * (parent.orientation * local.scale),
|
|
};
|
|
}
|
|
|
|
inline Transform& operator*=(Transform& parent, const Transform& local)
|
|
{
|
|
parent = parent * local;
|
|
return parent;
|
|
}
|
|
|
|
// Local = World / Parent
|
|
inline Transform operator/(const Transform& world, const Transform& parent)
|
|
{
|
|
const Quaternion parentConjugate = conjugate(parent.orientation);
|
|
|
|
return Transform
|
|
{
|
|
.position = (parentConjugate * (world.position - parent.position)) / parent.scale,
|
|
.orientation = (parentConjugate * world.orientation),
|
|
.scale = (parentConjugate * (world.scale / parent.scale)),
|
|
};
|
|
}
|
|
|
|
inline Transform& operator/=(Transform& world, const Transform& parent)
|
|
{
|
|
world = world / parent;
|
|
return world;
|
|
}
|
|
|
|
inline vec3 transformPoint(const Transform& transform, const vec3& point)
|
|
{
|
|
return (conjugate(transform.orientation) * (transform.position - point)) / transform.scale;
|
|
}
|
|
|
|
inline Transform inverse(const Transform& t)
|
|
{
|
|
const Quaternion invOrientation{ conjugate(t.orientation) };
|
|
|
|
return Transform
|
|
{
|
|
.position = (invOrientation * -t.position) / t.scale,
|
|
.orientation = (invOrientation),
|
|
.scale = (invOrientation * (vec3{ 1.0f } / t.scale)),
|
|
};
|
|
}
|
|
|
|
// Returns true if a Transform does bugger all.
|
|
bool identity(const Transform& t)
|
|
{
|
|
return t.position == vec3{0.0f} &&
|
|
t.orientation == quat{} &&
|
|
t.scale == vec3{1.0f};
|
|
}
|
|
|
|
// TODO:
|
|
mat4 transformMatrix4(const Transform& t)
|
|
{
|
|
return Math::translate(t.position) *
|
|
quaternionToMatrix4(t.orientation) *
|
|
Math::scale(t.scale);
|
|
}
|
|
|
|
}
|