#ifndef __URDE_CMETROIDAREACOLLIDER_HPP__ #define __URDE_CMETROIDAREACOLLIDER_HPP__ #include "RetroTypes.hpp" #include "zeus/CAABox.hpp" #include "CAreaOctTree.hpp" namespace urde { class CCollisionInfoList; class CCollisionInfo; class CMaterialList; class CAABoxAreaCache { friend class CMetroidAreaCollider; const zeus::CAABox& x0_aabb; const zeus::CPlane* x4_planes; const CMaterialFilter& x8_filter; const CMaterialList& xc_material; CCollisionInfoList& x10_collisionList; zeus::CVector3f x14_center; zeus::CVector3f x20_halfExtent; public: CAABoxAreaCache(const zeus::CAABox& aabb, const zeus::CPlane* pl, const CMaterialFilter& filter, const CMaterialList& material, CCollisionInfoList& collisionList); }; class CBooleanAABoxAreaCache { friend class CMetroidAreaCollider; const zeus::CAABox& x0_aabb; const CMaterialFilter& x4_filter; zeus::CVector3f x8_center; zeus::CVector3f x14_halfExtent; public: CBooleanAABoxAreaCache(const zeus::CAABox& aabb, const CMaterialFilter& filter); }; class CSphereAreaCache { friend class CMetroidAreaCollider; const zeus::CAABox& x0_aabb; const zeus::CSphere& x4_sphere; const CMaterialFilter& x8_filter; const CMaterialList& xc_material; CCollisionInfoList& x10_collisionList; public: CSphereAreaCache(const zeus::CAABox& aabb, const zeus::CSphere& sphere, const CMaterialFilter& filter, const CMaterialList& material, CCollisionInfoList& collisionList); }; class CBooleanSphereAreaCache { friend class CMetroidAreaCollider; const zeus::CAABox& x0_aabb; const zeus::CSphere& x4_sphere; const CMaterialFilter& x8_filter; public: CBooleanSphereAreaCache(const zeus::CAABox& aabb, const zeus::CSphere& sphere, const CMaterialFilter& filter); }; struct SBoxEdge { zeus::CLineSeg x0_seg; zeus::CVector3d x28_dir; zeus::CVector3d x40_end; zeus::CVector3d x58_start; zeus::CVector3d x70_coDir; double x88_dirCoDirDot; SBoxEdge(const zeus::CAABox& aabb, int idx, const zeus::CVector3f& dir); }; class CMovingAABoxComponents { friend class CMetroidAreaCollider; friend class CCollidableOBBTree; rstl::reserved_vector x0_edges; rstl::reserved_vector x6c4_vertIdxs; zeus::CAABox x6e8_aabb; public: CMovingAABoxComponents(const zeus::CAABox& aabb, const zeus::CVector3f& dir); }; class CMetroidAreaCollider { friend class CCollidableOBBTree; static u32 g_CalledClip; static u32 g_RejectedByClip; static u32 g_TrianglesProcessed; static u32 g_DupTrianglesProcessed; static u16 g_DupPrimitiveCheckCount; static u16 g_DupVertexList[0x5000]; static u16 g_DupEdgeList[0xC000]; static u16 g_DupTriangleList[0x4000]; static bool AABoxCollisionCheckBoolean_Internal(const CAreaOctTree::Node& node, const CBooleanAABoxAreaCache& cache); static bool AABoxCollisionCheck_Internal(const CAreaOctTree::Node& node, const CAABoxAreaCache& cache); static bool SphereCollisionCheckBoolean_Internal(const CAreaOctTree::Node& node, const CBooleanSphereAreaCache& cache); static bool SphereCollisionCheck_Internal(const CAreaOctTree::Node& node, const CSphereAreaCache& cache); static bool MovingAABoxCollisionCheck_BoxVertexTri(const CCollisionSurface& surf, const zeus::CAABox& aabb, const rstl::reserved_vector& vertIndices, const zeus::CVector3f& dir, double& d, zeus::CVector3f& normal, zeus::CVector3f& point); static bool MovingAABoxCollisionCheck_TriVertexBox(const zeus::CVector3f& vert, const zeus::CAABox& aabb, const zeus::CVector3f& dir, double& d, zeus::CVector3f& normal, zeus::CVector3f& point); static bool MovingAABoxCollisionCheck_Edge(const zeus::CVector3f& ev0, const zeus::CVector3f& ev1, const rstl::reserved_vector& edges, const zeus::CVector3f& dir, double& d, zeus::CVector3f& normal, zeus::CVector3f& point); public: class COctreeLeafCache { friend class CMetroidAreaCollider; const CAreaOctTree& x0_octTree; rstl::reserved_vector x4_nodeCache; bool x908_24_overflow : 1; public: COctreeLeafCache(const CAreaOctTree& octTree); void AddLeaf(const CAreaOctTree::Node& node); u32 GetNumLeaves() const { return x4_nodeCache.size(); } bool HasCacheOverflowed() const { return x908_24_overflow; } }; static void BuildOctreeLeafCache(const CAreaOctTree::Node& root, const zeus::CAABox& aabb, CMetroidAreaCollider::COctreeLeafCache& cache); static bool ConvexPolyCollision(const zeus::CPlane* planes, const zeus::CVector3f* verts, zeus::CAABox& aabb); static bool AABoxCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb, const CMaterialFilter& filter); static bool AABoxCollisionCheckBoolean(const CAreaOctTree& octTree, const zeus::CAABox& aabb, const CMaterialFilter& filter); static bool SphereCollisionCheckBoolean_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb, const zeus::CSphere& sphere, const CMaterialFilter& filter); static bool SphereCollisionCheckBoolean(const CAreaOctTree& octTree, const zeus::CAABox& aabb, const zeus::CSphere& sphere, const CMaterialFilter& filter); static bool AABoxCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb, const CMaterialFilter& filter, const CMaterialList& matList, CCollisionInfoList& list); static bool AABoxCollisionCheck(const CAreaOctTree& octTree, const zeus::CAABox& aabb, const CMaterialFilter& filter, const CMaterialList& matList, CCollisionInfoList& list); static bool SphereCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb, const zeus::CSphere& sphere, const CMaterialList& matList, const CMaterialFilter& filter, CCollisionInfoList& list); static bool SphereCollisionCheck(const CAreaOctTree& octTree, const zeus::CAABox& aabb, const zeus::CSphere& sphere, const CMaterialList& matList, const CMaterialFilter& filter, CCollisionInfoList& list); static bool MovingAABoxCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb, const CMaterialFilter& filter, const CMaterialList& matList, const zeus::CVector3f& dir, float mag, CCollisionInfo& infoOut, double& dOut); static bool MovingSphereCollisionCheck_Cached(const COctreeLeafCache& leafCache, const zeus::CAABox& aabb, const zeus::CSphere& sphere, const CMaterialFilter& filter, const CMaterialList& matList, const zeus::CVector3f& dir, float mag, CCollisionInfo& infoOut, double& dOut); static void ResetInternalCounters(); }; class CAreaCollisionCache { zeus::CAABox x0_aabb; rstl::reserved_vector x18_leafCaches; union { struct { bool x1b40_24_leafOverflow : 1; bool x1b40_25_cacheOverflow : 1; }; u32 _dummy = 0; }; public: CAreaCollisionCache(const zeus::CAABox& aabb) : x0_aabb(aabb) {} void ClearCache(); const zeus::CAABox& GetCacheBounds() const { return x0_aabb; } void SetCacheBounds(const zeus::CAABox& aabb) { x0_aabb = aabb; } void AddOctreeLeafCache(const CMetroidAreaCollider::COctreeLeafCache& leafCache); u32 GetNumCaches() const { return x18_leafCaches.size(); } const CMetroidAreaCollider::COctreeLeafCache& GetOctreeLeafCache(int idx) { return x18_leafCaches[idx]; } bool HasCacheOverflowed() const { return x1b40_24_leafOverflow; } rstl::reserved_vector::iterator begin() { return x18_leafCaches.begin(); } rstl::reserved_vector::iterator end() { return x18_leafCaches.end(); } }; } #endif // __URDE_CMETROIDAREACOLLIDER_HPP__