Skip to content

feat(v2.1.0): MDL/GPU bridge, TPC fix, walkmesh click, specular/frustum/portal culling, save_are, +185 tests (2748 total)#13

Open
genspark-ai-developer[bot] wants to merge 3 commits into
mainfrom
genspark_ai_developer
Open

feat(v2.1.0): MDL/GPU bridge, TPC fix, walkmesh click, specular/frustum/portal culling, save_are, +185 tests (2748 total)#13
genspark-ai-developer[bot] wants to merge 3 commits into
mainfrom
genspark_ai_developer

Conversation

@genspark-ai-developer

@genspark-ai-developer genspark-ai-developer Bot commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

GModular v2.1.0 — Full Feature & Fix Session

Test result: 2748 passed, 7 skipped, 0 failures (was 2,492 at v2.0.15 start of session)


v2.0.14 Changes (test_roadmap_pass8.py — 58 tests)

Feature Reference Status
Specular camera_pos fix — view_dir = normalize(camera_pos - v_world_pos) in all 4 lit shaders McKesson Ch.9, Lengyel §7
CPU normal matrix — cpu_normal_mat uniform via _cpu_normal_matrix() Lengyel §4
Möller-Trumbore ray-triangle — _ray_tri_intersect() + hit_test_walkmesh() Ericson §5.3.6
Frustum culling — _extract_frustum_planes() + _aabb_inside_frustum() + room AABB cache Lengyel §8, Ericson §4
Portal/VIS culling — set_vis_rooms(), _vis_rooms gate in render loop Eberly §7, Ericson §7.6
save_are() — complete GFF V3.2 serialiser for .ARE files xoreos, KotOR spec
GFFStruct.set_field() overload — accepts GFFField objects GFF V3.2 spec

v2.0.15 Changes (test_roadmap_pass9.py — 46 tests)

  • _ray_tri_intersect() edge-case validation (parallel, behind, near-edge, tuple verts, miss outside)
  • hit_test_walkmesh() multi-triangle selection (closest-win, single miss, side-miss, empty, degenerate)
  • set_vis_rooms() portal state management (enable/disable/empty/None/membership)
  • _cpu_normal_matrix() correctness (identity, translation, uniform scale, dtype, shape)
  • Frustum helpers: 6-plane extraction, 4-component planes, empty bypass, inside/behind culling
  • LayoutData.from_string() world-coord preservation (single, two rooms, negative coords, .position tuple)
  • VisibilityData API (are_visible true/false, visible_from, case-insensitive)
  • save_are() / save_ifo() binary validation (ARE/IFO magic bytes, tag-divergence)
  • GFFStruct.set_field() round-trip (GFFField accept, byte value, string, overwrite, in operator)

v2.1.0 Changes (test_roadmap_pass10.py + pass11.py — 81 tests)

Core API fixes

  • MeshData.renderable_nodes() — canonical alias for visible_mesh_nodes() added to mdl_parser.py
  • load_mdl_mesh fix — face-indexed vertex expansion corrected; _upload_textured_mesh called with correct positional args (positions, normals, uvs, uvs2, color)
  • _load_tpc_texture fix — replaced broken TPCReader(bytes).to_rgba() with correct TPCReader.from_bytes(data)TPCImage.rgba_bytes; dimensions read from tpc.width/tpc.height
  • viewport.py < 3,000 lines — trimmed to 2,995; passes TestViewportLineCount

Feature wiring

  • Walkmesh face selection interactivemousePressEvent calls _pick_walkmesh_face(sx, sy) when _walkmesh_edit_mode active; emits walkmesh_face_selected(face_idx, t)
  • VIS portal graph auto-loadedVisibilityData.from_string() called after mod open; set_vis_rooms() receives visible-room set from .vis data

Test fixtures

  • slem_ar.mod rebuilt — now contains slem_ar.mdl + slem_ar.mdx (8 resources, was 5); test_mod_loads_and_has_mdl now passes

Files Changed

File Change
gmodular/formats/mdl_parser.py renderable_nodes() alias added
gmodular/gui/viewport.py load_mdl_mesh fix, _load_tpc_texture fix, walkmesh click wiring, line count trimmed
gmodular/gui/viewport_renderer.py Specular/frustum/portal culling, room AABB cache
gmodular/gui/main_window.py VIS portal graph loaded after mod open
gmodular/gui/animation_panel.py AnimationPlayer seek/elapsed API
tests/test_data/slem_ar.mod Rebuilt with MDL+MDX (ERFWriter)
tests/test_roadmap_pass8.py 58 new tests (v2.0.14)
tests/test_roadmap_pass9.py 46 new tests (v2.0.15)
tests/test_roadmap_pass10.py 49 new tests (v2.1.0)
tests/test_roadmap_pass11.py 32 new tests (v2.1.0)
ROADMAP.md Updated to v2.1.0; Tier 1/2/3 priorities
README.md v2.1.0 What's New; features checklist

Next Priorities (from ROADMAP.md)

Tier 1 — Critical Path:

  1. LYT world-offset integration — ensure RoomPlacement.x/y/z flows to rebuild_room_vaos
  2. TPC textures in rebuild_room_vaos — wire fixed _load_tpc_texture into room-VAO build
  3. Animation signal stubs → real Qt signals — replace pass stubs in animation_panel.py
  4. test_roadmap_pass12.py — cover the above three features

Tier 2 — High Value:
5. Game installation detection (game_detector.py) — mirror PyKotor strategy
6. Module thumbnail generator wired to content browser
7. module_io.py silent-swallow audit

… FBO, LYT parser, render tests

Root cause: _perspective() in viewport_camera.py used OpenGL column-major
convention (proj[2][3]=-1, proj[3][2]=2fn/(n-f)) but was composed with
row-major numpy matrices.  This produced w_clip≈0.044 instead of the
correct ≈22, mapping all room geometry to NDC values >400 — completely
outside the clip frustum and therefore invisible.

Fix (viewport_camera.py):
  - Swap proj[2][3] and proj[3][2] to match row-major convention:
      proj[3][2] = -1        (produces w_clip = -z_eye)
      proj[2][3] = 2fn/(n-f) (produces correct z_clip)
  - Expanded docstring explaining the convention and .T.tobytes() usage.

Fix (viewport_renderer.py):
  - ensure_fbo(): replace simple_framebuffer() (colour-only) with a proper
    RGBA8 + D24 framebuffer so DEPTH_TEST actually works during EGL rendering.
    Without a depth renderbuffer the depth test is a no-op and all faces
    overwrite each other producing a flat uniform colour.
  - Remove _HAS_MDL guard from MDL load path (use try/import instead) so
    headless scripts that import _EGLRenderer directly can still load MDL files.
  - Add _depth_rbo / _color_rbo attributes; release them in release().

Fix (lyt_vis.py LYTParser):
  - Handle beginlayout / donelayout block markers (GModular canonical format).
  - Support 'room N resref x y z' lines both at top level and inside a
    roomcount block, in addition to the classic 'resref x y z' format.
    This fixes zero-room LYT parse results when loading mods written by
    LYTWriter (which emits the GModular format).

Tests (tests/test_viewport_refactor.py):
  - TestProjectionMatrixConvention: 7 tests verifying proj[3][2]==-1,
    proj[2][3]==2fn/(n-f), w_clip formula, target-point visibility, and
    all room-corner visibility.
  - TestEGLRendering: 4 integration tests — mod loads with MDL/MDX,
    LYT parser returns 1 room, w_clip≈distance, and full EGL render
    produces >1% non-background pixels (72 000 pixels, 15% coverage).

Test data:
  - tests/test_data/slem_ar.mod already contains slem_ar.mdl + slem_ar.mdx
    (packed in a previous session).
  - viewport_render_fixed.png: rendered proof image (800×600, 15% coverage).

Results: 2563 passed, 7 skipped in 8.90s (was 2378 passed before these changes).
@genspark-ai-developer genspark-ai-developer Bot changed the title fix(viewport): correct perspective matrix layout — viewport now renders rooms fix(viewport): correct perspective matrix + depth FBO + LYT parser + render tests Mar 20, 2026
Study report (TEXTBOOK_STUDY_REPORT.md):
- Eberly 3D Game Engine Design 2e: three-pass loop, portal rendering,
  Effect objects, LOD nodes, 16-bone palette validation
- Varcholik RT3D Rendering DirectX+HLSL: row-vs-column major validated,
  DXT textures, TBN normal mapping, shadow mapping, instancing
- Ericson Real-Time Collision Detection: AABB tree validated, frustum
  culling algorithm (Lengyel formula), Möller-Trumbore ray-triangle,
  cells-and-portals matches KotOR .vis, spatial coherence caching
- McKesson Learning Modern 3D Graphics: column-major OpenGL explanation,
  non-linear depth / reverse-Z, view_dir specular BUG identified,
  sRGB gamma correction needed, depth precision for outdoor modules
- Lengyel Mathematics for 3D Game Programming 3e: normal matrix CPU
  precompute optimisation, frustum plane extraction formula,
  TBN tangent space, Cook-Torrance BRDF option
- Lengyel Foundations of GED Vol.2 Rendering: UBOs for per-frame data,
  dual quaternion skinning, danglymesh morph targets, FXAA pass,
  portal visibility confirmed as correct KotOR architecture
- Millington Game Physics Engine Development 2e: physics not priority,
  AABB update for moved objects, walkmesh BSP for play mode,
  RK4 for animation splines, damped spring for danglymesh
- Millington Preview Ch.18: 2D physics for room assembly overlap check

ROADMAP.md updates:
- Phase 1: added 1.10 (specular camera_pos fix) and 1.11 (write uniform)
- Phase 2: added 2.9 (Möller-Trumbore ray hit) and 2.10 (2D AABB overlap)
- Phase 3: added 3.8-3.14 (frustum culling, portal culling, normal matrix
  precompute, camera_pos, sRGB, shadow mapping, TBN tangent space)
- Phase 4: added 4.6-4.8 (RK4 splines, danglymesh spring, DQ skinning)
- Phase 5b NEW: Renderer Performance phase (UBOs, instancing, LOD,
  FXAA, reverse-Z, cull/draw pass split, spatial coherence cache)
- Version targets updated to v2.0.13 base, test counts revised upward
- Priority order expanded: specular fix and Möller-Trumbore now top items
@genspark-ai-developer genspark-ai-developer Bot changed the title fix(viewport): correct perspective matrix + depth FBO + LYT parser + render tests fix(viewport): perspective matrix + depth FBO + LYT parser + render tests + textbook study report Mar 21, 2026
…um/portal culling, save_are, +185 tests (2748 total)

## v2.0.15 (test_roadmap_pass9.py — 46 tests)
- _ray_tri_intersect() edge-case validation (parallel, behind, near-edge, tuple verts)
- hit_test_walkmesh() multi-triangle selection (closest-win, empty, degenerate)
- set_vis_rooms() portal state management (enable, disable, empty set, None)
- _cpu_normal_matrix() correctness (identity, translation, uniform scale)
- Frustum helpers: 6-plane extraction, inside/behind culling
- LayoutData.from_string() world-coord preservation + .position tuple
- VisibilityData API (are_visible, visible_from, case-insensitive)
- save_are() / save_ifo() binary validation
- GFFStruct.set_field() round-trip

## v2.1.0 (test_roadmap_pass10.py + test_roadmap_pass11.py — 81 tests)

### Core API fixes
- gmodular/formats/mdl_parser.py: MeshData.renderable_nodes() alias for visible_mesh_nodes()
- gmodular/gui/viewport.py: load_mdl_mesh — correct face-indexed vertex expansion;
  _upload_textured_mesh called with correct positional args
- gmodular/gui/viewport.py: _load_tpc_texture — use TPCReader.from_bytes() + TPCImage.rgba_bytes
  (replaced broken TPCReader(bytes).to_rgba() call)
- gmodular/gui/viewport.py: viewport.py kept under 3,000 lines (trimmed to 2,995)

### Feature wiring
- gmodular/gui/viewport.py: walkmesh face selection now interactive — mousePressEvent
  calls _pick_walkmesh_face(sx,sy) when _walkmesh_edit_mode active; emits
  walkmesh_face_selected(face_idx, t) Signal
- gmodular/gui/main_window.py: VisibilityData.from_string() called after mod load;
  viewport.set_vis_rooms() receives visible-room set from parsed .vis data

### Test fixtures
- tests/test_data/slem_ar.mod: rebuilt with ERFWriter to include slem_ar.mdl + slem_ar.mdx
  (8 resources total, was 5); test_mod_loads_and_has_mdl now passes

### New test files
- tests/test_roadmap_pass10.py: 49 tests (ViewportWidget, MeshNode/MeshData, VisibilityData)
- tests/test_roadmap_pass11.py: 32 tests (TPC API, renderable_nodes, slem_ar fixture)

### Previously in this branch (v2.0.14, test_roadmap_pass8.py — 58 tests)
- Specular camera_pos fix (view_dir = normalize(camera_pos - v_world_pos)) in all 4 shaders
- CPU normal matrix (_cpu_normal_matrix() uniform)
- Moller-Trumbore ray-triangle intersection (_ray_tri_intersect + hit_test_walkmesh)
- Frustum culling (_extract_frustum_planes + _aabb_inside_frustum + room AABB cache)
- Portal/VIS culling (set_vis_rooms, _vis_rooms gate in render loop)
- save_are() — complete GFF V3.2 serialiser for .ARE files
- GFFStruct.set_field() overload accepting GFFField objects

### Docs
- ROADMAP.md: updated to v2.1.0 (2748 tests); session summary tables; Tier 1/2/3 priorities
- README.md: v2.1.0 What's New section; features checklist updated
- TEXTBOOK_STUDY_REPORT.md: eight-book study report

Test result: 2748 passed, 7 skipped, 0 failures
@genspark-ai-developer genspark-ai-developer Bot changed the title fix(viewport): perspective matrix + depth FBO + LYT parser + render tests + textbook study report feat(v2.1.0): MDL/GPU bridge, TPC fix, walkmesh click, specular/frustum/portal culling, save_are, +185 tests (2748 total) Mar 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants