Added detailed logging for WMO vertex data to diagnose pitch black areas:
- Log MOCV (vertex colors) chunk presence and first color value
- Log MONR (normals) chunk presence and first normal vector
- Log WMO group flags to identify interior vs exterior groups
Increased WMO ambient light from (0.4, 0.4, 0.5) to (0.55, 0.55, 0.6) to
make shadowed/dark areas more visible. This addresses pitch black areas in
Stormwind and other locations where diffuse lighting may be insufficient.
The diagnostic output will help identify if black areas are caused by:
- Missing or incorrect vertex color data (MOCV)
- Missing or incorrect normal data (MONR)
- Groups incorrectly flagged as interior (0x2000 flag)
Removed both persistent grid cache and per-frame dedup cache. Even the
per-frame cache was causing issues when player Z changes between queries
in the same frame (multi-sampling), returning stale floor heights and
causing fall-through at stairs. Floor queries now always raycast fresh.
Disabled persistent WMO floor grid cache - it stored one height per
2-unit cell causing fall-through at stairs where floor height changes
within a cell. Per-frame dedup cache is sufficient for performance.
Added camera raycast collision against WMO walls (when inside) and M2
objects to zoom in when camera would clip through geometry instead of
phasing through walls.
Relaxed walkable slope threshold from 0.40 to 0.35 (~70° max) for
steeper stair climbing. Tightened WMO floor cache above-tolerance
back to 0.25 units to prevent cached stair landing from overriding
approach floor. Added M2 floor preference for ship decks to prevent
falling through to water below.
Changed walkable slope threshold from 0.45 (63°) to 0.40 (66°) in both
WMO and M2 collision to allow climbing steeper stairs (like 60° steps).
Increased WMO floor cache above-tolerance from 0.35 to 0.50 units to
prevent falling through floors in places like Booty Bay where cached
floor is slightly above query point.
When inside a WMO, use:
- Smaller sweep step size (0.20 vs 0.35) for more frequent collision checks
- Tighter player radius (0.45 vs 0.50) for less claustrophobic corridors
- Stronger push response (0.12 vs 0.08 max) for more responsive walls
Prevents clipping through walls in tight indoor spaces while keeping
outdoor movement smooth.
Cap WMO swept wall collision pushback to 0.15 units (was 0.55) so walls
stop the player without violent shoves. Fix M2 stepped fountain lateral
push using effectiveTop instead of rawMax.z so the near-top check matches
the stepped profile height at the player's radial position.
Remove active group fast path from getFloorHeight to fix bridge clipping.
Replace ground smoothing with immediate step-up snap (WoW-style: snap up,
smooth down). Accept upward Z from wall collision at all call sites. Skip
floor-like surfaces (absNz >= 0.45) in wall collision to prevent false
wall hits on ramps. Increase getFloorHeight allowAbove from 0.5 to 2.0
for ramp reacquisition. Prefer highest reachable surface in floor selection.
- Add mutex to AssetManager::loadTexture/loadDBC/fileExists to prevent
StormLib thread-safety races that silently fail texture reads; stop
caching texture load failures so transient errors are retried.
- Replace /unstuckgy DBC lookup (which used wrong coordinate transform)
with hardcoded safe locations per map.
- Widen WMO floor raycast from single grid cell to ±1 unit range query
to catch bridge/walkway triangles at cell boundaries.
- Tighten swept collision hit threshold (0.5 → 0.15) and grid query
margin (2.5 → 1.5) to prevent false-positive wall pushes.
- Tighten post-wall-push Z snap lower bound (-1.0 → -0.3) to prevent
gradual floor sinking.
Relax swept collision hit threshold, expand spatial grid query range,
enable WMO floor detection in first person, raise ramp rejection
threshold, and snap Z after wall collision XY adjustment.
- Add setInstancePosition() to M2Renderer and WMORenderer for moving
transport instances at runtime
- Detect UPDATEFLAG_TRANSPORT on gameobjects and track transport GUIDs
- Parse player-on-transport state from movement blocks
- Wire transport move callback in Application to update render positions
- Implement CMSG_GAMEOBJECT_QUERY / SMSG_GAMEOBJECT_QUERY_RESPONSE so
gameobjects display proper names instead of "Unknown"
- Add name/entry fields to GameObject entity class
- Fix CMSG_USE_ITEM packet: remove extra uint8 that shifted the item
GUID by one byte, breaking hearthstone and all item usage
- Remove redundant CMSG_LOOT after CMSG_GAMEOBJECT_USE for chests
- Show PvP enabled/disabled state in toggle message
- Relax WMO ramp wall-collision step-up check to allow walking on
gentle ramps where floor rise per step is under 0.1 units
- Add M2 fallback when WMO group files fail to load for gameobjects
- Handle re-creation of existing gameobject render instances by
updating position instead of silently ignoring
Clear aura list on AURA_UPDATE_ALL so dismount/WMO transitions refresh
properly. Increase WMO step height thresholds to reduce stair blocking.
Change buff cancel to right-click and support dismount via buff bar.
Guard pendingTiles.erase() with queueMutex in processReadyTiles and
unloadTile to prevent data race with worker threads. Add defensive null
checks in M2/WMO render and animation paths. Move cleanupUnusedModels
out of per-tile unload loop to run once after all tiles are removed.
- Remove early-out in wall collision so multiple wall faces are resolved
per frame, preventing corner clip-through
- Update localTo after each wall push so subsequent triangles check
against the corrected position
- Tighten collision sweep steps from 0.65 to 0.35 units (max 5 steps)
for better tunneling prevention on thin walls and corners
- Carpet slide fix: use raw model bounds (rawMax.z) instead of radius-
inflated effectiveTop for the on-top-of-object check, so thin objects
like rugs correctly skip lateral push
- Brighten WMO interior vertex lighting from 2.2/0.3 to 2.4/0.35
- Implement flight path system: SMSG_SHOWTAXINODES parser, CMSG_ACTIVATETAXIEXPRESS builder, BFS multi-hop pathfinding through TaxiNodes/TaxiPath DBC, taxi destination UI, movement blocking during flight
- Fix WMO interiors too dark by boosting vertex color lighting multiplier
- Dim M2 objects inside WMO interiors (rugs, furniture) via per-instance interior detection
- Fix ramp/stair clipping by lowering wall collision normal threshold from 0.85 to 0.55
- Restore 5-sample cardinal footprint for ground detection to fix rug slipping
- Fix /unstuck command to reset player Z to WMO/terrain floor height
- Handle MSG_MOVE_TELEPORT_ACK and SMSG_TRANSFER_PENDING for hearthstone teleports
- Fix spawning under Stormwind with online-mode camera controller reset
Lower MAX_STEP_HEIGHT from 1.0 to 0.6 so curb walls aren't skipped.
Tighten ramp and short surface filters (0.8 height threshold instead of
1.2-1.5) to prevent clipping through tunnel entrance geometry in Stormwind.
- Skip wall collision sweep entirely when player isn't moving (saves all
collision calls when standing still)
- Reduce max sweep steps from 4 to 2 with 1.0f step size (all paths:
follow, free-fly, swimming)
- Cache floor height between frames, reuse when position changes <0.5 units
- Fix floor height not updating after walking off tall objects (fountain etc)
by always smoothing toward detected ground instead of ignoring drops >2 units
- Reduce free-fly ground probes from 5 to 1
- Disable WMO camera collision (raycast + floor probes) for performance
- Add spatial grid to raycastBoundingBoxes for when camera collision is re-enabled
Build a 2D triangle grid per WMO group at load time so getFloorHeight and
checkWallCollision only test triangles in nearby cells instead of brute-forcing
all triangles. Also reduce sweep steps (12→4), ground probes (3→1), camera
floor probes (5→2), throttle isInsideWMO to every 10 frames, and early-out
wall collision on first hit.
- Fix CMSG_BUY_ITEM count field from uint8 to uint32 (server silently dropped undersized packets)
- Character select screen: remember last selected character, two-column layout with details panel, double-click to enter world, responsive window sizing
- Fix stale character data between logins by replacing static init flag with per-character GUID tracking
- Parallelize WMO visibility culling across worker threads (same pattern as M2 renderer)
- Optimize WMO collision queries with world-space group bounds early rejection in getFloorHeight, checkWallCollision, isInsideWMO, and raycastBoundingBoxes
- Reduce camera ground samples from 5 to 3 movement-aligned probes
- Add WMO interior lighting, unlit materials, vertex color multiply, and alpha blending support
Reduce max zoom to 15 units when inside a building. Increase player
collision radius to 0.70, lower step height threshold, and use more
aggressive pushback and finer sweep steps to prevent wall clipping.
- Remove complex ramp/edge filtering that was skipping building walls
- Simpler wall detection: any vertical geometry above step height
- Add intro camera pan on game start
- Use explicit loaded flag for heightmap instead of checking height values
- Increase player collision radius from 0.50 to 0.55 for better wall collision
- Increase footprint sampling radius from 0.28 to 0.4 units
- Only update floor cache if found floor is close to query height
- Prevents caching wrong floor from different stories
Skip cached floor height if it's too far below query point (>4 units),
forcing a full raycast. This handles cases where the cache has a
different floor's height (e.g., ground floor cached while on upper floor).
Save/load floor cache per map (e.g., cache/wmo_floor_Azeroth.bin) instead
of a single global file. Saves current zone's cache before teleporting,
loads target zone's cache after terrain streaming completes.
Add precomputeFloorCache() method that samples all WMO bounds at load time
and populates the persistent floor height grid. Called after terrain
streaming completes (initial spawn and teleport) when cache is empty.
- Add texture-sorted batch merging with glMultiDrawElements to reduce draw calls
- Pre-compute merged batches at load time instead of per-frame
- Add persistent floor height cache with disk save/load (cache/wmo_floor_cache.bin)
- Reduce collision focus radius and sweep steps for faster collision checks
- Add floor cache size to performance HUD
- Reduce WMO group distance culling to 80 units
Renders bounding boxes in depth-only pre-pass and queries GPU for
visibility. Groups fully occluded in previous frame are skipped.
Significantly improves performance in dense areas like Stormwind.
Portal-based visibility culling for WMO rendering (disabled by default,
needs debugging for complex WMOs like Stormwind). Skip character creation
screen when characters already exist in single-player mode.
Replace hardcoded specular multipliers with uLightColor * uSpecularIntensity
uniforms in all 4 world shaders (terrain, WMO, M2, character), set HDR sun
color (1.5, 1.4, 1.3) and specular intensity 0.5 so highlights can exceed
1.0, and switch the post-process pass from passthrough to exposure-compensated
Reinhard (exposure=1.8) for soft highlight roll-off without clipping.
Anisotropic filtering now queries GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT once
and applies via a single applyAnisotropicFiltering() utility, replacing
hardcoded calls across all renderers. Fog (sky horizon color, 100-600
range) and Blinn-Phong specular highlights are added to WMO, M2, and
character shaders for visual parity with terrain. Shadow sampling
plumbing (sampler2DShadow with 3x3 PCF) is wired into all three shaders
gated by uShadowEnabled, ready for a future shadow map pass.
- Add spellbook screen (P key) with Spell.dbc name lookup and action bar assignment
- Default Attack and Hearthstone spells available in single player
- Fix WMO floor clipping (gryphon roost) by tightening ceiling rejection threshold
- Darken ocean water, increase wave motion and opacity
- Add M2 model distance fade-in to prevent pop-in
- Reposition chat window, add slash/enter key focus
- Remove debug key commands (keep only F1 perf HUD, N minimap)
- Performance: return chat history by const ref, use deque for O(1) pop_front