[FEATURE] Engine-owned visual vertex buffer (set_vverts / get_vverts API)#2776
[FEATURE] Engine-owned visual vertex buffer (set_vverts / get_vverts API)#2776duburcqa wants to merge 5 commits into
Conversation
…ero-copy fallback kernel
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0c6587a54c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| return bool(is_custom[entity.vvert_start, self.rendered_envs_idx].any()) | ||
| return bool(is_custom[entity.vvert_start]) |
There was a problem hiding this comment.
Detect custom vverts across the full entity range
_entity_has_custom_vverts only inspects entity.vvert_start, so it misses overrides written to any later slice (e.g., RigidVisGeom.set_vverts on a non-first vgeom). In that case update_rigid never migrates the entity to the per-env vertex-upload path, and the custom vertices are ignored in rendering/sensors even though set_vverts succeeded. This regresses correctness for multi-vgeom entities where users override a subset that does not include the first vertex.
Useful? React with 👍 / 👎.
56f26e4 to
be93ac4
Compare
be93ac4 to
d63fdd4
Compare
Summary
Adds
vverts_statetoKinematicSolveras the single engine-side ground truth for per-frame world-space visual vertex positions. Surfacesset_vverts/get_vvertsat solver, entity, and vgeom levels. Rasterizer picks up user overrides via a lazy migration to per-env vertex-buffer rendering; collision/sdf rendering is unchanged.This is the renderer half. PR #2769 (visual-mesh raycasting) rebases on top of this — its
kernel_copy_custom_vvertsand parallel_custom_vvertsbuffer go away becausevverts_stateis now the engine-level buffer everyone reads.Supersedes the closed #2768 by relocating the buffer from
KinematicEntityto the solver.Design
vverts_state.pos: gs.qd_vec3, (n_vverts_, B)— populated bykernel_update_all_vverts(vgeom-pose ×init_pos) inKinematicSolver.update_vgeoms.vverts_info.is_custom: gs.qd_int— flips to 1 for entries written byset_vverts. FK skips them so user data survivesstep().KinematicOptions.batch_vverts_info: bool = False(mirrorsbatch_links_info/batch_dofs_info/batch_joints_info). When True, the wholevverts_infostruct gains aBdimension; without it, partialenvs_idxonset_vvertsraises.set_vverts(verts, envs_idx=None)/get_vverts(envs_idx=None)atKinematicSolver,KinematicEntity,Vgeom.vverts=Noneclears. Plane entities are refused.vverts_state.poseach frame. Clear migrates back; the restored render is byte-identical to baseline.set_vvertswhen supported; warns once per build on non-zero-copy backends and uses a fallback kernel.Test plan
tests/test_render.py::test_set_vverts[False-RASTERIZER]and[True-RASTERIZER]cover the API + render path end-to-end (round-trip, broadcast forms, get-returns-copy, vgeom-level write, Plane refusal, migration back, partial-envs error for unbatched, mixed user/FK envs for batched).vverts_infobatching change doesn't break existing consumers (only one ingenesis/vis/batch_renderer.py; adjusted to take env-0 slice when batched).Relationship to other PRs
_custom_vvertsbuffer is gone; engine state on the solver is the new ground truth.kernel_copy_custom_vverts(obsolete —vverts_stateis already the ground truth)._update_visual_bvh_for_solver(just callsolver.update_vgeoms(); FK is properly wired now).entity.has_custom_vvertschecks withis_custom-based logic where still needed.