From 204969965ecd045ecc195fd12fd82996fd77d01f Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Fri, 5 Aug 2016 11:44:19 -1000 Subject: [PATCH] More CAreaOctTree imps --- Runtime/Collision/CAreaOctTree.cpp | 127 +++++++++++++++++++++++++++-- Runtime/Collision/CAreaOctTree.hpp | 95 ++++++++++++++------- 2 files changed, 187 insertions(+), 35 deletions(-) diff --git a/Runtime/Collision/CAreaOctTree.cpp b/Runtime/Collision/CAreaOctTree.cpp index 2e203295c..0e54619e6 100644 --- a/Runtime/Collision/CAreaOctTree.cpp +++ b/Runtime/Collision/CAreaOctTree.cpp @@ -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(m_ptr); + const u32* offsets = reinterpret_cast(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(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(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(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(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(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&& 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 CAreaOctTree::MakeFromMemory(void* buf, unsigned i u32 treeSize = r.readUint32Big(); u8* cur = reinterpret_cast(buf) + r.position(); - void* treeBuf = cur; + std::unique_ptr treeBuf(new u8[treeSize]); + memmove(treeBuf.get(), cur, treeSize); cur += treeSize; u32 matCount = hecl::SBig(*reinterpret_cast(cur)); @@ -77,7 +190,7 @@ std::unique_ptr CAreaOctTree::MakeFromMemory(void* buf, unsigned i zeus::CVector3f* vertBuf = reinterpret_cast(cur); cur += polyCount * 2; - return std::make_unique(aabb, nodeType, reinterpret_cast(buf), treeBuf, + return std::make_unique(aabb, nodeType, reinterpret_cast(buf), std::move(treeBuf), matCount, matBuf, vertMatsBuf, edgeMatsBuf, polyMatsBuf, edgeCount, edgeBuf, polyCount, polyBuf, vertCount, vertBuf); } diff --git a/Runtime/Collision/CAreaOctTree.hpp b/Runtime/Collision/CAreaOctTree.hpp index dd8eb2ab9..e8cef7c7c 100644 --- a/Runtime/Collision/CAreaOctTree.hpp +++ b/Runtime/Collision/CAreaOctTree.hpp @@ -19,11 +19,18 @@ public: class TriListReference { + u16 m_count; + std::unique_ptr 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(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(m_ptr); + } + + Node GetChild(int idx) const; + + TriListReference GetTriangleArray() const + { + return TriListReference(reinterpret_cast(m_ptr + 24)); + } + + ETreeType GetChildType(int idx) const + { + u16 flags = *reinterpret_cast(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 x20_treeBuf; u32 x24_matCount; - u32* x28_materials; + std::vector x28_materials; u8* x2c_vertMats; u8* x30_edgeMats; u8* x34_polyMats; u32 x38_edgeCount; std::vector x3c_edges; u32 x40_polyCount; - u16* x44_polyEdges; + std::vector x44_polyEdges; u32 x48_vertCount; std::vector 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&& 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 MakeFromMemory(void* buf, unsigned int size);