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");
#define AROT_MAX_LEVEL 6
#define AROT_MAX_LEVEL 10
#define AROT_MIN_SUBDIV 10.f
#define AROT_MIN_MODELS 8
#define COLLISION_MIN_NODE_TRIANGLES 8
#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,
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))
childIndices.insert(i);
zeus::CVector3f extents = curAABB.extents();
/* Return early if empty, triangle intersection below performance threshold, or at max level */
if (childIndices.empty())
{
typeOut = BspNodeType::Invalid;
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;
return;
@ -87,22 +102,45 @@ void AROTBuilder::Node::addChild(int level, int minChildren, const std::vector<z
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 */
compSubdivs = 0;
if (childNodes[0].childIndices != childNodes[1].childIndices ||
childNodes[4].childIndices != childNodes[5].childIndices ||
childNodes[2].childIndices != childNodes[3].childIndices ||
childNodes[6].childIndices != childNodes[7].childIndices)
if (compareSets(0, 1) ||
compareSets(4, 5) ||
compareSets(2, 3) ||
compareSets(6, 7))
compSubdivs |= 0x4;
if (childNodes[0].childIndices != childNodes[2].childIndices ||
childNodes[1].childIndices != childNodes[3].childIndices ||
childNodes[4].childIndices != childNodes[6].childIndices ||
childNodes[5].childIndices != childNodes[7].childIndices)
if (compareSets(0, 2) ||
compareSets(1, 3) ||
compareSets(4, 6) ||
compareSets(5, 7))
compSubdivs |= 0x2;
if (childNodes[0].childIndices != childNodes[4].childIndices ||
childNodes[1].childIndices != childNodes[5].childIndices ||
childNodes[2].childIndices != childNodes[6].childIndices ||
childNodes[3].childIndices != childNodes[7].childIndices)
if (compareSets(0, 4) ||
compareSets(1, 5) ||
compareSets(2, 6) ||
compareSets(3, 7))
compSubdivs |= 0x1;
if (!compSubdivs)

View File

@ -37,6 +37,8 @@ struct AROTBuilder
void addChild(int level, int minChildren, const std::vector<zeus::CAABox>& triBoxes,
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 writeIndirectionTable(athena::io::MemoryWriter& w);
void writeNodes(athena::io::MemoryWriter& w, int nodeIdx);

View File

@ -523,7 +523,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath,
#if DUMP_OCTREE
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;
/* Open Py Stream and read sections */
@ -594,7 +594,7 @@ bool MREA::Cook(const hecl::ProjectPath& outPath,
#if DUMP_OCTREE
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;
/* 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)
{
if (x4_nodeCache.size() == 64)
if (x4_nodeCache.size() == x4_nodeCache.capacity())
{
x908_24_overflow = true;
return;
@ -187,13 +187,13 @@ void CMetroidAreaCollider::BuildOctreeLeafCache(const CAreaOctTree::Node& node,
{
for (int i=0 ; i<8 ; ++i)
{
u16 flags = (node.GetChildFlags() >> (i * 2)) & 0x3;
if (flags)
CAreaOctTree::Node::ETreeType type = node.GetChildType(i);
if (type != CAreaOctTree::Node::ETreeType::Invalid)
{
CAreaOctTree::Node ch = node.GetChild(i);
if (aabb.intersects(ch.GetBoundingBox()))
{
if (flags == 0x2)
if (type == CAreaOctTree::Node::ETreeType::Leaf)
cache.AddLeaf(ch);
else
BuildOctreeLeafCache(ch, aabb, cache);

View File

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

View File

@ -17,10 +17,10 @@ CRandomStaticFilter::CRandomStaticFilter(EFilterType type, bool cookieCutter)
zeus::CVector2f m_uv;
} verts[4] =
{
{{-1.0, -1.0}, {0.0, 0.0}},
{{-1.0, 1.0}, {0.0, 448.0}},
{{ 1.0, -1.0}, {640.0, 0.0}},
{{ 1.0, 1.0}, {640.0, 448.0}},
{{-1.f, -1.f}, {0.f, 0.f}},
{{-1.f, 1.f}, {0.f, 448.f}},
{{ 1.f, -1.f}, {640.f, 0.f}},
{{ 1.f, 1.f}, {640.f, 448.f}},
};
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, sizeof(Vert), 4);
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)
{
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_uniBuf->load(&m_uniform, sizeof(Uniform));

View File

@ -2006,7 +2006,7 @@ CFrontEndUI::CFrontEndUI()
m->ResetGameState();
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->WriteBackupBuf();

View File

@ -1218,7 +1218,8 @@ void CSamusHud::LeaveFirstPerson(const CStateManager& mgr)
EHudState CSamusHud::GetDesiredHudState(const CStateManager& mgr)
{
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;
switch (mgr.GetPlayerState()->GetTransitioningVisor())

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