Correctly apply visibility state from mjvOption.
PiperOrigin-RevId: 948792559 Change-Id: Ic0357c7841519e8e5c903b45f045831745f0b2b3
This commit is contained in:
committed by
Copybara-Service
parent
f841b67c17
commit
3b63fbc6ba
@@ -14,15 +14,15 @@
|
|||||||
|
|
||||||
#include "render/filament/support/renderable_manager.h"
|
#include "render/filament/support/renderable_manager.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <array>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <span>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <math/TVecHelpers.h>
|
||||||
#include <math/mat3.h>
|
#include <math/mat3.h>
|
||||||
#include <math/quat.h>
|
#include <math/quat.h>
|
||||||
#include <math/TVecHelpers.h>
|
|
||||||
#include <math/vec3.h>
|
#include <math/vec3.h>
|
||||||
#include <math/vec4.h>
|
#include <math/vec4.h>
|
||||||
#include <mujoco/mjdata.h>
|
#include <mujoco/mjdata.h>
|
||||||
@@ -208,11 +208,10 @@ RenderableManager::~RenderableManager() {
|
|||||||
mjrf_removeRenderableFromScene(scene_, renderable.get());
|
mjrf_removeRenderableFromScene(scene_, renderable.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto& renderable : sliders_) {
|
for (auto& [_, renderables] : slider_cranks_) {
|
||||||
mjrf_removeRenderableFromScene(scene_, renderable.get());
|
for (auto& renderable : renderables) {
|
||||||
}
|
mjrf_removeRenderableFromScene(scene_, renderable.get());
|
||||||
for (auto& renderable : cranks_) {
|
}
|
||||||
mjrf_removeRenderableFromScene(scene_, renderable.get());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,8 +236,8 @@ void RenderableManager::Update(const mjData* data) {
|
|||||||
const bool smooth_skinning = vopts_.flags[mjVIS_FLEXSKIN];
|
const bool smooth_skinning = vopts_.flags[mjVIS_FLEXSKIN];
|
||||||
const bool edges = !smooth_skinning && vopts_.flags[mjVIS_FLEXEDGE];
|
const bool edges = !smooth_skinning && vopts_.flags[mjVIS_FLEXEDGE];
|
||||||
const bool vertices = !smooth_skinning && vopts_.flags[mjVIS_FLEXVERT];
|
const bool vertices = !smooth_skinning && vopts_.flags[mjVIS_FLEXVERT];
|
||||||
auto mesh = CreateFlexMesh(ctx, model, data, i, flex_layer,
|
auto mesh = CreateFlexMesh(ctx, model, data, i, flex_layer, smooth_skinning,
|
||||||
smooth_skinning, edges, vertices);
|
edges, vertices);
|
||||||
mjrf_setRenderableMesh(flexes_[i].get(), mesh.get(), 0, 0);
|
mjrf_setRenderableMesh(flexes_[i].get(), mesh.get(), 0, 0);
|
||||||
flex_meshes_[i] = std::move(mesh);
|
flex_meshes_[i] = std::move(mesh);
|
||||||
}
|
}
|
||||||
@@ -253,12 +252,10 @@ void RenderableManager::Update(const mjData* data) {
|
|||||||
UpdateSpatialTendons(data, i);
|
UpdateSpatialTendons(data, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
int renderable_index = 0;
|
|
||||||
for (int i = 0; i < model->nu; i++) {
|
for (int i = 0; i < model->nu; i++) {
|
||||||
if (model->actuator_trntype[i] != mjTRN_SLIDERCRANK) {
|
if (model->actuator_trntype[i] == mjTRN_SLIDERCRANK) {
|
||||||
continue;
|
UpdateSliderCranks(data, i);
|
||||||
}
|
}
|
||||||
UpdateSliderCranks(data, i, renderable_index++);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vopts_.flags[mjVIS_ISLAND]) {
|
if (vopts_.flags[mjVIS_ISLAND]) {
|
||||||
@@ -293,13 +290,13 @@ void RenderableManager::Update(const mjData* data) {
|
|||||||
if (model->flex_interp[i]) {
|
if (model->flex_interp[i]) {
|
||||||
int nodeadr = model->flex_nodeadr[i];
|
int nodeadr = model->flex_nodeadr[i];
|
||||||
for (int j = 0; j < model->flex_nodenum[i] && bodyid < 0; j++) {
|
for (int j = 0; j < model->flex_nodenum[i] && bodyid < 0; j++) {
|
||||||
int b = model->flex_nodebodyid[nodeadr+j];
|
int b = model->flex_nodebodyid[nodeadr + j];
|
||||||
if (model->body_treeid[b] >= 0) bodyid = b;
|
if (model->body_treeid[b] >= 0) bodyid = b;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int vertadr = model->flex_vertadr[i];
|
int vertadr = model->flex_vertadr[i];
|
||||||
for (int j=0; j < model->flex_vertnum[i] && bodyid < 0; j++) {
|
for (int j = 0; j < model->flex_vertnum[i] && bodyid < 0; j++) {
|
||||||
int b = model->flex_vertbodyid[vertadr+j];
|
int b = model->flex_vertbodyid[vertadr + j];
|
||||||
if (model->body_treeid[b] >= 0) bodyid = b;
|
if (model->body_treeid[b] >= 0) bodyid = b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -328,8 +325,8 @@ void RenderableManager::Update(const mjData* data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mjrfRenderable* RenderableManager::GetRenderable(mjtObj obj_type,
|
mjrfRenderable* RenderableManager::GetRenderable(mjtObj obj_type, int obj_index,
|
||||||
int obj_index) {
|
int sub_index) {
|
||||||
switch (obj_type) {
|
switch (obj_type) {
|
||||||
case mjOBJ_GEOM:
|
case mjOBJ_GEOM:
|
||||||
if (obj_index >= 0 && obj_index < geoms_.size()) {
|
if (obj_index >= 0 && obj_index < geoms_.size()) {
|
||||||
@@ -351,9 +348,20 @@ mjrfRenderable* RenderableManager::GetRenderable(mjtObj obj_type,
|
|||||||
return skins_[obj_index].get();
|
return skins_[obj_index].get();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case mjOBJ_TENDON:
|
||||||
|
if (obj_index >= 0 && obj_index < tendons_.size()) {
|
||||||
|
auto& segments = tendons_[obj_index];
|
||||||
|
if (sub_index >= 0 && sub_index < segments.size()) {
|
||||||
|
return segments[sub_index].get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case mjOBJ_ACTUATOR:
|
case mjOBJ_ACTUATOR:
|
||||||
if (obj_index >= 0 && obj_index < sliders_.size()) {
|
if (auto it = slider_cranks_.find(obj_index);
|
||||||
return sliders_[obj_index].get();
|
it != slider_cranks_.end()) {
|
||||||
|
if (sub_index >= 0 && sub_index < it->second.size()) {
|
||||||
|
return it->second[sub_index].get();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mjOBJ_BODY: {
|
case mjOBJ_BODY: {
|
||||||
@@ -488,8 +496,6 @@ void RenderableManager::AddSliderCrankGeoms() {
|
|||||||
mjrfRenderableParams params;
|
mjrfRenderableParams params;
|
||||||
mjrf_defaultRenderableParams(¶ms);
|
mjrf_defaultRenderableParams(¶ms);
|
||||||
|
|
||||||
sliders_.reserve(model->nu);
|
|
||||||
cranks_.reserve(model->nu);
|
|
||||||
for (int i = 0; i < model->nu; i++) {
|
for (int i = 0; i < model->nu; i++) {
|
||||||
if (model->actuator_trntype[i] != mjTRN_SLIDERCRANK) {
|
if (model->actuator_trntype[i] != mjTRN_SLIDERCRANK) {
|
||||||
continue;
|
continue;
|
||||||
@@ -500,18 +506,26 @@ void RenderableManager::AddSliderCrankGeoms() {
|
|||||||
mjrf_setRenderableGeomMesh(slider.get(), mjGEOM_CYLINDER, nstack, nslice,
|
mjrf_setRenderableGeomMesh(slider.get(), mjGEOM_CYLINDER, nstack, nslice,
|
||||||
nquad);
|
nquad);
|
||||||
mjrf_addRenderableToScene(scene_, slider.get());
|
mjrf_addRenderableToScene(scene_, slider.get());
|
||||||
sliders_.emplace_back(std::move(slider));
|
|
||||||
|
|
||||||
auto crank = CreateRenderable(ctx, params);
|
auto crank = CreateRenderable(ctx, params);
|
||||||
mjrf_setRenderableGeomMesh(crank.get(), mjGEOM_CAPSULE, nstack, nslice,
|
mjrf_setRenderableGeomMesh(crank.get(), mjGEOM_CAPSULE, nstack, nslice,
|
||||||
nquad);
|
nquad);
|
||||||
mjrf_addRenderableToScene(scene_, crank.get());
|
mjrf_addRenderableToScene(scene_, crank.get());
|
||||||
cranks_.emplace_back(std::move(crank));
|
|
||||||
|
std::array<UniquePtr<mjrfRenderable>, 2> pair{std::move(slider),
|
||||||
|
std::move(crank)};
|
||||||
|
slider_cranks_.emplace(i, std::move(pair));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableManager::UpdateSliderCranks(const mjData* data, int actuator_id,
|
void RenderableManager::UpdateSliderCranks(const mjData* data,
|
||||||
int index) {
|
int actuator_id) {
|
||||||
|
auto it = slider_cranks_.find(actuator_id);
|
||||||
|
if (it == slider_cranks_.end()) {
|
||||||
|
mju_error("Slider/crank not found: %d", actuator_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const mjModel* model = model_objects_->GetModel();
|
const mjModel* model = model_objects_->GetModel();
|
||||||
const float scale = model->stat.meansize;
|
const float scale = model->stat.meansize;
|
||||||
const float slider_width = scale * model->vis.scale.slidercrank;
|
const float slider_width = scale * model->vis.scale.slidercrank;
|
||||||
@@ -539,8 +553,8 @@ void RenderableManager::UpdateSliderCranks(const mjData* data, int actuator_id,
|
|||||||
|
|
||||||
const float3 end = slider_pos + (axis * len);
|
const float3 end = slider_pos + (axis * len);
|
||||||
|
|
||||||
mjrfRenderable* slider = sliders_[index].get();
|
mjrfRenderable* slider = it->second[0].get();
|
||||||
mjrfRenderable* crank = cranks_[index].get();
|
mjrfRenderable* crank = it->second[1].get();
|
||||||
Connect(slider, slider_pos, end, slider_width);
|
Connect(slider, slider_pos, end, slider_width);
|
||||||
Connect(crank, end, crank_pos, crank_width);
|
Connect(crank, end, crank_pos, crank_width);
|
||||||
|
|
||||||
@@ -583,7 +597,8 @@ void RenderableManager::RemoveSegmentFromTendon(int tendon_id) {
|
|||||||
segments.pop_back();
|
segments.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableManager::UpdateSpatialTendons(const mjData* data, int tendon_id) {
|
void RenderableManager::UpdateSpatialTendons(const mjData* data,
|
||||||
|
int tendon_id) {
|
||||||
const mjModel* model = model_objects_->GetModel();
|
const mjModel* model = model_objects_->GetModel();
|
||||||
|
|
||||||
// Gather the points that define the tendon. We'll use a simple cache to avoid
|
// Gather the points that define the tendon. We'll use a simple cache to avoid
|
||||||
@@ -869,85 +884,96 @@ mjrfMaterial RenderableManager::GetDefaultMaterial(mjtObj obj_type,
|
|||||||
return material;
|
return material;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableManager::SelectObject(mjtObj obj_type, int obj_index) {
|
namespace {
|
||||||
if (obj_type != selected_obj_type_ || obj_index != selected_obj_index_) {
|
enum VisibilityOp { kNoop, kShow, kHide };
|
||||||
mjrfMaterial material;
|
}
|
||||||
|
|
||||||
mjrfRenderable* prev_renderable =
|
static void DetermineVisibilities(VisibilityOp* ops, mjtByte* vis_by_group,
|
||||||
GetRenderable(selected_obj_type_, selected_obj_index_);
|
mjtByte* vis_by_flag, int idx, bool visible) {
|
||||||
if (prev_renderable) {
|
const bool prev_global_vis = vis_by_flag ? *vis_by_flag : true;
|
||||||
mjrf_getRenderableMaterial(prev_renderable, &material);
|
const bool curr_global_vis = idx == mjNGROUP ? visible : prev_global_vis;
|
||||||
material.selected = 0;
|
|
||||||
mjrf_setRenderableMaterial(prev_renderable, &material);
|
for (int i = 0; i < mjNGROUP; ++i) {
|
||||||
|
const bool prev_group_vis = vis_by_group[i];
|
||||||
|
const bool curr_group_vis = idx == i ? visible : prev_group_vis;
|
||||||
|
|
||||||
|
const bool previously_visible = prev_global_vis && prev_group_vis;
|
||||||
|
const bool currently_visible = curr_global_vis && curr_group_vis;
|
||||||
|
|
||||||
|
if (previously_visible == currently_visible) {
|
||||||
|
ops[i] = kNoop;
|
||||||
|
} else if (currently_visible) {
|
||||||
|
ops[i] = kShow;
|
||||||
|
} else {
|
||||||
|
ops[i] = kHide;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
selected_obj_type_ = obj_type;
|
if (idx < mjNGROUP) {
|
||||||
selected_obj_index_ = obj_index;
|
vis_by_group[idx] = visible;
|
||||||
|
} else if (vis_by_flag) {
|
||||||
|
*vis_by_flag = visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mjrfRenderable* curr_renderable =
|
static void ApplyVisibility(VisibilityOp* ops, int group, mjrfScene* scene,
|
||||||
GetRenderable(selected_obj_type_, selected_obj_index_);
|
std::span<UniquePtr<mjrfRenderable>> renderables) {
|
||||||
if (curr_renderable) {
|
const VisibilityOp op = ops[group];
|
||||||
mjrf_getRenderableMaterial(curr_renderable, &material);
|
if (op == kShow) {
|
||||||
material.selected = 1;
|
for (auto& renderable : renderables) {
|
||||||
mjrf_setRenderableMaterial(curr_renderable, &material);
|
mjrf_addRenderableToScene(scene, renderable.get());
|
||||||
|
}
|
||||||
|
} else if (op == kHide) {
|
||||||
|
for (auto& renderable : renderables) {
|
||||||
|
mjrf_removeRenderableFromScene(scene, renderable.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableManager::SetVisibility(mjtObj obj_type, bool visible,
|
void RenderableManager::SetVisibility(mjtObj obj_type, int idx, bool visible) {
|
||||||
std::optional<int> group) {
|
|
||||||
const mjModel* model = model_objects_->GetModel();
|
const mjModel* model = model_objects_->GetModel();
|
||||||
|
|
||||||
|
VisibilityOp ops[mjNGROUP] = {kNoop};
|
||||||
switch (obj_type) {
|
switch (obj_type) {
|
||||||
case mjOBJ_GEOM:
|
case mjOBJ_GEOM:
|
||||||
if (group.has_value()) {
|
DetermineVisibilities(ops, vopts_.geomgroup, nullptr, idx, visible);
|
||||||
if (vopts_.geomgroup[group.value()] == visible) {
|
for (int i = 0; i < model->ngeom; ++i) {
|
||||||
return;
|
ApplyVisibility(ops, model->geom_group[i], scene_, {&geoms_[i], 1});
|
||||||
}
|
|
||||||
for (int i = 0; i < model->ngeom; ++i) {
|
|
||||||
if (model->geom_group[i] != group.value()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
mjrfRenderable* renderable = geoms_[i].get();
|
|
||||||
if (visible) {
|
|
||||||
mjrf_addRenderableToScene(scene_, renderable);
|
|
||||||
} else {
|
|
||||||
mjrf_removeRenderableFromScene(scene_, renderable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mju_error("Unsupported object type: %d", obj_type);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mjOBJ_SITE:
|
case mjOBJ_SITE:
|
||||||
if (group.has_value()) {
|
DetermineVisibilities(ops, vopts_.sitegroup, nullptr, idx, visible);
|
||||||
if (vopts_.sitegroup[group.value()] == visible) {
|
for (int i = 0; i < model->nsite; ++i) {
|
||||||
return;
|
ApplyVisibility(ops, model->site_group[i], scene_, {&sites_[i], 1});
|
||||||
}
|
|
||||||
for (int i = 0; i < model->nsite; ++i) {
|
|
||||||
if (model->site_group[i] != group.value()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
mjrfRenderable* renderable = sites_[i].get();
|
|
||||||
if (visible) {
|
|
||||||
mjrf_addRenderableToScene(scene_, renderable);
|
|
||||||
} else {
|
|
||||||
mjrf_removeRenderableFromScene(scene_, renderable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
mju_error("Unsupported object type: %d", obj_type);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case mjOBJ_JOINT:
|
|
||||||
break;
|
|
||||||
case mjOBJ_TENDON:
|
|
||||||
break;
|
|
||||||
case mjOBJ_ACTUATOR:
|
|
||||||
break;
|
|
||||||
case mjOBJ_FLEX:
|
case mjOBJ_FLEX:
|
||||||
|
DetermineVisibilities(ops, vopts_.flexgroup, &vopts_.flags[mjVIS_FLEXSKIN], idx, visible);
|
||||||
|
for (int i = 0; i < model->nflex; ++i) {
|
||||||
|
ApplyVisibility(ops, model->flex_group[i], scene_, {&flexes_[i], 1});
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case mjOBJ_SKIN:
|
case mjOBJ_SKIN:
|
||||||
|
DetermineVisibilities(ops, vopts_.skingroup, &vopts_.flags[mjVIS_SKIN], idx, visible);
|
||||||
|
for (int i = 0; i < model->nskin; ++i) {
|
||||||
|
ApplyVisibility(ops, model->skin_group[i], scene_, {&skins_[i], 1});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case mjOBJ_TENDON:
|
||||||
|
DetermineVisibilities(ops, vopts_.tendongroup, &vopts_.flags[mjVIS_TENDON], idx, visible);
|
||||||
|
for (int i = 0; i < model->ntendon; ++i) {
|
||||||
|
ApplyVisibility(ops, model->tendon_group[i], scene_, tendons_[i]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case mjOBJ_ACTUATOR:
|
||||||
|
DetermineVisibilities(ops, vopts_.actuatorgroup, &vopts_.flags[mjVIS_ACTUATOR], idx, visible);
|
||||||
|
for (int i = 0; i < model->nu; ++i) {
|
||||||
|
auto it = slider_cranks_.find(i);
|
||||||
|
if (it == slider_cranks_.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ApplyVisibility(ops, model->actuator_group[i], scene_, it->second);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mju_error("Unsupported object type: %d", obj_type);
|
mju_error("Unsupported object type: %d", obj_type);
|
||||||
@@ -955,31 +981,49 @@ void RenderableManager::SetVisibility(mjtObj obj_type, bool visible,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderableManager::Apply(const mjvOption& vopts) {
|
void RenderableManager::SetOptions(const mjvOption& opt) {
|
||||||
const mjModel* model = model_objects_->GetModel();
|
const mjModel* model = model_objects_->GetModel();
|
||||||
for (int i = 0; i < mjNGROUP; ++i) {
|
|
||||||
SetVisibility(mjOBJ_GEOM, vopts.geomgroup[i], i);
|
|
||||||
SetVisibility(mjOBJ_SITE, vopts.sitegroup[i], i);
|
|
||||||
SetVisibility(mjOBJ_JOINT, vopts.jointgroup[i], i);
|
|
||||||
SetVisibility(mjOBJ_TENDON, vopts.tendongroup[i], i);
|
|
||||||
SetVisibility(mjOBJ_ACTUATOR, vopts.actuatorgroup[i], i);
|
|
||||||
SetVisibility(mjOBJ_FLEX, vopts.flexgroup[i], i);
|
|
||||||
SetVisibility(mjOBJ_SKIN, vopts.skingroup[i], i);
|
|
||||||
}
|
|
||||||
SetVisibility(mjOBJ_JOINT, vopts.flags[mjVIS_JOINT]);
|
|
||||||
SetVisibility(mjOBJ_TENDON, vopts.flags[mjVIS_TENDON]);
|
|
||||||
SetVisibility(mjOBJ_ACTUATOR, vopts.flags[mjVIS_ACTUATOR]);
|
|
||||||
SetVisibility(mjOBJ_SKIN, vopts.flags[mjVIS_SKIN]);
|
|
||||||
SetVisibility(mjOBJ_FLEX, vopts.flags[mjVIS_FLEXSKIN]);
|
|
||||||
|
|
||||||
// Swap geoms between convex and non-convex meshes based on flags.
|
for (int i = 0; i < mjNGROUP; ++i) {
|
||||||
if (vopts.flags[mjVIS_CONVEXHULL] != vopts_.flags[mjVIS_CONVEXHULL]) {
|
if (vopts_.geomgroup[i] != opt.geomgroup[i]) {
|
||||||
|
SetVisibility(mjOBJ_GEOM, i, opt.geomgroup[i]);
|
||||||
|
}
|
||||||
|
if (vopts_.sitegroup[i] != opt.sitegroup[i]) {
|
||||||
|
SetVisibility(mjOBJ_SITE, i, opt.sitegroup[i]);
|
||||||
|
}
|
||||||
|
if (vopts_.skingroup[i] != opt.skingroup[i]) {
|
||||||
|
SetVisibility(mjOBJ_SKIN, i, opt.skingroup[i]);
|
||||||
|
}
|
||||||
|
if (vopts_.flexgroup[i] != opt.flexgroup[i]) {
|
||||||
|
SetVisibility(mjOBJ_FLEX, i, opt.flexgroup[i]);
|
||||||
|
}
|
||||||
|
if (vopts_.tendongroup[i] != opt.tendongroup[i]) {
|
||||||
|
SetVisibility(mjOBJ_TENDON, i, opt.tendongroup[i]);
|
||||||
|
}
|
||||||
|
if (vopts_.actuatorgroup[i] != opt.actuatorgroup[i]) {
|
||||||
|
SetVisibility(mjOBJ_ACTUATOR, i, opt.actuatorgroup[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vopts_.flags[mjVIS_SKIN] != opt.flags[mjVIS_SKIN]) {
|
||||||
|
SetVisibility(mjOBJ_SKIN, mjNGROUP, opt.flags[mjVIS_SKIN]);
|
||||||
|
}
|
||||||
|
if (vopts_.flags[mjVIS_FLEXSKIN] != opt.flags[mjVIS_FLEXSKIN]) {
|
||||||
|
SetVisibility(mjOBJ_FLEX, mjNGROUP, opt.flags[mjVIS_FLEXSKIN]);
|
||||||
|
}
|
||||||
|
if (vopts_.flags[mjVIS_TENDON] != opt.flags[mjVIS_TENDON]) {
|
||||||
|
SetVisibility(mjOBJ_TENDON, mjNGROUP, opt.flags[mjVIS_TENDON]);
|
||||||
|
}
|
||||||
|
if (vopts_.flags[mjVIS_ACTUATOR] != opt.flags[mjVIS_ACTUATOR]) {
|
||||||
|
SetVisibility(mjOBJ_ACTUATOR, mjNGROUP, opt.flags[mjVIS_ACTUATOR]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vopts_.flags[mjVIS_CONVEXHULL] != opt.flags[mjVIS_CONVEXHULL]) {
|
||||||
for (int i = 0; i < model->ngeom; ++i) {
|
for (int i = 0; i < model->ngeom; ++i) {
|
||||||
const mjtGeom geom_type = (mjtGeom)model->geom_type[i];
|
const mjtGeom geom_type = (mjtGeom)model->geom_type[i];
|
||||||
if (geom_type == mjGEOM_MESH || geom_type == mjGEOM_SDF) {
|
if (geom_type == mjGEOM_MESH || geom_type == mjGEOM_SDF) {
|
||||||
mjrfRenderable* renderable = geoms_[i].get();
|
mjrfRenderable* renderable = geoms_[i].get();
|
||||||
const int mesh_id =
|
const int mesh_id =
|
||||||
model->geom_dataid[i] * 2 + (vopts.flags[mjVIS_CONVEXHULL] ? 1 : 0);
|
model->geom_dataid[i] * 2 + (opt.flags[mjVIS_CONVEXHULL] ? 1 : 0);
|
||||||
const mjrfMesh* mesh = model_objects_->GetMesh(mesh_id);
|
const mjrfMesh* mesh = model_objects_->GetMesh(mesh_id);
|
||||||
if (mesh) {
|
if (mesh) {
|
||||||
mjrf_setRenderableMesh(renderable, mesh, 0, 0);
|
mjrf_setRenderableMesh(renderable, mesh, 0, 0);
|
||||||
@@ -988,10 +1032,9 @@ void RenderableManager::Apply(const mjvOption& vopts) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust alpha of dynamic geoms based on transparent flag.
|
if (vopts_.flags[mjVIS_TRANSPARENT] != opt.flags[mjVIS_TRANSPARENT]) {
|
||||||
if (vopts.flags[mjVIS_TRANSPARENT] != vopts_.flags[mjVIS_TRANSPARENT]) {
|
|
||||||
float multiplier = model->vis.map.alpha;
|
float multiplier = model->vis.map.alpha;
|
||||||
if (!vopts.flags[mjVIS_TRANSPARENT]) {
|
if (!opt.flags[mjVIS_TRANSPARENT]) {
|
||||||
multiplier = 1.0f / multiplier;
|
multiplier = 1.0f / multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1006,7 +1049,32 @@ void RenderableManager::Apply(const mjvOption& vopts) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vopts_ = vopts;
|
vopts_ = opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderableManager::MarkAsSelected(mjtObj obj_type, int obj_index) {
|
||||||
|
if (obj_type != selected_obj_type_ || obj_index != selected_obj_index_) {
|
||||||
|
mjrfMaterial material;
|
||||||
|
|
||||||
|
mjrfRenderable* prev_renderable = GetRenderable(
|
||||||
|
selected_obj_type_, selected_obj_index_);
|
||||||
|
if (prev_renderable) {
|
||||||
|
mjrf_getRenderableMaterial(prev_renderable, &material);
|
||||||
|
material.selected = 0;
|
||||||
|
mjrf_setRenderableMaterial(prev_renderable, &material);
|
||||||
|
}
|
||||||
|
|
||||||
|
selected_obj_type_ = obj_type;
|
||||||
|
selected_obj_index_ = obj_index;
|
||||||
|
|
||||||
|
mjrfRenderable* curr_renderable = GetRenderable(
|
||||||
|
selected_obj_type_, selected_obj_index_);
|
||||||
|
if (curr_renderable) {
|
||||||
|
mjrf_getRenderableMaterial(curr_renderable, &material);
|
||||||
|
material.selected = 1;
|
||||||
|
mjrf_setRenderableMaterial(curr_renderable, &material);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mujoco
|
} // namespace mujoco
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
#ifndef MUJOCO_SRC_EXPERIMENTAL_FILAMENT_COMPAT_RENDERABLE_MANAGER_H_
|
#ifndef MUJOCO_SRC_EXPERIMENTAL_FILAMENT_COMPAT_RENDERABLE_MANAGER_H_
|
||||||
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_COMPAT_RENDERABLE_MANAGER_H_
|
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_COMPAT_RENDERABLE_MANAGER_H_
|
||||||
|
|
||||||
#include <optional>
|
#include <array>
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <math/vec4.h>
|
#include <math/vec4.h>
|
||||||
#include <mujoco/mjdata.h>
|
#include <mujoco/mjdata.h>
|
||||||
@@ -38,7 +39,13 @@ class RenderableManager {
|
|||||||
void Update(const mjData* data);
|
void Update(const mjData* data);
|
||||||
|
|
||||||
// Returns the renderable corresponding to the given model object.
|
// Returns the renderable corresponding to the given model object.
|
||||||
mjrfRenderable* GetRenderable(mjtObj obj_type, int obj_index);
|
// For most objects, the sub_index is ignored. For slider-crank actuators,
|
||||||
|
// sub_index=0 returns the slider, sub_index=1 returns the crank. For tendons,
|
||||||
|
// sub_index is the tendon segment index. The number of segments can vary
|
||||||
|
// between frames so is undefined. If obj_type == mjOBJ_BODY, returns the
|
||||||
|
// geom or site associated with the body.
|
||||||
|
mjrfRenderable* GetRenderable(mjtObj obj_type, int obj_index,
|
||||||
|
int sub_index = -1);
|
||||||
|
|
||||||
// Returns the default material (as defined in the mjModel) for the given
|
// Returns the default material (as defined in the mjModel) for the given
|
||||||
// object. Useful if you want to "reset" the material of a renderable back
|
// object. Useful if you want to "reset" the material of a renderable back
|
||||||
@@ -47,15 +54,21 @@ class RenderableManager {
|
|||||||
|
|
||||||
// Marks the given object as "selected", unmarking any previously selected
|
// Marks the given object as "selected", unmarking any previously selected
|
||||||
// object.
|
// object.
|
||||||
void SelectObject(mjtObj obj_type, int obj_index);
|
void MarkAsSelected(mjtObj obj_type, int obj_index);
|
||||||
|
|
||||||
// Sets the visibility of all renderables of the given type. If `group` is
|
// Sets the visualization options on the renderables. The following options
|
||||||
// specified, only applies to renderables in that group.
|
// are supported:
|
||||||
void SetVisibility(mjtObj obj_type, bool visible,
|
// - shows/hides renderables based on the group visibility
|
||||||
std::optional<int> group = std::nullopt);
|
// - shows/hides renderables based on mjVIS_SKIN, mjVIS_FLEXSKIN,
|
||||||
|
// mjVIS_TENDON, and mjVIS_ACTUATOR flags
|
||||||
|
// - adds island state to materials if mjVIS_ISLAND is enabled
|
||||||
|
// - switches meshes to convex hull mode if mjVIS_CONVEXHULL is enabled
|
||||||
|
// - adjusts alpha values if mjVIS_TRANSPARENT is enabled
|
||||||
|
void SetOptions(const mjvOption& opt);
|
||||||
|
|
||||||
|
// Returns the current visualization options.
|
||||||
|
const mjvOption& GetOptions() const { return vopts_; }
|
||||||
|
|
||||||
// Applies the visualization options to the renderables in the scene.
|
|
||||||
void Apply(const mjvOption& vopts);
|
|
||||||
|
|
||||||
RenderableManager(const RenderableManager&) = delete;
|
RenderableManager(const RenderableManager&) = delete;
|
||||||
RenderableManager& operator=(const RenderableManager&) = delete;
|
RenderableManager& operator=(const RenderableManager&) = delete;
|
||||||
@@ -70,29 +83,29 @@ class RenderableManager {
|
|||||||
void UpdateSpatialTendons(const mjData* data, int tendon_id);
|
void UpdateSpatialTendons(const mjData* data, int tendon_id);
|
||||||
void AppendSegmentToTendon(int tendon_id);
|
void AppendSegmentToTendon(int tendon_id);
|
||||||
void RemoveSegmentFromTendon(int tendon_id);
|
void RemoveSegmentFromTendon(int tendon_id);
|
||||||
void UpdateSliderCranks(const mjData* data, int actuator_id, int index);
|
void UpdateSliderCranks(const mjData* data, int actuator_id);
|
||||||
|
|
||||||
int GetSegmentationId(mjtObj obj_type, int obj_index);
|
int GetSegmentationId(mjtObj obj_type, int obj_index);
|
||||||
|
|
||||||
|
void SetVisibility(mjtObj obj_type, int idx, bool visible);
|
||||||
|
|
||||||
mjrfScene* scene_;
|
mjrfScene* scene_;
|
||||||
ModelObjects* model_objects_;
|
ModelObjects* model_objects_;
|
||||||
|
|
||||||
mjvOption vopts_;
|
mjvOption vopts_;
|
||||||
|
mjtObj selected_obj_type_ = mjOBJ_UNKNOWN;
|
||||||
|
int selected_obj_index_ = -1;
|
||||||
|
|
||||||
std::vector<UniquePtr<mjrfRenderable>> geoms_;
|
std::vector<UniquePtr<mjrfRenderable>> geoms_;
|
||||||
std::vector<UniquePtr<mjrfRenderable>> sites_;
|
std::vector<UniquePtr<mjrfRenderable>> sites_;
|
||||||
std::vector<UniquePtr<mjrfRenderable>> flexes_;
|
std::vector<UniquePtr<mjrfRenderable>> flexes_;
|
||||||
std::vector<UniquePtr<mjrfRenderable>> skins_;
|
std::vector<UniquePtr<mjrfRenderable>> skins_;
|
||||||
std::vector<UniquePtr<mjrfRenderable>> sliders_;
|
std::unordered_map<int, std::array<UniquePtr<mjrfRenderable>, 2>> slider_cranks_;
|
||||||
std::vector<UniquePtr<mjrfRenderable>> cranks_;
|
|
||||||
std::vector<std::vector<UniquePtr<mjrfRenderable>>> tendons_;
|
std::vector<std::vector<UniquePtr<mjrfRenderable>>> tendons_;
|
||||||
|
|
||||||
std::vector<UniquePtr<mjrfMesh>> flex_meshes_;
|
std::vector<UniquePtr<mjrfMesh>> flex_meshes_;
|
||||||
std::vector<UniquePtr<mjrfMesh>> skin_meshes_;
|
std::vector<UniquePtr<mjrfMesh>> skin_meshes_;
|
||||||
std::vector<filament::math::float4> point_cache_;
|
std::vector<filament::math::float4> point_cache_;
|
||||||
|
|
||||||
mjtObj selected_obj_type_ = mjOBJ_UNKNOWN;
|
|
||||||
int selected_obj_index_ = -1;
|
|
||||||
};
|
};
|
||||||
} // namespace mujoco
|
} // namespace mujoco
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user