2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-05-13 15:11:22 +00:00
metaforce/Runtime/Collision/COBBTree.hpp
Lioncash e76804079d COBBTree: Return std::array from GetTriangleVertexIndices() directly
While the game binary uses an out pointer here, we can slightly modify
it in this case in order to make it more difficult to misuse the
call-sites by returning the data directly as a std::array.
2020-04-06 01:17:24 -04:00

97 lines
3.2 KiB
C++

#pragma once
#include <array>
#include <memory>
#include <vector>
#include "Runtime/RetroTypes.hpp"
#include "Runtime/Collision/CCollisionEdge.hpp"
#include "Runtime/Collision/CCollisionSurface.hpp"
#include <zeus/COBBox.hpp>
#include <zeus/CVector3f.hpp>
namespace urde {
class CCollidableOBBTreeGroupContainer;
class COBBTree {
public:
struct SIndexData {
std::vector<u32> x0_materials;
std::vector<u8> x10_vertMaterials;
std::vector<u8> x20_edgeMaterials;
std::vector<u8> x30_surfaceMaterials;
std::vector<CCollisionEdge> x40_edges;
std::vector<u16> x50_surfaceIndices;
std::vector<zeus::CVector3f> x60_vertices;
SIndexData() = default;
explicit SIndexData(CInputStream&);
};
class CLeafData {
std::vector<u16> x0_surface;
public:
CLeafData() = default;
explicit CLeafData(std::vector<u16>&& surface);
explicit CLeafData(CInputStream&);
const std::vector<u16>& GetSurfaceVector() const;
size_t GetMemoryUsage() const;
};
class CNode {
zeus::COBBox x0_obb;
bool x3c_isLeaf = false;
std::unique_ptr<CNode> x40_left;
std::unique_ptr<CNode> x44_right;
std::unique_ptr<CLeafData> x48_leaf;
bool x4c_hit = false;
public:
CNode() = default;
CNode(const zeus::CTransform&, const zeus::CVector3f&, std::unique_ptr<CNode>&&, std::unique_ptr<CNode>&&,
std::unique_ptr<CLeafData>&&);
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<CNode> x88_root;
public:
COBBTree() = default;
explicit COBBTree(CInputStream&);
static std::unique_ptr<COBBTree> 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<u16, 3> 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 urde