diff --git a/framework/common/matrix.hpp b/framework/common/matrix.hpp index 0cbe368..3a2959c 100644 --- a/framework/common/matrix.hpp +++ b/framework/common/matrix.hpp @@ -600,6 +600,29 @@ namespace xna { const auto posy = normal.X * matrix.M12 + normal.Y * matrix.M22; return { posx, posy }; } + + constexpr Vector3 Vector3::Transform(Vector3 const& position, Matrix const& matrix) { + const auto num1 = (position.X * matrix.M11 + position.Y * matrix.M21 + position.Z * matrix.M31) + matrix.M41; + const auto num2 = (position.X * matrix.M12 + position.Y * matrix.M22 + position.Z * matrix.M32) + matrix.M42; + const auto num3 = (position.X * matrix.M13 + position.Y * matrix.M23 + position.Z * matrix.M33) + matrix.M43; + Vector3 vector3; + vector3.X = num1; + vector3.Y = num2; + vector3.Z = num3; + return vector3; + } + + constexpr Vector3 Vector3::TransformNormal(Vector3 const& normal, Matrix const& matrix) + { + const auto num1 = normal.X * matrix.M11 + normal.Y * matrix.M21 + normal.Z * matrix.M31; + const auto num2 = normal.X * matrix.M12 + normal.Y * matrix.M22 + normal.Z * matrix.M32; + const auto num3 = normal.X * matrix.M13 + normal.Y * matrix.M23 + normal.Z * matrix.M33; + Vector3 vector3; + vector3.X = num1; + vector3.Y = num2; + vector3.Z = num3; + return vector3; + } } #endif \ No newline at end of file diff --git a/framework/common/quaternion.hpp b/framework/common/quaternion.hpp index f3c3506..87372d7 100644 --- a/framework/common/quaternion.hpp +++ b/framework/common/quaternion.hpp @@ -34,7 +34,29 @@ namespace xna { return{ x,y }; } - + constexpr Vector3 Vector3::Transform(Vector3 const& value, Quaternion const& rotation) + { + const auto num1 = rotation.X + rotation.X; + const auto num2 = rotation.Y + rotation.Y; + const auto num3 = rotation.Z + rotation.Z; + const auto num4 = rotation.W * num1; + const auto num5 = rotation.W * num2; + const auto num6 = rotation.W * num3; + const auto num7 = rotation.X * num1; + const auto num8 = rotation.X * num2; + const auto num9 = rotation.X * num3; + const auto num10 = rotation.Y * num2; + const auto num11 = rotation.Y * num3; + const auto num12 = rotation.Z * num3; + const auto num13 = (value.X * (1.0F - num10 - num12) + value.Y * (num8 - num6) + value.Z * (num9 + num5)); + const auto num14 = (value.X * (num8 + num6) + value.Y * (1.0F - num7 - num12) + value.Z * (num11 - num4)); + const auto num15 = (value.X * (num9 - num5) + value.Y * (num11 + num4) + value.Z * (1.0F - num7 - num10)); + Vector3 vector3; + vector3.X = num13; + vector3.Y = num14; + vector3.Z = num15; + return vector3; + } } #endif \ No newline at end of file diff --git a/framework/common/vectors.cpp b/framework/common/vectors.cpp index 34ced99..eb7dc6c 100644 --- a/framework/common/vectors.cpp +++ b/framework/common/vectors.cpp @@ -116,4 +116,161 @@ namespace xna { return true; } + + void Vector3::Normalize() { + const auto num = 1.0f / std::sqrt(X * X + Y * Y + Z * Z); + X *= num; + Y *= num; + Z *= num; + } + + Vector3 Vector3::Normalize(Vector3 const& value) { + const auto num = 1.0f / std::sqrt(value.X * value.X + value.Y * value.Y + value.Z * value.Z); + + Vector3 vector3; + vector3.X = value.X * num; + vector3.Y = value.Y * num; + vector3.Z = value.Z * num; + + return vector3; + } + + bool xna::Vector3::Transform(std::vector const& sourceArray, Matrix const& matrix, std::vector& destinationArray) + { + if (destinationArray.size() < sourceArray.size()) + return false; + + for (size_t index = 0; index < sourceArray.size(); ++index) + { + const auto& source = sourceArray[index]; + destinationArray[index].X = (source.X * matrix.M11 + source.Y * matrix.M21 + source.Z * matrix.M31) + matrix.M41; + destinationArray[index].Y = (source.X * matrix.M12 + source.Y * matrix.M22 + source.Z * matrix.M32) + matrix.M42; + destinationArray[index].Z = (source.X * matrix.M13 + source.Y * matrix.M23 + source.Z * matrix.M33) + matrix.M43; + } + + return true; + } + + bool Vector3::Transform(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length) + { + if (sourceArray.size() < sourceIndex + length || destinationArray.size() < destinationIndex + length) + return false; + + for (size_t index = 0; index < length; ++index) + { + const auto& source = sourceArray[sourceIndex + index]; + destinationArray[destinationIndex + index].X = (source.X * matrix.M11 + source.Y * matrix.M21 + source.Z * matrix.M31) + matrix.M41; + destinationArray[destinationIndex + index].Y = (source.X * matrix.M12 + source.Y * matrix.M22 + source.Z * matrix.M32) + matrix.M42; + destinationArray[destinationIndex + index].Z = (source.X * matrix.M13 + source.Y * matrix.M23 + source.Z * matrix.M33) + matrix.M43; + } + + return true; + } + + bool Vector3::TransformNormal(std::vector const& sourceArray, Matrix const& matrix, std::vector& destinationArray) + { + if (destinationArray.size() < sourceArray.size()) + return false; + + for (size_t index = 0; index < sourceArray.size(); ++index) + { + const auto& source = sourceArray[index]; + destinationArray[index].X = source.X * matrix.M11 + source.Y * matrix.M21 + source.Z * matrix.M31; + destinationArray[index].Y = source.X * matrix.M12 + source.Y * matrix.M22 + source.Z * matrix.M32; + destinationArray[index].Z = source.X * matrix.M13 + source.Y * matrix.M23 + source.Z * matrix.M33; + } + + return true; + } + + bool Vector3::TransformNormal(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length) + { + if (sourceArray.size() < sourceIndex + length || destinationArray.size() < destinationIndex + length) + return false; + + for (size_t index = 0; index < length; ++index) { + const auto& source = sourceArray[sourceIndex + index]; + destinationArray[destinationIndex + index].X = source.X * matrix.M11 + source.Y * matrix.M21 + source.Z * matrix.M31; + destinationArray[destinationIndex + index].Y = source.X * matrix.M12 + source.Y * matrix.M22 + source.Z * matrix.M32; + destinationArray[destinationIndex + index].Z = source.X * matrix.M13 + source.Y * matrix.M23 + source.Z * matrix.M33; + } + + return true; + } + + bool Vector3::TransformNormal(std::vector const& sourceArray, Quaternion const& rotation, std::vector& destinationArray) + { + if (destinationArray.size() < sourceArray.size()) + return false; + + const auto num1 = rotation.X + rotation.X; + const auto num2 = rotation.Y + rotation.Y; + const auto num3 = rotation.Z + rotation.Z; + const auto num4 = rotation.W * num1; + const auto num5 = rotation.W * num2; + const auto num6 = rotation.W * num3; + const auto num7 = rotation.X * num1; + const auto num8 = rotation.X * num2; + const auto num9 = rotation.X * num3; + const auto num10 = rotation.Y * num2; + const auto num11 = rotation.Y * num3; + const auto num12 = rotation.Z * num3; + const auto num13 = 1.0f - num10 - num12; + const auto num14 = num8 - num6; + const auto num15 = num9 + num5; + const auto num16 = num8 + num6; + const auto num17 = 1.0f - num7 - num12; + const auto num18 = num11 - num4; + const auto num19 = num9 - num5; + const auto num20 = num11 + num4; + const auto num21 = 1.0f - num7 - num10; + + for (size_t index = 0; index < sourceArray.size(); ++index) + { + const auto& source = sourceArray[index]; + destinationArray[index].X = source.X * num13 + source.Y * num14 + source.Z * num15; + destinationArray[index].Y = source.X * num16 + source.Y * num17 + source.Z * num18; + destinationArray[index].Z = source.X * num19 + source.Y * num20 + source.Z * num21; + } + + return true; + } + + bool Vector3::TransformNormal(std::vector const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector& destinationArray, size_t destinationIndex, size_t length) + { + if (sourceArray.size() < sourceIndex + length || destinationArray.size() < destinationIndex + length) + return false; + + const auto num1 = rotation.X + rotation.X; + const auto num2 = rotation.Y + rotation.Y; + const auto num3 = rotation.Z + rotation.Z; + const auto num4 = rotation.W * num1; + const auto num5 = rotation.W * num2; + const auto num6 = rotation.W * num3; + const auto num7 = rotation.X * num1; + const auto num8 = rotation.X * num2; + const auto num9 = rotation.X * num3; + const auto num10 = rotation.Y * num2; + const auto num11 = rotation.Y * num3; + const auto num12 = rotation.Z * num3; + const auto num13 = 1.0f - num10 - num12; + const auto num14 = num8 - num6; + const auto num15 = num9 + num5; + const auto num16 = num8 + num6; + const auto num17 = 1.0f - num7 - num12; + const auto num18 = num11 - num4; + const auto num19 = num9 - num5; + const auto num20 = num11 + num4; + const auto num21 = 1.0f - num7 - num10; + + for (size_t index = 0; index < length; ++index) + { + const auto& source = sourceArray[sourceIndex + index]; + destinationArray[destinationIndex + index].X = source.X * num13 + source.Y * num14 + source.Z * num15; + destinationArray[destinationIndex + index].Y = source.X * num16 + source.Y * num17 + source.Z * num18; + destinationArray[destinationIndex + index].Z = source.X * num19 + source.Y * num20 + source.Z * num21; + } + + return true; + } } \ No newline at end of file diff --git a/framework/common/vectors.hpp b/framework/common/vectors.hpp index cb02a77..5587285 100644 --- a/framework/common/vectors.hpp +++ b/framework/common/vectors.hpp @@ -217,30 +217,252 @@ namespace xna { constexpr Vector3() = default; + constexpr Vector3(float value) + : X(value), Y(value), Z(value) { } + constexpr Vector3(float X, float Y, float Z) : X(X), Y(Y), Z(Z) { } + constexpr Vector3(Vector2 const& value, float z) + : X(value.X), Y(value.Y), Z(z) { } + constexpr bool operator==(const Vector3& other) const { return X == other.X && Y == other.Y && Z == other.Z; } - static Vector3 Cross(Vector3 const& vector1, Vector3 const& vector2) { return {}; } - static float Dot(Vector3 const& vector1, Vector3 const& vector2) { return 0; } - static Vector3 Forward() { return {}; } - static Vector3 Right() { return {}; } - float LengthSquared() const { return 0; }; - static Vector3 Normalize(Vector3 const& value) { return {}; } - static Vector3 Multiply(Vector3 value1, Vector3 value2) { return {}; } - static Vector3 Subtract(Vector3 value1, Vector3 value2) { return {}; } - static Vector3 Multiply(Vector3 value1, float value) { return {}; } - void Normalize() {} + static Vector3 Zero() { return {}; } + static Vector3 One() { return { 1 }; } + static Vector3 UnitX() { return { 1,0,0 }; } + static Vector3 UnitY() { return { 0,1,0 }; } + static Vector3 UnitZ() { return { 0,0,1 }; } + static Vector3 Up() { return UnitY(); } + static Vector3 Down() { return -UnitY(); } + static Vector3 Right() { return UnitX(); } + static Vector3 Left() { return -UnitX(); } + static Vector3 Forward() { return -UnitZ(); } + static Vector3 Backward() { return UnitZ(); } + + inline float Length() const { return sqrt(LengthSquared()); } + constexpr float LengthSquared() const { return (X * X + Y * Y + Z * Z); } + + inline static float Distance(Vector3 const& value1, Vector3 const& value2) { + return std::sqrt(DistanceSquared(value1, value2)); + } + + static constexpr float DistanceSquared(Vector3 const& value1, Vector3 const& value2) { + const auto x = value1.X - value2.X; + const auto y = value1.Y - value2.Y; + const auto z = value1.Z - value2.Z; + return x * x + y * y + z * z; + } + + static float Dot(Vector3 const& vector1, Vector3 const& vector2) { + return vector1.X * vector2.X + vector1.Y * vector2.Y + vector1.Z * vector2.Z; + } + + void Normalize(); + static Vector3 Normalize(Vector3 const& value); + + static constexpr Vector3 Cross(Vector3 const& vector1, Vector3 const& vector2) { + Vector3 vector3; + vector3.X = vector1.Y * vector2.Z - vector1.Z * vector2.Y; + vector3.Y = vector1.Z * vector2.X - vector1.X * vector2.Z; + vector3.Z = vector1.X * vector2.Y - vector1.Y * vector2.X; + return vector3; + } + + static constexpr Vector3 Reflect(Vector3 const& vector, Vector3 const& normal) { + const auto num = vector.X * normal.X + vector.Y * normal.Y + vector.Z * normal.Z; + Vector3 vector3; + vector3.X = vector.X - 2.0f * num * normal.X; + vector3.Y = vector.Y - 2.0f * num * normal.Y; + vector3.Z = vector.Z - 2.0f * num * normal.Z; + return vector3; + } + + static constexpr Vector3 Min(Vector3 const& value1, Vector3 const& value2) { + Vector3 vector3; + vector3.X = value1.X < value2.X ? value1.X : value2.X; + vector3.Y = value1.Y < value2.Y ? value1.Y : value2.Y; + vector3.Z = value1.Z < value2.Z ? value1.Z : value2.Z; + return vector3; + } + + static constexpr Vector3 Max(Vector3 const& value1, Vector3 const& value2) { + Vector3 vector3; + vector3.X = value1.X > value2.X ? value1.X : value2.X; + vector3.Y = value1.Y > value2.Y ? value1.Y : value2.Y; + vector3.Z = value1.Z > value2.Z ? value1.Z : value2.Z; + return vector3; + } + + static constexpr Vector3 Clamp(Vector3 const& value1, Vector3 const& min, Vector3 const& max) { + const auto x = value1.X > max.X ? max.X : value1.X; + const auto _x = x < min.X ? min.X : x; + const auto y = value1.Y > max.Y ? max.Y : value1.Y; + const auto _y = y < min.Y ? min.Y : y; + const auto z = value1.Z > max.Z ? max.Z : value1.Z; + const auto _z = z < min.Z ? min.Z : z; + + Vector3 vector3; + vector3.X = _x; + vector3.Y = _y; + vector3.Z = _z; + return vector3; + } + + static constexpr Vector3 Lerp(Vector3 const& value1, Vector3 const& value2, float amount) { + Vector3 vector3; + vector3.X = value1.X + (value2.X - value1.X) * amount; + vector3.Y = value1.Y + (value2.Y - value1.Y) * amount; + vector3.Z = value1.Z + (value2.Z - value1.Z) * amount; + return vector3; + } + + static constexpr Vector3 Barycentric(Vector3 const& value1, Vector3 const& value2, Vector3 const& value3, float amount1, float amount2) { + Vector3 vector3; + vector3.X = value1.X + amount1 * (value2.X - value1.X) + amount2 * (value3.X - value1.X); + vector3.Y = value1.Y + amount1 * (value2.Y - value1.Y) + amount2 * (value3.Y - value1.Y); + vector3.Z = value1.Z + amount1 * (value2.Z - value1.Z) + amount2 * (value3.Z - value1.Z); + return vector3; + } + + static constexpr Vector3 SmoothStep(Vector3 const& value1, Vector3 const& value2, float amount) { + amount = amount > 1.0F ? 1.0f : (amount < 0.0f ? 0.0f : amount); + amount = (amount * amount * (3.0f - 2.0f * amount)); + Vector3 vector3; + vector3.X = value1.X + (value2.X - value1.X) * amount; + vector3.Y = value1.Y + (value2.Y - value1.Y) * amount; + vector3.Z = value1.Z + (value2.Z - value1.Z) * amount; + return vector3; + } + + static constexpr Vector3 CatmullRom(Vector3 const& value1, Vector3 const& value2, Vector3 const& value3, Vector3 const& value4, float amount) { + const auto num1 = amount * amount; + const auto num2 = amount * num1; + Vector3 vector3; + vector3.X = 0.5f * (2.0f * value2.X + (-value1.X + value3.X) * amount + (2.0f * value1.X - 5.0f * value2.X + 4.0f * value3.X - value4.X) * num1 + (-value1.X + 3.0f * value2.X - 3.0f * value3.X + value4.X) * num2); + vector3.Y = 0.5f * (2.0f * value2.Y + (-value1.Y + value3.Y) * amount + (2.0f * value1.Y - 5.0f * value2.Y + 4.0f * value3.Y - value4.Y) * num1 + (-value1.Y + 3.0f * value2.Y - 3.0f * value3.Y + value4.Y) * num2); + vector3.Z = 0.5f * (2.0f * value2.Z + (-value1.Z + value3.Z) * amount + (2.0f * value1.Z - 5.0f * value2.Z + 4.0f * value3.Z - value4.Z) * num1 + (-value1.Z + 3.0f * value2.Z - 3.0f * value3.Z + value4.Z) * num2); + return vector3; + } + + static Vector3 Hermite(Vector3 const& value1, Vector3 const& tangent1, Vector3 const& value2, Vector3 const& tangent2, float amount) { + const auto num1 = amount * amount; + const auto num2 = amount * num1; + const auto num3 = 2.0F * num2 - 3.0F * num1 + 1.0F; + const auto num4 = -2.0F * num2 + 3.0F * num1; + const auto num5 = num2 - 2.0f * num1 + amount; + const auto num6 = num2 - num1; + Vector3 vector3; + vector3.X = value1.X * num3 + value2.X * num4 + tangent1.X * num5 + tangent2.X * num6; + vector3.Y = value1.Y * num3 + value2.Y * num4 + tangent1.Y * num5 + tangent2.Y * num6; + vector3.Z = value1.Z * num3 + value2.Z * num4 + tangent1.Z * num5 + tangent2.Z * num6; + return vector3; + } + + static constexpr Vector3 Transform(Vector3 const& position, Matrix const& matrix); + static constexpr Vector3 TransformNormal(Vector3 const& normal, Matrix const& matrix); + static constexpr Vector3 Transform(Vector3 const& value, Quaternion const& rotation); + static bool Transform(std::vector const& sourceArray, Matrix const& matrix, std::vector& destinationArray); + static bool Transform(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length); + static bool TransformNormal(std::vector const& sourceArray, Matrix const& matrix, std::vector& destinationArray); + static bool TransformNormal(std::vector const& sourceArray, size_t sourceIndex, Matrix const& matrix, std::vector& destinationArray, size_t destinationIndex, size_t length); + static bool TransformNormal(std::vector const& sourceArray, Quaternion const& rotation, std::vector& destinationArray); + static bool TransformNormal(std::vector const& sourceArray, size_t sourceIndex, Quaternion const& rotation, std::vector& destinationArray, size_t destinationIndex, size_t length); + + static constexpr Vector3 Negate(Vector3 const& value) + { + Vector3 vector3; + vector3.X = -value.X; + vector3.Y = -value.Y; + vector3.Z = -value.Z; + return vector3; + } + + static constexpr Vector3 Add(Vector3 const& value1, Vector3 const& value2) { + Vector3 vector3; + vector3.X = value1.X + value2.X; + vector3.Y = value1.Y + value2.Y; + vector3.Z = value1.Z + value2.Z; + return vector3; + } + + static constexpr Vector3 Subtract(Vector3 const& value1, Vector3 const& value2) { + Vector3 vector3; + vector3.X = value1.X - value2.X; + vector3.Y = value1.Y - value2.Y; + vector3.Z = value1.Z - value2.Z; + return vector3; + } + + static constexpr Vector3 Multiply(Vector3 const& value1, Vector3 const& value2) { + Vector3 vector3; + vector3.X = value1.X * value2.X; + vector3.Y = value1.Y * value2.Y; + vector3.Z = value1.Z * value2.Z; + return vector3; + } + + static constexpr Vector3 Multiply(Vector3 const& value1, float scaleFactor) { + Vector3 vector3; + vector3.X = value1.X * scaleFactor; + vector3.Y = value1.Y * scaleFactor; + vector3.Z = value1.Z * scaleFactor; + return vector3; + } + + static constexpr Vector3 Divide(Vector3 const& value1, Vector3 const& value2) { + Vector3 vector3; + vector3.X = value1.X / value2.X; + vector3.Y = value1.Y / value2.Y; + vector3.Z = value1.Z / value2.Z; + return vector3; + } + + static constexpr Vector3 Divide(Vector3 const& value1, float divider) { + float num = 1.0f / divider; + Vector3 vector3; + vector3.X = value1.X * num; + vector3.Y = value1.Y * num; + vector3.Z = value1.Z * num; + return vector3; + } constexpr Vector3 operator-() const { - return Vector3(); + return Vector3::Negate(*this); + } + + friend constexpr Vector3 operator+(Vector3 const& value1, Vector3 const& value2) { + return Vector3::Add(value1, value2); } friend constexpr Vector3 operator-(Vector3 const& value1, Vector3 const& value2) { - return Vector3(); + return Vector3::Subtract(value1, value2); + } + + friend constexpr Vector3 operator*(Vector3 const& value1, Vector3 const& value2) { + return Vector3::Multiply(value1, value2); + } + + friend constexpr Vector3 operator*(Vector3 const& value, float factor) { + return Vector3::Multiply(value, factor); + } + + friend constexpr Vector3 operator*(float factor, Vector3 const& value) { + return Vector3::Multiply(value, factor); + } + + friend constexpr Vector3 operator/(Vector3 const& value1, Vector3 const& value2) { + return Vector3::Divide(value1, value2); + } + + friend constexpr Vector3 operator/(Vector3 const& value, float divider) { + return Vector3::Divide(value, divider); + } + + friend constexpr Vector3 operator/(float divider, Vector3 const& value) { + return Vector3::Divide(value, divider); } };