mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-25 16:30:15 +00:00
Add ambient sound system and eliminate log spam
- Implement AmbientSoundManager with tavern/outdoor ambience - Fix audio buffer limit (5s → 60s) for long ambient loops - Set log level to INFO to eliminate DEBUG spam (130MB → 3.2MB logs) - Remove excessive terrain/model/network logging - Fix ambient sound timer sharing and pitch parameter bugs
This commit is contained in:
parent
4a7e599764
commit
dab23f1895
24 changed files with 701 additions and 138 deletions
|
|
@ -860,9 +860,6 @@ uint32_t CharacterRenderer::createInstance(uint32_t modelId, const glm::vec3& po
|
|||
instance.boneMatrices.resize(std::max(static_cast<size_t>(1), model.bones.size()), glm::mat4(1.0f));
|
||||
|
||||
instances[instance.id] = instance;
|
||||
|
||||
core::Logger::getInstance().info("Created character instance ", instance.id, " from model ", modelId);
|
||||
|
||||
return instance.id;
|
||||
}
|
||||
|
||||
|
|
@ -1253,9 +1250,6 @@ void CharacterRenderer::render(const Camera& camera, const glm::mat4& view, cons
|
|||
gpuModel.textureIds.size(), " textures loaded, ",
|
||||
gpuModel.data.textureLookup.size(), " in lookup table");
|
||||
for (size_t t = 0; t < gpuModel.data.textures.size(); t++) {
|
||||
LOG_INFO(" Texture[", t, "]: type=", gpuModel.data.textures[t].type,
|
||||
" file=", gpuModel.data.textures[t].filename,
|
||||
" glId=", (t < gpuModel.textureIds.size() ? std::to_string(gpuModel.textureIds[t]) : "N/A"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "audio/activity_sound_manager.hpp"
|
||||
#include "audio/mount_sound_manager.hpp"
|
||||
#include "audio/npc_voice_manager.hpp"
|
||||
#include "audio/ambient_sound_manager.hpp"
|
||||
#include <GL/glew.h>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtx/euler_angles.hpp>
|
||||
|
|
@ -344,6 +345,7 @@ bool Renderer::initialize(core::Window* win) {
|
|||
activitySoundManager = std::make_unique<audio::ActivitySoundManager>();
|
||||
mountSoundManager = std::make_unique<audio::MountSoundManager>();
|
||||
npcVoiceManager = std::make_unique<audio::NpcVoiceManager>();
|
||||
ambientSoundManager = std::make_unique<audio::AmbientSoundManager>();
|
||||
|
||||
// Underwater full-screen tint overlay (applies to all world geometry).
|
||||
underwaterOverlayShader = std::make_unique<Shader>();
|
||||
|
|
@ -1383,12 +1385,21 @@ void Renderer::update(float deltaTime) {
|
|||
|
||||
activitySoundManager->setSwimmingState(swimming, moving);
|
||||
|
||||
// Fade music underwater
|
||||
if (musicManager) {
|
||||
musicManager->setUnderwaterMode(swimming);
|
||||
}
|
||||
|
||||
sfxPrevGrounded = grounded;
|
||||
sfxPrevJumping = jumping;
|
||||
sfxPrevFalling = falling;
|
||||
sfxPrevSwimming = swimming;
|
||||
} else {
|
||||
activitySoundManager->setSwimmingState(false, false);
|
||||
// Restore music volume when activity sounds disabled
|
||||
if (musicManager) {
|
||||
musicManager->setUnderwaterMode(false);
|
||||
}
|
||||
sfxStateInitialized = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1404,6 +1415,16 @@ void Renderer::update(float deltaTime) {
|
|||
}
|
||||
}
|
||||
|
||||
// Ambient environmental sounds: fireplaces, water, birds, etc.
|
||||
if (ambientSoundManager && camera && wmoRenderer && cameraController) {
|
||||
glm::vec3 camPos = camera->getPosition();
|
||||
uint32_t wmoId = 0;
|
||||
bool isIndoor = wmoRenderer->isInsideWMO(camPos.x, camPos.y, camPos.z, &wmoId);
|
||||
bool isSwimming = cameraController->isSwimming();
|
||||
|
||||
ambientSoundManager->update(deltaTime, camPos, isIndoor, isSwimming);
|
||||
}
|
||||
|
||||
// Update M2 doodad animations (pass camera for frustum-culling bone computation)
|
||||
if (m2Renderer && camera) {
|
||||
m2Renderer->update(deltaTime, camera->getPosition(),
|
||||
|
|
@ -2040,6 +2061,10 @@ bool Renderer::loadTestTerrain(pipeline::AssetManager* assetManager, const std::
|
|||
if (wmoRenderer) {
|
||||
terrainManager->setWMORenderer(wmoRenderer.get());
|
||||
}
|
||||
// Set ambient sound manager for environmental audio emitters
|
||||
if (ambientSoundManager) {
|
||||
terrainManager->setAmbientSoundManager(ambientSoundManager.get());
|
||||
}
|
||||
// Pass asset manager to character renderer for texture loading
|
||||
if (characterRenderer) {
|
||||
characterRenderer->setAssetManager(assetManager);
|
||||
|
|
@ -2117,6 +2142,9 @@ bool Renderer::loadTestTerrain(pipeline::AssetManager* assetManager, const std::
|
|||
if (npcVoiceManager) {
|
||||
npcVoiceManager->initialize(assetManager);
|
||||
}
|
||||
if (ambientSoundManager) {
|
||||
ambientSoundManager->initialize(assetManager);
|
||||
}
|
||||
cachedAssetManager = assetManager;
|
||||
}
|
||||
|
||||
|
|
@ -2201,6 +2229,14 @@ bool Renderer::loadTerrainArea(const std::string& mapName, int centerX, int cent
|
|||
if (npcVoiceManager && cachedAssetManager) {
|
||||
npcVoiceManager->initialize(cachedAssetManager);
|
||||
}
|
||||
if (ambientSoundManager && cachedAssetManager) {
|
||||
ambientSoundManager->initialize(cachedAssetManager);
|
||||
}
|
||||
|
||||
// Wire ambient sound manager to terrain manager for emitter registration
|
||||
if (terrainManager && ambientSoundManager) {
|
||||
terrainManager->setAmbientSoundManager(ambientSoundManager.get());
|
||||
}
|
||||
|
||||
// Wire WMO, M2, and water renderer to camera controller
|
||||
if (cameraController && wmoRenderer) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "rendering/m2_renderer.hpp"
|
||||
#include "rendering/wmo_renderer.hpp"
|
||||
#include "rendering/camera.hpp"
|
||||
#include "audio/ambient_sound_manager.hpp"
|
||||
#include "core/coordinates.hpp"
|
||||
#include "core/memory_monitor.hpp"
|
||||
#include "pipeline/asset_manager.hpp"
|
||||
|
|
@ -465,6 +466,49 @@ std::shared_ptr<PendingTile> TerrainManager::prepareTile(int x, int y) {
|
|||
// Extract world position for frustum culling
|
||||
glm::vec3 worldPos = glm::vec3(worldMatrix[3]);
|
||||
|
||||
// Detect ambient sound emitters from doodad model path
|
||||
std::string m2PathLower = m2Path;
|
||||
std::transform(m2PathLower.begin(), m2PathLower.end(), m2PathLower.begin(), ::tolower);
|
||||
|
||||
// Debug: Log all doodad paths to help identify fire-related models
|
||||
static int doodadLogCount = 0;
|
||||
if (doodadLogCount < 50) { // Limit logging to first 50 doodads
|
||||
LOG_DEBUG("WMO doodad: ", m2Path);
|
||||
doodadLogCount++;
|
||||
}
|
||||
|
||||
if (m2PathLower.find("fire") != std::string::npos ||
|
||||
m2PathLower.find("brazier") != std::string::npos ||
|
||||
m2PathLower.find("campfire") != std::string::npos) {
|
||||
// Fireplace/brazier emitter
|
||||
PendingTile::AmbientEmitter emitter;
|
||||
emitter.position = worldPos;
|
||||
if (m2PathLower.find("small") != std::string::npos || m2PathLower.find("campfire") != std::string::npos) {
|
||||
emitter.type = 0; // FIREPLACE_SMALL
|
||||
} else {
|
||||
emitter.type = 1; // FIREPLACE_LARGE
|
||||
}
|
||||
pending->ambientEmitters.push_back(emitter);
|
||||
} else if (m2PathLower.find("torch") != std::string::npos) {
|
||||
// Torch emitter
|
||||
PendingTile::AmbientEmitter emitter;
|
||||
emitter.position = worldPos;
|
||||
emitter.type = 2; // TORCH
|
||||
pending->ambientEmitters.push_back(emitter);
|
||||
} else if (m2PathLower.find("fountain") != std::string::npos) {
|
||||
// Fountain emitter
|
||||
PendingTile::AmbientEmitter emitter;
|
||||
emitter.position = worldPos;
|
||||
emitter.type = 3; // FOUNTAIN
|
||||
pending->ambientEmitters.push_back(emitter);
|
||||
} else if (m2PathLower.find("waterfall") != std::string::npos) {
|
||||
// Waterfall emitter
|
||||
PendingTile::AmbientEmitter emitter;
|
||||
emitter.position = worldPos;
|
||||
emitter.type = 6; // WATERFALL
|
||||
pending->ambientEmitters.push_back(emitter);
|
||||
}
|
||||
|
||||
PendingTile::WMODoodadReady doodadReady;
|
||||
doodadReady.modelId = doodadModelId;
|
||||
doodadReady.model = std::move(m2Model);
|
||||
|
|
@ -533,6 +577,60 @@ void TerrainManager::finalizeTile(const std::shared_ptr<PendingTile>& pending) {
|
|||
waterRenderer->loadFromTerrain(pending->terrain, true, x, y);
|
||||
}
|
||||
|
||||
// Register water surface ambient sound emitters
|
||||
if (ambientSoundManager) {
|
||||
// Scan ADT water data for water surfaces
|
||||
int waterEmitterCount = 0;
|
||||
for (size_t chunkIdx = 0; chunkIdx < pending->terrain.waterData.size(); chunkIdx++) {
|
||||
const auto& chunkWater = pending->terrain.waterData[chunkIdx];
|
||||
if (!chunkWater.hasWater()) continue;
|
||||
|
||||
// Calculate chunk position in world coordinates
|
||||
int chunkX = chunkIdx % 16;
|
||||
int chunkY = chunkIdx / 16;
|
||||
|
||||
// WoW coordinates: Each ADT tile is 533.33 units, each chunk is 533.33/16 = 33.333 units
|
||||
// Tile origin in GL space
|
||||
float tileOriginX = (32.0f - x) * 533.33333f;
|
||||
float tileOriginY = (32.0f - y) * 533.33333f;
|
||||
|
||||
// Chunk center position
|
||||
float chunkCenterX = tileOriginX + (chunkX + 0.5f) * 33.333333f;
|
||||
float chunkCenterY = tileOriginY + (chunkY + 0.5f) * 33.333333f;
|
||||
|
||||
// Use first layer for height and type detection
|
||||
if (!chunkWater.layers.empty()) {
|
||||
const auto& layer = chunkWater.layers[0];
|
||||
float waterHeight = layer.minHeight;
|
||||
|
||||
// Determine water type and register appropriate emitter
|
||||
// liquidType: 0=water/lake, 1=ocean, 2=magma, 3=slime
|
||||
if (layer.liquidType == 0) {
|
||||
// Lake/river water - add water surface emitter every 32 chunks to avoid spam
|
||||
if (chunkIdx % 32 == 0) {
|
||||
PendingTile::AmbientEmitter emitter;
|
||||
emitter.position = glm::vec3(chunkCenterX, chunkCenterY, waterHeight);
|
||||
emitter.type = 4; // WATER_SURFACE
|
||||
pending->ambientEmitters.push_back(emitter);
|
||||
waterEmitterCount++;
|
||||
}
|
||||
} else if (layer.liquidType == 1) {
|
||||
// Ocean - add ocean emitter every 64 chunks (oceans are very large)
|
||||
if (chunkIdx % 64 == 0) {
|
||||
PendingTile::AmbientEmitter emitter;
|
||||
emitter.position = glm::vec3(chunkCenterX, chunkCenterY, waterHeight);
|
||||
emitter.type = 4; // WATER_SURFACE (could add separate OCEAN type later)
|
||||
pending->ambientEmitters.push_back(emitter);
|
||||
waterEmitterCount++;
|
||||
}
|
||||
}
|
||||
// Skip magma and slime for now (no ambient sounds for those)
|
||||
}
|
||||
}
|
||||
if (waterEmitterCount > 0) {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<uint32_t> m2InstanceIds;
|
||||
std::vector<uint32_t> wmoInstanceIds;
|
||||
std::vector<uint32_t> tileUniqueIds;
|
||||
|
|
@ -631,6 +729,15 @@ void TerrainManager::finalizeTile(const std::shared_ptr<PendingTile>& pending) {
|
|||
}
|
||||
}
|
||||
|
||||
// Register ambient sound emitters with ambient sound manager
|
||||
if (ambientSoundManager && !pending->ambientEmitters.empty()) {
|
||||
for (const auto& emitter : pending->ambientEmitters) {
|
||||
// Cast uint32_t type to AmbientSoundManager::AmbientType enum
|
||||
auto type = static_cast<audio::AmbientSoundManager::AmbientType>(emitter.type);
|
||||
ambientSoundManager->addEmitter(emitter.position, type);
|
||||
}
|
||||
}
|
||||
|
||||
// Create tile entry
|
||||
auto tile = std::make_unique<TerrainTile>();
|
||||
tile->coord = coord;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue