Files
WickedEngine/WickedEngine/wiPrimitive.h
T

221 lines
7.3 KiB
C++

#pragma once
#include "CommonInclude.h"
#include "wiArchive.h"
#include "wiMath.h"
#include "wiECS.h"
#include <limits>
namespace wi::primitive
{
struct Sphere;
struct Ray;
struct AABB;
struct Capsule;
struct Plane;
struct AABB
{
enum INTERSECTION_TYPE
{
OUTSIDE,
INTERSECTS,
INSIDE,
};
XMFLOAT3 _min;
uint32_t layerMask = ~0u;
XMFLOAT3 _max;
uint32_t userdata = 0;
AABB(
const XMFLOAT3& _min = XMFLOAT3(std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max()),
const XMFLOAT3& _max = XMFLOAT3(std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest())
) : _min(_min), _max(_max) {}
void createFromHalfWidth(const XMFLOAT3& center, const XMFLOAT3& halfwidth);
AABB transform(const XMMATRIX& mat) const;
AABB transform(const XMFLOAT4X4& mat) const;
XMFLOAT3 getCenter() const;
XMFLOAT3 getHalfWidth() const;
XMMATRIX getAsBoxMatrix() const;
float getArea() const;
float getRadius() const;
INTERSECTION_TYPE intersects2D(const AABB& b) const;
INTERSECTION_TYPE intersects(const AABB& b) const;
bool intersects(const XMFLOAT3& p) const;
bool intersects(const Ray& ray) const;
bool intersects(const Sphere& sphere) const;
bool intersects(const BoundingFrustum& frustum) const;
AABB operator* (float a);
static AABB Merge(const AABB& a, const AABB& b);
constexpr XMFLOAT3 getMin() const { return _min; }
constexpr XMFLOAT3 getMax() const { return _max; }
constexpr XMFLOAT3 corner(int index) const
{
switch (index)
{
case 0: return _min;
case 1: return XMFLOAT3(_min.x, _max.y, _min.z);
case 2: return XMFLOAT3(_min.x, _max.y, _max.z);
case 3: return XMFLOAT3(_min.x, _min.y, _max.z);
case 4: return XMFLOAT3(_max.x, _min.y, _min.z);
case 5: return XMFLOAT3(_max.x, _max.y, _min.z);
case 6: return _max;
case 7: return XMFLOAT3(_max.x, _min.y, _max.z);
}
assert(0);
return XMFLOAT3(0, 0, 0);
}
constexpr bool IsValid() const
{
if (_min.x > _max.x || _min.y > _max.y || _min.z > _max.z)
return false;
return true;
}
void Serialize(wi::Archive& archive, wi::ecs::EntitySerializer& seri);
};
struct Sphere
{
XMFLOAT3 center;
float radius;
Sphere() :center(XMFLOAT3(0, 0, 0)), radius(0) {}
Sphere(const XMFLOAT3& c, float r) :center(c), radius(r) {}
bool intersects(const AABB& b) const;
bool intersects(const Sphere& b) const;
bool intersects(const Sphere& b, float& dist) const;
bool intersects(const Sphere& b, float& dist, XMFLOAT3& direction) const;
bool intersects(const Capsule& b) const;
bool intersects(const Capsule& b, float& dist) const;
bool intersects(const Capsule& b, float& dist, XMFLOAT3& direction) const;
bool intersects(const Plane& b) const;
bool intersects(const Plane& b, float& dist) const;
bool intersects(const Plane& b, float& dist, XMFLOAT3& direction) const;
bool intersects(const Ray& b) const;
bool intersects(const Ray& b, float& dist) const;
bool intersects(const Ray& b, float& dist, XMFLOAT3& direction) const;
};
struct Capsule
{
XMFLOAT3 base = XMFLOAT3(0, 0, 0);
XMFLOAT3 tip = XMFLOAT3(0, 0, 0);
float radius = 0;
Capsule() = default;
Capsule(const XMFLOAT3& base, const XMFLOAT3& tip, float radius) :base(base), tip(tip), radius(radius) {}
Capsule(const Sphere& sphere, float height) :
base(XMFLOAT3(sphere.center.x, sphere.center.y - sphere.radius, sphere.center.z)),
tip(XMFLOAT3(base.x, base.y + height, base.z)),
radius(sphere.radius)
{}
inline AABB getAABB() const
{
XMFLOAT3 halfWidth = XMFLOAT3(radius, radius, radius);
AABB base_aabb;
base_aabb.createFromHalfWidth(base, halfWidth);
AABB tip_aabb;
tip_aabb.createFromHalfWidth(tip, halfWidth);
return AABB::Merge(base_aabb, tip_aabb);
}
bool intersects(const Capsule& b, XMFLOAT3& position, XMFLOAT3& incident_normal, float& penetration_depth) const;
bool intersects(const Sphere& b) const;
bool intersects(const Sphere& b, float& dist) const;
bool intersects(const Sphere& b, float& dist, XMFLOAT3& direction) const;
bool intersects(const Plane& b) const;
bool intersects(const Plane& b, float& dist) const;
bool intersects(const Plane& b, float& dist, XMFLOAT3& direction) const;
bool intersects(const Ray& b) const;
bool intersects(const Ray& b, float& dist) const;
bool intersects(const Ray& b, float& dist, XMFLOAT3& direction) const;
bool intersects(const XMFLOAT3& point) const;
};
struct Plane
{
XMFLOAT3 origin = {};
XMFLOAT3 normal = {};
XMFLOAT4X4 projection = wi::math::IDENTITY_MATRIX;
bool intersects(const Sphere& b) const;
bool intersects(const Sphere& b, float& dist) const;
bool intersects(const Sphere& b, float& dist, XMFLOAT3& direction) const;
bool intersects(const Capsule& b) const;
bool intersects(const Capsule& b, float& dist) const;
bool intersects(const Capsule& b, float& dist, XMFLOAT3& direction) const;
bool intersects(const Ray& b) const;
bool intersects(const Ray& b, float& dist) const;
bool intersects(const Ray& b, float& dist, XMFLOAT3& direction) const;
};
struct Ray
{
XMFLOAT3 origin;
float TMin = 0;
XMFLOAT3 direction;
float TMax = std::numeric_limits<float>::max();
XMFLOAT3 direction_inverse;
Ray(const XMFLOAT3& newOrigin = XMFLOAT3(0, 0, 0), const XMFLOAT3& newDirection = XMFLOAT3(0, 0, 1), float newTMin = 0, float newTMax = std::numeric_limits<float>::max()) :
Ray(XMLoadFloat3(&newOrigin), XMLoadFloat3(&newDirection), newTMin, newTMax)
{}
Ray(const XMVECTOR& newOrigin, const XMVECTOR& newDirection, float newTMin = 0, float newTMax = std::numeric_limits<float>::max())
{
XMStoreFloat3(&origin, newOrigin);
XMStoreFloat3(&direction, newDirection);
XMStoreFloat3(&direction_inverse, XMVectorReciprocal(newDirection));
TMin = newTMin;
TMax = newTMax;
}
bool intersects(const AABB& b) const;
bool intersects(const Sphere& b) const;
bool intersects(const Sphere& b, float& dist) const;
bool intersects(const Sphere& b, float& dist, XMFLOAT3& direction) const;
bool intersects(const Capsule& b) const;
bool intersects(const Capsule& b, float& dist) const;
bool intersects(const Capsule& b, float& dist, XMFLOAT3& direction) const;
bool intersects(const Plane& b) const;
bool intersects(const Plane& b, float& dist) const;
bool intersects(const Plane& b, float& dist, XMFLOAT3& direction) const;
void CreateFromPoints(const XMFLOAT3& a, const XMFLOAT3& b);
};
struct Frustum
{
XMFLOAT4 planes[6];
void Create(const XMMATRIX& viewProjection);
bool CheckPoint(const XMFLOAT3&) const;
bool CheckSphere(const XMFLOAT3&, float) const;
enum BoxFrustumIntersect
{
BOX_FRUSTUM_OUTSIDE,
BOX_FRUSTUM_INTERSECTS,
BOX_FRUSTUM_INSIDE,
};
BoxFrustumIntersect CheckBox(const AABB& box) const;
bool CheckBoxFast(const AABB& box) const;
const XMFLOAT4& getNearPlane() const;
const XMFLOAT4& getFarPlane() const;
const XMFLOAT4& getLeftPlane() const;
const XMFLOAT4& getRightPlane() const;
const XMFLOAT4& getTopPlane() const;
const XMFLOAT4& getBottomPlane() const;
};
class Hitbox2D
{
public:
XMFLOAT2 pos;
XMFLOAT2 siz;
Hitbox2D() :pos(XMFLOAT2(0, 0)), siz(XMFLOAT2(0, 0)) {}
Hitbox2D(const XMFLOAT2& newPos, const XMFLOAT2 newSiz) :pos(newPos), siz(newSiz) {}
~Hitbox2D() {};
bool intersects(const Hitbox2D& b) const;
};
}