blob: c4aa6b27ec87219e7d8251dc5b47e01b9f49af27 [file] [log] [blame]
// 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 "flutter/testing/testing.h"
#include "impeller/geometry/geometry_asserts.h"
#include "impeller/geometry/matrix.h"
#include "impeller/scene/importer/conversions.h"
#include "impeller/scene/importer/importer.h"
#include "impeller/scene/importer/scene_flatbuffers.h"
namespace impeller {
namespace scene {
namespace importer {
namespace testing {
TEST(ImporterTest, CanParseUnskinnedGLTF) {
auto mapping =
flutter::testing::OpenFixtureAsMapping("flutter_logo_baked.glb");
fb::SceneT scene;
ASSERT_TRUE(ParseGLTF(*mapping, scene));
ASSERT_EQ(scene.children.size(), 1u);
auto& node = scene.nodes[scene.children[0]];
Matrix node_transform = ToMatrix(*node->transform);
ASSERT_MATRIX_NEAR(node_transform, Matrix());
ASSERT_EQ(node->mesh_primitives.size(), 1u);
auto& mesh = *node->mesh_primitives[0];
ASSERT_EQ(mesh.indices->count, 918u);
uint16_t first_index =
*reinterpret_cast<uint16_t*>(mesh.indices->data.data());
ASSERT_EQ(first_index, 45u);
ASSERT_EQ(mesh.vertices.type, fb::VertexBuffer::UnskinnedVertexBuffer);
auto& vertices = mesh.vertices.AsUnskinnedVertexBuffer()->vertices;
ASSERT_EQ(vertices.size(), 260u);
auto& vertex = vertices[0];
Vector3 position = ToVector3(vertex.position());
ASSERT_VECTOR3_NEAR(position, Vector3(-0.0100185, -0.522907, 0.133178));
Vector3 normal = ToVector3(vertex.normal());
ASSERT_VECTOR3_NEAR(normal, Vector3(0.556997, -0.810833, 0.179733));
Vector4 tangent = ToVector4(vertex.tangent());
ASSERT_VECTOR4_NEAR(tangent, Vector4(0.155901, -0.110485, -0.981574, 1));
Vector2 texture_coords = ToVector2(vertex.texture_coords());
ASSERT_POINT_NEAR(texture_coords, Vector2(0.727937, 0.713817));
Color color = ToColor(vertex.color());
ASSERT_COLOR_NEAR(color, Color(0.0221714, 0.467781, 0.921584, 1));
}
TEST(ImporterTest, CanParseSkinnedGLTF) {
auto mapping = flutter::testing::OpenFixtureAsMapping("two_triangles.glb");
fb::SceneT scene;
ASSERT_TRUE(ParseGLTF(*mapping, scene));
ASSERT_EQ(scene.children.size(), 1u);
auto& node = scene.nodes[scene.children[0]];
Matrix node_transform = ToMatrix(*node->transform);
ASSERT_MATRIX_NEAR(node_transform, Matrix());
ASSERT_EQ(node->mesh_primitives.size(), 0u);
ASSERT_EQ(node->children.size(), 2u);
// The skinned node contains both a skeleton and skinned mesh primitives that
// reference bones in the skeleton.
auto& skinned_node = scene.nodes[node->children[0]];
ASSERT_NE(skinned_node->skin, nullptr);
ASSERT_EQ(skinned_node->mesh_primitives.size(), 2u);
auto& bottom_triangle = *skinned_node->mesh_primitives[0];
ASSERT_EQ(bottom_triangle.indices->count, 3u);
ASSERT_EQ(bottom_triangle.vertices.type,
fb::VertexBuffer::SkinnedVertexBuffer);
auto& vertices = bottom_triangle.vertices.AsSkinnedVertexBuffer()->vertices;
ASSERT_EQ(vertices.size(), 3u);
auto& vertex = vertices[0];
Vector3 position = ToVector3(vertex.vertex().position());
ASSERT_VECTOR3_NEAR(position, Vector3(1, 1, 0));
Vector3 normal = ToVector3(vertex.vertex().normal());
ASSERT_VECTOR3_NEAR(normal, Vector3(0, 0, 1));
Vector4 tangent = ToVector4(vertex.vertex().tangent());
ASSERT_VECTOR4_NEAR(tangent, Vector4(1, 0, 0, -1));
Vector2 texture_coords = ToVector2(vertex.vertex().texture_coords());
ASSERT_POINT_NEAR(texture_coords, Vector2(0, 1));
Color color = ToColor(vertex.vertex().color());
ASSERT_COLOR_NEAR(color, Color(1, 1, 1, 1));
Vector4 joints = ToVector4(vertex.joints());
ASSERT_VECTOR4_NEAR(joints, Vector4(0, 0, 0, 0));
Vector4 weights = ToVector4(vertex.weights());
ASSERT_VECTOR4_NEAR(weights, Vector4(1, 0, 0, 0));
ASSERT_EQ(scene.animations.size(), 2u);
ASSERT_EQ(scene.animations[0]->name, "Idle");
ASSERT_EQ(scene.animations[1]->name, "Metronome");
ASSERT_EQ(scene.animations[1]->channels.size(), 6u);
auto& channel = scene.animations[1]->channels[3];
ASSERT_EQ(channel->keyframes.type, fb::Keyframes::RotationKeyframes);
auto* keyframes = channel->keyframes.AsRotationKeyframes();
ASSERT_EQ(keyframes->values.size(), 40u);
ASSERT_VECTOR4_NEAR(ToVector4(keyframes->values[0]),
Vector4(0.653281, -0.270598, 0.270598, 0.653281));
ASSERT_VECTOR4_NEAR(ToVector4(keyframes->values[10]),
Vector4(0.700151, 0.0989373, -0.0989373, 0.700151));
}
} // namespace testing
} // namespace importer
} // namespace scene
} // namespace impeller