Update compat library to use public functions.

There are still a few places where the compat library is downcasting
to the internal types due to limitations in the public APIs.

PiperOrigin-RevId: 910646480
Change-Id: I1ccb6714db08a2010d9535f59338e5eba06d1d35
This commit is contained in:
Haroon Qureshi
2026-05-05 06:32:19 -07:00
committed by Copybara-Service
parent b9c1877ecb
commit 24ce1eff10
14 changed files with 229 additions and 249 deletions
@@ -18,31 +18,28 @@
#include <cstdint>
#include <cstring>
#include <memory>
#include <utility>
#include <vector>
#include <imgui.h>
#include <math/mat3.h>
#include <math/vec3.h>
#include <mujoco/mujoco.h>
#include "experimental/filament/filament/filament_context.h"
#include "experimental/filament/filament/mesh.h"
#include "experimental/filament/filament/renderable.h"
#include "experimental/filament/filament/scene_view.h"
#include "experimental/filament/filament/texture.h"
#include "experimental/filament/render_context_filament.h"
#include "experimental/filament/render_context_filament_cpp.h"
namespace mujoco {
using filament::math::float3;
using filament::math::mat3f;
ImguiBridge::ImguiBridge(FilamentContext* ctx) : ctx_(ctx) {
ImguiBridge::ImguiBridge(mjrfContext* ctx) : ctx_(ctx) {
mjrSceneParams params;
mjr_defaultSceneParams(&params);
params.enable_post_processing = false;
params.enable_reflections = false;
params.enable_shadows = false;
scene_view_ = std::make_unique<SceneView>(ctx_, params);
scene_ = CreateScene(ctx_, params);
}
ImguiBridge::~ImguiBridge() {
@@ -77,12 +74,12 @@ uintptr_t ImguiBridge::UploadImage(uintptr_t tex_id, const uint8_t* pixels,
tex_id = next_tex_id_++;
}
std::unique_ptr<Texture>& texture = textures_[tex_id];
mjrTexture* texture = GetTexture(tex_id);
// If the texture does not exist or the dimensions have changed, we create a
// new texture.
if (texture == nullptr || texture->GetWidth() != width ||
texture->GetHeight() != height) {
if (texture == nullptr || mjrf_getTextureWidth(texture) != width ||
mjrf_getTextureHeight(texture) != height) {
mjrTextureConfig config;
mjr_defaultTextureConfig(&config);
config.width = width;
@@ -90,7 +87,9 @@ uintptr_t ImguiBridge::UploadImage(uintptr_t tex_id, const uint8_t* pixels,
config.target = mjTEXTURE_2D;
config.format = bpp == 4 ? mjPIXEL_FORMAT_RGBA8 : mjPIXEL_FORMAT_RGB8;
config.color_space = mjCOLORSPACE_LINEAR;
texture = std::make_unique<Texture>(ctx_, config);
UniquePtr<mjrTexture> new_texture = ::mujoco::CreateTexture(ctx_, config);
texture = new_texture.get();
textures_.insert_or_assign(tex_id, std::move(new_texture));
}
// Create a copy of the image to pass it to filament as we don't know the
@@ -108,7 +107,7 @@ uintptr_t ImguiBridge::UploadImage(uintptr_t tex_id, const uint8_t* pixels,
texture_data.release_callback = callback;
std::memcpy(bytes, pixels, num_bytes);
texture->Upload(texture_data);
mjrf_setTextureData(texture, &texture_data);
return tex_id;
}
@@ -126,7 +125,7 @@ void ImguiBridge::CreateTexture(ImTextureData* data) {
config.color_space = mjCOLORSPACE_LINEAR;
const uintptr_t tex_id = next_tex_id_++;
textures_[tex_id] = std::make_unique<Texture>(ctx_, config);
textures_.insert_or_assign(tex_id, ::mujoco::CreateTexture(ctx_, config));
data->SetTexID((ImTextureID)tex_id);
UpdateTexture(data);
}
@@ -143,7 +142,7 @@ void ImguiBridge::UpdateTexture(ImTextureData* data) {
texture_data.nbytes = data->Width * data->Height * 4;
texture_data.user_data = nullptr;
texture_data.release_callback = nullptr;
iter->second->Upload(texture_data);
mjrf_setTextureData(iter->second.get(), &texture_data);
data->SetStatus(ImTextureStatus_OK);
}
@@ -156,6 +155,14 @@ void ImguiBridge::DestroyTexture(ImTextureData* data) {
}
}
mjrTexture* ImguiBridge::GetTexture(uintptr_t tex_id) const {
auto iter = textures_.find(tex_id);
if (iter == textures_.end()) {
return nullptr;
}
return iter->second.get();
}
void ImguiBridge::Update() {
if (!ImGui::GetCurrentContext()) {
PrepareRenderables(0);
@@ -233,21 +240,22 @@ void ImguiBridge::Update() {
data.indices = cmds->IdxBuffer.Data;
data.index_type = mjINDEX_TYPE_U16;
data.primitive_type = mjMESH_PRIMITIVE_TYPE_TRIANGLES;
meshes_.push_back(std::make_unique<Mesh>(ctx_, data));
meshes_.push_back(CreateMesh(ctx_, data));
const Mesh* mesh = meshes_.back().get();
const mjrMesh* mesh = meshes_.back().get();
int index_offset = 0;
for (const ImDrawCmd& command : cmds->CmdBuffer) {
const int width = size.x * scale.x;
const int height = size.y * scale.y;
auto& renderable = renderables_[renderable_index];
renderable->SetMesh(mesh, index_offset, command.ElemCount);
UniquePtr<mjrRenderable>& renderable = renderables_[renderable_index];
mjrf_setRenderableMesh(renderable.get(), mesh, index_offset,
command.ElemCount);
mjrMaterialTextures textures;
mjr_defaultMaterialTextures(&textures);
textures.color = textures_[command.GetTexID()].get();
textures.color = GetTexture(command.GetTexID());
mjrMaterialParams properties;
mjr_defaultMaterialParams(&properties);
@@ -264,9 +272,12 @@ void ImguiBridge::Update() {
properties.scissor[2] = width;
properties.scissor[3] = height;
}
renderable->UpdateMaterial(properties, textures);
renderable->SetTransform(
{float3{0, 0, 0}, mat3f(), float3(scale.x, scale.y, 1.0f)});
mjrf_setRenderableMaterial(renderable.get(), &properties, &textures);
const float position[] = {0, 0, 0};
const float rotation[] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
const float size[] = {scale.x, scale.y, 1.0f};
mjrf_setRenderableTransform(renderable.get(), position, rotation, size);
index_offset += command.ElemCount;
++renderable_index;
@@ -279,15 +290,14 @@ void ImguiBridge::PrepareRenderables(int count) {
mjrRenderableParams params;
mjr_defaultRenderableParams(&params);
params.shading_model = mjSHADING_MODEL_UX;
auto& r =
renderables_.emplace_back(std::make_unique<Renderable>(ctx_, params));
r->SetCastShadows(false);
r->SetReceiveShadows(false);
r->SetBlendOrder(static_cast<std::uint16_t>(renderables_.size()));
scene_view_->AddToScene(r.get());
params.cast_shadows = false;
params.receive_shadows = false;
params.blend_order = static_cast<std::uint16_t>(renderables_.size() + 1);
auto& renderable = renderables_.emplace_back(CreateRenderable(ctx_, params));
mjrf_addRenderableToScene(scene_.get(), renderable.get());
}
while (renderables_.size() > count) {
scene_view_->RemoveFromScene(renderables_.back().get());
mjrf_removeRenderableFromScene(scene_.get(), renderables_.back().get());
renderables_.pop_back();
}
}
+10 -13
View File
@@ -16,23 +16,19 @@
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_COMPAT_IMGUI_BRIDGE_H_
#include <cstdint>
#include <memory>
#include <unordered_map>
#include <vector>
#include <imgui.h>
#include "experimental/filament/filament/filament_context.h"
#include "experimental/filament/filament/mesh.h"
#include "experimental/filament/filament/renderable.h"
#include "experimental/filament/filament/scene_view.h"
#include "experimental/filament/filament/texture.h"
#include "experimental/filament/render_context_filament.h"
#include "experimental/filament/render_context_filament_cpp.h"
namespace mujoco {
// Creates and manages a SceneView using data read from ImGui.
class ImguiBridge {
public:
explicit ImguiBridge(FilamentContext* ctx);
explicit ImguiBridge(mjrfContext* ctx);
~ImguiBridge();
// Prepares the Renderables using data from the current ImGui state. This
@@ -41,7 +37,7 @@ class ImguiBridge {
void Update();
// Returns the managed UX scene.
SceneView* GetSceneView() const { return scene_view_.get(); }
mjrScene* GetScene() const { return scene_.get(); }
// Uploads texture to be used with ImGui's Image and ImageButton functions.
uintptr_t UploadImage(uintptr_t tex_id, const uint8_t* pixels, int width,
@@ -58,12 +54,13 @@ class ImguiBridge {
void CreateTexture(ImTextureData* data);
void UpdateTexture(ImTextureData* data);
void DestroyTexture(ImTextureData* data);
mjrTexture* GetTexture(uintptr_t tex_id) const;
FilamentContext* ctx_ = nullptr;
std::unique_ptr<SceneView> scene_view_;
std::vector<std::unique_ptr<Renderable>> renderables_;
std::vector<std::unique_ptr<Mesh>> meshes_;
std::unordered_map<uintptr_t, std::unique_ptr<Texture>> textures_;
mjrfContext* ctx_ = nullptr;
UniquePtr<mjrScene> scene_{nullptr, nullptr};
std::vector<UniquePtr<mjrRenderable>> renderables_;
std::vector<UniquePtr<mjrMesh>> meshes_;
std::unordered_map<uintptr_t, UniquePtr<mjrTexture>> textures_;
uintptr_t next_tex_id_ = 1;
};
@@ -651,7 +651,7 @@ void DrawLightGui(filament::LightManager& lm,
}
void DrawGui(SceneBridge* scene_bridge) {
SceneView* scene_view = scene_bridge->GetSceneView();
SceneView* scene_view = SceneView::downcast(scene_bridge->GetScene());
filament::View* view = scene_view->GetDefaultRenderView();
filament::Engine* engine = scene_view->GetEngine();
filament::LightManager& lm = engine->getLightManager();
@@ -27,8 +27,8 @@
#include "experimental/filament/compat/scene_bridge.h"
#include "experimental/filament/filament/filament_context.h"
#include "experimental/filament/filament/model_util.h"
#include "experimental/filament/filament/render_target.h"
#include "experimental/filament/render_context_filament.h"
#include "experimental/filament/render_context_filament_cpp.h"
namespace mujoco {
@@ -43,10 +43,10 @@ void MjrFilamentRenderer::Init(const mjModel* model) {
mjr_defaultRenderRequest(&render_requests_[0]);
mjr_defaultRenderRequest(&render_requests_[1]);
render_requests_[0].scene = scene_bridge_->GetSceneView();
render_requests_[0].scene = scene_bridge_->GetScene();
render_requests_[0].draw_mode = mjDRAW_MODE_COLOR;
render_requests_[1].scene = imgui_bridge_->GetSceneView();
render_requests_[1].scene = imgui_bridge_->GetScene();
render_requests_[1].draw_mode = mjDRAW_MODE_COLOR;
// The UX camera is a fixed orthographic camera. We only need to change the
@@ -135,8 +135,7 @@ void MjrFilamentRenderer::ReadPixels(mjrRect viewport, unsigned char* rgb,
config.height = viewport.height;
config.color_format = mjPIXEL_FORMAT_RGB8;
config.depth_format = mjPIXEL_FORMAT_DEPTH32F;
auto target =
std::make_unique<RenderTarget>(filament_context_.get(), config);
auto target = CreateRenderTarget(filament_context_.get(), config);
render_requests_[0].target = target.get();
render_requests_[1].target = target.get();
@@ -158,11 +157,11 @@ void MjrFilamentRenderer::ReadPixels(mjrRect viewport, unsigned char* rgb,
if (depth) {
mjrRenderTargetConfig config;
mjr_defaultRenderTargetConfig(&config);
config.width = viewport.width;
config.height = viewport.height;
config.color_format = mjPIXEL_FORMAT_R32F;
config.depth_format = mjPIXEL_FORMAT_DEPTH32F;
auto target =
std::make_unique<RenderTarget>(filament_context_.get(), config);
target->Prepare(viewport.width, viewport.height);
auto target = CreateRenderTarget(filament_context_.get(), config);
render_requests_[0].target = target.get();
render_requests_[1].target = target.get();
@@ -14,7 +14,6 @@
#include "experimental/filament/compat/model_objects.h"
#include <array>
#include <algorithm>
#include <cfloat>
#include <cstddef>
@@ -25,18 +24,16 @@
#include <utility>
#include <vector>
#include <filament/Engine.h>
#include <math/TVecHelpers.h>
#include <math/vec2.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <mujoco/mujoco.h>
#include "experimental/filament/filament/builtins.h"
#include "experimental/filament/filament/filament_context.h"
#include "experimental/filament/filament/math_util.h"
#include "experimental/filament/filament/mesh.h"
#include "experimental/filament/filament/model_util.h"
#include "experimental/filament/filament/texture.h"
#include "experimental/filament/render_context_filament.h"
#include "experimental/filament/render_context_filament_cpp.h"
namespace mujoco {
@@ -407,7 +404,7 @@ static std::span<const int> GetIndices(const mjModel* model,
}
}
static void UpdatemjrMeshData(mjrMeshData* data, const mjModel* model, int id,
static void UpdateMeshData(mjrMeshData* data, const mjModel* model, int id,
MeshType mesh_type) {
if (!IsValidIndex(model, id, mesh_type)) {
mju_error("Invalid index %d for type %d", id, mesh_type);
@@ -462,7 +459,7 @@ static void UpdatemjrMeshData(mjrMeshData* data, const mjModel* model, int id,
data->bounds_max[2] = builder->bounds_max.z;
}
void UpdateSkinFlexmjrMeshData(mjrMeshData* data, const mjModel* model,
void UpdateSkinFlexMeshData(mjrMeshData* data, const mjModel* model,
const mjvScene* scene, const mjvGeom& geom) {
auto positions = GetPositions(model, scene, geom);
auto normals = GetNormals(model, scene, geom);
@@ -494,21 +491,21 @@ void UpdateSkinFlexmjrMeshData(mjrMeshData* data, const mjModel* model,
data->user_data = nullptr;
}
ModelObjects::ModelObjects(const mjModel* model, FilamentContext* ctx)
ModelObjects::ModelObjects(const mjModel* model, mjrfContext* ctx)
: model_(model), ctx_(ctx) {
const int nstack = model->vis.quality.numstacks;
const int nslice = model->vis.quality.numslices;
const int nquad = model->vis.quality.numquads;
shapes_[kLine] = CreateLine(ctx_);
shapes_[kBox] = CreateBox(ctx_, nquad);
shapes_[kLineBox] = CreateLineBox(ctx_);
shapes_[kCone] = CreateCone(ctx_, nstack, nslice);
shapes_[kDisk] = CreateDisk(ctx_, nslice);
shapes_[kDome] = CreateDome(ctx_, nstack / 2, nslice);
shapes_[kTube] = CreateTube(ctx_, nstack, nslice);
shapes_[kPlane] = CreatePlane(ctx_, nquad);
shapes_[kSphere] = CreateSphere(ctx_, nstack, nslice);
shapes_[kTriangle] = CreateTriangle(ctx_);
shapes_.insert({kLine, CreateLine(ctx_)});
shapes_.insert({kBox, CreateBox(ctx_, nquad)});
shapes_.insert({kLineBox, CreateLineBox(ctx_)});
shapes_.insert({kCone, CreateCone(ctx_, nstack, nslice)});
shapes_.insert({kDisk, CreateDisk(ctx_, nslice)});
shapes_.insert({kDome, CreateDome(ctx_, nstack / 2, nslice)});
shapes_.insert({kTube, CreateTube(ctx_, nstack, nslice)});
shapes_.insert({kPlane, CreatePlane(ctx_, nquad)});
shapes_.insert({kSphere, CreateSphere(ctx_, nstack, nslice)});
shapes_.insert({kTriangle, CreateTriangle(ctx_)});
for (int i = 0; i < model_->ntex; ++i) {
UploadTexture(model_, i);
@@ -545,14 +542,14 @@ void ModelObjects::UploadMesh(const mjModel* model, int id) {
mjrMeshData data;
mjr_defaultMeshData(&data);
UpdatemjrMeshData(&data, model, id, MeshType::kNormal);
meshes_[id] = std::make_unique<Mesh>(ctx_, data);
UpdateMeshData(&data, model, id, MeshType::kNormal);
meshes_.insert_or_assign(id, CreateMesh(ctx_, data));
if (model->mesh_graphadr[id] >= 0) {
mjrMeshData convex_hull_data;
mjr_defaultMeshData(&convex_hull_data);
UpdatemjrMeshData(&convex_hull_data, model, id, MeshType::kConvexHull);
convex_hulls_[id] = std::make_unique<Mesh>(ctx_, convex_hull_data);
UpdateMeshData(&convex_hull_data, model, id, MeshType::kConvexHull);
convex_hulls_.insert_or_assign(id, CreateMesh(ctx_, convex_hull_data));
}
}
@@ -597,9 +594,9 @@ void ModelObjects::UploadTexture(const mjModel* model, int id) {
payload.user_data = nullptr;
payload.release_callback = nullptr;
auto texture = std::make_unique<Texture>(ctx_, config);
texture->Upload(payload);
textures_[id] = std::move(texture);
auto texture = CreateTexture(ctx_, config);
mjrf_setTextureData(texture.get(), &payload);
textures_.insert_or_assign(id, std::move(texture));
}
void ModelObjects::UploadHeightField(const mjModel* model, int id) {
@@ -614,18 +611,18 @@ void ModelObjects::UploadHeightField(const mjModel* model, int id) {
mjrMeshData data;
mjr_defaultMeshData(&data);
UpdatemjrMeshData(&data, model, id, MeshType::kHeightField);
height_fields_[id] = std::make_unique<Mesh>(ctx_, data);
UpdateMeshData(&data, model, id, MeshType::kHeightField);
height_fields_.insert_or_assign(id, CreateMesh(ctx_, data));
}
void ModelObjects::CreateSkinFlexMesh(const mjvScene* scene, const mjvGeom& geom) {
mjrMeshData data;
mjr_defaultMeshData(&data);
UpdateSkinFlexmjrMeshData(&data, model_, scene, geom);
dynamic_meshes_[geom.objid] = std::make_unique<Mesh>(ctx_, data);
UpdateSkinFlexMeshData(&data, model_, scene, geom);
dynamic_meshes_.insert_or_assign(geom.objid, CreateMesh(ctx_, data));
}
const Mesh* ModelObjects::GetMeshBuffer(int data_id) const {
const mjrMesh* ModelObjects::GetMeshBuffer(int data_id) const {
// As defined by mjv_updateScene:
// original mesh: mesh_id * 2
// convex hull: (mesh_id * 2) + 1
@@ -639,29 +636,27 @@ const Mesh* ModelObjects::GetMeshBuffer(int data_id) const {
}
}
const Mesh* ModelObjects::GetHeightFieldBuffer(int hfield_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 Mesh* ModelObjects::GetShapeBuffer(ShapeType shape) const {
if (shape < 0 || shape >= kNumShapes) {
mju_error("Invalid shape type: %d", shape);
}
return shapes_[shape].get();
const mjrMesh* ModelObjects::GetShapeBuffer(ShapeType shape) const {
auto it = shapes_.find(shape);
return it != shapes_.end() ? it->second.get() : nullptr;
}
const Mesh* ModelObjects::GetFlexSkinGeomMesh(int geom_id) const {
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 Texture* ModelObjects::GetTexture(int tex_id) const {
const mjrTexture* ModelObjects::GetTexture(int tex_id) const {
auto it = textures_.find(tex_id);
return it != textures_.end() ? it->second.get() : nullptr;
}
const Texture* ModelObjects::GetTexture(int mat_id, int role) const {
const mjrTexture* ModelObjects::GetTexture(int mat_id, int role) const {
if (mat_id < 0 || mat_id >= model_->nmat || role < 0 || role >= mjNTEXROLE) {
return nullptr;
}
@@ -669,7 +664,7 @@ const Texture* ModelObjects::GetTexture(int mat_id, int role) const {
return GetTexture(tex_id);
}
const Texture* ModelObjects::GetSkyboxTexture() const {
const mjrTexture* ModelObjects::GetSkyboxTexture() const {
for (auto& iter : textures_) {
if (model_->tex_type[iter.first] == mjTEXTURE_SKYBOX) {
return iter.second.get();
@@ -15,22 +15,19 @@
#ifndef MUJOCO_SRC_EXPERIMENTAL_FILAMENT_COMPAT_MODEL_OBJECTS_H_
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_COMPAT_MODEL_OBJECTS_H_
#include <array>
#include <memory>
#include <unordered_map>
#include <mujoco/mjmodel.h>
#include <mujoco/mujoco.h>
#include "experimental/filament/filament/filament_context.h"
#include "experimental/filament/filament/mesh.h"
#include "experimental/filament/filament/texture.h"
#include "experimental/filament/render_context_filament.h"
#include "experimental/filament/render_context_filament_cpp.h"
namespace mujoco {
// Creates and owns various filament objects based on the mjModel.
class ModelObjects {
public:
ModelObjects(const mjModel* model, FilamentContext* ctx);
ModelObjects(const mjModel* model, mjrfContext* ctx);
~ModelObjects();
enum ShapeType {
@@ -56,13 +53,13 @@ class ModelObjects {
void CreateSkinFlexMesh(const mjvScene* scene, const mjvGeom& geom);
// Returns the cached instance of a filament object created from the mjModel.
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;
const Texture* GetSkyboxTexture() const;
const mjrMesh* GetShapeBuffer(ShapeType shape) const;
const mjrMesh* GetMeshBuffer(int data_id) const;
const mjrMesh* GetHeightFieldBuffer(int hfield_id) const;
const mjrMesh* GetFlexSkinGeomMesh(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_; }
float GetShininessMultiplier() const { return shininess_multiplier_; }
@@ -75,13 +72,13 @@ class ModelObjects {
private:
const mjModel* model_ = nullptr;
FilamentContext* ctx_ = nullptr;
std::array<std::unique_ptr<Mesh>, kNumShapes> shapes_;
std::unordered_map<int, std::unique_ptr<Mesh>> meshes_;
std::unordered_map<int, std::unique_ptr<Mesh>> convex_hulls_;
std::unordered_map<int, std::unique_ptr<Mesh>> height_fields_;
std::unordered_map<int, std::unique_ptr<Mesh>> dynamic_meshes_;
std::unordered_map<int, std::unique_ptr<Texture>> textures_;
mjrfContext* ctx_ = nullptr;
std::unordered_map<ShapeType, UniquePtr<mjrMesh>> shapes_;
std::unordered_map<int, UniquePtr<mjrMesh>> meshes_;
std::unordered_map<int, UniquePtr<mjrMesh>> convex_hulls_;
std::unordered_map<int, UniquePtr<mjrMesh>> height_fields_;
std::unordered_map<int, UniquePtr<mjrMesh>> dynamic_meshes_;
std::unordered_map<int, UniquePtr<mjrTexture>> textures_;
float specular_multiplier_ = 0.2f;
float shininess_multiplier_ = 0.1f;
float emissive_multiplier_ = 0.3f;
@@ -19,8 +19,6 @@
#include <string_view>
#include <utility>
#include <filament/Options.h>
#include <filament/View.h>
#include <math/TMatHelpers.h>
#include <math/mat4.h>
#include <math/mathfwd.h>
@@ -31,16 +29,13 @@
#include "experimental/filament/compat/imgui_bridge.h"
#include "experimental/filament/compat/model_objects.h"
#include "experimental/filament/compat/scene_geom_util.h"
#include "experimental/filament/filament/color_grading_options.h"
#include "experimental/filament/filament/filament_context.h"
#include "experimental/filament/filament/light.h"
#include "experimental/filament/filament/object_manager.h"
#include "experimental/filament/filament/math_util.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_view.h"
#include "experimental/filament/filament/texture.h"
#include "experimental/filament/render_context_filament.h"
#include "experimental/filament/render_context_filament_cpp.h"
namespace mujoco {
@@ -49,14 +44,14 @@ using filament::math::float4;
using filament::math::mat3;
using filament::math::mat4;
static std::unique_ptr<Texture> CreateFallbackIndirectLightTexture(
FilamentContext* ctx, std::string_view filename = "") {
static UniquePtr<mjrTexture> CreateFallbackIndirectLightTexture(
mjrfContext* ctx, std::string_view filename = "") {
if (filename.empty()) {
filename = ObjectManager::kDefaultEnvironmentLight;
}
std::unique_ptr<ObjectManager::Asset> asset =
ctx->GetObjectManager()->LoadAsset(filename);
FilamentContext::downcast(ctx)->GetObjectManager()->LoadAsset(filename);
mjrTextureConfig config;
mjr_defaultTextureConfig(&config);
@@ -66,7 +61,7 @@ static std::unique_ptr<Texture> CreateFallbackIndirectLightTexture(
config.format = mjPIXEL_FORMAT_KTX;
config.color_space = mjCOLORSPACE_AUTO;
auto texture = std::make_unique<Texture>(ctx, config);
auto texture = CreateTexture(ctx, config);
mjrTextureData payload;
mjr_defaultTextureData(&payload);
@@ -77,20 +72,20 @@ static std::unique_ptr<Texture> CreateFallbackIndirectLightTexture(
};
payload.user_data = asset.release();
texture->Upload(payload);
mjrf_setTextureData(texture.get(), &payload);
return texture;
}
SceneBridge::SceneBridge(FilamentContext* ctx, const mjModel* model)
SceneBridge::SceneBridge(mjrfContext* ctx, const mjModel* model)
: ctx_(ctx) {
mjrSceneParams params;
mjr_defaultSceneParams(&params);
params.layer_mask = mjCAT_ALL;
params.reflection_layer_mask = mjCAT_DYNAMIC | mjCAT_STATIC;
scene_view_ = std::make_unique<SceneView>(ctx_, params);
scene_ = CreateScene(ctx_, params);
model_objects_ = std::make_unique<ModelObjects>(model, ctx_);
scene_view_->Configure(model);
mjrf_configureSceneFromModel(scene_.get(), model);
default_shadow_map_size_ = ReadElement(
model, "filament.shadows.map_size", default_shadow_map_size_);
@@ -111,15 +106,15 @@ SceneBridge::SceneBridge(FilamentContext* ctx, const mjModel* model)
SceneBridge::~SceneBridge() {
for (auto& iter : lights_) {
scene_view_->RemoveFromScene(iter.get());
mjrf_removeLightFromScene(scene_.get(), iter.get());
}
lights_.clear();
if (fallback_ibl_) {
scene_view_->RemoveFromScene(fallback_ibl_.get());
mjrf_removeLightFromScene(scene_.get(), fallback_ibl_.get());
}
fallback_ibl_.reset();
for (auto& iter : renderables_) {
scene_view_->RemoveFromScene(iter.get());
mjrf_removeRenderableFromScene(scene_.get(), iter.get());
}
renderables_.clear();
}
@@ -127,14 +122,14 @@ SceneBridge::~SceneBridge() {
void SceneBridge::SetEnvironmentLight(std::string_view filename,
float intensity) {
for (auto& light : lights_) {
if (light->GetType() == mjLIGHT_IMAGE) {
scene_view_->RemoveFromScene(light.get());
if (mjrf_getLightType(light.get()) == mjLIGHT_IMAGE) {
mjrf_removeLightFromScene(scene_.get(), light.get());
light.reset();
break;
}
}
if (fallback_ibl_) {
scene_view_->RemoveFromScene(fallback_ibl_.get());
mjrf_removeLightFromScene(scene_.get(), fallback_ibl_.get());
fallback_ibl_.reset();
}
@@ -145,8 +140,8 @@ void SceneBridge::SetEnvironmentLight(std::string_view filename,
params.type = mjLIGHT_IMAGE;
params.texture = fallback_ibl_texture_.get();
params.intensity = intensity;
fallback_ibl_ = std::make_unique<Light>(ctx_, params);
scene_view_->AddToScene(fallback_ibl_.get());
fallback_ibl_ = CreateLight(ctx_, params);
mjrf_addLightToScene(scene_.get(), fallback_ibl_.get());
}
std::optional<float3> SceneBridge::ClipFromWorld(const float3& pos) const{
@@ -171,8 +166,8 @@ void SceneBridge::PrepareLights() {
params.type = mjLIGHT_IMAGE;
params.texture = model_objects_->GetTexture(model->light_texid[i]);
params.intensity = model->light_intensity[i];
auto light_obj = std::make_unique<Light>(ctx_, params);
scene_view_->AddToScene(light_obj.get());
auto light_obj = CreateLight(ctx_, params);
mjrf_addLightToScene(scene_.get(), light_obj.get());
lights_.emplace_back(std::move(light_obj));
has_image_based_light = true;
} else {
@@ -192,8 +187,8 @@ void SceneBridge::PrepareLights() {
params.spot_cone_angle = model->light_cutoff[i];
}
auto light_obj = std::make_unique<Light>(ctx_, params);
scene_view_->AddToScene(light_obj.get());
auto light_obj = CreateLight(ctx_, params);
mjrf_addLightToScene(scene_.get(), light_obj.get());
lights_.emplace_back(std::move(light_obj));
}
}
@@ -212,8 +207,8 @@ void SceneBridge::PrepareLights() {
params.cast_shadows = 0;
params.intensity = 0.0f;
params.spot_cone_angle = 90.0f;
auto light_obj = std::make_unique<Light>(ctx_, params);
scene_view_->AddToScene(light_obj.get());
auto light_obj = CreateLight(ctx_, params);
mjrf_addLightToScene(scene_.get(), light_obj.get());
lights_.emplace_back(std::move(light_obj));
}
@@ -224,8 +219,8 @@ void SceneBridge::PrepareLights() {
mjr_defaultLightParams(&params);
params.type = mjLIGHT_IMAGE;
params.intensity = 10.0f;
fallback_ibl_ = std::make_unique<Light>(ctx_, params);
scene_view_->AddToScene(fallback_ibl_.get());
fallback_ibl_ = CreateLight(ctx_, params);
mjrf_addLightToScene(scene_.get(), fallback_ibl_.get());
}
// There are no "physical" lights in the scene which means we're likely
@@ -240,21 +235,22 @@ void SceneBridge::PrepareLights() {
params.type = mjLIGHT_IMAGE;
params.texture = fallback_ibl_texture_.get();
params.intensity = fallback_environment_light_intensity_;
fallback_ibl_ = std::make_unique<Light>(ctx_, params);
scene_view_->AddToScene(fallback_ibl_.get());
fallback_ibl_ = CreateLight(ctx_, params);
mjrf_addLightToScene(scene_.get(), fallback_ibl_.get());
// Distribute the fallback scene light intensity among the lights.
const float intensity = fallback_scene_light_intensity_ / lights_.size();
for (auto& light : lights_) {
if (light) {
const bool is_headlight = (light == lights_.back());
light->SetIntensity(is_headlight ? fallback_head_light_intensity_
: intensity);
mjrf_setLightIntensity(light.get(),
is_headlight ? fallback_head_light_intensity_
: intensity);
}
}
}
scene_view_->SetSkybox(model_objects_->GetSkyboxTexture());
mjrf_setSceneSkybox(scene_.get(), model_objects_->GetSkyboxTexture());
}
mat4 CalculateClipFromWorld(const mjrRect& viewport, const mjvGLCamera& cam) {
@@ -285,16 +281,8 @@ mat4 CalculateClipFromWorld(const mjrRect& viewport, const mjvGLCamera& cam) {
}
void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) {
if (scene->flags[mjRND_SHADOW]) {
scene_view_->EnableShadows();
} else {
scene_view_->DisableShadows();
}
if (scene->flags[mjRND_REFLECTION]) {
scene_view_->EnableReflections();
} else {
scene_view_->DisableReflections();
}
mjrf_setSceneShadowsEnabled(scene_.get(), scene->flags[mjRND_SHADOW]);
mjrf_setSceneReflectionsEnabled(scene_.get(), scene->flags[mjRND_REFLECTION]);
mjtNum hpos[3], hfwd[3];
float headpos[3], gazedir[3];
@@ -308,7 +296,7 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) {
// Remove all drawables from previous render and prepare new ones.
for (auto& iter : renderables_) {
scene_view_->RemoveFromScene(iter.get());
mjrf_removeRenderableFromScene(scene_.get(), iter.get());
}
renderables_.clear();
for (int i = 0; i < scene->ngeom; ++i) {
@@ -324,10 +312,10 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) {
model_objects_->CreateSkinFlexMesh(scene, *geom);
}
std::unique_ptr<Renderable> renderable = CreateGeomRenderable(
UniquePtr<mjrRenderable> renderable = CreateGeomRenderable(
*geom, scene, ctx_, model_objects_.get(), headpos);
scene_view_->AddToScene(renderable.get());
mjrf_addRenderableToScene(scene_.get(), renderable.get());
renderables_.push_back(std::move(renderable));
}
@@ -343,16 +331,15 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) {
headpos[2] -= gazedir[2] * 0.05f;
// The headlight is always the "back" light.
std::unique_ptr<Light>& light = lights_.back();
light->SetColor(ReadFloat3(scene_light.diffuse));
light->SetTransform(ReadFloat3(headpos), ReadFloat3(gazedir));
UniquePtr<mjrLight>& light = lights_.back();
mjrf_setLightColor(light.get(), scene_light.diffuse);
mjrf_setLightTransform(light.get(), headpos, gazedir);
continue;
} else if (scene_light.id < lights_.size() - 1) {
std::unique_ptr<Light>& light = lights_[scene_light.id];
UniquePtr<mjrLight>& light = lights_[scene_light.id];
if (light) {
light->SetColor(ReadFloat3(scene_light.diffuse));
light->SetTransform(ReadFloat3(scene_light.pos),
ReadFloat3(scene_light.dir));
mjrf_setLightColor(light.get(), scene_light.diffuse);
mjrf_setLightTransform(light.get(), scene_light.pos, scene_light.dir);
}
} else {
mju_error("Unexpected light id: %d", scene_light.id);
@@ -360,11 +347,7 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) {
}
// Enable/disable the headlight based on whether or not it's in the scene.
if (headlight_enabled) {
lights_.back()->Enable();
} else {
lights_.back()->Disable();
}
mjrf_setLightEnabled(lights_.back().get(), headlight_enabled);
}
void SceneBridge::UploadMesh(const mjModel* model, int id) {
+10 -13
View File
@@ -25,18 +25,15 @@
#include <mujoco/mjvisualize.h>
#include <mujoco/mujoco.h>
#include "experimental/filament/compat/model_objects.h"
#include "experimental/filament/filament/filament_context.h"
#include "experimental/filament/filament/light.h"
#include "experimental/filament/filament/renderable.h"
#include "experimental/filament/filament/scene_view.h"
#include "experimental/filament/filament/texture.h"
#include "experimental/filament/render_context_filament.h"
#include "experimental/filament/render_context_filament_cpp.h"
namespace mujoco {
// Manages all mjModel data and updates a SceneView using an mjvScene.
class SceneBridge {
public:
SceneBridge(FilamentContext* ctx, const mjModel* model);
SceneBridge(mjrfContext* ctx, const mjModel* model);
~SceneBridge();
// Updates the environment light using the KTX image at the given path.
@@ -55,7 +52,7 @@ class SceneBridge {
void UploadHeightField(const mjModel* model, int id);
// Returns the managed scene.
SceneView* GetSceneView() const { return scene_view_.get(); }
mjrScene* GetScene() const { return scene_.get(); }
SceneBridge(const SceneBridge&) = delete;
SceneBridge& operator=(const SceneBridge&) = delete;
@@ -68,13 +65,13 @@ class SceneBridge {
std::optional<filament::math::float3> ClipFromWorld(
const filament::math::float3& pos) const;
FilamentContext* ctx_ = nullptr;
std::unique_ptr<SceneView> scene_view_;
mjrfContext* ctx_ = nullptr;
std::unique_ptr<ModelObjects> model_objects_;
std::unique_ptr<Light> fallback_ibl_;
std::unique_ptr<Texture> fallback_ibl_texture_;
std::vector<std::unique_ptr<Light>> lights_;
std::vector<std::unique_ptr<Renderable>> renderables_;
UniquePtr<mjrScene> scene_{nullptr, nullptr};
UniquePtr<mjrLight> fallback_ibl_{nullptr, nullptr};
UniquePtr<mjrTexture> fallback_ibl_texture_{nullptr, nullptr};
std::vector<UniquePtr<mjrLight>> lights_;
std::vector<UniquePtr<mjrRenderable>> renderables_;
filament::math::mat4 clip_from_world_;
int default_shadow_map_size_ = 2048;
float default_vsm_blur_width_ = 0.0f;
@@ -16,6 +16,7 @@
#include <cmath>
#include <cstdint>
#include <cstring>
#include <memory>
#include <numbers>
#include <vector>
@@ -27,12 +28,10 @@
#include <mujoco/mjvisualize.h>
#include <mujoco/mujoco.h>
#include "experimental/filament/compat/model_objects.h"
#include "experimental/filament/filament/filament_context.h"
#include "experimental/filament/filament/math_util.h"
#include "experimental/filament/filament/mesh.h"
#include "experimental/filament/filament/renderable.h"
#include "experimental/filament/filament/texture.h"
#include "experimental/filament/render_context_filament.h"
#include "experimental/filament/render_context_filament_cpp.h"
namespace mujoco {
@@ -64,39 +63,39 @@ static bool IsBehind(const float* headpos, const float* pos, const float* mat) {
0.0f);
}
static const Mesh* GetMesh(ModelObjects* model_objs, int data_id) {
const Mesh* mesh = model_objs->GetMeshBuffer(data_id);
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 Mesh* GetSkinFlexMesh(ModelObjects* model_objs, int objid) {
static const mjrMesh* GetSkinFlexMesh(ModelObjects* model_objs, int objid) {
return model_objs->GetFlexSkinGeomMesh(objid);
}
static const Mesh* GetHeightField(ModelObjects* model_objs, int hfield_id) {
const Mesh* mesh = model_objs->GetHeightFieldBuffer(hfield_id);
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 const Mesh* GetShape(ModelObjects* model_objs,
static const mjrMesh* GetShape(ModelObjects* model_objs,
ModelObjects::ShapeType shape_type) {
const Mesh* mesh = model_objs->GetShapeBuffer(shape_type);
const mjrMesh* mesh = model_objs->GetShapeBuffer(shape_type);
if (mesh == nullptr) {
mju_error("Unknown shape %d", shape_type);
}
return mesh;
}
static void PrepareGeomMeshes(Renderable& renderable, const mjvGeom& geom,
static void PrepareGeomMeshes(mjrRenderable* renderable, const mjvGeom& geom,
const mjvScene* scene,
ModelObjects* model_objects) {
std::vector<const Mesh*> meshes;
std::vector<const mjrMesh*> meshes;
Renderable::GetTransformFn get_transforms;
Trs trs = {
@@ -334,11 +333,18 @@ static void PrepareGeomMeshes(Renderable& renderable, const mjvGeom& geom,
break;
}
renderable.SetMeshes(meshes, get_transforms);
renderable.SetTransform(trs);
Renderable::downcast(renderable)->SetMeshes(meshes, get_transforms);
float position[3];
std::memcpy(position, &trs.translation[0], 3 * sizeof(float));
float rotation[9];
std::memcpy(rotation, &trs.rotation[0], 9 * sizeof(float));
float size[3];
std::memcpy(size, &trs.size[0], 3 * sizeof(float));
mjrf_setRenderableTransform(renderable, position, rotation, size);
}
static void UpdateGeomMaterial(Renderable& renderable, const mjvGeom& geom,
static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom,
const mjvScene* scene, ModelObjects* model_objs,
const float headpos[3]) {
const mjModel* model = model_objs->GetModel();
@@ -353,19 +359,19 @@ static void UpdateGeomMaterial(Renderable& renderable, const mjvGeom& geom,
if (geom.type == mjGEOM_PLANE) {
if (IsBehind(headpos, geom.pos, geom.mat)) {
params.color[3] *= 0.3;
renderable.SetReceiveShadows(false);
mjrf_setRenderableReceiveShadows(renderable, false);
params.reflective = false;
} else {
renderable.SetReceiveShadows(true);
mjrf_setRenderableReceiveShadows(renderable, true);
params.reflective = geom.reflectance > 0 && params.color[3] == 1.0f;
}
}
renderable.SetLayerMask(geom.category);
mjrf_setRenderableLayerMask(renderable, geom.category);
if (geom.category == mjCAT_DECOR) {
renderable.SetCastShadows(false);
renderable.SetReceiveShadows(false);
mjrf_setRenderableCastShadows(renderable, false);
mjrf_setRenderableReceiveShadows(renderable, false);
} else {
renderable.SetWireframe(scene->flags[mjRND_WIREFRAME]);
mjrf_setRenderableWireframe(renderable, scene->flags[mjRND_WIREFRAME]);
}
mjrMaterialTextures textures;
@@ -420,7 +426,7 @@ static void UpdateGeomMaterial(Renderable& renderable, const mjvGeom& geom,
// the programmatic UVs.
if (textures.color) {
if (Texture::downcast(textures.color)->GetTarget() == mjTEXTURE_2D) {
if (mjrf_getTextureTarget(textures.color) == mjTEXTURE_2D) {
// For 2D textures, `tex_repeat` specifies how many times the texture
// image is repeated. The `tex_uniform` flag determines if the repetition
// is applied at in object space (false) or in world space (true).
@@ -482,11 +488,11 @@ static void UpdateGeomMaterial(Renderable& renderable, const mjvGeom& geom,
params.specular *= model_objs->GetSpecularMultiplier();
params.glossiness *= model_objs->GetShininessMultiplier();
renderable.UpdateMaterial(params, textures);
mjrf_setRenderableMaterial(renderable, &params, &textures);
}
std::unique_ptr<Renderable> CreateGeomRenderable(
const mjvGeom& geom, const mjvScene* scene, FilamentContext* ctx,
UniquePtr<mjrRenderable> CreateGeomRenderable(
const mjvGeom& geom, const mjvScene* scene, mjrfContext* ctx,
ModelObjects* model_objs, const float headpos[3]) {
mjrShadingModel shading_model = mjSHADING_MODEL_SCENE_OBJECT;
if (geom.type == mjGEOM_LINE || geom.type == mjGEOM_LINEBOX) {
@@ -498,9 +504,9 @@ std::unique_ptr<Renderable> CreateGeomRenderable(
mjrRenderableParams params;
mjr_defaultRenderableParams(&params);
params.shading_model = shading_model;
auto renderable = std::make_unique<Renderable>(ctx, params);
PrepareGeomMeshes(*renderable, geom, scene, model_objs);
UpdateGeomMaterial(*renderable, geom, scene, model_objs, headpos);
auto renderable = CreateRenderable(ctx, params);
PrepareGeomMeshes(renderable.get(), geom, scene, model_objs);
UpdateGeomMaterial(renderable.get(), geom, scene, model_objs, headpos);
return renderable;
}
} // namespace mujoco
@@ -15,18 +15,16 @@
#ifndef MUJOCO_SRC_EXPERIMENTAL_FILAMENT_COMPAT_SCENE_GEOM_UTIL_H_
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_COMPAT_SCENE_GEOM_UTIL_H_
#include <memory>
#include <mujoco/mjvisualize.h>
#include "experimental/filament/compat/model_objects.h"
#include "experimental/filament/filament/filament_context.h"
#include "experimental/filament/filament/renderable.h"
#include "experimental/filament/render_context_filament.h"
#include "experimental/filament/render_context_filament_cpp.h"
namespace mujoco {
// Creates a Renderable from the given mjvGeom.
std::unique_ptr<Renderable> CreateGeomRenderable(
const mjvGeom& geom, const mjvScene* scene, FilamentContext* ctx,
UniquePtr<mjrRenderable> CreateGeomRenderable(
const mjvGeom& geom, const mjvScene* scene, mjrfContext* ctx,
ModelObjects* model_objs, const float headpos[3]);
} // namespace mujoco
+13 -13
View File
@@ -28,6 +28,7 @@
#include "experimental/filament/filament/math_util.h"
#include "experimental/filament/filament/mesh.h"
#include "experimental/filament/render_context_filament.h"
#include "experimental/filament/render_context_filament_cpp.h"
namespace mujoco {
@@ -64,15 +65,14 @@ class BuiltinBuilder : public mjrMeshData {
virtual ~BuiltinBuilder() = default;
template <typename T, typename... Args>
static std::unique_ptr<Mesh> Create(FilamentContext* ctx,
Args&&... args) {
static UniquePtr<mjrMesh> Create(mjrfContext* ctx, Args&&... args) {
auto builder = new T(std::forward<Args>(args)...);
mjrMeshData* mesh_data = builder->PrepareMeshData();
mesh_data->release_callback = +[](void* user_data) {
delete static_cast<BuiltinBuilder*>(user_data);
};
mesh_data->user_data = builder;
return std::make_unique<Mesh>(ctx, *mesh_data);
return CreateMesh(ctx, *mesh_data);
}
mjrMeshData* PrepareMeshData() {
@@ -617,43 +617,43 @@ class DomeBuilder : public BuiltinBuilder {
}
};
std::unique_ptr<Mesh> CreateLine(FilamentContext* ctx) {
UniquePtr<mjrMesh> CreateLine(mjrfContext* ctx) {
return BuiltinBuilder::Create<LineBuilder>(ctx);
}
std::unique_ptr<Mesh> CreatePlane(FilamentContext* ctx, int nquad) {
UniquePtr<mjrMesh> CreatePlane(mjrfContext* ctx, int nquad) {
return BuiltinBuilder::Create<PlaneBuilder>(ctx, nquad);
}
std::unique_ptr<Mesh> CreateTriangle(FilamentContext* ctx) {
UniquePtr<mjrMesh> CreateTriangle(mjrfContext* ctx) {
return BuiltinBuilder::Create<TriangleBuilder>(ctx);
}
std::unique_ptr<Mesh> CreateBox(FilamentContext* ctx, int nquad) {
UniquePtr<mjrMesh> CreateBox(mjrfContext* ctx, int nquad) {
return BuiltinBuilder::Create<BoxBuilder>(ctx, nquad);
}
std::unique_ptr<Mesh> CreateLineBox(FilamentContext* ctx) {
UniquePtr<mjrMesh> CreateLineBox(mjrfContext* ctx) {
return BuiltinBuilder::Create<LineBoxBuilder>(ctx);
}
std::unique_ptr<Mesh> CreateSphere(FilamentContext* ctx, int nstack, int nslice) {
UniquePtr<mjrMesh> CreateSphere(mjrfContext* ctx, int nstack, int nslice) {
return BuiltinBuilder::Create<SphereBuilder>(ctx, nstack, nslice);
}
std::unique_ptr<Mesh> CreateTube(FilamentContext* ctx, int nstack, int nslice) {
UniquePtr<mjrMesh> CreateTube(mjrfContext* ctx, int nstack, int nslice) {
return BuiltinBuilder::Create<TubeBuilder>(ctx, nstack, nslice);
}
std::unique_ptr<Mesh> CreateDisk(FilamentContext* ctx, int nslice) {
UniquePtr<mjrMesh> CreateDisk(mjrfContext* ctx, int nslice) {
return BuiltinBuilder::Create<DiskBuilder>(ctx, nslice);
}
std::unique_ptr<Mesh> CreateDome(FilamentContext* ctx, int nstack, int nslice) {
UniquePtr<mjrMesh> CreateDome(mjrfContext* ctx, int nstack, int nslice) {
return BuiltinBuilder::Create<DomeBuilder>(ctx, nstack, nslice);
}
std::unique_ptr<Mesh> CreateCone(FilamentContext* ctx, int nstack, int nslice) {
UniquePtr<mjrMesh> CreateCone(mjrfContext* ctx, int nstack, int nslice) {
return BuiltinBuilder::Create<ConeBuilder>(ctx, nstack, nslice);
}
+12 -14
View File
@@ -15,24 +15,22 @@
#ifndef MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_BUILTINS_H_
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_BUILTINS_H_
#include <memory>
#include "experimental/filament/filament/filament_context.h"
#include "experimental/filament/filament/mesh.h"
#include "experimental/filament/render_context_filament.h"
#include "experimental/filament/render_context_filament_cpp.h"
// Generates buffers for built-in shapes.
namespace mujoco {
std::unique_ptr<Mesh> CreateLine(FilamentContext* ctx);
std::unique_ptr<Mesh> CreatePlane(FilamentContext* ctx, int nquad);
std::unique_ptr<Mesh> CreateTriangle(FilamentContext* ctx);
std::unique_ptr<Mesh> CreateBox(FilamentContext* ctx, int nquad);
std::unique_ptr<Mesh> CreateLineBox(FilamentContext* ctx);
std::unique_ptr<Mesh> CreateSphere(FilamentContext* ctx, int nstack, int nslice);
std::unique_ptr<Mesh> CreateTube(FilamentContext* ctx, int nstack, int nslice);
std::unique_ptr<Mesh> CreateDisk(FilamentContext* ctx, int nslice);
std::unique_ptr<Mesh> CreateDome(FilamentContext* ctx, int nstack, int nslice);
std::unique_ptr<Mesh> CreateCone(FilamentContext* ctx, int nstack, int nslice);
UniquePtr<mjrMesh> CreateLine(mjrfContext* ctx);
UniquePtr<mjrMesh> CreatePlane(mjrfContext* ctx, int nquad);
UniquePtr<mjrMesh> CreateTriangle(mjrfContext* ctx);
UniquePtr<mjrMesh> CreateBox(mjrfContext* ctx, int nquad);
UniquePtr<mjrMesh> CreateLineBox(mjrfContext* ctx);
UniquePtr<mjrMesh> CreateSphere(mjrfContext* ctx, int nstack, int nslice);
UniquePtr<mjrMesh> CreateTube(mjrfContext* ctx, int nstack, int nslice);
UniquePtr<mjrMesh> CreateDisk(mjrfContext* ctx, int nslice);
UniquePtr<mjrMesh> CreateDome(mjrfContext* ctx, int nstack, int nslice);
UniquePtr<mjrMesh> CreateCone(mjrfContext* ctx, int nstack, int nslice);
} // namespace mujoco
@@ -159,7 +159,7 @@ const mat4f& Renderable::GetTransform() const {
return transform_;
}
void Renderable::SetMeshes(std::span<const Mesh*> meshes,
void Renderable::SetMeshes(std::span<const mjrMesh*> meshes,
GetTransformFn get_transform_fn) {
if (!parts_.empty()) {
mju_error("Cannot set meshes for renderable with multiple parts.");
@@ -168,7 +168,7 @@ void Renderable::SetMeshes(std::span<const Mesh*> meshes,
get_transform_fn_ = get_transform_fn;
for (int i = 0; i < meshes.size(); ++i) {
Part& part = parts_.emplace_back();
part.mesh = meshes[i];
part.mesh = Mesh::downcast(meshes[i]);
part.elem_offset = 0;
part.elem_count = part.mesh->GetFilamentIndexBuffer()->getIndexCount();
InitPartEntity(part);
@@ -70,7 +70,7 @@ class Renderable : public mjrRenderable {
// relative to the transform of the renderable itself. This allows users to
// construct compound (but rigid) objects from multiple meshes.
using GetTransformFn = std::function<filament::math::mat4f(int, const Trs&)>;
void SetMeshes(std::span<const Mesh*> meshes,
void SetMeshes(std::span<const mjrMesh*> meshes,
GetTransformFn get_transform = nullptr);
// Sets the layer mask for the managed filament Entities. Layer masks can be