perf: eliminate ~70 unnecessary sqrt ops per frame, optimize caches and threading

Squared distance optimizations across 30 files:
- Convert glm::length() comparisons to glm::dot() (no sqrt)
- Use glm::inversesqrt() for check-then-normalize patterns (1 rsqrt vs 2 sqrt)
- Defer sqrt to after early-out checks in collision/movement code
- Hottest paths: camera_controller (21), weather particles, WMO collision,
  transport movement, creature interpolation, nameplate culling

Container and algorithm improvements:
- std::map<string> → std::unordered_map for asset/DBC/MPQ/warden caches
- std::mutex → std::shared_mutex for asset_manager and mpq_manager caches
- std::sort → std::partial_sort in lighting_manager (top-2 of N volumes)
- Double-lookup find()+operator[] → insert_or_assign in game_handler
- Add reserve() for per-frame vectors: weather, swim_effects, WMO/M2 collision

Threading and synchronization:
- Replace 1ms busy-wait polling with condition_variable in character_renderer
- Move timestamp capture before mutex in logger
- Use memory_order_acquire/release for normal map completion signaling

API additions:
- DBC getStringView()/getStringViewByOffset() for zero-copy string access
- Parse creature display IDs from SMSG_CREATURE_QUERY_SINGLE_RESPONSE
This commit is contained in:
Kelsi 2026-03-27 16:33:16 -07:00
parent cf0e2aa240
commit b0466e9029
29 changed files with 328 additions and 196 deletions

View file

@ -542,7 +542,7 @@ void SwimEffects::update(const Camera& camera, const CameraController& cc,
// Compute movement direction from camera yaw
float yawRad = glm::radians(cc.getYaw());
glm::vec3 moveDir(std::cos(yawRad), std::sin(yawRad), 0.0f);
if (glm::length(glm::vec2(moveDir)) > 0.001f) {
if (moveDir.x * moveDir.x + moveDir.y * moveDir.y > 1e-6f) {
moveDir = glm::normalize(moveDir);
}
@ -676,6 +676,7 @@ void SwimEffects::update(const Camera& camera, const CameraController& cc,
// --- Build vertex data ---
rippleVertexData.clear();
rippleVertexData.reserve(ripples.size() * 5);
for (const auto& p : ripples) {
rippleVertexData.push_back(p.position.x);
rippleVertexData.push_back(p.position.y);
@ -685,6 +686,7 @@ void SwimEffects::update(const Camera& camera, const CameraController& cc,
}
bubbleVertexData.clear();
bubbleVertexData.reserve(bubbles.size() * 5);
for (const auto& p : bubbles) {
bubbleVertexData.push_back(p.position.x);
bubbleVertexData.push_back(p.position.y);
@ -694,6 +696,7 @@ void SwimEffects::update(const Camera& camera, const CameraController& cc,
}
insectVertexData.clear();
insectVertexData.reserve(insects.size() * 5);
for (const auto& p : insects) {
insectVertexData.push_back(p.position.x);
insectVertexData.push_back(p.position.y);