Files
Seele/src/Engine/Math/Vector.h
T

133 lines
3.6 KiB
C++
Raw Normal View History

#pragma once
#pragma warning(push)
#pragma warning(disable: 4201)
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
2020-05-05 01:51:13 +02:00
2020-04-15 02:03:56 +02:00
#include <glm/gtc/quaternion.hpp>
#pragma warning(pop)
2023-01-21 18:43:21 +01:00
#include <nlohmann/json_fwd.hpp>
2023-07-13 21:01:20 +02:00
#include "Serialization/Serialization.h"
2023-02-13 14:56:13 +01:00
2020-04-12 15:47:19 +02:00
namespace Seele
{
typedef glm::vec2 Vector2;
2020-04-15 02:03:56 +02:00
typedef glm::vec3 Vector;
2020-04-12 15:47:19 +02:00
typedef glm::vec4 Vector4;
2020-04-12 15:47:19 +02:00
typedef glm::uvec2 UVector2;
2023-02-13 14:56:13 +01:00
typedef glm::uvec3 UVector;
2020-04-12 15:47:19 +02:00
typedef glm::uvec4 UVector4;
2020-04-12 15:47:19 +02:00
typedef glm::ivec2 IVector2;
2023-02-13 14:56:13 +01:00
typedef glm::ivec3 IVector;
2020-04-12 15:47:19 +02:00
typedef glm::ivec4 IVector4;
2020-04-15 02:03:56 +02:00
typedef glm::quat Quaternion;
2020-06-02 11:46:18 +02:00
Vector parseVector(const char*);
2020-04-15 02:03:56 +02:00
static inline float square(float x)
{
2020-05-05 01:51:13 +02:00
return x * x;
2020-04-15 02:03:56 +02:00
}
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;
}
2020-05-05 01:51:13 +02:00
static inline bool equalsQuaternion(const Quaternion &right, const Quaternion &left, float tolerance)
2020-04-15 02:03:56 +02:00
{
2020-05-05 01:51:13 +02:00
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);
2020-04-15 02:03:56 +02:00
}
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;
}
2020-05-05 01:51:13 +02:00
static inline Vector toRotator(const Quaternion &other)
2020-04-15 02:03:56 +02:00
{
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)));
2020-05-05 01:51:13 +02:00
2020-04-15 02:03:56 +02:00
const float SINGULARITY_THRESHOLD = 0.4999995f;
2023-02-01 22:13:04 +01:00
constexpr const float RAD_TO_DEG = (180.f) / glm::pi<float>();
2020-04-15 02:03:56 +02:00
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;
}
2023-01-21 18:43:21 +01:00
void to_json(nlohmann::json& j, const Vector& vec);
void from_json(nlohmann::json& j, Vector& vec);
2023-02-13 14:56:13 +01:00
namespace Serialization
{
static void save(ArchiveBuffer& buffer, const IVector2& vec)
{
save(buffer, vec.x);
save(buffer, vec.y);
}
static void load(ArchiveBuffer& buffer, IVector2& vec)
{
save(buffer, vec.x);
save(buffer, vec.y);
}
static void save(ArchiveBuffer& buffer, const Vector& vec)
{
save(buffer, vec.x);
save(buffer, vec.y);
save(buffer, vec.z);
}
static void load(ArchiveBuffer& buffer, Vector& vec)
{
save(buffer, vec.x);
save(buffer, vec.y);
save(buffer, vec.z);
}
} // namespace Serialization
2022-11-17 16:47:42 +01:00
} // namespace Seele
2023-01-21 18:43:21 +01:00
std::ostream& operator<<(std::ostream& stream, const Seele::Vector2& vector);
std::ostream& operator<<(std::ostream& stream, const Seele::Vector& vector);
2023-02-13 14:56:13 +01:00
std::ostream& operator<<(std::ostream& stream, const Seele::Vector4& vector);