mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-07 17:43:51 +00:00
perf(editor): cache M2/WMO models across rebuilds, only clear instances
The editor's rebuildObjects path was destroying every cached model and re-uploading it on every (debounced) change. Added M2Renderer::clearInstances that drops only the instance list while keeping models loaded. Editor's clearObjects switches to clearInstances (M2) + clearInstances (WMO), and persistent path->modelId maps survive across rebuilds. clearTerrain fully evicts when loading a new zone.
This commit is contained in:
parent
f18976ced9
commit
5241bbd669
4 changed files with 45 additions and 5 deletions
|
|
@ -357,6 +357,9 @@ public:
|
|||
void removeInstances(const std::vector<uint32_t>& instanceIds);
|
||||
void setSkipCollision(uint32_t instanceId, bool skip);
|
||||
void clear();
|
||||
/** Drop all instances but keep models in GPU memory. Cheap path for the
|
||||
* editor's rebuild loop where the same model is re-instanced repeatedly. */
|
||||
void clearInstances();
|
||||
void cleanupUnusedModels();
|
||||
|
||||
bool checkCollision(const glm::vec3& from, const glm::vec3& to,
|
||||
|
|
|
|||
|
|
@ -377,6 +377,22 @@ void M2Renderer::clear() {
|
|||
textureBudgetRejectWarnings_ = 0;
|
||||
}
|
||||
|
||||
void M2Renderer::clearInstances() {
|
||||
if (vkCtx_) vkDeviceWaitIdle(vkCtx_->getDevice());
|
||||
for (auto& inst : instances) destroyInstanceBones(inst);
|
||||
instances.clear();
|
||||
spatialGrid.clear();
|
||||
instanceIndexById.clear();
|
||||
instanceDedupMap_.clear();
|
||||
smokeInstanceIndices_.clear();
|
||||
portalInstanceIndices_.clear();
|
||||
animatedInstanceIndices_.clear();
|
||||
particleOnlyInstanceIndices_.clear();
|
||||
particleInstanceIndices_.clear();
|
||||
smokeParticles.clear();
|
||||
smokeEmitAccum = 0.0f;
|
||||
}
|
||||
|
||||
void M2Renderer::setCollisionFocus(const glm::vec3& worldPos, float radius) {
|
||||
collisionFocusEnabled = (radius > 0.0f);
|
||||
collisionFocusPos = worldPos;
|
||||
|
|
|
|||
|
|
@ -80,6 +80,13 @@ bool EditorViewport::loadTerrain(const pipeline::TerrainMesh& mesh,
|
|||
|
||||
void EditorViewport::clearTerrain() {
|
||||
if (terrainRenderer_) terrainRenderer_->clear();
|
||||
// Loading a different zone invalidates the cached models; flush them so
|
||||
// their slots can be reused without leaking GPU memory across zones.
|
||||
persistentM2ModelIds_.clear();
|
||||
persistentWMOModelIds_.clear();
|
||||
nextPersistentModelId_ = 1;
|
||||
if (m2Renderer_) m2Renderer_->clear();
|
||||
if (wmoRenderer_) wmoRenderer_->clearAll();
|
||||
}
|
||||
|
||||
void EditorViewport::updateWater(const pipeline::ADTTerrain& terrain, int tileX, int tileY) {
|
||||
|
|
@ -106,12 +113,16 @@ void EditorViewport::clearObjects() {
|
|||
ghostModelId_ = 0;
|
||||
ghostModelPath_.clear();
|
||||
|
||||
// Drop instances but keep models cached on the GPU. The editor's rebuild
|
||||
// path destroys-and-recreates instances every time the placement set
|
||||
// changes; preserving model GPU buffers makes that path much cheaper for
|
||||
// large NPC populations using shared models.
|
||||
if (m2Renderer_) {
|
||||
vkCtx_->waitAllUploads();
|
||||
m2Renderer_->clear();
|
||||
m2Renderer_->clearInstances();
|
||||
}
|
||||
if (wmoRenderer_) {
|
||||
wmoRenderer_->clearAll();
|
||||
wmoRenderer_->clearInstances();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -120,9 +131,11 @@ void EditorViewport::rebuildObjects(const std::vector<PlacedObject>& objects,
|
|||
clearObjects();
|
||||
if (objects.empty() && npcs.empty()) return;
|
||||
|
||||
// Don't call beginUploadBatch here — loadModel starts its own batch
|
||||
uint32_t nextModelId = 1;
|
||||
std::unordered_map<std::string, uint32_t> m2ModelIds, wmoModelIds;
|
||||
// Don't call beginUploadBatch here — loadModel starts its own batch.
|
||||
// Use the persistent model-id maps so models stay cached across rebuilds.
|
||||
auto& m2ModelIds = persistentM2ModelIds_;
|
||||
auto& wmoModelIds = persistentWMOModelIds_;
|
||||
uint32_t& nextModelId = nextPersistentModelId_;
|
||||
|
||||
for (const auto& obj : objects) {
|
||||
if (obj.type == PlaceableType::M2 && m2Renderer_) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@
|
|||
#include <vulkan/vulkan.h>
|
||||
#include <vk_mem_alloc.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace wowee {
|
||||
namespace pipeline { class AssetManager; }
|
||||
|
|
@ -114,6 +116,12 @@ private:
|
|||
float fogNear_ = 5000.0f, fogFar_ = 10000.0f;
|
||||
float timeOfDay_ = 12.0f;
|
||||
|
||||
// Persistent path -> renderer model ID maps. Keeping these across rebuilds
|
||||
// lets the renderer skip re-uploading models that are still in its cache.
|
||||
std::unordered_map<std::string, uint32_t> persistentM2ModelIds_;
|
||||
std::unordered_map<std::string, uint32_t> persistentWMOModelIds_;
|
||||
uint32_t nextPersistentModelId_ = 1;
|
||||
|
||||
// Ghost preview state
|
||||
std::string ghostModelPath_;
|
||||
uint32_t ghostModelId_ = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue