[Impeller Scene] Fix crasher for nodes with no meshes (flutter/engine#38374)
This commit is contained in:
@@ -43,12 +43,14 @@ Node Node::MakeFromFlatbuffer(const fb::Scene& scene, Allocator& allocator) {
|
||||
Node Node::MakeFromFlatbuffer(const fb::Node& node, Allocator& allocator) {
|
||||
Node result;
|
||||
|
||||
Mesh mesh;
|
||||
for (const auto* primitives : *node.mesh_primitives()) {
|
||||
auto geometry = Geometry::MakeFromFlatbuffer(*primitives, allocator);
|
||||
mesh.AddPrimitive({geometry, Material::MakeUnlit()});
|
||||
if (node.mesh_primitives()) {
|
||||
Mesh mesh;
|
||||
for (const auto* primitives : *node.mesh_primitives()) {
|
||||
auto geometry = Geometry::MakeFromFlatbuffer(*primitives, allocator);
|
||||
mesh.AddPrimitive({geometry, Material::MakeUnlit()});
|
||||
}
|
||||
result.SetMesh(std::move(mesh));
|
||||
}
|
||||
result.SetMesh(std::move(mesh));
|
||||
|
||||
if (!node.children()) {
|
||||
return result;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "impeller/scene/mesh.h"
|
||||
#include "impeller/scene/scene.h"
|
||||
#include "third_party/flatbuffers/include/flatbuffers/verifier.h"
|
||||
#include "third_party/imgui/imgui.h"
|
||||
|
||||
// #include "third_party/tinygltf/tiny_gltf.h"
|
||||
|
||||
@@ -65,7 +66,7 @@ TEST_P(SceneTest, CuboidUnlit) {
|
||||
OpenPlaygroundHere(callback);
|
||||
}
|
||||
|
||||
TEST_P(SceneTest, GLTFScene) {
|
||||
TEST_P(SceneTest, FlutterLogo) {
|
||||
auto allocator = GetContext()->GetResourceAllocator();
|
||||
|
||||
auto mapping =
|
||||
@@ -108,6 +109,54 @@ TEST_P(SceneTest, GLTFScene) {
|
||||
OpenPlaygroundHere(callback);
|
||||
}
|
||||
|
||||
TEST_P(SceneTest, TwoTriangles) {
|
||||
auto allocator = GetContext()->GetResourceAllocator();
|
||||
|
||||
auto mapping =
|
||||
flutter::testing::OpenFixtureAsMapping("two_triangles.glb.ipscene");
|
||||
ASSERT_NE(mapping, nullptr);
|
||||
|
||||
std::optional<Node> gltf_scene =
|
||||
Node::MakeFromFlatbuffer(*mapping, *allocator);
|
||||
ASSERT_TRUE(gltf_scene.has_value());
|
||||
|
||||
auto scene = Scene(GetContext());
|
||||
scene.GetRoot().AddChild(std::move(gltf_scene.value()));
|
||||
|
||||
Renderer::RenderCallback callback = [&](RenderTarget& render_target) {
|
||||
Node& node = scene.GetRoot().GetChildren()[0];
|
||||
node.SetLocalTransform(node.GetLocalTransform() *
|
||||
Matrix::MakeRotation(0.02, {0, 1, 0, 0}));
|
||||
|
||||
static ImVec2 mouse_pos_prev = ImGui::GetMousePos();
|
||||
ImVec2 mouse_pos = ImGui::GetMousePos();
|
||||
Vector2 mouse_diff =
|
||||
Vector2(mouse_pos.x - mouse_pos_prev.x, mouse_pos.y - mouse_pos_prev.y);
|
||||
|
||||
static Vector3 position(0, 1, -5);
|
||||
static Vector3 cam_position = position;
|
||||
auto strafe =
|
||||
Vector3(ImGui::IsKeyDown(ImGuiKey_D) - ImGui::IsKeyDown(ImGuiKey_A),
|
||||
ImGui::IsKeyDown(ImGuiKey_E) - ImGui::IsKeyDown(ImGuiKey_Q),
|
||||
ImGui::IsKeyDown(ImGuiKey_W) - ImGui::IsKeyDown(ImGuiKey_S));
|
||||
position += strafe * 0.5;
|
||||
cam_position = cam_position.Lerp(position, 0.02);
|
||||
|
||||
// Face towards the +Z direction (+X right, +Y up).
|
||||
auto camera = Camera::MakePerspective(
|
||||
/* fov */ Degrees(60),
|
||||
/* position */ cam_position)
|
||||
.LookAt(
|
||||
/* target */ cam_position + Vector3(0, 0, 1),
|
||||
/* up */ {0, 1, 0});
|
||||
|
||||
scene.Render(render_target, camera);
|
||||
return true;
|
||||
};
|
||||
|
||||
OpenPlaygroundHere(callback);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace scene
|
||||
} // namespace impeller
|
||||
|
||||
Reference in New Issue
Block a user