Skip to content

[FEATURE] Per-frame visual vertex deformation for KinematicEntity#2768

Closed
Kashu7100 wants to merge 3 commits into
Genesis-Embodied-AI:mainfrom
Kashu7100:feat-deformable-vmesh
Closed

[FEATURE] Per-frame visual vertex deformation for KinematicEntity#2768
Kashu7100 wants to merge 3 commits into
Genesis-Embodied-AI:mainfrom
Kashu7100:feat-deformable-vmesh

Conversation

@Kashu7100
Copy link
Copy Markdown
Collaborator

Summary

Adds KinematicEntity.set_vverts(vverts, envs_idx=None) so externally-skinned meshes (e.g. SMPL body models, deforming objects) can drive visual vertex positions per frame without going through the per-vgeom transform path.

The rasterizer grows a per-env "skinned" node path: when an entity has has_custom_vverts set, each rendered env gets its own pyrender node and _update_rigid_custom_vverts blits the user vertex buffer into the node's GL buffers (positions and recomputed normals) per frame. The instanced rigid_node is lazily migrated on first use, so paying the per-env cost is opt-in via set_vverts.

Mesh topology is unchanged; only vertex positions move per frame, so the rasterizer's vertex-reorder cache hit path stays valid.

Files changed

  • genesis/engine/entities/rigid_entity/rigid_entity.py_custom_vverts buffer, has_custom_vverts property, set_vverts(vverts, envs_idx=None) API.
  • genesis/vis/rasterizer_context.py — per-env skinned_nodes dict, add_skinned_node, _update_rigid_custom_vverts, _seg_key_for_geom helper extracted for reuse, lazy migration from instanced rigid node.
  • examples/rendering/custom_visual_mesh.py — wave-deforming subdivided box (no external deps) and SMPL body model demo (requires smplx).

Relationship to the previous PR

This PR is the rendering half of #2721. The other half — visual-mesh raycasting (depth camera / lidar against KinematicEntity) — is split into a separate dependent PR.

Test plan

  • python examples/rendering/custom_visual_mesh.py -v renders a wave-deforming box that visibly deforms each frame
  • python examples/rendering/custom_visual_mesh.py -v -B 4 renders 4 batched envs each with their own deformation phase
  • python examples/rendering/custom_visual_mesh.py -v --smpl --model_path <path> renders an animated SMPL body
  • Existing rendering paths unaffected for entities without set_vverts

🤖 Generated with Claude Code

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e7dfd584f8

ℹ️ 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".

Comment thread genesis/vis/rasterizer_context.py Outdated
Kashu7100 and others added 2 commits May 12, 2026 15:25
Adds ``KinematicEntity.set_vverts(vverts, envs_idx=None)`` so externally-
skinned meshes (e.g. SMPL body models, deforming objects) can drive visual
vertex positions without going through the per-vgeom transform path.

The rasterizer grows a per-env "skinned" node path: when an entity has
``has_custom_vverts`` set, each rendered env gets its own pyrender node and
``_update_rigid_custom_vverts`` blits the user vertex buffer into the node's
GL buffers (positions and recomputed normals) per frame. The instanced
rigid_node is lazily migrated on first use.

Mesh topology is unchanged; only vertex positions move per frame, so the
rasterizer's vertex-reorder cache hit path stays valid.

Includes ``examples/rendering/custom_visual_mesh.py`` with two demos:
- A wave-deforming subdivided box (no external dependencies)
- A SMPL body model driven via ``smplx`` (optional dependency)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When an entity rendered in collision or sdf mode also has set_vverts called
on it, the custom-vverts branch took over and continue'd, freezing the
collision/sdf nodes at their initial pose. set_vverts only writes the
visual mesh, so the early-out should be conditional on vis_mode=='visual'.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@duburcqa duburcqa force-pushed the feat-deformable-vmesh branch from 6a1022f to 86c956d Compare May 12, 2026 15:45
@duburcqa duburcqa force-pushed the feat-deformable-vmesh branch from 86c956d to ea7b110 Compare May 12, 2026 16:25
@duburcqa
Copy link
Copy Markdown
Collaborator

it turns out the split is a bad idea. Let's close this and merge with #2769.

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.

2 participants