Rename FilamentBuffers class to Mesh.
Update the Mesh class so that it manages the lifetime of the vertex and index buffers. PiperOrigin-RevId: 895794022 Change-Id: I5eda578b8b7ed7f918e792f6181ec724729b5215
This commit is contained in:
committed by
Copybara-Service
parent
6de35648d1
commit
28d8ddcbeb
@@ -18,6 +18,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <backend/BufferDescriptor.h>
|
#include <backend/BufferDescriptor.h>
|
||||||
@@ -30,15 +31,59 @@
|
|||||||
// Functions for creating filament vertex and index buffers.
|
// Functions for creating filament vertex and index buffers.
|
||||||
namespace mujoco {
|
namespace mujoco {
|
||||||
|
|
||||||
// Simple tuple-type of a IndexBuffer+VertexBuffer.
|
// Owns a Vertex and Index buffer representing a geometry mesh.
|
||||||
struct FilamentBuffers {
|
class Mesh {
|
||||||
filament::IndexBuffer* index_buffer = nullptr;
|
public:
|
||||||
filament::VertexBuffer* vertex_buffer = nullptr;
|
Mesh(filament::Engine* engine, filament::IndexBuffer* index_buffer,
|
||||||
std::optional<filament::Box> bounds = std::nullopt;
|
filament::VertexBuffer* vertex_buffer,
|
||||||
filament::RenderableManager::PrimitiveType type =
|
std::optional<filament::Box> bounds = std::nullopt,
|
||||||
|
filament::RenderableManager::PrimitiveType type =
|
||||||
|
filament::RenderableManager::PrimitiveType::TRIANGLES)
|
||||||
|
: engine_(engine),
|
||||||
|
index_buffer_(index_buffer),
|
||||||
|
vertex_buffer_(vertex_buffer),
|
||||||
|
type_(type),
|
||||||
|
bounds_(bounds) {}
|
||||||
|
|
||||||
|
~Mesh() {
|
||||||
|
if (index_buffer_) {
|
||||||
|
engine_->destroy(index_buffer_);
|
||||||
|
}
|
||||||
|
if (vertex_buffer_) {
|
||||||
|
engine_->destroy(vertex_buffer_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
filament::IndexBuffer* GetFilamentIndexBuffer() const {
|
||||||
|
return index_buffer_;
|
||||||
|
}
|
||||||
|
filament::VertexBuffer* GetFilamentVertexBuffer() const {
|
||||||
|
return vertex_buffer_;
|
||||||
|
}
|
||||||
|
filament::RenderableManager::PrimitiveType GetPrimitiveType() const {
|
||||||
|
return type_;
|
||||||
|
}
|
||||||
|
bool HasBounds() const {
|
||||||
|
return bounds_.has_value();
|
||||||
|
}
|
||||||
|
filament::Box GetBounds() const {
|
||||||
|
return bounds_.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh(const Mesh&) = delete;
|
||||||
|
Mesh& operator=(const Mesh&) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
filament::Engine* engine_ = nullptr;
|
||||||
|
filament::IndexBuffer* index_buffer_ = nullptr;
|
||||||
|
filament::VertexBuffer* vertex_buffer_ = nullptr;
|
||||||
|
filament::RenderableManager::PrimitiveType type_ =
|
||||||
filament::RenderableManager::PrimitiveType::TRIANGLES;
|
filament::RenderableManager::PrimitiveType::TRIANGLES;
|
||||||
|
std::optional<filament::Box> bounds_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using MeshPtr = std::unique_ptr<Mesh>;
|
||||||
|
|
||||||
// Function that fills in the given buffer with actual data.
|
// Function that fills in the given buffer with actual data.
|
||||||
using FillBufferFn = std::function<void(std::byte*, std::size_t)>;
|
using FillBufferFn = std::function<void(std::byte*, std::size_t)>;
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
#include <numbers>
|
#include <numbers>
|
||||||
|
|
||||||
#include <filament/Box.h>
|
#include <filament/Box.h>
|
||||||
@@ -422,8 +423,8 @@ class ConeBuilder {
|
|||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (int j = 0; j < num_slices_; ++j) {
|
for (int j = 0; j < num_slices_; ++j) {
|
||||||
const float angle1 = (j+0) * delta_angle;
|
const float angle1 = (j + 0) * delta_angle;
|
||||||
const float angle2 = (j+1) * delta_angle;
|
const float angle2 = (j + 1) * delta_angle;
|
||||||
|
|
||||||
ptr[idx++] = MakeVert(angle1, delta_radius);
|
ptr[idx++] = MakeVert(angle1, delta_radius);
|
||||||
ptr[idx++] = MakeVert(angle2, delta_radius);
|
ptr[idx++] = MakeVert(angle2, delta_radius);
|
||||||
@@ -436,12 +437,12 @@ class ConeBuilder {
|
|||||||
|
|
||||||
// the rest: use quads
|
// the rest: use quads
|
||||||
for (int i = 1; i < num_stacks_; ++i) {
|
for (int i = 1; i < num_stacks_; ++i) {
|
||||||
const float radius1 = delta_radius * (i+0);
|
const float radius1 = delta_radius * (i + 0);
|
||||||
const float radius2 = delta_radius * (i+1);
|
const float radius2 = delta_radius * (i + 1);
|
||||||
|
|
||||||
for (int j = 0; j < num_slices_; ++j) {
|
for (int j = 0; j < num_slices_; ++j) {
|
||||||
const float angle1 = (j+0) * delta_angle;
|
const float angle1 = (j + 0) * delta_angle;
|
||||||
const float angle2 = (j+1) * delta_angle;
|
const float angle2 = (j + 1) * delta_angle;
|
||||||
|
|
||||||
ptr[idx++] = MakeVert(angle1, radius2);
|
ptr[idx++] = MakeVert(angle1, radius2);
|
||||||
ptr[idx++] = MakeVert(angle2, radius2);
|
ptr[idx++] = MakeVert(angle2, radius2);
|
||||||
@@ -676,34 +677,34 @@ class DomeBuilder {
|
|||||||
(num_quads_body * kNumIndicesPerQuad);
|
(num_quads_body * kNumIndicesPerQuad);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateVertices(VertexType* ptr, size_t num) const {
|
void GenerateVertices(VertexType* ptr, size_t num) const {
|
||||||
const float lat_angle_delta =
|
const float lat_angle_delta =
|
||||||
0.5 * std::numbers::pi / static_cast<float>(num_stacks_);
|
0.5 * std::numbers::pi / static_cast<float>(num_stacks_);
|
||||||
const float lon_angle_delta =
|
const float lon_angle_delta =
|
||||||
2.0 * std::numbers::pi / static_cast<float>(num_slices_);
|
2.0 * std::numbers::pi / static_cast<float>(num_slices_);
|
||||||
|
|
||||||
// Add the pole.
|
// Add the pole.
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
ptr[idx++] = MakeVert(0, 0, 1);
|
ptr[idx++] = MakeVert(0, 0, 1);
|
||||||
|
|
||||||
// Vertices by latitude.
|
// Vertices by latitude.
|
||||||
for (int lat = 0; lat < num_stacks_; ++lat) {
|
for (int lat = 0; lat < num_stacks_; ++lat) {
|
||||||
// +1 because we handle the north pole (which would be at a lat angle of
|
// +1 because we handle the north pole (which would be at a lat angle of
|
||||||
// 0-degrees) explicitly.
|
// 0-degrees) explicitly.
|
||||||
const float lat_angle = static_cast<float>(lat + 1) * lat_angle_delta;
|
const float lat_angle = static_cast<float>(lat + 1) * lat_angle_delta;
|
||||||
const float cos_lat_angle = std::cos(lat_angle);
|
const float cos_lat_angle = std::cos(lat_angle);
|
||||||
const float sin_lat_angle = std::sin(lat_angle);
|
const float sin_lat_angle = std::sin(lat_angle);
|
||||||
const float z = cos_lat_angle;
|
const float z = cos_lat_angle;
|
||||||
|
|
||||||
for (int lon = 0; lon < num_slices_; ++lon) {
|
for (int lon = 0; lon < num_slices_; ++lon) {
|
||||||
const float lon_angle = static_cast<float>(lon) * lon_angle_delta;
|
const float lon_angle = static_cast<float>(lon) * lon_angle_delta;
|
||||||
const float cos_lon_angle = std::cos(lon_angle);
|
const float cos_lon_angle = std::cos(lon_angle);
|
||||||
const float sin_lon_angle = std::sin(lon_angle);
|
const float sin_lon_angle = std::sin(lon_angle);
|
||||||
|
|
||||||
const float x = sin_lat_angle * cos_lon_angle;
|
const float x = sin_lat_angle * cos_lon_angle;
|
||||||
const float y = sin_lat_angle * sin_lon_angle;
|
const float y = sin_lat_angle * sin_lon_angle;
|
||||||
ptr[idx++] = MakeVert(x, y, z);
|
ptr[idx++] = MakeVert(x, y, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,9 +757,8 @@ class DomeBuilder {
|
|||||||
int num_slices_;
|
int num_slices_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FilamentBuffers CreateFromBuilder(filament::Engine* engine, const T& builder) {
|
MeshPtr CreateFromBuilder(filament::Engine* engine, const T& builder) {
|
||||||
using VertexType = typename T::VertexType;
|
using VertexType = typename T::VertexType;
|
||||||
using IndexType = typename T::IndexType;
|
using IndexType = typename T::IndexType;
|
||||||
|
|
||||||
@@ -786,46 +786,47 @@ FilamentBuffers CreateFromBuilder(filament::Engine* engine, const T& builder) {
|
|||||||
|
|
||||||
auto vb = CreateVertexBuffer<VertexType>(engine, num_vertices, vertices);
|
auto vb = CreateVertexBuffer<VertexType>(engine, num_vertices, vertices);
|
||||||
auto ib = CreateIndexBuffer<IndexType>(engine, num_indices, indices);
|
auto ib = CreateIndexBuffer<IndexType>(engine, num_indices, indices);
|
||||||
return {ib, vb, builder.GetBounds(), T::kPrimitiveType};
|
return std::make_unique<Mesh>(engine, ib, vb, builder.GetBounds(),
|
||||||
|
T::kPrimitiveType);
|
||||||
}
|
}
|
||||||
|
|
||||||
FilamentBuffers CreateLine(filament::Engine* engine) {
|
MeshPtr CreateLine(filament::Engine* engine) {
|
||||||
return CreateFromBuilder(engine, LineBuilder());
|
return CreateFromBuilder(engine, LineBuilder());
|
||||||
}
|
}
|
||||||
|
|
||||||
FilamentBuffers CreatePlane(filament::Engine* engine, int nquad) {
|
MeshPtr CreatePlane(filament::Engine* engine, int nquad) {
|
||||||
return CreateFromBuilder(engine, PlaneBuilder(nquad));
|
return CreateFromBuilder(engine, PlaneBuilder(nquad));
|
||||||
}
|
}
|
||||||
|
|
||||||
FilamentBuffers CreateTriangle(filament::Engine* engine) {
|
MeshPtr CreateTriangle(filament::Engine* engine) {
|
||||||
return CreateFromBuilder(engine, TriangleBuilder());
|
return CreateFromBuilder(engine, TriangleBuilder());
|
||||||
}
|
}
|
||||||
|
|
||||||
FilamentBuffers CreateBox(filament::Engine* engine, int nquad) {
|
MeshPtr CreateBox(filament::Engine* engine, int nquad) {
|
||||||
return CreateFromBuilder(engine, BoxBuilder(nquad));
|
return CreateFromBuilder(engine, BoxBuilder(nquad));
|
||||||
}
|
}
|
||||||
|
|
||||||
FilamentBuffers CreateLineBox(filament::Engine* engine) {
|
MeshPtr CreateLineBox(filament::Engine* engine) {
|
||||||
return CreateFromBuilder(engine, LineBoxBuilder());
|
return CreateFromBuilder(engine, LineBoxBuilder());
|
||||||
}
|
}
|
||||||
|
|
||||||
FilamentBuffers CreateSphere(filament::Engine* engine, int nstack, int nslice) {
|
MeshPtr CreateSphere(filament::Engine* engine, int nstack, int nslice) {
|
||||||
return CreateFromBuilder(engine, SphereBuilder(nstack, nslice));
|
return CreateFromBuilder(engine, SphereBuilder(nstack, nslice));
|
||||||
}
|
}
|
||||||
|
|
||||||
FilamentBuffers CreateTube(filament::Engine* engine, int nstack, int nslice) {
|
MeshPtr CreateTube(filament::Engine* engine, int nstack, int nslice) {
|
||||||
return CreateFromBuilder(engine, TubeBuilder(nstack, nslice));
|
return CreateFromBuilder(engine, TubeBuilder(nstack, nslice));
|
||||||
}
|
}
|
||||||
|
|
||||||
FilamentBuffers CreateDisk(filament::Engine* engine, int nslice) {
|
MeshPtr CreateDisk(filament::Engine* engine, int nslice) {
|
||||||
return CreateFromBuilder(engine, DiskBuilder(nslice));
|
return CreateFromBuilder(engine, DiskBuilder(nslice));
|
||||||
}
|
}
|
||||||
|
|
||||||
FilamentBuffers CreateDome(filament::Engine* engine, int nstack, int nslice) {
|
MeshPtr CreateDome(filament::Engine* engine, int nstack, int nslice) {
|
||||||
return CreateFromBuilder(engine, DomeBuilder(nstack, nslice));
|
return CreateFromBuilder(engine, DomeBuilder(nstack, nslice));
|
||||||
}
|
}
|
||||||
|
|
||||||
FilamentBuffers CreateCone(filament::Engine* engine, int nstack, int nslice) {
|
MeshPtr CreateCone(filament::Engine* engine, int nstack, int nslice) {
|
||||||
return CreateFromBuilder(engine, ConeBuilder(nstack, nslice));
|
return CreateFromBuilder(engine, ConeBuilder(nstack, nslice));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,16 +21,16 @@
|
|||||||
// Generates buffers for built-in shapes.
|
// Generates buffers for built-in shapes.
|
||||||
namespace mujoco {
|
namespace mujoco {
|
||||||
|
|
||||||
FilamentBuffers CreateLine(filament::Engine* engine);
|
MeshPtr CreateLine(filament::Engine* engine);
|
||||||
FilamentBuffers CreatePlane(filament::Engine* engine, int nquad);
|
MeshPtr CreatePlane(filament::Engine* engine, int nquad);
|
||||||
FilamentBuffers CreateTriangle(filament::Engine* engine);
|
MeshPtr CreateTriangle(filament::Engine* engine);
|
||||||
FilamentBuffers CreateBox(filament::Engine* engine, int nquad);
|
MeshPtr CreateBox(filament::Engine* engine, int nquad);
|
||||||
FilamentBuffers CreateLineBox(filament::Engine* engine);
|
MeshPtr CreateLineBox(filament::Engine* engine);
|
||||||
FilamentBuffers CreateSphere(filament::Engine* engine, int nstack, int nslice);
|
MeshPtr CreateSphere(filament::Engine* engine, int nstack, int nslice);
|
||||||
FilamentBuffers CreateTube(filament::Engine* engine, int nstack, int nslice);
|
MeshPtr CreateTube(filament::Engine* engine, int nstack, int nslice);
|
||||||
FilamentBuffers CreateDisk(filament::Engine* engine, int nslice);
|
MeshPtr CreateDisk(filament::Engine* engine, int nslice);
|
||||||
FilamentBuffers CreateDome(filament::Engine* engine, int nstack, int nslice);
|
MeshPtr CreateDome(filament::Engine* engine, int nstack, int nslice);
|
||||||
FilamentBuffers CreateCone(filament::Engine* engine, int nstack, int nslice);
|
MeshPtr CreateCone(filament::Engine* engine, int nstack, int nslice);
|
||||||
|
|
||||||
} // namespace mujoco
|
} // namespace mujoco
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
#include <numbers>
|
#include <numbers>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -173,12 +174,12 @@ void Drawable::Update(const mjModel* model, const mjvScene* scene,
|
|||||||
if (geom.type == mjGEOM_FLEX || geom.type == mjGEOM_SKIN) {
|
if (geom.type == mjGEOM_FLEX || geom.type == mjGEOM_SKIN) {
|
||||||
// Flex geometry is updated every frame with new vertex data.
|
// Flex geometry is updated every frame with new vertex data.
|
||||||
filament::Engine* engine = renderables_.GetEngine();
|
filament::Engine* engine = renderables_.GetEngine();
|
||||||
FilamentBuffers buffers = CreateGeomBuffers(engine, model, scene, geom);
|
std::unique_ptr<Mesh> mesh = CreateGeomBuffers(engine, model, scene, geom);
|
||||||
|
|
||||||
if (renderables_.GetNumEntities() == 0) {
|
if (renderables_.GetNumEntities() == 0) {
|
||||||
renderables_.Append(std::move(buffers));
|
renderables_.Append(std::move(mesh));
|
||||||
} else {
|
} else {
|
||||||
renderables_.Update(0, std::move(buffers));
|
renderables_.Update(0, std::move(mesh));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,27 +193,27 @@ void Drawable::Update(const mjModel* model, const mjvScene* scene,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Drawable::AddMesh(int data_id) {
|
void Drawable::AddMesh(int data_id) {
|
||||||
const FilamentBuffers* buffers = model_objs_->GetMeshBuffer(data_id);
|
const Mesh* buffers = model_objs_->GetMeshBuffer(data_id);
|
||||||
if (buffers == nullptr) {
|
if (buffers == nullptr) {
|
||||||
mju_error("Unknown mesh %d", data_id);
|
mju_error("Unknown mesh %d", data_id);
|
||||||
}
|
}
|
||||||
renderables_.Append(*buffers);
|
renderables_.Append(buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Drawable::AddHeightField(int hfield_id) {
|
void Drawable::AddHeightField(int hfield_id) {
|
||||||
const FilamentBuffers* buffers = model_objs_->GetHeightFieldBuffer(hfield_id);
|
const Mesh* buffers = model_objs_->GetHeightFieldBuffer(hfield_id);
|
||||||
if (buffers == nullptr) {
|
if (buffers == nullptr) {
|
||||||
mju_error("Unknown height field %d", hfield_id);
|
mju_error("Unknown height field %d", hfield_id);
|
||||||
}
|
}
|
||||||
renderables_.Append(*buffers);
|
renderables_.Append(buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Drawable::AddShape(ModelObjects::ShapeType shape_type) {
|
void Drawable::AddShape(ModelObjects::ShapeType shape_type) {
|
||||||
const FilamentBuffers* buffers = model_objs_->GetShapeBuffer(shape_type);
|
const Mesh* buffers = model_objs_->GetShapeBuffer(shape_type);
|
||||||
if (buffers == nullptr) {
|
if (buffers == nullptr) {
|
||||||
mju_error("Unknown shape %d", shape_type);
|
mju_error("Unknown shape %d", shape_type);
|
||||||
}
|
}
|
||||||
renderables_.Append(*buffers);
|
renderables_.Append(buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Drawable::AddToScene(filament::Scene* scene) {
|
void Drawable::AddToScene(filament::Scene* scene) {
|
||||||
|
|||||||
@@ -18,8 +18,10 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <memory>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
|
||||||
|
#include <filament/Box.h>
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
#include <filament/IndexBuffer.h>
|
#include <filament/IndexBuffer.h>
|
||||||
#include <filament/VertexBuffer.h>
|
#include <filament/VertexBuffer.h>
|
||||||
@@ -162,9 +164,8 @@ static filament::IndexBuffer* BuildIndexBuffer(filament::Engine* engine,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FilamentBuffers CreateGeomBuffers(filament::Engine* engine,
|
MeshPtr CreateGeomBuffers(filament::Engine* engine, const mjModel* model,
|
||||||
const mjModel* model, const mjvScene* scene,
|
const mjvScene* scene, const mjvGeom& geom) {
|
||||||
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);
|
||||||
auto uvs = GetUvs(model, scene, geom);
|
auto uvs = GetUvs(model, scene, geom);
|
||||||
@@ -175,14 +176,13 @@ FilamentBuffers CreateGeomBuffers(filament::Engine* engine,
|
|||||||
num_indices = 3 * scene->flexfaceused[geom.objid];
|
num_indices = 3 * scene->flexfaceused[geom.objid];
|
||||||
}
|
}
|
||||||
|
|
||||||
FilamentBuffers buffers;
|
|
||||||
float3 vmin = {FLT_MAX, FLT_MAX, FLT_MAX};
|
float3 vmin = {FLT_MAX, FLT_MAX, FLT_MAX};
|
||||||
float3 vmax = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
|
float3 vmax = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
|
||||||
buffers.vertex_buffer =
|
auto vertex_buffer = BuildVertexBuffer(engine, positions, normals, uvs, &vmin, &vmax);
|
||||||
BuildVertexBuffer(engine, positions, normals, uvs, &vmin, &vmax);
|
auto index_buffer = BuildIndexBuffer(engine, indices, num_indices);
|
||||||
buffers.index_buffer = BuildIndexBuffer(engine, indices, num_indices);
|
filament::Box bounds;
|
||||||
buffers.bounds.emplace().set(vmin, vmax);
|
bounds.set(vmin, vmax);
|
||||||
return buffers;
|
return std::make_unique<Mesh>(engine, index_buffer, vertex_buffer, bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mujoco
|
} // namespace mujoco
|
||||||
|
|||||||
@@ -22,9 +22,8 @@
|
|||||||
namespace mujoco {
|
namespace mujoco {
|
||||||
|
|
||||||
// Populates the FilamentBuffers for a flex geometry.
|
// Populates the FilamentBuffers for a flex geometry.
|
||||||
FilamentBuffers CreateGeomBuffers(filament::Engine* engine,
|
MeshPtr CreateGeomBuffers(filament::Engine* engine, const mjModel* model,
|
||||||
const mjModel* model, const mjvScene* scene,
|
const mjvScene* scene, const mjvGeom& geom);
|
||||||
const mjvGeom& geom);
|
|
||||||
|
|
||||||
} // namespace mujoco
|
} // namespace mujoco
|
||||||
|
|
||||||
|
|||||||
@@ -62,10 +62,7 @@ GuiView::~GuiView() {
|
|||||||
}
|
}
|
||||||
auto& em = utils::EntityManager::get();
|
auto& em = utils::EntityManager::get();
|
||||||
em.destroy(renderable_);
|
em.destroy(renderable_);
|
||||||
for (auto& buffer : buffers_) {
|
meshes_.clear();
|
||||||
engine_->destroy(buffer.vertex_buffer);
|
|
||||||
engine_->destroy(buffer.index_buffer);
|
|
||||||
}
|
|
||||||
for (auto& instance : instances_) {
|
for (auto& instance : instances_) {
|
||||||
engine_->destroy(instance);
|
engine_->destroy(instance);
|
||||||
}
|
}
|
||||||
@@ -84,12 +81,7 @@ void GuiView::ResetRenderable() {
|
|||||||
em.destroy(renderable_);
|
em.destroy(renderable_);
|
||||||
renderable_ = utils::Entity();
|
renderable_ = utils::Entity();
|
||||||
}
|
}
|
||||||
|
meshes_.clear();
|
||||||
for (auto& buffer : buffers_) {
|
|
||||||
engine_->destroy(buffer.vertex_buffer);
|
|
||||||
engine_->destroy(buffer.index_buffer);
|
|
||||||
}
|
|
||||||
buffers_.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr_t GuiView::UploadImage(uintptr_t tex_id, const uint8_t* pixels,
|
uintptr_t GuiView::UploadImage(uintptr_t tex_id, const uint8_t* pixels,
|
||||||
@@ -275,12 +267,7 @@ void GuiView::UpdateRenderable() {
|
|||||||
builder.build(*engine_, renderable_);
|
builder.build(*engine_, renderable_);
|
||||||
scene_->addEntity(renderable_);
|
scene_->addEntity(renderable_);
|
||||||
}
|
}
|
||||||
|
meshes_.clear();
|
||||||
for (auto& buffer : buffers_) {
|
|
||||||
engine_->destroy(buffer.vertex_buffer);
|
|
||||||
engine_->destroy(buffer.index_buffer);
|
|
||||||
}
|
|
||||||
buffers_.clear();
|
|
||||||
|
|
||||||
auto ri = rm.getInstance(renderable_);
|
auto ri = rm.getInstance(renderable_);
|
||||||
|
|
||||||
@@ -299,10 +286,13 @@ void GuiView::UpdateRenderable() {
|
|||||||
}
|
}
|
||||||
std::memcpy(dst, cmds->IdxBuffer.Data, size);
|
std::memcpy(dst, cmds->IdxBuffer.Data, size);
|
||||||
};
|
};
|
||||||
buffers_.push_back(
|
filament::IndexBuffer* index_buffer =
|
||||||
{CreateIndexBuffer<uint16_t>(engine_, cmds->IdxBuffer.Size, ifill),
|
CreateIndexBuffer<uint16_t>(engine_, cmds->IdxBuffer.Size, ifill);
|
||||||
CreateVertexBuffer<GuiVertex>(engine_, cmds->VtxBuffer.Size, vfill)});
|
filament::VertexBuffer* vertex_buffer =
|
||||||
const mujoco::FilamentBuffers& buffer = buffers_.back();
|
CreateVertexBuffer<GuiVertex>(engine_, cmds->VtxBuffer.Size, vfill);
|
||||||
|
|
||||||
|
meshes_.push_back(std::make_unique<Mesh>(engine_, index_buffer, vertex_buffer));
|
||||||
|
const auto& mesh = meshes_.back();
|
||||||
|
|
||||||
int index_offset = 0;
|
int index_offset = 0;
|
||||||
for (const ImDrawCmd& command : cmds->CmdBuffer) {
|
for (const ImDrawCmd& command : cmds->CmdBuffer) {
|
||||||
@@ -327,8 +317,9 @@ void GuiView::UpdateRenderable() {
|
|||||||
rm.setMaterialInstanceAt(
|
rm.setMaterialInstanceAt(
|
||||||
ri, drawable_index,
|
ri, drawable_index,
|
||||||
GetMaterialInstance(drawable_index, clip_rect, command.GetTexID()));
|
GetMaterialInstance(drawable_index, clip_rect, command.GetTexID()));
|
||||||
rm.setGeometryAt(ri, drawable_index, kTriangles, buffer.vertex_buffer,
|
rm.setGeometryAt(
|
||||||
buffer.index_buffer, index_offset, command.ElemCount);
|
ri, drawable_index, kTriangles, mesh->GetFilamentVertexBuffer(),
|
||||||
|
mesh->GetFilamentIndexBuffer(), index_offset, command.ElemCount);
|
||||||
rm.setBlendOrderAt(ri, drawable_index, drawable_index);
|
rm.setBlendOrderAt(ri, drawable_index, drawable_index);
|
||||||
|
|
||||||
index_offset += command.ElemCount;
|
index_offset += command.ElemCount;
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class GuiView {
|
|||||||
filament::View* view_ = nullptr;
|
filament::View* view_ = nullptr;
|
||||||
filament::Material* material_ = nullptr;
|
filament::Material* material_ = nullptr;
|
||||||
utils::Entity renderable_;
|
utils::Entity renderable_;
|
||||||
std::vector<FilamentBuffers> buffers_;
|
std::vector<MeshPtr> meshes_;
|
||||||
std::vector<filament::MaterialInstance*> instances_;
|
std::vector<filament::MaterialInstance*> instances_;
|
||||||
std::unordered_map<uintptr_t, std::unique_ptr<Texture>> textures_;
|
std::unordered_map<uintptr_t, std::unique_ptr<Texture>> textures_;
|
||||||
int num_elements_ = 0;
|
int num_elements_ = 0;
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <filament/Box.h>
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
#include <filament/IndirectLight.h>
|
#include <filament/IndirectLight.h>
|
||||||
#include <filament/Material.h>
|
#include <filament/Material.h>
|
||||||
@@ -29,7 +30,6 @@
|
|||||||
#include "experimental/filament/filament/model_util.h"
|
#include "experimental/filament/filament/model_util.h"
|
||||||
#include "experimental/filament/filament/texture.h"
|
#include "experimental/filament/filament/texture.h"
|
||||||
|
|
||||||
|
|
||||||
namespace mujoco {
|
namespace mujoco {
|
||||||
|
|
||||||
ModelObjects::ModelObjects(const mjModel* model, filament::Engine* engine)
|
ModelObjects::ModelObjects(const mjModel* model, filament::Engine* engine)
|
||||||
@@ -73,14 +73,7 @@ ModelObjects::~ModelObjects() {
|
|||||||
for (auto& iter : indirect_lights_) {
|
for (auto& iter : indirect_lights_) {
|
||||||
engine_->destroy(iter);
|
engine_->destroy(iter);
|
||||||
}
|
}
|
||||||
for (auto& iter : meshes_) {
|
meshes_.clear();
|
||||||
engine_->destroy(iter.second.vertex_buffer);
|
|
||||||
engine_->destroy(iter.second.index_buffer);
|
|
||||||
}
|
|
||||||
for (auto& iter : shapes_) {
|
|
||||||
engine_->destroy(iter.vertex_buffer);
|
|
||||||
engine_->destroy(iter.index_buffer);
|
|
||||||
}
|
|
||||||
textures_.clear();
|
textures_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,32 +81,25 @@ void ModelObjects::UploadMesh(const mjModel* model, int id) {
|
|||||||
if (model != model_) {
|
if (model != model_) {
|
||||||
mju_error("Model mismatch.");
|
mju_error("Model mismatch.");
|
||||||
}
|
}
|
||||||
if (id < 0 || id >= model->nmesh) {
|
if (id < 0 || id >= model->nmesh) {
|
||||||
mju_error("Invalid mesh index %d", id);
|
mju_error("Invalid mesh index %d", id);
|
||||||
}
|
}
|
||||||
|
meshes_.erase(id);
|
||||||
|
convex_hulls_.erase(id);
|
||||||
|
|
||||||
if (auto iter = meshes_.find(id); iter != meshes_.end()) {
|
filament::Box bounds;
|
||||||
engine_->destroy(iter->second.vertex_buffer);
|
auto vertex_buffer =
|
||||||
engine_->destroy(iter->second.index_buffer);
|
CreateVertexBuffer(engine_, model, id, MeshType::kNormal, &bounds);
|
||||||
}
|
auto index_buffer = CreateIndexBuffer(engine_, model, id, MeshType::kNormal);
|
||||||
if (auto iter = convex_hulls_.find(id); iter != convex_hulls_.end()) {
|
meshes_[id] =
|
||||||
engine_->destroy(iter->second.vertex_buffer);
|
std::make_unique<Mesh>(engine_, index_buffer, vertex_buffer, bounds);
|
||||||
engine_->destroy(iter->second.index_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
FilamentBuffers& buffers = meshes_[id];
|
|
||||||
buffers.vertex_buffer = CreateVertexBuffer(
|
|
||||||
engine_, model, id, MeshType::kNormal, &buffers.bounds.emplace());
|
|
||||||
buffers.index_buffer =
|
|
||||||
CreateIndexBuffer(engine_, model, id, MeshType::kNormal);
|
|
||||||
|
|
||||||
if (model->mesh_graphadr[id] >= 0) {
|
if (model->mesh_graphadr[id] >= 0) {
|
||||||
FilamentBuffers& hull_buffers = convex_hulls_[id];
|
vertex_buffer =
|
||||||
hull_buffers.vertex_buffer =
|
CreateVertexBuffer(engine_, model, id, MeshType::kConvexHull, &bounds);
|
||||||
CreateVertexBuffer(engine_, model, id, MeshType::kConvexHull,
|
index_buffer = CreateIndexBuffer(engine_, model, id, MeshType::kConvexHull);
|
||||||
&hull_buffers.bounds.emplace());
|
convex_hulls_[id] =
|
||||||
hull_buffers.index_buffer =
|
std::make_unique<Mesh>(engine_, index_buffer, vertex_buffer, bounds);
|
||||||
CreateIndexBuffer(engine_, model, id, MeshType::kConvexHull);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,43 +158,41 @@ void ModelObjects::UploadHeightField(const mjModel* model, int id) {
|
|||||||
mju_error("Invalid height field index %d", id);
|
mju_error("Invalid height field index %d", id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto iter = height_fields_.find(id); iter != height_fields_.end()) {
|
height_fields_.erase(id);
|
||||||
engine_->destroy(iter->second.vertex_buffer);
|
|
||||||
engine_->destroy(iter->second.index_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
FilamentBuffers& buffers = height_fields_[id];
|
filament::Box bounds;
|
||||||
buffers.vertex_buffer = CreateVertexBuffer(
|
auto vertex_buffer =
|
||||||
engine_, model, id, MeshType::kHeightField, &buffers.bounds.emplace());
|
CreateVertexBuffer(engine_, model, id, MeshType::kHeightField, &bounds);
|
||||||
buffers.index_buffer =
|
auto index_buffer =
|
||||||
CreateIndexBuffer(engine_, model, id, MeshType::kHeightField);
|
CreateIndexBuffer(engine_, model, id, MeshType::kHeightField);
|
||||||
|
height_fields_[id] =
|
||||||
|
std::make_unique<Mesh>(engine_, index_buffer, vertex_buffer, bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilamentBuffers* ModelObjects::GetMeshBuffer(int data_id) const {
|
const Mesh* ModelObjects::GetMeshBuffer(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
|
||||||
const int mesh_id = data_id / 2;
|
const int mesh_id = data_id / 2;
|
||||||
if (data_id % 2 == 0) {
|
if (data_id % 2 == 0) {
|
||||||
auto it = meshes_.find(mesh_id);
|
auto it = meshes_.find(mesh_id);
|
||||||
return it != meshes_.end() ? &it->second : nullptr;
|
return it != meshes_.end() ? it->second.get() : nullptr;
|
||||||
} else {
|
} else {
|
||||||
auto it = convex_hulls_.find(mesh_id);
|
auto it = convex_hulls_.find(mesh_id);
|
||||||
return it != convex_hulls_.end() ? &it->second : nullptr;
|
return it != convex_hulls_.end() ? it->second.get() : nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilamentBuffers* ModelObjects::GetHeightFieldBuffer(
|
const Mesh* ModelObjects::GetHeightFieldBuffer(int hfield_id) const {
|
||||||
int hfield_id) const {
|
|
||||||
auto it = height_fields_.find(hfield_id);
|
auto it = height_fields_.find(hfield_id);
|
||||||
return it != height_fields_.end() ? &it->second : nullptr;
|
return it != height_fields_.end() ? it->second.get() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FilamentBuffers* ModelObjects::GetShapeBuffer(ShapeType shape) const {
|
const Mesh* ModelObjects::GetShapeBuffer(ShapeType shape) const {
|
||||||
if (shape < 0 || shape >= kNumShapes) {
|
if (shape < 0 || shape >= kNumShapes) {
|
||||||
mju_error("Invalid shape type: %d", shape);
|
mju_error("Invalid shape type: %d", shape);
|
||||||
}
|
}
|
||||||
return &shapes_[shape];
|
return shapes_[shape].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Texture* ModelObjects::GetTexture(int tex_id) const {
|
const Texture* ModelObjects::GetTexture(int tex_id) const {
|
||||||
|
|||||||
@@ -61,9 +61,9 @@ class ModelObjects {
|
|||||||
filament::Engine* GetEngine() const { return engine_; }
|
filament::Engine* GetEngine() const { return engine_; }
|
||||||
|
|
||||||
// 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 FilamentBuffers* GetShapeBuffer(ShapeType shape) const;
|
const Mesh* GetShapeBuffer(ShapeType shape) const;
|
||||||
const FilamentBuffers* GetMeshBuffer(int data_id) const;
|
const Mesh* GetMeshBuffer(int data_id) const;
|
||||||
const FilamentBuffers* GetHeightFieldBuffer(int hfield_id) const;
|
const Mesh* GetHeightFieldBuffer(int hfield_id) const;
|
||||||
const Texture* GetTexture(int tex_id) const;
|
const Texture* GetTexture(int tex_id) const;
|
||||||
const Texture* GetTexture(int mat_id, int role) const;
|
const Texture* GetTexture(int mat_id, int role) const;
|
||||||
|
|
||||||
@@ -84,10 +84,10 @@ class ModelObjects {
|
|||||||
filament::Engine* engine_ = nullptr;
|
filament::Engine* engine_ = nullptr;
|
||||||
std::vector<filament::Skybox*> skyboxes_;
|
std::vector<filament::Skybox*> skyboxes_;
|
||||||
std::vector<filament::IndirectLight*> indirect_lights_;
|
std::vector<filament::IndirectLight*> indirect_lights_;
|
||||||
std::array<FilamentBuffers, kNumShapes> shapes_;
|
std::array<MeshPtr, kNumShapes> shapes_;
|
||||||
std::unordered_map<int, FilamentBuffers> meshes_;
|
std::unordered_map<int, MeshPtr> meshes_;
|
||||||
std::unordered_map<int, FilamentBuffers> convex_hulls_;
|
std::unordered_map<int, MeshPtr> convex_hulls_;
|
||||||
std::unordered_map<int, FilamentBuffers> height_fields_;
|
std::unordered_map<int, MeshPtr> height_fields_;
|
||||||
std::unordered_map<int, std::unique_ptr<Texture>> textures_;
|
std::unordered_map<int, std::unique_ptr<Texture>> textures_;
|
||||||
float specular_multiplier_ = 0.2f;
|
float specular_multiplier_ = 0.2f;
|
||||||
float shininess_multiplier_ = 0.1f;
|
float shininess_multiplier_ = 0.1f;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
#include "experimental/filament/filament/renderables.h"
|
#include "experimental/filament/filament/renderables.h"
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <optional>
|
#include <utility>
|
||||||
|
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
#include <filament/RenderableManager.h>
|
#include <filament/RenderableManager.h>
|
||||||
@@ -49,67 +49,65 @@ void Renderables::RemoveLast() {
|
|||||||
engine_->destroy(entity);
|
engine_->destroy(entity);
|
||||||
em.destroy(entity);
|
em.destroy(entity);
|
||||||
entities_.pop_back();
|
entities_.pop_back();
|
||||||
|
meshes_.pop_back();
|
||||||
if (owned_buffers_.back().owned) {
|
|
||||||
engine_->destroy(owned_buffers_.back().buffers.vertex_buffer);
|
|
||||||
engine_->destroy(owned_buffers_.back().buffers.index_buffer);
|
|
||||||
}
|
|
||||||
owned_buffers_.pop_back();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderables::Update(int index, const FilamentBuffers& buffers) {
|
void Renderables::Update(int index, const Mesh* mesh) {
|
||||||
if (index < 0 || index >= entities_.size()) {
|
if (index < 0 || index >= entities_.size()) {
|
||||||
mju_error("Invalid index %d for renderable.", index);
|
mju_error("Invalid index %d for renderable.", index);
|
||||||
}
|
}
|
||||||
utils::Entity& entity = entities_[index];
|
utils::Entity& entity = entities_[index];
|
||||||
UpdateEntity(entity, buffers);
|
UpdateEntity(entity, mesh);
|
||||||
UpdateBuffers(index, buffers, false);
|
UpdateMeshes(index, mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderables::Update(int index, FilamentBuffers&& buffers) {
|
void Renderables::Update(int index, MeshPtr mesh) {
|
||||||
if (index < 0 || index >= entities_.size()) {
|
if (index < 0 || index >= entities_.size()) {
|
||||||
mju_error("Invalid index %d for renderable.", index);
|
mju_error("Invalid index %d for renderable.", index);
|
||||||
}
|
}
|
||||||
utils::Entity& entity = entities_[index];
|
utils::Entity& entity = entities_[index];
|
||||||
UpdateEntity(entity, buffers);
|
UpdateEntity(entity, mesh.get());
|
||||||
UpdateBuffers(index, buffers, true);
|
UpdateMeshes(index, mesh.get(), std::move(mesh));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderables::Append(const FilamentBuffers& buffers) {
|
void Renderables::Append(const Mesh* mesh) {
|
||||||
utils::Entity entity = CreateEntity(buffers);
|
utils::Entity entity = CreateEntity(mesh);
|
||||||
entities_.push_back(entity);
|
entities_.push_back(entity);
|
||||||
owned_buffers_.push_back({.owned = false, .buffers = buffers});
|
meshes_.emplace_back(nullptr, mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderables::Append(FilamentBuffers&& buffers) {
|
void Renderables::Append(MeshPtr mesh) {
|
||||||
utils::Entity entity = CreateEntity(buffers);
|
utils::Entity entity = CreateEntity(mesh.get());
|
||||||
entities_.push_back(entity);
|
entities_.push_back(entity);
|
||||||
owned_buffers_.push_back({.owned = true, .buffers = buffers});
|
meshes_.emplace_back(std::move(mesh), mesh.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::Entity Renderables::CreateEntity(const FilamentBuffers& buffers) {
|
utils::Entity Renderables::CreateEntity(const Mesh* mesh) {
|
||||||
if (buffers.vertex_buffer == nullptr) {
|
filament::VertexBuffer* vertex_buffer = mesh->GetFilamentVertexBuffer();
|
||||||
|
if (vertex_buffer == nullptr) {
|
||||||
mju_error("Invalid (null) vertex buffer.");
|
mju_error("Invalid (null) vertex buffer.");
|
||||||
}
|
}
|
||||||
if (buffers.index_buffer == nullptr) {
|
|
||||||
|
filament::IndexBuffer* index_buffer = mesh->GetFilamentIndexBuffer();
|
||||||
|
if (index_buffer == nullptr) {
|
||||||
mju_error("Invalid (null) index buffer.");
|
mju_error("Invalid (null) index buffer.");
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::Entity entity = utils::EntityManager::get().create();
|
utils::Entity entity = utils::EntityManager::get().create();
|
||||||
if (entity.isNull()) {
|
if (entity.isNull()) {
|
||||||
mju_error("Failed to create entity.");
|
mju_error("Failed to create entity.");
|
||||||
}
|
}
|
||||||
|
|
||||||
filament::RenderableManager::Builder builder(1);
|
filament::RenderableManager::Builder builder(1);
|
||||||
builder.geometry(0, buffers.type, buffers.vertex_buffer,
|
builder.geometry(0, mesh->GetPrimitiveType(), vertex_buffer, index_buffer);
|
||||||
buffers.index_buffer);
|
if (mesh->HasBounds()) {
|
||||||
if (material_instance_) {
|
builder.boundingBox(mesh->GetBounds());
|
||||||
builder.material(0, material_instance_);
|
|
||||||
}
|
|
||||||
if (buffers.bounds.has_value()) {
|
|
||||||
builder.boundingBox(buffers.bounds.value());
|
|
||||||
} else {
|
} else {
|
||||||
builder.culling(false);
|
builder.culling(false);
|
||||||
}
|
}
|
||||||
|
if (material_instance_) {
|
||||||
|
builder.material(0, material_instance_);
|
||||||
|
}
|
||||||
builder.castShadows(cast_shadows_);
|
builder.castShadows(cast_shadows_);
|
||||||
builder.receiveShadows(receive_shadows_);
|
builder.receiveShadows(receive_shadows_);
|
||||||
builder.layerMask(0xff, layer_mask_);
|
builder.layerMask(0xff, layer_mask_);
|
||||||
@@ -123,30 +121,29 @@ utils::Entity Renderables::CreateEntity(const FilamentBuffers& buffers) {
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderables::UpdateEntity(utils::Entity entity,
|
void Renderables::UpdateEntity(utils::Entity entity, const Mesh* mesh) {
|
||||||
const FilamentBuffers& buffers) {
|
filament::VertexBuffer* vertex_buffer = mesh->GetFilamentVertexBuffer();
|
||||||
if (buffers.vertex_buffer == nullptr) {
|
if (vertex_buffer == nullptr) {
|
||||||
mju_error("Invalid (null) vertex buffer.");
|
mju_error("Invalid (null) vertex buffer.");
|
||||||
}
|
}
|
||||||
if (buffers.index_buffer == nullptr) {
|
|
||||||
|
filament::IndexBuffer* index_buffer = mesh->GetFilamentIndexBuffer();
|
||||||
|
if (index_buffer == nullptr) {
|
||||||
mju_error("Invalid (null) index buffer.");
|
mju_error("Invalid (null) index buffer.");
|
||||||
}
|
}
|
||||||
|
|
||||||
filament::RenderableManager& rm = engine_->getRenderableManager();
|
filament::RenderableManager& rm = engine_->getRenderableManager();
|
||||||
rm.setGeometryAt(rm.getInstance(entity), 0, buffers.type,
|
rm.setGeometryAt(rm.getInstance(entity), 0, mesh->GetPrimitiveType(),
|
||||||
buffers.vertex_buffer, buffers.index_buffer, 0,
|
vertex_buffer, index_buffer, 0,
|
||||||
buffers.index_buffer->getIndexCount());
|
index_buffer->getIndexCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderables::UpdateBuffers(int index, FilamentBuffers buffers, bool owned) {
|
void Renderables::UpdateMeshes(int index, const Mesh* mesh, MeshPtr owned_mesh) {
|
||||||
if (index < 0 || index >= owned_buffers_.size()) {
|
if (index < 0 || index >= meshes_.size()) {
|
||||||
mju_error("Invalid index %d for renderable.", index);
|
mju_error("Invalid index %d for renderable.", index);
|
||||||
}
|
}
|
||||||
if (owned_buffers_[index].owned) {
|
meshes_[index].owned_mesh = std::move(owned_mesh);
|
||||||
engine_->destroy(owned_buffers_[index].buffers.vertex_buffer);
|
meshes_[index].mesh = mesh;
|
||||||
engine_->destroy(owned_buffers_[index].buffers.index_buffer);
|
|
||||||
}
|
|
||||||
owned_buffers_[index].buffers = buffers;
|
|
||||||
owned_buffers_[index].owned = owned;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderables::AddToScene(filament::Scene* scene) {
|
void Renderables::AddToScene(filament::Scene* scene) {
|
||||||
@@ -239,11 +236,13 @@ void Renderables::SetWireframe(bool wireframe) {
|
|||||||
filament::RenderableManager& rm = engine_->getRenderableManager();
|
filament::RenderableManager& rm = engine_->getRenderableManager();
|
||||||
for (int i = 0; i < entities_.size(); ++i) {
|
for (int i = 0; i < entities_.size(); ++i) {
|
||||||
utils::Entity& entity = entities_[i];
|
utils::Entity& entity = entities_[i];
|
||||||
FilamentBuffers& buffers = owned_buffers_[i].buffers;
|
const Mesh* mesh = meshes_[i].mesh;
|
||||||
|
filament::VertexBuffer* vertex_buffer = mesh->GetFilamentVertexBuffer();
|
||||||
|
filament::IndexBuffer* index_buffer = mesh->GetFilamentIndexBuffer();
|
||||||
rm.setGeometryAt(rm.getInstance(entity), 0,
|
rm.setGeometryAt(rm.getInstance(entity), 0,
|
||||||
wireframe_ ? kWireframeType : buffers.type,
|
wireframe_ ? kWireframeType : mesh->GetPrimitiveType(),
|
||||||
buffers.vertex_buffer, buffers.index_buffer, 0,
|
vertex_buffer, index_buffer, 0,
|
||||||
buffers.index_buffer->getIndexCount());
|
index_buffer->getIndexCount());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_RENDERABLES_H_
|
#define MUJOCO_SRC_EXPERIMENTAL_FILAMENT_FILAMENT_RENDERABLES_H_
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <optional>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <filament/Engine.h>
|
#include <filament/Engine.h>
|
||||||
@@ -39,13 +38,13 @@ class Renderables {
|
|||||||
Renderables(const Renderables&) = delete;
|
Renderables(const Renderables&) = delete;
|
||||||
Renderables& operator=(const Renderables&) = delete;
|
Renderables& operator=(const Renderables&) = delete;
|
||||||
|
|
||||||
// Appends a new renderable entity built from the given buffers.
|
// Appends a new renderable entity built from the given mesh.
|
||||||
void Append(const FilamentBuffers& buffers);
|
void Append(const Mesh* mesh);
|
||||||
void Append(FilamentBuffers&& buffers);
|
void Append(MeshPtr mesh);
|
||||||
|
|
||||||
// Updates the entity at the index with new buffers.
|
// Updates the entity at the index with new mesh.
|
||||||
void Update(int index, const FilamentBuffers& buffers);
|
void Update(int index, const Mesh* mesh);
|
||||||
void Update(int index, FilamentBuffers&& buffers);
|
void Update(int index, MeshPtr mesh);
|
||||||
|
|
||||||
// Removes the last entity.
|
// Removes the last entity.
|
||||||
void RemoveLast();
|
void RemoveLast();
|
||||||
@@ -53,7 +52,7 @@ class Renderables {
|
|||||||
// Returns the entity at the given index.
|
// Returns the entity at the given index.
|
||||||
utils::Entity operator[](int index) { return entities_[index]; }
|
utils::Entity operator[](int index) { return entities_[index]; }
|
||||||
|
|
||||||
// Returns the owned buffers at the given index.
|
// Returns the number of Entities that make up this renderable.
|
||||||
int GetNumEntities() const { return entities_.size(); }
|
int GetNumEntities() const { return entities_.size(); }
|
||||||
|
|
||||||
// Hides all managed entities.
|
// Hides all managed entities.
|
||||||
@@ -84,22 +83,20 @@ class Renderables {
|
|||||||
filament::Engine* GetEngine() { return engine_; }
|
filament::Engine* GetEngine() { return engine_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
utils::Entity CreateEntity(const FilamentBuffers& buffers);
|
utils::Entity CreateEntity(const Mesh* mesh);
|
||||||
void UpdateEntity(utils::Entity entity, const FilamentBuffers& buffers);
|
void UpdateEntity(utils::Entity entity, const Mesh* mesh);
|
||||||
void UpdateBuffers(int index, FilamentBuffers buffers, bool owned);
|
void UpdateMeshes(int index, const Mesh* mesh, MeshPtr owned_mesh = nullptr);
|
||||||
|
|
||||||
// Tracks whether of not the filament buffers should be destroyed by this
|
struct MeshWrapper {
|
||||||
// class.
|
MeshPtr owned_mesh;
|
||||||
struct OwnedBuffers {
|
const Mesh* mesh = nullptr;
|
||||||
bool owned = false;
|
|
||||||
FilamentBuffers buffers;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
filament::Engine* engine_ = nullptr;
|
filament::Engine* engine_ = nullptr;
|
||||||
filament::Scene* assigned_scene_ = nullptr;
|
filament::Scene* assigned_scene_ = nullptr;
|
||||||
filament::MaterialInstance* material_instance_ = nullptr;
|
filament::MaterialInstance* material_instance_ = nullptr;
|
||||||
std::vector<utils::Entity> entities_;
|
std::vector<utils::Entity> entities_;
|
||||||
std::vector<OwnedBuffers> owned_buffers_;
|
std::vector<MeshWrapper> meshes_;
|
||||||
std::uint8_t priority_ = kDefaultPriority;
|
std::uint8_t priority_ = kDefaultPriority;
|
||||||
std::uint8_t layer_mask_ = kDefaultLayerMask;
|
std::uint8_t layer_mask_ = kDefaultLayerMask;
|
||||||
bool wireframe_ = false;
|
bool wireframe_ = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user