mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-05-03 08:03:50 +00:00
perf: eliminate double map lookups, dynamic_cast in render loops, div by 255
- Replace count()+operator[] double lookups with find() or try_emplace() in gameObjectInstances_, playerTextureSlotsByModelId_, onlinePlayerAppearance_ - Add Entity::isUnit() helper; replace 5 dynamic_cast<Unit*> in per-frame UI rendering (nameplates, combat text, pet frame) with isUnit()+static_cast - Add constexpr kInv255 reciprocal for per-pixel normal map generation loops in character_renderer and wmo_renderer
This commit is contained in:
parent
6f2c8962e5
commit
6b1c728377
5 changed files with 36 additions and 27 deletions
|
|
@ -153,6 +153,9 @@ public:
|
||||||
ObjectType getType() const { return type; }
|
ObjectType getType() const { return type; }
|
||||||
void setType(ObjectType t) { type = t; }
|
void setType(ObjectType t) { type = t; }
|
||||||
|
|
||||||
|
/// True if this entity is a Unit or Player (both derive from Unit).
|
||||||
|
bool isUnit() const { return type == ObjectType::UNIT || type == ObjectType::PLAYER; }
|
||||||
|
|
||||||
// Fields (for update values)
|
// Fields (for update values)
|
||||||
void setField(uint16_t index, uint32_t value) {
|
void setField(uint16_t index, uint32_t value) {
|
||||||
fields[index] = value;
|
fields[index] = value;
|
||||||
|
|
|
||||||
|
|
@ -7155,7 +7155,9 @@ void Application::spawnOnlinePlayer(uint64_t guid,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine texture slots once per model
|
// Determine texture slots once per model
|
||||||
if (!playerTextureSlotsByModelId_.count(modelId)) {
|
{
|
||||||
|
auto [slotIt, inserted] = playerTextureSlotsByModelId_.try_emplace(modelId);
|
||||||
|
if (inserted) {
|
||||||
PlayerTextureSlots slots;
|
PlayerTextureSlots slots;
|
||||||
if (const auto* md = charRenderer->getModelData(modelId)) {
|
if (const auto* md = charRenderer->getModelData(modelId)) {
|
||||||
for (size_t ti = 0; ti < md->textures.size(); ti++) {
|
for (size_t ti = 0; ti < md->textures.size(); ti++) {
|
||||||
|
|
@ -7165,7 +7167,8 @@ void Application::spawnOnlinePlayer(uint64_t guid,
|
||||||
else if (t == 8 && slots.underwear < 0) slots.underwear = static_cast<int>(ti);
|
else if (t == 8 && slots.underwear < 0) slots.underwear = static_cast<int>(ti);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
playerTextureSlotsByModelId_[modelId] = slots;
|
slotIt->second = slots;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create instance at server position
|
// Create instance at server position
|
||||||
|
|
@ -7330,14 +7333,13 @@ void Application::setOnlinePlayerEquipment(uint64_t guid,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the player isn't spawned yet, store equipment until spawn.
|
// If the player isn't spawned yet, store equipment until spawn.
|
||||||
if (!playerInstances_.count(guid) || !onlinePlayerAppearance_.count(guid)) {
|
auto appIt = onlinePlayerAppearance_.find(guid);
|
||||||
|
if (!playerInstances_.count(guid) || appIt == onlinePlayerAppearance_.end()) {
|
||||||
pendingOnlinePlayerEquipment_[guid] = {displayInfoIds, inventoryTypes};
|
pendingOnlinePlayerEquipment_[guid] = {displayInfoIds, inventoryTypes};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = onlinePlayerAppearance_.find(guid);
|
const OnlinePlayerAppearanceState& st = appIt->second;
|
||||||
if (it == onlinePlayerAppearance_.end()) return;
|
|
||||||
const OnlinePlayerAppearanceState& st = it->second;
|
|
||||||
|
|
||||||
auto* charRenderer = renderer->getCharacterRenderer();
|
auto* charRenderer = renderer->getCharacterRenderer();
|
||||||
if (!charRenderer) return;
|
if (!charRenderer) return;
|
||||||
|
|
@ -7533,9 +7535,10 @@ void Application::spawnOnlineGameObject(uint64_t guid, uint32_t entry, uint32_t
|
||||||
}
|
}
|
||||||
if (!gameObjectLookupsBuilt_) return;
|
if (!gameObjectLookupsBuilt_) return;
|
||||||
|
|
||||||
if (gameObjectInstances_.count(guid)) {
|
auto goIt = gameObjectInstances_.find(guid);
|
||||||
|
if (goIt != gameObjectInstances_.end()) {
|
||||||
// Already have a render instance — update its position (e.g. transport re-creation)
|
// Already have a render instance — update its position (e.g. transport re-creation)
|
||||||
auto& info = gameObjectInstances_[guid];
|
auto& info = goIt->second;
|
||||||
glm::vec3 renderPos = core::coords::canonicalToRender(glm::vec3(x, y, z));
|
glm::vec3 renderPos = core::coords::canonicalToRender(glm::vec3(x, y, z));
|
||||||
LOG_DEBUG("GameObject position update: displayId=", displayId, " guid=0x", std::hex, guid, std::dec,
|
LOG_DEBUG("GameObject position update: displayId=", displayId, " guid=0x", std::hex, guid, std::dec,
|
||||||
" pos=(", x, ", ", y, ", ", z, ")");
|
" pos=(", x, ", ", y, ", ", z, ")");
|
||||||
|
|
|
||||||
|
|
@ -546,12 +546,13 @@ CharacterRenderer::NormalMapResult CharacterRenderer::generateNormalHeightMapCPU
|
||||||
const uint8_t* pixels = srcPixels.data();
|
const uint8_t* pixels = srcPixels.data();
|
||||||
|
|
||||||
// Step 1: Compute height from luminance
|
// Step 1: Compute height from luminance
|
||||||
|
constexpr float kInv255 = 1.0f / 255.0f;
|
||||||
std::vector<float> heightMap(totalPixels);
|
std::vector<float> heightMap(totalPixels);
|
||||||
double sumH = 0.0, sumH2 = 0.0;
|
double sumH = 0.0, sumH2 = 0.0;
|
||||||
for (uint32_t i = 0; i < totalPixels; i++) {
|
for (uint32_t i = 0; i < totalPixels; i++) {
|
||||||
float r = pixels[i * 4 + 0] / 255.0f;
|
float r = pixels[i * 4 + 0] * kInv255;
|
||||||
float g = pixels[i * 4 + 1] / 255.0f;
|
float g = pixels[i * 4 + 1] * kInv255;
|
||||||
float b = pixels[i * 4 + 2] / 255.0f;
|
float b = pixels[i * 4 + 2] * kInv255;
|
||||||
float h = 0.299f * r + 0.587f * g + 0.114f * b;
|
float h = 0.299f * r + 0.587f * g + 0.114f * b;
|
||||||
heightMap[i] = h;
|
heightMap[i] = h;
|
||||||
sumH += h;
|
sumH += h;
|
||||||
|
|
|
||||||
|
|
@ -2159,12 +2159,13 @@ std::unique_ptr<VkTexture> WMORenderer::generateNormalHeightMap(
|
||||||
const uint32_t totalPixels = width * height;
|
const uint32_t totalPixels = width * height;
|
||||||
|
|
||||||
// Step 1: Compute height from luminance
|
// Step 1: Compute height from luminance
|
||||||
|
constexpr float kInv255 = 1.0f / 255.0f;
|
||||||
std::vector<float> heightMap(totalPixels);
|
std::vector<float> heightMap(totalPixels);
|
||||||
double sumH = 0.0, sumH2 = 0.0;
|
double sumH = 0.0, sumH2 = 0.0;
|
||||||
for (uint32_t i = 0; i < totalPixels; i++) {
|
for (uint32_t i = 0; i < totalPixels; i++) {
|
||||||
float r = pixels[i * 4 + 0] / 255.0f;
|
float r = pixels[i * 4 + 0] * kInv255;
|
||||||
float g = pixels[i * 4 + 1] / 255.0f;
|
float g = pixels[i * 4 + 1] * kInv255;
|
||||||
float b = pixels[i * 4 + 2] / 255.0f;
|
float b = pixels[i * 4 + 2] * kInv255;
|
||||||
float h = 0.299f * r + 0.587f * g + 0.114f * b;
|
float h = 0.299f * r + 0.587f * g + 0.114f * b;
|
||||||
heightMap[i] = h;
|
heightMap[i] = h;
|
||||||
sumH += h;
|
sumH += h;
|
||||||
|
|
|
||||||
|
|
@ -3681,7 +3681,7 @@ void GameScreen::renderPetFrame(game::GameHandler& gameHandler) {
|
||||||
|
|
||||||
auto petEntity = gameHandler.getEntityManager().getEntity(petGuid);
|
auto petEntity = gameHandler.getEntityManager().getEntity(petGuid);
|
||||||
if (!petEntity) return;
|
if (!petEntity) return;
|
||||||
auto* petUnit = dynamic_cast<game::Unit*>(petEntity.get());
|
auto* petUnit = petEntity->isUnit() ? static_cast<game::Unit*>(petEntity.get()) : nullptr;
|
||||||
if (!petUnit) return;
|
if (!petUnit) return;
|
||||||
|
|
||||||
// Position below player frame. If in a group, push below party frames
|
// Position below player frame. If in a group, push below party frames
|
||||||
|
|
@ -11255,7 +11255,7 @@ void GameScreen::renderCombatText(game::GameHandler& gameHandler) {
|
||||||
// Fallback to entity canonical position
|
// Fallback to entity canonical position
|
||||||
auto entity = gameHandler.getEntityManager().getEntity(entry.dstGuid);
|
auto entity = gameHandler.getEntityManager().getEntity(entry.dstGuid);
|
||||||
if (entity) {
|
if (entity) {
|
||||||
auto* unit = dynamic_cast<game::Unit*>(entity.get());
|
auto* unit = entity->isUnit() ? static_cast<game::Unit*>(entity.get()) : nullptr;
|
||||||
if (unit) {
|
if (unit) {
|
||||||
renderPos = core::coords::canonicalToRender(
|
renderPos = core::coords::canonicalToRender(
|
||||||
glm::vec3(unit->getX(), unit->getY(), unit->getZ()));
|
glm::vec3(unit->getX(), unit->getY(), unit->getZ()));
|
||||||
|
|
@ -11540,8 +11540,9 @@ void GameScreen::renderNameplates(game::GameHandler& gameHandler) {
|
||||||
for (const auto& [guid, entityPtr] : gameHandler.getEntityManager().getEntities()) {
|
for (const auto& [guid, entityPtr] : gameHandler.getEntityManager().getEntities()) {
|
||||||
if (!entityPtr || guid == playerGuid) continue;
|
if (!entityPtr || guid == playerGuid) continue;
|
||||||
|
|
||||||
auto* unit = dynamic_cast<game::Unit*>(entityPtr.get());
|
if (!entityPtr->isUnit()) continue;
|
||||||
if (!unit || unit->getMaxHealth() == 0) continue;
|
auto* unit = static_cast<game::Unit*>(entityPtr.get());
|
||||||
|
if (unit->getMaxHealth() == 0) continue;
|
||||||
|
|
||||||
bool isPlayer = (entityPtr->getType() == game::ObjectType::PLAYER);
|
bool isPlayer = (entityPtr->getType() == game::ObjectType::PLAYER);
|
||||||
bool isTarget = (guid == targetGuid);
|
bool isTarget = (guid == targetGuid);
|
||||||
|
|
@ -14403,7 +14404,7 @@ void GameScreen::renderGuildRoster(game::GameHandler& gameHandler) {
|
||||||
if (sig.playerGuid != 0) {
|
if (sig.playerGuid != 0) {
|
||||||
auto entity = gameHandler.getEntityManager().getEntity(sig.playerGuid);
|
auto entity = gameHandler.getEntityManager().getEntity(sig.playerGuid);
|
||||||
if (entity) {
|
if (entity) {
|
||||||
auto* unit = dynamic_cast<game::Unit*>(entity.get());
|
auto* unit = entity->isUnit() ? static_cast<game::Unit*>(entity.get()) : nullptr;
|
||||||
if (unit) sigName = unit->getName();
|
if (unit) sigName = unit->getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -15801,7 +15802,7 @@ void GameScreen::renderLootWindow(game::GameHandler& gameHandler) {
|
||||||
const auto& candidates = gameHandler.getMasterLootCandidates();
|
const auto& candidates = gameHandler.getMasterLootCandidates();
|
||||||
for (uint64_t candidateGuid : candidates) {
|
for (uint64_t candidateGuid : candidates) {
|
||||||
auto entity = gameHandler.getEntityManager().getEntity(candidateGuid);
|
auto entity = gameHandler.getEntityManager().getEntity(candidateGuid);
|
||||||
auto* unit = entity ? dynamic_cast<game::Unit*>(entity.get()) : nullptr;
|
auto* unit = (entity && entity->isUnit()) ? static_cast<game::Unit*>(entity.get()) : nullptr;
|
||||||
const char* cName = unit ? unit->getName().c_str() : nullptr;
|
const char* cName = unit ? unit->getName().c_str() : nullptr;
|
||||||
char nameBuf[64];
|
char nameBuf[64];
|
||||||
if (!cName || cName[0] == '\0') {
|
if (!cName || cName[0] == '\0') {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue