1
0
mirror of https://github.com/borgesdan/xn65 synced 2024-12-29 21:54:47 +01:00

Implementa Quaternion

This commit is contained in:
Danilo 2024-05-10 15:51:03 -03:00
parent ca83f9d8d7
commit fd32d56715
8 changed files with 433 additions and 90 deletions

View File

@ -39,14 +39,15 @@ add_executable (xna WIN32
"content/manager.cpp"
"content/reader.cpp"
"csharp/binary.cpp"
"content/lzx/decoder.cpp"
"content/lzx/decoderstream.cpp"
"content/typereadermanager.cpp"
"csharp/object.cpp"
"csharp/type.cpp"
"platform/init-dx.cpp"
"game/servicecontainer.cpp"
"common/color.cpp")
"content/lzx/decoder.cpp"
"content/lzx/decoderstream.cpp"
"content/typereadermanager.cpp"
"csharp/object.cpp"
"csharp/type.cpp"
"platform/init-dx.cpp"
"game/servicecontainer.cpp"
"common/color.cpp"
"common/math.cpp" "common/quaternion.cpp")
if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET xna PROPERTY CXX_STANDARD 20)

View File

@ -1,5 +1,71 @@
#include "common/color.hpp"
namespace xna {
Color::Color(float r, float g, float b, float a) :
_packedValue(PackHelper(r, g, b, a)) {
}
Color::Color(Vector3 const& vector) :
_packedValue(PackHelper(vector.X, vector.Y, vector.Z, 1.0F)) {
}
Color::Color(Vector4 const& vector) :
_packedValue(PackHelper(vector.X, vector.Y, vector.Z, vector.W)) {
}
void Color::PackFromVector4(Vector4 const& vector) {
_packedValue = PackHelper(vector.X, vector.Y, vector.Z, vector.W);
}
Color Color::FromNonPremultiplied(Vector4 const& vector) {
Color color;
color._packedValue = PackHelper(vector.X * vector.W, vector.Y * vector.W, vector.Z * vector.W, vector.W);
return color;
}
Color Color::FromNonPremultiplied(Int r, Int g, Int b, Int a) {
r = ClampToByte32(r * a / ByteMaxValue);
g = ClampToByte32(g * a / ByteMaxValue);
b = ClampToByte32(b * a / ByteMaxValue);
a = ClampToByte32(a);
g <<= 8;
b <<= 16;
a <<= 24;
Color color;
color._packedValue = static_cast<Uint>(r | g | b | a);
return color;
}
Color Color::Lerp(Color const& value1, Color const& value2, float amount) {
const Int r1 = value1.R();
const Int g1 = value1.G();
const Int b1 = value1.B();
const Int a1 = value1.A();
const Int r2 = value2.R();
const Int g2 = value2.G();
const Int b2 = value2.B();
const Int a2 = value2.A();
const auto bitmask = static_cast<Int>(PackUtils::PackUNorm(65536.0f, amount));
const Int r = r1 + ((r2 - r1) * bitmask >> 16);
const Int g = g1 + ((g2 - g1) * bitmask >> 16);
const Int b = b1 + ((b2 - b1) * bitmask >> 16);
const Int a = a1 + ((a2 - a1) * bitmask >> 16);
Color color;
color._packedValue = static_cast<Uint>(r | g << 8 | b << 16 | a << 24);
return color;
}
Uint Color::PackHelper(float vectorX, float vectorY, float vectorZ, float vectorW) {
const auto byteMax = static_cast<float>(ByteMaxValue);
const auto x = PackUtils::PackUNorm(byteMax, vectorX);
const auto y = PackUtils::PackUNorm(byteMax, vectorY) << 8;
const auto z = PackUtils::PackUNorm(byteMax, vectorZ);
const auto w = PackUtils::PackUNorm(byteMax, vectorW) << 24;
return x | y | z | w;
}
}

20
framework/common/math.cpp Normal file
View File

@ -0,0 +1,20 @@
#include "common/math.hpp"
namespace xna {
float MathHelper::CatmullRom(float value1, float value2, float value3, float value4, float amount) {
const auto num1 = amount * amount;
const auto num2 = amount * num1;
return (0.5F * (2.0F * value2 + (-value1 + value3) * amount + (2.0F * value1 - 5.0F * value2 + 4.0F * value3 - value4) * num1 + (-value1 + 3.0F * value2 - 3.0F * value3 + value4) * num2));
}
float MathHelper::Hermite(float value1, float tangent1, float value2, float tangent2, float amount) {
const auto num1 = amount;
const auto num2 = num1 * num1;
const auto num3 = num1 * num2;
const auto num4 = (2.0F * num3 - 3.0F * num2 + 1.0F);
const auto num5 = (-2.0F * num3 + 3.0F * num2);
const auto num6 = num3 - 2.0f * num2 + num1;
const auto num7 = num3 - num2;
return value1 * num4 + value2 * num5 + tangent1 * num6 + tangent2 * num7;
}
}

View File

@ -0,0 +1,133 @@
#include "common/quaternion.hpp"
#include "common/matrix.hpp"
namespace xna {
Quaternion Quaternion::CreateFromAxisAngle(Vector3 const& axis, float angle) {
const auto num1 = angle * 0.5f;
const auto num2 = std::sin(num1);
const auto num3 = std::cos(num1);
Quaternion fromAxisAngle;
fromAxisAngle.X = axis.X * num2;
fromAxisAngle.Y = axis.Y * num2;
fromAxisAngle.Z = axis.Z * num2;
fromAxisAngle.W = num3;
return fromAxisAngle;
}
Quaternion Quaternion::CreateFromYawPitchRoll(float yaw, float pitch, float roll) {
const auto num1 = roll * 0.5f;
const auto num2 = std::sin(num1);
const auto num3 = std::cos(num1);
const auto num4 = pitch * 0.5f;
const auto num5 = std::sin(num4);
const auto num6 = std::cos(num4);
const auto num7 = yaw * 0.5f;
const auto num8 = std::sin(num7);
const auto num9 = std::cos(num7);
Quaternion fromYawPitchRoll;
fromYawPitchRoll.X = (num9 * num5 * num3 + num8 * num6 * num2);
fromYawPitchRoll.Y = (num8 * num6 * num3 - num9 * num5 * num2);
fromYawPitchRoll.Z = (num9 * num6 * num2 - num8 * num5 * num3);
fromYawPitchRoll.W = (num9 * num6 * num3 + num8 * num5 * num2);
return fromYawPitchRoll;
}
Quaternion Quaternion::CreateFromRotationMatrix(Matrix const& matrix) {
const auto num1 = matrix.M11 + matrix.M22 + matrix.M33;
Quaternion fromRotationMatrix;
if (num1 > 0.0)
{
const auto num2 = std::sqrt(num1 + 1.0F);
fromRotationMatrix.W = num2 * 0.5f;
const auto num3 = 0.5f / num2;
fromRotationMatrix.X = (matrix.M23 - matrix.M32) * num3;
fromRotationMatrix.Y = (matrix.M31 - matrix.M13) * num3;
fromRotationMatrix.Z = (matrix.M12 - matrix.M21) * num3;
}
else if (matrix.M11 >= matrix.M22 && matrix.M11 >= matrix.M33)
{
const auto num4 = std::sqrt(1.0F + matrix.M11 - matrix.M22 - matrix.M33);
const auto num5 = 0.5f / num4;
fromRotationMatrix.X = 0.5f * num4;
fromRotationMatrix.Y = (matrix.M12 + matrix.M21) * num5;
fromRotationMatrix.Z = (matrix.M13 + matrix.M31) * num5;
fromRotationMatrix.W = (matrix.M23 - matrix.M32) * num5;
}
else if (matrix.M22 > matrix.M33)
{
const auto num6 = std::sqrt(1.0F + matrix.M22 - matrix.M11 - matrix.M33);
const auto num7 = 0.5f / num6;
fromRotationMatrix.X = (matrix.M21 + matrix.M12) * num7;
fromRotationMatrix.Y = 0.5f * num6;
fromRotationMatrix.Z = (matrix.M32 + matrix.M23) * num7;
fromRotationMatrix.W = (matrix.M31 - matrix.M13) * num7;
}
else
{
const auto num8 = std::sqrt(1.0F + matrix.M33 - matrix.M11 - matrix.M22);
const auto num9 = 0.5f / num8;
fromRotationMatrix.X = (matrix.M31 + matrix.M13) * num9;
fromRotationMatrix.Y = (matrix.M32 + matrix.M23) * num9;
fromRotationMatrix.Z = 0.5f * num8;
fromRotationMatrix.W = (matrix.M12 - matrix.M21) * num9;
}
return fromRotationMatrix;
}
Quaternion Quaternion::Slerp(Quaternion const& quaternion1, Quaternion const& quaternion2, float amount) {
const auto num1 = amount;
auto d = quaternion1.X * quaternion2.X + quaternion1.Y * quaternion2.Y + quaternion1.Z * quaternion2.Z + quaternion1.W * quaternion2.W;
bool flag = false;
if (d < 0.0) {
flag = true;
d = -d;
}
float num2 = 0;
float num3 = 0;
if (d > 0.99999898672103882) {
num2 = 1.0f - num1;
num3 = flag ? -num1 : num1;
}
else {
const auto a = std::acos(d);
const auto num4 = 1.0F / std::sin(a);
num2 = std::sin((1.0F - num1) * a) * num4;
num3 = flag ? -std::sin(num1 * a) * num4 : std::sin(num1 * a) * num4;
}
Quaternion quaternion;
quaternion.X = num2 * quaternion1.X + num3 * quaternion2.X;
quaternion.Y = num2 * quaternion1.Y + num3 * quaternion2.Y;
quaternion.Z = num2 * quaternion1.Z + num3 * quaternion2.Z;
quaternion.W = num2 * quaternion1.W + num3 * quaternion2.W;
return quaternion;
}
Quaternion Quaternion::Lerp(Quaternion const& quaternion1, Quaternion const& quaternion2, float amount) {
const auto num1 = amount;
const auto num2 = 1.0f - num1;
Quaternion quaternion;
if (quaternion1.X * quaternion2.X + quaternion1.Y * quaternion2.Y + quaternion1.Z * quaternion2.Z + quaternion1.W * quaternion2.W >= 0.0) {
quaternion.X = num2 * quaternion1.X + num1 * quaternion2.X;
quaternion.Y = num2 * quaternion1.Y + num1 * quaternion2.Y;
quaternion.Z = num2 * quaternion1.Z + num1 * quaternion2.Z;
quaternion.W = num2 * quaternion1.W + num1 * quaternion2.W;
}
else {
quaternion.X = num2 * quaternion1.X - num1 * quaternion2.X;
quaternion.Y = num2 * quaternion1.Y - num1 * quaternion2.Y;
quaternion.Z = num2 * quaternion1.Z - num1 * quaternion2.Z;
quaternion.W = num2 * quaternion1.W - num1 * quaternion2.W;
}
const auto num3 = 1.0f / std::sqrt(quaternion.X * quaternion.X + quaternion.Y * quaternion.Y + quaternion.Z * quaternion.Z + quaternion.W * quaternion.W);
quaternion.X *= num3;
quaternion.Y *= num3;
quaternion.Z *= num3;
quaternion.W *= num3;
return quaternion;
}
}

View File

@ -27,41 +27,15 @@ namespace xna {
_packedValue = static_cast<Uint>(r | g | b | a);
}
Color(float r, float g, float b, float a = 1.0F) :
_packedValue(PackHelper(r, g, b, a)) {
}
Color(float r, float g, float b, float a = 1.0F);
Color(Vector3 const& vector);
Color(Vector4 const& vector);
Color(Vector3 const& vector) :
_packedValue(PackHelper(vector.X, vector.Y, vector.Z, 1.0F)) {
}
virtual void PackFromVector4(Vector4 const& vector) override;
Color(Vector4 const& vector) :
_packedValue(PackHelper(vector.X, vector.Y, vector.Z, vector.W)) {
}
static Color FromNonPremultiplied(Vector4 const& vector);
virtual void PackFromVector4(Vector4 const& vector) override {
_packedValue = PackHelper(vector.X, vector.Y, vector.Z, vector.W);
}
static Color FromNonPremultiplied(Vector4 const& vector) {
Color color;
color._packedValue = PackHelper(vector.X * vector.W, vector.Y * vector.W, vector.Z * vector.W, vector.W);
return color;
}
static Color FromNonPremultiplied(Int r, Int g, Int b, Int a) {
r = ClampToByte32(r * a / ByteMaxValue);
g = ClampToByte32(g * a / ByteMaxValue);
b = ClampToByte32(b * a / ByteMaxValue);
a = ClampToByte32(a);
g <<= 8;
b <<= 16;
a <<= 24;
Color color;
color._packedValue = static_cast<Uint>(r | g | b | a);
return color;
}
static Color FromNonPremultiplied(Int r, Int g, Int b, Int a);
constexpr Vector3 ToVector3() const {
Vector3 vector3;
@ -122,27 +96,7 @@ namespace xna {
_packedValue = value;
}
static Color Lerp(Color const& value1, Color const& value2, float amount) {
const Int r1 = value1.R();
const Int g1 = value1.G();
const Int b1 = value1.B();
const Int a1 = value1.A();
const Int r2 = value2.R();
const Int g2 = value2.G();
const Int b2 = value2.B();
const Int a2 = value2.A();
const auto bitmask = static_cast<Int>(PackUtils::PackUNorm(65536.0f, amount));
const Int r = r1 + ((r2 - r1) * bitmask >> 16);
const Int g = g1 + ((g2 - g1) * bitmask >> 16);
const Int b = b1 + ((b2 - b1) * bitmask >> 16);
const Int a = a1 + ((a2 - a1) * bitmask >> 16);
Color color;
color._packedValue = static_cast<Uint>(r | g << 8 | b << 16 | a << 24);
return color;
}
static Color Lerp(Color const& value1, Color const& value2, float amount);
static constexpr Color Multiply(Color const& value, float scale) {
const Uint r = value.R();
@ -203,15 +157,7 @@ namespace xna {
return value > ByteMaxValue ? ByteMaxValue : value;
}
static Uint PackHelper(float vectorX, float vectorY, float vectorZ, float vectorW) {
const auto byteMax = static_cast<float>(ByteMaxValue);
const auto x = PackUtils::PackUNorm(byteMax, vectorX);
const auto y = PackUtils::PackUNorm(byteMax, vectorY) << 8;
const auto z = PackUtils::PackUNorm(byteMax, vectorZ);
const auto w = PackUtils::PackUNorm(byteMax, vectorW) << 24;
return x | y | z | w;
}
static Uint PackHelper(float vectorX, float vectorY, float vectorZ, float vectorW);
};
struct Colors {

View File

@ -6,9 +6,9 @@
namespace xna {
struct MathHelper {
static constexpr double E = 2.7182818284590451;
static constexpr double PI = 3.1415926535897931;
static constexpr double TAU = 6.2831853071795862;
static constexpr double E = 2.7182818284590452354;
static constexpr double PI = 3.14159265358979323846;
static constexpr double TAU = PI * 2;
static constexpr double EPSILON = std::numeric_limits<double>::epsilon();
static constexpr float ToRadians(float degrees) { return degrees * (static_cast<float>(PI) / 180.0f); }
@ -36,22 +36,8 @@ namespace xna {
return Lerp(value1, value2, (num * num * (3.0F - 2.0F * num)));
}
static float CatmullRom(float value1, float value2, float value3, float value4, float amount) {
const auto num1 = amount * amount;
const auto num2 = amount * num1;
return (0.5F * (2.0F * value2 + (-value1 + value3) * amount + (2.0F * value1 - 5.0F * value2 + 4.0F * value3 - value4) * num1 + (-value1 + 3.0F * value2 - 3.0F * value3 + value4) * num2));
}
static float Hermite(float value1, float tangent1, float value2, float tangent2, float amount) {
const auto num1 = amount;
const auto num2 = num1 * num1;
const auto num3 = num1 * num2;
const auto num4 = (2.0F * num3 - 3.0F * num2 + 1.0F);
const auto num5 = (-2.0F * num3 + 3.0F * num2);
const auto num6 = num3 - 2.0f * num2 + num1;
const auto num7 = num3 - num2;
return value1 * num4 + value2 * num5 + tangent1 * num6 + tangent2 * num7;
}
static float CatmullRom(float value1, float value2, float value3, float value4, float amount);
static float Hermite(float value1, float tangent1, float value2, float tangent2, float amount);
};
}

View File

@ -1,9 +1,9 @@
#ifndef CXNA_COMMON_PACKEDVECTOR_HPP
#define CXNA_COMMON_PACKEDVECTOR_HPP
#include "../default.hpp"
#include "vectors.hpp"
#include <cmath>
#include "../default.hpp"
namespace xna {
class IPackedVector {

View File

@ -15,9 +15,200 @@ namespace xna {
constexpr Quaternion(float X, float Y, float Z, float W)
: X(X), Y(Y), Z(Z), W(W) { }
constexpr Quaternion(Vector3 vectorPart, float scalarPart)
: X(vectorPart.X), Y(vectorPart.Y), Z(vectorPart.Z), W(scalarPart) { }
constexpr bool operator==(const Quaternion& other) const {
return X == other.X && Y == other.Y && Z == other.Z && W == other.W;
}
static constexpr Quaternion Identity() {
return { 0.0f, 0.0f, 0.0f, 1.0f };
}
float constexpr LengthSquared() const {
return X * X + Y * Y + Z * Z + W * W;
}
inline float Length() const { return std::sqrt(LengthSquared()); }
void Normalize() {
const auto num = 1.0F / Length();
X *= num;
Y *= num;
Z *= num;
W *= num;
}
static Quaternion Normalize(Quaternion const& quaternion) {
auto q = quaternion;
q.Normalize();
return q;
}
constexpr void Conjugate() {
X = -X;
Y = -Y;
Z = -Z;
}
static constexpr Quaternion Conjugate(Quaternion const& value) {
Quaternion quaternion;
quaternion.X = -value.X;
quaternion.Y = -value.Y;
quaternion.Z = -value.Z;
quaternion.W = value.W;
return quaternion;
}
static constexpr Quaternion Inverse(Quaternion const& quaternion) {
const auto num = 1.0f / quaternion.LengthSquared();
Quaternion quaternion1;
quaternion1.X = -quaternion.X * num;
quaternion1.Y = -quaternion.Y * num;
quaternion1.Z = -quaternion.Z * num;
quaternion1.W = quaternion.W * num;
return quaternion1;
}
static Quaternion CreateFromAxisAngle(Vector3 const& axis, float angle);
static Quaternion CreateFromYawPitchRoll(float yaw, float pitch, float roll);
static Quaternion CreateFromRotationMatrix(Matrix const& matrix);
static constexpr float Dot(Quaternion const& quaternion1, Quaternion const& quaternion2) {
return quaternion1.X * quaternion2.X + quaternion1.Y * quaternion2.Y + quaternion1.Z * quaternion2.Z + quaternion1.W * quaternion2.W;
}
static Quaternion Slerp(Quaternion const& quaternion1, Quaternion const& quaternion2, float amount);
static Quaternion Lerp(Quaternion const& quaternion1, Quaternion const& quaternion2, float amount);
static constexpr Quaternion Concatenate(Quaternion const& value1, Quaternion const& value2) {
const auto x1 = value2.X;
const auto y1 = value2.Y;
const auto z1 = value2.Z;
const auto w1 = value2.W;
const auto x2 = value1.X;
const auto y2 = value1.Y;
const auto z2 = value1.Z;
const auto w2 = value1.W;
const auto num1 = y1 * z2 - z1 * y2;
const auto num2 = z1 * x2 - x1 * z2;
const auto num3 = x1 * y2 - y1 * x2;
const auto num4 = x1 * x2 + y1 * y2 + z1 * z2;
Quaternion quaternion;
quaternion.X = (x1 * w2 + x2 * w1) + num1;
quaternion.Y = (y1 * w2 + y2 * w1) + num2;
quaternion.Z = (z1 * w2 + z2 * w1) + num3;
quaternion.W = w1 * w2 - num4;
return quaternion;
}
static constexpr Quaternion Negate(Quaternion const& quaternion) {
Quaternion quaternion1;
quaternion1.X = -quaternion.X;
quaternion1.Y = -quaternion.Y;
quaternion1.Z = -quaternion.Z;
quaternion1.W = -quaternion.W;
return quaternion1;
}
static constexpr Quaternion Add(Quaternion const& quaternion1, Quaternion const& quaternion2) {
Quaternion quaternion;
quaternion.X = quaternion1.X + quaternion2.X;
quaternion.Y = quaternion1.Y + quaternion2.Y;
quaternion.Z = quaternion1.Z + quaternion2.Z;
quaternion.W = quaternion1.W + quaternion2.W;
return quaternion;
}
static constexpr Quaternion Subtract(Quaternion const& quaternion1, Quaternion const& quaternion2) {
Quaternion quaternion;
quaternion.X = quaternion1.X - quaternion2.X;
quaternion.Y = quaternion1.Y - quaternion2.Y;
quaternion.Z = quaternion1.Z - quaternion2.Z;
quaternion.W = quaternion1.W - quaternion2.W;
return quaternion;
}
static constexpr Quaternion Multiply(Quaternion const& quaternion1, Quaternion const& quaternion2) {
const auto x1 = quaternion1.X;
const auto y1 = quaternion1.Y;
const auto z1 = quaternion1.Z;
const auto w1 = quaternion1.W;
const auto x2 = quaternion2.X;
const auto y2 = quaternion2.Y;
const auto z2 = quaternion2.Z;
const auto w2 = quaternion2.W;
const auto num1 = y1 * z2 - z1 * y2;
const auto num2 = z1 * x2 - x1 * z2;
const auto num3 = x1 * y2 - y1 * x2;
const auto num4 = x1 * x2 + y1 * y2 + z1 * z2;
Quaternion quaternion;
quaternion.X = (x1 * w2 + x2 * w1) + num1;
quaternion.Y = (y1 * w2 + y2 * w1) + num2;
quaternion.Z = (z1 * w2 + z2 * w1) + num3;
quaternion.W = w1 * w2 - num4;
return quaternion;
}
static constexpr Quaternion Multiply(Quaternion const& quaternion1, float scaleFactor) {
Quaternion quaternion;
quaternion.X = quaternion1.X * scaleFactor;
quaternion.Y = quaternion1.Y * scaleFactor;
quaternion.Z = quaternion1.Z * scaleFactor;
quaternion.W = quaternion1.W * scaleFactor;
return quaternion;
}
static constexpr Quaternion Divide(Quaternion const& quaternion1, Quaternion const& quaternion2) {
const auto x = quaternion1.X;
const auto y = quaternion1.Y;
const auto z = quaternion1.Z;
const auto w = quaternion1.W;
const auto num1 = 1.0f / (quaternion2.X * quaternion2.X + quaternion2.Y * quaternion2.Y + quaternion2.Z * quaternion2.Z + quaternion2.W * quaternion2.W);
const auto num2 = -quaternion2.X * num1;
const auto num3 = -quaternion2.Y * num1;
const auto num4 = -quaternion2.Z * num1;
const auto num5 = quaternion2.W * num1;
const auto num6 = y * num4 - z * num3;
const auto num7 = z * num2 - x * num4;
const auto num8 = x * num3 - y * num2;
const auto num9 = x * num2 + y * num3 + z * num4;
Quaternion quaternion;
quaternion.X = (x * num5 + num2 * w) + num6;
quaternion.Y = (y * num5 + num3 * w) + num7;
quaternion.Z = (z * num5 + num4 * w) + num8;
quaternion.W = w * num5 - num9;
return quaternion;
}
constexpr Quaternion operator-(Quaternion const& quaternion) const {
return Quaternion::Negate(quaternion);
}
constexpr friend Quaternion operator+(Quaternion const& q1, Quaternion const& q2) {
return Quaternion::Add(q1, q2);
}
constexpr friend Quaternion operator-(Quaternion const& q1, Quaternion const& q2) {
return Quaternion::Add(q1, q2);
}
constexpr friend Quaternion operator*(Quaternion const& q1, Quaternion const& q2) {
return Quaternion::Multiply(q1, q2);
}
constexpr friend Quaternion operator/(Quaternion const& q1, Quaternion const& q2) {
return Quaternion::Divide(q1, q2);
}
constexpr friend Quaternion operator*(Quaternion const& q1, float scaleValue) {
return Quaternion::Multiply(q1, scaleValue);
}
constexpr friend Quaternion operator*(float scaleValue, Quaternion const& q1) {
return Quaternion::Multiply(q1, scaleValue);
}
};
constexpr Vector2 Vector2::Transform(Vector2 const& value, Quaternion const& rotation) {