2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-07-14 10:05:52 +00:00

Better octree generation density

This commit is contained in:
Jack Andersen 2018-06-23 13:09:16 -10:00
parent bc9d225c89
commit cfe384b5c2
9 changed files with 72 additions and 31 deletions

View File

@ -6,7 +6,8 @@ namespace DataSpec
{ {
logvisor::Module Log("AROTBuilder"); logvisor::Module Log("AROTBuilder");
#define AROT_MAX_LEVEL 6 #define AROT_MAX_LEVEL 10
#define AROT_MIN_SUBDIV 10.f
#define AROT_MIN_MODELS 8 #define AROT_MIN_MODELS 8
#define COLLISION_MIN_NODE_TRIANGLES 8 #define COLLISION_MIN_NODE_TRIANGLES 8
#define PATH_MIN_NODE_REGIONS 16 #define PATH_MIN_NODE_REGIONS 16
@ -57,6 +58,17 @@ static zeus::CAABox SplitAABB(const zeus::CAABox& aabb, int i)
} }
} }
void AROTBuilder::Node::mergeSets(int a, int b)
{
childNodes[a].childIndices.insert(childNodes[b].childIndices.cbegin(), childNodes[b].childIndices.cend());
childNodes[b].childIndices = childNodes[a].childIndices;
}
bool AROTBuilder::Node::compareSets(int a, int b) const
{
return childNodes[a].childIndices != childNodes[b].childIndices;
}
void AROTBuilder::Node::addChild(int level, int minChildren, const std::vector<zeus::CAABox>& triBoxes, void AROTBuilder::Node::addChild(int level, int minChildren, const std::vector<zeus::CAABox>& triBoxes,
const zeus::CAABox& curAABB, BspNodeType& typeOut) const zeus::CAABox& curAABB, BspNodeType& typeOut)
{ {
@ -65,13 +77,16 @@ void AROTBuilder::Node::addChild(int level, int minChildren, const std::vector<z
if (triBoxes[i].intersects(curAABB)) if (triBoxes[i].intersects(curAABB))
childIndices.insert(i); childIndices.insert(i);
zeus::CVector3f extents = curAABB.extents();
/* Return early if empty, triangle intersection below performance threshold, or at max level */ /* Return early if empty, triangle intersection below performance threshold, or at max level */
if (childIndices.empty()) if (childIndices.empty())
{ {
typeOut = BspNodeType::Invalid; typeOut = BspNodeType::Invalid;
return; return;
} }
else if (childIndices.size() < minChildren || level == AROT_MAX_LEVEL) else if (childIndices.size() < minChildren || level == AROT_MAX_LEVEL ||
std::max(extents.x, std::max(extents.y, extents.z)) < AROT_MIN_SUBDIV)
{ {
typeOut = BspNodeType::Leaf; typeOut = BspNodeType::Leaf;
return; return;
@ -87,22 +102,45 @@ void AROTBuilder::Node::addChild(int level, int minChildren, const std::vector<z
flags |= int(chType) << (i * 2); flags |= int(chType) << (i * 2);
} }
/* Unsubdivide minimum axis dimensions */
if (extents.x < AROT_MIN_SUBDIV)
{
mergeSets(0, 1);
mergeSets(4, 5);
mergeSets(2, 3);
mergeSets(6, 7);
}
if (extents.y < AROT_MIN_SUBDIV)
{
mergeSets(0, 2);
mergeSets(1, 3);
mergeSets(4, 6);
mergeSets(5, 7);
}
if (extents.z < AROT_MIN_SUBDIV)
{
mergeSets(0, 4);
mergeSets(1, 5);
mergeSets(2, 6);
mergeSets(3, 7);
}
/* Unsubdivide */ /* Unsubdivide */
compSubdivs = 0; compSubdivs = 0;
if (childNodes[0].childIndices != childNodes[1].childIndices || if (compareSets(0, 1) ||
childNodes[4].childIndices != childNodes[5].childIndices || compareSets(4, 5) ||
childNodes[2].childIndices != childNodes[3].childIndices || compareSets(2, 3) ||
childNodes[6].childIndices != childNodes[7].childIndices) compareSets(6, 7))
compSubdivs |= 0x4; compSubdivs |= 0x4;
if (childNodes[0].childIndices != childNodes[2].childIndices || if (compareSets(0, 2) ||
childNodes[1].childIndices != childNodes[3].childIndices || compareSets(1, 3) ||
childNodes[4].childIndices != childNodes[6].childIndices || compareSets(4, 6) ||
childNodes[5].childIndices != childNodes[7].childIndices) compareSets(5, 7))
compSubdivs |= 0x2; compSubdivs |= 0x2;
if (childNodes[0].childIndices != childNodes[4].childIndices || if (compareSets(0, 4) ||
childNodes[1].childIndices != childNodes[5].childIndices || compareSets(1, 5) ||
childNodes[2].childIndices != childNodes[6].childIndices || compareSets(2, 6) ||
childNodes[3].childIndices != childNodes[7].childIndices) compareSets(3, 7))
compSubdivs |= 0x1; compSubdivs |= 0x1;
if (!compSubdivs) if (!compSubdivs)

View File

@ -37,6 +37,8 @@ struct AROTBuilder
void addChild(int level, int minChildren, const std::vector<zeus::CAABox>& triBoxes, void addChild(int level, int minChildren, const std::vector<zeus::CAABox>& triBoxes,
const zeus::CAABox& curAABB, BspNodeType& typeOut); const zeus::CAABox& curAABB, BspNodeType& typeOut);
void mergeSets(int a, int b);
bool compareSets(int a, int b) const;
void nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPool, size_t& curOff); void nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPool, size_t& curOff);
void writeIndirectionTable(athena::io::MemoryWriter& w); void writeIndirectionTable(athena::io::MemoryWriter& w);
void writeNodes(athena::io::MemoryWriter& w, int nodeIdx); void writeNodes(athena::io::MemoryWriter& w, int nodeIdx);

View File

@ -523,7 +523,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath,
#if DUMP_OCTREE #if DUMP_OCTREE
hecl::blender::Connection& conn = btok.getBlenderConnection(); hecl::blender::Connection& conn = btok.getBlenderConnection();
if (!conn.createBlend(inPath.getWithExtension(_S(".octree.blend"), true), hecl::blender::Connection::BlendType::Area)) if (!conn.createBlend(inPath.getWithExtension(_S(".octree.blend"), true), hecl::blender::BlendType::Area))
return false; return false;
/* Open Py Stream and read sections */ /* Open Py Stream and read sections */
@ -594,7 +594,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath,
#if DUMP_OCTREE #if DUMP_OCTREE
hecl::blender::Connection& conn = btok.getBlenderConnection(); hecl::blender::Connection& conn = btok.getBlenderConnection();
if (!conn.createBlend(inPath.getWithExtension(_S(".octree.blend"), true), hecl::blender::Connection::BlendType::Area)) if (!conn.createBlend(inPath.getWithExtension(_S(".coctree.blend"), true), hecl::blender::BlendType::Area))
return false; return false;
/* Open Py Stream and read sections */ /* Open Py Stream and read sections */

View File

@ -173,7 +173,7 @@ CMetroidAreaCollider::COctreeLeafCache::COctreeLeafCache(const CAreaOctTree& oct
void CMetroidAreaCollider::COctreeLeafCache::AddLeaf(const CAreaOctTree::Node& node) void CMetroidAreaCollider::COctreeLeafCache::AddLeaf(const CAreaOctTree::Node& node)
{ {
if (x4_nodeCache.size() == 64) if (x4_nodeCache.size() == x4_nodeCache.capacity())
{ {
x908_24_overflow = true; x908_24_overflow = true;
return; return;
@ -187,13 +187,13 @@ void CMetroidAreaCollider::BuildOctreeLeafCache(const CAreaOctTree::Node& node,
{ {
for (int i=0 ; i<8 ; ++i) for (int i=0 ; i<8 ; ++i)
{ {
u16 flags = (node.GetChildFlags() >> (i * 2)) & 0x3; CAreaOctTree::Node::ETreeType type = node.GetChildType(i);
if (flags) if (type != CAreaOctTree::Node::ETreeType::Invalid)
{ {
CAreaOctTree::Node ch = node.GetChild(i); CAreaOctTree::Node ch = node.GetChild(i);
if (aabb.intersects(ch.GetBoundingBox())) if (aabb.intersects(ch.GetBoundingBox()))
{ {
if (flags == 0x2) if (type == CAreaOctTree::Node::ETreeType::Leaf)
cache.AddLeaf(ch); cache.AddLeaf(ch);
else else
BuildOctreeLeafCache(ch, aabb, cache); BuildOctreeLeafCache(ch, aabb, cache);

View File

@ -1414,7 +1414,7 @@ void CBooRenderer::FindOverlappingWorldModels(std::vector<u32>& modelBits, const
u32 wordModel = 0; u32 wordModel = 0;
for (int i=0 ; i<item.x4_octTree->x14_bitmapWordCount ; ++i, wordModel += 32) for (int i=0 ; i<item.x4_octTree->x14_bitmapWordCount ; ++i, wordModel += 32)
{ {
u32& word = modelBits[i]; u32& word = modelBits[curWord + i];
if (!word) if (!word)
continue; continue;
for (int j=0 ; j<32 ; ++j) for (int j=0 ; j<32 ; ++j)
@ -1450,7 +1450,7 @@ int CBooRenderer::DrawOverlappingWorldModelIDs(int alphaVal, const std::vector<u
u32 wordModel = 0; u32 wordModel = 0;
for (int i=0 ; i<item.x4_octTree->x14_bitmapWordCount ; ++i, wordModel += 32) for (int i=0 ; i<item.x4_octTree->x14_bitmapWordCount ; ++i, wordModel += 32)
{ {
const u32& word = modelBits[i]; const u32& word = modelBits[curWord + i];
if (!word) if (!word)
continue; continue;
for (int j=0 ; j<32 ; ++j) for (int j=0 ; j<32 ; ++j)
@ -1493,7 +1493,7 @@ void CBooRenderer::DrawOverlappingWorldModelShadows(int alphaVal, const std::vec
u32 wordModel = 0; u32 wordModel = 0;
for (int i=0 ; i<item.x4_octTree->x14_bitmapWordCount ; ++i, wordModel += 32) for (int i=0 ; i<item.x4_octTree->x14_bitmapWordCount ; ++i, wordModel += 32)
{ {
const u32& word = modelBits[i]; const u32& word = modelBits[curWord + i];
if (!word) if (!word)
continue; continue;
for (int j=0 ; j<32 ; ++j) for (int j=0 ; j<32 ; ++j)

View File

@ -17,10 +17,10 @@ CRandomStaticFilter::CRandomStaticFilter(EFilterType type, bool cookieCutter)
zeus::CVector2f m_uv; zeus::CVector2f m_uv;
} verts[4] = } verts[4] =
{ {
{{-1.0, -1.0}, {0.0, 0.0}}, {{-1.f, -1.f}, {0.f, 0.f}},
{{-1.0, 1.0}, {0.0, 448.0}}, {{-1.f, 1.f}, {0.f, 448.f}},
{{ 1.0, -1.0}, {640.0, 0.0}}, {{ 1.f, -1.f}, {640.f, 0.f}},
{{ 1.0, 1.0}, {640.0, 448.0}}, {{ 1.f, 1.f}, {640.f, 448.f}},
}; };
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, sizeof(Vert), 4); m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, sizeof(Vert), 4);
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1);
@ -32,7 +32,7 @@ CRandomStaticFilter::CRandomStaticFilter(EFilterType type, bool cookieCutter)
void CRandomStaticFilter::draw(const zeus::CColor& color, float t) void CRandomStaticFilter::draw(const zeus::CColor& color, float t)
{ {
m_uniform.color = color; m_uniform.color = color;
m_uniform.randOff = ROUND_UP_32(rand() * 32767 / RAND_MAX); m_uniform.randOff = ROUND_UP_32(int64_t(rand()) * 32767 / RAND_MAX);
m_uniform.discardThres = 1.f - t; m_uniform.discardThres = 1.f - t;
m_uniBuf->load(&m_uniform, sizeof(Uniform)); m_uniBuf->load(&m_uniform, sizeof(Uniform));

View File

@ -2006,7 +2006,7 @@ CFrontEndUI::CFrontEndUI()
m->ResetGameState(); m->ResetGameState();
g_GameState->SetCurrentWorldId(g_ResFactory->TranslateOriginalToNew(g_DefaultWorldTag.id)); g_GameState->SetCurrentWorldId(g_ResFactory->TranslateOriginalToNew(g_DefaultWorldTag.id));
g_GameState->CurrentWorldState().SetAreaId(0); g_GameState->CurrentWorldState().SetAreaId(4);
g_GameState->GameOptions().ResetToDefaults(); g_GameState->GameOptions().ResetToDefaults();
g_GameState->WriteBackupBuf(); g_GameState->WriteBackupBuf();

View File

@ -1218,7 +1218,8 @@ void CSamusHud::LeaveFirstPerson(const CStateManager& mgr)
EHudState CSamusHud::GetDesiredHudState(const CStateManager& mgr) EHudState CSamusHud::GetDesiredHudState(const CStateManager& mgr)
{ {
if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed || if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed ||
mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphing) mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphing ||
mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Unmorphing)
return EHudState::Ball; return EHudState::Ball;
switch (mgr.GetPlayerState()->GetTransitioningVisor()) switch (mgr.GetPlayerState()->GetTransitioningVisor())

@ -1 +1 @@
Subproject commit 7d36a59969777f72ccc45b446b2637f88a33e6ac Subproject commit 88a4a52d82f0a60e46181d0bf60e4d4d2ceee02c