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.
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.
Use CharHairGeosets.dbc to map (race, sex, hairStyleId) to the correct
group 0 scalp mesh instead of the broken 101+hairStyleId formula. Filter
group 0 submeshes so only the body base and correct hair mesh render
(prevents overlapping scalp variants). Fix ItemDisplayInfo.dbc column
indices (5→7) and geoset formulas for equipment. Add CharSections.dbc
hair texture lookup and CharacterFacialHairStyles.dbc support.
For body part batches (group 0) that resolve to white/fallback texture,
fall back to the first valid texture in the model. This handles humanoid
NPCs where body parts use different texture slots that may not be set.
Baked NPC textures must be applied to all skin-related texture slots
(type 1 char skin, type 2 object skin, type 6 hair) since body parts
use different texture slots. Removed separate hair texture lookup as
baked textures already include the complete NPC appearance.
M2 humanoid models have duplicate body meshes - one set for baked textures
and another for skin compositing. Skip body part batches (group 0) that
resolve to white/fallback texture to avoid rendering the wrong set.
Group 0 (body parts 0-18) always renders all submeshes since they represent
different body parts. Other groups filter by exact submeshId match to show
only one variation per group.
Body parts (submeshId 0-99) now always render regardless of activeGeosets.
Other geoset groups (hair, chest, etc.) still require explicit enabling.
This fixes missing body parts while maintaining equipment filtering.
Expanded body part geoset range from 0-18 to 0-99 to cover all humanoid
submesh IDs. Added per-model debug logging to track submesh IDs and
geoset filtering behavior.
M2 batches have a geosetIndex field that determines the geoset group for
filtering (0-18=body, 1xx=hair, etc.). We were incorrectly using submeshId
from the submesh struct instead. Now properly stores and uses geosetId.
Baked NPC textures already include complete appearance (skin, features,
armor). Equipment component textures are designed for player characters
with different UV layout and were causing body parts to disappear.
Add world entry callback that triggers terrain loading when receiving
SMSG_LOGIN_VERIFY_WORLD. Fix coordinate conversion by applying
serverToCanonical() to properly swap X/Y axes from server format.
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
Don't snap player down when detected floor is >2 units below current
position. This prevents falling through upper floors when the raycast
accidentally detects the ground floor through geometry gaps.
- 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.
For Section 0 (body skin) and Section 4 (underwear), the skin color is
stored in colorIndex with variation=0, not the other way around. This
fixes the preview showing no texture for skin colors other than 0.
Render an animated M2 character model in the creation screen using a
dedicated CharacterRenderer with an offscreen FBO. Preview updates on
race/gender/appearance changes, supports mouse-drag rotation, and
composites skin, face, hair scalp, and underwear textures from
CharSections.dbc. Extracts getPlayerModelPath() to a shared free
function in game/character.
Replace the 3D top-down rendered minimap with WoW's native pre-rendered
BLP tile textures loaded via md5translate.trs. Tiles are composited into
a 3x3 grid FBO with proper axis transposition matching the ADT terrain
convention. The screen shader provides camera-rotation, circular mask,
directional player arrow, and 20% transparency. Minimap is now on by
default with the N toggle key removed.
Teleporter panel (T key) lets the player teleport between Goldshire,
Stormwind Gate, Ironforge, and Westfall in single-player mode. Adds
serverToCanonical/canonicalToServer conversion at the network packet
boundary so positions are compatible with TrinityCore/MaNGOS/AzerothCore
emulator servers.
Centralizes all coordinate conversions in core/coordinates.hpp with
proper canonical WoW coords (+X=North, +Y=West, +Z=Up). Fixes critical
tile calculation bug that was loading wrong surrounding tiles during
terrain streaming, and fixes position sync sending ADT-raw format
instead of canonical coordinates to the server.
Drop specular lighting from terrain shader — ground materials (dirt, grass,
stone) are purely diffuse and specular highlights made them look plastic.
Replace Reinhard tonemapper with a shoulder-only compressor that is identity
below 0.9 and softly rolls off HDR values above, preserving scene contrast.
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.