More CAreaOctTree imps

This commit is contained in:
Jack Andersen 2016-08-05 11:44:19 -10:00
parent 2eb77b9a7a
commit 204969965e
2 changed files with 187 additions and 35 deletions

View File

@ -3,23 +3,135 @@
namespace urde
{
CAreaOctTree::CAreaOctTree(const zeus::CAABox& aabb, Node::ETreeType treeType, u8* buf, void* treeBuf,
CAreaOctTree::Node CAreaOctTree::Node::GetChild(int idx) const
{
u16 flags = *reinterpret_cast<const u16*>(m_ptr);
const u32* offsets = reinterpret_cast<const u32*>(m_ptr + 4);
ETreeType type = ETreeType((flags << (2 * idx)) & 0x3);
if (type == ETreeType::Branch)
{
zeus::CAABox pos, neg, res;
m_aabb.splitZ(pos, neg);
if (idx & 4)
{
pos.splitY(pos, neg);
if (idx & 2)
{
pos.splitX(pos, neg);
if (idx & 1)
res = pos;
else
res = neg;
}
else
{
neg.splitX(pos, neg);
if (idx & 1)
res = pos;
else
res = neg;
}
}
else
{
neg.splitY(pos, neg);
if (idx & 2)
{
pos.splitX(pos, neg);
if (idx & 1)
res = pos;
else
res = neg;
}
else
{
neg.splitX(pos, neg);
if (idx & 1)
res = pos;
else
res = neg;
}
}
return Node(m_ptr + offsets[idx] + 36, res, m_owner, ETreeType::Branch);
}
else if (type == ETreeType::Leaf)
{
const zeus::CAABox* aabb = reinterpret_cast<const zeus::CAABox*>(m_ptr + offsets[idx] + 36);
return Node(aabb, *aabb, m_owner, ETreeType::Leaf);
}
else
{
return Node(nullptr, zeus::CAABox::skNullBox, m_owner, ETreeType::Invalid);
}
}
void CAreaOctTree::SwapTreeNode(u8* ptr, Node::ETreeType type)
{
if (type == Node::ETreeType::Branch)
{
u16* typeBits = reinterpret_cast<u16*>(ptr);
*typeBits = hecl::SBig(*typeBits);
for (int i=0 ; i<8 ; ++i)
{
Node::ETreeType ctype = Node::ETreeType((*typeBits << (2 * i)) & 0x3);
u32* offsets = reinterpret_cast<u32*>(ptr + 4);
offsets[i] = hecl::SBig(offsets[i]);
SwapTreeNode(ptr + offsets[i] + 36, ctype);
}
}
else if (type == Node::ETreeType::Leaf)
{
zeus::CAABox* aabb = reinterpret_cast<zeus::CAABox*>(ptr);
aabb->min[0] = hecl::SBig(aabb->min[0]);
aabb->min[1] = hecl::SBig(aabb->min[1]);
aabb->min[2] = hecl::SBig(aabb->min[2]);
aabb->max[0] = hecl::SBig(aabb->max[0]);
aabb->max[1] = hecl::SBig(aabb->max[1]);
aabb->max[2] = hecl::SBig(aabb->max[2]);
u16* countIdxs = reinterpret_cast<u16*>(ptr + 24);
*countIdxs = hecl::SBig(*countIdxs);
for (u16 i=0 ; i<*countIdxs ; ++i)
countIdxs[i+1] = hecl::SBig(countIdxs[i+1]);
}
}
CAreaOctTree::CAreaOctTree(const zeus::CAABox& aabb, Node::ETreeType treeType, u8* buf, std::unique_ptr<u8[]>&& treeBuf,
u32 matCount, u32* materials, u8* vertMats, u8* edgeMats, u8* polyMats,
u32 edgeCount, CCollisionEdge* edges, u32 polyCount, u16* polyEdges,
u32 vertCount, zeus::CVector3f* verts)
: x0_aabb(aabb), x18_treeType(treeType), x1c_buf(buf), x20_treeBuf(treeBuf),
x24_matCount(matCount), x28_materials(materials), x2c_vertMats(vertMats),
: x0_aabb(aabb), x18_treeType(treeType), x1c_buf(buf), x20_treeBuf(std::move(treeBuf)),
x24_matCount(matCount), x2c_vertMats(vertMats),
x30_edgeMats(edgeMats), x34_polyMats(polyMats), x38_edgeCount(edgeCount),
x40_polyCount(polyCount), x44_polyEdges(polyEdges),
x40_polyCount(polyCount),
x48_vertCount(vertCount)
{
SwapTreeNode(x20_treeBuf.get(), treeType);
{
x28_materials.reserve(matCount);
athena::io::MemoryReader r(materials, matCount * 4);
for (u32 i=0 ; i<matCount ; ++i)
x28_materials.push_back(r.readUint32Big());
}
{
x3c_edges.reserve(edgeCount);
athena::io::MemoryReader r(edges, edgeCount * 4);
for (u32 i=0 ; i<vertCount ; ++i)
for (u32 i=0 ; i<edgeCount ; ++i)
x3c_edges.emplace_back(r);
}
{
x44_polyEdges.reserve(polyCount);
athena::io::MemoryReader r(polyEdges, polyCount * 2);
for (u32 i=0 ; i<polyCount ; ++i)
x44_polyEdges.push_back(r.readUint16Big());
}
{
x4c_verts.reserve(vertCount);
athena::io::MemoryReader r(verts, vertCount * 12);
@ -39,7 +151,8 @@ std::unique_ptr<CAreaOctTree> CAreaOctTree::MakeFromMemory(void* buf, unsigned i
u32 treeSize = r.readUint32Big();
u8* cur = reinterpret_cast<u8*>(buf) + r.position();
void* treeBuf = cur;
std::unique_ptr<u8[]> treeBuf(new u8[treeSize]);
memmove(treeBuf.get(), cur, treeSize);
cur += treeSize;
u32 matCount = hecl::SBig(*reinterpret_cast<u32*>(cur));
@ -77,7 +190,7 @@ std::unique_ptr<CAreaOctTree> CAreaOctTree::MakeFromMemory(void* buf, unsigned i
zeus::CVector3f* vertBuf = reinterpret_cast<zeus::CVector3f*>(cur);
cur += polyCount * 2;
return std::make_unique<CAreaOctTree>(aabb, nodeType, reinterpret_cast<u8*>(buf), treeBuf,
return std::make_unique<CAreaOctTree>(aabb, nodeType, reinterpret_cast<u8*>(buf), std::move(treeBuf),
matCount, matBuf, vertMatsBuf, edgeMatsBuf, polyMatsBuf,
edgeCount, edgeBuf, polyCount, polyBuf, vertCount, vertBuf);
}

View File

@ -19,11 +19,18 @@ public:
class TriListReference
{
u16 m_count;
std::unique_ptr<u16[]> m_refs;
public:
TriListReference(const void*);
TriListReference(const u16*);
void GetAt(s32) const;
void GetSize() const;
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; }
};
class Node
@ -37,58 +44,90 @@ public:
};
private:
const u8* m_ptr;
zeus::CAABox m_aabb;
const CAreaOctTree& m_owner;
ETreeType m_nodeType;
public:
Node(const void*, const zeus::CAABox&, const CAreaOctTree& owner, ETreeType);
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)
{
}
#if 0
void LineTestEx(const zeus::CLine&, const CMaterialFilter&, SRayResult&, float) const;
void LineTestExInternal(const zeus::CLine&, const CMaterialFilter&, SRayResult&, float, float, float,
const zeus::CVector3f&) const;
#endif
const CAreaOctTree& GetOwner() const;
const zeus::CAABox& GetBoundingBox() const;
u32 GetChildFlags() const;
const Node* GetChild(s32) const;
TriListReference GetTriangleArray() const;
ETreeType GetChildType(s32) const;
ETreeType GetTreeType(s32) const;
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; }
};
zeus::CAABox x0_aabb;
Node::ETreeType x18_treeType;
u8* x1c_buf;
void* x20_treeBuf;
std::unique_ptr<u8[]> x20_treeBuf;
u32 x24_matCount;
u32* x28_materials;
std::vector<u32> x28_materials;
u8* x2c_vertMats;
u8* x30_edgeMats;
u8* x34_polyMats;
u32 x38_edgeCount;
std::vector<CCollisionEdge> x3c_edges;
u32 x40_polyCount;
u16* x44_polyEdges;
std::vector<u16> x44_polyEdges;
u32 x48_vertCount;
std::vector<zeus::CVector3f> x4c_verts;
void SwapTreeNode(u8* ptr, Node::ETreeType type);
public:
CAreaOctTree(const zeus::CAABox& aabb, Node::ETreeType treeType, u8* buf, void* treeBuf,
CAreaOctTree(const zeus::CAABox& aabb, Node::ETreeType treeType, u8* buf, std::unique_ptr<u8[]>&& treeBuf,
u32 matCount, u32* materials, u8* vertMats, u8* edgeMats, u8* polyMats,
u32 edgeCount, CCollisionEdge* edges, u32 polyCount, u16* polyEdges,
u32 vertCount, zeus::CVector3f* verts);
const Node* GetRootNode() const;
void GetTreeMemory() const;
zeus::CVector3f GetVert(s32) const;
CCollisionEdge GetEdge(s32) const;
void GetEdgeMaterial();
void GetTriangleMaterial();
u32 GetNumEdges() const;
u32 GetNumVerts() const;
void GetNumTriangles() const;
void GetMasterListTriangle(u16);
void GetTriangleVertexIndices(u16);
void GetTriangleEdgeIndices(u16);
Node GetRootNode() const { return Node(x20_treeBuf.get(), x0_aabb, *this, x18_treeType); }
const u8* GetTreeMemory() const { return x20_treeBuf.get(); }
const zeus::CVector3f& GetVert(int idx) const { return x4c_verts[idx]; }
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;
static std::unique_ptr<CAreaOctTree> MakeFromMemory(void* buf, unsigned int size);