#include "AROTBuilder.hpp" namespace DataSpec { #define AROT_MAX_LEVEL 11 /* These go to 11 */ static const uint32_t AROTChildCounts[] = { 0, 2, 2, 4, 2, 4, 4, 8 }; size_t AROTBuilder::BitmapPool::addIndices(const std::set& indices) { for (size_t i=0 ; i(ptr) = curAABB.min; *reinterpret_cast(ptr + 12) = curAABB.max; athena::io::MemoryWriter w(ptr + 24, INT32_MAX); w.writeUint16Big(childIndices.size()); for (int idx : childIndices) w.writeUint16Big(idx); ptr += 26 + childIndices.size() * 2; } else { uint16_t* pflags = reinterpret_cast(ptr); uint32_t* offsets = reinterpret_cast(ptr + 4); *pflags = 0; for (int i=0 ; i < 1 + ((flags & 0x1) != 0) ; ++i) { for (int j=0 ; j < 1 + ((flags & 0x2) != 0) ; ++j) { for (int k=0 ; k < 1 + ((flags & 0x4) != 0) ; ++k) { int idx = i*4 + j*2 + k; uint32_t thisOffset; uint16_t thisFlags = childNodes[idx].getColRef(thisOffset); if (thisFlags) { *pflags |= thisFlags << (idx * 2); offsets[idx] = thisOffset - nodeOff; } } } } ptr += 36; zeus::CAABox X[2]; if (flags & 0x1) curAABB.splitX(X[0], X[1]); else { X[0] = curAABB; X[1] = curAABB; } for (int i=0 ; i < 1 + ((flags & 0x1) != 0) ; ++i) { zeus::CAABox Y[2]; if (flags & 0x2) X[i].splitY(Y[0], Y[1]); else { Y[0] = X[i]; Y[1] = X[i]; } for (int j=0 ; j < 1 + ((flags & 0x2) != 0) ; ++j) { zeus::CAABox Z[2]; if (flags & 0x4) Y[j].splitZ(Z[0], Z[1]); else { Z[0] = Y[j]; Z[1] = Y[j]; } for (int k=0 ; k < 1 + ((flags & 0x4) != 0) ; ++k) { int idx = i*4 + j*2 + k; childNodes[idx].writeColNodes(ptr, Z[k]); } } } } } } uint16_t AROTBuilder::Node::getColRef(uint32_t& offset) { if (childIndices.size()) { offset = nodeOff; if (childNodes.empty()) return 2; else return 1; } return 0; } void AROTBuilder::build(std::vector>& secs, const zeus::CAABox& fullAabb, const std::vector& meshAabbs, const std::vector& meshes) { for (int i=0 ; i bmpWords; bmpWords.reserve(bmpWordCount); for (const std::set& bmp : bmpPool.m_pool) { bmpWords.clear(); bmpWords.resize(bmpWordCount); auto bmpIt = bmp.cbegin(); if (bmpIt != bmp.cend()) { int curIdx = 0; for (int w=0 ; w, uint32_t> AROTBuilder::buildCol(const ColMesh& mesh, BspNodeType& rootOut) { zeus::CAABox fullAabb(zeus::CVector3f(mesh.aabbMin), zeus::CVector3f(mesh.aabbMax)); int t = 0; for (const ColMesh::Triangle& tri : mesh.trianges) { zeus::CAABox aabb; for (int e=0 ; e<3 ; ++e) { const ColMesh::Edge& edge = mesh.edges[tri.edges[e]]; for (int v=0 ; v<2 ; ++v) { const auto& vert = mesh.verts[edge.verts[v]]; aabb.accumulateBounds(zeus::CVector3f(vert)); } } rootNode.addChild(0, fullAabb, aabb, t); ++t; } size_t totalSize = 0; rootNode.colSize(totalSize); std::unique_ptr ret(new uint8_t[totalSize]); uint32_t dummy; rootOut = BspNodeType(rootNode.getColRef(dummy)); uint8_t* ptr = ret.get(); rootNode.writeColNodes(ptr, fullAabb); return {std::move(ret), totalSize}; } }