#pragma once #include #include #include #include "Runtime/RetroTypes.hpp" #include "Runtime/Collision/CCollisionEdge.hpp" #include "Runtime/Collision/CCollisionSurface.hpp" #include #include namespace metaforce { class CCollidableOBBTreeGroupContainer; class COBBTree { public: struct SIndexData { std::vector x0_materials; std::vector x10_vertMaterials; std::vector x20_edgeMaterials; std::vector x30_surfaceMaterials; std::vector x40_edges; std::vector x50_surfaceIndices; std::vector x60_vertices; SIndexData() = default; explicit SIndexData(CInputStream&); }; class CLeafData { std::vector x0_surface; public: CLeafData() = default; explicit CLeafData(std::vector&& surface); explicit CLeafData(CInputStream&); const std::vector& GetSurfaceVector() const; size_t GetMemoryUsage() const; }; class CNode { zeus::COBBox x0_obb; bool x3c_isLeaf = false; std::unique_ptr x40_left; std::unique_ptr x44_right; std::unique_ptr x48_leaf; bool x4c_hit = false; public: CNode() = default; CNode(const zeus::CTransform&, const zeus::CVector3f&, std::unique_ptr&&, std::unique_ptr&&, std::unique_ptr&&); explicit CNode(CInputStream&); bool WasHit() const { return x4c_hit; } void SetHit(bool h) { x4c_hit = h; } const CNode& GetLeft() const { return *x40_left; } const CNode& GetRight() const { return *x44_right; } const CLeafData& GetLeafData() const { return *x48_leaf; } const zeus::COBBox& GetOBB() const { return x0_obb; } size_t GetMemoryUsage() const; bool IsLeaf() const { return x3c_isLeaf; } }; private: u32 x0_magic = 0; u32 x4_version = 0; u32 x8_memsize = 0; /* CSimpleAllocator xc_ We're not using this but lets keep track*/ SIndexData x18_indexData; std::unique_ptr x88_root; public: COBBTree() = default; explicit COBBTree(CInputStream&); static std::unique_ptr BuildOrientedBoundingBoxTree(const zeus::CVector3f&, const zeus::CVector3f&); CCollisionSurface GetSurface(u16 idx) const; const u16* GetTriangleEdgeIndices(u16 idx) const { return &x18_indexData.x50_surfaceIndices[idx * 3]; } // In the game binary, this used to use an out pointer for the indices after the index. std::array GetTriangleVertexIndices(u16 idx) const; const CCollisionEdge& GetEdge(int idx) const { return x18_indexData.x40_edges[idx]; } const zeus::CVector3f& GetVert(int idx) const { return x18_indexData.x60_vertices[idx]; } u32 GetVertMaterial(u16 idx) const { return x18_indexData.x0_materials[x18_indexData.x10_vertMaterials[idx]]; } u32 GetEdgeMaterial(u16 idx) const { return x18_indexData.x0_materials[x18_indexData.x20_edgeMaterials[idx]]; } CCollisionSurface GetTransformedSurface(u16 idx, const zeus::CTransform& xf) const; zeus::CAABox CalculateLocalAABox() const; zeus::CAABox CalculateAABox(const zeus::CTransform&) const; const CNode& GetRoot() const { return *x88_root; } }; } // namespace metaforce