From f3f12bfad6a4cf974ac0cfbe5c706a4bcf048eb3 Mon Sep 17 00:00:00 2001 From: Haroon Qureshi Date: Mon, 20 Apr 2026 01:23:20 -0700 Subject: [PATCH] Manage dynamic meshes (skins, flexes) in model_objects. Simplifies Renderable as it no longer has the option of owning any Meshes. Instead, the ModelObjects owns the Meshes for flex and skin geom (just like it owns all the other mjModel Meshes). PiperOrigin-RevId: 902485912 Change-Id: I8b9f9d394de6c46f7e25aa4b3885a374aad05294 --- .../filament/filament/model_objects.cc | 18 +++++++--------- .../filament/filament/model_objects.h | 16 +++++++------- .../filament/filament/renderable.cc | 21 +++---------------- .../filament/filament/renderable.h | 8 ++----- .../filament/filament/scene_bridge.cc | 4 ++++ .../filament/filament/scene_geom_util.cc | 14 +++++-------- 6 files changed, 30 insertions(+), 51 deletions(-) diff --git a/src/experimental/filament/filament/model_objects.cc b/src/experimental/filament/filament/model_objects.cc index 1f88dce0..15121743 100644 --- a/src/experimental/filament/filament/model_objects.cc +++ b/src/experimental/filament/filament/model_objects.cc @@ -630,20 +630,11 @@ void ModelObjects::UploadHeightField(const mjModel* model, int id) { height_fields_[id] = std::make_unique(engine_, data); } -MeshPtr ModelObjects::CreateFlexMesh(const mjvScene* scene, - const mjvGeom& geom) { +void ModelObjects::CreateSkinFlexMesh(const mjvScene* scene, const mjvGeom& geom) { MeshData data; DefaultMeshData(&data); UpdateSkinFlexMeshData(&data, model_, scene, geom); - return std::make_unique(engine_, data); -} - -MeshPtr ModelObjects::CreateSkinMesh(const mjvScene* scene, - const mjvGeom& geom) { - MeshData data; - DefaultMeshData(&data); - UpdateSkinFlexMeshData(&data, model_, scene, geom); - return std::make_unique(engine_, data); + dynamic_meshes_[geom.objid] = std::make_unique(engine_, data); } const Mesh* ModelObjects::GetMeshBuffer(int data_id) const { @@ -672,6 +663,11 @@ const Mesh* ModelObjects::GetShapeBuffer(ShapeType shape) const { return shapes_[shape].get(); } +const Mesh* ModelObjects::GetFlexSkinGeomMesh(int geom_id) const { + auto it = dynamic_meshes_.find(geom_id); + return it != dynamic_meshes_.end() ? it->second.get() : nullptr; +} + const Texture* ModelObjects::GetTexture(int tex_id) const { auto it = textures_.find(tex_id); return it != textures_.end() ? it->second.get() : nullptr; diff --git a/src/experimental/filament/filament/model_objects.h b/src/experimental/filament/filament/model_objects.h index bc6a005b..d85693e3 100644 --- a/src/experimental/filament/filament/model_objects.h +++ b/src/experimental/filament/filament/model_objects.h @@ -15,6 +15,7 @@ #ifndef MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_MODEL_OBJECTS_H_ #define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_MODEL_OBJECTS_H_ +#include #include #include #include @@ -55,6 +56,8 @@ class ModelObjects { void UploadHeightField(const mjModel* model, int id); + void CreateSkinFlexMesh(const mjvScene* scene, const mjvGeom& geom); + // Returns the filament engine used by the ModelObjects to create filament // objects. filament::Engine* GetEngine() const { return engine_; } @@ -63,12 +66,10 @@ class ModelObjects { const Mesh* GetShapeBuffer(ShapeType shape) const; const Mesh* GetMeshBuffer(int data_id) const; const Mesh* GetHeightFieldBuffer(int hfield_id) const; + const Mesh* GetFlexSkinGeomMesh(int geom_id) const; const Texture* GetTexture(int tex_id) const; const Texture* GetTexture(int mat_id, int role) const; - MeshPtr CreateFlexMesh(const mjvScene* scene, const mjvGeom& geom); - MeshPtr CreateSkinMesh(const mjvScene* scene, const mjvGeom& geom); - filament::Skybox* CreateSkybox(); filament::IndirectLight* CreateIndirectLight(int tex_id, float intensity); @@ -86,10 +87,11 @@ class ModelObjects { filament::Engine* engine_ = nullptr; std::vector skyboxes_; std::vector indirect_lights_; - std::array shapes_; - std::unordered_map meshes_; - std::unordered_map convex_hulls_; - std::unordered_map height_fields_; + std::array, kNumShapes> shapes_; + std::unordered_map> meshes_; + std::unordered_map> convex_hulls_; + std::unordered_map> height_fields_; + std::unordered_map> dynamic_meshes_; std::unordered_map> textures_; float specular_multiplier_ = 0.2f; float shininess_multiplier_ = 0.1f; diff --git a/src/experimental/filament/filament/renderable.cc b/src/experimental/filament/filament/renderable.cc index 6a3da110..4fc9aaf3 100644 --- a/src/experimental/filament/filament/renderable.cc +++ b/src/experimental/filament/filament/renderable.cc @@ -66,25 +66,12 @@ void Renderable::RemoveLastEntity() { void Renderable::UpdateMesh(int index, const Mesh* mesh, int elem_offset, int elem_count) { - MeshInfo& mesh_info = SetMesh(index, mesh, nullptr, elem_offset, elem_count); - UpdateEntity(index, mesh_info); -} - -void Renderable::UpdateMesh(int index, MeshPtr mesh, int elem_offset, - int elem_count) { - MeshInfo& mesh_info = - SetMesh(index, mesh.get(), std::move(mesh), elem_offset, elem_count); + MeshInfo& mesh_info = SetMesh(index, mesh, elem_offset, elem_count); UpdateEntity(index, mesh_info); } void Renderable::AppendMesh(const Mesh* mesh, int elem_offset, int elem_count) { - MeshInfo& mesh_info = SetMesh(-1, mesh, nullptr, elem_offset, elem_count); - AppendEntity(mesh_info); -} - -void Renderable::AppendMesh(MeshPtr mesh, int elem_offset, int elem_count) { - MeshInfo& mesh_info = - SetMesh(-1, mesh.get(), std::move(mesh), elem_offset, elem_count); + MeshInfo& mesh_info = SetMesh(-1, mesh, elem_offset, elem_count); AppendEntity(mesh_info); } @@ -154,8 +141,7 @@ void Renderable::UpdateEntity(int index, const MeshInfo& mesh_info) { } Renderable::MeshInfo& Renderable::SetMesh(int index, const Mesh* mesh, - MeshPtr owned_mesh, int elem_offset, - int elem_count) { + int elem_offset, int elem_count) { if (index == -1) { index = meshes_.size(); meshes_.emplace_back(); @@ -165,7 +151,6 @@ Renderable::MeshInfo& Renderable::SetMesh(int index, const Mesh* mesh, } MeshInfo* mesh_info = &meshes_[index]; - mesh_info->owned_mesh = std::move(owned_mesh); mesh_info->mesh = mesh; mesh_info->elem_offset = elem_offset; mesh_info->elem_count = elem_count; diff --git a/src/experimental/filament/filament/renderable.h b/src/experimental/filament/filament/renderable.h index dbe03498..016824b8 100644 --- a/src/experimental/filament/filament/renderable.h +++ b/src/experimental/filament/filament/renderable.h @@ -60,15 +60,12 @@ class Renderable { // can be used to specify a submesh to append. If elem_count is 0, assumes // the entire mesh should be appended. void AppendMesh(const Mesh* mesh, int elem_offset = 0, int elem_count = 0); - void AppendMesh(MeshPtr mesh, int elem_offset = 0, int elem_count = 0); // Replaces the mesh at the index with a new mesh. The elem_offset and // elem_count parameters can be used to specify a submesh to append. If // elem_count is 0, assumes the entire mesh should be appended. void UpdateMesh(int index, const Mesh* mesh, int elem_offset = 0, int elem_count = 0); - void UpdateMesh(int index, MeshPtr mesh, int elem_offset = 0, - int elem_count = 0); // Returns the number of meshes that define the renderable. int GetNumMeshes() const { return meshes_.size(); } @@ -124,7 +121,6 @@ class Renderable { private: struct MeshInfo { - MeshPtr owned_mesh; const Mesh* mesh = nullptr; int elem_offset = 0; int elem_count = 0; @@ -132,8 +128,8 @@ class Renderable { // Sets the mesh information for the mesh at the given index. If index is -1, // a new mesh will be appended to the renderable. - MeshInfo& SetMesh(int index, const Mesh* mesh, MeshPtr owned_mesh, - int elem_offset, int elem_count); + MeshInfo& SetMesh(int index, const Mesh* mesh, int elem_offset, + int elem_count); // Appends a new filament::Entity to the renderable, configured to use the // given mesh. diff --git a/src/experimental/filament/filament/scene_bridge.cc b/src/experimental/filament/filament/scene_bridge.cc index e8198b00..3438b8c9 100644 --- a/src/experimental/filament/filament/scene_bridge.cc +++ b/src/experimental/filament/filament/scene_bridge.cc @@ -381,6 +381,10 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) { } } + if (geom->type == mjGEOM_FLEX || geom->type == mjGEOM_SKIN) { + model_objects_->CreateSkinFlexMesh(scene, *geom); + } + std::unique_ptr renderable = CreateGeomRenderable( *geom, scene, object_mgr_, model_objects_.get(), headpos); diff --git a/src/experimental/filament/filament/scene_geom_util.cc b/src/experimental/filament/filament/scene_geom_util.cc index e60bacf4..1b20fd18 100644 --- a/src/experimental/filament/filament/scene_geom_util.cc +++ b/src/experimental/filament/filament/scene_geom_util.cc @@ -96,13 +96,9 @@ static void AddMesh(Renderable& renderable, ModelObjects* model_objs, renderable.AppendMesh(mesh); } -static void AddGeom(Renderable& renderable, ModelObjects* model_objs, - const mjvScene* scene, const mjvGeom& geom) { - if (geom.type == mjGEOM_FLEX) { - renderable.AppendMesh(model_objs->CreateFlexMesh(scene, geom)); - } else if (geom.type == mjGEOM_SKIN) { - renderable.AppendMesh(model_objs->CreateSkinMesh(scene, geom)); - } +static void AddSkinFlexMesh(Renderable& renderable, ModelObjects* model_objs, + int objid) { + renderable.AppendMesh(model_objs->GetFlexSkinGeomMesh(objid)); } static void AddHeightField(Renderable& renderable, ModelObjects* model_objs, @@ -183,10 +179,10 @@ static void PrepareGeomMeshes(Renderable& renderable, const mjvGeom& geom, AddShape(renderable, model_objects, ModelObjects::kTriangle); break; case mjGEOM_FLEX: - AddGeom(renderable, model_objects, scene, geom); + AddSkinFlexMesh(renderable, model_objects, geom.objid); break; case mjGEOM_SKIN: - AddGeom(renderable, model_objects, scene, geom); + AddSkinFlexMesh(renderable, model_objects, geom.objid); break; case mjGEOM_NONE: case mjGEOM_LABEL: