Implement additional draw modes:

- Default rendering but without textures.
- Island coloring based on sleep state.
- Selected object highlighting.

PiperOrigin-RevId: 928482603
Change-Id: I5eda1307bc6e71a4b0b2933b5b941e945cb9de75
This commit is contained in:
Haroon Qureshi
2026-06-08 04:29:00 -07:00
committed by Copybara-Service
parent 543165a6cc
commit da5500c202
3 changed files with 53 additions and 0 deletions
@@ -34,6 +34,7 @@
#include <math/vec4.h>
#include <utils/EntityManager.h>
#include <mujoco/mujoco.h>
#include "engine/engine_vis_visualize.h"
#include "experimental/filament/filament_util.h"
#include "experimental/filament/filament/builtins.h"
#include "experimental/filament/filament/material_manager.h"
@@ -270,6 +271,40 @@ void Renderable::Prepare(std::span<const mjrRenderRequest*> requests,
material.segmentation_id = 0;
}
if (request->draw_mode == mjDRAW_MODE_ISLANDS &&
material.sleep_state != mjS_STATIC) {
float hue = 1.0f;
float saturation = 0.0f;
float value = 0.7f;
if (material.island_id >= 0) {
const double h = static_cast<double>(material.island_id) + 1.0;
hue = mju_Halton(h, 7);
saturation = 0.5 + 0.5 * mju_Halton(h, 3);
value = 0.6 + 0.4 * mju_Halton(h, 5);
}
if (material.sleep_state == mjS_ASLEEP) {
value *= 0.6;
saturation *= 0.7;
}
hsv2rgb(material.color, hue, saturation, value);
material.color[3] = 1;
// Remove textures so they don't interfere with the island color.
material.color_texture = nullptr;
material.metallic_texture = nullptr;
material.roughness_texture = nullptr;
material.occlusion_texture = nullptr;
material.orm_texture = nullptr;
}
if (request->draw_mode == mjDRAW_MODE_DEFAULT_NO_TEXTURES) {
material.color_texture = nullptr;
material.metallic_texture = nullptr;
material.roughness_texture = nullptr;
material.occlusion_texture = nullptr;
material.orm_texture = nullptr;
}
const bool reflective = request->draw_mode == mjDRAW_MODE_DEFAULT &&
request->enable_reflections &&
material.reflectance > 0.0;
@@ -278,6 +313,10 @@ void Renderable::Prepare(std::span<const mjrRenderRequest*> requests,
this, request->viewport.width, request->viewport.height);
}
if (material.selected) {
material.emissive += 0.3f; // vis->global.glow
}
const Mesh* mesh = !parts_.empty() ? parts_[0].mesh : nullptr;
draw_state.material_key = material_mgr_->PrepareMaterialInstance(
material, request->draw_mode, geom_type_, mesh);
@@ -81,6 +81,8 @@ void mjr_defaultMaterial(mjrMaterial* material) {
memset(material, 0, sizeof(mjrMaterial));
setf(material->color, {1.f, 1.f, 1.f, 1.f});
setf(material->uv_scale, {1, 1, 1});
material->sleep_state = mjS_STATIC;
material->island_id = -1;
material->emissive = -1.0f;
material->specular = -1.0f;
material->glossiness = -1.0f;
@@ -129,10 +129,14 @@ void mjrf_destroyContext(mjrfContext* ctx);
typedef enum mjrDrawMode_ {
// Render the scene with default settings for colors and lighting (shading).
mjDRAW_MODE_DEFAULT,
// Like mjDRAW_MODE_DEFAULT, but disable textures.
mjDRAW_MODE_DEFAULT_NO_TEXTURES,
// Render the scene as a wireframe.
mjDRAW_MODE_WIREFRAME,
// Render the scene as a grayscale depth map.
mjDRAW_MODE_DEPTH,
// Render each object using its.
mjDRAW_MODE_ISLANDS,
// Render each object using its segmentation id (see mjrMaterial).
mjDRAW_MODE_SEGMENTATION_BY_ID,
// Render each object with a unique color based on its segmentation id.
@@ -600,6 +604,10 @@ struct mjrMaterial {
// RGB8 color, so only the first 24 bits are used.
int32_t segmentation_id;
// The island ID and sleep state.
int32_t island_id;
mjtSleepState sleep_state;
// Applies an addition scale to the UV coordinates of the object. Defaults to
// (1, 1, 1).
float uv_scale[3];
@@ -630,6 +638,10 @@ struct mjrMaterial {
// used for UX or decorative elements like contact forces and labels.
mjtByte decor_ux;
// If true, renders the object such that it appears "selected" for the
// purposes of UX visualization.
mjtByte selected;
// The texture containing the base color of the object.
const mjrTexture* color_texture;