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

Implementa BoundingFrustum

This commit is contained in:
Danilo 2024-05-16 17:23:52 -03:00
parent fd32d56715
commit 887dbe7b49
12 changed files with 679 additions and 34 deletions

View File

@ -47,7 +47,11 @@ add_executable (xna WIN32
"platform/init-dx.cpp"
"game/servicecontainer.cpp"
"common/color.cpp"
"common/math.cpp" "common/quaternion.cpp")
"common/math.cpp"
"common/quaternion.cpp"
"common/collision.cpp"
"common/gjk.cpp"
)
if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET xna PROPERTY CXX_STANDARD 20)

View File

@ -0,0 +1,199 @@
#include "common/collision.hpp"
namespace xna {
bool BoundingFrustum::Intersects(BoundingBox const& box) {
gjk.Reset();
Vector3 result1 = Vector3::Subtract(corners[0], box.Min);
if (result1.LengthSquared() < 9.9999997473787516E-06)
result1 = Vector3::Subtract(corners[0], box.Max);
auto num1 = FloatMaxValue;
float num2 = 0;
do
{
Vector3 v;
v.X = -result1.X;
v.Y = -result1.Y;
v.Z = -result1.Z;
Vector3 result2;
SupportMapping(v, result2);
Vector3 result3;
box.SupportMapping(result1, result3);
Vector3 result4 = Vector3::Subtract(result2, result3);
if (result1.X * result4.X + result1.Y * result4.Y + result1.Z * result4.Z > 0.0)
return false;
gjk.AddSupportPoint(result4);
result1 = gjk.ClosestPoint();
float num3 = num1;
num1 = result1.LengthSquared();
if (num3 - num1 <= 9.9999997473787516E-06 * num3)
return false;
num2 = 4E-05f * gjk.MaxLengthSquared();
} while (!gjk.FullSimplex() && num1 >= num2);
return true;
}
std::optional<float> BoundingFrustum::Intersects(Ray const& ray) const {
auto result1 = Contains(ray.Position);
if (result1 == ContainmentType::Contains)
return 0.0F;
auto num1 = FloatMinValue;
auto num2 = FloatMaxValue;
for (size_t i = 0; i < planes.size(); ++i) {
const auto& plane = planes[i];
Vector3 normal = plane.Normal;
const auto result2 = Vector3::Dot(ray.Direction, normal);
float result3 = Vector3::Dot(ray.Position, normal);
result3 += plane.D;
if (std::abs(static_cast<double>(result2)) < 9.9999997473787516E-06)
{
if (result3 > 0.0)
return {};
}
else
{
const auto num3 = -result3 / result2;
if (result2 < 0.0)
{
if (num3 > num2)
return {};
if (num3 > num1)
num1 = num3;
}
else
{
if (num3 < num1)
return {};
if (num3 < num2)
num2 = num3;
}
}
}
auto num4 = num1 >= 0.0F ? num1 : num2;
if (num4 < 0.0)
return{};
return num4;
}
bool BoundingFrustum::Intersects(BoundingSphere const& sphere) {
gjk.Reset();
auto result1 = Vector3::Subtract(corners[0], sphere.Center);
if (result1.LengthSquared() < 9.9999997473787516E-06)
result1 = Vector3::UnitX();
auto num1 = FloatMaxValue;
auto num2 = 0.0F;
do
{
Vector3 v;
v.X = -result1.X;
v.Y = -result1.Y;
v.Z = -result1.Z;
Vector3 result2;
SupportMapping(v, result2);
Vector3 result3;
sphere.SupportMapping(result1, result3);
Vector3 result4 = Vector3::Subtract(result2, result3);
if (result1.X * result4.X + result1.Y * result4.Y + result1.Z * result4.Z > 0.0)
return false;
gjk.AddSupportPoint(result4);
result1 = gjk.ClosestPoint();
auto num3 = num1;
num1 = result1.LengthSquared();
if (num3 - num1 <= 9.9999997473787516E-06 * num3)
return false;
num2 = 4E-05f * gjk.MaxLengthSquared();
} while (!gjk.FullSimplex() && num1 >= num2);
return true;
}
bool BoundingFrustum::Intersects(BoundingFrustum const& frustum) {
gjk.Reset();
Vector3 result1 = Vector3::Subtract(corners[0], frustum.corners[0]);
if (result1.LengthSquared() < 9.9999997473787516E-06)
result1 = Vector3::Subtract(corners[0], frustum.corners[1]);
float num1 = FloatMaxValue;
float num2 = 0;
do
{
Vector3 v;
v.X = -result1.X;
v.Y = -result1.Y;
v.Z = -result1.Z;
Vector3 result2;
SupportMapping(v, result2);
Vector3 result3;
frustum.SupportMapping(result1, result3);
const auto result4 = Vector3::Subtract(result2, result3);
if (result1.X * result4.X + result1.Y * result4.Y + result1.Z * result4.Z > 0.0)
return false;
gjk.AddSupportPoint(result4);
result1 = gjk.ClosestPoint();
const auto num3 = num1;
num1 = result1.LengthSquared();
num2 = 4E-05f * gjk.MaxLengthSquared();
if (num3 - num1 <= 9.9999997473787516E-06 * num3)
return false;
} while (!gjk.FullSimplex() && num1 >= num2);
return true;
}
ContainmentType BoundingFrustum::Contains(BoundingFrustum const& frustum) {
ContainmentType containmentType = ContainmentType::Disjoint;
if (Intersects(frustum)) {
containmentType = ContainmentType::Contains;
for (size_t index = 0; index < corners.size(); ++index) {
if (Contains(frustum.corners[index]) == ContainmentType::Disjoint)
{
containmentType = ContainmentType::Intersects;
break;
}
}
}
return containmentType;
}
}

104
framework/common/gjk.cpp Normal file
View File

@ -0,0 +1,104 @@
#include "common/gjk.hpp"
namespace xna {
Vector3 Gjk::ComputeClosestPoint() {
auto num1 = 0.0f;
Vector3 zero = Vector3::Zero();
maxLengthSq = 0.0f;
for (auto bitsToIndex = Gjk::BitsToIndices[simplexBits]; bitsToIndex != 0; bitsToIndex >>= 3)
{
auto index = (bitsToIndex & 7) - 1;
auto num2 = det[simplexBits][index];
num1 += num2;
zero += y[index] * num2;
maxLengthSq = MathHelper::Max(maxLengthSq, yLengthSq[index]);
}
return zero / num1;
}
bool Gjk::UpdateSimplex(Int newIndex) {
auto yBits = simplexBits | 1 << newIndex;
auto xBits = 1 << newIndex;
for (auto sb = simplexBits; sb != 0; --sb)
{
if ((sb & yBits) == sb && IsSatisfiesRule(sb | xBits, yBits))
{
simplexBits = sb | xBits;
closestPoint = ComputeClosestPoint();
return true;
}
}
bool flag = false;
if (IsSatisfiesRule(xBits, yBits)) {
simplexBits = xBits;
closestPoint = y[newIndex];
maxLengthSq = yLengthSq[newIndex];
flag = true;
}
return flag;
}
void Gjk::UpdateDeterminant(Int xmIdx) {
auto index1 = 1 << xmIdx;
det[index1][xmIdx] = 1.0f;
auto bitsToIndex = Gjk::BitsToIndices[simplexBits];
auto num1 = bitsToIndex;
auto num2 = 0;
while (num1 != 0)
{
auto index2 = (num1 & 7) - 1;
auto num3 = 1 << index2;
auto index3 = num3 | index1;
det[index3][index2] = Vector3::Dot(edges[xmIdx][index2], y[xmIdx]);
det[index3][xmIdx] = Vector3::Dot(edges[index2][xmIdx], y[index2]);
auto num4 = bitsToIndex;
for (auto index4 = 0; index4 < num2; ++index4)
{
auto index5 = (num4 & 7) - 1;
auto num5 = 1 << index5;
auto index6 = index3 | num5;
auto index7 = Gjk::edgeLengthSq[index2][index5] < Gjk::edgeLengthSq[xmIdx][index5] ? index2 : xmIdx;
det[index6][index5] = (Gjk::det[index3][index2] * Vector3::Dot(edges[index7][index5], y[index2]) + Gjk::det[index3][xmIdx] * Vector3::Dot(edges[index7][index5], y[xmIdx]));
auto index8 = Gjk::edgeLengthSq[index5][index2] < Gjk::edgeLengthSq[xmIdx][index2] ? index5 : xmIdx;
det[index6][index2] = (Gjk::det[num5 | index1][index5] * Vector3::Dot(edges[index8][index2], y[index5]) + Gjk::det[num5 | index1][xmIdx] * Vector3::Dot(edges[index8][index2], y[xmIdx]));
auto index9 = Gjk::edgeLengthSq[index2][xmIdx] < Gjk::edgeLengthSq[index5][xmIdx] ? index2 : index5;
det[index6][xmIdx] = (Gjk::det[num3 | num5][index5] * Vector3::Dot(edges[index9][xmIdx], y[index5]) + Gjk::det[num3 | num5][index2] * Vector3::Dot(edges[index9][xmIdx], y[index2]));
num4 >>= 3;
}
num1 >>= 3;
++num2;
}
if ((simplexBits | index1) != 15)
return;
auto index10 = Gjk::edgeLengthSq[1][0] < Gjk::edgeLengthSq[2][0] ? (Gjk::edgeLengthSq[1][0] < Gjk::edgeLengthSq[3][0] ? 1 : 3) : (Gjk::edgeLengthSq[2][0] < Gjk::edgeLengthSq[3][0] ? 2 : 3);
det[15][0] = (Gjk::det[14][1] * Vector3::Dot(edges[index10][0], y[1]) + Gjk::det[14][2] * Vector3::Dot(edges[index10][0], y[2]) + Gjk::det[14][3] * Vector3::Dot(edges[index10][0], y[3]));
auto index11 = Gjk::edgeLengthSq[0][1] < Gjk::edgeLengthSq[2][1] ? (Gjk::edgeLengthSq[0][1] < Gjk::edgeLengthSq[3][1] ? 0 : 3) : (Gjk::edgeLengthSq[2][1] < Gjk::edgeLengthSq[3][1] ? 2 : 3);
det[15][1] = (Gjk::det[13][0] * Vector3::Dot(edges[index11][1], y[0]) + Gjk::det[13][2] * Vector3::Dot(edges[index11][1], y[2]) + Gjk::det[13][3] * Vector3::Dot(edges[index11][1], y[3]));
auto index12 = Gjk::edgeLengthSq[0][2] < Gjk::edgeLengthSq[1][2] ? (Gjk::edgeLengthSq[0][2] < Gjk::edgeLengthSq[3][2] ? 0 : 3) : (Gjk::edgeLengthSq[1][2] < Gjk::edgeLengthSq[3][2] ? 1 : 3);
det[15][2] = (Gjk::det[11][0] * Vector3::Dot(edges[index12][2], y[0]) + Gjk::det[11][1] * Vector3::Dot(edges[index12][2], y[1]) + Gjk::det[11][3] * Vector3::Dot(edges[index12][2], y[3]));
auto index13 = Gjk::edgeLengthSq[0][3] < Gjk::edgeLengthSq[1][3] ? (Gjk::edgeLengthSq[0][3] < Gjk::edgeLengthSq[2][3] ? 0 : 2) : (Gjk::edgeLengthSq[1][3] < Gjk::edgeLengthSq[2][3] ? 1 : 2);
det[15][3] = (Gjk::det[7][0] * Vector3::Dot(edges[index13][3], y[0]) + Gjk::det[7][1] * Vector3::Dot(edges[index13][3], y[1]) + Gjk::det[7][2] * Vector3::Dot(edges[index13][3], y[2]));
}
bool Gjk::AddSupportPoint(Vector3 const& newPoint) {
auto index1 = (Gjk::BitsToIndices[simplexBits ^ 15] & 7) - 1;
y[index1] = newPoint;
yLengthSq[index1] = newPoint.LengthSquared();
for (auto bitsToIndex = Gjk::BitsToIndices[simplexBits]; bitsToIndex != 0; bitsToIndex >>= 3)
{
auto index2 = (bitsToIndex & 7) - 1;
Vector3 vector3 = y[index2] - newPoint;
edges[index2][index1] = vector3;
edges[index1][index2] = -vector3;
edgeLengthSq[index1][index2] = edgeLengthSq[index2][index1] = vector3.LengthSquared();
}
UpdateDeterminant(index1);
return UpdateSimplex(index1);
}
}

239
inc/common/collision.hpp Normal file
View File

@ -0,0 +1,239 @@
#ifndef XNA_COMMON_SHAPES_HPP
#define XNA_COMMON_SHAPES_HPP
#include "default.hpp"
#include "vectors.hpp"
#include "matrix.hpp"
#include "gjk.hpp"
#include <optional>
namespace xna {
struct Plane {
Vector3 Normal{ 0 };
float D{ 0 };
};
struct BoundingFrustum {
inline static constexpr int CornerCount = 8;
inline static constexpr int PlaneCount = 6;
Plane Near() { return planes[0]; }
Plane Far() { return planes[1]; }
Plane Left() { return planes[2]; }
Plane Right() { return planes[3]; }
Plane Top() { return planes[4]; }
Plane Bottom() { return planes[5]; }
constexpr bool operator==(BoundingFrustum const& other) const {
return matrix == other.matrix;
}
constexpr void GetCorners(std::vector<Vector3>& destination) const;
constexpr Matrix GetMatrix() const { return matrix; }
constexpr void SetMatrix(Matrix const& value);
bool Intersects(BoundingBox const& box);
bool Intersects(BoundingSphere const& box);
constexpr PlaneIntersectionType Intersects(Plane const& plane) const;
bool Intersects(BoundingFrustum const& frustum);
std::optional<float> Intersects(Ray const& ray) const;
constexpr ContainmentType Contains(BoundingBox const& box) const;
ContainmentType Contains(BoundingFrustum const& box);
constexpr ContainmentType Contains(Vector3 const& point) const;
constexpr ContainmentType Contains(BoundingSphere const& box) const;
constexpr void SupportMapping(Vector3 const& v, Vector3& result) const;
private:
std::vector<Plane> planes{ 6 };
std::vector<Vector3> corners{ 8 };
Matrix matrix{ Matrix::Identity() };
Gjk gjk{};
private:
static constexpr Ray ComputeIntersectionLine(Plane const& p1, Plane const& p2);
static constexpr Vector3 ComputeIntersection(Plane const& plane, Ray const& ray);
};
struct BoundingBox {
Vector3 Min{};
Vector3 Max{};
constexpr PlaneIntersectionType Intersects(Plane const& plane) const {
return PlaneIntersectionType::Intersecting;
}
void SupportMapping(Vector3 const& v, Vector3& result) const {
}
};
struct BoundingSphere {
Vector3 Center{};
float Radius{ 0 };
void SupportMapping(Vector3 const& v, Vector3& result) const {
//TODO
}
};
struct Ray {
Vector3 Position{};
Vector3 Direction{};
};
//---------------------------------------------------------------------------------//
// IMPLEMENTATIONS //
//---------------------------------------------------------------------------------//
constexpr void BoundingFrustum::GetCorners(std::vector<Vector3>& destination) const {
if (destination.size() < CornerCount)
destination.resize(CornerCount);
for (size_t i = 0; i < CornerCount; ++i)
destination[i] = corners[i];
}
constexpr Ray BoundingFrustum::ComputeIntersectionLine(Plane const& p1, Plane const& p2) {
Ray intersectionLine{};
intersectionLine.Direction = Vector3::Cross(p1.Normal, p2.Normal);
const auto num = intersectionLine.Direction.LengthSquared();
intersectionLine.Position = Vector3::Cross(-p1.D * p2.Normal + p2.D * p1.Normal, intersectionLine.Direction) / num;
return intersectionLine;
}
constexpr Vector3 BoundingFrustum::ComputeIntersection(Plane const& plane, Ray const& ray) {
const auto num = (-plane.D - Vector3::Dot(plane.Normal, ray.Position)) / Vector3::Dot(plane.Normal, ray.Direction);
return ray.Position + ray.Direction * num;
}
constexpr void BoundingFrustum::SupportMapping(Vector3 const& v, Vector3& result) const {
size_t index1 = 0;
auto result1 = Vector3::Dot(corners[0], v);
for (size_t index2 = 1; index2 < CornerCount; ++index2)
{
auto result2 = Vector3::Dot(corners[index2], v);
if (result2 > result1)
{
index1 = index2;
result1 = result2;
}
}
result = corners[index1];
}
constexpr PlaneIntersectionType BoundingFrustum::Intersects(Plane const& plane) const {
int num = 0;
for (size_t index = 0; index < CornerCount; ++index)
{
auto result = Vector3::Dot(corners[index], plane.Normal);
if (result + plane.D > 0.0F)
num |= 1;
else
num |= 2;
if (num == 3)
return PlaneIntersectionType::Intersecting;
}
return num != 1 ? PlaneIntersectionType::Back : PlaneIntersectionType::Front;
}
constexpr ContainmentType BoundingFrustum::Contains(Vector3 const& point) const {
for (size_t i = 0; i < PlaneCount; ++i) {
const auto& plane = planes[i];
if ((static_cast<double>(plane.Normal.X * point.X + plane.Normal.Y * point.Y + plane.Normal.Z * point.Z) + plane.D) > 9.9999997473787516E-06)
return ContainmentType::Disjoint;
}
return ContainmentType::Contains;
}
constexpr ContainmentType BoundingFrustum::Contains(BoundingBox const& box) const {
bool flag = false;
for (size_t i = 0; i < PlaneCount; ++i)
{
const auto& plane = planes[i];
switch (box.Intersects(plane))
{
case PlaneIntersectionType::Front:
return ContainmentType::Disjoint;
case PlaneIntersectionType::Intersecting:
flag = true;
break;
}
}
return !flag ? ContainmentType::Contains : ContainmentType::Intersects;
}
constexpr ContainmentType BoundingFrustum::Contains(BoundingSphere const& sphere) const {
auto center = sphere.Center;
auto radius = sphere.Radius;
auto num1 = 0;
for (size_t i = 0; i < PlaneCount; ++i)
{
const auto& plane = planes[i];
auto num2 = (plane.Normal.X * center.X + plane.Normal.Y * center.Y + plane.Normal.Z * center.Z) + plane.D;
if (num2 > radius)
return ContainmentType::Disjoint;
if (num2 < -radius)
++num1;
}
return num1 != 6 ? ContainmentType::Intersects : ContainmentType::Contains;
}
constexpr void BoundingFrustum::SetMatrix(Matrix const& value) {
matrix = value;
planes[2].Normal.X = -value.M14 - value.M11;
planes[2].Normal.Y = -value.M24 - value.M21;
planes[2].Normal.Z = -value.M34 - value.M31;
planes[2].D = -value.M44 - value.M41;
planes[3].Normal.X = -value.M14 + value.M11;
planes[3].Normal.Y = -value.M24 + value.M21;
planes[3].Normal.Z = -value.M34 + value.M31;
planes[3].D = -value.M44 + value.M41;
planes[4].Normal.X = -value.M14 + value.M12;
planes[4].Normal.Y = -value.M24 + value.M22;
planes[4].Normal.Z = -value.M34 + value.M32;
planes[4].D = -value.M44 + value.M42;
planes[5].Normal.X = -value.M14 - value.M12;
planes[5].Normal.Y = -value.M24 - value.M22;
planes[5].Normal.Z = -value.M34 - value.M32;
planes[5].D = -value.M44 - value.M42;
planes[0].Normal.X = -value.M13;
planes[0].Normal.Y = -value.M23;
planes[0].Normal.Z = -value.M33;
planes[0].D = -value.M43;
planes[1].Normal.X = -value.M14 + value.M13;
planes[1].Normal.Y = -value.M24 + value.M23;
planes[1].Normal.Z = -value.M34 + value.M33;
planes[1].D = -value.M44 + value.M43;
for (size_t index = 0; index < PlaneCount; ++index)
{
const auto num = planes[index].Normal.Length();
planes[index].Normal = planes[index].Normal / num;
planes[index].D /= num;
}
Ray intersectionLine1 = BoundingFrustum::ComputeIntersectionLine(planes[0], planes[2]);
corners[0] = BoundingFrustum::ComputeIntersection(planes[4], intersectionLine1);
corners[3] = BoundingFrustum::ComputeIntersection(planes[5], intersectionLine1);
Ray intersectionLine2 = BoundingFrustum::ComputeIntersectionLine(planes[3], planes[0]);
corners[1] = BoundingFrustum::ComputeIntersection(planes[4], intersectionLine2);
corners[2] = BoundingFrustum::ComputeIntersection(planes[5], intersectionLine2);
intersectionLine2 = BoundingFrustum::ComputeIntersectionLine(planes[2], planes[1]);
corners[4] = BoundingFrustum::ComputeIntersection(planes[4], intersectionLine2);
corners[7] = BoundingFrustum::ComputeIntersection(planes[5], intersectionLine2);
intersectionLine2 = BoundingFrustum::ComputeIntersectionLine(planes[1], planes[3]);
corners[5] = BoundingFrustum::ComputeIntersection(planes[4], intersectionLine2);
corners[6] = BoundingFrustum::ComputeIntersection(planes[5], intersectionLine2);
}
}
#endif

71
inc/common/gjk.hpp Normal file
View File

@ -0,0 +1,71 @@
#ifndef XNA_COMMON_GDK_HPP
#define XNA_COMMON_GDK_HPP
#include "default.hpp"
#include "vectors.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

@ -6,16 +6,16 @@
namespace xna {
struct MathHelper {
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 double E = 2.7182818284590451;
static constexpr double PI = 3.1415926535897931;
static constexpr double TAU = 6.2831853071795862;
static constexpr double EPSILON = 4.94065645841247E-324;
static constexpr float ToRadians(float degrees) { return degrees * (static_cast<float>(PI) / 180.0f); }
static constexpr float ToDegrees(float radians) { return radians * 57.2957764F; }
static float Distance(float value1, float value2) { return std::abs(value1 - value2); }
static float Min(float value1, float value2) { return (std::min)(value1, value2); }
static float Max(float value1, float value2) { return (std::max)(value1, value2); }
static constexpr float Min(float value1, float value2) { return (std::min)(value1, value2); }
static constexpr float Max(float value1, float value2) { return (std::max)(value1, value2); }
static constexpr float Clamp(float value, float min, float max) {
value = value > max ? max : value;

View File

@ -4,19 +4,7 @@
#include "../types.hpp"
namespace xna {
struct Point {
Int X{0};
Int Y{ 0 };
constexpr Point() = default;
constexpr Point(const Int& X, const Int& Y)
: X(X), Y(Y) {}
constexpr bool operator==(const Point& other) const {
return X == other.X && Y == other.Y;
}
};
}
#endif

View File

@ -2,9 +2,22 @@
#define XNA_COMMON_RECTANGLE_HPP
#include "../types.hpp"
#include "point.hpp"
namespace xna {
struct Point {
Int X{ 0 };
Int Y{ 0 };
constexpr Point() = default;
constexpr Point(const Int& X, const Int& Y)
: X(X), Y(Y) {}
constexpr bool operator==(const Point& other) const {
return X == other.X && Y == other.Y;
}
};
struct Rectangle {
Int X{ 0 };
Int Y{ 0 };

View File

@ -263,7 +263,7 @@ namespace xna {
return x * x + y * y + z * z;
}
static float Dot(Vector3 const& vector1, Vector3 const& vector2) {
static constexpr float Dot(Vector3 const& vector1, Vector3 const& vector2) {
return vector1.X * vector2.X + vector1.Y * vector2.Y + vector1.Z * vector2.Z;
}
@ -487,6 +487,20 @@ namespace xna {
friend constexpr Vector3 operator/(float divider, Vector3 const& value) {
return Vector3::Divide(value, divider);
}
friend constexpr Vector3 operator+=(Vector3 const& value1, Vector3 const& value2) {
auto vec = value1;
vec.X += value2.X;
vec.Y += value2.Y;
return vec;
}
friend constexpr Vector3 operator-=(Vector3 const& value1, Vector3 const& value2) {
auto vec = value1;
vec.X -= value2.X;
vec.Y -= value2.Y;
return vec;
}
};
struct Vector4 {

View File

@ -114,7 +114,13 @@ namespace xna {
Blue,
Alpha,
All
};
};
enum class ContainmentType {
Disjoint,
Contains,
Intersects,
};
enum class ComparisonFunction {
Never,
@ -379,6 +385,12 @@ namespace xna {
Down,
};
enum class PlaneIntersectionType {
Front,
Back,
Intersecting,
};
enum class PlayerIndex
{
One,

View File

@ -24,20 +24,20 @@ namespace xna {
class ContentTypeReader;
class ContentTypeReaderManager;
//Framework
class BoundingBox;
class BoundingFrustum;
class BoundinSphere;
//Common
struct BoundingBox;
struct BoundingFrustum;
struct BoundingSphere;
struct Color;
class Curve;
class CurveContinuity;
class CurveKey;
class CurveKeyCollection;
struct Curve;
struct CurveContinuity;
struct CurveKey;
struct CurveKeyCollection;
struct Matrix;
class Plane;
struct Plane;
struct Point;
struct Quaternion;
class Ray;
struct Ray;
struct Rectangle;
struct Vector2;
struct Vector3;

View File

@ -3,16 +3,17 @@
#include "helpers.hpp"
#include "forward.hpp"
#include "enums.hpp"
#include "default.hpp"
#include "audio/audioengine.hpp"
#include "audio/soundeffect.hpp"
#include "common/color.hpp"
#include "common/gjk.hpp"
#include "common/math.hpp"
#include "common/matrix.hpp"
#include "common/packedvalue.hpp"
#include "common/point.hpp"
#include "common/quaternion.hpp"
#include "common/rectangle.hpp"
#include "common/collision.hpp"
#include "common/vectors.hpp"
#include "content/defaultreaders.hpp"
#include "content/manager.hpp"