perf(models): skip model hooks for vanilla blocks

This commit is contained in:
Jacobwasbeast
2026-03-11 22:04:41 -05:00
parent a481822593
commit 5871a38fab
3 changed files with 60 additions and 8 deletions

View File

@@ -576,6 +576,8 @@ namespace GameHooks
static bool TryGetModelForState(int blockId, int data, void* levelPtr, int x, int y, int z, const std::vector<ModelBox>*& outBoxes)
{
if (!ModelRegistry::HasModel(blockId))
return false;
if (data < 0)
data = 0;
const int profile = ModelRegistry::GetRotationProfile(blockId);
@@ -3427,7 +3429,7 @@ namespace GameHooks
{
const std::vector<ModelBox>* boxes = nullptr;
int tileId = GetTileId(tilePtr);
if (tileId >= 0)
if (tileId >= 0 && ModelRegistry::HasModel(tileId))
{
int data = forceData;
void* levelPtr = nullptr;
@@ -3456,7 +3458,8 @@ namespace GameHooks
{
const std::vector<ModelBox>* boxes = nullptr;
int tileId = GetTileId(tilePtr);
if (tileId >= 0 && TryGetModelForState(tileId, data, nullptr, 0, 0, 0, boxes) && boxes && !boxes->empty())
if (tileId >= 0 && ModelRegistry::HasModel(tileId) &&
TryGetModelForState(tileId, data, nullptr, 0, 0, 0, boxes) && boxes && !boxes->empty())
{
if (Original_TileRendererRenderTile && Tile_SetShape)
{
@@ -3483,7 +3486,8 @@ namespace GameHooks
const std::vector<ModelBox>* boxes = nullptr;
int tileId = GetTileId(thisPtr);
int data = Level_GetData && levelPtr ? Level_GetData(levelPtr, x, y, z) : 0;
if (tileId >= 0 && TryGetModelForState(tileId, data, levelPtr, x, y, z, boxes) && boxes && !boxes->empty() && AABB_NewTemp && boxesPtr && boxPtr)
if (tileId >= 0 && ModelRegistry::HasModel(tileId) &&
TryGetModelForState(tileId, data, levelPtr, x, y, z, boxes) && boxes && !boxes->empty() && AABB_NewTemp && boxesPtr && boxPtr)
{
auto list = reinterpret_cast<std::vector<void*>*>(boxesPtr);
const AABBRaw* clipBox = reinterpret_cast<const AABBRaw*>(boxPtr);
@@ -3535,7 +3539,8 @@ namespace GameHooks
const std::vector<ModelBox>* boxes = nullptr;
int tileId = GetTileId(thisPtr);
if (tileId >= 0 && ModelRegistry::TryGetModel(tileId, boxes) && boxes && !boxes->empty() && Tile_SetShape)
if (tileId >= 0 && ModelRegistry::HasModel(tileId) &&
ModelRegistry::TryGetModel(tileId, boxes) && boxes && !boxes->empty() && Tile_SetShape)
{
float minX = 0.0f, minY = 0.0f, minZ = 0.0f;
float maxX = 0.0f, maxY = 0.0f, maxZ = 0.0f;
@@ -3581,7 +3586,8 @@ namespace GameHooks
{
const std::vector<ModelBox>* boxes = nullptr;
int tileId = GetTileId(thisPtr);
if (tileId >= 0 && ModelRegistry::TryGetModel(tileId, boxes) && boxes && !boxes->empty())
if (tileId >= 0 && ModelRegistry::HasModel(tileId) &&
ModelRegistry::TryGetModel(tileId, boxes) && boxes && !boxes->empty())
{
if (IsFullCubeModel(*boxes))
return Original_TileIsSolidRender ? Original_TileIsSolidRender(thisPtr, isServerLevel) : true;
@@ -3595,7 +3601,8 @@ namespace GameHooks
{
const std::vector<ModelBox>* boxes = nullptr;
int tileId = GetTileId(thisPtr);
if (tileId >= 0 && ModelRegistry::TryGetModel(tileId, boxes) && boxes && !boxes->empty())
if (tileId >= 0 && ModelRegistry::HasModel(tileId) &&
ModelRegistry::TryGetModel(tileId, boxes) && boxes && !boxes->empty())
{
if (IsFullCubeModel(*boxes))
return Original_TileIsCubeShaped ? Original_TileIsCubeShaped(thisPtr) : true;
@@ -3613,7 +3620,8 @@ namespace GameHooks
const std::vector<ModelBox>* boxes = nullptr;
int tileId = GetTileId(thisPtr);
int data = Level_GetData && levelPtr ? Level_GetData(levelPtr, x, y, z) : 0;
if (tileId < 0 || !TryGetModelForState(tileId, data, levelPtr, x, y, z, boxes) || !boxes || boxes->empty())
if (tileId < 0 || !ModelRegistry::HasModel(tileId) ||
!TryGetModelForState(tileId, data, levelPtr, x, y, z, boxes) || !boxes || boxes->empty())
{
return Original_TileClip ? Original_TileClip(thisPtr, levelPtr, x, y, z, aPtr, bPtr) : nullptr;
}
@@ -3697,7 +3705,8 @@ namespace GameHooks
const std::vector<ModelBox>* boxes = nullptr;
int data = Level_GetData ? Level_GetData(thisPtr, x, y, z) : 0;
if (!TryGetModelForState(tileId, data, thisPtr, x, y, z, boxes) || !boxes || boxes->empty())
if (!ModelRegistry::HasModel(tileId) ||
!TryGetModelForState(tileId, data, thisPtr, x, y, z, boxes) || !boxes || boxes->empty())
continue;
for (const auto& box : *boxes)

View File

@@ -3,9 +3,13 @@
#include <unordered_map>
#include <mutex>
#include <string>
#include <array>
#include <atomic>
namespace
{
constexpr int kFastModelLimit = 4096;
struct BlockModelEntry
{
std::vector<ModelBox> base;
@@ -15,6 +19,13 @@ namespace
std::unordered_map<int, BlockModelEntry> g_models;
std::mutex g_mutex;
std::array<std::atomic<uint8_t>, kFastModelLimit> g_hasModel{};
std::array<std::atomic<int>, kFastModelLimit> g_rotationProfile{};
inline bool IsFastIndex(int blockId)
{
return blockId >= 0 && blockId < kFastModelLimit;
}
}
void ModelRegistry::RegisterBlockModel(int blockId, const ModelBox* boxes, int count)
@@ -32,6 +43,9 @@ void ModelRegistry::RegisterBlockModel(int blockId, const ModelBox* boxes, int c
g_models[blockId].base = std::move(data);
}
if (IsFastIndex(blockId))
g_hasModel[blockId].store(1, std::memory_order_release);
LogUtil::Log("[WeaveLoader] ModelRegistry: registered %d box(es) for block %d", count, blockId);
}
@@ -50,6 +64,9 @@ void ModelRegistry::RegisterBlockModelVariant(int blockId, const char* key, cons
g_models[blockId].variants[std::string(key)] = std::move(data);
}
if (IsFastIndex(blockId))
g_hasModel[blockId].store(1, std::memory_order_release);
LogUtil::Log("[WeaveLoader] ModelRegistry: registered variant '%s' (%d box(es)) for block %d", key, count, blockId);
}
@@ -57,12 +74,33 @@ void ModelRegistry::SetRotationProfile(int blockId, int profile)
{
if (blockId < 0)
return;
if (IsFastIndex(blockId))
g_rotationProfile[blockId].store(profile, std::memory_order_release);
std::lock_guard<std::mutex> guard(g_mutex);
g_models[blockId].rotationProfile = profile;
}
bool ModelRegistry::HasModel(int blockId)
{
if (blockId < 0)
return false;
if (IsFastIndex(blockId))
return g_hasModel[blockId].load(std::memory_order_acquire) != 0;
std::lock_guard<std::mutex> guard(g_mutex);
auto it = g_models.find(blockId);
if (it == g_models.end())
return false;
return !it->second.base.empty() || !it->second.variants.empty();
}
int ModelRegistry::GetRotationProfile(int blockId)
{
if (blockId < 0)
return 0;
if (IsFastIndex(blockId))
return g_rotationProfile[blockId].load(std::memory_order_acquire);
std::lock_guard<std::mutex> guard(g_mutex);
auto it = g_models.find(blockId);
if (it == g_models.end())
@@ -72,6 +110,8 @@ int ModelRegistry::GetRotationProfile(int blockId)
bool ModelRegistry::TryGetModel(int blockId, const std::vector<ModelBox>*& outBoxes)
{
if (!HasModel(blockId))
return false;
std::lock_guard<std::mutex> guard(g_mutex);
auto it = g_models.find(blockId);
if (it == g_models.end())
@@ -86,6 +126,8 @@ bool ModelRegistry::TryGetModelVariant(int blockId, const char* key, const std::
{
if (!key)
return false;
if (!HasModel(blockId))
return false;
std::lock_guard<std::mutex> guard(g_mutex);
auto it = g_models.find(blockId);
if (it == g_models.end())

View File

@@ -17,6 +17,7 @@ namespace ModelRegistry
void RegisterBlockModel(int blockId, const ModelBox* boxes, int count);
void RegisterBlockModelVariant(int blockId, const char* key, const ModelBox* boxes, int count);
void SetRotationProfile(int blockId, int profile);
bool HasModel(int blockId);
int GetRotationProfile(int blockId);
bool TryGetModel(int blockId, const std::vector<ModelBox>*& outBoxes);
bool TryGetModelVariant(int blockId, const char* key, const std::vector<ModelBox>*& outBoxes);