From a299d96a8b1789eeb31d0eb90cc8e08c017e3ec0 Mon Sep 17 00:00:00 2001 From: Kevin <136357605+energydrink02@users.noreply.github.com> Date: Fri, 28 Nov 2025 12:54:42 +0100 Subject: [PATCH] xPartition: 100% match --- configure.py | 2 +- src/SB/Core/gc/iEnv.h | 5 ++ src/SB/Core/x/xEnv.h | 5 ++ src/SB/Core/x/xPartition.cpp | 159 +++++++++++++++++++++++++++++++++-- src/SB/Core/x/xPartition.h | 14 ++- 5 files changed, 171 insertions(+), 14 deletions(-) diff --git a/configure.py b/configure.py index 8dd1206bb..eb9fae2af 100644 --- a/configure.py +++ b/configure.py @@ -448,7 +448,7 @@ def MatchingFor(*versions): Object(NonMatching, "SB/Core/x/xParCmd.cpp"), Object(Matching, "SB/Core/x/xParGroup.cpp"), Object(Matching, "SB/Core/x/xParMgr.cpp"), - Object(NonMatching, "SB/Core/x/xPartition.cpp"), + Object(Matching, "SB/Core/x/xPartition.cpp", extra_cflags=["-sym on"]), Object(NonMatching, "SB/Core/x/xpkrsvc.cpp"), Object(NonMatching, "SB/Core/x/xQuickCull.cpp"), Object(Matching, "SB/Core/x/xsavegame.cpp"), diff --git a/src/SB/Core/gc/iEnv.h b/src/SB/Core/gc/iEnv.h index acceb7a9f..94e4d5ace 100644 --- a/src/SB/Core/gc/iEnv.h +++ b/src/SB/Core/gc/iEnv.h @@ -27,4 +27,9 @@ void iEnvLightingBasics(iEnv*, xEnvAsset*); void iEnvRender(iEnv* env); void iEnvEndRenderFX(iEnv*); +inline RwBBox* iEnvGetBBox(iEnv* r3) +{ + return &r3->world->boundingBox; +} + #endif diff --git a/src/SB/Core/x/xEnv.h b/src/SB/Core/x/xEnv.h index a64c5b119..0fc4dee11 100644 --- a/src/SB/Core/x/xEnv.h +++ b/src/SB/Core/x/xEnv.h @@ -36,4 +36,9 @@ void xEnvFree(xEnv* env); void xEnvSetup(xEnv* env); void xEnvRender(xEnv* env); +inline RwBBox* xEnvGetBBox(xEnv* r3) +{ + return iEnvGetBBox(r3->geom); +} + #endif diff --git a/src/SB/Core/x/xPartition.cpp b/src/SB/Core/x/xPartition.cpp index 8d7f412a3..c556d6930 100644 --- a/src/SB/Core/x/xPartition.cpp +++ b/src/SB/Core/x/xPartition.cpp @@ -6,17 +6,17 @@ void xPartitionReset() { } -_tagPartLink* PartitionGetFreeLink() +static _tagPartLink* PartitionGetFreeLink() { return (_tagPartLink*)xMemAllocSize(sizeof(_tagPartLink)); } -void PartitionSpaceReset(_tagPartSpace* space) +static void PartitionSpaceReset(_tagPartSpace* space) { memset(space, 0, sizeof(_tagPartSpace)); } -void PartitionSpaceInsert(_tagPartSpace* space, void* data) +static void PartitionSpaceInsert(_tagPartSpace* space, void* data) { space->total++; _tagPartLink* head = &space->head; @@ -31,10 +31,159 @@ void PartitionSpaceInsert(_tagPartSpace* space, void* data) tmp->next->next = NULL; } -// Need to figure out the correct order. S32 xPartitionGetTrueIdx(_tagPartition* part, S32 x_spaces, S32 y_spaces, S32 z_spaces) { - return part->total_x * z_spaces + part->total_x * y_spaces * part->total_z + x_spaces; + S32 idx = (y_spaces * (part->total_x * part->total_z)); + idx += part->total_x * z_spaces; + idx += x_spaces; + return idx; +} + +void xPartitionVolume(_tagPartition* part, xVolume* volume, S32 x_spaces, S32 y_spaces, + S32 z_spaces) +{ + memset(part, 0, sizeof(_tagPartition)); + xBound* xb = volume->GetBound(); + xBox* bb = &xb->box.box; + part->min = bb->lower; + part->max = bb->upper; + + F32 dx = part->max.x - part->min.x; + F32 dy = part->max.y - part->min.y; + F32 dz = part->max.z - part->min.z; + + part->total_x = x_spaces; + part->total_y = y_spaces; + part->total_z = z_spaces; + + part->space_dim.x = dx / part->total_x; + part->space_dim.y = dy / part->total_y; + part->space_dim.z = dz / part->total_z; + + part->space = (_tagPartSpace*)xMemAlloc( + gActiveHeap, sizeof(_tagPartSpace) * part->total_x * part->total_y * part->total_z, 0); + + for (S32 z = 0; z < z_spaces; z++) + { + for (S32 y = 0; y < y_spaces; y++) + { + for (S32 x = 0; x < x_spaces; x++) + { + S32 idx = xPartitionGetTrueIdx(part, x, y, z); + PartitionSpaceReset(&part->space[idx]); + } + } + } + + PartitionSpaceReset(&part->global); +} + +void xPartitionWorld(_tagPartition* part, xEnv* env, S32 x_spaces, S32 y_spaces, S32 z_spaces) +{ + memset(part, 0, sizeof(_tagPartition)); + xBox* bb = (xBox*)xEnvGetBBox(env); + part->min = bb->lower; + part->max = bb->upper; + + F32 dx = part->max.x - part->min.x; + F32 dy = part->max.y - part->min.y; + F32 dz = part->max.z - part->min.z; + + part->total_x = x_spaces; + part->total_y = y_spaces; + part->total_z = z_spaces; + + part->space_dim.x = dx / part->total_x; + part->space_dim.y = dy / part->total_y; + part->space_dim.z = dz / part->total_z; + + part->space = (_tagPartSpace*)xMemAlloc( + gActiveHeap, sizeof(_tagPartSpace) * part->total_x * part->total_y * part->total_z, 0); + + for (S32 z = 0; z < z_spaces; z++) + { + for (S32 y = 0; y < y_spaces; y++) + { + for (S32 x = 0; x < x_spaces; x++) + { + S32 idx = xPartitionGetTrueIdx(part, x, y, z); + PartitionSpaceReset(&part->space[idx]); + } + } + } + + PartitionSpaceReset(&part->global); +} + +S32 xPartitionInsert(_tagPartition* part, void* insert_data, xVec3* insert_pos) +{ + if (insert_pos->x < part->min.x || insert_pos->x > part->max.x || insert_pos->y < part->min.y || + insert_pos->y > part->max.y || insert_pos->z < part->min.z || insert_pos->z > part->max.z) + { + PartitionSpaceInsert(&part->global, insert_data); + return -1; + } + + S32 idx = xPartitionGetTrueIdx(part, (insert_pos->x - part->min.x) / part->space_dim.x, + (insert_pos->y - part->min.y) / part->space_dim.y, + (insert_pos->z - part->min.z) / part->space_dim.z); + PartitionSpaceInsert(&part->space[idx], insert_data); + + return idx; +} + +S32 xPartitionUpdate(_tagPartition* part, void* data, S32 old_idx, xVec3* current_pos) +{ + S32 cur_idx; + + if (current_pos->x < part->min.x || current_pos->x > part->max.x || + current_pos->y < part->min.y || current_pos->y > part->max.y || + current_pos->z < part->min.z || current_pos->z > part->max.z) + { + cur_idx = -1; + } + else + { + cur_idx = xPartitionGetTrueIdx(part, (current_pos->x - part->min.x) / part->space_dim.x, + (current_pos->y - part->min.y) / part->space_dim.y, + (current_pos->z - part->min.z) / part->space_dim.z); + } + + if (old_idx == cur_idx) + return cur_idx; + + _tagPartSpace* src = old_idx == -1 ? &part->global : &part->space[old_idx]; + xPartitionSpaceMove(src, cur_idx == -1 ? &part->global : &part->space[cur_idx], (U32)data); + return cur_idx; +} + +void xPartitionSpaceMove(_tagPartSpace* src, _tagPartSpace* dest, U32 data) +{ + _tagPartLink* dest_lnk = &dest->head; + _tagPartLink* src_lnk; + _tagPartLink* src_pre; + + while (dest_lnk->next != NULL) + { + dest_lnk = dest_lnk->next; + } + + src_lnk = &src->head; + src_pre = &src->head; + + while (src_lnk->data != (void*)data) + { + src_pre = src_lnk; + src_lnk = src_lnk->next; + } + + src_pre->next = src_lnk->next; + + dest_lnk->next = src_lnk; + dest_lnk->next->next = NULL; + + src->total--; + dest->total++; } void xPartitionDump(_tagPartition*, char*) diff --git a/src/SB/Core/x/xPartition.h b/src/SB/Core/x/xPartition.h index 6a6edd155..068b96b6d 100644 --- a/src/SB/Core/x/xPartition.h +++ b/src/SB/Core/x/xPartition.h @@ -2,7 +2,6 @@ #define XPARTITION_H #include -#include "xMath3.h" #include "xEnv.h" #include "xVolume.h" @@ -31,16 +30,15 @@ struct _tagPartition }; void xPartitionReset(); -_tagPartLink* PartitionGetFreeLink(); -void PartitionSpaceReset(_tagPartSpace* space); -void PartitionSpaceInsert(_tagPartSpace* space, void* data); S32 xPartitionGetTrueIdx(_tagPartition* part, S32 x_spaces, S32 y_spaces, S32 z_spaces); -void xPartitionWorld(_tagPartition* part, xEnv* env, S32 x_spaces, S32 y_spaces, - S32 z_spaces); void xPartitionVolume(_tagPartition* part, xVolume* volume, S32 x_spaces, S32 y_spaces, S32 z_spaces); -void xPartitionDump(_tagPartition* part, char* string); -S32 xPartitionUpdate(_tagPartition* part, void* data, S32 old_idx, xVec3* current_pos); +void xPartitionWorld(_tagPartition* part, xEnv* env, S32 x_spaces, S32 y_spaces, + S32 z_spaces); S32 xPartitionInsert(_tagPartition* part, void* insert_data, xVec3* insert_pos); +S32 xPartitionUpdate(_tagPartition* part, void* data, S32 old_idx, xVec3* current_pos); +void xPartitionSpaceMove(_tagPartSpace* src, _tagPartSpace* dest, U32 data); +void xPartitionDump(_tagPartition*, char*); + #endif