From 9c372fbbea3a24ae75eaa8076038faa9316611f8 Mon Sep 17 00:00:00 2001 From: Haroon Qureshi Date: Thu, 14 May 2026 04:54:00 -0700 Subject: [PATCH] Minor cleanup to scene_geom_util. PiperOrigin-RevId: 915367694 Change-Id: Ia20c3ba050d9f364da5c26f0812bf9a9c5763cd6 --- .../filament/compat/model_objects.cc | 33 +++--- .../filament/compat/model_objects.h | 7 +- .../filament/compat/scene_bridge.cc | 2 +- .../filament/compat/scene_geom_util.cc | 101 +++++++----------- .../filament/compat/scene_geom_util.h | 5 +- 5 files changed, 64 insertions(+), 84 deletions(-) diff --git a/src/experimental/filament/compat/model_objects.cc b/src/experimental/filament/compat/model_objects.cc index dfd7d644..989cc781 100644 --- a/src/experimental/filament/compat/model_objects.cc +++ b/src/experimental/filament/compat/model_objects.cc @@ -602,7 +602,7 @@ void ModelObjects::CreateSkinFlexMesh(const mjvScene* scene, const mjvGeom& geom dynamic_meshes_.insert_or_assign(geom.objid, CreateMesh(ctx_, data)); } -const mjrMesh* ModelObjects::GetMeshBuffer(int data_id) const { +const mjrMesh* ModelObjects::GetMesh(int data_id) const { // As defined by mjv_updateScene: // original mesh: mesh_id * 2 // convex hull: (mesh_id * 2) + 1 @@ -616,27 +616,28 @@ const mjrMesh* ModelObjects::GetMeshBuffer(int data_id) const { } } -const mjrMesh* ModelObjects::GetHeightFieldBuffer(int hfield_id) const { - auto it = height_fields_.find(hfield_id); - return it != height_fields_.end() ? it->second.get() : nullptr; +const mjrMesh* ModelObjects::GetHeightField(int hfield_id) const { + if (auto it = height_fields_.find(hfield_id); it != height_fields_.end()) { + return it->second.get(); + } + mju_error("Unknown height field %d", hfield_id); + return nullptr; } -const mjrMesh* ModelObjects::GetFlexSkinGeomMesh(int geom_id) const { - auto it = dynamic_meshes_.find(geom_id); - return it != dynamic_meshes_.end() ? it->second.get() : nullptr; +const mjrMesh* ModelObjects::GetFlexSkinMesh(int geom_id) const { + if (auto it = dynamic_meshes_.find(geom_id); it != dynamic_meshes_.end()) { + return it->second.get(); + } + mju_error("Unknown dynamic mesh %d", geom_id); + return nullptr; } const mjrTexture* ModelObjects::GetTexture(int tex_id) const { - auto it = textures_.find(tex_id); - return it != textures_.end() ? it->second.get() : nullptr; -} - -const mjrTexture* ModelObjects::GetTexture(int mat_id, int role) const { - if (mat_id < 0 || mat_id >= model_->nmat || role < 0 || role >= mjNTEXROLE) { - return nullptr; + if (auto it = textures_.find(tex_id); it != textures_.end()) { + return it->second.get(); } - const int tex_id = model_->mat_texid[mat_id * mjNTEXROLE + role]; - return GetTexture(tex_id); + mju_error("Unknown texture %d", tex_id); + return nullptr; } const mjrTexture* ModelObjects::GetSkyboxTexture() const { diff --git a/src/experimental/filament/compat/model_objects.h b/src/experimental/filament/compat/model_objects.h index b0bf9036..0cee9ad8 100644 --- a/src/experimental/filament/compat/model_objects.h +++ b/src/experimental/filament/compat/model_objects.h @@ -38,11 +38,10 @@ class ModelObjects { void CreateSkinFlexMesh(const mjvScene* scene, const mjvGeom& geom); // Returns the cached instance of a filament object created from the mjModel. - const mjrMesh* GetMeshBuffer(int data_id) const; - const mjrMesh* GetHeightFieldBuffer(int hfield_id) const; - const mjrMesh* GetFlexSkinGeomMesh(int geom_id) const; + const mjrMesh* GetMesh(int data_id) const; + const mjrMesh* GetHeightField(int hfield_id) const; + const mjrMesh* GetFlexSkinMesh(int geom_id) const; const mjrTexture* GetTexture(int tex_id) const; - const mjrTexture* GetTexture(int mat_id, int role) const; const mjrTexture* GetSkyboxTexture() const; float GetSpecularMultiplier() const { return specular_multiplier_; } diff --git a/src/experimental/filament/compat/scene_bridge.cc b/src/experimental/filament/compat/scene_bridge.cc index ac3a9d37..c87b05a7 100644 --- a/src/experimental/filament/compat/scene_bridge.cc +++ b/src/experimental/filament/compat/scene_bridge.cc @@ -299,7 +299,7 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) { } UniquePtr renderable = CreateGeomRenderable( - *geom, scene, ctx_, model_objects_.get(), headpos); + *geom, ctx_, model_objects_.get(), headpos, scene->flags); mjrf_addRenderableToScene(scene_.get(), renderable.get()); renderables_.push_back(std::move(renderable)); diff --git a/src/experimental/filament/compat/scene_geom_util.cc b/src/experimental/filament/compat/scene_geom_util.cc index 99839645..0ca7dcac 100644 --- a/src/experimental/filament/compat/scene_geom_util.cc +++ b/src/experimental/filament/compat/scene_geom_util.cc @@ -46,30 +46,9 @@ static bool IsBehind(const float* headpos, const float* pos, const float* mat) { 0.0f); } -static const mjrMesh* GetMesh(ModelObjects* model_objs, int data_id) { - const mjrMesh* mesh = model_objs->GetMeshBuffer(data_id); - if (mesh == nullptr) { - mju_error("Unknown mesh %d", data_id); - } - return mesh; -} - -static const mjrMesh* GetSkinFlexMesh(ModelObjects* model_objs, int objid) { - return model_objs->GetFlexSkinGeomMesh(objid); -} - -static const mjrMesh* GetHeightField(ModelObjects* model_objs, int hfield_id) { - const mjrMesh* mesh = model_objs->GetHeightFieldBuffer(hfield_id); - if (mesh == nullptr) { - mju_error("Unknown height field %d", hfield_id); - } - return mesh; -} - static void PrepareGeomMeshes(mjrRenderable* renderable, const mjvGeom& geom, - const mjvScene* scene, - ModelObjects* model_objects) { - const mjModel* model = model_objects->GetModel(); + ModelObjects* model_objs) { + const mjModel* model = model_objs->GetModel(); const int nstack = model->vis.quality.numstacks; const int nslice = model->vis.quality.numslices; const int nquad = model->vis.quality.numquads; @@ -81,24 +60,25 @@ static void PrepareGeomMeshes(mjrRenderable* renderable, const mjvGeom& geom, float size[3]; std::memcpy(size, &geom.size, 3 * sizeof(float)); - switch ((mjtGeom)geom.type) { + const mjtGeom geom_type = (mjtGeom)geom.type; + switch (geom_type) { case mjGEOM_MESH: case mjGEOM_SDF: - mjrf_setRenderableMesh(renderable, GetMesh(model_objects, geom.dataid), 0, 0); + mjrf_setRenderableMesh(renderable, model_objs->GetMesh(geom.dataid), 0, 0); // Ignore size for meshes. size[0] = 1.f; size[1] = 1.f; size[2] = 1.f; break; case mjGEOM_HFIELD: - mjrf_setRenderableMesh(renderable, GetHeightField(model_objects, geom.dataid), 0, 0); + mjrf_setRenderableMesh(renderable, model_objs->GetHeightField(geom.dataid), 0, 0); // Ignore size for meshes. size[0] = 1.f; size[1] = 1.f; size[2] = 1.f; break; case mjGEOM_PLANE: { - mjrf_setRenderableGeomMesh(renderable, (mjtGeom)geom.type, nstack, nslice, nquad); + mjrf_setRenderableGeomMesh(renderable, geom_type, nstack, nslice, nquad); const bool is_infinite = !(size[0] > 0 && size[1] > 0); if (is_infinite) { @@ -113,40 +93,40 @@ static void PrepareGeomMeshes(mjrRenderable* renderable, const mjvGeom& geom, break; } case mjGEOM_SPHERE: - mjrf_setRenderableGeomMesh(renderable, (mjtGeom)geom.type, nstack, nslice, nquad); + mjrf_setRenderableGeomMesh(renderable, geom_type, nstack, nslice, nquad); break; case mjGEOM_ELLIPSOID: - mjrf_setRenderableGeomMesh(renderable, (mjtGeom)geom.type, nstack, nslice, nquad); + mjrf_setRenderableGeomMesh(renderable, geom_type, nstack, nslice, nquad); break; case mjGEOM_BOX: - mjrf_setRenderableGeomMesh(renderable, (mjtGeom)geom.type, nstack, nslice, nquad); + mjrf_setRenderableGeomMesh(renderable, geom_type, nstack, nslice, nquad); break; case mjGEOM_CAPSULE: - mjrf_setRenderableGeomMesh(renderable, (mjtGeom)geom.type, nstack, nslice, nquad); + mjrf_setRenderableGeomMesh(renderable, geom_type, nstack, nslice, nquad); break; case mjGEOM_CYLINDER: - mjrf_setRenderableGeomMesh(renderable, (mjtGeom)geom.type, nstack, nslice, nquad); + mjrf_setRenderableGeomMesh(renderable, geom_type, nstack, nslice, nquad); break; case mjGEOM_ARROW: - mjrf_setRenderableGeomMesh(renderable, (mjtGeom)geom.type, nstack, nslice, nquad); + mjrf_setRenderableGeomMesh(renderable, geom_type, nstack, nslice, nquad); break; case mjGEOM_ARROW1: - mjrf_setRenderableGeomMesh(renderable, (mjtGeom)geom.type, nstack, nslice, nquad); + mjrf_setRenderableGeomMesh(renderable, geom_type, nstack, nslice, nquad); break; case mjGEOM_ARROW2: - mjrf_setRenderableGeomMesh(renderable, (mjtGeom)geom.type, nstack, nslice, nquad); + mjrf_setRenderableGeomMesh(renderable, geom_type, nstack, nslice, nquad); break; case mjGEOM_LINE: - mjrf_setRenderableGeomMesh(renderable, (mjtGeom)geom.type, nstack, nslice, nquad); + mjrf_setRenderableGeomMesh(renderable, geom_type, nstack, nslice, nquad); break; case mjGEOM_LINEBOX: - mjrf_setRenderableGeomMesh(renderable, (mjtGeom)geom.type, nstack, nslice, nquad); + mjrf_setRenderableGeomMesh(renderable, geom_type, nstack, nslice, nquad); break; case mjGEOM_TRIANGLE: - mjrf_setRenderableGeomMesh(renderable, (mjtGeom)geom.type, nstack, nslice, nquad); + mjrf_setRenderableGeomMesh(renderable, geom_type, nstack, nslice, nquad); break; case mjGEOM_FLEX: - mjrf_setRenderableMesh(renderable, GetSkinFlexMesh(model_objects, geom.objid), 0, 0); + mjrf_setRenderableMesh(renderable, model_objs->GetFlexSkinMesh(geom.objid), 0, 0); // Flexes are defined in global space. std::memset(position, 0, sizeof(position)); std::memset(rotation, 0, sizeof(rotation)); @@ -158,7 +138,7 @@ static void PrepareGeomMeshes(mjrRenderable* renderable, const mjvGeom& geom, size[2] = 1.f; break; case mjGEOM_SKIN: - mjrf_setRenderableMesh(renderable, GetSkinFlexMesh(model_objects, geom.objid), 0, 0); + mjrf_setRenderableMesh(renderable, model_objs->GetFlexSkinMesh(geom.objid), 0, 0); // Skins are defined in global space. std::memset(position, 0, sizeof(position)); std::memset(rotation, 0, sizeof(rotation)); @@ -182,11 +162,10 @@ static void PrepareGeomMeshes(mjrRenderable* renderable, const mjvGeom& geom, } static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom, - const mjvScene* scene, ModelObjects* model_objs, - const float headpos[3]) { + ModelObjects* model_objs, const float headpos[3], + const mjtByte render_flags[mjNRNDFLAG]) { const mjModel* model = model_objs->GetModel(); - const bool use_segid_color = scene->flags[mjRND_IDCOLOR]; mjrMaterial material; mjr_defaultMaterial(&material); @@ -213,22 +192,21 @@ static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom, mjrf_setRenderableCastShadows(renderable, false); mjrf_setRenderableReceiveShadows(renderable, false); } else { - mjrf_setRenderableWireframe(renderable, scene->flags[mjRND_WIREFRAME]); + mjrf_setRenderableWireframe(renderable, render_flags[mjRND_WIREFRAME]); } - if (geom.matid >= 0) { - material.color_texture = model_objs->GetTexture(geom.matid, mjTEXROLE_RGB); - material.normal_texture = - model_objs->GetTexture(geom.matid, mjTEXROLE_NORMAL); - material.emissive_texture = - model_objs->GetTexture(geom.matid, mjTEXROLE_EMISSIVE); - material.orm_texture = model_objs->GetTexture(geom.matid, mjTEXROLE_ORM); - material.metallic_texture = - model_objs->GetTexture(geom.matid, mjTEXROLE_METALLIC); - material.roughness_texture = - model_objs->GetTexture(geom.matid, mjTEXROLE_ROUGHNESS); - material.occlusion_texture = - model_objs->GetTexture(geom.matid, mjTEXROLE_OCCLUSION); + if (geom.matid >= 0 && geom.matid < model->nmat) { + auto get_texture = [&](int role) -> const mjrTexture* { + const int tex_id = model->mat_texid[geom.matid * mjNTEXROLE + role]; + return tex_id >= 0 ? model_objs->GetTexture(tex_id) : nullptr; + }; + material.color_texture = get_texture(mjTEXROLE_RGB); + material.normal_texture = get_texture(mjTEXROLE_NORMAL); + material.emissive_texture = get_texture(mjTEXROLE_EMISSIVE); + material.orm_texture = get_texture(mjTEXROLE_ORM); + material.metallic_texture = get_texture(mjTEXROLE_METALLIC); + material.roughness_texture = get_texture(mjTEXROLE_ROUGHNESS); + material.occlusion_texture = get_texture(mjTEXROLE_OCCLUSION); } material.reflectance = geom.reflectance; @@ -242,6 +220,7 @@ static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom, if (geom.segid >= 0) { uint32_t segmentation_color = geom.segid + 1; + const bool use_segid_color = render_flags[mjRND_IDCOLOR]; if (!use_segid_color) { constexpr double phi1 = 1.61803398874989484820; // Cached Phi(1). constexpr double coef1 = 1.0 / phi1; @@ -337,13 +316,13 @@ static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom, } UniquePtr CreateGeomRenderable( - const mjvGeom& geom, const mjvScene* scene, mjrfContext* ctx, - ModelObjects* model_objs, const float headpos[3]) { + const mjvGeom& geom, mjrfContext* ctx, ModelObjects* model_objs, + const float headpos[3], const mjtByte render_flags[mjNRNDFLAG]) { mjrRenderableParams params; mjr_defaultRenderableParams(¶ms); auto renderable = CreateRenderable(ctx, params); - PrepareGeomMeshes(renderable.get(), geom, scene, model_objs); - UpdateGeomMaterial(renderable.get(), geom, scene, model_objs, headpos); + PrepareGeomMeshes(renderable.get(), geom, model_objs); + UpdateGeomMaterial(renderable.get(), geom, model_objs, headpos, render_flags); return renderable; } } // namespace mujoco diff --git a/src/experimental/filament/compat/scene_geom_util.h b/src/experimental/filament/compat/scene_geom_util.h index 7823dca3..89e516a2 100644 --- a/src/experimental/filament/compat/scene_geom_util.h +++ b/src/experimental/filament/compat/scene_geom_util.h @@ -16,6 +16,7 @@ #define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_COMPAT_SCENE_GEOM_UTIL_H_ #include +#include #include "experimental/filament/compat/model_objects.h" #include "experimental/filament/render_context_filament.h" #include "experimental/filament/render_context_filament_cpp.h" @@ -24,8 +25,8 @@ namespace mujoco { // Creates a Renderable from the given mjvGeom. UniquePtr CreateGeomRenderable( - const mjvGeom& geom, const mjvScene* scene, mjrfContext* ctx, - ModelObjects* model_objs, const float headpos[3]); + const mjvGeom& geom, mjrfContext* ctx, ModelObjects* model_objs, + const float headpos[3], const mjtByte render_flags[mjNRNDFLAG]); } // namespace mujoco