Commit graph

61 commits

Author SHA1 Message Date
Kelsi
f3f3b62880 Transport hell 2026-02-11 00:54:38 -08:00
Kelsi
73db7768d4 Add steep slope limiting to prevent terrain clipping
Added slope normal checking to reject surfaces too steep to walk.
Prevents character/mount from clipping through steep terrain.

Changes:
- Added MIN_WALKABLE_NORMAL threshold (0.7 = ~45° max slope)
- WMO collision: query surface normal, reject if normalZ < 0.7
- M2 collision: query surface normal, reject if normalZ < 0.7
- Updated M2Renderer::getFloorHeight to output surface normal
- M2 already had internal 0.35 check (~70°), new 0.7 is more restrictive

Steep slopes now block movement instead of allowing clipping.
2026-02-10 20:45:25 -08:00
Kelsi
3c783d1845 Optimize M2 and terrain rendering for 60fps target
Implements aggressive performance optimizations to improve frame rate from 29fps to 40fps:

M2 Rendering:
- Ultra-aggressive animation culling (25/50/80 unit distances down from 95/140)
- Tighter render distances (700/350/1000 down from 1200/1200/3500)
- Early distance rejection before model lookup in render loop
- Lower threading threshold (6 instances vs 32) for earlier parallelization
- Reduced frustum padding (1.5x vs 2.5x) for tighter culling
- Better memory reservation based on expected visible count

Terrain Rendering:
- Early distance culling at 1200 units before frustum checks
- Skips ~11,500 distant chunks per frame (12,500 total chunks loaded)
- Saves 5-6ms on render pass

Performance Impact:
- Render time: 20ms → 14-15ms (30% faster)
- Frame rate: 29fps → 40fps (+11fps)
- Total savings: ~9ms per frame
2026-02-10 17:23:41 -08:00
Kelsi
8e60d0e781 Implement WoW-accurate DBC-driven sky system with lore-faithful celestial bodies
Add SkySystem coordinator that follows WoW's actual architecture where skyboxes
are authoritative and procedural elements serve as fallbacks. Integrate lighting
system across all renderers (terrain, WMO, M2, character) with unified parameters.

Sky System:
- SkySystem coordinator manages skybox, celestial bodies, stars, clouds, lens flare
- Skybox is authoritative (baked stars from M2 models, procedural fallback only)
- skyboxHasStars flag gates procedural star rendering (prevents double-star bug)

Celestial Bodies (Lore-Accurate):
- Two moons: White Lady (30-day cycle, pale white) + Blue Child (27-day cycle, pale blue)
- Deterministic moon phases from server gameTime (not deltaTime toys)
- Sun positioning driven by LightingManager directionalDir (DBC-sourced)
- Camera-locked sky dome (translation ignored, rotation applied)

Lighting Integration:
- Apply LightingManager params to WMO, M2, character renderers
- Unified lighting: directional light, diffuse color, ambient color, fog
- Star occlusion by cloud density (70% weight) and fog density (30% weight)

Documentation:
- Add comprehensive SKY_SYSTEM.md technical guide
- Update MEMORY.md with sky system architecture and anti-patterns
- Update README.md with WoW-accurate descriptions

Critical design decisions:
- NO latitude-based star rotation (Azeroth not modeled as spherical planet)
- NO always-on procedural stars (skybox authority prevents zone identity loss)
- NO universal dual-moon setup (map-specific celestial configurations)
2026-02-10 14:36:17 -08:00
Kelsi
8cb6311470 Make InvisibleTrap objects invisible and non-collidable
Event objects like Fire Festival Fury Trap and Mercutio Post use
SpellObject_InvisibleTrap.m2 models which were rendering as white
tiles using WHITE1.BLP texture. These are meant to be invisible
spell trigger objects that should not obstruct player movement.

Changes:
- Added isInvisibleTrap flag to M2ModelGPU struct
- Detect models with "invisibletrap" in name during loading
- Skip rendering invisible trap instances in render loop
- Disable all collision checks (floor/wall/occlusion) for invisible traps
- Objects remain functional for spell casting but are now invisible
2026-02-09 22:31:36 -08:00
Kelsi
0c590ac952 Disable collision for carpet and rug M2 models
- Add carpet/rug name detection in model loading
- Set collisionNoBlock flag for carpet and rug models
- Prevents slipping/sliding on decorative floor coverings
- Player can now walk through carpets without collision
2026-02-09 20:05:24 -08:00
Kelsi
b222b78734 Increase M2 frustum culling padding to prevent edge pop-out
- Increase padding from 1.2x to 2.5x model radius
- Add minimum 5 unit padding for small objects like lamps
- Fixes models disappearing at viewport edges during camera rotation
2026-02-09 20:02:52 -08:00
Kelsi
28330adfb0 Eliminate per-frame allocations in M2 renderer to reduce CPU stutter
Use persistent vectors for animation work indices, futures, and glow sprites instead of allocating each frame.
2026-02-09 00:41:07 -08:00
Kelsi
c047446fb7 Add dynamic memory-based asset caching and aggressive loading
- Add MemoryMonitor class for dynamic cache sizing based on available RAM
- Increase terrain load radius to 8 tiles (17x17 grid, 289 tiles)
- Scale worker threads to 75% of logical cores (no cap)
- Increase cache budget to 80% of available RAM, max file size to 50%
- Increase M2 render distance: 1200 units during taxi, 800 when >2000 instances
- Fix camera positioning during taxi flights (external follow mode)
- Add 2-second landing cooldown to prevent re-entering taxi mode on lag
- Update interval reduced to 33ms for faster streaming responsiveness

Optimized for high-memory systems while scaling gracefully to lower-end hardware.
Cache and render distances now fully utilize available VRAM on minimum spec GPUs.
2026-02-08 23:15:26 -08:00
Kelsi
709138cf5d Relax aggressive taxi culling to show more detail
With VRAM model caching eliminating loading hitches, we can now render
much more detail during taxi flights for better visual quality.

Changes:
- boundRadius threshold: 15.0 → 2.0 (now show buildings, trees, large props)
- Foliage: was skipping ALL, now only skip small bushes/flowers < 5 units
- Trees: now visible (removed collisionTreeTrunk blanket skip)
- Underwater: -5.0 → -10.0 (only skip very deep objects)

Before: Only massive buildings visible, world looked empty
After: Buildings, trees, large props visible for immersive flight experience

Performance remains good due to persistent VRAM caching from earlier optimization.
2026-02-08 22:24:11 -08:00
Kelsi
2e0a7e0039 Fix taxi mount orientation and eliminate tile loading hitches
Fixes two critical taxi flight issues:

1. Mount orientation now correctly faces flight direction:
   - Prevent camera controller from updating facingYaw during taxi (externalFollow_ check)
   - Taxi orientation callback system updates mount rotation from spline tangent
   - Initial orientation set when flight starts
   - Smooth Catmull-Rom spline interpolation for natural curved paths

2. Eliminate frame hitches from tile loading during flight:
   - New taxiFlightStartCallback uploads ALL precached tiles to GPU before flight begins
   - Previously tiles loaded async during 3s mount delay but uploaded 1/frame during flight
   - Now processAllReadyTiles() blocks briefly after mount delay to batch upload everything
   - Combined with 2.0s terrain update interval and aggressive culling for smooth flight

Additional optimizations:
   - Aggressive taxi culling: skip models <15 units, all foliage/trees, underwater objects
   - Max render distance reduced to 150 units during taxi
   - Movement heartbeat packets disabled during taxi (server controls position)
   - Reduced taxi speed from 32 to 18 units/sec to prevent streaming overload
2026-02-08 22:00:33 -08:00
Kelsi
536b3cea48 Implement comprehensive taxi flight optimizations and proper spline paths
Major improvements:
- Load TaxiPathNode.dbc for actual curved flight paths (no more flying through terrain)
- Add 3-second mounting delay with terrain precaching for entire route
- Implement LOD system for M2 models with distance-based quality reduction
- Add circular terrain loading pattern (13 tiles vs 25, 48% reduction)
- Increase terrain cache from 2GB to 8GB for modern systems

Performance optimizations during taxi:
- Cull small M2 models (boundRadius < 3.0) - not visible from altitude
- Disable particle systems (weather, smoke, M2 emitters) - saves ~7000 particles
- Disable specular lighting on M2 models - saves Blinn-Phong calculations
- Disable shadow mapping on M2 models - saves shadow map sampling and PCF

Technical details:
- Parse TaxiPathNode.dbc spline waypoints for curved paths around terrain
- Build full path from node pairs using TaxiPathEdge lookup
- Precache callback triggers during mounting delay for smooth takeoff
- Circular tile loading uses Euclidean distance check (dx²+dy² <= r²)
- LOD fallback to base mesh when higher LODs unavailable

Result: Buttery smooth taxi flights with no terrain clipping or performance hitches
2026-02-08 21:32:38 -08:00
Kelsi
941dac446d Implement distance-based LOD system for M2 models
Added LOD (Level of Detail) selection based on camera distance:
- 0-40 units: LOD 0 (base detail)
- 40-80 units: LOD 1 (medium detail)
- 80-150 units: LOD 2 (medium-low detail)
- 150+ units: LOD 3 (lowest detail)

Matches WoW retail behavior. Each M2 skin file contains multiple LOD
versions (submeshLevel 0-3). System filters batches to only render
the appropriate LOD for each instance's distance, significantly
improving performance with many distant models.
2026-02-08 20:55:10 -08:00
Kelsi
dbadfb043b Fix stair approach fall-through and relax steep slope climbing
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.
2026-02-08 20:31:00 -08:00
Kelsi
58ec7693a1 Relax walkable slope threshold and floor cache for steep stairs
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.
2026-02-08 20:26:24 -08:00
Kelsi
d7aabc0caa Add M2 collision mesh parsing and mesh-based wall/floor collision
Parse bounding vertices, triangles, and normals from M2 files and use
them for proper triangle-level collision instead of AABB heuristics.
Spatial grid bucketing for efficient queries, closest-point wall push
with soft clamping, and ray-triangle floor detection alongside existing
AABB fallback.
2026-02-08 19:56:17 -08:00
Kelsi
fc003a2aba Soften WMO wall pushback and fix fountain climbing
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.
2026-02-08 18:53:56 -08:00
Kelsi
046d4615ea Fix M2 texture loading, /unstuckgy, and WMO floor detection
- 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.
2026-02-08 14:17:04 -08:00
Kelsi
0ce38cfb99 Add transport support, gameobject queries, and fix item use
- 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
2026-02-08 00:59:40 -08:00
Kelsi
22b9ee9726 Reduce collision trapping and improve /unstuck
Add root, branch, thorn, moss, ivy, and other natural doodads to the no-block foliage list. /unstuck now moves the player 5 units forward instead of resetting in place.
2026-02-07 23:34:28 -08:00
Kelsi
38c9fdad6b Improve targeting, minimap, and bridge collisions 2026-02-07 20:51:53 -08:00
Kelsi
9f19d9fa1a Fix movement, mounts, and terrain seams 2026-02-07 20:24:25 -08:00
Kelsi
361277cf5b Make mushrooms non-blocking foliage 2026-02-07 19:45:09 -08:00
Kelsi
a71902a571 Add tiled particle atlas support 2026-02-07 19:20:37 -08:00
Kelsi
0d94bca896 Fix terrain streaming crash: pendingTiles data race and missing null checks
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.
2026-02-07 18:57:34 -08:00
Kelsi
87aaa30eed Fix carpet sliding and brighten WMO interiors 10%
- 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
2026-02-07 17:09:57 -08:00
Kelsi
2d2b9cc1fc Fix M2 interior lighting and carpet sliding
- M2 interior darkening now uses global player-inside-WMO flag instead
  of per-instance queries that were unreliable
- Fix carpet/rug sliding by skipping lateral collision push when player
  is standing on top of any stepable low object, not just platforms
2026-02-07 17:05:30 -08:00
Kelsi
3c2a728ec4 Add taxi system, fix WMO interior lighting, ramp collision, and /unstuck
- 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
2026-02-07 16:59:20 -08:00
Kelsi
ca88860929 Skip bone computation for off-screen M2 instances, sort by model for batched VAO binds, and eliminate sqrt in distance fade 2026-02-07 14:37:14 -08:00
Kelsi
249c4fa842 Parallelize M2 bone matrix computation across worker threads
Split the M2 animation update loop into three phases: sequential animation state update, parallel bone matrix computation via std::async (when 32+ animated instances), and sequential particle update. Each thread processes a disjoint slice of instances so no synchronization is needed.
2026-02-07 14:28:14 -08:00
Kelsi
104a9d0898 Enable M2 particle emitters with correct WotLK struct parsing and overflow guards 2026-02-06 20:57:02 -08:00
Kelsi
88241cbddc Render M2 glow batches as billboarded light sprites
Replace flat mesh rendering of additive/mod blend batches (blendMode >= 3)
with camera-facing point sprites using a soft radial gradient texture and
additive blending. Adds M2 particle emitter infrastructure (structs, shader,
parsing stubs) but disables emitter parsing — the assumed 476-byte struct
size is wrong for WotLK 3.3.5a, causing misaligned reads that explode RAM.
2026-02-06 08:58:26 -08:00
Kelsi
b9fdc3396d Skip additive/mod blend batches in M2 rendering
These batches are particle emitter placeholder geometry (glow halos,
light volumes) that render as visible transparent discs without a proper
particle system. Skip them entirely instead of attempting to render as
raw mesh geometry.
2026-02-06 08:05:40 -08:00
Kelsi
81b1f87313 Fix lantern glow rendering and add NPC combat animations
Disable depth testing for additive/mod blend mode batches so glow quads
render as proper light halos instead of visible transparent discs. Add
NPC swing callback to play attack animation (anim 16) when NPCs melee
in single-player combat.
2026-02-06 03:39:36 -08:00
Kelsi
e01d80f4eb Add unlit rendering for M2 glow/additive batches
Batches with the M2 unlit material flag (0x01) or additive blend modes
(3+) now skip lighting, shadows, and fog, emitting texture color directly.
Fixes lantern glow quads appearing as dull transparent circles.
2026-02-06 03:28:21 -08:00
Kelsi
4d80b92c39 Parse M2 render flags and apply per-batch blend modes
Water/lava batches in fountain and Ironforge M2 models use non-opaque
blend modes (alpha, additive) defined in the M2 material table. Without
parsing these, they rendered as solid surfaces extending visibly beyond
their containers. Now each batch looks up its blend mode from the
material array and sets the appropriate GL blend function.
2026-02-06 01:54:25 -08:00
Kelsi
ad04da31c3 Implement M2 texture animation (UV scrolling) for fountain water
Parse M2TextureTransform entries and texture transform lookups from the
M2 binary, then apply per-batch UV offsets in the vertex shader using
the existing animation time base and global sequence durations.
2026-02-06 01:49:27 -08:00
Kelsi
3d63c32b7f Reduce foliage and bush pop-in distance artifacts 2026-02-04 16:32:48 -08:00
Kelsi
ab4cb878ea Improve shadow stability and reduce foliage pop-in 2026-02-04 16:30:24 -08:00
Kelsi
979c0b5592 Stabilize shadows and soften foliage shadow casting 2026-02-04 16:22:18 -08:00
Kelsi
09e1ee0ae2 Enable HDR lighting with Reinhard tonemapping across all world shaders
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.
2026-02-04 15:28:47 -08:00
Kelsi
aeccddddeb Add centralized anisotropic filtering, fog, and Blinn-Phong specular to all renderers
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.
2026-02-04 15:05:46 -08:00
Kelsi
c9adcd3d96 Add smoke particle emitters with ember sparks and enable 4x MSAA
Replace UV scroll workaround for chimney smoke with proper GL_POINTS
particle system. Smoke particles rise, expand, drift, and fade over
4-7 seconds. One in eight particles spawns as a bright orange/red
ember spark. Enable 4x multisample antialiasing for smoother edges
on player models, fences, and foliage.
2026-02-04 14:37:32 -08:00
Kelsi
11a4958e84 Add M2 global sequence animation, smoke UV scroll, and fix WMO floor detection
- Parse global sequence durations from M2 binary and use them in bone
  interpolation so torches, candles, and other env doodads animate.
- Add UV scroll shader effect for smoke models (HouseSmoke, SmokeStack)
  as a workaround for unimplemented M2 particle emitters.
- Tighten WMO floor probe heights to prevent multi-story buildings from
  returning the wrong floor, fixing player clipping through inn floors
  and camera locking onto the second floor.
- Use player ground level as reference for camera orbit floor collision
  so the camera doesn't fight upper floors in buildings.
2026-02-04 14:06:59 -08:00
Kelsi
6ca9e9024a Add loading screen, fix tree/foliage collision, jump buffering, and fence rotation
- Loading screen stays visible until all terrain tiles finish streaming;
  character spawns only after terrain is loaded and Z-snapped to ground
- Reduce tree trunk collision bounds (5% of canopy, capped at 5.0) and
  make all small/medium trees, bushes, lily pads, and foliage walkthrough
- Add jump input buffering (150ms) and coyote time (100ms) for responsive jumps
- Fix fence orientation by adding +180° heading rotation
- Increase terrain load radius from 1 to 2 (5x5 tile grid)
- Add hearthstone callback for single-player camera reset
2026-02-04 13:29:27 -08:00
Kelsi
f7cd871895 Add M2 idle animation variations, dedup instances, fix terrain textures
- Add idle variation system: creatures randomly play Stand variations
  (stretch, flap, look around) every 4-10s, then return to idle loop
- Deduplicate M2 instances at same position (was hidden before animation
  made duplicates visible with different random start times)
- Adaptive M2 render distance: 350 units in open terrain, 180 in cities
- Restore terrain sampler-to-unit uniform bindings lost during texture
  bind optimization (roads were invisible under grass)
- Safety: clamp bone count to 128, validate sequence indices, sanitize scale
2026-02-04 11:50:18 -08:00
Kelsi
15fa055726 Add M2 skeletal animation and fix terrain texture layers
- Implement GPU bone skinning for M2 doodads/creatures (gryphons, birds)
- Store bone hierarchy and animation keyframes per model
- Compute bone matrices per-instance with keyframe interpolation
- Upload bone weights/indices in vertex buffer, skinning in vertex shader
- Fix terrain texture rendering: restore sampler-to-unit uniform bindings
  removed during texture bind optimization (roads were invisible)
2026-02-04 11:40:00 -08:00
Kelsi
4bc5064515 Add spellbook, fix WMO floor clipping, and polish UI/visuals
- 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
2026-02-04 11:31:08 -08:00
Kelsi
871172d63e Tune collision behavior for ramps, props, and structural walls 2026-02-03 19:10:22 -08:00
Kelsi
f00d13bfc0 Improve performance and tune ramp/planter collision behavior 2026-02-03 17:21:04 -08:00