mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-23 15:50:20 +00:00
Add property-based mount animation discovery and procedural lean
Mount Animation System: - Property-based jump animation discovery using sequence metadata - Chain linkage scoring (nextAnimation/aliasNext) for accurate detection - Correct loop detection: flags & 0x01 == 0 means looping - Avoids brake/stop animations via blendTime penalties - Works on any mount model without hardcoded animation IDs Mount Physics: - Physics-based jump height: vz = sqrt(2 * g * h) - Configurable MOUNT_JUMP_HEIGHT constant (1.0m default) - Procedural lean into turns for ground mounts - Smooth roll based on turn rate (±14° max, 6x/sec blend) Audio Improvements: - State-machine driven mount sounds (jump, land, rear-up) - Semantic sound methods (no animation ID dependencies) - Debug logging for missing sound files Bug Fixes: - Fixed mount animation sequencing (JumpStart → JumpLoop → JumpEnd) - Fixed animation loop flag interpretation (0x20 vs 0x21) - Rider bone attachment working correctly during all mount actions
This commit is contained in:
parent
3c783d1845
commit
c623fcef51
16 changed files with 1083 additions and 145 deletions
|
|
@ -389,25 +389,62 @@ void Application::update(float deltaTime) {
|
|||
break;
|
||||
|
||||
case AppState::IN_GAME: {
|
||||
// Application update profiling
|
||||
static int appProfileCounter = 0;
|
||||
static float ghTime = 0.0f, worldTime = 0.0f, spawnTime = 0.0f;
|
||||
static float creatureQTime = 0.0f, goQTime = 0.0f, mountTime = 0.0f;
|
||||
static float npcMgrTime = 0.0f, questMarkTime = 0.0f, syncTime = 0.0f;
|
||||
|
||||
auto gh1 = std::chrono::high_resolution_clock::now();
|
||||
if (gameHandler) {
|
||||
gameHandler->update(deltaTime);
|
||||
}
|
||||
auto gh2 = std::chrono::high_resolution_clock::now();
|
||||
ghTime += std::chrono::duration<float, std::milli>(gh2 - gh1).count();
|
||||
|
||||
auto w1 = std::chrono::high_resolution_clock::now();
|
||||
if (world) {
|
||||
world->update(deltaTime);
|
||||
}
|
||||
auto w2 = std::chrono::high_resolution_clock::now();
|
||||
worldTime += std::chrono::duration<float, std::milli>(w2 - w1).count();
|
||||
|
||||
auto s1 = std::chrono::high_resolution_clock::now();
|
||||
// Spawn NPCs once when entering world
|
||||
spawnNpcs();
|
||||
auto s2 = std::chrono::high_resolution_clock::now();
|
||||
spawnTime += std::chrono::duration<float, std::milli>(s2 - s1).count();
|
||||
|
||||
auto cq1 = std::chrono::high_resolution_clock::now();
|
||||
// Process deferred online creature spawns (throttled)
|
||||
processCreatureSpawnQueue();
|
||||
auto cq2 = std::chrono::high_resolution_clock::now();
|
||||
creatureQTime += std::chrono::duration<float, std::milli>(cq2 - cq1).count();
|
||||
|
||||
auto goq1 = std::chrono::high_resolution_clock::now();
|
||||
processGameObjectSpawnQueue();
|
||||
auto goq2 = std::chrono::high_resolution_clock::now();
|
||||
goQTime += std::chrono::duration<float, std::milli>(goq2 - goq1).count();
|
||||
|
||||
auto m1 = std::chrono::high_resolution_clock::now();
|
||||
processPendingMount();
|
||||
auto m2 = std::chrono::high_resolution_clock::now();
|
||||
mountTime += std::chrono::duration<float, std::milli>(m2 - m1).count();
|
||||
|
||||
auto nm1 = std::chrono::high_resolution_clock::now();
|
||||
if (npcManager && renderer && renderer->getCharacterRenderer()) {
|
||||
npcManager->update(deltaTime, renderer->getCharacterRenderer());
|
||||
}
|
||||
auto nm2 = std::chrono::high_resolution_clock::now();
|
||||
npcMgrTime += std::chrono::duration<float, std::milli>(nm2 - nm1).count();
|
||||
|
||||
auto qm1 = std::chrono::high_resolution_clock::now();
|
||||
// Update 3D quest markers above NPCs
|
||||
updateQuestMarkers();
|
||||
auto qm2 = std::chrono::high_resolution_clock::now();
|
||||
questMarkTime += std::chrono::duration<float, std::milli>(qm2 - qm1).count();
|
||||
|
||||
auto sync1 = std::chrono::high_resolution_clock::now();
|
||||
|
||||
// Sync server run speed to camera controller
|
||||
if (renderer && gameHandler && renderer->getCameraController()) {
|
||||
|
|
@ -489,6 +526,22 @@ void Application::update(float deltaTime) {
|
|||
} else {
|
||||
movementHeartbeatTimer = 0.0f;
|
||||
}
|
||||
|
||||
auto sync2 = std::chrono::high_resolution_clock::now();
|
||||
syncTime += std::chrono::duration<float, std::milli>(sync2 - sync1).count();
|
||||
|
||||
// Log profiling every 60 frames
|
||||
if (++appProfileCounter >= 60) {
|
||||
LOG_INFO("APP UPDATE PROFILE (60 frames): gameHandler=", ghTime / 60.0f,
|
||||
"ms world=", worldTime / 60.0f, "ms spawn=", spawnTime / 60.0f,
|
||||
"ms creatureQ=", creatureQTime / 60.0f, "ms goQ=", goQTime / 60.0f,
|
||||
"ms mount=", mountTime / 60.0f, "ms npcMgr=", npcMgrTime / 60.0f,
|
||||
"ms questMark=", questMarkTime / 60.0f, "ms sync=", syncTime / 60.0f, "ms");
|
||||
appProfileCounter = 0;
|
||||
ghTime = worldTime = spawnTime = 0.0f;
|
||||
creatureQTime = goQTime = mountTime = 0.0f;
|
||||
npcMgrTime = questMarkTime = syncTime = 0.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -498,14 +551,30 @@ void Application::update(float deltaTime) {
|
|||
}
|
||||
|
||||
// Update renderer (camera, etc.) only when in-game
|
||||
static int rendererProfileCounter = 0;
|
||||
static float rendererTime = 0.0f, uiTime = 0.0f;
|
||||
|
||||
auto r1 = std::chrono::high_resolution_clock::now();
|
||||
if (renderer && state == AppState::IN_GAME) {
|
||||
renderer->update(deltaTime);
|
||||
}
|
||||
auto r2 = std::chrono::high_resolution_clock::now();
|
||||
rendererTime += std::chrono::duration<float, std::milli>(r2 - r1).count();
|
||||
|
||||
// Update UI
|
||||
auto u1 = std::chrono::high_resolution_clock::now();
|
||||
if (uiManager) {
|
||||
uiManager->update(deltaTime);
|
||||
}
|
||||
auto u2 = std::chrono::high_resolution_clock::now();
|
||||
uiTime += std::chrono::duration<float, std::milli>(u2 - u1).count();
|
||||
|
||||
if (state == AppState::IN_GAME && ++rendererProfileCounter >= 60) {
|
||||
LOG_INFO("RENDERER/UI PROFILE (60 frames): renderer=", rendererTime / 60.0f,
|
||||
"ms ui=", uiTime / 60.0f, "ms");
|
||||
rendererProfileCounter = 0;
|
||||
rendererTime = uiTime = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void Application::render() {
|
||||
|
|
@ -518,9 +587,9 @@ void Application::render() {
|
|||
// Only render 3D world when in-game (after server connect or single-player)
|
||||
if (state == AppState::IN_GAME) {
|
||||
if (world) {
|
||||
renderer->renderWorld(world.get());
|
||||
renderer->renderWorld(world.get(), gameHandler.get());
|
||||
} else {
|
||||
renderer->renderWorld(nullptr);
|
||||
renderer->renderWorld(nullptr, gameHandler.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue