Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[Impeller Scene] Refactor Nodes/Meshes for simplicity and GLTF compatibility #38180

Merged
merged 3 commits into from
Dec 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1662,19 +1662,19 @@ FILE: ../../../flutter/impeller/scene/importer/vertices_builder.cc
FILE: ../../../flutter/impeller/scene/importer/vertices_builder.h
FILE: ../../../flutter/impeller/scene/material.cc
FILE: ../../../flutter/impeller/scene/material.h
FILE: ../../../flutter/impeller/scene/mesh.cc
FILE: ../../../flutter/impeller/scene/mesh.h
FILE: ../../../flutter/impeller/scene/node.cc
FILE: ../../../flutter/impeller/scene/node.h
FILE: ../../../flutter/impeller/scene/scene.cc
FILE: ../../../flutter/impeller/scene/scene.h
FILE: ../../../flutter/impeller/scene/scene_context.cc
FILE: ../../../flutter/impeller/scene/scene_context.h
FILE: ../../../flutter/impeller/scene/scene_encoder.cc
FILE: ../../../flutter/impeller/scene/scene_encoder.h
FILE: ../../../flutter/impeller/scene/scene_entity.cc
FILE: ../../../flutter/impeller/scene/scene_entity.h
FILE: ../../../flutter/impeller/scene/scene_unittests.cc
FILE: ../../../flutter/impeller/scene/shaders/geometry.vert
FILE: ../../../flutter/impeller/scene/shaders/unlit.frag
FILE: ../../../flutter/impeller/scene/static_mesh_entity.cc
FILE: ../../../flutter/impeller/scene/static_mesh_entity.h
FILE: ../../../flutter/impeller/tessellator/c/tessellator.cc
FILE: ../../../flutter/impeller/tessellator/c/tessellator.h
FILE: ../../../flutter/impeller/tessellator/dart/lib/tessellator.dart
Expand Down
8 changes: 4 additions & 4 deletions impeller/scene/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ impeller_component("scene") {
"geometry.h",
"material.cc",
"material.h",
"mesh.cc",
"mesh.h",
"node.cc",
"node.h",
"scene.cc",
"scene.h",
"scene_context.cc",
"scene_context.h",
"scene_encoder.cc",
"scene_encoder.h",
"scene_entity.cc",
"scene_entity.h",
"static_mesh_entity.cc",
"static_mesh_entity.h",
]

public_deps = [
Expand Down
52 changes: 25 additions & 27 deletions impeller/scene/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,54 +43,52 @@ run_action.SetLoop(impeller::scene::AnimationAction::kLoopForever);
run_action.SetWeight(0.3f);
run_action.Play();

scene.Add(
scene.GetRoot().AddChild(
impeller::scene::DirectionalLight(
/* color */ impeller::Color::AntiqueWhite(),
/* intensity */ 5,
/* direction */ {2, 3, 4}));

impeller::scene::StaticMeshEntity sphere_entity;
sphere_entity.SetGlobalTransform(
Node sphere_node;
Mesh sphere_mesh;
sphere_node.SetGlobalTransform(
Matrix::MakeRotationEuler({kPiOver4, kPiOver4, 0}));
sphere_entity.SetCullingMode(impeller::scene::CullingMode::kFrustum);

std::unique_ptr<impeller::scene::SphereGeometry> sphere =
auto sphere_geometry =
impeller::scene::Geometry::MakeSphere(allocator, /* radius */ 2);

sphere_entity.SetGeometry(sphere);

auto material = impeller::scene::Material::MakeStandard();
material.SetAlbedo(impeller::Color::Red());
material.SetRoughness(0.4);
material.SetMetallic(0.2);
material->SetAlbedo(impeller::Color::Red());
material->SetRoughness(0.4);
material->SetMetallic(0.2);
// Common properties shared by all materials.
material.SetEnvironmentMap(environment_hdri);
material.SetFlatShaded(true);
material.SetBlendConfig({
material->SetEnvironmentMap(environment_hdri);
material->SetFlatShaded(true);
material->SetBlendConfig({
impeller::BlendOperation::kAdd, // color_op
impeller::BlendFactor::kOne, // source_color_factor
impeller::BlendFactor::kOneMinusSourceAlpha, // destination_color_factor
impeller::BlendOperation::kAdd, // alpha_op
impeller::BlendFactor::kOne, // source_alpha_factor
impeller::BlendFactor::kOneMinusSourceAlpha, // destination_alpha_factor
});
material.SetStencilConfig({
material->SetStencilConfig({
impeller::StencilOperation::kIncrementClamp, // operation
impeller::CompareFunction::kAlways, // compare
});

sphere_entity->SetMaterials({material});


impeller::scene::StaticMeshEntity cube_entity;
cube_entity.GetGeometry(
impeller::scene::Geometry::MakeCube(allocator, {4, 4, 4}));
cube_entity.SetMaterials({material});

cube_entity.SetLocalTransform(Matrix::MakeTranslation({4, 0, 0}));

sphere_entity->Add(sube_entity);
scene.Add(sphere_entity);
sphere_mesh.AddPrimitive({sphere_geometry, material});
sphere_node.SetMesh(sphere_mesh);

Node cube_node;
cube_node.SetLocalTransform(Matrix::MakeTranslation({4, 0, 0}));
Mesh cube_mesh;
auto cube_geometry = impeller::scene::Geometry::MakeCuboid(
allocator, {4, 4, 4});
cube_mesh.AddPrimitive({cube_geometry, material});
cube_node.SetMesh(cube_mesh);

sphere_node.AddChild(cube_node);
scene.GetRoot().AddChild(sphere_node);

/// Post processing.

Expand Down
8 changes: 4 additions & 4 deletions impeller/scene/geometry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ std::shared_ptr<VertexBufferGeometry> Geometry::MakeVertexBuffer(
return result;
}

std::shared_ptr<VertexBufferGeometry> Geometry::MakeFromFBMesh(
const fb::StaticMesh& mesh,
std::shared_ptr<VertexBufferGeometry> Geometry::MakeFromFBMeshPrimitive(
const fb::MeshPrimitive& mesh,
Allocator& allocator) {
IndexType index_type;
switch (mesh.indices()->type()) {
case fb::IndicesType::k16Bit:
case fb::IndexType::k16Bit:
index_type = IndexType::k16bit;
break;
case fb::IndicesType::k32Bit:
case fb::IndexType::k32Bit:
index_type = IndexType::k32bit;
break;
}
Expand Down
4 changes: 2 additions & 2 deletions impeller/scene/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ class Geometry {
static std::shared_ptr<VertexBufferGeometry> MakeVertexBuffer(
VertexBuffer vertex_buffer);

static std::shared_ptr<VertexBufferGeometry> MakeFromFBMesh(
const fb::StaticMesh& mesh,
static std::shared_ptr<VertexBufferGeometry> MakeFromFBMeshPrimitive(
const fb::MeshPrimitive& mesh,
Allocator& allocator);

virtual VertexBuffer GetVertexBuffer(Allocator& allocator) const = 0;
Expand Down
20 changes: 10 additions & 10 deletions impeller/scene/importer/importer_gltf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ static bool WithinRange(int index, size_t size) {
return index >= 0 && static_cast<size_t>(index) < size;
}

static bool ProcessStaticMesh(const tinygltf::Model& gltf,
const tinygltf::Primitive& primitive,
fb::StaticMeshT& static_mesh) {
static bool ProcessMeshPrimitive(const tinygltf::Model& gltf,
const tinygltf::Primitive& primitive,
fb::MeshPrimitiveT& mesh_primitive) {
//---------------------------------------------------------------------------
/// Vertices.
///
Expand Down Expand Up @@ -93,7 +93,7 @@ static bool ProcessStaticMesh(const tinygltf::Model& gltf,
accessor.count); // count
}

builder.WriteFBVertices(static_mesh.vertices);
builder.WriteFBVertices(mesh_primitive.vertices);
}

//---------------------------------------------------------------------------
Expand All @@ -112,10 +112,10 @@ static bool ProcessStaticMesh(const tinygltf::Model& gltf,

switch (index_accessor.componentType) {
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
indices->type = fb::IndicesType::k16Bit;
indices->type = fb::IndexType::k16Bit;
break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
indices->type = fb::IndicesType::k32Bit;
indices->type = fb::IndexType::k32Bit;
break;
default:
std::cerr << "Mesh primitive has unsupported index type "
Expand All @@ -128,7 +128,7 @@ static bool ProcessStaticMesh(const tinygltf::Model& gltf,
&gltf.buffers[index_view.buffer].data[index_view.byteOffset];
std::memcpy(indices->data.data(), index_buffer, indices->data.size());

static_mesh.indices = std::move(indices);
mesh_primitive.indices = std::move(indices);

return true;
}
Expand Down Expand Up @@ -177,11 +177,11 @@ static void ProcessNode(const tinygltf::Model& gltf,
if (WithinRange(in_node.mesh, gltf.meshes.size())) {
auto& mesh = gltf.meshes[in_node.mesh];
for (const auto& primitive : mesh.primitives) {
auto static_mesh = std::make_unique<fb::StaticMeshT>();
if (!ProcessStaticMesh(gltf, primitive, *static_mesh)) {
auto mesh_primitive = std::make_unique<fb::MeshPrimitiveT>();
if (!ProcessMeshPrimitive(gltf, primitive, *mesh_primitive)) {
continue;
}
out_node.meshes.push_back(std::move(static_mesh));
out_node.mesh_primitives.push_back(std::move(mesh_primitive));
}
}

Expand Down
4 changes: 2 additions & 2 deletions impeller/scene/importer/importer_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ TEST(ImporterTest, CanParseGLTF) {
Matrix node_transform = ToMatrix(*node.transform);
ASSERT_MATRIX_NEAR(node_transform, Matrix());

ASSERT_EQ(node.meshes.size(), 1u);
auto& mesh = *node.meshes[0];
ASSERT_EQ(node.mesh_primitives.size(), 1u);
auto& mesh = *node.mesh_primitives[0];
ASSERT_EQ(mesh.indices->count, 918u);

uint16_t first_index =
Expand Down
8 changes: 4 additions & 4 deletions impeller/scene/importer/scene.fbs
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ struct Vertex {
color: Color;
}

enum IndicesType:byte {
enum IndexType:byte {
k16Bit,
k32Bit,
}

table Indices {
data: [ubyte];
count: uint32;
type: IndicesType;
type: IndexType;
}

table Texture {
Expand All @@ -65,7 +65,7 @@ table Material {
// TODO(bdero): PBR textures.
}

table StaticMesh {
table MeshPrimitive {
vertices: [Vertex];
indices: Indices;
material: Material;
Expand All @@ -74,7 +74,7 @@ table StaticMesh {
table Node {
children: [Node];
transform: Matrix;
meshes: [StaticMesh];
mesh_primitives: [MeshPrimitive];
}

table Scene {
Expand Down
44 changes: 44 additions & 0 deletions impeller/scene/mesh.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "impeller/scene/mesh.h"

#include <memory>

#include "impeller/base/validation.h"
#include "impeller/scene/material.h"
#include "impeller/scene/scene_encoder.h"

namespace impeller {
namespace scene {

Mesh::Mesh() = default;
Mesh::~Mesh() = default;

void Mesh::AddPrimitive(Primitive mesh) {
if (mesh.geometry_ == nullptr) {
VALIDATION_LOG << "Mesh geometry cannot be null.";
}
if (mesh.material_ == nullptr) {
VALIDATION_LOG << "Mesh material cannot be null.";
}

meshes_.push_back(std::move(mesh));
}

bool Mesh::Render(SceneEncoder& encoder, const Matrix& transform) const {
for (const auto& mesh : meshes_) {
SceneCommand command = {
.label = "Mesh Primitive",
.transform = transform,
.geometry = mesh.geometry_.get(),
.material = mesh.material_.get(),
};
encoder.Add(command);
}
return true;
}

} // namespace scene
} // namespace impeller
37 changes: 37 additions & 0 deletions impeller/scene/mesh.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#pragma once

#include <memory>
#include <type_traits>

#include "flutter/fml/macros.h"
#include "impeller/scene/geometry.h"
#include "impeller/scene/material.h"
#include "impeller/scene/scene_encoder.h"

namespace impeller {
namespace scene {

class Mesh final {
public:
struct Primitive {
std::shared_ptr<Geometry> geometry_;
std::shared_ptr<Material> material_;
};

Mesh();
~Mesh();

void AddPrimitive(Primitive mesh_);

bool Render(SceneEncoder& encoder, const Matrix& transform) const;

private:
std::vector<Primitive> meshes_;
};

} // namespace scene
} // namespace impeller
Loading