From 26277f915c418910a8f766e603276fb4d74eafc0 Mon Sep 17 00:00:00 2001 From: ragnarok-clanker Date: Tue, 3 Nov 2026 12:59:38 +0000 Subject: [PATCH] Maintenance: [forced, user-approved] Family W3: remove invented ModelLightingContext and WorldModelLoading. Evidence: C3dActor::Prepa Batch #10256 by ragnarok-clanker: forced by an admin (0 lower score(s), 8 changed function(s)); checked with 113 compiled unit(s), including every includer of Source/Contents/Models/ModelActor.h, Source/Contents/Models/ModelNode.h, Source/Contents/Models/ModelRendering.h, Source/Contents/World/World.h, Source/Contents/World/WorldModelLoading.h. --- Source/Contents/Models/ModelActor.cpp | 32 +----- Source/Contents/Models/ModelActor.h | 6 +- Source/Contents/Models/ModelLighting.cpp | 44 ++++--- Source/Contents/Models/ModelNode.h | 4 +- Source/Contents/Models/ModelRendering.h | 12 -- Source/Contents/World/World.h | 2 + Source/Contents/World/WorldModelLoading.cpp | 121 ++++---------------- Source/Contents/World/WorldModelLoading.h | 25 ---- 8 files changed, 60 insertions(+), 186 deletions(-) diff --git a/Source/Contents/Models/ModelActor.cpp b/Source/Contents/Models/ModelActor.cpp index fe5eddda3..2e0dd0cf9 100644 --- a/Source/Contents/Models/ModelActor.cpp +++ b/Source/Contents/Models/ModelActor.cpp @@ -128,51 +128,29 @@ void C3dActor::UpdateBounds() { // OFFSET: 0x00ABBA50 // FUNCTION: fn_17518 -void C3dActor::Prepare(ModelLightingContext&) { +void C3dActor::Prepare(const float*, const float*, const float*) { } // OFFSET: 0x00ABBA60 // FUNCTION: fn_17519 -void C3dActorV1::Prepare(ModelLightingContext& context) { +void C3dActorV1::Prepare(const float* direction, const float* diffuse, const float* ambient) { if (this->dirty == 1) { this->UpdateMatrix(); } - const float* previousPosition = context.position; - const std::uint32_t* previousColor = context.color; - const int* previousShade = context.shade; - - context.position = this->position; - context.color = &this->color; - context.shade = &this->shade; - this->root->Prepare(this->transform.values, context); - context.position = previousPosition; - context.color = previousColor; - context.shade = previousShade; + this->root->Prepare(this->transform.values, direction, diffuse, ambient, this->shade); } // OFFSET: 0x00ABBAA0 // FUNCTION: fn_17520 -void C3dActorV2::Prepare(ModelLightingContext& context) { +void C3dActorV2::Prepare(const float* direction, const float* diffuse, const float* ambient) { if (this->dirty == 1) { this->UpdateMatrix(); } - const float* previousPosition = context.position; - const std::uint32_t* previousColor = context.color; - const int* previousShade = context.shade; - - context.position = this->position; - context.color = &this->color; - context.shade = &this->shade; - for (C3dNodeV2* root : this->roots) { - root->Prepare(this->transform.values, context); + root->Prepare(this->transform.values, direction, diffuse, ambient, this->shade); } - - context.position = previousPosition; - context.color = previousColor; - context.shade = previousShade; } // OFFSET: 0x00AB9060 diff --git a/Source/Contents/Models/ModelActor.h b/Source/Contents/Models/ModelActor.h index 6f2181679..0df53b0c7 100644 --- a/Source/Contents/Models/ModelActor.h +++ b/Source/Contents/Models/ModelActor.h @@ -14,7 +14,7 @@ public: virtual void Assign(const C3dModelRes& resource); virtual void UpdateMatrix(); virtual void UpdateBounds(); - virtual void Prepare(ModelLightingContext& context); + virtual void Prepare(const float* direction, const float* diffuse, const float* ambient); virtual void Animate(double frame); virtual void Update(); virtual void Draw(const float* matrix, bool clip, ModelRenderContext& context); @@ -60,7 +60,7 @@ public: ~C3dActorV1() override; void Assign(const C3dModelRes& resource) override; void UpdateBounds() override; - void Prepare(ModelLightingContext& context) override; + void Prepare(const float* direction, const float* diffuse, const float* ambient) override; void Animate(double frame) override; void Update() override; void Draw(const float* matrix, bool clip, ModelRenderContext& context) override; @@ -79,7 +79,7 @@ public: void Assign(const C3dModelRes& resource) override; void UpdateMatrix() override; void UpdateBounds() override; - void Prepare(ModelLightingContext& context) override; + void Prepare(const float* direction, const float* diffuse, const float* ambient) override; void Animate(double frame) override; void Update() override; void Draw(const float* matrix, bool clip, ModelRenderContext& context) override; diff --git a/Source/Contents/Models/ModelLighting.cpp b/Source/Contents/Models/ModelLighting.cpp index ba29ed91a..f3a22f5be 100644 --- a/Source/Contents/Models/ModelLighting.cpp +++ b/Source/Contents/Models/ModelLighting.cpp @@ -1,11 +1,19 @@ +#include "Client/Mode/CGameMode.h" +#include "Client/Mode/ModeMgr.h" #include "Contents/Ground/GroundGeometry.h" +#include "Contents/Models/ModelActor.h" #include "Contents/Models/ModelNode.h" +#include "Contents/World/World.h" +#include "Render/Renderer.h" #include "Render/Textures/Texture.h" #include "Utility/Math/ScalarConversion.h" #include #include +// GLOBAL: gl_25474 +static std::uint32_t g_modelFaceColors[90000]; + namespace { // INLINED unsigned Byte(float value) { @@ -19,16 +27,16 @@ namespace { } // INLINED - void Light(const float* normal, const float* matrix, const ModelLightingContext& context, float* output) { + void Light(const float* normal, const float* matrix, const float* direction, const float* diffuse, const float* ambient, float* output) { const float x = ((normal[0] * matrix[0] + normal[1] * matrix[3]) + normal[2] * matrix[6]) + 0.0f; const float y = ((normal[0] * matrix[1] + normal[1] * matrix[4]) + normal[2] * matrix[7]) + 0.0f; const float z = ((normal[0] * matrix[2] + normal[1] * matrix[5]) + normal[2] * matrix[8]) + 0.0f; const float inverse = InverseLength((y * y + x * x) + z * z); - const float dot = ((y * inverse) * context.direction[1] + (x * inverse) * context.direction[0]) + (z * inverse) * context.direction[2]; + const float dot = ((y * inverse) * direction[1] + (x * inverse) * direction[0]) + (z * inverse) * direction[2]; const float amount = dot > 0.0f ? dot : 0.0f; for (unsigned component = 0; component < 3; ++component) { - const float color = amount * context.diffuse[component] + context.ambient[component]; + const float color = amount * diffuse[component] + ambient[component]; output[component] = color < 1.0f ? color : 1.0f; } } @@ -77,7 +85,9 @@ void C3dNode::OverrideColors() { // OFFSET: 0x00ABB450 // FUNCTION: fn_17515 -void C3dNode::SampleGroundColors(const float* matrix, const float* position, const GroundGeometry& ground) { +void C3dNode::SampleGroundColors(const CRenderer*, const float* matrix, const GroundGeometry& ground) { + const float* position = this->model->position; + for (int index = 0; index < this->mesh->faceCount; ++index) { const ModelFace& face = this->mesh->faces[index]; @@ -101,7 +111,7 @@ void C3dNode::SampleGroundColors(const float* matrix, const float* position, con // OFFSET: 0x00ABBB00 // FUNCTION: fn_17521 -void C3dNode::Prepare(const float* matrix, ModelLightingContext& context) { +void C3dNode::Prepare(const float* matrix, const float* direction, const float* diffuse, const float* ambient, int shade) { struct matrix parentMatrix; std::memcpy(parentMatrix.values, matrix, sizeof(parentMatrix.values)); struct matrix combined; @@ -111,22 +121,22 @@ void C3dNode::Prepare(const float* matrix, ModelLightingContext& context) { const ModelFace& face = this->mesh->faces[index]; float light[3]; - if (*context.shade == 1) { - Light(this->mesh->faceNormals[index].data(), combined.values, context, light); + if (shade == 1) { + Light(this->mesh->faceNormals[index].data(), combined.values, direction, diffuse, ambient, light); } for (unsigned corner = 0; corner < 3; ++corner) { - std::uint32_t& color = context.colors[index * 3u + corner]; + std::uint32_t& color = g_modelFaceColors[index * 3u + corner]; - if (*context.shade == 0) { - color = (*context.color & 0x00FFFFFFu) | (Byte(this->alpha * 255.0f) << 24); - } else if (*context.shade == 1 || *context.shade == 2) { - if (*context.shade == 2) { - Light(this->mesh->vertexNormals[index * 3u + corner].data(), combined.values, context, light); + if (shade == 0) { + color = (this->model->color & 0x00FFFFFFu) | (Byte(this->alpha * 255.0f) << 24); + } else if (shade == 1 || shade == 2) { + if (shade == 2) { + Light(this->mesh->vertexNormals[index * 3u + corner].data(), combined.values, direction, diffuse, ambient, light); } const bool shaded = this->mesh->textureVertices[face.textureVertices[corner]].shaded != 0; - color = LitColor(*context.color, this->alpha, shaded, light); + color = LitColor(this->model->color, this->alpha, shaded, light); } } } @@ -145,7 +155,7 @@ void C3dNode::Prepare(const float* matrix, ModelLightingContext& context) { ModelFaceState& state = this->faceState[index]; for (unsigned corner = 0; corner < 3; ++corner) { - state.colors[corner] = context.colors[index * 3u + corner]; + state.colors[corner] = g_modelFaceColors[index * 3u + corner]; } for (unsigned corner = 0; corner < 3; ++corner) { @@ -163,9 +173,9 @@ void C3dNode::Prepare(const float* matrix, ModelLightingContext& context) { } while (index < this->mesh->faceCount && this->mesh->faces[index].texture == texture); } - this->SampleGroundColors(combined.values, context.position, context.ground); + this->SampleGroundColors(g_renderer, combined.values, *static_cast(g_modeMgr.GetGameMode())->scene->ground); for (C3dNode* child : this->children) { - child->Prepare(combined.values, context); + child->Prepare(combined.values, direction, diffuse, ambient, shade); } } diff --git a/Source/Contents/Models/ModelNode.h b/Source/Contents/Models/ModelNode.h index 86afe5aa2..865c609b5 100644 --- a/Source/Contents/Models/ModelNode.h +++ b/Source/Contents/Models/ModelNode.h @@ -26,8 +26,8 @@ public: virtual void Draw(const float* matrix, unsigned char reversed, bool clip, unsigned char commandMode, ModelRenderContext& context); C3dNode* Find(const char* name); void OverrideColors(); - void Prepare(const float* matrix, ModelLightingContext& context); - void SampleGroundColors(const float* matrix, const float* position, const class GroundGeometry& ground); + void Prepare(const float* matrix, const float* direction, const float* diffuse, const float* ambient, int shade); + void SampleGroundColors(const class CRenderer* renderer, const float* matrix, const class GroundGeometry& ground); void AccumulateBounds(float* bounds, const float* matrix); /* 0004 */ std::string name; diff --git a/Source/Contents/Models/ModelRendering.h b/Source/Contents/Models/ModelRendering.h index a8385402e..ca475cb97 100644 --- a/Source/Contents/Models/ModelRendering.h +++ b/Source/Contents/Models/ModelRendering.h @@ -17,18 +17,6 @@ struct ModelFaceState { /* 000C */ float uv[3][2]; }; -struct ModelLightingContext { - const float* position; - const std::uint32_t* color; - const float* direction; - const float* diffuse; - const float* ambient; - const int* shade; - const class GroundGeometry& ground; - - std::array colors{}; -}; - struct ModelRenderContext { const RenderProjection& projection; RenderCommandPool& commands; diff --git a/Source/Contents/World/World.h b/Source/Contents/World/World.h index b1c3e4136..80380e561 100644 --- a/Source/Contents/World/World.h +++ b/Source/Contents/World/World.h @@ -53,6 +53,8 @@ public: void AddPcPosFromCell(std::uint32_t aid, const int* cell); void AddPcPosUnindexed(std::uint32_t aid, const CellFloatPos& cell); void InitWorld(); + static unsigned long __stdcall LoadDeferredModels(void* parameter); + void FinishModelLoading(); /* 0004 */ CGameMode* gameMode; /* 0008 */ std::list objects; diff --git a/Source/Contents/World/WorldModelLoading.cpp b/Source/Contents/World/WorldModelLoading.cpp index 4f1c78a40..2ebe79084 100644 --- a/Source/Contents/World/WorldModelLoading.cpp +++ b/Source/Contents/World/WorldModelLoading.cpp @@ -60,7 +60,7 @@ namespace { } // INLINED - C3dActor* CreatePlacedWorldModel(const WorldModelRecord& placement, C3dModelRes& resource, BinkMovies& movies, ModelLightingContext& lighting) { + C3dActor* CreateWorldModel(const WorldModelRecord& placement, C3dModelRes& resource, BinkMovies& movies) { resource.RegisterMovies(movies, placement.position); if (!resource.FindNode(placement.node) && resource.nodes.empty()) { @@ -88,130 +88,51 @@ namespace { actor->color = static_cast(placement.index); actor->Assign(resource); actor->occlusionEnabled = 0; - actor->Prepare(lighting); + actor->Prepare(g_worldLightDirection, g_worldDiffuse, g_worldAmbient); return actor; } - - // INLINED - C3dActor* CreateInitWorldModel(const WorldModelRecord& placement, C3dModelRes& resource, BinkMovies& movies) { - resource.RegisterMovies(movies, placement.position); - - if (!resource.FindNode(placement.node) && resource.nodes.empty()) { - return nullptr; - } - - C3dActor* actor = nullptr; - - if (resource.major == 1) { - actor = new C3dActorV1; - } else if (resource.major == 2) { - actor = new C3dActorV2; - } - - actor->CopyVolumes(resource.volumes); - actor->SetSpeed(placement.animationSpeed); - actor->playback = placement.animation; - std::memcpy(actor->position, placement.position, sizeof(actor->position)); - actor->dirty = 1; - std::memcpy(actor->rotation, placement.rotation, sizeof(actor->rotation)); - actor->dirty = 1; - std::memcpy(actor->scale, placement.scale, sizeof(actor->scale)); - actor->dirty = 1; - actor->commandMode = placement.flag; - actor->color = static_cast(placement.index); - actor->Assign(resource); - actor->occlusionEnabled = 0; - void** actorVtbl = *reinterpret_cast(actor); - reinterpret_cast(actorVtbl[4])( - actor, g_worldLightDirection, g_worldDiffuse, g_worldAmbient - ); - - return actor; - } -} - -// INLINED -void WorldModelLoading::Schedule(const WorldModelRecord& placement, const TerrainHeight& terrain, int column, int row, float* center) { - terrain.CellCenter(column, row, center[0], center[2]); - const float y = placement.position[1] - center[1]; - const float x = placement.position[0] - center[0]; - const float z = placement.position[2] - center[2]; - const float squared = (y * y + x * x) + z * z; - const float distance = std::sqrt(squared); - - if (distance > 200.0f) { - this->deferred.push_back({distance, &placement}); - return; - } - - auto* resource = static_cast(this->resources.Load(placement.model)); - - if (resource) { - if (C3dActor* model = CreatePlacedWorldModel(placement, *resource, this->movies, this->lighting)) { - this->models.push_back(model); - } - } } // OFFSET: 0x00AC8BF0 // FUNCTION: fn_17680 -DWORD WINAPI WorldModelLoading::ThreadEntry(void* context) { - static_cast(context)->Run(); - return 0; -} - -// INLINED -void WorldModelLoading::Start() { - this->thread = CreateThread(nullptr, 0, &WorldModelLoading::ThreadEntry, this, 0, nullptr); - - if (!this->thread) { - this->Run(); - this->Finish(); - } -} - -// INLINED -void WorldModelLoading::Run() { +DWORD WINAPI CWorld::LoadDeferredModels(void* parameter) { + CWorld* world = static_cast(parameter); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); - std::sort(this->deferred.begin(), this->deferred.end(), Before); + std::sort(g_deferredWorldModels.begin(), g_deferredWorldModels.end(), Before); - for (const DeferredWorldModel& entry : this->deferred) { + for (const DeferredWorldModel& entry : g_deferredWorldModels) { const WorldModelRecord& placement = *entry.placement; - auto* resource = static_cast(this->resources.Load(placement.model)); + auto* resource = static_cast(ResourceMgr::Instance().Load(placement.model)); if (!resource) { continue; } - C3dActor* model = CreatePlacedWorldModel(placement, *resource, this->movies, this->lighting); + C3dActor* model = CreateWorldModel(placement, *resource, *world->movies); if (!model) { continue; } - this->models.push_back(model); - std::atomic_ref(this->pending).fetch_add(1, std::memory_order_seq_cst); + world->models.push_back(model); + std::atomic_ref(world->pending).fetch_add(1, std::memory_order_seq_cst); Sleep(0); } -} -// INLINED -void WorldModelLoading::Publish(WorldSpatialTree& root) { - C3dActor* const* data = this->models.data(); - PublishWorldModels(root, data, this->published, this->pending); + return 0; } // OFFSET: 0x00ACB6C0 // FUNCTION: fn_17705 -void WorldModelLoading::Finish() { - if (this->thread) { - WaitForSingleObject(this->thread, INFINITE); - CloseHandle(this->thread); - this->thread = nullptr; +void CWorld::FinishModelLoading() { + if (hObject) { + WaitForSingleObject(hObject, INFINITE); + CloseHandle(hObject); + hObject = nullptr; } - this->deferred.clear(); + g_deferredWorldModels.clear(); std::atomic_ref(this->pending).store(0, std::memory_order_release); } @@ -343,7 +264,7 @@ void CWorld::InitWorld() { } else { auto* modelRes = static_cast(ResourceMgr::Instance().Load(placement->model)); if (modelRes) { - if (C3dActor* actor = CreateInitWorldModel(*placement, *modelRes, *this->movies)) { + if (C3dActor* actor = CreateWorldModel(*placement, *modelRes, *this->movies)) { this->models.push_back(actor); } } @@ -358,10 +279,10 @@ void CWorld::InitWorld() { this->published = static_cast(this->models.size()); DWORD threadId = 0; - hObject = CreateThread(nullptr, 0, &WorldModelLoading::ThreadEntry, this, 0, &threadId); + hObject = CreateThread(nullptr, 0, &CWorld::LoadDeferredModels, this, 0, &threadId); if (!hObject) { - WorldModelLoading::ThreadEntry(this); - reinterpret_cast(this)->Finish(); + CWorld::LoadDeferredModels(this); + this->FinishModelLoading(); } this->player = new CPlayer(); diff --git a/Source/Contents/World/WorldModelLoading.h b/Source/Contents/World/WorldModelLoading.h index 501f71c1d..615de0d3f 100644 --- a/Source/Contents/World/WorldModelLoading.h +++ b/Source/Contents/World/WorldModelLoading.h @@ -5,13 +5,7 @@ #include #include -class C3dActor; -class ResourceMgr; -class BinkMovies; struct WorldModelRecord; -struct ModelLightingContext; -struct WorldSpatialTree; -struct TerrainHeight; struct DeferredWorldModel { /* 0000 */ float distance; @@ -31,23 +25,4 @@ extern float g_worldAmbient[3]; extern float g_worldLoadCenter[3]; extern int g_partyEffectNoticePending; -struct WorldModelLoading { - ResourceMgr& resources; - BinkMovies& movies; - ModelLightingContext& lighting; - std::vector& models; - int& published; - int& pending; - std::vector& deferred; - HANDLE& thread; - - void Schedule(const WorldModelRecord& placement, const TerrainHeight& terrain, int column, int row, float* center); - void Start(); - void Run(); - void Publish(WorldSpatialTree& root); - void Finish(); - - static DWORD WINAPI ThreadEntry(void* context); -}; - #endif