Add line and linebox geom primitives.
PiperOrigin-RevId: 818570050 Change-Id: If02873dd878a23b442368ce69bc024e0310e9d02
This commit is contained in:
committed by
Copybara-Service
parent
66a1c22cae
commit
9b7e7e471d
@@ -0,0 +1,29 @@
|
||||
// Copyright 2025 DeepMind Technologies Limited
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
material {
|
||||
name : unlit_segmentation,
|
||||
shadingModel : unlit,
|
||||
culling: none,
|
||||
parameters : [
|
||||
{ type : float4, name : BaseColorFactor }
|
||||
]
|
||||
}
|
||||
|
||||
fragment {
|
||||
void material(inout MaterialInputs material) {
|
||||
prepareMaterial(material);
|
||||
material.baseColor = materialParams.BaseColorFactor;
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <filament/Box.h>
|
||||
#include <filament/Engine.h>
|
||||
#include <filament/IndexBuffer.h>
|
||||
#include <filament/RenderableManager.h>
|
||||
#include <filament/VertexBuffer.h>
|
||||
|
||||
// Functions for creating filament vertex and index buffers.
|
||||
@@ -33,6 +34,8 @@ struct FilamentBuffers {
|
||||
filament::IndexBuffer* index_buffer = nullptr;
|
||||
filament::VertexBuffer* vertex_buffer = nullptr;
|
||||
filament::Box bounds = {{-1, -1, -1}, {1, 1, 1}};
|
||||
filament::RenderableManager::PrimitiveType type =
|
||||
filament::RenderableManager::PrimitiveType::TRIANGLES;
|
||||
};
|
||||
|
||||
// Function that fills in the given buffer with actual data.
|
||||
|
||||
@@ -58,10 +58,45 @@ std::size_t NumIndicesPerSide(int num_quads_per_axis) {
|
||||
return kNumIndicesPerQuad * num_quads_per_axis * num_quads_per_axis;
|
||||
}
|
||||
|
||||
class LineBuilder {
|
||||
public:
|
||||
using VertexType = VertexNoUv;
|
||||
using IndexType = uint16_t;
|
||||
static constexpr filament::RenderableManager::PrimitiveType kPrimitiveType =
|
||||
filament::RenderableManager::PrimitiveType::LINES;
|
||||
|
||||
explicit LineBuilder() {}
|
||||
|
||||
std::size_t NumVertices() const {
|
||||
return 2;
|
||||
}
|
||||
|
||||
std::size_t NumIndices() const {
|
||||
return 2;
|
||||
}
|
||||
|
||||
void GenerateVertices(VertexType* ptr, size_t num) const {
|
||||
constexpr float4 kOrientation = {0, 0, 0, 1}; // Unused for lines.
|
||||
ptr[0] = VertexType({0, 0, 0}, kOrientation);
|
||||
ptr[1] = VertexType({0, 0, 1}, kOrientation);
|
||||
}
|
||||
|
||||
void GenerateIndices(IndexType* ptr, size_t num) const {
|
||||
ptr[0] = 0;
|
||||
ptr[1] = 1;
|
||||
}
|
||||
|
||||
filament::Box GetBounds() const {
|
||||
return {{-0.001, -0.001, 0}, {0.001, 0.001, 1}};
|
||||
}
|
||||
};
|
||||
|
||||
class PlaneBuilder {
|
||||
public:
|
||||
using VertexType = VertexNoUv;
|
||||
using IndexType = uint16_t;
|
||||
static constexpr filament::RenderableManager::PrimitiveType kPrimitiveType =
|
||||
filament::RenderableManager::PrimitiveType::TRIANGLES;
|
||||
|
||||
explicit PlaneBuilder(int num_quads_per_axis)
|
||||
: num_quads_per_axis_(num_quads_per_axis),
|
||||
@@ -109,10 +144,74 @@ class PlaneBuilder {
|
||||
float4 orientation_;
|
||||
};
|
||||
|
||||
class LineBoxBuilder {
|
||||
public:
|
||||
using VertexType = VertexNoUv;
|
||||
using IndexType = uint16_t;
|
||||
static constexpr filament::RenderableManager::PrimitiveType kPrimitiveType =
|
||||
filament::RenderableManager::PrimitiveType::LINES;
|
||||
|
||||
explicit LineBoxBuilder() {}
|
||||
|
||||
std::size_t NumVertices() const {
|
||||
return 8;
|
||||
}
|
||||
|
||||
std::size_t NumIndices() const {
|
||||
return 24;
|
||||
}
|
||||
|
||||
void GenerateVertices(VertexType* ptr, size_t num) const {
|
||||
constexpr float4 kOrientation = {0, 0, 0, 1}; // Unused for lines.
|
||||
ptr[0] = VertexType({-1.0f, -1.0f, -1.0f}, kOrientation);
|
||||
ptr[1] = VertexType({ 1.0f, -1.0f, -1.0f}, kOrientation);
|
||||
ptr[2] = VertexType({-1.0f, 1.0f, -1.0f}, kOrientation);
|
||||
ptr[3] = VertexType({ 1.0f, 1.0f, -1.0f}, kOrientation);
|
||||
ptr[4] = VertexType({-1.0f, -1.0f, 1.0f}, kOrientation);
|
||||
ptr[5] = VertexType({ 1.0f, -1.0f, 1.0f}, kOrientation);
|
||||
ptr[6] = VertexType({-1.0f, 1.0f, 1.0f}, kOrientation);
|
||||
ptr[7] = VertexType({ 1.0f, 1.0f, 1.0f}, kOrientation);
|
||||
}
|
||||
|
||||
void GenerateIndices(IndexType* ptr, size_t num) const {
|
||||
// Bottom square (where z == -1).
|
||||
ptr[0] = 0;
|
||||
ptr[1] = 1;
|
||||
ptr[2] = 1;
|
||||
ptr[3] = 3;
|
||||
ptr[4] = 3;
|
||||
ptr[5] = 2;
|
||||
ptr[6] = 2;
|
||||
ptr[7] = 0;
|
||||
// Top square (where z == 1).
|
||||
ptr[8] = 4;
|
||||
ptr[9] = 5;
|
||||
ptr[10] = 5;
|
||||
ptr[11] = 7;
|
||||
ptr[12] = 7;
|
||||
ptr[13] = 6;
|
||||
ptr[14] = 6;
|
||||
ptr[15] = 4;
|
||||
// Connect edges from bottom to top.
|
||||
ptr[16] = 2;
|
||||
ptr[17] = 6;
|
||||
ptr[18] = 3;
|
||||
ptr[19] = 7;
|
||||
ptr[20] = 0;
|
||||
ptr[21] = 4;
|
||||
ptr[22] = 1;
|
||||
ptr[23] = 5;
|
||||
}
|
||||
|
||||
filament::Box GetBounds() const { return {{-1, -1, -1}, {1, 1, 1}}; }
|
||||
};
|
||||
|
||||
class BoxBuilder {
|
||||
public:
|
||||
using VertexType = VertexNoUv;
|
||||
using IndexType = uint16_t;
|
||||
static constexpr filament::RenderableManager::PrimitiveType kPrimitiveType =
|
||||
filament::RenderableManager::PrimitiveType::TRIANGLES;
|
||||
|
||||
static constexpr int kNumSides = 6;
|
||||
|
||||
@@ -196,6 +295,8 @@ class TubeBuilder {
|
||||
public:
|
||||
using VertexType = VertexNoUv;
|
||||
using IndexType = uint16_t;
|
||||
static constexpr filament::RenderableManager::PrimitiveType kPrimitiveType =
|
||||
filament::RenderableManager::PrimitiveType::TRIANGLES;
|
||||
|
||||
TubeBuilder(int num_stacks, int num_slices)
|
||||
: num_stacks_(num_stacks), num_slices_(num_slices) {}
|
||||
@@ -252,6 +353,8 @@ class ConeBuilder {
|
||||
public:
|
||||
using VertexType = VertexNoUv;
|
||||
using IndexType = uint16_t;
|
||||
static constexpr filament::RenderableManager::PrimitiveType kPrimitiveType =
|
||||
filament::RenderableManager::PrimitiveType::TRIANGLES;
|
||||
|
||||
ConeBuilder(int num_stacks, int num_slices)
|
||||
: num_stacks_(num_stacks), num_slices_(num_slices) {}
|
||||
@@ -341,6 +444,8 @@ class DiskBuilder {
|
||||
public:
|
||||
using VertexType = VertexNoUv;
|
||||
using IndexType = uint16_t;
|
||||
static constexpr filament::RenderableManager::PrimitiveType kPrimitiveType =
|
||||
filament::RenderableManager::PrimitiveType::TRIANGLES;
|
||||
|
||||
explicit DiskBuilder(int num_slices) : num_slices_(num_slices) {
|
||||
orientation_ = CalculateOrientation({0, 0, 1});
|
||||
@@ -388,6 +493,8 @@ class SphereBuilder {
|
||||
public:
|
||||
using VertexType = VertexNoUv;
|
||||
using IndexType = uint16_t;
|
||||
static constexpr filament::RenderableManager::PrimitiveType kPrimitiveType =
|
||||
filament::RenderableManager::PrimitiveType::TRIANGLES;
|
||||
|
||||
static constexpr IndexType kNorthPoleIndex = 0;
|
||||
static constexpr IndexType kSouthPoleIndex = 1;
|
||||
@@ -494,6 +601,8 @@ class DomeBuilder {
|
||||
public:
|
||||
using VertexType = VertexNoUv;
|
||||
using IndexType = uint16_t;
|
||||
static constexpr filament::RenderableManager::PrimitiveType kPrimitiveType =
|
||||
filament::RenderableManager::PrimitiveType::TRIANGLES;
|
||||
|
||||
static constexpr IndexType kPoleIndex = 0;
|
||||
|
||||
@@ -617,7 +726,11 @@ FilamentBuffers CreateFromBuilder(filament::Engine* engine, const T& builder) {
|
||||
|
||||
auto vb = CreateVertexBuffer<VertexType>(engine, num_vertices, vertices);
|
||||
auto ib = CreateIndexBuffer<IndexType>(engine, num_indices, indices);
|
||||
return {ib, vb, builder.GetBounds()};
|
||||
return {ib, vb, builder.GetBounds(), T::kPrimitiveType};
|
||||
}
|
||||
|
||||
FilamentBuffers CreateLine(filament::Engine* engine, const mjModel* model) {
|
||||
return CreateFromBuilder(engine, LineBuilder());
|
||||
}
|
||||
|
||||
FilamentBuffers CreatePlane(filament::Engine* engine, const mjModel* model) {
|
||||
@@ -630,6 +743,10 @@ FilamentBuffers CreateBox(filament::Engine* engine, const mjModel* model) {
|
||||
return CreateFromBuilder(engine, BoxBuilder(num_quads));
|
||||
}
|
||||
|
||||
FilamentBuffers CreateLineBox(filament::Engine* engine, const mjModel* model) {
|
||||
return CreateFromBuilder(engine, LineBoxBuilder());
|
||||
}
|
||||
|
||||
FilamentBuffers CreateSphere(filament::Engine* engine, const mjModel* model) {
|
||||
const int num_stacks = model->vis.quality.numstacks;
|
||||
const int num_slices = model->vis.quality.numslices;
|
||||
|
||||
@@ -22,7 +22,9 @@
|
||||
// Generates buffers for built-in shapes.
|
||||
namespace mujoco {
|
||||
|
||||
FilamentBuffers CreateLine(filament::Engine* engine, const mjModel* model);
|
||||
FilamentBuffers CreateBox(filament::Engine* engine, const mjModel* model);
|
||||
FilamentBuffers CreateLineBox(filament::Engine* engine, const mjModel* model);
|
||||
FilamentBuffers CreatePlane(filament::Engine* engine, const mjModel* model);
|
||||
FilamentBuffers CreateSphere(filament::Engine* engine, const mjModel* model);
|
||||
FilamentBuffers CreateTube(filament::Engine* engine, const mjModel* model);
|
||||
|
||||
@@ -106,6 +106,10 @@ Drawable::Drawable(ObjectManager* object_mgr, const mjvGeom& geom)
|
||||
AddShape(ObjectManager::kCone);
|
||||
AddShape(ObjectManager::kDisk);
|
||||
AddShape(ObjectManager::kDisk);
|
||||
} else if (geom.type == mjGEOM_LINE) {
|
||||
AddShape(ObjectManager::kLine);
|
||||
} else if (geom.type == mjGEOM_LINEBOX) {
|
||||
AddShape(ObjectManager::kLineBox);
|
||||
} else if (geom.type == mjGEOM_FLEX || geom.type == mjGEOM_SKIN) {
|
||||
// Flex and skin geometries are dynamically updated every frame.
|
||||
} else {
|
||||
@@ -298,53 +302,57 @@ void Drawable::UpdateMaterial(const mjvGeom& geom) {
|
||||
textures.occlusion = object_mgr->GetTexture(geom.matid, mjTEXROLE_OCCLUSION);
|
||||
}
|
||||
|
||||
if (geom.matid >= 0) {
|
||||
if (textures.orm) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPbrPacked);
|
||||
} else if (textures.metallic) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPbr);
|
||||
} else if (textures.roughness) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPbr);
|
||||
} else if (model->mat_metallic[geom.matid] >= 0) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPbr);
|
||||
} else if (model->mat_roughness[geom.matid] >= 0) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPbr);
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if we're dealing with a mesh with texture coordinates.
|
||||
// `data_id` is the id of the mesh in model (i.e. the geom has mesh geometry)
|
||||
// and `mesh_texcoordadr` stores the address of the mesh uvs if it has them.
|
||||
bool has_texcoords = false;
|
||||
if ((geom.type == mjGEOM_MESH || geom.type == mjGEOM_SDF) &&
|
||||
geom.dataid >= 0 && model->mesh_texcoordadr[geom.dataid / 2] >= 0) {
|
||||
has_texcoords = true;
|
||||
}
|
||||
|
||||
if (textures.color == nullptr) {
|
||||
if (geom.rgba[3] < 1.0f) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhongColorFade);
|
||||
} else {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhongColor);
|
||||
}
|
||||
} else if (textures.color->getTarget() ==
|
||||
filament::Texture::Sampler::SAMPLER_CUBEMAP) {
|
||||
if (geom.rgba[3] < 1.0f) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhongCubeFade);
|
||||
} else {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhongCube);
|
||||
}
|
||||
} else if (has_texcoords) {
|
||||
if (geom.rgba[3] < 1.0f) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhong2dUvFade);
|
||||
} else {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhong2dUv);
|
||||
}
|
||||
if (geom.type == mjGEOM_LINE || geom.type == mjGEOM_LINEBOX) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kUnlitLine);
|
||||
} else {
|
||||
if (geom.rgba[3] < 1.0f) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhong2dFade);
|
||||
if (geom.matid >= 0) {
|
||||
if (textures.orm) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPbrPacked);
|
||||
} else if (textures.metallic) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPbr);
|
||||
} else if (textures.roughness) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPbr);
|
||||
} else if (model->mat_metallic[geom.matid] >= 0) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPbr);
|
||||
} else if (model->mat_roughness[geom.matid] >= 0) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPbr);
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if we're dealing with a mesh with texture coordinates.
|
||||
// `data_id` is the id of the mesh in model (i.e. the geom has mesh geometry)
|
||||
// and `mesh_texcoordadr` stores the address of the mesh uvs if it has them.
|
||||
bool has_texcoords = false;
|
||||
if ((geom.type == mjGEOM_MESH || geom.type == mjGEOM_SDF) &&
|
||||
geom.dataid >= 0 && model->mesh_texcoordadr[geom.dataid / 2] >= 0) {
|
||||
has_texcoords = true;
|
||||
}
|
||||
|
||||
if (textures.color == nullptr) {
|
||||
if (geom.rgba[3] < 1.0f) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhongColorFade);
|
||||
} else {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhongColor);
|
||||
}
|
||||
} else if (textures.color->getTarget() ==
|
||||
filament::Texture::Sampler::SAMPLER_CUBEMAP) {
|
||||
if (geom.rgba[3] < 1.0f) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhongCubeFade);
|
||||
} else {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhongCube);
|
||||
}
|
||||
} else if (has_texcoords) {
|
||||
if (geom.rgba[3] < 1.0f) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhong2dUvFade);
|
||||
} else {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhong2dUv);
|
||||
}
|
||||
} else {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhong2d);
|
||||
if (geom.rgba[3] < 1.0f) {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhong2dFade);
|
||||
} else {
|
||||
material_.SetNormalMaterialType(ObjectManager::kPhong2d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,9 @@ struct Asset {
|
||||
ObjectManager::ObjectManager(const mjModel* model, filament::Engine* engine,
|
||||
const mjrFilamentConfig* config)
|
||||
: model_(model), engine_(engine), config_(config) {
|
||||
shapes_[kLine] = CreateLine(engine_, model_);
|
||||
shapes_[kBox] = CreateBox(engine_, model_);
|
||||
shapes_[kLineBox] = CreateLineBox(engine_, model_);
|
||||
shapes_[kCone] = CreateCone(engine_, model_);
|
||||
shapes_[kDisk] = CreateDisk(engine_, model_);
|
||||
shapes_[kDome] = CreateDome(engine_, model_);
|
||||
@@ -94,6 +96,7 @@ ObjectManager::ObjectManager(const mjModel* model, filament::Engine* engine,
|
||||
materials_[kPhongCube] = LoadMaterial("phong_cube.filamat");
|
||||
materials_[kPhongCubeFade] = LoadMaterial("phong_cube_fade.filamat");
|
||||
materials_[kUnlitSegmentation] = LoadMaterial("unlit_segmentation.filamat");
|
||||
materials_[kUnlitLine] = LoadMaterial("unlit_line.filamat");
|
||||
materials_[kUnlitDepth] = LoadMaterial("unlit_depth.filamat");
|
||||
materials_[kUnlitUi] = LoadMaterial("unlit_ui.filamat");
|
||||
|
||||
|
||||
@@ -51,11 +51,14 @@ class ObjectManager {
|
||||
kPhongCubeFade,
|
||||
kUnlitSegmentation,
|
||||
kUnlitDepth,
|
||||
kUnlitLine,
|
||||
kUnlitUi,
|
||||
kNumMaterials,
|
||||
};
|
||||
|
||||
enum ShapeType {
|
||||
kLine,
|
||||
kLineBox,
|
||||
kPlane,
|
||||
kBox,
|
||||
kSphere,
|
||||
|
||||
@@ -96,8 +96,8 @@ utils::Entity Renderables::CreateEntity(const FilamentBuffers& buffers) {
|
||||
}
|
||||
|
||||
filament::RenderableManager::Builder builder(1);
|
||||
builder.geometry(0, filament::RenderableManager::PrimitiveType::TRIANGLES,
|
||||
buffers.vertex_buffer, buffers.index_buffer);
|
||||
builder.geometry(0, buffers.type, buffers.vertex_buffer,
|
||||
buffers.index_buffer);
|
||||
if (material_instance_) {
|
||||
builder.material(0, material_instance_);
|
||||
}
|
||||
@@ -124,8 +124,7 @@ void Renderables::UpdateEntity(utils::Entity entity,
|
||||
mju_error("Invalid (null) index buffer.");
|
||||
}
|
||||
filament::RenderableManager& rm = engine_->getRenderableManager();
|
||||
rm.setGeometryAt(rm.getInstance(entity), 0,
|
||||
filament::RenderableManager::PrimitiveType::TRIANGLES,
|
||||
rm.setGeometryAt(rm.getInstance(entity), 0, buffers.type,
|
||||
buffers.vertex_buffer, buffers.index_buffer, 0,
|
||||
buffers.index_buffer->getIndexCount());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user