Fix namespace for filament-specific "mjrf" API.

PiperOrigin-RevId: 928582582
Change-Id: Idc312607b2f063d8ace8d5cc79bfbc8ac588d13f
This commit is contained in:
Haroon Qureshi
2026-06-08 08:37:12 -07:00
committed by Copybara-Service
parent 7a7dc7ccad
commit 7e790879ef
35 changed files with 445 additions and 439 deletions
@@ -35,7 +35,7 @@ using filament::math::float4;
using filament::math::mat3; using filament::math::mat3;
using filament::math::mat4; using filament::math::mat4;
static UniquePtr<mjrTexture> CreateFallbackIndirectLightTexture( static UniquePtr<mjrfTexture> CreateFallbackIndirectLightTexture(
mjrfContext* ctx) { mjrfContext* ctx) {
const std::string filename = ResolveFilamentAssetPath("ibl.ktx"); const std::string filename = ResolveFilamentAssetPath("ibl.ktx");
mjResource* resource = mjResource* resource =
@@ -49,8 +49,8 @@ static UniquePtr<mjrTexture> CreateFallbackIndirectLightTexture(
mju_error("Failed to read resource: %s", filename.c_str()); mju_error("Failed to read resource: %s", filename.c_str());
} }
mjrTextureConfig config; mjrfTextureConfig config;
mjr_defaultTextureConfig(&config); mjrf_defaultTextureConfig(&config);
config.width = 1; config.width = 1;
config.height = 1; config.height = 1;
config.sampler_type = mjTEXTURE_CUBE; config.sampler_type = mjTEXTURE_CUBE;
@@ -59,8 +59,8 @@ static UniquePtr<mjrTexture> CreateFallbackIndirectLightTexture(
auto texture = CreateTexture(ctx, config); auto texture = CreateTexture(ctx, config);
mjrTextureData payload; mjrfTextureData payload;
mjr_defaultTextureData(&payload); mjrf_defaultTextureData(&payload);
payload.bytes = bytes; payload.bytes = bytes;
payload.nbytes = nbytes; payload.nbytes = nbytes;
payload.release_callback = +[](void* user_data) { payload.release_callback = +[](void* user_data) {
@@ -72,7 +72,7 @@ static UniquePtr<mjrTexture> CreateFallbackIndirectLightTexture(
return texture; return texture;
} }
LightManager::LightManager(mjrfContext* ctx, mjrScene* scene, LightManager::LightManager(mjrfContext* ctx, mjrfScene* scene,
ModelObjects* model_objects) ModelObjects* model_objects)
: ctx_(ctx), scene_(scene) { : ctx_(ctx), scene_(scene) {
const mjModel* model = model_objects->GetModel(); const mjModel* model = model_objects->GetModel();
@@ -112,8 +112,8 @@ void LightManager::Prepare(ModelObjects* model_objects) {
total_light_intensity += model->light_intensity[i]; total_light_intensity += model->light_intensity[i];
if (model->light_type[i] == mjLIGHT_IMAGE) { if (model->light_type[i] == mjLIGHT_IMAGE) {
mjrLightParams params; mjrfLightParams params;
mjr_defaultLightParams(&params); mjrf_defaultLightParams(&params);
params.type = mjLIGHT_IMAGE; params.type = mjLIGHT_IMAGE;
params.texture = model_objects->GetTexture(model->light_texid[i]); params.texture = model_objects->GetTexture(model->light_texid[i]);
params.intensity = model->light_intensity[i]; params.intensity = model->light_intensity[i];
@@ -122,8 +122,8 @@ void LightManager::Prepare(ModelObjects* model_objects) {
lights_.emplace_back(std::move(light_obj)); lights_.emplace_back(std::move(light_obj));
has_image_based_light = true; has_image_based_light = true;
} else { } else {
mjrLightParams params; mjrfLightParams params;
mjr_defaultLightParams(&params); mjrf_defaultLightParams(&params);
params.color[0] = model->light_diffuse[0]; params.color[0] = model->light_diffuse[0];
params.color[1] = model->light_diffuse[1]; params.color[1] = model->light_diffuse[1];
params.color[2] = model->light_diffuse[2]; params.color[2] = model->light_diffuse[2];
@@ -147,8 +147,8 @@ void LightManager::Prepare(ModelObjects* model_objects) {
// Add a placeholder (black) headlight as our last light. Going forward, we'll // Add a placeholder (black) headlight as our last light. Going forward, we'll
// assume lights_.back() is always the headlight. // assume lights_.back() is always the headlight.
{ {
mjrLightParams params; mjrfLightParams params;
mjr_defaultLightParams(&params); mjrf_defaultLightParams(&params);
// We break with the spec here slightly and use a spot light for the head // We break with the spec here slightly and use a spot light for the head
// light instead of a directional params. This is because filament only // light instead of a directional params. This is because filament only
// supports a single directional light, and we'd rather allow a scene // supports a single directional light, and we'd rather allow a scene
@@ -166,8 +166,8 @@ void LightManager::Prepare(ModelObjects* model_objects) {
if (!has_image_based_light && total_light_intensity > 0.0f) { if (!has_image_based_light && total_light_intensity > 0.0f) {
// Create a black indirect light to ensure that the skybox is // Create a black indirect light to ensure that the skybox is
// oriented to respect mujoco's Z-up convention. // oriented to respect mujoco's Z-up convention.
mjrLightParams params; mjrfLightParams params;
mjr_defaultLightParams(&params); mjrf_defaultLightParams(&params);
params.type = mjLIGHT_IMAGE; params.type = mjLIGHT_IMAGE;
params.intensity = 10.0f; params.intensity = 10.0f;
fallback_ibl_ = CreateLight(ctx_, params); fallback_ibl_ = CreateLight(ctx_, params);
@@ -181,8 +181,8 @@ void LightManager::Prepare(ModelObjects* model_objects) {
// Create a fallback environment light. // Create a fallback environment light.
fallback_ibl_texture_ = CreateFallbackIndirectLightTexture(ctx_); fallback_ibl_texture_ = CreateFallbackIndirectLightTexture(ctx_);
mjrLightParams params; mjrfLightParams params;
mjr_defaultLightParams(&params); mjrf_defaultLightParams(&params);
params.type = mjLIGHT_IMAGE; params.type = mjLIGHT_IMAGE;
params.texture = fallback_ibl_texture_.get(); params.texture = fallback_ibl_texture_.get();
params.intensity = fallback_environment_light_intensity_; params.intensity = fallback_environment_light_intensity_;
@@ -204,7 +204,7 @@ void LightManager::Prepare(ModelObjects* model_objects) {
mjrf_setSceneSkybox(scene_, model_objects->GetSkyboxTexture()); mjrf_setSceneSkybox(scene_, model_objects->GetSkyboxTexture());
} }
mjrLight* LightManager::GetLight(int index) { mjrfLight* LightManager::GetLight(int index) {
if (index < 0 || index >= lights_.size()) { if (index < 0 || index >= lights_.size()) {
return nullptr; return nullptr;
} }
@@ -23,15 +23,15 @@
namespace mujoco { namespace mujoco {
// Manages Light entities for an mjrScene using data from an mjvScene. // Manages Light entities for an mjrfScene using data from an mjvScene.
class LightManager { class LightManager {
public: public:
LightManager(mjrfContext* ctx, mjrScene* scene, ModelObjects* model_objects); LightManager(mjrfContext* ctx, mjrfScene* scene, ModelObjects* model_objects);
~LightManager(); ~LightManager();
// Returns the light with the given index in the mjModel. Note that an extra // Returns the light with the given index in the mjModel. Note that an extra
// headlight is assigned of the index `nlight`. // headlight is assigned of the index `nlight`.
mjrLight* GetLight(int index); mjrfLight* GetLight(int index);
LightManager(const LightManager&) = delete; LightManager(const LightManager&) = delete;
LightManager& operator=(const LightManager&) = delete; LightManager& operator=(const LightManager&) = delete;
@@ -40,10 +40,10 @@ class LightManager {
void Prepare(ModelObjects* model_objects); void Prepare(ModelObjects* model_objects);
mjrfContext* ctx_ = nullptr; mjrfContext* ctx_ = nullptr;
mjrScene* scene_ = nullptr; mjrfScene* scene_ = nullptr;
UniquePtr<mjrLight> fallback_ibl_{nullptr, nullptr}; UniquePtr<mjrfLight> fallback_ibl_{nullptr, nullptr};
UniquePtr<mjrTexture> fallback_ibl_texture_{nullptr, nullptr}; UniquePtr<mjrfTexture> fallback_ibl_texture_{nullptr, nullptr};
std::vector<UniquePtr<mjrLight>> lights_; std::vector<UniquePtr<mjrfLight>> lights_;
int default_shadow_map_size_ = 2048; int default_shadow_map_size_ = 2048;
float default_vsm_blur_width_ = 0.0f; float default_vsm_blur_width_ = 0.0f;
float fallback_head_light_intensity_ = 0.f; float fallback_head_light_intensity_ = 0.f;
@@ -402,7 +402,7 @@ static std::span<const int> GetIndices(const mjModel* model,
} }
} }
static void UpdateMeshData(mjrMeshData* data, const mjModel* model, int id, static void UpdateMeshData(mjrfMeshData* data, const mjModel* model, int id,
MeshType mesh_type) { MeshType mesh_type) {
if (!IsValidIndex(model, id, mesh_type)) { if (!IsValidIndex(model, id, mesh_type)) {
mju_error("Invalid index %d for type %d", id, mesh_type); mju_error("Invalid index %d for type %d", id, mesh_type);
@@ -457,7 +457,7 @@ static void UpdateMeshData(mjrMeshData* data, const mjModel* model, int id,
data->bounds_max[2] = builder->bounds_max.z; data->bounds_max[2] = builder->bounds_max.z;
} }
void UpdateSkinFlexMeshData(mjrMeshData* data, const mjModel* model, void UpdateSkinFlexMeshData(mjrfMeshData* data, const mjModel* model,
const mjvScene* scene, const mjvGeom& geom) { const mjvScene* scene, const mjvGeom& geom) {
auto positions = GetPositions(model, scene, geom); auto positions = GetPositions(model, scene, geom);
auto normals = GetNormals(model, scene, geom); auto normals = GetNormals(model, scene, geom);
@@ -520,14 +520,14 @@ void ModelObjects::UploadMesh(const mjModel* model, int id) {
meshes_.erase(id); meshes_.erase(id);
convex_hulls_.erase(id); convex_hulls_.erase(id);
mjrMeshData data; mjrfMeshData data;
mjr_defaultMeshData(&data); mjrf_defaultMeshData(&data);
UpdateMeshData(&data, model, id, MeshType::kNormal); UpdateMeshData(&data, model, id, MeshType::kNormal);
meshes_.insert_or_assign(id, CreateMesh(ctx_, data)); meshes_.insert_or_assign(id, CreateMesh(ctx_, data));
if (model->mesh_graphadr[id] >= 0) { if (model->mesh_graphadr[id] >= 0) {
mjrMeshData convex_hull_data; mjrfMeshData convex_hull_data;
mjr_defaultMeshData(&convex_hull_data); mjrf_defaultMeshData(&convex_hull_data);
UpdateMeshData(&convex_hull_data, model, id, MeshType::kConvexHull); UpdateMeshData(&convex_hull_data, model, id, MeshType::kConvexHull);
convex_hulls_.insert_or_assign(id, CreateMesh(ctx_, convex_hull_data)); convex_hulls_.insert_or_assign(id, CreateMesh(ctx_, convex_hull_data));
} }
@@ -541,8 +541,8 @@ void ModelObjects::UploadTexture(const mjModel* model, int id) {
mju_error("Invalid texture index: %d", id); mju_error("Invalid texture index: %d", id);
} }
mjrTextureConfig config; mjrfTextureConfig config;
mjr_defaultTextureConfig(&config); mjrf_defaultTextureConfig(&config);
config.width = model->tex_width[id]; config.width = model->tex_width[id];
config.height = model->tex_height[id]; config.height = model->tex_height[id];
config.sampler_type = (mjtTexture)model->tex_type[id]; config.sampler_type = (mjtTexture)model->tex_type[id];
@@ -565,8 +565,8 @@ void ModelObjects::UploadTexture(const mjModel* model, int id) {
config.format = mjPIXEL_FORMAT_KTX; config.format = mjPIXEL_FORMAT_KTX;
} }
mjrTextureData payload; mjrfTextureData payload;
mjr_defaultTextureData(&payload); mjrf_defaultTextureData(&payload);
payload.bytes = model->tex_data + model->tex_adr[id]; payload.bytes = model->tex_data + model->tex_adr[id];
payload.nbytes = payload.nbytes =
model->tex_width[id] * model->tex_height[id] * model->tex_nchannel[id]; model->tex_width[id] * model->tex_height[id] * model->tex_nchannel[id];
@@ -589,15 +589,15 @@ void ModelObjects::UploadHeightField(const mjModel* model, int id) {
height_fields_.erase(id); height_fields_.erase(id);
mjrMeshData data; mjrfMeshData data;
mjr_defaultMeshData(&data); mjrf_defaultMeshData(&data);
UpdateMeshData(&data, model, id, MeshType::kHeightField); UpdateMeshData(&data, model, id, MeshType::kHeightField);
height_fields_.insert_or_assign(id, CreateMesh(ctx_, data)); height_fields_.insert_or_assign(id, CreateMesh(ctx_, data));
} }
void ModelObjects::CreateSkinFlexMesh(const mjvScene* scene, const mjvGeom& geom) { void ModelObjects::CreateSkinFlexMesh(const mjvScene* scene, const mjvGeom& geom) {
mjrMeshData data; mjrfMeshData data;
mjr_defaultMeshData(&data); mjrf_defaultMeshData(&data);
UpdateSkinFlexMeshData(&data, model_, scene, geom); UpdateSkinFlexMeshData(&data, model_, scene, geom);
if (geom.type == mjGEOM_FLEX) { if (geom.type == mjGEOM_FLEX) {
flexes_.insert_or_assign(geom.objid, CreateMesh(ctx_, data)); flexes_.insert_or_assign(geom.objid, CreateMesh(ctx_, data));
@@ -608,7 +608,7 @@ void ModelObjects::CreateSkinFlexMesh(const mjvScene* scene, const mjvGeom& geom
} }
} }
const mjrMesh* ModelObjects::GetMesh(int data_id) const { const mjrfMesh* ModelObjects::GetMesh(int data_id) const {
// As defined by mjv_updateScene: // As defined by mjv_updateScene:
// original mesh: mesh_id * 2 // original mesh: mesh_id * 2
// convex hull: (mesh_id * 2) + 1 // convex hull: (mesh_id * 2) + 1
@@ -622,7 +622,7 @@ const mjrMesh* ModelObjects::GetMesh(int data_id) const {
} }
} }
const mjrMesh* ModelObjects::GetHeightField(int hfield_id) const { const mjrfMesh* ModelObjects::GetHeightField(int hfield_id) const {
if (auto it = height_fields_.find(hfield_id); it != height_fields_.end()) { if (auto it = height_fields_.find(hfield_id); it != height_fields_.end()) {
return it->second.get(); return it->second.get();
} }
@@ -630,7 +630,7 @@ const mjrMesh* ModelObjects::GetHeightField(int hfield_id) const {
return nullptr; return nullptr;
} }
const mjrMesh* ModelObjects::GetFlexMesh(int geom_id) const { const mjrfMesh* ModelObjects::GetFlexMesh(int geom_id) const {
if (auto it = flexes_.find(geom_id); it != flexes_.end()) { if (auto it = flexes_.find(geom_id); it != flexes_.end()) {
return it->second.get(); return it->second.get();
} }
@@ -638,7 +638,7 @@ const mjrMesh* ModelObjects::GetFlexMesh(int geom_id) const {
return nullptr; return nullptr;
} }
const mjrMesh* ModelObjects::GetSkinMesh(int geom_id) const { const mjrfMesh* ModelObjects::GetSkinMesh(int geom_id) const {
if (auto it = skins_.find(geom_id); it != skins_.end()) { if (auto it = skins_.find(geom_id); it != skins_.end()) {
return it->second.get(); return it->second.get();
} }
@@ -646,7 +646,7 @@ const mjrMesh* ModelObjects::GetSkinMesh(int geom_id) const {
return nullptr; return nullptr;
} }
const mjrTexture* ModelObjects::GetTexture(int tex_id) const { const mjrfTexture* ModelObjects::GetTexture(int tex_id) const {
if (auto it = textures_.find(tex_id); it != textures_.end()) { if (auto it = textures_.find(tex_id); it != textures_.end()) {
return it->second.get(); return it->second.get();
} }
@@ -654,7 +654,7 @@ const mjrTexture* ModelObjects::GetTexture(int tex_id) const {
return nullptr; return nullptr;
} }
const mjrTexture* ModelObjects::GetSkyboxTexture() const { const mjrfTexture* ModelObjects::GetSkyboxTexture() const {
for (auto& iter : textures_) { for (auto& iter : textures_) {
if (model_->tex_type[iter.first] == mjTEXTURE_SKYBOX) { if (model_->tex_type[iter.first] == mjTEXTURE_SKYBOX) {
return iter.second.get(); return iter.second.get();
@@ -38,12 +38,12 @@ class ModelObjects {
void CreateSkinFlexMesh(const mjvScene* scene, const mjvGeom& geom); void CreateSkinFlexMesh(const mjvScene* scene, const mjvGeom& geom);
// Returns the cached instance of a filament object created from the mjModel. // Returns the cached instance of a filament object created from the mjModel.
const mjrMesh* GetMesh(int data_id) const; const mjrfMesh* GetMesh(int data_id) const;
const mjrMesh* GetHeightField(int hfield_id) const; const mjrfMesh* GetHeightField(int hfield_id) const;
const mjrMesh* GetSkinMesh(int geom_id) const; const mjrfMesh* GetSkinMesh(int geom_id) const;
const mjrMesh* GetFlexMesh(int geom_id) const; const mjrfMesh* GetFlexMesh(int geom_id) const;
const mjrTexture* GetTexture(int tex_id) const; const mjrfTexture* GetTexture(int tex_id) const;
const mjrTexture* GetSkyboxTexture() const; const mjrfTexture* GetSkyboxTexture() const;
float GetSpecularMultiplier() const { return specular_multiplier_; } float GetSpecularMultiplier() const { return specular_multiplier_; }
float GetShininessMultiplier() const { return shininess_multiplier_; } float GetShininessMultiplier() const { return shininess_multiplier_; }
@@ -57,12 +57,12 @@ class ModelObjects {
private: private:
const mjModel* model_ = nullptr; const mjModel* model_ = nullptr;
mjrfContext* ctx_ = nullptr; mjrfContext* ctx_ = nullptr;
std::unordered_map<int, UniquePtr<mjrMesh>> meshes_; std::unordered_map<int, UniquePtr<mjrfMesh>> meshes_;
std::unordered_map<int, UniquePtr<mjrMesh>> convex_hulls_; std::unordered_map<int, UniquePtr<mjrfMesh>> convex_hulls_;
std::unordered_map<int, UniquePtr<mjrMesh>> height_fields_; std::unordered_map<int, UniquePtr<mjrfMesh>> height_fields_;
std::unordered_map<int, UniquePtr<mjrMesh>> skins_; std::unordered_map<int, UniquePtr<mjrfMesh>> skins_;
std::unordered_map<int, UniquePtr<mjrMesh>> flexes_; std::unordered_map<int, UniquePtr<mjrfMesh>> flexes_;
std::unordered_map<int, UniquePtr<mjrTexture>> textures_; std::unordered_map<int, UniquePtr<mjrfTexture>> textures_;
float specular_multiplier_ = 0.2f; float specular_multiplier_ = 0.2f;
float shininess_multiplier_ = 0.1f; float shininess_multiplier_ = 0.1f;
float emissive_multiplier_ = 0.3f; float emissive_multiplier_ = 0.3f;
@@ -41,8 +41,8 @@ using filament::math::mat4;
SceneBridge::SceneBridge(mjrfContext* ctx, const mjModel* model) SceneBridge::SceneBridge(mjrfContext* ctx, const mjModel* model)
: ctx_(ctx) { : ctx_(ctx) {
mjrSceneParams params; mjrfSceneParams params;
mjr_defaultSceneParams(&params); mjrf_defaultSceneParams(&params);
params.layer_mask = mjCAT_ALL; params.layer_mask = mjCAT_ALL;
params.reflection_layer_mask = mjCAT_DYNAMIC | mjCAT_STATIC; params.reflection_layer_mask = mjCAT_DYNAMIC | mjCAT_STATIC;
scene_ = CreateScene(ctx_, params); scene_ = CreateScene(ctx_, params);
@@ -129,14 +129,14 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) {
model_objects_->CreateSkinFlexMesh(scene, *geom); model_objects_->CreateSkinFlexMesh(scene, *geom);
} }
UniquePtr<mjrRenderable> renderable = UniquePtr<mjrfRenderable> renderable =
CreateGeomRenderable(*geom, ctx_, model_objects_.get(), scene->flags); CreateGeomRenderable(*geom, ctx_, model_objects_.get(), scene->flags);
mjrf_addRenderableToScene(scene_.get(), renderable.get()); mjrf_addRenderableToScene(scene_.get(), renderable.get());
renderables_.push_back(std::move(renderable)); renderables_.push_back(std::move(renderable));
} }
mjrLight* headlight = nullptr; mjrfLight* headlight = nullptr;
bool headlight_enabled = false; bool headlight_enabled = false;
for (int i = 0; i < scene->nlight; ++i) { for (int i = 0; i < scene->nlight; ++i) {
const mjvLight& scene_light = scene->lights[i]; const mjvLight& scene_light = scene->lights[i];
@@ -156,7 +156,7 @@ void SceneBridge::Update(const mjrRect& viewport, const mjvScene* scene) {
mjrf_setLightColor(headlight, scene_light.diffuse); mjrf_setLightColor(headlight, scene_light.diffuse);
mjrf_setLightTransform(headlight, headpos, gazedir); mjrf_setLightTransform(headlight, headpos, gazedir);
continue; continue;
} else if (mjrLight* light = light_manager_->GetLight(scene_light.id)) { } else if (mjrfLight* light = light_manager_->GetLight(scene_light.id)) {
mjrf_setLightColor(light, scene_light.diffuse); mjrf_setLightColor(light, scene_light.diffuse);
mjrf_setLightTransform(light, scene_light.pos, scene_light.dir); mjrf_setLightTransform(light, scene_light.pos, scene_light.dir);
} else { } else {
@@ -186,7 +186,7 @@ void SceneBridge::SetDrawTextFunction(DrawTextAtFn fn) {
draw_text_callback_ = std::move(fn); draw_text_callback_ = std::move(fn);
} }
mjrScene* SceneBridge::GetScene() const { return scene_.get(); } mjrfScene* SceneBridge::GetScene() const { return scene_.get(); }
mjrCamera SceneBridge::GetCamera() const { return camera_; } mjrCamera SceneBridge::GetCamera() const { return camera_; }
@@ -50,7 +50,7 @@ class SceneBridge {
void SetDrawTextFunction(DrawTextAtFn fn); void SetDrawTextFunction(DrawTextAtFn fn);
// Returns the managed scene. // Returns the managed scene.
mjrScene* GetScene() const; mjrfScene* GetScene() const;
mjrCamera GetCamera() const; mjrCamera GetCamera() const;
SceneBridge(const SceneBridge&) = delete; SceneBridge(const SceneBridge&) = delete;
@@ -67,8 +67,8 @@ class SceneBridge {
std::unique_ptr<LightManager> light_manager_; std::unique_ptr<LightManager> light_manager_;
mjrCamera camera_; mjrCamera camera_;
DrawTextAtFn draw_text_callback_; DrawTextAtFn draw_text_callback_;
UniquePtr<mjrScene> scene_{nullptr, nullptr}; UniquePtr<mjrfScene> scene_{nullptr, nullptr};
std::vector<UniquePtr<mjrRenderable>> renderables_; std::vector<UniquePtr<mjrfRenderable>> renderables_;
filament::math::mat4 clip_from_world_; filament::math::mat4 clip_from_world_;
}; };
@@ -40,7 +40,7 @@ static float GetPlaneTileSize(const mjModel* model, int matid,
} }
} }
static void PrepareGeomMeshes(mjrRenderable* renderable, const mjvGeom& geom, static void PrepareGeomMeshes(mjrfRenderable* renderable, const mjvGeom& geom,
ModelObjects* model_objs) { ModelObjects* model_objs) {
const mjModel* model = model_objs->GetModel(); const mjModel* model = model_objs->GetModel();
const int nstack = model->vis.quality.numstacks; const int nstack = model->vis.quality.numstacks;
@@ -142,13 +142,13 @@ static void PrepareGeomMeshes(mjrRenderable* renderable, const mjvGeom& geom,
mjrf_setRenderableTransform(renderable, position, rotation); mjrf_setRenderableTransform(renderable, position, rotation);
} }
static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom, static void UpdateGeomMaterial(mjrfRenderable* renderable, const mjvGeom& geom,
ModelObjects* model_objs, ModelObjects* model_objs,
const mjtByte render_flags[mjNRNDFLAG]) { const mjtByte render_flags[mjNRNDFLAG]) {
const mjModel* model = model_objs->GetModel(); const mjModel* model = model_objs->GetModel();
mjrMaterial material; mjrfMaterial material;
mjr_defaultMaterial(&material); mjrf_defaultMaterial(&material);
if (geom.category == mjCAT_DECOR) { if (geom.category == mjCAT_DECOR) {
material.decor_ux = true; material.decor_ux = true;
@@ -160,7 +160,7 @@ static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom,
material.color[3] = geom.rgba[3]; material.color[3] = geom.rgba[3];
if (geom.matid >= 0 && geom.matid < model->nmat) { if (geom.matid >= 0 && geom.matid < model->nmat) {
auto get_texture = [&](int role) -> const mjrTexture* { auto get_texture = [&](int role) -> const mjrfTexture* {
const int tex_id = model->mat_texid[geom.matid * mjNTEXROLE + role]; const int tex_id = model->mat_texid[geom.matid * mjNTEXROLE + role];
return tex_id >= 0 ? model_objs->GetTexture(tex_id) : nullptr; return tex_id >= 0 ? model_objs->GetTexture(tex_id) : nullptr;
}; };
@@ -263,11 +263,11 @@ static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom,
mjrf_setRenderableMaterial(renderable, &material); mjrf_setRenderableMaterial(renderable, &material);
} }
UniquePtr<mjrRenderable> CreateGeomRenderable( UniquePtr<mjrfRenderable> CreateGeomRenderable(
const mjvGeom& geom, mjrfContext* ctx, ModelObjects* model_objs, const mjvGeom& geom, mjrfContext* ctx, ModelObjects* model_objs,
const mjtByte render_flags[mjNRNDFLAG]) { const mjtByte render_flags[mjNRNDFLAG]) {
mjrRenderableParams params; mjrfRenderableParams params;
mjr_defaultRenderableParams(&params); mjrf_defaultRenderableParams(&params);
params.layer_mask = geom.category; params.layer_mask = geom.category;
auto renderable = CreateRenderable(ctx, params); auto renderable = CreateRenderable(ctx, params);
PrepareGeomMeshes(renderable.get(), geom, model_objs); PrepareGeomMeshes(renderable.get(), geom, model_objs);
@@ -24,7 +24,7 @@
namespace mujoco { namespace mujoco {
// Creates a Renderable from the given mjvGeom. // Creates a Renderable from the given mjvGeom.
UniquePtr<mjrRenderable> CreateGeomRenderable( UniquePtr<mjrfRenderable> CreateGeomRenderable(
const mjvGeom& geom, mjrfContext* ctx, ModelObjects* model_objs, const mjvGeom& geom, mjrfContext* ctx, ModelObjects* model_objs,
const mjtByte render_flags[mjNRNDFLAG]); const mjtByte render_flags[mjNRNDFLAG]);
@@ -59,16 +59,16 @@ static std::size_t NumIndicesPerSide(int num_quads_per_axis) {
return kNumIndicesPerQuad * num_quads_per_axis * num_quads_per_axis; return kNumIndicesPerQuad * num_quads_per_axis * num_quads_per_axis;
} }
class BuiltinBuilder : public mjrMeshData { class BuiltinBuilder : public mjrfMeshData {
public: public:
BuiltinBuilder() { mjr_defaultMeshData(this); } BuiltinBuilder() { mjrf_defaultMeshData(this); }
virtual ~BuiltinBuilder() = default; virtual ~BuiltinBuilder() = default;
template <typename T, typename... Args> template <typename T, typename... Args>
static std::unique_ptr<Mesh> Create(filament::Engine* engine, static std::unique_ptr<Mesh> Create(filament::Engine* engine,
Args&&... args) { Args&&... args) {
auto builder = new T(std::forward<Args>(args)...); auto builder = new T(std::forward<Args>(args)...);
mjrMeshData* mesh_data = builder->PrepareMeshData(); mjrfMeshData* mesh_data = builder->PrepareMeshData();
mesh_data->release_callback = +[](void* user_data) { mesh_data->release_callback = +[](void* user_data) {
delete static_cast<BuiltinBuilder*>(user_data); delete static_cast<BuiltinBuilder*>(user_data);
}; };
@@ -76,8 +76,8 @@ class BuiltinBuilder : public mjrMeshData {
return std::make_unique<Mesh>(engine, *mesh_data); return std::make_unique<Mesh>(engine, *mesh_data);
} }
mjrMeshData* PrepareMeshData() { mjrfMeshData* PrepareMeshData() {
// Update the `mjrMeshData` fields. // Update the `mjrfMeshData` fields.
nattributes = 2; nattributes = 2;
attributes[0].usage = mjVERTEX_ATTRIBUTE_USAGE_POSITION; attributes[0].usage = mjVERTEX_ATTRIBUTE_USAGE_POSITION;
attributes[0].type = mjVERTEX_ATTRIBUTE_TYPE_FLOAT3; attributes[0].type = mjVERTEX_ATTRIBUTE_TYPE_FLOAT3;
@@ -80,9 +80,9 @@ FilamentContext::~FilamentContext() {
filament::Engine::destroy(engine_); filament::Engine::destroy(engine_);
} }
mjrFrameHandle FilamentContext::Render( mjrfFrameHandle FilamentContext::Render(
std::span<const mjrRenderRequest> requests, std::span<const mjrfRenderRequest> requests,
std::span<const mjrReadPixelsRequest> read_requests) { std::span<const mjrfReadPixelsRequest> read_requests) {
if (read_requests.size() > 1) { if (read_requests.size() > 1) {
mju_error("Only one read request is supported for now."); mju_error("Only one read request is supported for now.");
} }
@@ -96,8 +96,8 @@ mjrFrameHandle FilamentContext::Render(
material_manager_->BeginFrame(); material_manager_->BeginFrame();
std::unordered_map<mjrScene*, std::vector<const mjrRenderRequest*>> scene_to_requests; std::unordered_map<mjrfScene*, std::vector<const mjrfRenderRequest*>> scene_to_requests;
for (const mjrRenderRequest& request : requests) { for (const mjrfRenderRequest& request : requests) {
scene_to_requests[request.scene].push_back(&request); scene_to_requests[request.scene].push_back(&request);
} }
for (auto& [scene, requests] : scene_to_requests) { for (auto& [scene, requests] : scene_to_requests) {
@@ -105,8 +105,8 @@ mjrFrameHandle FilamentContext::Render(
} }
bool render_began = false; bool render_began = false;
mjrRenderTarget* current_target = nullptr; mjrfRenderTarget* current_target = nullptr;
for (const mjrRenderRequest& request : requests) { for (const mjrfRenderRequest& request : requests) {
if (request.target != current_target && render_began) { if (request.target != current_target && render_began) {
renderer_->endFrame(); renderer_->endFrame();
render_began = false; render_began = false;
@@ -134,7 +134,7 @@ mjrFrameHandle FilamentContext::Render(
"Rendering to a render target without a read request is pointless."); "Rendering to a render target without a read request is pointless.");
} }
const mjrReadPixelsRequest& read_request = read_requests[0]; const mjrfReadPixelsRequest& read_request = read_requests[0];
if (read_request.num_bytes == 0) { if (read_request.num_bytes == 0) {
mju_error("Output buffer size is zero."); mju_error("Output buffer size is zero.");
} }
@@ -173,7 +173,7 @@ mjrFrameHandle FilamentContext::Render(
return ++frame_counter_; return ++frame_counter_;
} }
void FilamentContext::WaitForFrame(mjrFrameHandle frame_handle) { void FilamentContext::WaitForFrame(mjrfFrameHandle frame_handle) {
if (frame_counter_ < frame_handle) { if (frame_counter_ < frame_handle) {
engine_->flushAndWait(); engine_->flushAndWait();
} }
@@ -187,8 +187,8 @@ void FilamentContext::SetClearColor(const filament::math::float4& color) {
renderer_->setClearOptions(opts); renderer_->setClearOptions(opts);
} }
void FilamentContext::GetFrameStats(mjrFrameHandle frame, void FilamentContext::GetFrameStats(mjrfFrameHandle frame,
mjrFrameStats* stats_out) const { mjrfFrameStats* stats_out) const {
utils::FixedCapacityVector<filament::Renderer::FrameInfo> frame_info = utils::FixedCapacityVector<filament::Renderer::FrameInfo> frame_info =
renderer_->getFrameInfoHistory(1); renderer_->getFrameInfoHistory(1);
if (!frame_info.empty()) { if (!frame_info.empty()) {
@@ -200,14 +200,14 @@ void FilamentContext::GetFrameStats(mjrFrameHandle frame,
} }
void FilamentContext::ValidateSwapChains( void FilamentContext::ValidateSwapChains(
std::span<const mjrRenderRequest> requests) { std::span<const mjrfRenderRequest> requests) {
// Determine the maximum extents of the requests. // Determine the maximum extents of the requests.
int max_window_width = 0; int max_window_width = 0;
int max_window_height = 0; int max_window_height = 0;
int max_offscreen_width = 0; int max_offscreen_width = 0;
int max_offscreen_height = 0; int max_offscreen_height = 0;
for (const mjrRenderRequest& request : requests) { for (const mjrfRenderRequest& request : requests) {
const int width = request.viewport.width + request.viewport.left; const int width = request.viewport.width + request.viewport.left;
const int height = request.viewport.height + request.viewport.bottom; const int height = request.viewport.height + request.viewport.bottom;
if (request.target == nullptr) { if (request.target == nullptr) {
@@ -44,18 +44,18 @@ class FilamentContext : public mjrfContext {
// immediately afterwards. The renderer thread will then perform the actual // immediately afterwards. The renderer thread will then perform the actual
// rendering on the GPU. Callers can use WaitForFrame to block until the // rendering on the GPU. Callers can use WaitForFrame to block until the
// rendering is complete. // rendering is complete.
mjrFrameHandle Render( mjrfFrameHandle Render(
std::span<const mjrRenderRequest> render_requests, std::span<const mjrfRenderRequest> render_requests,
std::span<const mjrReadPixelsRequest> read_requests = {}); std::span<const mjrfReadPixelsRequest> read_requests = {});
// Blocks until the given frame has completed rendering. // Blocks until the given frame has completed rendering.
void WaitForFrame(mjrFrameHandle frame_handle); void WaitForFrame(mjrfFrameHandle frame_handle);
// Sets the clear color for the renderer. // Sets the clear color for the renderer.
void SetClearColor(const filament::math::float4& color); void SetClearColor(const filament::math::float4& color);
// Returns information about the frame. // Returns information about the frame.
void GetFrameStats(mjrFrameHandle frame, mjrFrameStats* stats_out) const; void GetFrameStats(mjrfFrameHandle frame, mjrfFrameStats* stats_out) const;
filament::Engine* GetEngine() const { return engine_; } filament::Engine* GetEngine() const { return engine_; }
@@ -71,7 +71,7 @@ class FilamentContext : public mjrfContext {
} }
private: private:
void ValidateSwapChains(std::span<const mjrRenderRequest> render_requests); void ValidateSwapChains(std::span<const mjrfRenderRequest> render_requests);
mjrFilamentConfig config_; mjrFilamentConfig config_;
filament::Engine* engine_ = nullptr; filament::Engine* engine_ = nullptr;
@@ -647,7 +647,7 @@ void DrawLightGui(filament::LightManager& lm,
extern "C" { extern "C" {
void mjrf_DEBUG_drawImguiEditor(mjrScene* scene) { void mjrf_DEBUG_drawImguiEditor(mjrfScene* scene) {
mujoco::SceneView* scene_view = mujoco::SceneView::downcast(scene); mujoco::SceneView* scene_view = mujoco::SceneView::downcast(scene);
filament::View* view = scene_view->GetDefaultRenderView(); filament::View* view = scene_view->GetDefaultRenderView();
filament::Engine* engine = scene_view->GetEngine(); filament::Engine* engine = scene_view->GetEngine();
+1 -1
View File
@@ -34,7 +34,7 @@ namespace mujoco {
using filament::math::float3; using filament::math::float3;
using filament::math::mat3f; using filament::math::mat3f;
Light::Light(filament::Engine* engine, const mjrLightParams& params) Light::Light(filament::Engine* engine, const mjrfLightParams& params)
: engine_(engine), params_(params) { : engine_(engine), params_(params) {
// Filament treats image-based lights (IBLs) as separate objects (i.e. // Filament treats image-based lights (IBLs) as separate objects (i.e.
// filament::IndirectLight) and so we need to handle IBLs specially. // filament::IndirectLight) and so we need to handle IBLs specially.
+5 -5
View File
@@ -26,9 +26,9 @@ namespace mujoco {
// Wrapper around both a "normal" filament Light Entity and a filament // Wrapper around both a "normal" filament Light Entity and a filament
// IndirectLight. // IndirectLight.
class Light : public mjrLight { class Light : public mjrfLight {
public: public:
Light(filament::Engine* engine, const mjrLightParams& params); Light(filament::Engine* engine, const mjrfLightParams& params);
~Light() noexcept; ~Light() noexcept;
Light(const Light&) = delete; Light(const Light&) = delete;
@@ -57,10 +57,10 @@ class Light : public mjrLight {
void Enable(); void Enable();
void Disable(); void Disable();
static Light* downcast(mjrLight* light) { static Light* downcast(mjrfLight* light) {
return static_cast<Light*>(light); return static_cast<Light*>(light);
} }
static const Light* downcast(const mjrLight* light) { static const Light* downcast(const mjrfLight* light) {
return static_cast<const Light*>(light); return static_cast<const Light*>(light);
} }
@@ -68,7 +68,7 @@ class Light : public mjrLight {
filament::Engine* engine_ = nullptr; filament::Engine* engine_ = nullptr;
filament::IndirectLight* ibl_ = nullptr; filament::IndirectLight* ibl_ = nullptr;
utils::Entity entity_; utils::Entity entity_;
mjrLightParams params_; mjrfLightParams params_;
bool enabled_ = true; bool enabled_ = true;
}; };
@@ -96,7 +96,7 @@ void MaterialManager::EndFrame() {
static MaterialManager::MaterialKey BuildMaterialKey( static MaterialManager::MaterialKey BuildMaterialKey(
MaterialManager::MaterialType material_type, mjtGeom geom_type, MaterialManager::MaterialType material_type, mjtGeom geom_type,
const mjrMaterial& material) { const mjrfMaterial& material) {
// Normally, hashing the struct by memory would be a problem because of // Normally, hashing the struct by memory would be a problem because of
// padding and other uninitialized data. However, we do a memset(0) on the // padding and other uninitialized data. However, we do a memset(0) on the
// entire structure in mjr_defaultMaterial so this should be safe. // entire structure in mjr_defaultMaterial so this should be safe.
@@ -107,7 +107,7 @@ static MaterialManager::MaterialKey BuildMaterialKey(
} }
MaterialManager::MaterialType MaterialManager::GetMaterialType( MaterialManager::MaterialType MaterialManager::GetMaterialType(
const mjrMaterial& material, const Mesh* mesh) { const mjrfMaterial& material, const Mesh* mesh) {
if (material.decor_ux) { if (material.decor_ux) {
if (material.color_texture) { if (material.color_texture) {
return ObjectManager::kUnlitUi; return ObjectManager::kUnlitUi;
@@ -190,7 +190,7 @@ MaterialManager::MaterialType MaterialManager::GetMaterialType(
} }
MaterialManager::MaterialKey MaterialManager::PrepareMaterialInstance( MaterialManager::MaterialKey MaterialManager::PrepareMaterialInstance(
const mjrMaterial& material, mjrDrawMode draw_mode, mjtGeom geom_type, const mjrfMaterial& material, mjrDrawMode draw_mode, mjtGeom geom_type,
const Mesh* mesh) { const Mesh* mesh) {
ObjectManager::MaterialType type; ObjectManager::MaterialType type;
if (draw_mode == mjDRAW_MODE_DEPTH) { if (draw_mode == mjDRAW_MODE_DEPTH) {
@@ -228,7 +228,7 @@ filament::MaterialInstance* MaterialManager::GetInstance(MaterialKey key) {
} }
void MaterialManager::UpdateMaterialInstance(filament::MaterialInstance* instance, void MaterialManager::UpdateMaterialInstance(filament::MaterialInstance* instance,
const mjrMaterial& material) { const mjrfMaterial& material) {
if (material.scissor[2] != 0 && material.scissor[3] != 0) { if (material.scissor[2] != 0 && material.scissor[3] != 0) {
instance->setScissor(material.scissor[0], material.scissor[1], instance->setScissor(material.scissor[0], material.scissor[1],
material.scissor[2], material.scissor[3]); material.scissor[2], material.scissor[3]);
@@ -285,7 +285,7 @@ void MaterialManager::UpdateMaterialInstance(filament::MaterialInstance* instanc
sampler.setMinFilter( sampler.setMinFilter(
filament::TextureSampler::MinFilter::LINEAR_MIPMAP_LINEAR); filament::TextureSampler::MinFilter::LINEAR_MIPMAP_LINEAR);
auto TrySetTexture = [&](const char* name, const mjrTexture* texture, auto TrySetTexture = [&](const char* name, const mjrfTexture* texture,
mjtTextureRole role) { mjtTextureRole role) {
if (fmaterial->hasParameter(name)) { if (fmaterial->hasParameter(name)) {
if (texture != nullptr) { if (texture != nullptr) {
@@ -32,7 +32,7 @@ namespace mujoco {
// Centralizing the MaterialInstance management allows multiple Renderables to // Centralizing the MaterialInstance management allows multiple Renderables to
// share the same MaterialInstance, which can reduce GPU overhead. // share the same MaterialInstance, which can reduce GPU overhead.
// MaterialInstance uniqueness is determined by hashing the parameters (mainly // MaterialInstance uniqueness is determined by hashing the parameters (mainly
// the mjrMaterial) used to create the instance. // the mjrfMaterial) used to create the instance.
// //
// Any unused MaterialInstances are destroyed at the end of each frame. // Any unused MaterialInstances are destroyed at the end of each frame.
class MaterialManager { class MaterialManager {
@@ -57,11 +57,11 @@ class MaterialManager {
void EndFrame(); void EndFrame();
// Returns a MaterialType that best matches the given material data and mesh. // Returns a MaterialType that best matches the given material data and mesh.
MaterialType GetMaterialType(const mjrMaterial& material, const Mesh* mesh); MaterialType GetMaterialType(const mjrfMaterial& material, const Mesh* mesh);
// Prepares a MaterialInstance based on the given parameters if one does not // Prepares a MaterialInstance based on the given parameters if one does not
// already exist. Returns the key associated with the MaterialInstance. // already exist. Returns the key associated with the MaterialInstance.
MaterialKey PrepareMaterialInstance(const mjrMaterial& material, MaterialKey PrepareMaterialInstance(const mjrfMaterial& material,
mjrDrawMode draw_mode, mjtGeom geom_type, mjrDrawMode draw_mode, mjtGeom geom_type,
const Mesh* mesh); const Mesh* mesh);
@@ -77,7 +77,7 @@ class MaterialManager {
// texture is not provided, a default texture from the ObjectManager will be // texture is not provided, a default texture from the ObjectManager will be
// used instead. // used instead.
void UpdateMaterialInstance(filament::MaterialInstance* instance, void UpdateMaterialInstance(filament::MaterialInstance* instance,
const mjrMaterial& material); const mjrfMaterial& material);
ObjectManager* object_mgr_; ObjectManager* object_mgr_;
std::unordered_map<MaterialKey, filament::MaterialInstance*> instances_; std::unordered_map<MaterialKey, filament::MaterialInstance*> instances_;
+8 -8
View File
@@ -102,7 +102,7 @@ int FillSequence(std::byte* buffer, std::size_t num_bytes) {
return num; return num;
} }
Mesh::Mesh(filament::Engine* engine, const mjrMeshData& data) Mesh::Mesh(filament::Engine* engine, const mjrfMeshData& data)
: engine_(engine), shared_state_(std::make_shared<SharedState>()) { : engine_(engine), shared_state_(std::make_shared<SharedState>()) {
type_ = data.primitive_type == mjMESH_PRIMITIVE_TYPE_TRIANGLES type_ = data.primitive_type == mjMESH_PRIMITIVE_TYPE_TRIANGLES
? filament::RenderableManager::PrimitiveType::TRIANGLES ? filament::RenderableManager::PrimitiveType::TRIANGLES
@@ -131,9 +131,9 @@ Mesh::~Mesh() {
} }
} }
void Mesh::BuildVertexBuffer(const mjrMeshData& data) { void Mesh::BuildVertexBuffer(const mjrfMeshData& data) {
if (data.nvertices == 0) { if (data.nvertices == 0) {
mju_error("mjrMeshData has no vertices."); mju_error("mjrfMeshData has no vertices.");
} }
// The filament BufferDescriptor callback for releasing the memory. // The filament BufferDescriptor callback for releasing the memory.
@@ -168,13 +168,13 @@ void Mesh::BuildVertexBuffer(const mjrMeshData& data) {
} }
} }
if (!positions) { if (!positions) {
mju_error("mjrMeshData has no positions."); mju_error("mjrfMeshData has no positions.");
} }
if (data.attributes[0].usage != mjVERTEX_ATTRIBUTE_USAGE_POSITION) { if (data.attributes[0].usage != mjVERTEX_ATTRIBUTE_USAGE_POSITION) {
mju_error("Positions must be the first attribute."); mju_error("Positions must be the first attribute.");
} }
if (normals && tangents) { if (normals && tangents) {
mju_error("mjrMeshData has both normals and tangents."); mju_error("mjrfMeshData has both normals and tangents.");
} }
if (normals && data.interleaved) { if (normals && data.interleaved) {
// We need to build orientations from normals and so we require each // We need to build orientations from normals and so we require each
@@ -253,7 +253,7 @@ void Mesh::BuildVertexBuffer(const mjrMeshData& data) {
} }
} }
void Mesh::BuildIndexBuffer(const mjrMeshData& data) { void Mesh::BuildIndexBuffer(const mjrfMeshData& data) {
if (data.nindices == 0) { if (data.nindices == 0) {
return; return;
} }
@@ -306,7 +306,7 @@ float4* Mesh::BuildOrientationsFromNormals(int nvertices,
return orientations; return orientations;
} }
void Mesh::UpdateBounds(const mjrMeshData& data) { void Mesh::UpdateBounds(const mjrfMeshData& data) {
float3 bounds_min = ReadFloat3(data.bounds_min); float3 bounds_min = ReadFloat3(data.bounds_min);
float3 bounds_max = ReadFloat3(data.bounds_max); float3 bounds_max = ReadFloat3(data.bounds_max);
if (bounds_min != bounds_max) { if (bounds_min != bounds_max) {
@@ -316,7 +316,7 @@ void Mesh::UpdateBounds(const mjrMeshData& data) {
bounds_max = float3(-FLT_MAX, -FLT_MAX, -FLT_MAX); bounds_max = float3(-FLT_MAX, -FLT_MAX, -FLT_MAX);
if (data.attributes[0].usage != mjVERTEX_ATTRIBUTE_USAGE_POSITION) { if (data.attributes[0].usage != mjVERTEX_ATTRIBUTE_USAGE_POSITION) {
mju_error("mjrMeshData has no positions."); mju_error("mjrfMeshData has no positions.");
} }
const float* positions = const float* positions =
reinterpret_cast<const float*>(data.attributes[0].bytes); reinterpret_cast<const float*>(data.attributes[0].bytes);
+7 -7
View File
@@ -33,10 +33,10 @@
namespace mujoco { namespace mujoco {
// Owns a filament Vertex and Index buffer representing a geometry mesh. // Owns a filament Vertex and Index buffer representing a geometry mesh.
class Mesh : public mjrMesh { class Mesh : public mjrfMesh {
public: public:
// Creates a Mesh from the given MeshData. // Creates a Mesh from the given MeshData.
Mesh(filament::Engine* engine, const mjrMeshData& data); Mesh(filament::Engine* engine, const mjrfMeshData& data);
~Mesh(); ~Mesh();
Mesh(const Mesh&) = delete; Mesh(const Mesh&) = delete;
@@ -60,17 +60,17 @@ class Mesh : public mjrMesh {
// Returns the bounds of the mesh. // Returns the bounds of the mesh.
filament::Box GetBounds() const; filament::Box GetBounds() const;
static Mesh* downcast(mjrMesh* mesh) { static Mesh* downcast(mjrfMesh* mesh) {
return static_cast<Mesh*>(mesh); return static_cast<Mesh*>(mesh);
} }
static const Mesh* downcast(const mjrMesh* mesh) { static const Mesh* downcast(const mjrfMesh* mesh) {
return static_cast<const Mesh*>(mesh); return static_cast<const Mesh*>(mesh);
} }
private: private:
void BuildVertexBuffer(const mjrMeshData& data); void BuildVertexBuffer(const mjrfMeshData& data);
void BuildIndexBuffer(const mjrMeshData& data); void BuildIndexBuffer(const mjrfMeshData& data);
void UpdateBounds(const mjrMeshData& data); void UpdateBounds(const mjrfMeshData& data);
filament::math::float4* BuildOrientationsFromNormals( filament::math::float4* BuildOrientationsFromNormals(
int nvertices, const mjrVertexAttribute& normals); int nvertices, const mjrVertexAttribute& normals);
@@ -31,11 +31,11 @@ void ReflectionManager::ClearRenderables() {
renderables_.clear(); renderables_.clear();
} }
mjrTexture* ReflectionManager::Register(mjrRenderable* renderable, int width, mjrfTexture* ReflectionManager::Register(mjrfRenderable* renderable, int width,
int height) { int height) {
if (targets_.size() == renderables_.size()) { if (targets_.size() == renderables_.size()) {
mjrRenderTargetConfig config; mjrRenderTargetConfig config;
mjr_defaultRenderTargetConfig(&config); mjrf_defaultRenderTargetConfig(&config);
config.color_format = mjPIXEL_FORMAT_RGBA8; config.color_format = mjPIXEL_FORMAT_RGBA8;
config.depth_format = mjPIXEL_FORMAT_DEPTH32F; config.depth_format = mjPIXEL_FORMAT_DEPTH32F;
targets_.push_back(std::make_unique<RenderTarget>(engine_, config)); targets_.push_back(std::make_unique<RenderTarget>(engine_, config));
@@ -50,7 +50,7 @@ int ReflectionManager::GetNumRenderables() const {
return renderables_.size(); return renderables_.size();
} }
mjrRenderable* ReflectionManager::GetRenderable(int index) const { mjrfRenderable* ReflectionManager::GetRenderable(int index) const {
return renderables_[index]; return renderables_[index];
} }
@@ -36,7 +36,7 @@ class ReflectionManager {
// Registers a Renderable as being reflective. Internally, this function will // Registers a Renderable as being reflective. Internally, this function will
// create a RenderTarget of the given size and return the texture that the // create a RenderTarget of the given size and return the texture that the
// Renderable can use as its reflection. // Renderable can use as its reflection.
mjrTexture* Register(mjrRenderable* renderable, int width, int height); mjrfTexture* Register(mjrfRenderable* renderable, int width, int height);
// Clears all previously registered renderables. This should be called at the // Clears all previously registered renderables. This should be called at the
// beginning of a frame. // beginning of a frame.
@@ -46,14 +46,14 @@ class ReflectionManager {
int GetNumRenderables() const; int GetNumRenderables() const;
// Returns the renderable at the given index. // Returns the renderable at the given index.
mjrRenderable* GetRenderable(int index) const; mjrfRenderable* GetRenderable(int index) const;
// Returns the RenderTarget at the given index. // Returns the RenderTarget at the given index.
const RenderTarget* GetRenderTarget(int index) const; const RenderTarget* GetRenderTarget(int index) const;
private: private:
filament::Engine* engine_; filament::Engine* engine_;
std::vector<mjrRenderable*> renderables_; std::vector<mjrfRenderable*> renderables_;
std::vector<std::unique_ptr<RenderTarget>> targets_; std::vector<std::unique_ptr<RenderTarget>> targets_;
}; };
} // namespace mujoco } // namespace mujoco
@@ -56,8 +56,8 @@ void RenderTarget::Prepare(int width, int height) {
return; return;
} }
mjrTextureConfig color_config; mjrfTextureConfig color_config;
mjr_defaultTextureConfig(&color_config); mjrf_defaultTextureConfig(&color_config);
Texture::InternalFlags color_flags; Texture::InternalFlags color_flags;
color_config.width = width; color_config.width = width;
color_config.height = height; color_config.height = height;
@@ -67,8 +67,8 @@ void RenderTarget::Prepare(int width, int height) {
color_flags.color_attachment = true; color_flags.color_attachment = true;
color_texture_ = std::make_unique<Texture>(engine_, color_config, color_flags); color_texture_ = std::make_unique<Texture>(engine_, color_config, color_flags);
mjrTextureConfig depth_config; mjrfTextureConfig depth_config;
mjr_defaultTextureConfig(&depth_config); mjrf_defaultTextureConfig(&depth_config);
Texture::InternalFlags depth_flags; Texture::InternalFlags depth_flags;
depth_config.width = width; depth_config.width = width;
depth_config.height = height; depth_config.height = height;
@@ -27,7 +27,7 @@
namespace mujoco { namespace mujoco {
// Manages a filament RenderTarget and the textures which are bound to it. // Manages a filament RenderTarget and the textures which are bound to it.
class RenderTarget : public mjrRenderTarget { class RenderTarget : public mjrfRenderTarget {
public: public:
// Defines the types of textures to create for the color and depth // Defines the types of textures to create for the color and depth
// attachments. // attachments.
@@ -54,10 +54,10 @@ class RenderTarget : public mjrRenderTarget {
// Returns the underlying filament render target. // Returns the underlying filament render target.
filament::RenderTarget* GetFilamentRenderTarget() const; filament::RenderTarget* GetFilamentRenderTarget() const;
static RenderTarget* downcast(mjrRenderTarget* render_target) { static RenderTarget* downcast(mjrfRenderTarget* render_target) {
return static_cast<RenderTarget*>(render_target); return static_cast<RenderTarget*>(render_target);
} }
static const RenderTarget* downcast(const mjrRenderTarget* render_target) { static const RenderTarget* downcast(const mjrfRenderTarget* render_target) {
return static_cast<const RenderTarget*>(render_target); return static_cast<const RenderTarget*>(render_target);
} }
@@ -55,10 +55,10 @@ static constexpr float kArrowScale = 1.f / 6.f;
static constexpr float kArrowHeadSize = 1.75f; static constexpr float kArrowHeadSize = 1.75f;
Renderable::Renderable(filament::Engine* engine, Renderable::Renderable(filament::Engine* engine,
const mjrRenderableParams& params, const mjrfRenderableParams& params,
MaterialManager* material_mgr) MaterialManager* material_mgr)
: material_mgr_(material_mgr), params_(params) { : material_mgr_(material_mgr), params_(params) {
mjr_defaultMaterial(&material_); mjrf_defaultMaterial(&material_);
} }
Renderable::~Renderable() noexcept { Renderable::~Renderable() noexcept {
@@ -222,15 +222,15 @@ void Renderable::RemoveFromScene(filament::Scene* scene) {
assigned_scene_ = nullptr; assigned_scene_ = nullptr;
} }
void Renderable::UpdateMaterial(const mjrMaterial& material) { void Renderable::UpdateMaterial(const mjrfMaterial& material) {
material_ = material; material_ = material;
} }
const mjrMaterial& Renderable::GetMaterial() const { const mjrfMaterial& Renderable::GetMaterial() const {
return material_; return material_;
} }
void Renderable::Prepare(std::span<const mjrRenderRequest*> requests, void Renderable::Prepare(std::span<const mjrfRenderRequest*> requests,
ReflectionManager* reflection_mgr) { ReflectionManager* reflection_mgr) {
// We assume BindMaterialInstance will be called with the same requests in // We assume BindMaterialInstance will be called with the same requests in
// the same order. As such, we'll just store the draw state in a deque rather // the same order. As such, we'll just store the draw state in a deque rather
@@ -238,9 +238,9 @@ void Renderable::Prepare(std::span<const mjrRenderRequest*> requests,
draw_queue_.clear(); draw_queue_.clear();
curr_state_ = DrawState(); curr_state_ = DrawState();
for (const mjrRenderRequest* request : requests) { for (const mjrfRenderRequest* request : requests) {
DrawState draw_state; DrawState draw_state;
mjrMaterial material = material_; mjrfMaterial material = material_;
draw_state.wireframe = (request->draw_mode == mjDRAW_MODE_WIREFRAME); draw_state.wireframe = (request->draw_mode == mjDRAW_MODE_WIREFRAME);
if (material.decor_ux) { if (material.decor_ux) {
@@ -324,7 +324,7 @@ void Renderable::Prepare(std::span<const mjrRenderRequest*> requests,
} }
} }
void Renderable::BindMaterialInstance(const mjrRenderRequest& request) { void Renderable::BindMaterialInstance(const mjrfRenderRequest& request) {
if (draw_queue_.empty()) { if (draw_queue_.empty()) {
mju_error("No material instances to bind."); mju_error("No material instances to bind.");
} }
+10 -10
View File
@@ -40,9 +40,9 @@ namespace mujoco {
// The mesh describes the surface geometry of the object and the material // The mesh describes the surface geometry of the object and the material
// describes how that surface interacts with light (i.e. the color of each point // describes how that surface interacts with light (i.e. the color of each point
// on the surface). // on the surface).
class Renderable : public mjrRenderable { class Renderable : public mjrfRenderable {
public: public:
Renderable(filament::Engine* engine, const mjrRenderableParams& params, Renderable(filament::Engine* engine, const mjrfRenderableParams& params,
MaterialManager* material_mgr); MaterialManager* material_mgr);
~Renderable() noexcept; ~Renderable() noexcept;
@@ -98,22 +98,22 @@ class Renderable : public mjrRenderable {
void RemoveFromScene(filament::Scene* scene); void RemoveFromScene(filament::Scene* scene);
// Updates the parameters and textures of the material for this renderable. // Updates the parameters and textures of the material for this renderable.
void UpdateMaterial(const mjrMaterial& material); void UpdateMaterial(const mjrfMaterial& material);
// Returns this renderable's current material. // Returns this renderable's current material.
const mjrMaterial& GetMaterial() const; const mjrfMaterial& GetMaterial() const;
// Prepares the material instances for the given render requests. // Prepares the material instances for the given render requests.
void Prepare(std::span<const mjrRenderRequest*> requests, void Prepare(std::span<const mjrfRenderRequest*> requests,
ReflectionManager* reflection_mgr); ReflectionManager* reflection_mgr);
// Binds the material instance for the given render request. // Binds the material instance for the given render request.
void BindMaterialInstance(const mjrRenderRequest& request); void BindMaterialInstance(const mjrfRenderRequest& request);
static Renderable* downcast(mjrRenderable* renderable) { static Renderable* downcast(mjrfRenderable* renderable) {
return static_cast<Renderable*>(renderable); return static_cast<Renderable*>(renderable);
} }
static const Renderable* downcast(const mjrRenderable* renderable) { static const Renderable* downcast(const mjrfRenderable* renderable) {
return static_cast<const Renderable*>(renderable); return static_cast<const Renderable*>(renderable);
} }
@@ -163,9 +163,9 @@ class Renderable : public mjrRenderable {
filament::Engine* GetEngine(); filament::Engine* GetEngine();
MaterialManager* material_mgr_; MaterialManager* material_mgr_;
mjrRenderableParams params_; mjrfRenderableParams params_;
mjtGeom geom_type_ = mjGEOM_NONE; mjtGeom geom_type_ = mjGEOM_NONE;
mjrMaterial material_; mjrfMaterial material_;
std::deque<DrawState> draw_queue_; std::deque<DrawState> draw_queue_;
DrawState curr_state_; DrawState curr_state_;
filament::Scene* assigned_scene_ = nullptr; filament::Scene* assigned_scene_ = nullptr;
@@ -120,7 +120,7 @@ static void SetupReflectionCamera(const mat4& surface_xform,
reflection_camera->setCustomProjection(oblique, near, far); reflection_camera->setCustomProjection(oblique, near, far);
} }
SceneView::SceneView(filament::Engine* engine, const mjrSceneParams& params) SceneView::SceneView(filament::Engine* engine, const mjrfSceneParams& params)
: engine_(engine) { : engine_(engine) {
reflection_mgr_ = std::make_unique<ReflectionManager>(engine_); reflection_mgr_ = std::make_unique<ReflectionManager>(engine_);
@@ -218,8 +218,8 @@ void SceneView::SetSkybox(const Texture* skybox_texture) {
} }
} }
void SceneView::PrepareToRender(std::span<const mjrRenderRequest*> requests) { void SceneView::PrepareToRender(std::span<const mjrfRenderRequest*> requests) {
for (const mjrRenderRequest* request : requests) { for (const mjrfRenderRequest* request : requests) {
if (request->scene != this) { if (request->scene != this) {
mju_error("Invalid scene for SceneView::PrepareToRender."); mju_error("Invalid scene for SceneView::PrepareToRender.");
} }
@@ -231,7 +231,7 @@ void SceneView::PrepareToRender(std::span<const mjrRenderRequest*> requests) {
} }
} }
void SceneView::Render(filament::Renderer* renderer, const mjrRenderRequest& request) { void SceneView::Render(filament::Renderer* renderer, const mjrfRenderRequest& request) {
if (request.scene != this) { if (request.scene != this) {
mju_error("Invalid scene for SceneView::Render."); mju_error("Invalid scene for SceneView::Render.");
} }
@@ -39,9 +39,9 @@ namespace mujoco {
// The filament Scene is populated with the objects (e.g. lights, renderables, // The filament Scene is populated with the objects (e.g. lights, renderables,
// skybox, etc.). It manages multiple views to support a variety of draw modes // skybox, etc.). It manages multiple views to support a variety of draw modes
// (e.g. normal, depth, segmentation, etc.) as well as reflective surfaces. // (e.g. normal, depth, segmentation, etc.) as well as reflective surfaces.
class SceneView : public mjrScene { class SceneView : public mjrfScene {
public: public:
SceneView(filament::Engine* engine, const mjrSceneParams& params); SceneView(filament::Engine* engine, const mjrfSceneParams& params);
~SceneView(); ~SceneView();
SceneView(const SceneView&) = delete; SceneView(const SceneView&) = delete;
@@ -57,10 +57,10 @@ class SceneView : public mjrScene {
// Performs necessary preparations in order to render the given requests. // Performs necessary preparations in order to render the given requests.
// Assumes that the Render() function will be called the same number of times // Assumes that the Render() function will be called the same number of times
// and in the same order with the given requests. // and in the same order with the given requests.
void PrepareToRender(std::span<const mjrRenderRequest*> requests); void PrepareToRender(std::span<const mjrfRenderRequest*> requests);
// Fulfills the given render request using the renderer. // Fulfills the given render request using the renderer.
void Render(filament::Renderer* renderer, const mjrRenderRequest& request); void Render(filament::Renderer* renderer, const mjrfRenderRequest& request);
// Returns the filament Engine managing the scene. // Returns the filament Engine managing the scene.
filament::Engine* GetEngine() const { return engine_; } filament::Engine* GetEngine() const { return engine_; }
@@ -77,10 +77,10 @@ class SceneView : public mjrScene {
// scene view accordingly. // scene view accordingly.
void Configure(const mjModel* model); void Configure(const mjModel* model);
static SceneView* downcast(mjrScene* scene) { static SceneView* downcast(mjrfScene* scene) {
return static_cast<SceneView*>(scene); return static_cast<SceneView*>(scene);
} }
static const SceneView* downcast(const mjrScene* scene) { static const SceneView* downcast(const mjrfScene* scene) {
return static_cast<const SceneView*>(scene); return static_cast<const SceneView*>(scene);
} }
@@ -30,16 +30,16 @@ namespace mujoco {
static constexpr int kNumFacesPerCube = 6; static constexpr int kNumFacesPerCube = 6;
static bool IsCompressed(const mjrTextureConfig& config) { static bool IsCompressed(const mjrfTextureConfig& config) {
return config.format == mjPIXEL_FORMAT_KTX; return config.format == mjPIXEL_FORMAT_KTX;
} }
static bool IsCubeMap(const mjrTextureConfig& config) { static bool IsCubeMap(const mjrfTextureConfig& config) {
return config.sampler_type == mjTEXTURE_CUBE || return config.sampler_type == mjTEXTURE_CUBE ||
config.sampler_type == mjTEXTURE_SKYBOX; config.sampler_type == mjTEXTURE_SKYBOX;
} }
static int GetFaceHeight(const mjrTextureConfig& config) { static int GetFaceHeight(const mjrfTextureConfig& config) {
int face_height = config.height; int face_height = config.height;
if (config.width != config.height) { if (config.width != config.height) {
if (config.width * kNumFacesPerCube != config.height) { if (config.width * kNumFacesPerCube != config.height) {
@@ -53,7 +53,7 @@ static int GetFaceHeight(const mjrTextureConfig& config) {
return face_height; return face_height;
} }
static int GetNumChannels(const mjrTextureConfig& config) { static int GetNumChannels(const mjrfTextureConfig& config) {
switch (config.format) { switch (config.format) {
case mjPIXEL_FORMAT_R8: case mjPIXEL_FORMAT_R8:
return 1; return 1;
@@ -67,7 +67,7 @@ static int GetNumChannels(const mjrTextureConfig& config) {
} }
} }
static filament::Texture::Format GetTextureFormat(const mjrTextureConfig& config) { static filament::Texture::Format GetTextureFormat(const mjrfTextureConfig& config) {
switch (config.format) { switch (config.format) {
case mjPIXEL_FORMAT_R8: case mjPIXEL_FORMAT_R8:
return filament::Texture::Format::R; return filament::Texture::Format::R;
@@ -82,7 +82,7 @@ static filament::Texture::Format GetTextureFormat(const mjrTextureConfig& config
} }
static filament::Texture::InternalFormat GetTextureInternalFormat( static filament::Texture::InternalFormat GetTextureInternalFormat(
const mjrTextureConfig& config) { const mjrfTextureConfig& config) {
if (config.color_space == mjCOLORSPACE_SRGB) { if (config.color_space == mjCOLORSPACE_SRGB) {
switch (config.format) { switch (config.format) {
case mjPIXEL_FORMAT_RGB8: case mjPIXEL_FORMAT_RGB8:
@@ -112,7 +112,7 @@ static filament::Texture::InternalFormat GetTextureInternalFormat(
} }
} }
Texture::Texture(filament::Engine* engine, const mjrTextureConfig& config, Texture::Texture(filament::Engine* engine, const mjrfTextureConfig& config,
InternalFlags flags) InternalFlags flags)
: engine_(engine), config_(config) { : engine_(engine), config_(config) {
if (IsCompressed(config_)) { if (IsCompressed(config_)) {
@@ -160,7 +160,7 @@ Texture::~Texture() {
} }
} }
void Texture::Upload(const mjrTextureData& data) { void Texture::Upload(const mjrfTextureData& data) {
user_data_ = data.user_data; user_data_ = data.user_data;
release_callback_ = data.release_callback; release_callback_ = data.release_callback;
+6 -6
View File
@@ -24,7 +24,7 @@
namespace mujoco { namespace mujoco {
// Wrapper around a filament::Texture. // Wrapper around a filament::Texture.
class Texture : public mjrTexture { class Texture : public mjrfTexture {
public: public:
// Flags for internal use. // Flags for internal use.
struct InternalFlags { struct InternalFlags {
@@ -34,7 +34,7 @@ class Texture : public mjrTexture {
}; };
// Creates a texture with the given data. // Creates a texture with the given data.
Texture(filament::Engine* engine, const mjrTextureConfig& config, Texture(filament::Engine* engine, const mjrfTextureConfig& config,
InternalFlags flags = InternalFlags()); InternalFlags flags = InternalFlags());
~Texture(); ~Texture();
@@ -43,7 +43,7 @@ class Texture : public mjrTexture {
Texture& operator=(const Texture&) = delete; Texture& operator=(const Texture&) = delete;
// Uploads the given data to the texture. // Uploads the given data to the texture.
void Upload(const mjrTextureData& data); void Upload(const mjrfTextureData& data);
// Returns the width of the texture. // Returns the width of the texture.
int GetWidth() const { return config_.width; } int GetWidth() const { return config_.width; }
@@ -63,10 +63,10 @@ class Texture : public mjrTexture {
return has_spherical_harmonics_ ? &spherical_harmonics_ : nullptr; return has_spherical_harmonics_ ? &spherical_harmonics_ : nullptr;
} }
static Texture* downcast(mjrTexture* texture) { static Texture* downcast(mjrfTexture* texture) {
return static_cast<Texture*>(texture); return static_cast<Texture*>(texture);
} }
static const Texture* downcast(const mjrTexture* texture) { static const Texture* downcast(const mjrfTexture* texture) {
return static_cast<const Texture*>(texture); return static_cast<const Texture*>(texture);
} }
@@ -75,7 +75,7 @@ class Texture : public mjrTexture {
filament::Engine* engine_ = nullptr; filament::Engine* engine_ = nullptr;
filament::Texture* texture_ = nullptr; filament::Texture* texture_ = nullptr;
mjrTextureConfig config_; mjrfTextureConfig config_;
SphericalHarmonics spherical_harmonics_; SphericalHarmonics spherical_harmonics_;
bool has_spherical_harmonics_ = false; bool has_spherical_harmonics_ = false;
+14 -14
View File
@@ -88,8 +88,8 @@ void CompatContext::Render(const mjrRect& viewport, const mjvScene* scene) {
} }
if (framebuffer_ == mjFB_WINDOW) { if (framebuffer_ == mjFB_WINDOW) {
mjrRenderRequest req; mjrfRenderRequest req;
mjr_defaultRenderRequest(&req); mjrf_defaultRenderRequest(&req);
req.scene = scene_bridge_->GetScene(); req.scene = scene_bridge_->GetScene();
req.draw_mode = draw_mode_; req.draw_mode = draw_mode_;
req.camera = scene_bridge_->GetCamera(); req.camera = scene_bridge_->GetCamera();
@@ -106,54 +106,54 @@ void CompatContext::ReadPixels(mjrRect viewport, unsigned char* rgb,
if (rgb) { if (rgb) {
mjrRenderTargetConfig config; mjrRenderTargetConfig config;
mjr_defaultRenderTargetConfig(&config); mjrf_defaultRenderTargetConfig(&config);
config.width = viewport.width; config.width = viewport.width;
config.height = viewport.height; config.height = viewport.height;
config.color_format = mjPIXEL_FORMAT_RGB8; config.color_format = mjPIXEL_FORMAT_RGB8;
config.depth_format = mjPIXEL_FORMAT_DEPTH32F; config.depth_format = mjPIXEL_FORMAT_DEPTH32F;
auto target = CreateRenderTarget(context_.get(), config); auto target = CreateRenderTarget(context_.get(), config);
mjrRenderRequest req; mjrfRenderRequest req;
mjr_defaultRenderRequest(&req); mjrf_defaultRenderRequest(&req);
req.scene = scene_bridge_->GetScene(); req.scene = scene_bridge_->GetScene();
req.draw_mode = draw_mode_; req.draw_mode = draw_mode_;
req.camera = scene_bridge_->GetCamera(); req.camera = scene_bridge_->GetCamera();
req.viewport = viewport; req.viewport = viewport;
req.target = target.get(); req.target = target.get();
mjrReadPixelsRequest read_req; mjrfReadPixelsRequest read_req;
mjr_defaultReadPixelsRequest(&read_req); mjrf_defaultReadPixelsRequest(&read_req);
read_req.target = target.get(); read_req.target = target.get();
read_req.output = rgb; read_req.output = rgb;
read_req.num_bytes = viewport.width * viewport.height * 3; read_req.num_bytes = viewport.width * viewport.height * 3;
const mjrFrameHandle frame = mjrf_render(context_.get(), &req, 1, &read_req, 1); const mjrfFrameHandle frame = mjrf_render(context_.get(), &req, 1, &read_req, 1);
mjrf_waitForFrame(context_.get(), frame); mjrf_waitForFrame(context_.get(), frame);
} }
if (depth) { if (depth) {
mjrRenderTargetConfig config; mjrRenderTargetConfig config;
mjr_defaultRenderTargetConfig(&config); mjrf_defaultRenderTargetConfig(&config);
config.width = viewport.width; config.width = viewport.width;
config.height = viewport.height; config.height = viewport.height;
config.color_format = mjPIXEL_FORMAT_R32F; config.color_format = mjPIXEL_FORMAT_R32F;
config.depth_format = mjPIXEL_FORMAT_DEPTH32F; config.depth_format = mjPIXEL_FORMAT_DEPTH32F;
auto target = CreateRenderTarget(context_.get(), config); auto target = CreateRenderTarget(context_.get(), config);
mjrRenderRequest req; mjrfRenderRequest req;
mjr_defaultRenderRequest(&req); mjrf_defaultRenderRequest(&req);
req.scene = scene_bridge_->GetScene(); req.scene = scene_bridge_->GetScene();
req.draw_mode = mjDRAW_MODE_DEPTH; req.draw_mode = mjDRAW_MODE_DEPTH;
req.camera = scene_bridge_->GetCamera(); req.camera = scene_bridge_->GetCamera();
req.viewport = viewport; req.viewport = viewport;
req.target = target.get(); req.target = target.get();
mjrReadPixelsRequest read_req; mjrfReadPixelsRequest read_req;
mjr_defaultReadPixelsRequest(&read_req); mjrf_defaultReadPixelsRequest(&read_req);
read_req.output = reinterpret_cast<uint8_t*>(depth); read_req.output = reinterpret_cast<uint8_t*>(depth);
read_req.num_bytes = viewport.width * viewport.height * sizeof(float); read_req.num_bytes = viewport.width * viewport.height * sizeof(float);
const mjrFrameHandle frame = mjrf_render(context_.get(), &req, 1, &read_req, 1); const mjrfFrameHandle frame = mjrf_render(context_.get(), &req, 1, &read_req, 1);
mjrf_waitForFrame(context_.get(), frame); mjrf_waitForFrame(context_.get(), frame);
} }
} }
@@ -43,26 +43,26 @@ void mjrf_defaultFilamentConfig(mjrFilamentConfig* config) {
memset(config, 0, sizeof(mjrFilamentConfig)); memset(config, 0, sizeof(mjrFilamentConfig));
} }
void mjr_defaultTextureData(mjrTextureData* data) { void mjrf_defaultTextureData(mjrfTextureData* data) {
memset(data, 0, sizeof(mjrTextureData)); memset(data, 0, sizeof(mjrfTextureData));
} }
void mjr_defaultTextureConfig(mjrTextureConfig* config) { void mjrf_defaultTextureConfig(mjrfTextureConfig* config) {
memset(config, 0, sizeof(mjrTextureConfig)); memset(config, 0, sizeof(mjrfTextureConfig));
} }
void mjr_defaultMeshData(mjrMeshData* data) { void mjrf_defaultMeshData(mjrfMeshData* data) {
memset(data, 0, sizeof(mjrMeshData)); memset(data, 0, sizeof(mjrfMeshData));
} }
void mjr_defaultSceneParams(mjrSceneParams* params) { void mjrf_defaultSceneParams(mjrfSceneParams* params) {
memset(params, 0, sizeof(mjrSceneParams)); memset(params, 0, sizeof(mjrfSceneParams));
params->layer_mask = 0xff; params->layer_mask = 0xff;
params->reflection_layer_mask = 0xff; params->reflection_layer_mask = 0xff;
} }
void mjr_defaultLightParams(mjrLightParams* params) { void mjrf_defaultLightParams(mjrfLightParams* params) {
memset(params, 0, sizeof(mjrLightParams)); memset(params, 0, sizeof(mjrfLightParams));
params->type = mjLIGHT_POINT; params->type = mjLIGHT_POINT;
params->texture = nullptr; params->texture = nullptr;
params->color[0] = 0; params->color[0] = 0;
@@ -77,8 +77,8 @@ void mjr_defaultLightParams(mjrLightParams* params) {
params->vsm_blur_width = 0.0f; params->vsm_blur_width = 0.0f;
} }
void mjr_defaultMaterial(mjrMaterial* material) { void mjrf_defaultMaterial(mjrfMaterial* material) {
memset(material, 0, sizeof(mjrMaterial)); memset(material, 0, sizeof(mjrfMaterial));
setf(material->color, {1.f, 1.f, 1.f, 1.f}); setf(material->color, {1.f, 1.f, 1.f, 1.f});
setf(material->uv_scale, {1, 1, 1}); setf(material->uv_scale, {1, 1, 1});
material->sleep_state = mjS_STATIC; material->sleep_state = mjS_STATIC;
@@ -90,8 +90,8 @@ void mjr_defaultMaterial(mjrMaterial* material) {
material->roughness = -1.0f; material->roughness = -1.0f;
} }
void mjr_defaultRenderableParams(mjrRenderableParams* params) { void mjrf_defaultRenderableParams(mjrfRenderableParams* params) {
memset(params, 0, sizeof(mjrRenderableParams)); memset(params, 0, sizeof(mjrfRenderableParams));
params->cast_shadows = true; params->cast_shadows = true;
params->receive_shadows = true; params->receive_shadows = true;
params->layer_mask = 0x01; params->layer_mask = 0x01;
@@ -99,25 +99,25 @@ void mjr_defaultRenderableParams(mjrRenderableParams* params) {
params->blend_order = 0; params->blend_order = 0;
} }
void mjr_defaultRenderTargetConfig(mjrRenderTargetConfig* config) { void mjrf_defaultRenderTargetConfig(mjrRenderTargetConfig* config) {
memset(config, 0, sizeof(mjrRenderTargetConfig)); memset(config, 0, sizeof(mjrRenderTargetConfig));
config->color_format = mjPIXEL_FORMAT_RGBA8; config->color_format = mjPIXEL_FORMAT_RGBA8;
config->depth_format = mjPIXEL_FORMAT_DEPTH32F; config->depth_format = mjPIXEL_FORMAT_DEPTH32F;
} }
void mjr_defaultRenderRequest(mjrRenderRequest* request) { void mjrf_defaultRenderRequest(mjrfRenderRequest* request) {
memset(request, 0, sizeof(mjrRenderRequest)); memset(request, 0, sizeof(mjrfRenderRequest));
request->enable_post_processing = true; request->enable_post_processing = true;
request->enable_reflections = true; request->enable_reflections = true;
request->enable_shadows = true; request->enable_shadows = true;
} }
void mjr_defaultReadPixelsRequest(mjrReadPixelsRequest* request) { void mjrf_defaultReadPixelsRequest(mjrfReadPixelsRequest* request) {
memset(request, 0, sizeof(mjrReadPixelsRequest)); memset(request, 0, sizeof(mjrfReadPixelsRequest));
} }
void mjr_defaultFrameStats(mjrFrameStats* stats) { void mjrf_defaultFrameStats(mjrfFrameStats* stats) {
memset(stats, 0, sizeof(mjrFrameStats)); memset(stats, 0, sizeof(mjrfFrameStats));
} }
mjrfContext* mjrf_createContext(const mjrFilamentConfig* config) { mjrfContext* mjrf_createContext(const mjrFilamentConfig* config) {
@@ -128,79 +128,79 @@ void mjrf_destroyContext(mjrfContext* ctx) {
delete mujoco::FilamentContext::downcast(ctx); delete mujoco::FilamentContext::downcast(ctx);
} }
mjrTexture* mjrf_createTexture(mjrfContext* ctx, mjrfTexture* mjrf_createTexture(mjrfContext* ctx,
const mjrTextureConfig* config) { const mjrfTextureConfig* config) {
return new mujoco::Texture( return new mujoco::Texture(
mujoco::FilamentContext::downcast(ctx)->GetEngine(), *config); mujoco::FilamentContext::downcast(ctx)->GetEngine(), *config);
} }
void mjrf_destroyTexture(mjrTexture* texture) { void mjrf_destroyTexture(mjrfTexture* texture) {
delete mujoco::Texture::downcast(texture); delete mujoco::Texture::downcast(texture);
} }
mjrMesh* mjrf_createMesh(mjrfContext* ctx, const mjrMeshData* data) { mjrfMesh* mjrf_createMesh(mjrfContext* ctx, const mjrfMeshData* data) {
return new mujoco::Mesh(mujoco::FilamentContext::downcast(ctx)->GetEngine(), return new mujoco::Mesh(mujoco::FilamentContext::downcast(ctx)->GetEngine(),
*data); *data);
} }
void mjrf_destroyMesh(mjrMesh* mesh) { delete mujoco::Mesh::downcast(mesh); } void mjrf_destroyMesh(mjrfMesh* mesh) { delete mujoco::Mesh::downcast(mesh); }
mjrScene* mjrf_createScene(mjrfContext* ctx, const mjrSceneParams* params) { mjrfScene* mjrf_createScene(mjrfContext* ctx, const mjrfSceneParams* params) {
return new mujoco::SceneView( return new mujoco::SceneView(
mujoco::FilamentContext::downcast(ctx)->GetEngine(), *params); mujoco::FilamentContext::downcast(ctx)->GetEngine(), *params);
} }
void mjrf_destroyScene(mjrScene* scene) { void mjrf_destroyScene(mjrfScene* scene) {
delete mujoco::SceneView::downcast(scene); delete mujoco::SceneView::downcast(scene);
} }
mjrLight* mjrf_createLight(mjrfContext* ctx, const mjrLightParams* params) { mjrfLight* mjrf_createLight(mjrfContext* ctx, const mjrfLightParams* params) {
return new mujoco::Light(mujoco::FilamentContext::downcast(ctx)->GetEngine(), return new mujoco::Light(mujoco::FilamentContext::downcast(ctx)->GetEngine(),
*params); *params);
} }
void mjrf_destroyLight(mjrLight* light) { void mjrf_destroyLight(mjrfLight* light) {
delete mujoco::Light::downcast(light); delete mujoco::Light::downcast(light);
} }
mjrRenderable* mjrf_createRenderable(mjrfContext* ctx, mjrfRenderable* mjrf_createRenderable(mjrfContext* ctx,
const mjrRenderableParams* params) { const mjrfRenderableParams* params) {
return new mujoco::Renderable( return new mujoco::Renderable(
mujoco::FilamentContext::downcast(ctx)->GetEngine(), *params, mujoco::FilamentContext::downcast(ctx)->GetEngine(), *params,
mujoco::FilamentContext::downcast(ctx)->GetMaterialManager()); mujoco::FilamentContext::downcast(ctx)->GetMaterialManager());
} }
void mjrf_destroyRenderable(mjrRenderable* renderable) { void mjrf_destroyRenderable(mjrfRenderable* renderable) {
delete mujoco::Renderable::downcast(renderable); delete mujoco::Renderable::downcast(renderable);
} }
mjrRenderTarget* mjrf_createRenderTarget(mjrfContext* ctx, mjrfRenderTarget* mjrf_createRenderTarget(mjrfContext* ctx,
const mjrRenderTargetConfig* config) { const mjrRenderTargetConfig* config) {
return new mujoco::RenderTarget( return new mujoco::RenderTarget(
mujoco::FilamentContext::downcast(ctx)->GetEngine(), *config); mujoco::FilamentContext::downcast(ctx)->GetEngine(), *config);
} }
void mjrf_destroyRenderTarget(mjrRenderTarget* render_target) { void mjrf_destroyRenderTarget(mjrfRenderTarget* render_target) {
delete mujoco::RenderTarget::downcast(render_target); delete mujoco::RenderTarget::downcast(render_target);
} }
void mjrf_setTextureData(mjrTexture* texture, const mjrTextureData* data) { void mjrf_setTextureData(mjrfTexture* texture, const mjrfTextureData* data) {
mujoco::Texture::downcast(texture)->Upload(*data); mujoco::Texture::downcast(texture)->Upload(*data);
} }
int mjrf_getTextureWidth(const mjrTexture* texture) { int mjrf_getTextureWidth(const mjrfTexture* texture) {
return mujoco::Texture::downcast(texture)->GetWidth(); return mujoco::Texture::downcast(texture)->GetWidth();
} }
int mjrf_getTextureHeight(const mjrTexture* texture) { int mjrf_getTextureHeight(const mjrfTexture* texture) {
return mujoco::Texture::downcast(texture)->GetHeight(); return mujoco::Texture::downcast(texture)->GetHeight();
} }
mjrSamplerType mjrf_getSamplerType(const mjrTexture* texture) { mjrSamplerType mjrf_getSamplerType(const mjrfTexture* texture) {
return mujoco::Texture::downcast(texture)->GetSamplerType(); return mujoco::Texture::downcast(texture)->GetSamplerType();
} }
void mjrf_setLightEnabled(mjrLight* light, mjtByte enabled) { void mjrf_setLightEnabled(mjrfLight* light, mjtBool enabled) {
if (enabled) { if (enabled) {
mujoco::Light::downcast(light)->Enable(); mujoco::Light::downcast(light)->Enable();
} else { } else {
@@ -208,48 +208,48 @@ void mjrf_setLightEnabled(mjrLight* light, mjtByte enabled) {
} }
} }
void mjrf_setLightIntensity(mjrLight* light, float intensity) { void mjrf_setLightIntensity(mjrfLight* light, float intensity) {
mujoco::Light::downcast(light)->SetIntensity(intensity); mujoco::Light::downcast(light)->SetIntensity(intensity);
} }
void mjrf_setLightColor(mjrLight* light, const float color[3]) { void mjrf_setLightColor(mjrfLight* light, const float color[3]) {
mujoco::Light::downcast(light)->SetColor({color[0], color[1], color[2]}); mujoco::Light::downcast(light)->SetColor({color[0], color[1], color[2]});
} }
void mjrf_setLightTransform(mjrLight* light, const float position[3], void mjrf_setLightTransform(mjrfLight* light, const float position[3],
const float direction[3]) { const float direction[3]) {
mujoco::Light::downcast(light)->SetTransform( mujoco::Light::downcast(light)->SetTransform(
{position[0], position[1], position[2]}, {position[0], position[1], position[2]},
{direction[0], direction[1], direction[2]}); {direction[0], direction[1], direction[2]});
} }
mjrLightType mjrf_getLightType(const mjrLight* light) { mjrLightType mjrf_getLightType(const mjrfLight* light) {
return mujoco::Light::downcast(light)->GetType(); return mujoco::Light::downcast(light)->GetType();
} }
void mjrf_setRenderableMesh(mjrRenderable* renderable, const mjrMesh* mesh, void mjrf_setRenderableMesh(mjrfRenderable* renderable, const mjrfMesh* mesh,
int elem_offset, int elem_count) { int elem_offset, int elem_count) {
mujoco::Renderable::downcast(renderable) mujoco::Renderable::downcast(renderable)
->SetMesh(mujoco::Mesh::downcast(mesh), elem_offset, elem_count); ->SetMesh(mujoco::Mesh::downcast(mesh), elem_offset, elem_count);
} }
void mjrf_setRenderableGeomMesh(mjrRenderable* renderable, mjtGeom type, void mjrf_setRenderableGeomMesh(mjrfRenderable* renderable, mjtGeom type,
int nstack, int nslice, int nquad) { int nstack, int nslice, int nquad) {
mujoco::Renderable::downcast(renderable)->SetGeomMesh(type, nstack, nslice, mujoco::Renderable::downcast(renderable)->SetGeomMesh(type, nstack, nslice,
nquad); nquad);
} }
void mjrf_setRenderableMaterial(mjrRenderable* renderable, void mjrf_setRenderableMaterial(mjrfRenderable* renderable,
const mjrMaterial* material) { const mjrfMaterial* material) {
mujoco::Renderable::downcast(renderable)->UpdateMaterial(*material); mujoco::Renderable::downcast(renderable)->UpdateMaterial(*material);
} }
void mjrf_getRenderableMaterial(mjrRenderable* renderable, void mjrf_getRenderableMaterial(mjrfRenderable* renderable,
mjrMaterial* material) { mjrfMaterial* material) {
*material = mujoco::Renderable::downcast(renderable)->GetMaterial(); *material = mujoco::Renderable::downcast(renderable)->GetMaterial();
} }
void mjrf_setRenderableTransform(mjrRenderable* renderable, void mjrf_setRenderableTransform(mjrfRenderable* renderable,
const float position[3], const float position[3],
const float rotation[9]) { const float rotation[9]) {
const filament::math::float3 fposition{position[0], position[1], position[2]}; const filament::math::float3 fposition{position[0], position[1], position[2]};
@@ -260,50 +260,50 @@ void mjrf_setRenderableTransform(mjrRenderable* renderable,
->SetTransform(fposition, frotation); ->SetTransform(fposition, frotation);
} }
void mjrf_setRenderableSize(mjrRenderable* renderable, const float size[3]) { void mjrf_setRenderableSize(mjrfRenderable* renderable, const float size[3]) {
const filament::math::float3 fsize{size[0], size[1], size[2]}; const filament::math::float3 fsize{size[0], size[1], size[2]};
mujoco::Renderable::downcast(renderable)->SetSize(fsize); mujoco::Renderable::downcast(renderable)->SetSize(fsize);
} }
void mjrf_addLightToScene(mjrScene* scene, mjrLight* light) { void mjrf_addLightToScene(mjrfScene* scene, mjrfLight* light) {
mujoco::SceneView::downcast(scene)->AddToScene( mujoco::SceneView::downcast(scene)->AddToScene(
mujoco::Light::downcast(light)); mujoco::Light::downcast(light));
} }
void mjrf_removeLightFromScene(mjrScene* scene, mjrLight* light) { void mjrf_removeLightFromScene(mjrfScene* scene, mjrfLight* light) {
mujoco::SceneView::downcast(scene)->RemoveFromScene( mujoco::SceneView::downcast(scene)->RemoveFromScene(
mujoco::Light::downcast(light)); mujoco::Light::downcast(light));
} }
void mjrf_addRenderableToScene(mjrScene* scene, mjrRenderable* renderable) { void mjrf_addRenderableToScene(mjrfScene* scene, mjrfRenderable* renderable) {
mujoco::SceneView::downcast(scene)->AddToScene( mujoco::SceneView::downcast(scene)->AddToScene(
mujoco::Renderable::downcast(renderable)); mujoco::Renderable::downcast(renderable));
} }
void mjrf_removeRenderableFromScene(mjrScene* scene, void mjrf_removeRenderableFromScene(mjrfScene* scene,
mjrRenderable* renderable) { mjrfRenderable* renderable) {
mujoco::SceneView::downcast(scene)->RemoveFromScene( mujoco::SceneView::downcast(scene)->RemoveFromScene(
mujoco::Renderable::downcast(renderable)); mujoco::Renderable::downcast(renderable));
} }
void mjrf_setSceneSkybox(mjrScene* scene, const mjrTexture* texture) { void mjrf_setSceneSkybox(mjrfScene* scene, const mjrfTexture* texture) {
mujoco::SceneView::downcast(scene)->SetSkybox( mujoco::SceneView::downcast(scene)->SetSkybox(
mujoco::Texture::downcast(texture)); mujoco::Texture::downcast(texture));
} }
void mjrf_configureSceneFromModel(mjrScene* scene, const mjModel* model) { void mjrf_configureSceneFromModel(mjrfScene* scene, const mjModel* model) {
mujoco::SceneView::downcast(scene)->Configure(model); mujoco::SceneView::downcast(scene)->Configure(model);
} }
mjrFrameHandle mjrf_render(mjrfContext* ctx, const mjrRenderRequest* req, mjrfFrameHandle mjrf_render(mjrfContext* ctx, const mjrfRenderRequest* req,
int nreq, const mjrReadPixelsRequest* read_req, int nreq, const mjrfReadPixelsRequest* read_req,
int nread_req) { int nread_req) {
return mujoco::FilamentContext::downcast(ctx)->Render( return mujoco::FilamentContext::downcast(ctx)->Render(
{req, static_cast<size_t>(nreq)}, {req, static_cast<size_t>(nreq)},
{read_req, static_cast<size_t>(nread_req)}); {read_req, static_cast<size_t>(nread_req)});
} }
void mjrf_waitForFrame(mjrfContext* ctx, mjrFrameHandle frame) { void mjrf_waitForFrame(mjrfContext* ctx, mjrfFrameHandle frame) {
mujoco::FilamentContext::downcast(ctx)->WaitForFrame(frame); mujoco::FilamentContext::downcast(ctx)->WaitForFrame(frame);
} }
@@ -312,8 +312,8 @@ void mjrf_setClearColor(mjrfContext* ctx, const float color[3]) {
{color[0], color[1], color[2], 1.0f}); {color[0], color[1], color[2], 1.0f});
} }
void mjrf_getFrameStats(mjrfContext* ctx, mjrFrameHandle frame, void mjrf_getFrameStats(mjrfContext* ctx, mjrfFrameHandle frame,
mjrFrameStats* stats_out) { mjrfFrameStats* stats_out) {
mujoco::FilamentContext::downcast(ctx)->GetFrameStats(frame, stats_out); mujoco::FilamentContext::downcast(ctx)->GetFrameStats(frame, stats_out);
} }
} // extern "C" } // extern "C"
@@ -60,12 +60,12 @@ extern "C" {
// //
// For now, we'll just define opaque handles for each of our components. // For now, we'll just define opaque handles for each of our components.
struct mjrfContext {}; struct mjrfContext {};
struct mjrTexture {}; struct mjrfTexture {};
struct mjrMesh {}; struct mjrfMesh {};
struct mjrScene {}; struct mjrfScene {};
struct mjrLight {}; struct mjrfLight {};
struct mjrRenderable {}; struct mjrfRenderable {};
struct mjrRenderTarget {}; struct mjrfRenderTarget {};
// ## Rendering Context (mjrfContext) // ## Rendering Context (mjrfContext)
// //
@@ -109,7 +109,7 @@ struct mjrFilamentConfig {
mjrGraphicsApi graphics_api; mjrGraphicsApi graphics_api;
// Use software rendering even if the platform supports hardware rendering. // Use software rendering even if the platform supports hardware rendering.
mjtByte force_software_rendering; mjtBool force_software_rendering;
}; };
// Initializes the mjrFilamentConfig to default values. // Initializes the mjrFilamentConfig to default values.
@@ -125,16 +125,22 @@ void mjrf_destroyContext(mjrfContext* ctx);
typedef enum mjrDrawMode_ { typedef enum mjrDrawMode_ {
// Render the scene with default settings for colors and lighting (shading). // Render the scene with default settings for colors and lighting (shading).
mjDRAW_MODE_DEFAULT, mjDRAW_MODE_DEFAULT,
// Like mjDRAW_MODE_DEFAULT, but disable textures. // Like mjDRAW_MODE_DEFAULT, but disable textures.
mjDRAW_MODE_DEFAULT_NO_TEXTURES, mjDRAW_MODE_DEFAULT_NO_TEXTURES,
// Render the scene as a wireframe. // Render the scene as a wireframe.
mjDRAW_MODE_WIREFRAME, mjDRAW_MODE_WIREFRAME,
// Render the scene as a grayscale depth map. // Render the scene as a grayscale depth map.
mjDRAW_MODE_DEPTH, mjDRAW_MODE_DEPTH,
// Render each object using its. // Render each object using its.
mjDRAW_MODE_ISLANDS, mjDRAW_MODE_ISLANDS,
// Render each object using its segmentation id (see mjrMaterial).
// Render each object using its segmentation id.
mjDRAW_MODE_SEGMENTATION_BY_ID, mjDRAW_MODE_SEGMENTATION_BY_ID,
// Render each object with a unique color based on its segmentation id. // Render each object with a unique color based on its segmentation id.
mjDRAW_MODE_SEGMENTATION_BY_COLOR, mjDRAW_MODE_SEGMENTATION_BY_COLOR,
} mjrDrawMode; } mjrDrawMode;
@@ -143,9 +149,9 @@ typedef enum mjrDrawMode_ {
typedef mjvGLCamera mjrCamera; typedef mjvGLCamera mjrCamera;
// Describes a single rendering operation; used by `mjrf_render()`. // Describes a single rendering operation; used by `mjrf_render()`.
struct mjrRenderRequest { struct mjrfRenderRequest {
// The scene to render. // The scene to render.
mjrScene* scene; mjrfScene* scene;
// The camera from which to render the scene. // The camera from which to render the scene.
mjrCamera camera; mjrCamera camera;
@@ -156,28 +162,28 @@ struct mjrRenderRequest {
// The render target into which to render the image. If nullptr, the image // The render target into which to render the image. If nullptr, the image
// will be rendered to the window (as previously configured in // will be rendered to the window (as previously configured in
// mjrFilamentConfig::native_window). // mjrFilamentConfig::native_window).
mjrRenderTarget* target; mjrfRenderTarget* target;
// The method (e.g. Color, Depth, Segmentation, etc.) to use for rendering. // The method (e.g. Color, Depth, Segmentation, etc.) to use for rendering.
mjrDrawMode draw_mode; mjrDrawMode draw_mode;
// Whether or not to enable post processing; enabled by default. // Whether or not to enable post processing; enabled by default.
mjtByte enable_post_processing; mjtBool enable_post_processing;
// Whether or not to enable reflections; enabled by default. // Whether or not to enable reflections; enabled by default.
mjtByte enable_reflections; mjtBool enable_reflections;
// Whether or not to enable shadows; enabled by default. // Whether or not to enable shadows; enabled by default.
mjtByte enable_shadows; mjtBool enable_shadows;
}; };
// Initializes the mjrRenderRequest to default values. // Initializes the mjrfRenderRequest to default values.
void mjr_defaultRenderRequest(mjrRenderRequest* request); void mjrf_defaultRenderRequest(mjrfRenderRequest* request);
// Information needed to read pixels; used by `mjrf_render()`. // Information needed to read pixels; used by `mjrf_render()`.
struct mjrReadPixelsRequest { struct mjrfReadPixelsRequest {
// The render target from which to read the image pixels. // The render target from which to read the image pixels.
mjrRenderTarget* target; mjrfRenderTarget* target;
// The buffer into which the read pixels will be written. // The buffer into which the read pixels will be written.
void* output; void* output;
@@ -194,13 +200,13 @@ struct mjrReadPixelsRequest {
void* user_data; void* user_data;
}; };
// Initializes the mjrReadPixelsRequest to default values. // Initializes the mjrfReadPixelsRequest to default values.
void mjr_defaultReadPixelsRequest(mjrReadPixelsRequest* request); void mjrf_defaultReadPixelsRequest(mjrfReadPixelsRequest* request);
// Because rendering is asynchronous, each render request is assigned a // Because rendering is asynchronous, each render request is assigned a
// unique Handle which can be used to query the status of the request. The // unique Handle which can be used to query the status of the request. The
// Handle can also be used to block until the request is completed. // Handle can also be used to block until the request is completed.
typedef std::uint64_t mjrFrameHandle; typedef std::uint64_t mjrfFrameHandle;
// Submits the given requests for rendering. Because rendering may happen // Submits the given requests for rendering. Because rendering may happen
// asynchronously, we have to submit both the render and read requests in the // asynchronously, we have to submit both the render and read requests in the
@@ -212,36 +218,36 @@ typedef std::uint64_t mjrFrameHandle;
// requests should be grouped by target. Next, the combined area of the // requests should be grouped by target. Next, the combined area of the
// viewports for all requests for a given target must be contained within the // viewports for all requests for a given target must be contained within the
// dimensions of the target itself. // dimensions of the target itself.
mjrFrameHandle mjrf_render(mjrfContext* ctx, const mjrRenderRequest* req, mjrfFrameHandle mjrf_render(mjrfContext* ctx, const mjrfRenderRequest* req,
int nreq, const mjrReadPixelsRequest* read_req, int nreq, const mjrfReadPixelsRequest* read_req,
int nread_req); int nread_req);
// Waits for all rendering operations to complete for the given frame handle, // Waits for all rendering operations to complete for the given frame handle,
// triggering any callbacks as needed. // triggering any callbacks as needed.
void mjrf_waitForFrame(mjrfContext* ctx, mjrFrameHandle frame); void mjrf_waitForFrame(mjrfContext* ctx, mjrfFrameHandle frame);
// Sets the clear color for the renderer. // Sets the clear color for the renderer.
void mjrf_setClearColor(mjrfContext* ctx, const float color[3]); void mjrf_setClearColor(mjrfContext* ctx, const float color[3]);
// Information about a single frame of rendering. // Information about a single frame of rendering.
struct mjrFrameStats { struct mjrfFrameStats {
// The frame rate of the renderer, in frames per second. // The frame rate of the renderer, in frames per second.
double frame_rate; double frame_rate;
}; };
// Initializes the mjrFrameStats to default values. // Initializes the mjrFrameStats to default values.
void mjr_defaultFrameStats(mjrFrameStats* stats); void mjrf_defaultFrameStats(mjrfFrameStats* stats);
// Returns the stats for the given frame but updating the given `stats_out`. // Returns the stats for the given frame but updating the given `stats_out`.
void mjrf_getFrameStats(mjrfContext* ctx, mjrFrameHandle frame, void mjrf_getFrameStats(mjrfContext* ctx, mjrfFrameHandle frame,
mjrFrameStats* stats_out); mjrfFrameStats* stats_out);
// ## Textures (mjrTexture) // ## Textures (mjrfTexture)
// //
// A texture is a 2D or 3D (cubemap) image that adds visual detail to a rendered // A texture is a 2D or 3D (cubemap) image that adds visual detail to a rendered
// model, such as color or bumpiness, without increasing geometric complexity. // model, such as color or bumpiness, without increasing geometric complexity.
// //
// For textures intended to be used for image-based lights (see `mjrLight` // For textures intended to be used for image-based lights (see `mjrfLight`
// below), you should use filament's `cmgen` tool to generate a KTX image from // below), you should use filament's `cmgen` tool to generate a KTX image from
// your source image. This tool will calculate additional data (i.e. the // your source image. This tool will calculate additional data (i.e. the
// spherical harmonics) and encode that information into the KTX file. // spherical harmonics) and encode that information into the KTX file.
@@ -264,7 +270,7 @@ typedef mjtTexture mjrSamplerType;
typedef mjtColorSpace mjrColorSpace; typedef mjtColorSpace mjrColorSpace;
// Defines the basic properties of a texture. // Defines the basic properties of a texture.
struct mjrTextureConfig { struct mjrfTextureConfig {
// The width of the texture. For compressed textures (e.g. KTX), this is the // The width of the texture. For compressed textures (e.g. KTX), this is the
// number of bytes in the compressed data. // number of bytes in the compressed data.
int width; int width;
@@ -283,18 +289,18 @@ struct mjrTextureConfig {
mjrColorSpace color_space; mjrColorSpace color_space;
}; };
// Initializes the mjrTextureConfig to default values. // Initializes the mjrfTextureConfig to default values.
void mjr_defaultTextureConfig(mjrTextureConfig* config); void mjrf_defaultTextureConfig(mjrfTextureConfig* config);
// Creates a texture with the given configuration. Note that the texture will // Creates a texture with the given configuration. Note that the texture will
// not be created on the GPU until `mjrf_setTextureData()` is called. // not be created on the GPU until `mjrf_setTextureData()` is called.
mjrTexture* mjrf_createTexture(mjrfContext* ctx, const mjrTextureConfig* config); mjrfTexture* mjrf_createTexture(mjrfContext* ctx, const mjrfTextureConfig* config);
// Destroys the texture. // Destroys the texture.
void mjrf_destroyTexture(mjrTexture* texture); void mjrf_destroyTexture(mjrfTexture* texture);
// The binary data for a texture. // The binary data for a texture.
struct mjrTextureData { struct mjrfTextureData {
// Pointer to the data. If null, an empty texture will be created. // Pointer to the data. If null, an empty texture will be created.
const void* bytes; const void* bytes;
@@ -310,22 +316,22 @@ struct mjrTextureData {
void* user_data; void* user_data;
}; };
// Initializes the mjrTextureData to default values. // Initializes the mjrfTextureData to default values.
void mjr_defaultTextureData(mjrTextureData* data); void mjrf_defaultTextureData(mjrfTextureData* data);
// Uploads the given texture data to the texture. // Uploads the given texture data to the texture.
void mjrf_setTextureData(mjrTexture* texture, const mjrTextureData* data); void mjrf_setTextureData(mjrfTexture* texture, const mjrfTextureData* data);
// Returns the width of the texture. // Returns the width of the texture.
int mjrf_getTextureWidth(const mjrTexture* texture); int mjrf_getTextureWidth(const mjrfTexture* texture);
// Returns the height of the texture. // Returns the height of the texture.
int mjrf_getTextureHeight(const mjrTexture* texture); int mjrf_getTextureHeight(const mjrfTexture* texture);
// Returns the target type of the texture. // Returns the target type of the texture.
mjrSamplerType mjrf_getSamplerType(const mjrTexture* texture); mjrSamplerType mjrf_getSamplerType(const mjrfTexture* texture);
// ## Meshes (mjrMesh) // ## Meshes (mjrfMesh)
// //
// A mesh describes the surface geometry of an object to be rendered. It is // A mesh describes the surface geometry of an object to be rendered. It is
// defined as a collection of vertices (i.e. a VertexBuffer), a set of indices // defined as a collection of vertices (i.e. a VertexBuffer), a set of indices
@@ -387,7 +393,7 @@ struct mjrVertexAttribute {
enum { mjMAX_VERTEX_ATTRIBUTES = 16 }; enum { mjMAX_VERTEX_ATTRIBUTES = 16 };
// The binary contents of a mesh. // The binary contents of a mesh.
struct mjrMeshData { struct mjrfMeshData {
// The number of vertices in the mesh. Each of the vertex arrays below is // The number of vertices in the mesh. Each of the vertex arrays below is
// assumed to have this number of elements. // assumed to have this number of elements.
mjtSize nvertices; mjtSize nvertices;
@@ -408,7 +414,7 @@ struct mjrMeshData {
// //
// If false, assume each attribute is stored in a separate array as defined // If false, assume each attribute is stored in a separate array as defined
// by the `data` field of the attribute. // by the `data` field of the attribute.
mjtByte interleaved; mjtBool interleaved;
// The number of indices in the mesh. The indices array is assumed to have // The number of indices in the mesh. The indices array is assumed to have
// this number of elements. // this number of elements.
@@ -425,7 +431,7 @@ struct mjrMeshData {
mjrMeshPrimitiveType primitive_type; mjrMeshPrimitiveType primitive_type;
// Whether to compute the bounds of the mesh using the vertex positions. // Whether to compute the bounds of the mesh using the vertex positions.
mjtByte compute_bounds; mjtBool compute_bounds;
// The bounds of the mesh. If bounds_min == bounds_max, then we assume that // The bounds of the mesh. If bounds_min == bounds_max, then we assume that
// that the bounds are not set (i.e. the bounds is empty). // that the bounds are not set (i.e. the bounds is empty).
@@ -441,23 +447,23 @@ struct mjrMeshData {
void* user_data; void* user_data;
}; };
// Initializes the mjrMeshData to default values. // Initializes the mjrfMeshData to default values.
void mjr_defaultMeshData(mjrMeshData* data); void mjrf_defaultMeshData(mjrfMeshData* data);
// Creates a mesh with the given data. // Creates a mesh with the given data.
mjrMesh* mjrf_createMesh(mjrfContext* ctx, const mjrMeshData* data); mjrfMesh* mjrf_createMesh(mjrfContext* ctx, const mjrfMeshData* data);
// Destroys the mesh. // Destroys the mesh.
void mjrf_destroyMesh(mjrMesh* mesh); void mjrf_destroyMesh(mjrfMesh* mesh);
// ## Scenes (mjrScene) // ## Scenes (mjrfScene)
// //
// A scene is a collection of entities (Lights and Renderables) that defines // A scene is a collection of entities (Lights and Renderables) that defines
// what is to be rendered. It also specifies the various effects that are to be // what is to be rendered. It also specifies the various effects that are to be
// applied to the rendering (e.g. shadows, reflections, post-processing, etc.) // applied to the rendering (e.g. shadows, reflections, post-processing, etc.)
// Configuration parameters for a Scene. // Configuration parameters for a Scene.
struct mjrSceneParams { struct mjrfSceneParams {
// This mask, in conjunction with the layer mask in the Renderable, determines // This mask, in conjunction with the layer mask in the Renderable, determines
// which Renderables to render within the Scene. // which Renderables to render within the Scene.
uint8_t layer_mask; uint8_t layer_mask;
@@ -466,34 +472,34 @@ struct mjrSceneParams {
uint8_t reflection_layer_mask; uint8_t reflection_layer_mask;
}; };
// Initializes the mjrSceneParams to default values. // Initializes the mjrfSceneParams to default values.
void mjr_defaultSceneParams(mjrSceneParams* params); void mjrf_defaultSceneParams(mjrfSceneParams* params);
// Creates a scene with the given parameters. // Creates a scene with the given parameters.
mjrScene* mjrf_createScene(mjrfContext* ctx, const mjrSceneParams* params); mjrfScene* mjrf_createScene(mjrfContext* ctx, const mjrfSceneParams* params);
// Destroys the scene. // Destroys the scene.
void mjrf_destroyScene(mjrScene* scene); void mjrf_destroyScene(mjrfScene* scene);
// Adds a light to the scene. // Adds a light to the scene.
void mjrf_addLightToScene(mjrScene* scene, mjrLight* light); void mjrf_addLightToScene(mjrfScene* scene, mjrfLight* light);
// Removes the light from the scene. // Removes the light from the scene.
void mjrf_removeLightFromScene(mjrScene* scene, mjrLight* light); void mjrf_removeLightFromScene(mjrfScene* scene, mjrfLight* light);
// Adds a renderable to the scene. // Adds a renderable to the scene.
void mjrf_addRenderableToScene(mjrScene* scene, mjrRenderable* renderable); void mjrf_addRenderableToScene(mjrfScene* scene, mjrfRenderable* renderable);
// Removes the renderable from the scene. // Removes the renderable from the scene.
void mjrf_removeRenderableFromScene(mjrScene* scene, mjrRenderable* renderable); void mjrf_removeRenderableFromScene(mjrfScene* scene, mjrfRenderable* renderable);
// Sets the skybox (cube texture) for the scene. // Sets the skybox (cube texture) for the scene.
void mjrf_setSceneSkybox(mjrScene* scene, const mjrTexture* texture); void mjrf_setSceneSkybox(mjrfScene* scene, const mjrfTexture* texture);
// Configures the scene based on the parameters in an mjModel. // Configures the scene based on the parameters in an mjModel.
void mjrf_configureSceneFromModel(mjrScene* scene, const mjModel* model); void mjrf_configureSceneFromModel(mjrfScene* scene, const mjModel* model);
// ## Lights (mjrLight) // ## Lights (mjrfLight)
// //
// A light is a source of illumination in the scene. (Without lights, a scene // A light is a source of illumination in the scene. (Without lights, a scene
// will be completely black.) There are several different types of lights such // will be completely black.) There are several different types of lights such
@@ -517,12 +523,12 @@ void mjrf_configureSceneFromModel(mjrScene* scene, const mjModel* model);
typedef mjtLightType mjrLightType; typedef mjtLightType mjrLightType;
// Configuration parameters for a light. // Configuration parameters for a light.
struct mjrLightParams { struct mjrfLightParams {
// The type of light (e.g. spot, point, directional, etc.) // The type of light (e.g. spot, point, directional, etc.)
mjrLightType type; mjrLightType type;
// The texture to use for image lights. // The texture to use for image lights.
const mjrTexture* texture; const mjrfTexture* texture;
// The color of the light. // The color of the light.
float color[3]; float color[3];
@@ -531,7 +537,7 @@ struct mjrLightParams {
float intensity; float intensity;
// Whether or not the light casts shadows. // Whether or not the light casts shadows.
mjtByte cast_shadows; mjtBool cast_shadows;
// The range/distance in which the light is effective, in meters. // The range/distance in which the light is effective, in meters.
float range; float range;
@@ -549,32 +555,32 @@ struct mjrLightParams {
float vsm_blur_width; float vsm_blur_width;
}; };
// Initializes the mjrLightParams to default values. // Initializes the mjrfLightParams to default values.
void mjr_defaultLightParams(mjrLightParams* params); void mjrf_defaultLightParams(mjrfLightParams* params);
// Creates a light for the filament renderer. // Creates a light for the filament renderer.
mjrLight* mjrf_createLight(mjrfContext* ctx, const mjrLightParams* params); mjrfLight* mjrf_createLight(mjrfContext* ctx, const mjrfLightParams* params);
// Destroys the light. // Destroys the light.
void mjrf_destroyLight(mjrLight* light); void mjrf_destroyLight(mjrfLight* light);
// Enables or disables the light. // Enables or disables the light.
void mjrf_setLightEnabled(mjrLight* light, mjtByte enabled); void mjrf_setLightEnabled(mjrfLight* light, mjtBool enabled);
// Sets the intensity of the light, in candela. // Sets the intensity of the light, in candela.
void mjrf_setLightIntensity(mjrLight* light, float intensity); void mjrf_setLightIntensity(mjrfLight* light, float intensity);
// Sets the RGB color of the light. // Sets the RGB color of the light.
void mjrf_setLightColor(mjrLight* light, const float color[3]); void mjrf_setLightColor(mjrfLight* light, const float color[3]);
// Sets the position and direction of the light. // Sets the position and direction of the light.
void mjrf_setLightTransform(mjrLight* light, const float position[3], void mjrf_setLightTransform(mjrfLight* light, const float position[3],
const float direction[3]); const float direction[3]);
// Returns the type of the light. // Returns the type of the light.
mjrLightType mjrf_getLightType(const mjrLight* light); mjrLightType mjrf_getLightType(const mjrfLight* light);
// ## Renderables (mjrRenderable) // ## Renderables (mjrfRenderable)
// //
// A renderable is a single drawable object in the scene. It is defined as a // A renderable is a single drawable object in the scene. It is defined as a
// combination of a mesh (i.e. surface geometry) and a material (i.e. surface // combination of a mesh (i.e. surface geometry) and a material (i.e. surface
@@ -589,10 +595,10 @@ mjrLightType mjrf_getLightType(const mjrLight* light);
// 3. Unlit: this model ignores lighting and used for rendering UX or decorative // 3. Unlit: this model ignores lighting and used for rendering UX or decorative
// elements like contact forces and labels. // elements like contact forces and labels.
// //
// Which lighting model is used is determined by the mjrMaterial properties. // Which lighting model is used is determined by the mjrfMaterial properties.
// The material to be applied to a renderable. // The material to be applied to a renderable.
struct mjrMaterial { struct mjrfMaterial {
// The color of the object. Defaults to white. // The color of the object. Defaults to white.
float color[4]; float color[4];
@@ -632,51 +638,51 @@ struct mjrMaterial {
// If true, does not apply any lighting to the object. Assumes the object is // If true, does not apply any lighting to the object. Assumes the object is
// used for UX or decorative elements like contact forces and labels. // used for UX or decorative elements like contact forces and labels.
mjtByte decor_ux; mjtBool decor_ux;
// If true, renders the object such that it appears "selected" for the // If true, renders the object such that it appears "selected" for the
// purposes of UX visualization. // purposes of UX visualization.
mjtByte selected; mjtBool selected;
// The texture containing the base color of the object. // The texture containing the base color of the object.
const mjrTexture* color_texture; const mjrfTexture* color_texture;
// The texture containing the opacity of the object. // The texture containing the opacity of the object.
const mjrTexture* opacity_texture; const mjrfTexture* opacity_texture;
// The normal map of the object. // The normal map of the object.
const mjrTexture* normal_texture; const mjrfTexture* normal_texture;
// The metallic map of the object. // The metallic map of the object.
const mjrTexture* metallic_texture; const mjrfTexture* metallic_texture;
// The roughness map of the object. // The roughness map of the object.
const mjrTexture* roughness_texture; const mjrfTexture* roughness_texture;
// The occlusion map of the object. // The occlusion map of the object.
const mjrTexture* occlusion_texture; const mjrfTexture* occlusion_texture;
// A texture containing the occlusion, roughness, and metallic maps packed // A texture containing the occlusion, roughness, and metallic maps packed
// into the R, G, B channels, respectively. // into the R, G, B channels, respectively.
const mjrTexture* orm_texture; const mjrfTexture* orm_texture;
// An emissive texture for the object. // An emissive texture for the object.
const mjrTexture* emissive_texture; const mjrfTexture* emissive_texture;
// The reflection texture to use for the object. For internal use only. // The reflection texture to use for the object. For internal use only.
const mjrTexture* reflection_texture; const mjrfTexture* reflection_texture;
}; };
// Initializes the mjrMaterial to default values. // Initializes the mjrfMaterial to default values.
void mjr_defaultMaterial(mjrMaterial* material); void mjrf_defaultMaterial(mjrfMaterial* material);
// Configuration parameters for a Renderable. // Configuration parameters for a Renderable.
struct mjrRenderableParams { struct mjrfRenderableParams {
// Whether or not the Renderable casts shadows. // Whether or not the Renderable casts shadows.
mjtByte cast_shadows; mjtBool cast_shadows;
// Whether or not the Renderable receives shadows. // Whether or not the Renderable receives shadows.
mjtByte receive_shadows; mjtBool receive_shadows;
// The layers to which the Renderable belongs. This mask is used in // The layers to which the Renderable belongs. This mask is used in
// conjunction with the layer mask in the Scene to determine which // conjunction with the layer mask in the Scene to determine which
@@ -692,36 +698,36 @@ struct mjrRenderableParams {
uint16_t blend_order; uint16_t blend_order;
}; };
// Initializes the mjrRenderableParams to default values. // Initializes the mjrfRenderableParams to default values.
void mjr_defaultRenderableParams(mjrRenderableParams* params); void mjrf_defaultRenderableParams(mjrfRenderableParams* params);
// Creates a renderable with the given parameters. // Creates a renderable with the given parameters.
mjrRenderable* mjrf_createRenderable(mjrfContext* ctx, mjrfRenderable* mjrf_createRenderable(mjrfContext* ctx,
const mjrRenderableParams* params); const mjrfRenderableParams* params);
// Destroys the renderable. // Destroys the renderable.
void mjrf_destroyRenderable(mjrRenderable* renderable); void mjrf_destroyRenderable(mjrfRenderable* renderable);
// Sets the mesh of the renderable. // Sets the mesh of the renderable.
void mjrf_setRenderableMesh(mjrRenderable* renderable, const mjrMesh* mesh, void mjrf_setRenderableMesh(mjrfRenderable* renderable, const mjrfMesh* mesh,
int elem_offset, int elem_count); int elem_offset, int elem_count);
// Sets the mesh of the renderable to a built-in mesh based on the geom type. // Sets the mesh of the renderable to a built-in mesh based on the geom type.
// Note: using the same parameters (nstack, nslice, nquad) will have better // Note: using the same parameters (nstack, nslice, nquad) will have better
// performance as the internal mesh data can be shared across renderables. // performance as the internal mesh data can be shared across renderables.
void mjrf_setRenderableGeomMesh(mjrRenderable* renderable, mjtGeom type, void mjrf_setRenderableGeomMesh(mjrfRenderable* renderable, mjtGeom type,
int nstack, int nslice, int nquad); int nstack, int nslice, int nquad);
// Sets the material properties and textures of the renderable. // Sets the material properties and textures of the renderable.
void mjrf_setRenderableMaterial(mjrRenderable* renderable, void mjrf_setRenderableMaterial(mjrfRenderable* renderable,
const mjrMaterial* material); const mjrfMaterial* material);
// Copies the material properties of the renderable into the given mjrMaterial. // Copies the material properties of the renderable into the given mjrfMaterial.
void mjrf_getRenderableMaterial(mjrRenderable* renderable, void mjrf_getRenderableMaterial(mjrfRenderable* renderable,
mjrMaterial* material); mjrfMaterial* material);
// Sets the transform position and rotation of the renderable. // Sets the transform position and rotation of the renderable.
void mjrf_setRenderableTransform(mjrRenderable* renderable, void mjrf_setRenderableTransform(mjrfRenderable* renderable,
const float position[3], const float position[3],
const float rotation[9]); const float rotation[9]);
@@ -729,9 +735,9 @@ void mjrf_setRenderableTransform(mjrRenderable* renderable,
// equivalent to setting the scale. However, for some geom-based renderables, // equivalent to setting the scale. However, for some geom-based renderables,
// the size scale is not applied uniformly (e.g. the spherical ends of a // the size scale is not applied uniformly (e.g. the spherical ends of a
// capsule are scaled such that they always remain spherical). // capsule are scaled such that they always remain spherical).
void mjrf_setRenderableSize(mjrRenderable* renderable, const float size[3]); void mjrf_setRenderableSize(mjrfRenderable* renderable, const float size[3]);
// ## Render Targets (mjrRenderTarget) // ## Render Targets (mjrfRenderTarget)
// //
// A render target is a memory buffer that holds the results of a rendering // A render target is a memory buffer that holds the results of a rendering
// operation. (This is an alternative to rendering directly to the screen.) // operation. (This is an alternative to rendering directly to the screen.)
@@ -753,20 +759,20 @@ struct mjrRenderTargetConfig {
}; };
// Initializes the RenderTargetConfig to default values. // Initializes the RenderTargetConfig to default values.
void mjr_defaultRenderTargetConfig(mjrRenderTargetConfig* config); void mjrf_defaultRenderTargetConfig(mjrRenderTargetConfig* config);
// Creates a render target for the filament renderer. // Creates a render target for the filament renderer.
mjrRenderTarget* mjrf_createRenderTarget(mjrfContext* ctx, mjrfRenderTarget* mjrf_createRenderTarget(mjrfContext* ctx,
const mjrRenderTargetConfig* config); const mjrRenderTargetConfig* config);
// Destroys the render target. // Destroys the render target.
void mjrf_destroyRenderTarget(mjrRenderTarget* render_target); void mjrf_destroyRenderTarget(mjrfRenderTarget* render_target);
// ## Debug-only functions. // ## Debug-only functions.
// Draws an ImGui editor for the given scene, exposing filament-specific // Draws an ImGui editor for the given scene, exposing filament-specific
// settings. // settings.
void mjrf_DEBUG_drawImguiEditor(mjrScene* scene); void mjrf_DEBUG_drawImguiEditor(mjrfScene* scene);
#if defined(__cplusplus) #if defined(__cplusplus)
} // extern "C" } // extern "C"
@@ -31,40 +31,40 @@ inline UniquePtr<mjrfContext> CreateContext(const mjrFilamentConfig& config) {
return UniquePtr<mjrfContext>(context, mjrf_destroyContext); return UniquePtr<mjrfContext>(context, mjrf_destroyContext);
} }
inline UniquePtr<mjrTexture> CreateTexture(mjrfContext* ctx, inline UniquePtr<mjrfTexture> CreateTexture(mjrfContext* ctx,
const mjrTextureConfig& config) { const mjrfTextureConfig& config) {
mjrTexture* texture = mjrf_createTexture(ctx, &config); mjrfTexture* texture = mjrf_createTexture(ctx, &config);
return UniquePtr<mjrTexture>(texture, mjrf_destroyTexture); return UniquePtr<mjrfTexture>(texture, mjrf_destroyTexture);
} }
inline UniquePtr<mjrMesh> CreateMesh(mjrfContext* ctx, inline UniquePtr<mjrfMesh> CreateMesh(mjrfContext* ctx,
const mjrMeshData& data) { const mjrfMeshData& data) {
mjrMesh* mesh = mjrf_createMesh(ctx, &data); mjrfMesh* mesh = mjrf_createMesh(ctx, &data);
return UniquePtr<mjrMesh>(mesh, mjrf_destroyMesh); return UniquePtr<mjrfMesh>(mesh, mjrf_destroyMesh);
} }
inline UniquePtr<mjrScene> CreateScene(mjrfContext* ctx, inline UniquePtr<mjrfScene> CreateScene(mjrfContext* ctx,
const mjrSceneParams& params) { const mjrfSceneParams& params) {
mjrScene* scene = mjrf_createScene(ctx, &params); mjrfScene* scene = mjrf_createScene(ctx, &params);
return UniquePtr<mjrScene>(scene, mjrf_destroyScene); return UniquePtr<mjrfScene>(scene, mjrf_destroyScene);
} }
inline UniquePtr<mjrLight> CreateLight(mjrfContext* ctx, inline UniquePtr<mjrfLight> CreateLight(mjrfContext* ctx,
const mjrLightParams& params) { const mjrfLightParams& params) {
mjrLight* light = mjrf_createLight(ctx, &params); mjrfLight* light = mjrf_createLight(ctx, &params);
return UniquePtr<mjrLight>(light, mjrf_destroyLight); return UniquePtr<mjrfLight>(light, mjrf_destroyLight);
} }
inline UniquePtr<mjrRenderable> CreateRenderable( inline UniquePtr<mjrfRenderable> CreateRenderable(
mjrfContext* ctx, const mjrRenderableParams& params) { mjrfContext* ctx, const mjrfRenderableParams& params) {
mjrRenderable* renderable = mjrf_createRenderable(ctx, &params); mjrfRenderable* renderable = mjrf_createRenderable(ctx, &params);
return UniquePtr<mjrRenderable>(renderable, mjrf_destroyRenderable); return UniquePtr<mjrfRenderable>(renderable, mjrf_destroyRenderable);
} }
inline UniquePtr<mjrRenderTarget> CreateRenderTarget( inline UniquePtr<mjrfRenderTarget> CreateRenderTarget(
mjrfContext* ctx, const mjrRenderTargetConfig& config) { mjrfContext* ctx, const mjrRenderTargetConfig& config) {
mjrRenderTarget* render_target = mjrf_createRenderTarget(ctx, &config); mjrfRenderTarget* render_target = mjrf_createRenderTarget(ctx, &config);
return UniquePtr<mjrRenderTarget>(render_target, mjrf_destroyRenderTarget); return UniquePtr<mjrfRenderTarget>(render_target, mjrf_destroyRenderTarget);
} }
std::string ResolveFilamentAssetPath(const std::string& filename); std::string ResolveFilamentAssetPath(const std::string& filename);
+12 -12
View File
@@ -239,9 +239,9 @@ void Renderer::DoRender(int width, int height) {
draw_mode = mjDRAW_MODE_WIREFRAME; draw_mode = mjDRAW_MODE_WIREFRAME;
} }
mjrRenderRequest reqs[2]; mjrfRenderRequest reqs[2];
mjr_defaultRenderRequest(&reqs[0]); mjrf_defaultRenderRequest(&reqs[0]);
reqs[0].scene = scene_bridge_->GetScene(); reqs[0].scene = scene_bridge_->GetScene();
reqs[0].draw_mode = draw_mode; reqs[0].draw_mode = draw_mode;
reqs[0].camera = scene_bridge_->GetCamera(); reqs[0].camera = scene_bridge_->GetCamera();
@@ -249,7 +249,7 @@ void Renderer::DoRender(int width, int height) {
reqs[0].enable_shadows = scene_.flags[mjRND_SHADOW]; reqs[0].enable_shadows = scene_.flags[mjRND_SHADOW];
reqs[0].enable_reflections = scene_.flags[mjRND_REFLECTION]; reqs[0].enable_reflections = scene_.flags[mjRND_REFLECTION];
mjr_defaultRenderRequest(&reqs[1]); mjrf_defaultRenderRequest(&reqs[1]);
reqs[1].scene = imgui_bridge_->GetScene(); reqs[1].scene = imgui_bridge_->GetScene();
reqs[1].draw_mode = mjDRAW_MODE_DEFAULT; reqs[1].draw_mode = mjDRAW_MODE_DEFAULT;
reqs[1].camera = imgui_bridge_->GetCamera(viewport.width, viewport.height); reqs[1].camera = imgui_bridge_->GetCamera(viewport.width, viewport.height);
@@ -299,15 +299,15 @@ void Renderer::DoReadPixels(int width, int height, unsigned char* rgb) {
} }
mjrRenderTargetConfig config; mjrRenderTargetConfig config;
mjr_defaultRenderTargetConfig(&config); mjrf_defaultRenderTargetConfig(&config);
config.width = viewport.width; config.width = viewport.width;
config.height = viewport.height; config.height = viewport.height;
config.color_format = mjPIXEL_FORMAT_RGB8; config.color_format = mjPIXEL_FORMAT_RGB8;
config.depth_format = mjPIXEL_FORMAT_DEPTH32F; config.depth_format = mjPIXEL_FORMAT_DEPTH32F;
auto target = CreateRenderTarget(filament_context_.get(), config); auto target = CreateRenderTarget(filament_context_.get(), config);
mjrRenderRequest reqs[2]; mjrfRenderRequest reqs[2];
mjr_defaultRenderRequest(&reqs[0]); mjrf_defaultRenderRequest(&reqs[0]);
reqs[0].scene = scene_bridge_->GetScene(); reqs[0].scene = scene_bridge_->GetScene();
reqs[0].draw_mode = draw_mode; reqs[0].draw_mode = draw_mode;
reqs[0].camera = scene_bridge_->GetCamera(); reqs[0].camera = scene_bridge_->GetCamera();
@@ -316,7 +316,7 @@ void Renderer::DoReadPixels(int width, int height, unsigned char* rgb) {
reqs[0].enable_shadows = scene_.flags[mjRND_SHADOW]; reqs[0].enable_shadows = scene_.flags[mjRND_SHADOW];
reqs[0].enable_reflections = scene_.flags[mjRND_REFLECTION]; reqs[0].enable_reflections = scene_.flags[mjRND_REFLECTION];
mjr_defaultRenderRequest(&reqs[1]); mjrf_defaultRenderRequest(&reqs[1]);
reqs[1].scene = imgui_bridge_->GetScene(); reqs[1].scene = imgui_bridge_->GetScene();
reqs[1].draw_mode = mjDRAW_MODE_DEFAULT; reqs[1].draw_mode = mjDRAW_MODE_DEFAULT;
reqs[1].camera = imgui_bridge_->GetCamera(viewport.width, viewport.height); reqs[1].camera = imgui_bridge_->GetCamera(viewport.width, viewport.height);
@@ -326,14 +326,14 @@ void Renderer::DoReadPixels(int width, int height, unsigned char* rgb) {
reqs[1].enable_reflections = false; reqs[1].enable_reflections = false;
reqs[1].enable_post_processing = false; reqs[1].enable_post_processing = false;
mjrReadPixelsRequest read_request; mjrfReadPixelsRequest read_request;
mjr_defaultReadPixelsRequest(&read_request); mjrf_defaultReadPixelsRequest(&read_request);
read_request.target = target.get(); read_request.target = target.get();
read_request.output = rgb; read_request.output = rgb;
read_request.num_bytes = viewport.width * viewport.height * 3; read_request.num_bytes = viewport.width * viewport.height * 3;
const int num_requests = (framebuffer_mode_ == 2) ? 2 : 1; const int num_requests = (framebuffer_mode_ == 2) ? 2 : 1;
const mjrFrameHandle frame = mjrf_render( const mjrfFrameHandle frame = mjrf_render(
filament_context_.get(), &reqs[0], num_requests, &read_request, 1); filament_context_.get(), &reqs[0], num_requests, &read_request, 1);
mjrf_waitForFrame(filament_context_.get(), frame); mjrf_waitForFrame(filament_context_.get(), frame);
} }
@@ -354,8 +354,8 @@ void Renderer::UpdateFps() {
frames_ = 0; frames_ = 0;
} }
} else { } else {
mjrFrameStats stats; mjrfFrameStats stats;
mjr_defaultFrameStats(&stats); mjrf_defaultFrameStats(&stats);
mjrf_getFrameStats(filament_context_.get(), 0, &stats); mjrf_getFrameStats(filament_context_.get(), 0, &stats);
fps_ = stats.frame_rate; fps_ = stats.frame_rate;
} }
+22 -22
View File
@@ -34,8 +34,8 @@ using filament::math::float3;
using filament::math::mat3f; using filament::math::mat3f;
ImguiBridge::ImguiBridge(mjrfContext* ctx) : ctx_(ctx) { ImguiBridge::ImguiBridge(mjrfContext* ctx) : ctx_(ctx) {
mjrSceneParams params; mjrfSceneParams params;
mjr_defaultSceneParams(&params); mjrf_defaultSceneParams(&params);
scene_ = CreateScene(ctx_, params); scene_ = CreateScene(ctx_, params);
} }
@@ -71,20 +71,20 @@ uintptr_t ImguiBridge::UploadImage(uintptr_t tex_id, const uint8_t* pixels,
tex_id = next_tex_id_++; tex_id = next_tex_id_++;
} }
mjrTexture* texture = GetTexture(tex_id); mjrfTexture* texture = GetTexture(tex_id);
// If the texture does not exist or the dimensions have changed, we create a // If the texture does not exist or the dimensions have changed, we create a
// new texture. // new texture.
if (texture == nullptr || mjrf_getTextureWidth(texture) != width || if (texture == nullptr || mjrf_getTextureWidth(texture) != width ||
mjrf_getTextureHeight(texture) != height) { mjrf_getTextureHeight(texture) != height) {
mjrTextureConfig config; mjrfTextureConfig config;
mjr_defaultTextureConfig(&config); mjrf_defaultTextureConfig(&config);
config.width = width; config.width = width;
config.height = height; config.height = height;
config.sampler_type = mjTEXTURE_2D; config.sampler_type = mjTEXTURE_2D;
config.format = bpp == 4 ? mjPIXEL_FORMAT_RGBA8 : mjPIXEL_FORMAT_RGB8; config.format = bpp == 4 ? mjPIXEL_FORMAT_RGBA8 : mjPIXEL_FORMAT_RGB8;
config.color_space = mjCOLORSPACE_LINEAR; config.color_space = mjCOLORSPACE_LINEAR;
UniquePtr<mjrTexture> new_texture = ::mujoco::CreateTexture(ctx_, config); UniquePtr<mjrfTexture> new_texture = ::mujoco::CreateTexture(ctx_, config);
texture = new_texture.get(); texture = new_texture.get();
textures_.insert_or_assign(tex_id, std::move(new_texture)); textures_.insert_or_assign(tex_id, std::move(new_texture));
} }
@@ -96,8 +96,8 @@ uintptr_t ImguiBridge::UploadImage(uintptr_t tex_id, const uint8_t* pixels,
const auto callback = const auto callback =
+[](void* user) { delete[] reinterpret_cast<std::byte*>(user); }; +[](void* user) { delete[] reinterpret_cast<std::byte*>(user); };
mjrTextureData texture_data; mjrfTextureData texture_data;
mjr_defaultTextureData(&texture_data); mjrf_defaultTextureData(&texture_data);
texture_data.bytes = bytes; texture_data.bytes = bytes;
texture_data.nbytes = num_bytes; texture_data.nbytes = num_bytes;
texture_data.user_data = bytes; texture_data.user_data = bytes;
@@ -113,8 +113,8 @@ void ImguiBridge::CreateTexture(ImTextureData* data) {
mju_error("Unsupported texture format."); mju_error("Unsupported texture format.");
} }
mjrTextureConfig config; mjrfTextureConfig config;
mjr_defaultTextureConfig(&config); mjrf_defaultTextureConfig(&config);
config.width = data->Width; config.width = data->Width;
config.height = data->Height; config.height = data->Height;
config.sampler_type = mjTEXTURE_2D; config.sampler_type = mjTEXTURE_2D;
@@ -133,8 +133,8 @@ void ImguiBridge::UpdateTexture(ImTextureData* data) {
mju_error("Texture not found: %llu", data->TexID); mju_error("Texture not found: %llu", data->TexID);
} }
mjrTextureData texture_data; mjrfTextureData texture_data;
mjr_defaultTextureData(&texture_data); mjrf_defaultTextureData(&texture_data);
texture_data.bytes = data->GetPixels(); texture_data.bytes = data->GetPixels();
texture_data.nbytes = data->Width * data->Height * 4; texture_data.nbytes = data->Width * data->Height * 4;
texture_data.user_data = nullptr; texture_data.user_data = nullptr;
@@ -152,7 +152,7 @@ void ImguiBridge::DestroyTexture(ImTextureData* data) {
} }
} }
mjrTexture* ImguiBridge::GetTexture(uintptr_t tex_id) const { mjrfTexture* ImguiBridge::GetTexture(uintptr_t tex_id) const {
auto iter = textures_.find(tex_id); auto iter = textures_.find(tex_id);
if (iter == textures_.end()) { if (iter == textures_.end()) {
return nullptr; return nullptr;
@@ -219,8 +219,8 @@ void ImguiBridge::Update() {
for (int n = 0; n < commands->CmdListsCount; ++n) { for (int n = 0; n < commands->CmdListsCount; ++n) {
const ImDrawList* cmds = commands->CmdLists[n]; const ImDrawList* cmds = commands->CmdLists[n];
mjrMeshData data; mjrfMeshData data;
mjr_defaultMeshData(&data); mjrf_defaultMeshData(&data);
data.nattributes = 3; data.nattributes = 3;
data.attributes[0].usage = mjVERTEX_ATTRIBUTE_USAGE_POSITION; data.attributes[0].usage = mjVERTEX_ATTRIBUTE_USAGE_POSITION;
data.attributes[0].type = mjVERTEX_ATTRIBUTE_TYPE_FLOAT2; data.attributes[0].type = mjVERTEX_ATTRIBUTE_TYPE_FLOAT2;
@@ -239,19 +239,19 @@ void ImguiBridge::Update() {
data.primitive_type = mjMESH_PRIMITIVE_TYPE_TRIANGLES; data.primitive_type = mjMESH_PRIMITIVE_TYPE_TRIANGLES;
meshes_.push_back(CreateMesh(ctx_, data)); meshes_.push_back(CreateMesh(ctx_, data));
const mjrMesh* mesh = meshes_.back().get(); const mjrfMesh* mesh = meshes_.back().get();
int index_offset = 0; int index_offset = 0;
for (const ImDrawCmd& command : cmds->CmdBuffer) { for (const ImDrawCmd& command : cmds->CmdBuffer) {
const int width = size.x * scale.x; const int width = size.x * scale.x;
const int height = size.y * scale.y; const int height = size.y * scale.y;
UniquePtr<mjrRenderable>& renderable = renderables_[renderable_index]; UniquePtr<mjrfRenderable>& renderable = renderables_[renderable_index];
mjrf_setRenderableMesh(renderable.get(), mesh, index_offset, mjrf_setRenderableMesh(renderable.get(), mesh, index_offset,
command.ElemCount); command.ElemCount);
mjrMaterial material; mjrfMaterial material;
mjr_defaultMaterial(&material); mjrf_defaultMaterial(&material);
material.color_texture = GetTexture(command.GetTexID()); material.color_texture = GetTexture(command.GetTexID());
material.decor_ux = true; material.decor_ux = true;
@@ -281,8 +281,8 @@ void ImguiBridge::Update() {
void ImguiBridge::PrepareRenderables(int count) { void ImguiBridge::PrepareRenderables(int count) {
while (renderables_.size() < count) { while (renderables_.size() < count) {
mjrRenderableParams params; mjrfRenderableParams params;
mjr_defaultRenderableParams(&params); mjrf_defaultRenderableParams(&params);
params.cast_shadows = false; params.cast_shadows = false;
params.receive_shadows = false; params.receive_shadows = false;
params.blend_order = static_cast<std::uint16_t>(renderables_.size() + 1); params.blend_order = static_cast<std::uint16_t>(renderables_.size() + 1);
@@ -295,7 +295,7 @@ void ImguiBridge::PrepareRenderables(int count) {
} }
} }
mjrScene* ImguiBridge::GetScene() const { return scene_.get(); } mjrfScene* ImguiBridge::GetScene() const { return scene_.get(); }
mjrCamera ImguiBridge::GetCamera(int width, int height) const { mjrCamera ImguiBridge::GetCamera(int width, int height) const {
mjrCamera camera; mjrCamera camera;
+6 -6
View File
@@ -37,7 +37,7 @@ class ImguiBridge {
void Update(); void Update();
// Returns the managed UX scene. // Returns the managed UX scene.
mjrScene* GetScene() const; mjrfScene* GetScene() const;
mjrCamera GetCamera(int width, int height) const; mjrCamera GetCamera(int width, int height) const;
// Uploads texture to be used with ImGui's Image and ImageButton functions. // Uploads texture to be used with ImGui's Image and ImageButton functions.
@@ -55,13 +55,13 @@ class ImguiBridge {
void CreateTexture(ImTextureData* data); void CreateTexture(ImTextureData* data);
void UpdateTexture(ImTextureData* data); void UpdateTexture(ImTextureData* data);
void DestroyTexture(ImTextureData* data); void DestroyTexture(ImTextureData* data);
mjrTexture* GetTexture(uintptr_t tex_id) const; mjrfTexture* GetTexture(uintptr_t tex_id) const;
mjrfContext* ctx_ = nullptr; mjrfContext* ctx_ = nullptr;
UniquePtr<mjrScene> scene_{nullptr, nullptr}; UniquePtr<mjrfScene> scene_{nullptr, nullptr};
std::vector<UniquePtr<mjrRenderable>> renderables_; std::vector<UniquePtr<mjrfRenderable>> renderables_;
std::vector<UniquePtr<mjrMesh>> meshes_; std::vector<UniquePtr<mjrfMesh>> meshes_;
std::unordered_map<uintptr_t, UniquePtr<mjrTexture>> textures_; std::unordered_map<uintptr_t, UniquePtr<mjrfTexture>> textures_;
uintptr_t next_tex_id_ = 1; uintptr_t next_tex_id_ = 1;
}; };