metaforce/Runtime/Collision/CAreaOctTree.hpp

148 lines
4.4 KiB
C++
Raw Normal View History

2016-04-13 06:07:23 +00:00
#ifndef __URDE_CAREAOCTTREE_HPP__
#define __URDE_CAREAOCTTREE_HPP__
2015-08-21 00:06:39 +00:00
2016-07-26 22:45:01 +00:00
#include "RetroTypes.hpp"
#include "zeus/CAABox.hpp"
2016-08-05 20:26:23 +00:00
#include "Collision/CCollisionEdge.hpp"
2017-03-29 02:51:12 +00:00
#include "Collision/CCollisionSurface.hpp"
2016-07-26 22:45:01 +00:00
2016-03-04 23:04:53 +00:00
namespace urde
2015-08-21 00:06:39 +00:00
{
2016-07-26 22:45:01 +00:00
class CMaterialFilter;
2015-08-21 00:06:39 +00:00
class CAreaOctTree
{
2016-07-28 04:55:06 +00:00
friend class CBooRenderer;
2016-07-26 22:45:01 +00:00
public:
struct SRayResult
{
2017-03-29 02:51:12 +00:00
zeus::CPlane x0_plane;
rstl::optional_object<CCollisionSurface> x10_surface;
float x3c_;
2016-07-26 22:45:01 +00:00
};
class TriListReference
{
2016-08-05 21:44:19 +00:00
u16 m_count;
std::unique_ptr<u16[]> m_refs;
2016-07-26 22:45:01 +00:00
public:
2016-08-05 21:44:19 +00:00
TriListReference(const u16* ptr)
: m_count(ptr[0])
{
m_refs.reset(new u16[m_count]);
for (u16 i=0 ; i<m_count ; ++i)
m_refs[i] = ptr[i+1];
}
u16 GetAt(int idx) const { return m_refs[idx]; }
u16 GetSize() const { return m_count; }
2016-07-26 22:45:01 +00:00
};
class Node
{
public:
enum class ETreeType
{
Invalid,
Branch,
Leaf
};
private:
2016-08-05 21:44:19 +00:00
const u8* m_ptr;
zeus::CAABox m_aabb;
const CAreaOctTree& m_owner;
ETreeType m_nodeType;
2016-07-28 04:55:06 +00:00
2017-03-29 02:51:12 +00:00
bool LineTestInternal(const zeus::CLineSeg&, const CMaterialFilter&, float, float, float,
const zeus::CVector3f&) const;
bool LineTestExInternal(const zeus::CLineSeg&, const CMaterialFilter&, SRayResult&, float, float, float,
const zeus::CVector3f&) const;
2016-07-26 22:45:01 +00:00
public:
2016-08-05 21:44:19 +00:00
Node(const void* ptr, const zeus::CAABox& aabb,
const CAreaOctTree& owner, ETreeType type)
: m_ptr(reinterpret_cast<const u8*>(ptr)), m_aabb(aabb), m_owner(owner), m_nodeType(type)
{
}
2017-03-29 02:51:12 +00:00
bool LineTest(const zeus::CLineSeg&, const CMaterialFilter&, float) const;
bool LineTestEx(const zeus::CLineSeg&, const CMaterialFilter&, SRayResult&, float) const;
2016-07-26 22:45:01 +00:00
2016-08-05 21:44:19 +00:00
const CAreaOctTree& GetOwner() const
{
return m_owner;
}
const zeus::CAABox& GetBoundingBox() const
{
return m_aabb;
}
u16 GetChildFlags() const
{
return *reinterpret_cast<const u16*>(m_ptr);
}
Node GetChild(int idx) const;
TriListReference GetTriangleArray() const
{
return TriListReference(reinterpret_cast<const u16*>(m_ptr + 24));
}
ETreeType GetChildType(int idx) const
{
u16 flags = *reinterpret_cast<const u16*>(m_ptr);
return ETreeType((flags << (2 * idx)) & 0x3);
}
ETreeType GetTreeType() const { return m_nodeType; }
2016-07-26 22:45:01 +00:00
};
2016-08-05 20:26:23 +00:00
zeus::CAABox x0_aabb;
Node::ETreeType x18_treeType;
const u8* x1c_buf;
2017-02-28 07:31:14 +00:00
const u8* x20_treeBuf;
2016-08-05 20:26:23 +00:00
u32 x24_matCount;
2017-02-28 07:31:14 +00:00
const u32* x28_materials;
const u8* x2c_vertMats;
const u8* x30_edgeMats;
const u8* x34_polyMats;
2016-08-05 20:26:23 +00:00
u32 x38_edgeCount;
2017-02-28 07:31:14 +00:00
const CCollisionEdge* x3c_edges;
2016-08-05 20:26:23 +00:00
u32 x40_polyCount;
2017-02-28 07:31:14 +00:00
const u16* x44_polyEdges;
2016-08-05 20:26:23 +00:00
u32 x48_vertCount;
2017-02-28 07:31:14 +00:00
const float* x4c_verts;
2016-07-28 04:55:06 +00:00
2016-08-05 21:44:19 +00:00
void SwapTreeNode(u8* ptr, Node::ETreeType type);
2016-07-26 22:45:01 +00:00
public:
2017-02-28 07:31:14 +00:00
CAreaOctTree(const zeus::CAABox& aabb, Node::ETreeType treeType, const u8* buf, const u8* treeBuf,
u32 matCount, const u32* materials, const u8* vertMats, const u8* edgeMats, const u8* polyMats,
u32 edgeCount, const CCollisionEdge* edges, u32 polyCount, const u16* polyEdges,
2017-02-28 07:31:14 +00:00
u32 vertCount, const float* verts);
2016-07-26 22:45:01 +00:00
2017-02-28 07:31:14 +00:00
Node GetRootNode() const { return Node(x20_treeBuf, x0_aabb, *this, x18_treeType); }
const u8* GetTreeMemory() const { return x20_treeBuf; }
zeus::CVector3f GetVert(int idx) const
{
const float* vert = &x4c_verts[idx * 3];
return zeus::CVector3f(vert[0], vert[1], vert[2]);
}
2016-08-05 21:44:19 +00:00
const CCollisionEdge& GetEdge(int idx) const { return x3c_edges[idx]; }
u32 GetEdgeMaterial(int idx) const { return x28_materials[x30_edgeMats[idx]]; }
u32 GetTriangleMaterial(int idx) const { return x28_materials[x34_polyMats[idx]]; }
u32 GetNumEdges() const { return x38_edgeCount; }
u32 GetNumVerts() const { return x48_vertCount; }
u32 GetNumTriangles() const { return x40_polyCount; }
const u16* GetMasterListTriangle(u16 idx) const;
const u16* GetTriangleVertexIndices(u16 idx) const;
const u16* GetTriangleEdgeIndices(u16 idx) const;
2016-07-26 22:45:01 +00:00
2017-02-28 07:31:14 +00:00
static std::unique_ptr<CAreaOctTree> MakeFromMemory(const u8* buf, unsigned int size);
2015-08-21 00:06:39 +00:00
};
}
2016-04-13 06:07:23 +00:00
#endif // __URDE_CAREAOCTTREE_HPP__