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

Merge pull request #10 from borgesdan/develop

Develop
This commit is contained in:
Danilo Borges 2024-06-27 20:45:43 -03:00 committed by GitHub
commit 64641341da
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 180 additions and 110 deletions

View File

@ -1,4 +1,4 @@
#include "xna/common/gjk.hpp" #include "xna/common/collision.hpp"
namespace xna { namespace xna {
Vector3 Gjk::ComputeClosestPoint() { Vector3 Gjk::ComputeClosestPoint() {

View File

@ -1,15 +1,83 @@
#ifndef XNA_COMMON_SHAPES_HPP #ifndef XNA_COMMON_COLLISION_HPP
#define XNA_COMMON_SHAPES_HPP #define XNA_COMMON_COLLISION_HPP
#include "../default.hpp" #include "../default.hpp"
#include "numerics.hpp"
#include "gjk.hpp"
#include <optional>
#include "math.hpp" #include "math.hpp"
#include "numerics.hpp"
#include <optional>
namespace xna { namespace xna {
class Gjk {
public:
constexpr Gjk() {}
constexpr bool FullSimplex() const { return simplexBits == 15; }
constexpr float MaxLengthSquared() const { return maxLengthSq; }
constexpr Vector3 ClosestPoint() const { return closestPoint; }
constexpr void Reset() {
simplexBits = 0;
maxLengthSq = 0.0f;
}
bool AddSupportPoint(Vector3 const& newPoint);
private:
using listv3 = std::vector<Vector3>;
using listv3v3 = std::vector<std::vector<Vector3>>;
using listf = std::vector<float>;
using listff = std::vector<std::vector<float>>;
void UpdateDeterminant(Int xmIdx);
bool UpdateSimplex(Int newIndex);
Vector3 ComputeClosestPoint();
constexpr bool IsSatisfiesRule(Int xBits, Int yBits) const {
bool flag = true;
for (auto bitsToIndex = Gjk::BitsToIndices[yBits]; bitsToIndex != 0; bitsToIndex >>= 3)
{
auto index = (bitsToIndex & 7) - 1;
auto num = 1 << index;
if ((num & xBits) != 0) {
if (static_cast<float>(det[xBits][index]) <= 0.0F) {
flag = false;
break;
}
}
else if (static_cast<float>(det[xBits | num][index]) > 0.0F) {
flag = false;
break;
}
}
return flag;
}
private:
inline static auto BitsToIndices = std::vector<Int>{
0, 1, 2, 17, 3, 25, 26, 209, 4, 33, 34, 273, 35, 281, 282, 2257
};
using listv3 = std::vector<Vector3>;
using listv3v3 = std::vector<std::vector<Vector3>>;
using listf = std::vector<float>;
using listff = std::vector<std::vector<float>>;
Vector3 closestPoint{};
Int simplexBits{ 0 };
float maxLengthSq{ 0 };
listv3 y = listv3(4);
listf yLengthSq = listf(4);
listv3v3 edges = listv3v3(4, listv3(4));
listff edgeLengthSq = listff(4, listf(4));
listff det = listff(16, listf(4));
};
//Defines a plane.
struct Plane { struct Plane {
//The normal vector of the Plane.
Vector3 Normal{ 0 }; Vector3 Normal{ 0 };
//The distance of the Plane along its normal from the origin.
float D{ 0 }; float D{ 0 };
constexpr Plane() = default; constexpr Plane() = default;
@ -26,22 +94,34 @@ namespace xna {
return Normal == other.Normal && D == other.D; return Normal == other.Normal && D == other.D;
} }
//Changes the coefficients of the Normal vector of a Plane to make it of unit length.
void Normalize(); void Normalize();
//Changes the coefficients of the Normal vector of a Plane to make it of unit length.
static Plane Normalize(Plane const& value); static Plane Normalize(Plane const& value);
//Transforms a normalized Plane by a Matrix or Quaternion.
static constexpr Plane Transform(Plane const& plane, Matrix const& matrix); static constexpr Plane Transform(Plane const& plane, Matrix const& matrix);
//Transforms a normalized Plane by a Matrix or Quaternion.
static constexpr Plane Transform(Plane const& plane, Quaternion const& rotation); static constexpr Plane Transform(Plane const& plane, Quaternion const& rotation);
//Calculates the dot product of a specified Vector4 and this Plane.
constexpr float Dot(Vector4 const& value) const; constexpr float Dot(Vector4 const& value) const;
//Returns the dot product of a specified Vector3 and the Normal vector of this Plane plus the D constant value of the Plane.
constexpr float DotCoordinate(Vector3 const& value) const; constexpr float DotCoordinate(Vector3 const& value) const;
//Returns the dot product of a specified Vector3 and the Normal vector of this Plane.
constexpr float DotNormal(Vector3 const& value) const; constexpr float DotNormal(Vector3 const& value) const;
//Checks whether a Plane intersects a bounding volume.
constexpr PlaneIntersectionType Intersects(BoundingBox const& box) const; constexpr PlaneIntersectionType Intersects(BoundingBox const& box) const;
//Checks whether a Plane intersects a bounding volume.
constexpr PlaneIntersectionType Intersects(BoundingFrustum const& frustum) const; constexpr PlaneIntersectionType Intersects(BoundingFrustum const& frustum) const;
//Checks whether a Plane intersects a bounding volume.
constexpr PlaneIntersectionType Intersects(BoundingSphere const& sphere) const; constexpr PlaneIntersectionType Intersects(BoundingSphere const& sphere) const;
//Checks whether a Plane intersects a bounding volume.
std::optional<float> Intersects(Ray const& ray) const; std::optional<float> Intersects(Ray const& ray) const;
}; };
//Defines a frustum and helps determine whether forms intersect with it.
struct BoundingFrustum { struct BoundingFrustum {
inline static constexpr int CornerCount = 8; inline static constexpr int CornerCount = 8;
inline static constexpr int PlaneCount = 6; inline static constexpr int PlaneCount = 6;
@ -51,11 +131,17 @@ namespace xna {
SetMatrix(matrix); SetMatrix(matrix);
} }
//Gets the near plane of the BoundingFrustum.
Plane Near() { return planes[0]; } Plane Near() { return planes[0]; }
//Gets the far plane of the BoundingFrustum.
Plane Far() { return planes[1]; } Plane Far() { return planes[1]; }
//Gets the left plane of the BoundingFrustum.
Plane Left() { return planes[2]; } Plane Left() { return planes[2]; }
//Gets the right plane of the BoundingFrustum.
Plane Right() { return planes[3]; } Plane Right() { return planes[3]; }
//Gets the top plane of the BoundingFrustum.
Plane Top() { return planes[4]; } Plane Top() { return planes[4]; }
//Gets the bottom plane of the BoundingFrustum.
Plane Bottom() { return planes[5]; } Plane Bottom() { return planes[5]; }
constexpr bool operator==(BoundingFrustum const& other) const { constexpr bool operator==(BoundingFrustum const& other) const {
@ -69,20 +155,32 @@ namespace xna {
return corners[index]; return corners[index];
} }
//Gets an array of points that make up the corners of the BoundingFrustum.
constexpr void GetCorners(std::vector<Vector3>& destination) const; constexpr void GetCorners(std::vector<Vector3>& destination) const;
//Gets or sets the Matrix that describes this bounding frustum.
constexpr Matrix GetMatrix() const { return matrix; } constexpr Matrix GetMatrix() const { return matrix; }
//Gets or sets the Matrix that describes this bounding frustum.
constexpr void SetMatrix(Matrix const& value); constexpr void SetMatrix(Matrix const& value);
//Gets or sets the Matrix that describes this bounding frustum.
bool Intersects(BoundingBox const& box); bool Intersects(BoundingBox const& box);
//Gets or sets the Matrix that describes this bounding frustum.
bool Intersects(BoundingSphere const& box); bool Intersects(BoundingSphere const& box);
//Gets or sets the Matrix that describes this bounding frustum.
constexpr PlaneIntersectionType Intersects(Plane const& plane) const; constexpr PlaneIntersectionType Intersects(Plane const& plane) const;
//Gets or sets the Matrix that describes this bounding frustum.
bool Intersects(BoundingFrustum const& frustum); bool Intersects(BoundingFrustum const& frustum);
//Gets or sets the Matrix that describes this bounding frustum.
std::optional<float> Intersects(Ray const& ray) const; std::optional<float> Intersects(Ray const& ray) const;
//Checks whether the current BoundingFrustum contains a specified bounding volume.
constexpr ContainmentType Contains(BoundingBox const& box) const; constexpr ContainmentType Contains(BoundingBox const& box) const;
//Checks whether the current BoundingFrustum contains a specified bounding volume.
ContainmentType Contains(BoundingFrustum const& box); ContainmentType Contains(BoundingFrustum const& box);
//Checks whether the current BoundingFrustum contains a specified bounding volume.
constexpr ContainmentType Contains(Vector3 const& point) const; constexpr ContainmentType Contains(Vector3 const& point) const;
//Checks whether the current BoundingFrustum contains a specified bounding volume.
constexpr ContainmentType Contains(BoundingSphere const& box) const; constexpr ContainmentType Contains(BoundingSphere const& box) const;
constexpr void SupportMapping(Vector3 const& v, Vector3& result) const;
constexpr void SupportMapping(Vector3 const& v, Vector3& result) const;
public: public:
std::vector<Vector3> corners{ 8 }; std::vector<Vector3> corners{ 8 };
@ -96,10 +194,14 @@ namespace xna {
static constexpr Vector3 ComputeIntersection(Plane const& plane, Ray const& ray); static constexpr Vector3 ComputeIntersection(Plane const& plane, Ray const& ray);
}; };
//Defines an axis-aligned box-shaped 3D volume.
struct BoundingBox { struct BoundingBox {
//Specifies the total number of corners (8) in the BoundingBox.
inline static constexpr int CornerCount = 8; inline static constexpr int CornerCount = 8;
//The maximum point the BoundingBox contains.
Vector3 Min{}; Vector3 Min{};
//The minimum point the BoundingBox contains.
Vector3 Max{}; Vector3 Max{};
constexpr BoundingBox() = default; constexpr BoundingBox() = default;
@ -110,28 +212,44 @@ namespace xna {
return Min == other.Min && Max == other.Max; return Min == other.Min && Max == other.Max;
} }
//Gets an array of points that make up the corners of the BoundingBox.
constexpr void GetCorners(std::vector<Vector3>& corners) const; constexpr void GetCorners(std::vector<Vector3>& corners) const;
//Creates the smallest BoundingBox that contains the two specified BoundingBox instances.
static constexpr BoundingBox CreateMerged(BoundingBox const& original, BoundingBox const& additional); static constexpr BoundingBox CreateMerged(BoundingBox const& original, BoundingBox const& additional);
//Creates the smallest BoundingBox that will contain the specified BoundingSphere.
static constexpr BoundingBox CreateFromSphere(BoundingSphere const& sphere); static constexpr BoundingBox CreateFromSphere(BoundingSphere const& sphere);
//Creates the smallest BoundingBox that will contain a group of points.
static constexpr BoundingBox CreateFromPoints(std::vector<Vector3> const& points); static constexpr BoundingBox CreateFromPoints(std::vector<Vector3> const& points);
//Checks whether the current BoundingBox intersects with another bounding volume.
constexpr bool Intersects(BoundingBox const& box) const; constexpr bool Intersects(BoundingBox const& box) const;
//Checks whether the current BoundingBox intersects with another bounding volume.
bool Intersects(BoundingFrustum& frustum) const; bool Intersects(BoundingFrustum& frustum) const;
//Checks whether the current BoundingBox intersects with another bounding volume.
constexpr PlaneIntersectionType Intersects(Plane const& plane) const; constexpr PlaneIntersectionType Intersects(Plane const& plane) const;
//Checks whether the current BoundingBox intersects with another bounding volume.
std::optional<float> Intersects(Ray const& ray) const; std::optional<float> Intersects(Ray const& ray) const;
//Checks whether the current BoundingBox intersects with another bounding volume.
constexpr bool Intersects(BoundingSphere const& sphere) const; constexpr bool Intersects(BoundingSphere const& sphere) const;
//Tests whether the BoundingBox overlaps another bounding volume.
constexpr ContainmentType Contains(BoundingBox const& box) const; constexpr ContainmentType Contains(BoundingBox const& box) const;
//Tests whether the BoundingBox overlaps another bounding volume.
ContainmentType Contains(BoundingFrustum& frustum) const; ContainmentType Contains(BoundingFrustum& frustum) const;
//Tests whether the BoundingBox overlaps another bounding volume.
constexpr ContainmentType Contains(Vector3 const& point) const; constexpr ContainmentType Contains(Vector3 const& point) const;
//Tests whether the BoundingBox overlaps another bounding volume.
constexpr ContainmentType Contains(BoundingSphere const& sphere) const; constexpr ContainmentType Contains(BoundingSphere const& sphere) const;
constexpr void SupportMapping(Vector3 const& v, Vector3& result) const; constexpr void SupportMapping(Vector3 const& v, Vector3& result) const;
}; };
//Defines a sphere.
struct BoundingSphere { struct BoundingSphere {
//The center point of the sphere.
Vector3 Center{}; Vector3 Center{};
//The radius of the sphere.
float Radius{ 0 }; float Radius{ 0 };
constexpr BoundingSphere() = default; constexpr BoundingSphere() = default;
@ -142,28 +260,46 @@ namespace xna {
return Center == other.Center && Radius == other.Radius; return Center == other.Center && Radius == other.Radius;
} }
//Creates a BoundingSphere that contains the two specified BoundingSphere instances.
static BoundingSphere CreateMerged(BoundingSphere const& original, BoundingSphere const& additional); static BoundingSphere CreateMerged(BoundingSphere const& original, BoundingSphere const& additional);
//Creates the smallest BoundingSphere that can contain a specified BoundingBox.
static BoundingSphere CreateFromBoundingBox(BoundingBox const& box); static BoundingSphere CreateFromBoundingBox(BoundingBox const& box);
//Creates a BoundingSphere that can contain a specified list of points.
static BoundingSphere CreateFromPoints(std::vector<Vector3> const& points); static BoundingSphere CreateFromPoints(std::vector<Vector3> const& points);
//Creates the smallest BoundingSphere that can contain a specified BoundingFrustum.
static BoundingSphere CreateFromFrustum(BoundingFrustum const& points); static BoundingSphere CreateFromFrustum(BoundingFrustum const& points);
//Checks whether the current BoundingSphere intersects another bounding volume.
constexpr bool Intersects(BoundingBox const& box) const; constexpr bool Intersects(BoundingBox const& box) const;
//Checks whether the current BoundingSphere intersects another bounding volume.
bool Intersects(BoundingFrustum& frustum) const; bool Intersects(BoundingFrustum& frustum) const;
//Checks whether the current BoundingSphere intersects another bounding volume.
constexpr PlaneIntersectionType Intersects(Plane const& plane) const; constexpr PlaneIntersectionType Intersects(Plane const& plane) const;
//Checks whether the current BoundingSphere intersects another bounding volume.
std::optional<float> Intersects(Ray const& ray) const; std::optional<float> Intersects(Ray const& ray) const;
//Checks whether the current BoundingSphere intersects another bounding volume.
constexpr bool Intersects(BoundingSphere const& sphere) const; constexpr bool Intersects(BoundingSphere const& sphere) const;
//Checks whether the current BoundingSphere contains a specified bounding volume.
ContainmentType Contains(BoundingBox const& box) const; ContainmentType Contains(BoundingBox const& box) const;
//Checks whether the current BoundingSphere contains a specified bounding volume.
ContainmentType Contains(BoundingFrustum& frustum) const; ContainmentType Contains(BoundingFrustum& frustum) const;
//Checks whether the current BoundingSphere contains a specified bounding volume.
ContainmentType Contains(Vector3 const& point) const; ContainmentType Contains(Vector3 const& point) const;
//Checks whether the current BoundingSphere contains a specified bounding volume.
ContainmentType Contains(BoundingSphere const& sphere) const; ContainmentType Contains(BoundingSphere const& sphere) const;
//Translates and scales the BoundingSphere using a given Matrix.
BoundingSphere Transform(Matrix const& matrix) const; BoundingSphere Transform(Matrix const& matrix) const;
void SupportMapping(Vector3 const& v, Vector3& result) const; void SupportMapping(Vector3 const& v, Vector3& result) const;
}; };
//Defines a ray.
struct Ray { struct Ray {
//Specifies the starting point of the Ray.
Vector3 Position{}; Vector3 Position{};
//Unit vector specifying the direction the Ray is pointing.
Vector3 Direction{}; Vector3 Direction{};
constexpr Ray() = default; constexpr Ray() = default;
@ -174,19 +310,23 @@ namespace xna {
return Position == other.Position && Direction == other.Direction; return Position == other.Position && Direction == other.Direction;
} }
std::optional<float> Intersects(BoundingBox const& box) const { //Checks whether the Ray intersects a specified plane or bounding volume.
inline std::optional<float> Intersects(BoundingBox const& box) const {
return box.Intersects(*this); return box.Intersects(*this);
} }
std::optional<float> Intersects(BoundingFrustum const& frustum) const { //Checks whether the Ray intersects a specified plane or bounding volume.
inline std::optional<float> Intersects(BoundingFrustum const& frustum) const {
return frustum.Intersects(*this); return frustum.Intersects(*this);
} }
std::optional<float> Intersects(Plane const& plane) const { //Checks whether the Ray intersects a specified plane or bounding volume.
inline std::optional<float> Intersects(Plane const& plane) const {
return plane.Intersects(*this); return plane.Intersects(*this);
} }
std::optional<float> Sphere(BoundingSphere const& sphere) const { //Checks whether the Ray intersects a specified plane or bounding volume.
inline std::optional<float> Intersects(BoundingSphere const& sphere) const {
return sphere.Intersects(*this); return sphere.Intersects(*this);
} }
}; };

View File

@ -1,71 +0,0 @@
#ifndef XNA_COMMON_GDK_HPP
#define XNA_COMMON_GDK_HPP
#include "../default.hpp"
#include "numerics.hpp"
#include "math.hpp"
namespace xna {
class Gjk {
public:
constexpr Gjk() = default;
constexpr bool FullSimplex() const { return simplexBits == 15; }
constexpr float MaxLengthSquared() const { return maxLengthSq; }
constexpr Vector3 ClosestPoint() const { return closestPoint; }
constexpr void Reset() {
simplexBits = 0;
maxLengthSq = 0.0f;
}
bool AddSupportPoint(Vector3 const& newPoint);
private:
using listv3 = std::vector<Vector3>;
using listv3v3 = std::vector<std::vector<Vector3>>;
using listf = std::vector<float>;
using listff = std::vector<std::vector<float>>;
void UpdateDeterminant(Int xmIdx);
bool UpdateSimplex(Int newIndex);
Vector3 ComputeClosestPoint();
constexpr bool IsSatisfiesRule(Int xBits, Int yBits) const {
bool flag = true;
for (auto bitsToIndex = Gjk::BitsToIndices[yBits]; bitsToIndex != 0; bitsToIndex >>= 3)
{
auto index = (bitsToIndex & 7) - 1;
auto num = 1 << index;
if ((num & xBits) != 0) {
if (static_cast<float>(det[xBits][index]) <= 0.0F) {
flag = false;
break;
}
}
else if (static_cast<float>(det[xBits | num][index]) > 0.0F) {
flag = false;
break;
}
}
return flag;
}
private:
inline static auto BitsToIndices = std::vector<Int> {
0, 1, 2, 17, 3, 25, 26, 209, 4, 33, 34, 273, 35, 281, 282, 2257
};
Vector3 closestPoint{};
Int simplexBits{0};
float maxLengthSq{0};
listv3 y = listv3(4);
listf yLengthSq = listf(4);
listv3v3 edges = listv3v3(4, listv3(4));
listff edgeLengthSq = listff(4, listf(4));
listff det = listff(16, listf(4));
};
}
#endif

View File

@ -90,42 +90,44 @@ namespace xna {
} }
constexpr static Rectangle Intersect(Rectangle const& value1, Rectangle const& value2) { constexpr static Rectangle Intersect(Rectangle const& value1, Rectangle const& value2) {
const auto left1 = value1.Left(); const auto num1 = value1.X + value1.Width;
const auto left2 = value2.Left(); const auto num2 = value2.X + value2.Width;
const auto bottom1 = value1.Bottom(); const auto num3 = value1.Y + value1.Height;
const auto bottom2 = value2.Bottom(); const auto num4 = value2.Y + value2.Height;
const auto maxX = value1.X > value2.X ? value1.X : value2.X; const auto num5 = value1.X > value2.X ? value1.X : value2.X;
const auto maxY = value1.Y > value2.Y ? value1.Y : value2.Y; const auto num6 = value1.Y > value2.Y ? value1.Y : value2.Y;
const auto maxl = left1 < left2 ? left1 : left2; const auto num7 = num1 < num2 ? num1 : num2;
const auto maxb = bottom1 < bottom2 ? bottom1 : bottom2; const auto num8 = num3 < num4 ? num3 : num4;
Rectangle rectangle{}; Rectangle rectangle{};
if (maxl > maxX && maxb > maxY) { if (num7 > num5 && num8 > num6)
rectangle.X = maxX; {
rectangle.Y = maxY; rectangle.X = num5;
rectangle.Width = maxl - maxX; rectangle.Y = num6;
rectangle.Height = maxb - maxY; rectangle.Width = num7 - num5;
rectangle.Height = num8 - num6;
} }
return rectangle; return rectangle;
} }
constexpr static Rectangle Union(Rectangle const& value1, Rectangle const& value2) { constexpr static Rectangle Union(Rectangle const& value1, Rectangle const& value2) {
const auto left1 = value1.Left(); const auto num1 = value1.X + value1.Width;
const auto left2 = value2.Left(); const auto num2 = value2.X + value2.Width;
const auto bottom1 = value1.Bottom(); const auto num3 = value1.Y + value1.Height;
const auto bottom2 = value2.Bottom(); const auto num4 = value2.Y + value2.Height;
const auto minX = value1.X < value2.X ? value1.X : value2.X; const auto num5 = value1.X < value2.X ? value1.X : value2.X;
const auto miny = value1.Y < value2.Y ? value1.Y : value2.Y; const auto num6 = value1.Y < value2.Y ? value1.Y : value2.Y;
const auto maxl = left1 > left2 ? left1 : left2; const auto num7 = num1 > num2 ? num1 : num2;
const auto maxb = bottom1 > bottom2 ? bottom1 : bottom2; const auto num8 = num3 > num4 ? num3 : num4;
Rectangle rectangle; Rectangle rectangle;
rectangle.X = minX; rectangle.X = num5;
rectangle.Y = miny; rectangle.Y = num6;
rectangle.Width = maxl - minX; rectangle.Width = num7 - num5;
rectangle.Height = maxb - miny; rectangle.Height = num8 - num6;
return rectangle; return rectangle;
} }
}; };

View File

@ -17,7 +17,7 @@ namespace xna {
inline static const std::string MakeWindowAssociation = "Failed to create association with window"; inline static const std::string MakeWindowAssociation = "Failed to create association with window";
inline static const std::string BuildObject = "Unable to build object"; inline static const std::string BuildObject = "Unable to build object";
inline static const std::string NotImplemented = "Not Implemented"; inline static const std::string NotImplemented = "Not Implemented";
inline static const std::string ArgumentIsNull = "The argument or any of its internal values are null"; inline static const std::string ArgumentIsNull = "The argument is null or one of its values.";
}; };
//Structure for throwing exceptions with a message and information from the source file //Structure for throwing exceptions with a message and information from the source file

View File

@ -4,7 +4,6 @@
#include "common/collision.hpp" #include "common/collision.hpp"
#include "common/color.hpp" #include "common/color.hpp"
#include "common/curve.hpp" #include "common/curve.hpp"
#include "common/gjk.hpp"
#include "common/math.hpp" #include "common/math.hpp"
#include "common/numerics.hpp" #include "common/numerics.hpp"
#include "common/packedvalue.hpp" #include "common/packedvalue.hpp"