Implementing basic scene tree

This commit is contained in:
Dynamitos
2020-04-15 02:04:42 +02:00
parent 576747c369
commit 3ef8342247
34 changed files with 722 additions and 54 deletions
+3 -1
View File
@@ -2,4 +2,6 @@ target_sources(SeeleEngine
PRIVATE
Math.h
Matrix.h
Vector.h)
Vector.h
Transform.h
Transform.cpp)
+2 -2
View File
@@ -26,7 +26,7 @@ struct Rect
};
struct Rect3D
{
Vector3 size;
Vector3 offset;
Vector size;
Vector offset;
};
} // namespace Seele
+84
View File
@@ -0,0 +1,84 @@
#include "Transform.h"
using namespace Seele;
Transform::Transform()
: position(Vector4(0, 0, 0, 0)), rotation(Quaternion(0, 0, 0, 0)), scale(Vector4(1, 1, 1, 0))
{
}
Transform::Transform(Vector position)
: position(Vector4(position, 0)), rotation(Quaternion(0, 0, 0, 0)), scale(Vector4(1, 1, 1, 0))
{
}
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()
{
}
Vector Transform::inverseTransformPosition(const Vector& v) const
{
return (unrotateVector(rotation, v - Vector(position))) * getSafeScaleReciprocal(scale);
}
Vector Transform::getSafeScaleReciprocal(const Vector4& inScale, float tolerance)
{
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;
}
inline Vector Transform::getPosition() const
{
return Vector(position);
}
inline Quaternion Transform::getRotation() const
{
return rotation;
}
inline Vector Transform::getScale() const
{
return Vector(scale);
}
inline void Transform::multiply(Transform* outTransform, const Transform* a, const Transform* b)
{
outTransform->rotation = b->rotation * a->rotation;
outTransform->position = b->position * (b->scale * a->position) + b->position;
outTransform->scale = b->scale * a->scale;
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include "Vector.h"
namespace Seele
{
class Transform
{
public:
Transform();
Transform(Vector position);
Transform(Vector position, Quaternion rotation);
Transform(Vector position, Quaternion rotation, Vector scale);
Transform(Quaternion rotation, Vector scale);
~Transform();
Vector inverseTransformPosition(const Vector &v) const;
static Vector getSafeScaleReciprocal(const Vector4 &inScale, float tolerance = 0.00001f);
inline Vector getPosition() const;
inline Quaternion getRotation() const;
inline Vector getScale() const;
inline static void multiply(Transform* outTransform, const Transform* a, const Transform* b);
Transform& operator*(const Transform& other) const
{
Transform outTransform;
multiply(&outTransform, this, &other);
return outTransform;
}
private:
Vector4 position;
Quaternion rotation;
Vector4 scale;
};
} // namespace Seele
+99 -1
View File
@@ -2,10 +2,11 @@
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <glm/gtc/quaternion.hpp>
namespace Seele
{
typedef glm::vec2 Vector2;
typedef glm::vec3 Vector3;
typedef glm::vec3 Vector;
typedef glm::vec4 Vector4;
typedef glm::uvec2 UVector2;
@@ -15,4 +16,101 @@ typedef glm::uvec4 UVector4;
typedef glm::ivec2 IVector2;
typedef glm::ivec3 IVector3;
typedef glm::ivec4 IVector4;
typedef glm::quat Quaternion;
static inline float square(float x)
{
return x * x;
}
static inline Vector unrotateVector(Quaternion quaternion, Vector v)
{
const Vector q(-quaternion.x, -quaternion.y, -quaternion.z);
const Vector t = 2.f * glm::cross(q, v);
const Vector result = v + (quaternion.w * t) + glm::cross(q, t);
return result;
}
static inline bool equalsQuaternion(const Quaternion& right, const Quaternion& left, float tolerance)
{
return (abs(right.x - left.x) <= tolerance && abs(right.y - left.y) <= tolerance && abs(right.z - left.z) <= tolerance && abs(right.w - left.w) <= tolerance)
|| (abs(right.x + left.x) <= tolerance && abs(right.y + left.y) <= tolerance && abs(right.z + left.z) <= tolerance && abs(right.w + left.w) <= tolerance);
}
static inline float clampRotatorAxis(float angle)
{
angle = fmod(angle, 360.f);
if (angle < 0.f)
{
angle += 360.f;
}
return angle;
}
static inline float normalizeRotatorAxis(float angle)
{
angle = clampRotatorAxis(angle);
if (angle > 180.f)
{
angle -= 360.f;
}
return angle;
}
static inline Quaternion toQuaternion(const Vector& other)
{
Quaternion result;
const float DEG_TO_RAD = glm::pi<float>() / (180.f);
const float RADS_DIVIDED_BY_2 = DEG_TO_RAD / 2.f;
const float PitchNoWinding = fmod(other.x, 360.0f);
const float YawNoWinding = fmod(other.y, 360.0f);
const float RollNoWinding = fmod(other.z, 360.0f);
const float SP = sin(PitchNoWinding * RADS_DIVIDED_BY_2);
const float SY = sin(YawNoWinding * RADS_DIVIDED_BY_2);
const float SR = sin(RollNoWinding * RADS_DIVIDED_BY_2);
const float CP = cos(PitchNoWinding * RADS_DIVIDED_BY_2);
const float CY = cos(YawNoWinding * RADS_DIVIDED_BY_2);
const float CR = cos(RollNoWinding * RADS_DIVIDED_BY_2);
result.x = CR * SP * SY - SR * CP * CY;
result.y = -CR * SP * CY - SR * CP * SY;
result.z = CR * CP * SY - SR * SP * CY;
result.w = CR * CP * CY + SR * SP * SY;
return result;
}
static inline Vector toRotator(const Quaternion& other)
{
const float singularityTest = other.z * other.x - other.w * other.y;
const float yawY = 2.f * (other.w * other.z + other.x * other.y);
const float yawX = (1.f - 2.f * (square(other.y) + square(other.z)));
const float SINGULARITY_THRESHOLD = 0.4999995f;
const float RAD_TO_DEG = (180.f) / glm::pi<float>();
Vector rotatorFromQuat;
if (singularityTest < -SINGULARITY_THRESHOLD)
{
rotatorFromQuat.x = -90.f;
rotatorFromQuat.y = atan2(yawY, yawX) * RAD_TO_DEG;
rotatorFromQuat.z = normalizeRotatorAxis(-rotatorFromQuat.y - (2.f * atan2(other.x, other.w) * RAD_TO_DEG));
}
else if (singularityTest > SINGULARITY_THRESHOLD)
{
rotatorFromQuat.x = 90.f;
rotatorFromQuat.y = atan2(yawY, yawX) * RAD_TO_DEG;
rotatorFromQuat.z = normalizeRotatorAxis(rotatorFromQuat.y - (2.f * atan2(other.x, other.w) * RAD_TO_DEG));
}
else
{
rotatorFromQuat.x = asin(2.f * (singularityTest)) * RAD_TO_DEG;
rotatorFromQuat.y = atan2(yawY, yawX) * RAD_TO_DEG;
rotatorFromQuat.z = atan2(-2.f * (other.w * other.x + other.y * other.z), (1.f - 2.f * (square(other.x) + square(other.y)))) * RAD_TO_DEG;
}
return rotatorFromQuat;
}
} // namespace Seele