Skip to content

fix(MeshHelper): apply submesh baseVertex to triangle indices - #384

Open
nichinichisou0609 wants to merge 2 commits into
K0lb3:masterfrom
nichinichisou0609:codex/mesh-base-vertex
Open

nichinichisou0609 wants to merge 2 commits into
K0lb3:masterfrom
nichinichisou0609:codex/mesh-base-vertex

Conversation

@nichinichisou0609

Copy link
Copy Markdown
Contributor

MeshHandler.get_triangles() currently returns indices without applying the submesh's baseVertex. For a submesh containing [0, 1, 2] with baseVertex = 5, it returns (0, 1, 2) instead of (5, 6, 7). Consumers that index the mesh's complete vertex array consequently select the wrong vertices. In the synthetic OBJ case, the face changes from f 3/3/3 2/2/2 1/1/1 to f 8/8/8 7/7/7 6/6/6, preserving the exporter's winding and one-based indices.

Unity defines SubMeshDescriptor.baseVertex as the offset applied to each stored index, including when a 16-bit index buffer addresses a larger mesh. Mesh.GetTriangles applies that offset by default. These public APIs establish the expected index arithmetic independently of the implementation.

The change adds the submesh's nonzero baseVertex to each triangle corner after the existing topology conversion. Missing, None, and zero values retain their existing behavior. Applying the offset after triangulation covers triangles, triangle strips, and quads without changing their winding or degenerate-strip handling.

The affected path is visible in the base revision: get_triangles() slices the index buffer and converts topology without adding baseVertex; MeshExporter consumes those indices directly when writing OBJ faces. Correcting the helper therefore also corrects exported face references.

The triangulation refactor in #335 and empty-index handling in #381 remain intact. Neither applies this stored offset. AssetStudio reads baseVertex, but its triangulation also leaves it unapplied. The expected results here follow Unity's API contract rather than that exporter's output.

The 19 new regression cases construct in-memory Mesh objects with packed vertex and index buffers. They exercise MeshHandler.process() and the OBJ exporter without external asset files:

  • Nonzero and independent per-submesh offsets, with nonzero firstByte, for 16-bit and 32-bit index buffers.
  • Triangles, triangle strips with degenerates and alternating winding, and quads.
  • Zero, None, and absent baseVertex fields, and repeated reads without modifying the stored indices.
  • OBJ face indices from a small synthetic mesh, exercising the exporter as well as the helper.
  • A 16-bit index buffer with baseVertex = 65536, checking that the resolved indices and OBJ references are not truncated to 16 bits.
  • Packed compressed-mesh triangle indices with a nonzero base vertex, for both index-format values.

Validation on Linux x86_64 with CPython 3.9.25 / pytest 8.4.2 and CPython 3.13.16 / pytest 9.1.1. Both the compiled UnityPyBoost path and the Python fallback were exercised:

Check Result
New regression module against unmodified 417d595 14 failed, 5 passed; failures select the unshifted vertices
Complete suite, CPython 3.9.25 with extension / Python fallback 67 passed / 67 passed
Complete suite, CPython 3.13.16 with extension / Python fallback 67 passed / 67 passed
ruff check and ruff format --check Passed

The existing mesh-helper tests retain coverage for empty submeshes and absent index buffers. To reproduce the checks from the repository root after installing .[tests] and Ruff:

python -m pytest -q tests/test_mesh_base_vertex.py tests/test_mesh_helper.py
python -m pytest -q tests
ruff check
ruff format --check

This patch changes the returned vertex indices for the topologies already supported by get_triangles(). It adds no new topology, vertex-format decoder, serialization behavior, or public option. The fixtures exercise index arithmetic and export behavior. Windows/macOS CI and assets built by multiple Unity Editor versions have not been run for this change.

@nichinichisou0609
nichinichisou0609 marked this pull request as ready for review October 8, 2026 07:14

This branch has not been deployed

No deployments
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.

1 participant