mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-25 16:30:15 +00:00
Stabilize taxi/state sync and creature spawn handling
This commit is contained in:
parent
38cef8d9c6
commit
40b50454ce
18 changed files with 818 additions and 127 deletions
|
|
@ -735,9 +735,45 @@ void CameraController::update(float deltaTime) {
|
|||
}
|
||||
|
||||
// ===== WoW-style orbit camera =====
|
||||
// Pivot point at upper chest/neck
|
||||
// Pivot point at upper chest/neck.
|
||||
float mountedOffset = mounted_ ? mountHeightOffset_ : 0.0f;
|
||||
glm::vec3 pivot = targetPos + glm::vec3(0.0f, 0.0f, PIVOT_HEIGHT + mountedOffset);
|
||||
float pivotLift = 0.0f;
|
||||
if (terrainManager && !externalFollow_) {
|
||||
float moved = glm::length(glm::vec2(targetPos.x - lastPivotLiftQueryPos_.x,
|
||||
targetPos.y - lastPivotLiftQueryPos_.y));
|
||||
float distDelta = std::abs(currentDistance - lastPivotLiftDistance_);
|
||||
bool queryLift = (++pivotLiftQueryCounter_ >= PIVOT_LIFT_QUERY_INTERVAL) ||
|
||||
(moved >= PIVOT_LIFT_POS_THRESHOLD) ||
|
||||
(distDelta >= PIVOT_LIFT_DIST_THRESHOLD);
|
||||
if (queryLift) {
|
||||
pivotLiftQueryCounter_ = 0;
|
||||
lastPivotLiftQueryPos_ = targetPos;
|
||||
lastPivotLiftDistance_ = currentDistance;
|
||||
|
||||
// Estimate where camera sits horizontally and ensure enough terrain clearance.
|
||||
glm::vec3 probeCam = targetPos + (-forward3D) * currentDistance;
|
||||
auto terrainAtCam = terrainManager->getHeightAt(probeCam.x, probeCam.y);
|
||||
auto terrainAtPivot = terrainManager->getHeightAt(targetPos.x, targetPos.y);
|
||||
|
||||
float desiredLift = 0.0f;
|
||||
if (terrainAtCam) {
|
||||
// Keep pivot high enough so near-hill camera rays don't cut through terrain.
|
||||
constexpr float kMinRayClearance = 2.0f;
|
||||
float basePivotZ = targetPos.z + PIVOT_HEIGHT + mountedOffset;
|
||||
float rayClearance = basePivotZ - *terrainAtCam;
|
||||
if (rayClearance < kMinRayClearance) {
|
||||
desiredLift = std::clamp(kMinRayClearance - rayClearance, 0.0f, 1.4f);
|
||||
}
|
||||
}
|
||||
// If character is already below local terrain sample, avoid lifting aggressively.
|
||||
if (terrainAtPivot && targetPos.z < *terrainAtPivot - 0.2f) {
|
||||
desiredLift = 0.0f;
|
||||
}
|
||||
cachedPivotLift_ = desiredLift;
|
||||
}
|
||||
pivotLift = cachedPivotLift_;
|
||||
}
|
||||
glm::vec3 pivot = targetPos + glm::vec3(0.0f, 0.0f, PIVOT_HEIGHT + mountedOffset + pivotLift);
|
||||
|
||||
// Camera direction from yaw/pitch (already computed as forward3D)
|
||||
glm::vec3 camDir = -forward3D; // Camera looks at pivot, so it's behind
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ void Celestial::renderSun(const Camera& camera, float timeOfDay,
|
|||
// Create model matrix
|
||||
glm::mat4 model = glm::mat4(1.0f);
|
||||
model = glm::translate(model, sunPos);
|
||||
model = glm::scale(model, glm::vec3(500.0f, 500.0f, 1.0f)); // Large and visible
|
||||
model = glm::scale(model, glm::vec3(95.0f, 95.0f, 1.0f)); // Match WotLK-like apparent size
|
||||
|
||||
// Set uniforms
|
||||
glm::mat4 view = camera.getViewMatrix();
|
||||
|
|
|
|||
|
|
@ -986,7 +986,7 @@ void CharacterRenderer::update(float deltaTime, const glm::vec3& cameraPos) {
|
|||
|
||||
static int logCounter = 0;
|
||||
if (++logCounter >= 300) { // Log every 10 seconds at 30fps
|
||||
LOG_INFO("CharacterRenderer: ", updatedCount, "/", instances.size(), " instances updated (",
|
||||
LOG_DEBUG("CharacterRenderer: ", updatedCount, "/", instances.size(), " instances updated (",
|
||||
instances.size() - updatedCount, " culled)");
|
||||
logCounter = 0;
|
||||
}
|
||||
|
|
@ -1584,7 +1584,17 @@ void CharacterRenderer::setInstanceVisible(uint32_t instanceId, bool visible) {
|
|||
}
|
||||
|
||||
void CharacterRenderer::removeInstance(uint32_t instanceId) {
|
||||
instances.erase(instanceId);
|
||||
auto it = instances.find(instanceId);
|
||||
if (it == instances.end()) return;
|
||||
|
||||
// Remove child attachments first (helmets/weapons), otherwise they leak as
|
||||
// orphan render instances when the parent creature despawns.
|
||||
auto attachments = it->second.weaponAttachments;
|
||||
for (const auto& wa : attachments) {
|
||||
removeInstance(wa.weaponInstanceId);
|
||||
}
|
||||
|
||||
instances.erase(it);
|
||||
}
|
||||
|
||||
bool CharacterRenderer::getAnimationState(uint32_t instanceId, uint32_t& animationId,
|
||||
|
|
|
|||
|
|
@ -2053,7 +2053,7 @@ void M2Renderer::render(const Camera& camera, const glm::mat4& view, const glm::
|
|||
static int frameCounter = 0;
|
||||
if (++frameCounter >= 120) {
|
||||
frameCounter = 0;
|
||||
LOG_INFO("M2 Render: ", totalMs, " ms (culling/sort: ", cullingSortMs,
|
||||
LOG_DEBUG("M2 Render: ", totalMs, " ms (culling/sort: ", cullingSortMs,
|
||||
" ms, draw: ", drawLoopMs, " ms) | ", sortedVisible_.size(), " visible | ",
|
||||
totalBatchesDrawn, " batches | ", boneMatrixUploads, " bone uploads");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2143,7 +2143,7 @@ void Renderer::update(float deltaTime) {
|
|||
|
||||
// Log renderer profiling every 60 frames
|
||||
if (++rendProfileCounter >= 60) {
|
||||
LOG_INFO("RENDERER UPDATE PROFILE (60 frames): camera=", camTime / 60.0f,
|
||||
LOG_DEBUG("RENDERER UPDATE PROFILE (60 frames): camera=", camTime / 60.0f,
|
||||
"ms light=", lightTime / 60.0f, "ms charAnim=", charAnimTime / 60.0f,
|
||||
"ms terrain=", terrainTime / 60.0f, "ms sky=", skyTime / 60.0f,
|
||||
"ms charRend=", charRendTime / 60.0f, "ms audio=", audioTime / 60.0f,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue