Remove Drawable abstraction.
Instead, use a set of functions to create/update a Renderable from an mjvGeom. This completely isolates mjvScene/mjvGeom from SceneView, making SceneView a more general purpose class. PiperOrigin-RevId: 899475268 Change-Id: I48a3a45bc8fff3e1f514847c7a1ca8ab3a1ff16e
This commit is contained in:
committed by
Copybara-Service
parent
171e6dc177
commit
fd5a7004f8
@@ -27,8 +27,6 @@ target_sources(${MUJOCO_FILAMENT_TARGET_NAME}
|
||||
filament/builtins.h
|
||||
filament/color_grading_options.cc
|
||||
filament/color_grading_options.h
|
||||
filament/drawable.cc
|
||||
filament/drawable.h
|
||||
filament/filament_context.cc
|
||||
filament/filament_context.h
|
||||
filament/filament_platform_factory.cc
|
||||
@@ -56,6 +54,8 @@ target_sources(${MUJOCO_FILAMENT_TARGET_NAME}
|
||||
filament/renderable.h
|
||||
filament/scene_bridge.cc
|
||||
filament/scene_bridge.h
|
||||
filament/scene_geom_util.cc
|
||||
filament/scene_geom_util.h
|
||||
filament/scene_view.cc
|
||||
filament/scene_view.h
|
||||
filament/texture.cc
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
// Copyright 2025 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_DRAWABLE_H_
|
||||
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_DRAWABLE_H_
|
||||
|
||||
#include <math/mat4.h>
|
||||
#include <mujoco/mjmodel.h>
|
||||
#include <mujoco/mjtnum.h>
|
||||
#include <mujoco/mjvisualize.h>
|
||||
#include "experimental/filament/filament/material.h"
|
||||
#include "experimental/filament/filament/model_objects.h"
|
||||
#include "experimental/filament/filament/object_manager.h"
|
||||
#include "experimental/filament/filament/renderable.h"
|
||||
|
||||
namespace mujoco {
|
||||
|
||||
// Manages the filament Entities and MaterialInstances for a single mjvGeom.
|
||||
class Drawable {
|
||||
public:
|
||||
Drawable(ModelObjects* model_objects, const mjvScene* scene,
|
||||
const mjvGeom& geom);
|
||||
~Drawable() noexcept = default;
|
||||
|
||||
Drawable(const Drawable&) = delete;
|
||||
Drawable& operator=(const Drawable&) = delete;
|
||||
|
||||
// Updates the transform of the drawable for rendering.
|
||||
void SetTransform(const mjvGeom& geom);
|
||||
|
||||
// Updates the material parameters of the drawable for rendering.
|
||||
void UpdateMaterial(const mjModel* model, const mjvGeom& geom,
|
||||
ModelObjects* model_objs, const float headpos[3],
|
||||
const mjtByte render_flags[mjNRNDFLAG],
|
||||
ObjectManager::MaterialType* out_material_type);
|
||||
|
||||
// Returns the transform of the drawable.
|
||||
const filament::math::mat4& GetTransform() const { return transform_; }
|
||||
|
||||
// Returns the renderable for the drawable.
|
||||
Renderable& GetRenderable() { return renderable_; }
|
||||
|
||||
// Returns the material for the drawable.
|
||||
Material& GetMaterial() { return renderable_.GetMaterial(); }
|
||||
|
||||
private:
|
||||
void AddMesh(ModelObjects* model_objs, int data_id);
|
||||
void AddGeom(ModelObjects* model_objs, const mjvScene* scene,
|
||||
const mjvGeom& geom);
|
||||
void AddHeightField(ModelObjects* model_objs, int hfield_id);
|
||||
void AddShape(ModelObjects* model_objs, ModelObjects::ShapeType shape_type);
|
||||
|
||||
Renderable renderable_;
|
||||
filament::math::mat4 transform_;
|
||||
};
|
||||
|
||||
} // namespace mujoco
|
||||
|
||||
#endif // MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_DRAWABLE_H_
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <filament/RenderTarget.h>
|
||||
#include <filament/Skybox.h>
|
||||
#include <filament/View.h>
|
||||
#include <filament/Viewport.h>
|
||||
#include <math/TMatHelpers.h>
|
||||
#include <math/mat4.h>
|
||||
#include <math/mathfwd.h>
|
||||
@@ -38,7 +37,6 @@
|
||||
#include <math/TVecHelpers.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
#include "experimental/filament/filament/color_grading_options.h"
|
||||
#include "experimental/filament/filament/drawable.h"
|
||||
#include "experimental/filament/filament/gui_view.h"
|
||||
#include "experimental/filament/filament/light.h"
|
||||
#include "experimental/filament/filament/material.h"
|
||||
@@ -46,6 +44,8 @@
|
||||
#include "experimental/filament/filament/model_objects.h"
|
||||
#include "experimental/filament/filament/model_util.h"
|
||||
#include "experimental/filament/filament/object_manager.h"
|
||||
#include "experimental/filament/filament/renderable.h"
|
||||
#include "experimental/filament/filament/scene_geom_util.h"
|
||||
#include "experimental/filament/filament/scene_view.h"
|
||||
|
||||
namespace mujoco {
|
||||
@@ -164,10 +164,10 @@ SceneBridge::~SceneBridge() {
|
||||
}
|
||||
lights_.clear();
|
||||
|
||||
for (auto& iter : drawables_) {
|
||||
for (auto& iter : renderables_) {
|
||||
scene_view_->RemoveFromScene(iter.get());
|
||||
}
|
||||
drawables_.clear();
|
||||
renderables_.clear();
|
||||
}
|
||||
|
||||
void SceneBridge::SetEnvironmentLight(std::string_view filename,
|
||||
@@ -305,16 +305,15 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) {
|
||||
mju_n2f(headpos, hpos, 3);
|
||||
mju_n2f(gazedir, hfwd, 3);
|
||||
|
||||
const mjModel* model = model_objects_->GetModel();
|
||||
const mjvGLCamera gl_camera =
|
||||
mjv_averageCamera(scene->camera, scene->camera + 1);
|
||||
clip_from_world_ = CalculateClipFromWorld(viewport, gl_camera);
|
||||
|
||||
// Remove all drawables from previous render and prepare new ones.
|
||||
for (auto& iter : drawables_) {
|
||||
for (auto& iter : renderables_) {
|
||||
scene_view_->RemoveFromScene(iter.get());
|
||||
}
|
||||
drawables_.clear();
|
||||
renderables_.clear();
|
||||
for (int i = 0; i < scene->ngeom; ++i) {
|
||||
const mjvGeom* geom = scene->geoms + i;
|
||||
|
||||
@@ -324,28 +323,12 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) {
|
||||
}
|
||||
}
|
||||
|
||||
auto drawable =
|
||||
std::make_unique<Drawable>(model_objects_.get(), scene, *geom);
|
||||
drawable->SetTransform(*geom);
|
||||
std::unique_ptr<Renderable> renderable =
|
||||
CreateGeomRenderable(*geom, scene, object_mgr_, model_objects_.get(),
|
||||
headpos, &fallback_textures_);
|
||||
|
||||
ObjectManager::MaterialType material_type = ObjectManager::kNumMaterials;
|
||||
drawable->UpdateMaterial(model, *geom, model_objects_.get(), headpos,
|
||||
scene->flags, &material_type);
|
||||
|
||||
Material& material = drawable->GetMaterial();
|
||||
material.SetFallbackTextures(&fallback_textures_);
|
||||
material.SetMaterial(
|
||||
Material::DrawMode::kNormal,
|
||||
object_mgr_->GetMaterial(material_type));
|
||||
material.SetMaterial(
|
||||
Material::DrawMode::kDepth,
|
||||
object_mgr_->GetMaterial(ObjectManager::kUnlitDepth));
|
||||
material.SetMaterial(
|
||||
Material::DrawMode::kSegmentation,
|
||||
object_mgr_->GetMaterial(ObjectManager::kUnlitSegmentation));
|
||||
|
||||
scene_view_->AddToScene(drawable.get());
|
||||
drawables_.push_back(std::move(drawable));
|
||||
scene_view_->AddToScene(renderable.get());
|
||||
renderables_.push_back(std::move(renderable));
|
||||
}
|
||||
|
||||
bool headlight_enabled = false;
|
||||
|
||||
@@ -24,11 +24,11 @@
|
||||
#include <math/vec3.h>
|
||||
#include <mujoco/mjvisualize.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
#include "experimental/filament/filament/drawable.h"
|
||||
#include "experimental/filament/filament/light.h"
|
||||
#include "experimental/filament/filament/material.h"
|
||||
#include "experimental/filament/filament/model_objects.h"
|
||||
#include "experimental/filament/filament/object_manager.h"
|
||||
#include "experimental/filament/filament/renderable.h"
|
||||
#include "experimental/filament/filament/scene_view.h"
|
||||
|
||||
namespace mujoco {
|
||||
@@ -72,7 +72,7 @@ class SceneBridge {
|
||||
ObjectManager* object_mgr_ = nullptr;
|
||||
std::unique_ptr<ModelObjects> model_objects_;
|
||||
std::vector<std::unique_ptr<Light>> lights_;
|
||||
std::vector<std::unique_ptr<Drawable>> drawables_;
|
||||
std::vector<std::unique_ptr<Renderable>> renderables_;
|
||||
filament::math::mat4 clip_from_world_;
|
||||
int default_shadow_map_size_ = 2048;
|
||||
float default_vsm_blur_width_ = 0.0f;
|
||||
|
||||
+140
-109
@@ -12,10 +12,11 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "experimental/filament/filament/drawable.h"
|
||||
#include "experimental/filament/filament/scene_geom_util.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <numbers>
|
||||
|
||||
#include <filament/Material.h>
|
||||
@@ -81,80 +82,111 @@ static float GetPlaneTileSize(const mjModel* model, int matid,
|
||||
}
|
||||
|
||||
static bool IsBehind(const float* headpos, const float* pos, const float* mat) {
|
||||
return ((headpos[0] - pos[0]) * mat[2] +
|
||||
(headpos[1] - pos[1]) * mat[5] +
|
||||
(headpos[2] - pos[2]) * mat[8] < 0.0f);
|
||||
return ((headpos[0] - pos[0]) * mat[2] + (headpos[1] - pos[1]) * mat[5] +
|
||||
(headpos[2] - pos[2]) * mat[8] <
|
||||
0.0f);
|
||||
}
|
||||
|
||||
Drawable::Drawable(ModelObjects* model_objects, const mjvScene* scene,
|
||||
const mjvGeom& geom)
|
||||
: renderable_(model_objects->GetEngine()) {
|
||||
if (geom.category == mjCAT_DECOR) {
|
||||
renderable_.SetCastShadows(false);
|
||||
renderable_.SetReceiveShadows(false);
|
||||
static void AddMesh(Renderable& renderable, ModelObjects* model_objs,
|
||||
int data_id) {
|
||||
const Mesh* mesh = model_objs->GetMeshBuffer(data_id);
|
||||
if (mesh == nullptr) {
|
||||
mju_error("Unknown mesh %d", data_id);
|
||||
}
|
||||
renderable.Append(mesh);
|
||||
}
|
||||
|
||||
static void AddGeom(Renderable& renderable, ModelObjects* model_objs,
|
||||
const mjvScene* scene, const mjvGeom& geom) {
|
||||
if (geom.type == mjGEOM_FLEX) {
|
||||
renderable.Append(model_objs->CreateFlexMesh(scene, geom));
|
||||
} else if (geom.type == mjGEOM_SKIN) {
|
||||
renderable.Append(model_objs->CreateSkinMesh(scene, geom));
|
||||
}
|
||||
}
|
||||
|
||||
static void AddHeightField(Renderable& renderable, ModelObjects* model_objs,
|
||||
int hfield_id) {
|
||||
const Mesh* mesh = model_objs->GetHeightFieldBuffer(hfield_id);
|
||||
if (mesh == nullptr) {
|
||||
mju_error("Unknown height field %d", hfield_id);
|
||||
}
|
||||
renderable.Append(mesh);
|
||||
}
|
||||
|
||||
static void AddShape(Renderable& renderable, ModelObjects* model_objs,
|
||||
ModelObjects::ShapeType shape_type) {
|
||||
const Mesh* mesh = model_objs->GetShapeBuffer(shape_type);
|
||||
if (mesh == nullptr) {
|
||||
mju_error("Unknown shape %d", shape_type);
|
||||
}
|
||||
renderable.Append(mesh);
|
||||
}
|
||||
|
||||
static void PrepareGeomMeshes(Renderable& renderable, const mjvGeom& geom,
|
||||
const mjvScene* scene,
|
||||
ModelObjects* model_objects) {
|
||||
switch ((mjtGeom)geom.type) {
|
||||
case mjGEOM_MESH:
|
||||
AddMesh(model_objects, geom.dataid);
|
||||
AddMesh(renderable, model_objects, geom.dataid);
|
||||
break;
|
||||
case mjGEOM_HFIELD:
|
||||
AddHeightField(model_objects, geom.dataid);
|
||||
AddHeightField(renderable, model_objects, geom.dataid);
|
||||
break;
|
||||
case mjGEOM_PLANE:
|
||||
AddShape(model_objects, ModelObjects::kPlane);
|
||||
AddShape(renderable, model_objects, ModelObjects::kPlane);
|
||||
break;
|
||||
case mjGEOM_SPHERE:
|
||||
AddShape(model_objects, ModelObjects::kSphere);
|
||||
AddShape(renderable, model_objects, ModelObjects::kSphere);
|
||||
break;
|
||||
case mjGEOM_ELLIPSOID:
|
||||
AddShape(model_objects, ModelObjects::kSphere);
|
||||
AddShape(renderable, model_objects, ModelObjects::kSphere);
|
||||
break;
|
||||
case mjGEOM_BOX:
|
||||
AddShape(model_objects, ModelObjects::kBox);
|
||||
AddShape(renderable, model_objects, ModelObjects::kBox);
|
||||
break;
|
||||
case mjGEOM_CAPSULE:
|
||||
AddShape(model_objects, ModelObjects::kTube);
|
||||
AddShape(model_objects, ModelObjects::kDome);
|
||||
AddShape(model_objects, ModelObjects::kDome);
|
||||
AddShape(renderable, model_objects, ModelObjects::kTube);
|
||||
AddShape(renderable, model_objects, ModelObjects::kDome);
|
||||
AddShape(renderable, model_objects, ModelObjects::kDome);
|
||||
break;
|
||||
case mjGEOM_CYLINDER:
|
||||
AddShape(model_objects, ModelObjects::kTube);
|
||||
AddShape(model_objects, ModelObjects::kDisk);
|
||||
AddShape(model_objects, ModelObjects::kDisk);
|
||||
AddShape(renderable, model_objects, ModelObjects::kTube);
|
||||
AddShape(renderable, model_objects, ModelObjects::kDisk);
|
||||
AddShape(renderable, model_objects, ModelObjects::kDisk);
|
||||
break;
|
||||
case mjGEOM_ARROW:
|
||||
AddShape(model_objects, ModelObjects::kTube);
|
||||
AddShape(model_objects, ModelObjects::kCone);
|
||||
AddShape(model_objects, ModelObjects::kDisk);
|
||||
AddShape(renderable, model_objects, ModelObjects::kTube);
|
||||
AddShape(renderable, model_objects, ModelObjects::kCone);
|
||||
AddShape(renderable, model_objects, ModelObjects::kDisk);
|
||||
break;
|
||||
case mjGEOM_ARROW1:
|
||||
AddShape(model_objects, ModelObjects::kTube);
|
||||
AddShape(model_objects, ModelObjects::kCone);
|
||||
AddShape(model_objects, ModelObjects::kDisk);
|
||||
AddShape(model_objects, ModelObjects::kDisk);
|
||||
AddShape(renderable, model_objects, ModelObjects::kTube);
|
||||
AddShape(renderable, model_objects, ModelObjects::kCone);
|
||||
AddShape(renderable, model_objects, ModelObjects::kDisk);
|
||||
AddShape(renderable, model_objects, ModelObjects::kDisk);
|
||||
break;
|
||||
case mjGEOM_ARROW2:
|
||||
AddShape(model_objects, ModelObjects::kTube);
|
||||
AddShape(model_objects, ModelObjects::kCone);
|
||||
AddShape(model_objects, ModelObjects::kCone);
|
||||
AddShape(model_objects, ModelObjects::kDisk);
|
||||
AddShape(model_objects, ModelObjects::kDisk);
|
||||
AddShape(renderable, model_objects, ModelObjects::kTube);
|
||||
AddShape(renderable, model_objects, ModelObjects::kCone);
|
||||
AddShape(renderable, model_objects, ModelObjects::kCone);
|
||||
AddShape(renderable, model_objects, ModelObjects::kDisk);
|
||||
AddShape(renderable, model_objects, ModelObjects::kDisk);
|
||||
break;
|
||||
case mjGEOM_LINE:
|
||||
AddShape(model_objects, ModelObjects::kLine);
|
||||
AddShape(renderable, model_objects, ModelObjects::kLine);
|
||||
break;
|
||||
case mjGEOM_LINEBOX:
|
||||
AddShape(model_objects, ModelObjects::kLineBox);
|
||||
AddShape(renderable, model_objects, ModelObjects::kLineBox);
|
||||
break;
|
||||
case mjGEOM_TRIANGLE:
|
||||
AddShape(model_objects, ModelObjects::kTriangle);
|
||||
AddShape(renderable, model_objects, ModelObjects::kTriangle);
|
||||
break;
|
||||
case mjGEOM_FLEX:
|
||||
AddGeom(model_objects, scene, geom);
|
||||
AddGeom(renderable, model_objects, scene, geom);
|
||||
break;
|
||||
case mjGEOM_SKIN:
|
||||
AddGeom(model_objects, scene, geom);
|
||||
AddGeom(renderable, model_objects, scene, geom);
|
||||
break;
|
||||
case mjGEOM_NONE:
|
||||
case mjGEOM_LABEL:
|
||||
@@ -167,56 +199,22 @@ Drawable::Drawable(ModelObjects* model_objects, const mjvScene* scene,
|
||||
}
|
||||
}
|
||||
|
||||
void Drawable::AddMesh(ModelObjects* model_objs, int data_id) {
|
||||
const Mesh* mesh = model_objs->GetMeshBuffer(data_id);
|
||||
if (mesh == nullptr) {
|
||||
mju_error("Unknown mesh %d", data_id);
|
||||
}
|
||||
renderable_.Append(mesh);
|
||||
}
|
||||
|
||||
void Drawable::AddGeom(ModelObjects* model_objs, const mjvScene* scene,
|
||||
const mjvGeom& geom) {
|
||||
if (geom.type == mjGEOM_FLEX) {
|
||||
renderable_.Append(model_objs->CreateFlexMesh(scene, geom));
|
||||
} else if (geom.type == mjGEOM_SKIN) {
|
||||
renderable_.Append(model_objs->CreateSkinMesh(scene, geom));
|
||||
}
|
||||
}
|
||||
|
||||
void Drawable::AddHeightField(ModelObjects* model_objs, int hfield_id) {
|
||||
const Mesh* mesh = model_objs->GetHeightFieldBuffer(hfield_id);
|
||||
if (mesh == nullptr) {
|
||||
mju_error("Unknown height field %d", hfield_id);
|
||||
}
|
||||
renderable_.Append(mesh);
|
||||
}
|
||||
|
||||
void Drawable::AddShape(ModelObjects* model_objs,
|
||||
ModelObjects::ShapeType shape_type) {
|
||||
const Mesh* mesh = model_objs->GetShapeBuffer(shape_type);
|
||||
if (mesh == nullptr) {
|
||||
mju_error("Unknown shape %d", shape_type);
|
||||
}
|
||||
renderable_.Append(mesh);
|
||||
}
|
||||
|
||||
void Drawable::SetTransform(const mjvGeom& geom) {
|
||||
static void SetGeomTransform(Renderable& renderable, const mjvGeom& geom) {
|
||||
// Flex and skin geometries are in global space.
|
||||
if (geom.type == mjGEOM_FLEX || geom.type == mjGEOM_SKIN) {
|
||||
return;
|
||||
}
|
||||
|
||||
transform_ = mat4(ReadMat3(geom.mat), ReadFloat3(geom.pos));
|
||||
mat4 transform = mat4(ReadMat3(geom.mat), ReadFloat3(geom.pos));
|
||||
|
||||
float3 size = ReadFloat3(geom.size);
|
||||
filament::TransformManager& tm =
|
||||
renderable_.GetEngine()->getTransformManager();
|
||||
for (int j = 0; j < renderable_.GetNumEntities(); ++j) {
|
||||
const utils::Entity& entity = renderable_[j];
|
||||
renderable.GetEngine()->getTransformManager();
|
||||
for (int j = 0; j < renderable.GetNumEntities(); ++j) {
|
||||
const utils::Entity& entity = renderable[j];
|
||||
|
||||
// Update object transform.
|
||||
mat4 entity_transform = transform_;
|
||||
mat4 entity_transform = transform;
|
||||
|
||||
// Some built-in drawables are composed of multiple entities. For example,
|
||||
// capsules are a combination of a open tube and two dome end caps.
|
||||
@@ -318,27 +316,34 @@ void Drawable::SetTransform(const mjvGeom& geom) {
|
||||
}
|
||||
}
|
||||
|
||||
void Drawable::UpdateMaterial(const mjModel* model, const mjvGeom& geom,
|
||||
ModelObjects* model_objs, const float headpos[3],
|
||||
const mjtByte render_flags[mjNRNDFLAG],
|
||||
ObjectManager::MaterialType* out_material_type) {
|
||||
const bool use_segid_color = render_flags[mjRND_IDCOLOR];
|
||||
const bool enable_reflection = render_flags[mjRND_REFLECTION];
|
||||
static void UpdateGeomMaterial(Renderable& renderable, const mjvGeom& geom,
|
||||
const mjvScene* scene, ModelObjects* model_objs,
|
||||
ObjectManager* object_mgr,
|
||||
const float headpos[3]) {
|
||||
const mjModel* model = model_objs->GetModel();
|
||||
Material& material = renderable.GetMaterial();
|
||||
|
||||
const bool use_segid_color = scene->flags[mjRND_IDCOLOR];
|
||||
const bool enable_reflection = scene->flags[mjRND_REFLECTION];
|
||||
|
||||
Material::Params params;
|
||||
params.color = ReadFloat4(geom.rgba);
|
||||
if (geom.type == mjGEOM_PLANE) {
|
||||
if (IsBehind(headpos, geom.pos, geom.mat)) {
|
||||
params.color[3] *= 0.3;
|
||||
renderable_.SetReceiveShadows(false);
|
||||
renderable.SetReceiveShadows(false);
|
||||
params.reflective = false;
|
||||
} else {
|
||||
renderable_.SetReceiveShadows(true);
|
||||
renderable.SetReceiveShadows(true);
|
||||
params.reflective =
|
||||
enable_reflection && geom.reflectance > 0 && params.color.a == 1.0f;
|
||||
}
|
||||
}
|
||||
renderable_.SetWireframe(render_flags[mjRND_WIREFRAME]);
|
||||
renderable.SetWireframe(scene->flags[mjRND_WIREFRAME]);
|
||||
if (geom.category == mjCAT_DECOR) {
|
||||
renderable.SetCastShadows(false);
|
||||
renderable.SetReceiveShadows(false);
|
||||
}
|
||||
|
||||
Material::Textures textures;
|
||||
if (geom.matid >= 0) {
|
||||
@@ -351,25 +356,26 @@ void Drawable::UpdateMaterial(const mjModel* model, const mjvGeom& geom,
|
||||
model_objs->GetTexture(geom.matid, mjTEXROLE_ROUGHNESS);
|
||||
textures.occlusion =
|
||||
model_objs->GetTexture(geom.matid, mjTEXROLE_OCCLUSION);
|
||||
GetMaterial().UpdateTextures(textures);
|
||||
material.UpdateTextures(textures);
|
||||
}
|
||||
|
||||
ObjectManager::MaterialType material_type = ObjectManager::kNumMaterials;
|
||||
if (geom.type == mjGEOM_LINE || geom.type == mjGEOM_LINEBOX) {
|
||||
*out_material_type = ObjectManager::kUnlitLine;
|
||||
material_type = ObjectManager::kUnlitLine;
|
||||
} else {
|
||||
bool material_assigned = false;
|
||||
if (geom.matid >= 0) {
|
||||
material_assigned = true;
|
||||
if (textures.orm) {
|
||||
*out_material_type = ObjectManager::kPbrPacked;
|
||||
material_type = ObjectManager::kPbrPacked;
|
||||
} else if (textures.metallic) {
|
||||
*out_material_type = ObjectManager::kPbr;
|
||||
material_type = ObjectManager::kPbr;
|
||||
} else if (textures.roughness) {
|
||||
*out_material_type = ObjectManager::kPbr;
|
||||
material_type = ObjectManager::kPbr;
|
||||
} else if (model->mat_metallic[geom.matid] >= 0) {
|
||||
*out_material_type = ObjectManager::kPbr;
|
||||
material_type = ObjectManager::kPbr;
|
||||
} else if (model->mat_roughness[geom.matid] >= 0) {
|
||||
*out_material_type = ObjectManager::kPbr;
|
||||
material_type = ObjectManager::kPbr;
|
||||
} else {
|
||||
material_assigned = false;
|
||||
}
|
||||
@@ -388,36 +394,36 @@ void Drawable::UpdateMaterial(const mjModel* model, const mjvGeom& geom,
|
||||
|
||||
if (textures.color == nullptr) {
|
||||
if (params.color.a < 1.0f) {
|
||||
*out_material_type = ObjectManager::kPhongColorFade;
|
||||
material_type = ObjectManager::kPhongColorFade;
|
||||
} else if (params.reflective) {
|
||||
*out_material_type = ObjectManager::kPhongColorReflect;
|
||||
material_type = ObjectManager::kPhongColorReflect;
|
||||
} else {
|
||||
*out_material_type = ObjectManager::kPhongColor;
|
||||
material_type = ObjectManager::kPhongColor;
|
||||
}
|
||||
} else if (textures.color->GetFilamentTexture()->getTarget() ==
|
||||
filament::Texture::Sampler::SAMPLER_CUBEMAP) {
|
||||
filament::Texture::Sampler::SAMPLER_CUBEMAP) {
|
||||
if (params.color.a < 1.0f) {
|
||||
*out_material_type = ObjectManager::kPhongCubeFade;
|
||||
material_type = ObjectManager::kPhongCubeFade;
|
||||
} else if (params.reflective) {
|
||||
*out_material_type = ObjectManager::kPhongCubeReflect;
|
||||
material_type = ObjectManager::kPhongCubeReflect;
|
||||
} else {
|
||||
*out_material_type = ObjectManager::kPhongCube;
|
||||
material_type = ObjectManager::kPhongCube;
|
||||
}
|
||||
} else if (has_texcoords) {
|
||||
if (params.color.a < 1.0f) {
|
||||
*out_material_type = ObjectManager::kPhong2dUvFade;
|
||||
material_type = ObjectManager::kPhong2dUvFade;
|
||||
} else if (params.reflective) {
|
||||
*out_material_type = ObjectManager::kPhong2dUvReflect;
|
||||
material_type = ObjectManager::kPhong2dUvReflect;
|
||||
} else {
|
||||
*out_material_type = ObjectManager::kPhong2dUv;
|
||||
material_type = ObjectManager::kPhong2dUv;
|
||||
}
|
||||
} else {
|
||||
if (params.color.a < 1.0f) {
|
||||
*out_material_type = ObjectManager::kPhong2dFade;
|
||||
material_type = ObjectManager::kPhong2dFade;
|
||||
} else if (params.reflective) {
|
||||
*out_material_type = ObjectManager::kPhong2dReflect;
|
||||
material_type = ObjectManager::kPhong2dReflect;
|
||||
} else {
|
||||
*out_material_type = ObjectManager::kPhong2d;
|
||||
material_type = ObjectManager::kPhong2d;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -522,7 +528,32 @@ void Drawable::UpdateMaterial(const mjModel* model, const mjvGeom& geom,
|
||||
params.emissive *= model_objs->GetEmissiveMultiplier();
|
||||
params.specular *= model_objs->GetSpecularMultiplier();
|
||||
params.glossiness *= model_objs->GetShininessMultiplier();
|
||||
material.UpdateParams(params);
|
||||
|
||||
GetMaterial().UpdateParams(params);
|
||||
material.SetMaterial(
|
||||
Material::DrawMode::kNormal,
|
||||
object_mgr->GetMaterial(material_type));
|
||||
material.SetMaterial(
|
||||
Material::DrawMode::kDepth,
|
||||
object_mgr->GetMaterial(ObjectManager::kUnlitDepth));
|
||||
material.SetMaterial(
|
||||
Material::DrawMode::kSegmentation,
|
||||
object_mgr->GetMaterial(ObjectManager::kUnlitSegmentation));
|
||||
}
|
||||
|
||||
std::unique_ptr<Renderable> CreateGeomRenderable(
|
||||
const mjvGeom& geom, const mjvScene* scene, ObjectManager* object_mgr,
|
||||
ModelObjects* model_objs, const float headpos[3],
|
||||
Material::Textures* fallback_textures) {
|
||||
auto renderable = std::make_unique<Renderable>(model_objs->GetEngine());
|
||||
|
||||
// The order of these calls is important. e.g. We need to create the filament
|
||||
// renderable entities before we can set their transform.
|
||||
PrepareGeomMeshes(*renderable, geom, scene, model_objs);
|
||||
SetGeomTransform(*renderable, geom);
|
||||
renderable->GetMaterial().SetFallbackTextures(fallback_textures);
|
||||
UpdateGeomMaterial(*renderable, geom, scene, model_objs, object_mgr, headpos);
|
||||
|
||||
return renderable;
|
||||
}
|
||||
} // namespace mujoco
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright 2025 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_SCENE_GEOM_UTIL_H_
|
||||
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_SCENE_GEOM_UTIL_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <mujoco/mjvisualize.h>
|
||||
#include "experimental/filament/filament/material.h"
|
||||
#include "experimental/filament/filament/model_objects.h"
|
||||
#include "experimental/filament/filament/object_manager.h"
|
||||
#include "experimental/filament/filament/renderable.h"
|
||||
|
||||
namespace mujoco {
|
||||
|
||||
// Creates a Renderable from the given mjvGeom.
|
||||
std::unique_ptr<Renderable> CreateGeomRenderable(
|
||||
const mjvGeom& geom, const mjvScene* scene, ObjectManager* object_mgr,
|
||||
ModelObjects* model_objs, const float headpos[3],
|
||||
Material::Textures* fallback_textures);
|
||||
|
||||
} // namespace mujoco
|
||||
|
||||
#endif // MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_SCENE_GEOM_UTIL_H_
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <utils/EntityManager.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
#include "experimental/filament/filament/color_grading_options.h"
|
||||
#include "experimental/filament/filament/drawable.h"
|
||||
#include "experimental/filament/filament/light.h"
|
||||
#include "experimental/filament/filament/material.h"
|
||||
#include "experimental/filament/filament/math_util.h"
|
||||
@@ -162,11 +161,11 @@ SceneView::~SceneView() {
|
||||
for (auto& light : lights_) {
|
||||
light->RemoveFromScene(scene_);
|
||||
}
|
||||
for (auto& drawable : drawables_) {
|
||||
drawable->GetRenderable().RemoveFromScene(scene_);
|
||||
for (auto& renderable : renderables_) {
|
||||
renderable->RemoveFromScene(scene_);
|
||||
}
|
||||
lights_.clear();
|
||||
drawables_.clear();
|
||||
renderables_.clear();
|
||||
reflect_targets_.clear();
|
||||
engine_->destroyCameraComponent(reflect_camera_->getEntity());
|
||||
engine_->destroy(reflect_view_);
|
||||
@@ -192,22 +191,22 @@ void SceneView::RemoveFromScene(Light* light) {
|
||||
}
|
||||
}
|
||||
|
||||
void SceneView::AddToScene(Drawable* drawable) {
|
||||
if (drawables_.insert(drawable).second) {
|
||||
drawable->GetRenderable().AddToScene(scene_);
|
||||
if (drawable->GetMaterial().GetParams().reflective) {
|
||||
AddReflectiveDrawable(drawable);
|
||||
void SceneView::AddToScene(Renderable* renderable) {
|
||||
if (renderables_.insert(renderable).second) {
|
||||
renderable->AddToScene(scene_);
|
||||
if (renderable->GetMaterial().GetParams().reflective) {
|
||||
AddReflectiveRenderable(renderable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneView::RemoveFromScene(Drawable* drawable) {
|
||||
if (drawables_.erase(drawable)) {
|
||||
auto it = std::find(reflectives_.begin(), reflectives_.end(), drawable);
|
||||
void SceneView::RemoveFromScene(Renderable* renderable) {
|
||||
if (renderables_.erase(renderable)) {
|
||||
auto it = std::find(reflectives_.begin(), reflectives_.end(), renderable);
|
||||
if (it != reflectives_.end()) {
|
||||
reflectives_.erase(it);
|
||||
}
|
||||
drawable->GetRenderable().RemoveFromScene(scene_);
|
||||
renderable->RemoveFromScene(scene_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -246,11 +245,9 @@ void SceneView::Render(filament::Renderer* renderer,
|
||||
|
||||
SetupCamera(request.camera, viewport, camera_);
|
||||
|
||||
for (auto& iter : drawables_) {
|
||||
for (auto& iter : renderables_) {
|
||||
Material& material = iter->GetMaterial();
|
||||
Renderable& renderable = iter->GetRenderable();
|
||||
renderable.SetMaterialInstance(
|
||||
material.GetMaterialInstance(request.draw_mode));
|
||||
iter->SetMaterialInstance(material.GetMaterialInstance(request.draw_mode));
|
||||
}
|
||||
|
||||
filament::View* view = views_[static_cast<int>(request.draw_mode)];
|
||||
@@ -266,13 +263,17 @@ void SceneView::Render(filament::Renderer* renderer,
|
||||
|
||||
// Render reflection passes.
|
||||
if (request.draw_mode == DrawMode::kNormal) {
|
||||
filament::TransformManager& tm = engine_->getTransformManager();
|
||||
for (size_t i = 0; i < reflectives_.size(); ++i) {
|
||||
Drawable* drawable = reflectives_[i];
|
||||
Renderable* renderable = reflectives_[i];
|
||||
|
||||
SetupReflectionCamera(drawable->GetTransform(), camera_, reflect_camera_);
|
||||
// We assume the 0th entity is the reflective entity.
|
||||
const utils::Entity entity = (*renderable)[0];
|
||||
const mat4 transform(tm.getTransform(tm.getInstance(entity)));
|
||||
SetupReflectionCamera(transform, camera_, reflect_camera_);
|
||||
|
||||
// Hide reflective surface from its own reflection pass.
|
||||
drawable->GetRenderable().SetLayerMask(0x00);
|
||||
renderable->SetLayerMask(0x00);
|
||||
|
||||
// Render the reflection to its render target.
|
||||
reflect_view_->setRenderTarget(
|
||||
@@ -280,7 +281,7 @@ void SceneView::Render(filament::Renderer* renderer,
|
||||
renderer->render(reflect_view_);
|
||||
|
||||
// Unhide the reflective surface.
|
||||
drawable->GetRenderable().SetLayerMask(0x01);
|
||||
renderable->SetLayerMask(0x01);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,24 +294,24 @@ void SceneView::Render(filament::Renderer* renderer,
|
||||
}
|
||||
}
|
||||
|
||||
void SceneView::AddReflectiveDrawable(Drawable* drawable) {
|
||||
void SceneView::AddReflectiveRenderable(Renderable* renderable) {
|
||||
const int index = reflectives_.size();
|
||||
reflectives_.push_back(drawable);
|
||||
reflectives_.push_back(renderable);
|
||||
|
||||
// Ensure we have the same number of render targets as we do reflective
|
||||
// drawables.
|
||||
// renderables.
|
||||
while (reflect_targets_.size() < reflectives_.size()) {
|
||||
reflect_targets_.push_back(std::make_unique<RenderTarget>(
|
||||
engine_, RenderTargetTextureType::kReflectionColor,
|
||||
RenderTargetTextureType::kDepth));
|
||||
}
|
||||
|
||||
// Prepare a render target for the reflective drawable.
|
||||
// Prepare a render target for the reflective renderable.
|
||||
auto viewport = reflect_view_->getViewport();
|
||||
auto& target = reflect_targets_[index];
|
||||
target->Prepare(viewport.width, viewport.height);
|
||||
|
||||
Material& material = drawable->GetMaterial();
|
||||
Material& material = renderable->GetMaterial();
|
||||
Material::Textures textures = material.GetTextures();
|
||||
textures.reflection = target->GetColorTexture();
|
||||
material.UpdateTextures(textures);
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
#include <filament/View.h>
|
||||
#include <mujoco/mujoco.h>
|
||||
#include "experimental/filament/filament/color_grading_options.h"
|
||||
#include "experimental/filament/filament/drawable.h"
|
||||
#include "experimental/filament/filament/light.h"
|
||||
#include "experimental/filament/filament/material.h"
|
||||
#include "experimental/filament/filament/renderable.h"
|
||||
#include "experimental/filament/filament/render_target.h"
|
||||
|
||||
namespace mujoco {
|
||||
@@ -47,8 +47,8 @@ class SceneView {
|
||||
// Adds/removes entities from the scene.
|
||||
void AddToScene(Light* light);
|
||||
void RemoveFromScene(Light* light);
|
||||
void AddToScene(Drawable* drawable);
|
||||
void RemoveFromScene(Drawable* drawable);
|
||||
void AddToScene(Renderable* renderable);
|
||||
void RemoveFromScene(Renderable* renderable);
|
||||
void AddToScene(filament::Skybox* skybox);
|
||||
void RemoveFromScene(filament::Skybox* skybox);
|
||||
void AddToScene(filament::IndirectLight* indirect_light);
|
||||
@@ -85,9 +85,9 @@ class SceneView {
|
||||
SceneView& operator=(const SceneView&) = delete;
|
||||
|
||||
private:
|
||||
// Marks a drawable as reflective. Reflective drawables have to be rendered
|
||||
// in their own passes to create the reflective texture.
|
||||
void AddReflectiveDrawable(Drawable* drawable);
|
||||
// Marks a renderable as reflective. Reflective renderables have to be
|
||||
// rendered in their own passes to create the reflective texture.
|
||||
void AddReflectiveRenderable(Renderable* renderable);
|
||||
|
||||
filament::Engine* engine_ = nullptr;
|
||||
filament::Scene* scene_ = nullptr;
|
||||
@@ -99,7 +99,7 @@ class SceneView {
|
||||
|
||||
// Scene objects.
|
||||
std::unordered_set<Light*> lights_;
|
||||
std::unordered_set<Drawable*> drawables_;
|
||||
std::unordered_set<Renderable*> renderables_;
|
||||
filament::Skybox* skybox_ = nullptr;
|
||||
filament::IndirectLight* indirect_light_ = nullptr;
|
||||
|
||||
@@ -107,8 +107,8 @@ class SceneView {
|
||||
filament::View* reflect_view_ = nullptr;
|
||||
filament::Camera* reflect_camera_ = nullptr;
|
||||
|
||||
// The list of reflective drawables and their corresponding render targets.
|
||||
std::vector<Drawable*> reflectives_;
|
||||
// The list of reflective renderables and their corresponding render targets.
|
||||
std::vector<Renderable*> reflectives_;
|
||||
std::vector<std::unique_ptr<RenderTarget>> reflect_targets_;
|
||||
};
|
||||
} // namespace mujoco
|
||||
|
||||
Reference in New Issue
Block a user