#pragma once #include #include #include #include "Runtime/Collision/CMaterialList.hpp" #include "Runtime/Collision/CRayCastResult.hpp" #include #include #include namespace metaforce { class CCollisionPrimitive; class CMaterialFilter; class CInternalCollisionStructure { public: class CPrimDesc { const CCollisionPrimitive& x0_prim; const CMaterialFilter& x4_filter; zeus::CTransform x8_xf; public: CPrimDesc(const CCollisionPrimitive& prim, const CMaterialFilter& filter, const zeus::CTransform& xf) : x0_prim(prim), x4_filter(filter), x8_xf(xf) {} const CCollisionPrimitive& GetPrim() const { return x0_prim; } const CMaterialFilter& GetFilter() const { return x4_filter; } const zeus::CTransform& GetTransform() const { return x8_xf; } }; private: CPrimDesc x0_p0; CPrimDesc x38_p1; public: CInternalCollisionStructure(const CPrimDesc& p0, const CPrimDesc& p1) : x0_p0(p0), x38_p1(p1) {} const CPrimDesc& GetLeft() const { return x0_p0; } const CPrimDesc& GetRight() const { return x38_p1; } }; class COBBTree; class CCollisionInfo; class CCollisionInfoList; class CInternalRayCastStructure; using BooleanComparisonFunc = bool (*)(const CInternalCollisionStructure&); using ComparisonFunc = bool (*)(const CInternalCollisionStructure&, CCollisionInfoList&); using MovingComparisonFunc = bool (*)(const CInternalCollisionStructure&, const zeus::CVector3f&, double&, CCollisionInfo&); using PrimitiveSetter = void (*)(u32); class CCollisionPrimitive { public: class Type { PrimitiveSetter x0_setter = nullptr; const char* x4_info = nullptr; public: constexpr Type() noexcept = default; constexpr Type(PrimitiveSetter setter, const char* info) noexcept : x0_setter(setter), x4_info(info) {} constexpr const char* GetInfo() const noexcept { return x4_info; } constexpr PrimitiveSetter GetSetter() const noexcept { return x0_setter; } }; class Comparison { ComparisonFunc x0_collider; const char* x4_type1; const char* x8_type2; public: constexpr Comparison(ComparisonFunc collider, const char* type1, const char* type2) noexcept : x0_collider(collider), x4_type1(type1), x8_type2(type2) {} constexpr ComparisonFunc GetCollider() const noexcept { return x0_collider; } constexpr const char* GetType1() const noexcept { return x4_type1; } constexpr const char* GetType2() const noexcept { return x8_type2; } }; class MovingComparison { MovingComparisonFunc x0_collider; const char* x4_type1; const char* x8_type2; public: constexpr MovingComparison(MovingComparisonFunc collider, const char* type1, const char* type2) noexcept : x0_collider(collider), x4_type1(type1), x8_type2(type2) {} constexpr MovingComparisonFunc GetCollider() const noexcept { return x0_collider; } constexpr const char* GetType1() const noexcept { return x4_type1; } constexpr const char* GetType2() const noexcept { return x8_type2; } }; class BooleanComparison { BooleanComparisonFunc x0_collider; const char* x4_type1; const char* x8_type2; public: constexpr BooleanComparison(BooleanComparisonFunc collider, const char* type1, const char* type2) noexcept : x0_collider(collider), x4_type1(type1), x8_type2(type2) {} constexpr BooleanComparisonFunc GetCollider() const noexcept { return x0_collider; } constexpr const char* GetType1() const noexcept { return x4_type1; } constexpr const char* GetType2() const noexcept { return x8_type2; } }; private: CMaterialList x8_material; static s32 sNumTypes; static bool sInitComplete; static bool sTypesAdded; static bool sTypesAdding; static bool sCollidersAdded; static bool sCollidersAdding; static std::unique_ptr> sCollisionTypeList; static std::unique_ptr> sTableOfCollidables; static std::unique_ptr> sTableOfBooleanCollidables; static std::unique_ptr> sTableOfMovingCollidables; static ComparisonFunc sNullCollider; static BooleanComparisonFunc sNullBooleanCollider; static MovingComparisonFunc sNullMovingCollider; // Attempts to locate an entry within the collision type list that matches the supplied name. // Returns the end iterator in the event of no matches. static std::vector::const_iterator FindCollisionType(const char* name); static bool InternalCollide(const CInternalCollisionStructure& collision, CCollisionInfoList& list); static bool InternalCollideBoolean(const CInternalCollisionStructure& collision); static bool InternalCollideMoving(const CInternalCollisionStructure& collision, const zeus::CVector3f& dir, double& dOut, CCollisionInfo& infoOut); public: CCollisionPrimitive() = default; explicit CCollisionPrimitive(const CMaterialList& list); virtual u32 GetTableIndex() const = 0; virtual void SetMaterial(const CMaterialList&); virtual const CMaterialList& GetMaterial() const; virtual zeus::CAABox CalculateAABox(const zeus::CTransform&) const = 0; virtual zeus::CAABox CalculateLocalAABox() const = 0; virtual FourCC GetPrimType() const = 0; virtual ~CCollisionPrimitive() = default; virtual CRayCastResult CastRayInternal(const CInternalRayCastStructure&) const = 0; CRayCastResult CastRay(const zeus::CVector3f& start, const zeus::CVector3f& dir, float length, const CMaterialFilter& filter, const zeus::CTransform& xf) const; static bool Collide(const CInternalCollisionStructure::CPrimDesc& prim0, const CInternalCollisionStructure::CPrimDesc& prim1, CCollisionInfoList& list); static bool CollideBoolean(const CInternalCollisionStructure::CPrimDesc& prim0, const CInternalCollisionStructure::CPrimDesc& prim1); static bool CollideMoving(const CInternalCollisionStructure::CPrimDesc& prim0, const CInternalCollisionStructure::CPrimDesc& prim1, const zeus::CVector3f& dir, double& dOut, CCollisionInfo& infoOut); static void InitBeginTypes(); static void InitAddType(const Type& tp); static void InitEndTypes(); static void InitBeginColliders(); static void InitAddBooleanCollider(const BooleanComparison& cmp); static void InitAddBooleanCollider(BooleanComparisonFunc, const char*, const char*); static void InitAddMovingCollider(const MovingComparison& cmp); static void InitAddMovingCollider(MovingComparisonFunc, const char*, const char*); static void InitAddCollider(const Comparison& cmp); static void InitAddCollider(ComparisonFunc, const char*, const char*); static void InitEndColliders(); static void Uninitialize(); }; } // namespace metaforce