Flutter Engine
The Flutter Engine
Namespaces | Classes | Enumerations | Functions | Variables
impeller::scene::importer Namespace Reference

Namespaces

namespace  testing
 

Classes

class  SkinnedVerticesBuilder
 
struct  Switches
 
class  UnskinnedVerticesBuilder
 
class  VerticesBuilder
 

Enumerations

enum class  SourceType { kUnknown , kGLTF }
 

Functions

Matrix ToMatrix (const std::vector< double > &m)
 
Matrix ToMatrix (const fb::Matrix &m)
 
Vector2 ToVector2 (const fb::Vec2 &v)
 
Vector3 ToVector3 (const fb::Vec3 &v)
 
Vector4 ToVector4 (const fb::Vec4 &v)
 
Color ToColor (const fb::Color &c)
 
fb::Matrix ToFBMatrix (const Matrix &m)
 
std::unique_ptr< fb::Matrix > ToFBMatrixUniquePtr (const Matrix &m)
 
fb::Vec2 ToFBVec2 (const Vector2 v)
 
fb::Vec3 ToFBVec3 (const Vector3 v)
 
fb::Vec4 ToFBVec4 (const Vector4 v)
 
fb::Color ToFBColor (const Color c)
 
std::unique_ptr< fb::Color > ToFBColor (const std::vector< double > &c)
 
bool ParseGLTF (const fml::Mapping &source_mapping, fb::SceneT &out_scene)
 
static bool WithinRange (int index, size_t size)
 
static bool MeshPrimitiveIsSkinned (const tinygltf::Primitive &primitive)
 
static void ProcessMaterial (const tinygltf::Model &gltf, const tinygltf::Material &in_material, fb::MaterialT &out_material)
 
static bool ProcessMeshPrimitive (const tinygltf::Model &gltf, const tinygltf::Primitive &primitive, fb::MeshPrimitiveT &mesh_primitive)
 
static void ProcessNode (const tinygltf::Model &gltf, const tinygltf::Node &in_node, fb::NodeT &out_node)
 
static void ProcessTexture (const tinygltf::Model &gltf, const tinygltf::Texture &in_texture, fb::TextureT &out_texture)
 
static void ProcessAnimation (const tinygltf::Model &gltf, const tinygltf::Animation &in_animation, fb::AnimationT &out_animation)
 
static bool SetPermissiveAccess (const std::filesystem::path &p)
 
bool Main (const fml::CommandLine &command_line)
 
static SourceType SourceTypeFromCommandLine (const fml::CommandLine &command_line)
 
template<typename SourceType >
static Scalar ToScalar (const void *source, size_t index, bool normalized)
 Reads a numeric component from source and returns a 32bit float. If normalized is true, signed SourceTypes convert to a range of -1 to 1, and unsigned SourceTypes convert to a range of 0 to 1. More...
 
static void PassthroughAttributeWriter (Scalar *destination, const void *source, const VerticesBuilder::ComponentProperties &component, const VerticesBuilder::AttributeProperties &attribute)
 A ComponentWriter which simply converts all of an attribute's components to normalized scalar form. More...
 
static void JointsAttributeWriter (Scalar *destination, const void *source, const VerticesBuilder::ComponentProperties &component, const VerticesBuilder::AttributeProperties &attribute)
 A ComponentWriter which converts four vertex indices to scalars. More...
 

Variables

static const std::map< std::string, VerticesBuilder::AttributeTypekAttributes
 
static const std::map< std::string, SourceTypekKnownSourceTypes
 
static std::map< VerticesBuilder::ComponentType, VerticesBuilder::ComponentPropertieskComponentTypes
 

Enumeration Type Documentation

◆ SourceType

Enumerator
kUnknown 
kGLTF 

Definition at line 12 of file types.h.

Function Documentation

◆ JointsAttributeWriter()

static void impeller::scene::importer::JointsAttributeWriter ( Scalar destination,
const void *  source,
const VerticesBuilder::ComponentProperties component,
const VerticesBuilder::AttributeProperties attribute 
)
static

A ComponentWriter which converts four vertex indices to scalars.

Definition at line 70 of file vertices_builder.cc.

74 {
75 FML_DCHECK(attribute.component_count == 4);
76 for (int i = 0; i < 4; i++) {
77 *(destination + i) = component.convert_proc(source, i, false);
78 }
79}
SkBitmap source
Definition: examples.cpp:28
#define FML_DCHECK(condition)
Definition: logging.h:103

◆ Main()

bool impeller::scene::importer::Main ( const fml::CommandLine command_line)

Definition at line 40 of file scenec_main.cc.

40 {
42 if (command_line.HasOption("help")) {
43 Switches::PrintHelp(std::cout);
44 return true;
45 }
46
47 Switches switches(command_line);
48 if (!switches.AreValid(std::cerr)) {
49 std::cerr << "Invalid flags specified." << std::endl;
50 Switches::PrintHelp(std::cerr);
51 return false;
52 }
53
54 auto source_file_mapping =
55 fml::FileMapping::CreateReadOnly(switches.source_file_name);
56 if (!source_file_mapping) {
57 std::cerr << "Could not open input file." << std::endl;
58 return false;
59 }
60
61 fb::SceneT scene;
62 bool success = false;
63 switch (switches.input_type) {
64 case SourceType::kGLTF:
65 success = ParseGLTF(*source_file_mapping, scene);
66 break;
68 std::cerr << "Unknown input type." << std::endl;
69 return false;
70 }
71 if (!success) {
72 std::cerr << "Failed to parse input file." << std::endl;
73 return false;
74 }
75
76 flatbuffers::FlatBufferBuilder builder;
77 builder.Finish(fb::Scene::Pack(builder, &scene), fb::SceneIdentifier());
78
79 auto output_file_name = std::filesystem::absolute(
80 std::filesystem::current_path() / switches.output_file_name);
81 fml::NonOwnedMapping mapping(builder.GetCurrentBufferPointer(),
82 builder.GetSize());
83 if (!fml::WriteAtomically(*switches.working_directory,
84 compiler::Utf8FromPath(output_file_name).c_str(),
85 mapping)) {
86 std::cerr << "Could not write file to " << switches.output_file_name
87 << std::endl;
88 return false;
89 }
90
91 // Tools that consume the geometry data expect the access mode to be 0644.
92 if (!SetPermissiveAccess(output_file_name)) {
93 return false;
94 }
95
96 return true;
97}
bool HasOption(std::string_view name, size_t *index=nullptr) const
Definition: command_line.cc:40
static std::unique_ptr< FileMapping > CreateReadOnly(const std::string &path)
Definition: mapping.cc:20
static void * Pack(const T &ctx, SkArenaAlloc *alloc)
bool WriteAtomically(const fml::UniqueFD &base_directory, const char *file_name, const Mapping &mapping)
Definition: file_posix.cc:191
void InstallCrashHandler()
Definition: backtrace.cc:126
std::string Utf8FromPath(const std::filesystem::path &path)
Converts a native format path to a utf8 string.
Definition: utilities.cc:30
static bool SetPermissiveAccess(const std::filesystem::path &p)
Definition: scenec_main.cc:26
bool ParseGLTF(const fml::Mapping &source_mapping, fb::SceneT &out_scene)

◆ MeshPrimitiveIsSkinned()

static bool impeller::scene::importer::MeshPrimitiveIsSkinned ( const tinygltf::Primitive &  primitive)
static

Definition at line 39 of file importer_gltf.cc.

39 {
40 return primitive.attributes.find("JOINTS_0") != primitive.attributes.end() &&
41 primitive.attributes.find("WEIGHTS_0") != primitive.attributes.end();
42}

◆ ParseGLTF()

bool impeller::scene::importer::ParseGLTF ( const fml::Mapping source_mapping,
fb::SceneT &  out_scene 
)

Definition at line 450 of file importer_gltf.cc.

450 {
451 tinygltf::Model gltf;
452
453 {
454 tinygltf::TinyGLTF loader;
455 std::string error;
456 std::string warning;
457 bool success = loader.LoadBinaryFromMemory(&gltf, &error, &warning,
458 source_mapping.GetMapping(),
459 source_mapping.GetSize());
460 if (!warning.empty()) {
461 std::cerr << "Warning while loading GLTF: " << warning << std::endl;
462 }
463 if (!error.empty()) {
464 std::cerr << "Error while loading GLTF: " << error << std::endl;
465 }
466 if (!success) {
467 return false;
468 }
469 }
470
471 const tinygltf::Scene& scene = gltf.scenes[gltf.defaultScene];
472 out_scene.children = scene.nodes;
473
474 out_scene.transform =
475 ToFBMatrixUniquePtr(Matrix::MakeScale(Vector3(1, 1, -1)));
476
477 for (size_t texture_i = 0; texture_i < gltf.textures.size(); texture_i++) {
478 auto texture = std::make_unique<fb::TextureT>();
479 ProcessTexture(gltf, gltf.textures[texture_i], *texture);
480 out_scene.textures.push_back(std::move(texture));
481 }
482
483 for (size_t node_i = 0; node_i < gltf.nodes.size(); node_i++) {
484 auto node = std::make_unique<fb::NodeT>();
485 ProcessNode(gltf, gltf.nodes[node_i], *node);
486 out_scene.nodes.push_back(std::move(node));
487 }
488
489 for (size_t animation_i = 0; animation_i < gltf.animations.size();
490 animation_i++) {
491 auto animation = std::make_unique<fb::AnimationT>();
492 ProcessAnimation(gltf, gltf.animations[animation_i], *animation);
493 out_scene.animations.push_back(std::move(animation));
494 }
495
496 return true;
497}
virtual const uint8_t * GetMapping() const =0
virtual size_t GetSize() const =0
const uint8_t uint32_t uint32_t GError ** error
FlTexture * texture
std::unique_ptr< fb::Matrix > ToFBMatrixUniquePtr(const Matrix &m)
Definition: conversions.cc:62
static void ProcessAnimation(const tinygltf::Model &gltf, const tinygltf::Animation &in_animation, fb::AnimationT &out_animation)
static void ProcessNode(const tinygltf::Model &gltf, const tinygltf::Node &in_node, fb::NodeT &out_node)
static void ProcessTexture(const tinygltf::Model &gltf, const tinygltf::Texture &in_texture, fb::TextureT &out_texture)

◆ PassthroughAttributeWriter()

static void impeller::scene::importer::PassthroughAttributeWriter ( Scalar destination,
const void *  source,
const VerticesBuilder::ComponentProperties component,
const VerticesBuilder::AttributeProperties attribute 
)
static

A ComponentWriter which simply converts all of an attribute's components to normalized scalar form.

Definition at line 55 of file vertices_builder.cc.

59 {
60 FML_DCHECK(attribute.size_bytes ==
61 attribute.component_count * sizeof(Scalar));
62 for (size_t component_i = 0; component_i < attribute.component_count;
63 component_i++) {
64 *(destination + component_i) =
65 component.convert_proc(source, component_i, true);
66 }
67}
float Scalar
Definition: scalar.h:18

◆ ProcessAnimation()

static void impeller::scene::importer::ProcessAnimation ( const tinygltf::Model &  gltf,
const tinygltf::Animation &  in_animation,
fb::AnimationT &  out_animation 
)
static

Keyframe times.

Keyframe values.

Definition at line 316 of file importer_gltf.cc.

318 {
319 out_animation.name = in_animation.name;
320
321 // std::vector<impeller::fb::ChannelT> channels;
322 std::vector<impeller::fb::ChannelT> translation_channels;
323 std::vector<impeller::fb::ChannelT> rotation_channels;
324 std::vector<impeller::fb::ChannelT> scale_channels;
325 for (auto& in_channel : in_animation.channels) {
326 auto out_channel = fb::ChannelT();
327
328 out_channel.node = in_channel.target_node;
329 auto& sampler = in_animation.samplers[in_channel.sampler];
330
331 /// Keyframe times.
332 auto& times_accessor = gltf.accessors[sampler.input];
333 if (times_accessor.count <= 0) {
334 continue; // Nothing to record.
335 }
336 {
337 auto& times_bufferview = gltf.bufferViews[times_accessor.bufferView];
338 auto& times_buffer = gltf.buffers[times_bufferview.buffer];
339 if (times_accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
340 std::cerr << "Unexpected component type \""
341 << times_accessor.componentType
342 << "\" for animation channel times accessor. Skipping."
343 << std::endl;
344 continue;
345 }
346 if (times_accessor.type != TINYGLTF_TYPE_SCALAR) {
347 std::cerr << "Unexpected type \"" << times_accessor.type
348 << "\" for animation channel times accessor. Skipping."
349 << std::endl;
350 continue;
351 }
352 for (size_t time_i = 0; time_i < times_accessor.count; time_i++) {
353 const float* time_p = reinterpret_cast<const float*>(
354 times_buffer.data.data() + times_bufferview.byteOffset +
355 times_accessor.ByteStride(times_bufferview) * time_i);
356 out_channel.timeline.push_back(*time_p);
357 }
358 }
359
360 /// Keyframe values.
361 auto& values_accessor = gltf.accessors[sampler.output];
362 if (values_accessor.count != times_accessor.count) {
363 std::cerr << "Mismatch between time and value accessors for animation "
364 "channel. Skipping."
365 << std::endl;
366 continue;
367 }
368 {
369 auto& values_bufferview = gltf.bufferViews[values_accessor.bufferView];
370 auto& values_buffer = gltf.buffers[values_bufferview.buffer];
371 if (values_accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
372 std::cerr << "Unexpected component type \""
373 << values_accessor.componentType
374 << "\" for animation channel values accessor. Skipping."
375 << std::endl;
376 continue;
377 }
378 if (in_channel.target_path == "translation") {
379 if (values_accessor.type != TINYGLTF_TYPE_VEC3) {
380 std::cerr << "Unexpected type \"" << values_accessor.type
381 << "\" for animation channel \"translation\" accessor. "
382 "Skipping."
383 << std::endl;
384 continue;
385 }
386 fb::TranslationKeyframesT keyframes;
387 for (size_t value_i = 0; value_i < values_accessor.count; value_i++) {
388 const float* value_p = reinterpret_cast<const float*>(
389 values_buffer.data.data() + values_bufferview.byteOffset +
390 values_accessor.ByteStride(values_bufferview) * value_i);
391 keyframes.values.push_back(
392 fb::Vec3(value_p[0], value_p[1], value_p[2]));
393 }
394 out_channel.keyframes.Set(std::move(keyframes));
395 translation_channels.push_back(std::move(out_channel));
396 } else if (in_channel.target_path == "rotation") {
397 if (values_accessor.type != TINYGLTF_TYPE_VEC4) {
398 std::cerr << "Unexpected type \"" << values_accessor.type
399 << "\" for animation channel \"rotation\" accessor. "
400 "Skipping."
401 << std::endl;
402 continue;
403 }
404 fb::RotationKeyframesT keyframes;
405 for (size_t value_i = 0; value_i < values_accessor.count; value_i++) {
406 const float* value_p = reinterpret_cast<const float*>(
407 values_buffer.data.data() + values_bufferview.byteOffset +
408 values_accessor.ByteStride(values_bufferview) * value_i);
409 keyframes.values.push_back(
410 fb::Vec4(value_p[0], value_p[1], value_p[2], value_p[3]));
411 }
412 out_channel.keyframes.Set(std::move(keyframes));
413 rotation_channels.push_back(std::move(out_channel));
414 } else if (in_channel.target_path == "scale") {
415 if (values_accessor.type != TINYGLTF_TYPE_VEC3) {
416 std::cerr << "Unexpected type \"" << values_accessor.type
417 << "\" for animation channel \"scale\" accessor. "
418 "Skipping."
419 << std::endl;
420 continue;
421 }
422 fb::ScaleKeyframesT keyframes;
423 for (size_t value_i = 0; value_i < values_accessor.count; value_i++) {
424 const float* value_p = reinterpret_cast<const float*>(
425 values_buffer.data.data() + values_bufferview.byteOffset +
426 values_accessor.ByteStride(values_bufferview) * value_i);
427 keyframes.values.push_back(
428 fb::Vec3(value_p[0], value_p[1], value_p[2]));
429 }
430 out_channel.keyframes.Set(std::move(keyframes));
431 scale_channels.push_back(std::move(out_channel));
432 } else {
433 std::cerr << "Unsupported animation channel target path \""
434 << in_channel.target_path << "\". Skipping." << std::endl;
435 continue;
436 }
437 }
438 }
439
440 std::vector<std::unique_ptr<impeller::fb::ChannelT>> channels;
441 for (const auto& channel_list :
442 {translation_channels, rotation_channels, scale_channels}) {
443 for (const auto& channel : channel_list) {
444 channels.push_back(std::make_unique<fb::ChannelT>(channel));
445 }
446 }
447 out_animation.channels = std::move(channels);
448}
skvx::Vec< 4, float > Vec4

◆ ProcessMaterial()

static void impeller::scene::importer::ProcessMaterial ( const tinygltf::Model &  gltf,
const tinygltf::Material &  in_material,
fb::MaterialT &  out_material 
)
static

Definition at line 44 of file importer_gltf.cc.

46 {
47 out_material.type = fb::MaterialType::kUnlit;
48 out_material.base_color_factor =
49 ToFBColor(in_material.pbrMetallicRoughness.baseColorFactor);
50 bool base_color_texture_valid =
51 in_material.pbrMetallicRoughness.baseColorTexture.texCoord == 0 &&
52 in_material.pbrMetallicRoughness.baseColorTexture.index >= 0 &&
53 in_material.pbrMetallicRoughness.baseColorTexture.index <
54 static_cast<int32_t>(gltf.textures.size());
55 out_material.base_color_texture =
56 base_color_texture_valid
57 // This is safe because every GLTF input texture is mapped to a
58 // `Scene->texture`.
59 ? in_material.pbrMetallicRoughness.baseColorTexture.index
60 : -1;
61}
fb::Color ToFBColor(const Color c)
Definition: conversions.cc:82

◆ ProcessMeshPrimitive()

static bool impeller::scene::importer::ProcessMeshPrimitive ( const tinygltf::Model &  gltf,
const tinygltf::Primitive &  primitive,
fb::MeshPrimitiveT &  mesh_primitive 
)
static

Vertices.

Indices.

Material.

Definition at line 63 of file importer_gltf.cc.

65 {
66 //---------------------------------------------------------------------------
67 /// Vertices.
68 ///
69
70 {
71 bool is_skinned = MeshPrimitiveIsSkinned(primitive);
72 std::unique_ptr<VerticesBuilder> builder =
73 is_skinned ? VerticesBuilder::MakeSkinned()
74 : VerticesBuilder::MakeUnskinned();
75
76 for (const auto& attribute : primitive.attributes) {
77 auto attribute_type = kAttributes.find(attribute.first);
78 if (attribute_type == kAttributes.end()) {
79 std::cerr << "Vertex attribute \"" << attribute.first
80 << "\" not supported." << std::endl;
81 continue;
82 }
83 if (!is_skinned &&
84 (attribute_type->second == VerticesBuilder::AttributeType::kJoints ||
85 attribute_type->second ==
86 VerticesBuilder::AttributeType::kWeights)) {
87 // If the primitive doesn't have enough information to be skinned, skip
88 // skinning-related attributes.
89 continue;
90 }
91
92 const auto accessor = gltf.accessors[attribute.second];
93 const auto view = gltf.bufferViews[accessor.bufferView];
94
95 const auto buffer = gltf.buffers[view.buffer];
96 const unsigned char* source_start = &buffer.data[view.byteOffset];
97
98 VerticesBuilder::ComponentType type;
99 switch (accessor.componentType) {
100 case TINYGLTF_COMPONENT_TYPE_BYTE:
101 type = VerticesBuilder::ComponentType::kSignedByte;
102 break;
103 case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
105 break;
106 case TINYGLTF_COMPONENT_TYPE_SHORT:
107 type = VerticesBuilder::ComponentType::kSignedShort;
108 break;
109 case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
110 type = VerticesBuilder::ComponentType::kUnsignedShort;
111 break;
112 case TINYGLTF_COMPONENT_TYPE_INT:
113 type = VerticesBuilder::ComponentType::kSignedInt;
114 break;
115 case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
116 type = VerticesBuilder::ComponentType::kUnsignedInt;
117 break;
118 case TINYGLTF_COMPONENT_TYPE_FLOAT:
120 break;
121 default:
122 std::cerr << "Skipping attribute \"" << attribute.first
123 << "\" due to invalid component type." << std::endl;
124 continue;
125 }
126
127 builder->SetAttributeFromBuffer(
128 attribute_type->second, // attribute
129 type, // component_type
130 source_start, // buffer_start
131 accessor.ByteStride(view), // stride_bytes
132 accessor.count); // count
133 }
134
135 builder->WriteFBVertices(mesh_primitive);
136 }
137
138 //---------------------------------------------------------------------------
139 /// Indices.
140 ///
141
142 {
143 if (!WithinRange(primitive.indices, gltf.accessors.size())) {
144 std::cerr << "Mesh primitive has no index buffer. Skipping." << std::endl;
145 return false;
146 }
147
148 auto index_accessor = gltf.accessors[primitive.indices];
149 auto index_view = gltf.bufferViews[index_accessor.bufferView];
150
151 auto indices = std::make_unique<fb::IndicesT>();
152
153 switch (index_accessor.componentType) {
154 case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
155 indices->type = fb::IndexType::k16Bit;
156 break;
157 case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
158 indices->type = fb::IndexType::k32Bit;
159 break;
160 default:
161 std::cerr << "Mesh primitive has unsupported index type "
162 << index_accessor.componentType << ". Skipping.";
163 return false;
164 }
165 indices->count = index_accessor.count;
166 indices->data.resize(index_view.byteLength);
167 const auto* index_buffer =
168 &gltf.buffers[index_view.buffer].data[index_view.byteOffset];
169 std::memcpy(indices->data.data(), index_buffer, indices->data.size());
170
171 mesh_primitive.indices = std::move(indices);
172 }
173
174 //---------------------------------------------------------------------------
175 /// Material.
176 ///
177
178 {
179 auto material = std::make_unique<fb::MaterialT>();
180 if (primitive.material >= 0 &&
181 primitive.material < static_cast<int>(gltf.materials.size())) {
182 ProcessMaterial(gltf, gltf.materials[primitive.material], *material);
183 } else {
184 material->type = fb::MaterialType::kUnlit;
185 }
186 mesh_primitive.material = std::move(material);
187 }
188
189 return true;
190}
GLenum type
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
static bool MeshPrimitiveIsSkinned(const tinygltf::Primitive &primitive)
static bool WithinRange(int index, size_t size)
static void ProcessMaterial(const tinygltf::Model &gltf, const tinygltf::Material &in_material, fb::MaterialT &out_material)
static const std::map< std::string, VerticesBuilder::AttributeType > kAttributes

◆ ProcessNode()

static void impeller::scene::importer::ProcessNode ( const tinygltf::Model &  gltf,
const tinygltf::Node &  in_node,
fb::NodeT &  out_node 
)
static

Transform.

Static meshes.

Skin.

Definition at line 192 of file importer_gltf.cc.

194 {
195 out_node.name = in_node.name;
196 out_node.children = in_node.children;
197
198 //---------------------------------------------------------------------------
199 /// Transform.
200 ///
201
203 if (in_node.scale.size() == 3) {
204 transform =
205 transform * Matrix::MakeScale({static_cast<Scalar>(in_node.scale[0]),
206 static_cast<Scalar>(in_node.scale[1]),
207 static_cast<Scalar>(in_node.scale[2])});
208 }
209 if (in_node.rotation.size() == 4) {
210 transform = transform * Matrix::MakeRotation(Quaternion(
211 in_node.rotation[0], in_node.rotation[1],
212 in_node.rotation[2], in_node.rotation[3]));
213 }
214 if (in_node.translation.size() == 3) {
215 transform = transform * Matrix::MakeTranslation(
216 {static_cast<Scalar>(in_node.translation[0]),
217 static_cast<Scalar>(in_node.translation[1]),
218 static_cast<Scalar>(in_node.translation[2])});
219 }
220 if (in_node.matrix.size() == 16) {
221 if (!transform.IsIdentity()) {
222 std::cerr << "The `matrix` attribute of node (name: " << in_node.name
223 << ") is set in addition to one or more of the "
224 "`translation/rotation/scale` attributes. Using only the "
225 "`matrix` "
226 "attribute.";
227 }
228 transform = ToMatrix(in_node.matrix);
229 }
230 out_node.transform = ToFBMatrixUniquePtr(transform);
231
232 //---------------------------------------------------------------------------
233 /// Static meshes.
234 ///
235
236 if (WithinRange(in_node.mesh, gltf.meshes.size())) {
237 auto& mesh = gltf.meshes[in_node.mesh];
238 for (const auto& primitive : mesh.primitives) {
239 auto mesh_primitive = std::make_unique<fb::MeshPrimitiveT>();
240 if (!ProcessMeshPrimitive(gltf, primitive, *mesh_primitive)) {
241 continue;
242 }
243 out_node.mesh_primitives.push_back(std::move(mesh_primitive));
244 }
245 }
246
247 //---------------------------------------------------------------------------
248 /// Skin.
249 ///
250
251 if (WithinRange(in_node.skin, gltf.skins.size())) {
252 auto& skin = gltf.skins[in_node.skin];
253
254 auto ipskin = std::make_unique<fb::SkinT>();
255 ipskin->joints = skin.joints;
256 {
257 std::vector<fb::Matrix> matrices;
258 auto& matrix_accessor = gltf.accessors[skin.inverseBindMatrices];
259 auto& matrix_view = gltf.bufferViews[matrix_accessor.bufferView];
260 auto& matrix_buffer = gltf.buffers[matrix_view.buffer];
261 for (size_t matrix_i = 0; matrix_i < matrix_accessor.count; matrix_i++) {
262 auto* s = reinterpret_cast<const float*>(
263 matrix_buffer.data.data() + matrix_view.byteOffset +
264 matrix_accessor.ByteStride(matrix_view) * matrix_i);
265 Matrix m(s[0], s[1], s[2], s[3], //
266 s[4], s[5], s[6], s[7], //
267 s[8], s[9], s[10], s[11], //
268 s[12], s[13], s[14], s[15]);
269 matrices.push_back(ToFBMatrix(m));
270 }
271 ipskin->inverse_bind_matrices = std::move(matrices);
272 }
273 ipskin->skeleton = skin.skeleton;
274 out_node.skin = std::move(ipskin);
275 }
276}
struct MyStruct s
SkMesh mesh
Definition: SkRecords.h:345
static bool ProcessMeshPrimitive(const tinygltf::Model &gltf, const tinygltf::Primitive &primitive, fb::MeshPrimitiveT &mesh_primitive)
fb::Matrix ToFBMatrix(const Matrix &m)
Definition: conversions.cc:54
static Matrix ToMatrix(const SkMatrix &m)
SK_API sk_sp< PrecompileColorFilter > Matrix()
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition: p3.cpp:47
A 4x4 matrix using column-major storage.
Definition: matrix.h:37

◆ ProcessTexture()

static void impeller::scene::importer::ProcessTexture ( const tinygltf::Model &  gltf,
const tinygltf::Texture &  in_texture,
fb::TextureT &  out_texture 
)
static

Definition at line 278 of file importer_gltf.cc.

280 {
281 if (!WithinRange(in_texture.source, gltf.images.size())) {
282 return;
283 }
284 auto& image = gltf.images[in_texture.source];
285
286 auto embedded = std::make_unique<fb::EmbeddedImageT>();
287 embedded->bytes = image.image;
288 size_t bytes_per_component = 0;
289 switch (image.pixel_type) {
290 case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
291 embedded->component_type = fb::ComponentType::k8Bit;
292 bytes_per_component = 1;
293 break;
294 case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
295 embedded->component_type = fb::ComponentType::k16Bit;
296 bytes_per_component = 2;
297 break;
298 default:
299 std::cerr << "Texture component type " << image.pixel_type
300 << " not supported." << std::endl;
301 return;
302 }
303 if (image.image.size() !=
304 bytes_per_component * image.component * image.width * image.height) {
305 std::cerr << "Decompressed texture had unexpected buffer size. Skipping."
306 << std::endl;
307 return;
308 }
309 embedded->component_count = image.component;
310 embedded->width = image.width;
311 embedded->height = image.height;
312 out_texture.embedded_image = std::move(embedded);
313 out_texture.uri = image.uri;
314}
int width() const
Definition: SkImage.h:285
int height() const
Definition: SkImage.h:291
sk_sp< const SkImage > image
Definition: SkRecords.h:269

◆ SetPermissiveAccess()

static bool impeller::scene::importer::SetPermissiveAccess ( const std::filesystem::path &  p)
static

Definition at line 26 of file scenec_main.cc.

26 {
27 auto permissions =
28 std::filesystem::perms::owner_read | std::filesystem::perms::owner_write |
29 std::filesystem::perms::group_read | std::filesystem::perms::others_read;
30 std::error_code error;
31 std::filesystem::permissions(p, permissions, error);
32 if (error) {
33 std::cerr << "Failed to set access on file '" << p
34 << "': " << error.message() << std::endl;
35 return false;
36 }
37 return true;
38}

◆ SourceTypeFromCommandLine()

static SourceType impeller::scene::importer::SourceTypeFromCommandLine ( const fml::CommandLine command_line)
static

Definition at line 43 of file switches.cc.

44 {
45 auto source_type_option =
46 command_line.GetOptionValueWithDefault("input-type", "gltf");
47 auto source_type_search = kKnownSourceTypes.find(source_type_option);
48 if (source_type_search == kKnownSourceTypes.end()) {
50 }
51 return source_type_search->second;
52}
std::string GetOptionValueWithDefault(std::string_view name, std::string_view default_value) const
Definition: command_line.cc:72
static const std::map< std::string, SourceType > kKnownSourceTypes
Definition: switches.cc:20

◆ ToColor()

Color impeller::scene::importer::ToColor ( const fb::Color &  c)

Definition at line 46 of file conversions.cc.

46 {
47 return Color(c.r(), c.g(), c.b(), c.a());
48}
SK_API sk_sp< SkShader > Color(SkColor)

◆ ToFBColor() [1/2]

fb::Color impeller::scene::importer::ToFBColor ( const Color  c)

Definition at line 82 of file conversions.cc.

82 {
83 return fb::Color(c.red, c.green, c.blue, c.alpha);
84}
Scalar blue
Definition: color.h:138
Scalar alpha
Definition: color.h:143
Scalar red
Definition: color.h:128
Scalar green
Definition: color.h:133

◆ ToFBColor() [2/2]

std::unique_ptr< fb::Color > impeller::scene::importer::ToFBColor ( const std::vector< double > &  c)

Definition at line 86 of file conversions.cc.

86 {
87 auto* color = new fb::Color(c.size() > 0 ? c[0] : 1, //
88 c.size() > 1 ? c[1] : 1, //
89 c.size() > 2 ? c[2] : 1, //
90 c.size() > 3 ? c[3] : 1);
91 return std::unique_ptr<fb::Color>(color);
92}
DlColor color

◆ ToFBMatrix()

fb::Matrix impeller::scene::importer::ToFBMatrix ( const Matrix m)

Impeller -> Flatbuffers

Definition at line 54 of file conversions.cc.

54 {
55 auto array = std::array<Scalar, 16>{m.m[0], m.m[1], m.m[2], m.m[3], //
56 m.m[4], m.m[5], m.m[6], m.m[7], //
57 m.m[8], m.m[9], m.m[10], m.m[11], //
58 m.m[12], m.m[13], m.m[14], m.m[15]};
59 return fb::Matrix(array);
60}

◆ ToFBMatrixUniquePtr()

std::unique_ptr< fb::Matrix > impeller::scene::importer::ToFBMatrixUniquePtr ( const Matrix m)

Definition at line 62 of file conversions.cc.

62 {
63 auto array = std::array<Scalar, 16>{m.m[0], m.m[1], m.m[2], m.m[3], //
64 m.m[4], m.m[5], m.m[6], m.m[7], //
65 m.m[8], m.m[9], m.m[10], m.m[11], //
66 m.m[12], m.m[13], m.m[14], m.m[15]};
67 return std::make_unique<fb::Matrix>(array);
68}

◆ ToFBVec2()

fb::Vec2 impeller::scene::importer::ToFBVec2 ( const Vector2  v)

Definition at line 70 of file conversions.cc.

70 {
71 return fb::Vec2(v.x, v.y);
72}

◆ ToFBVec3()

fb::Vec3 impeller::scene::importer::ToFBVec3 ( const Vector3  v)

Definition at line 74 of file conversions.cc.

74 {
75 return fb::Vec3(v.x, v.y, v.z);
76}

◆ ToFBVec4()

fb::Vec4 impeller::scene::importer::ToFBVec4 ( const Vector4  v)

Definition at line 78 of file conversions.cc.

78 {
79 return fb::Vec4(v.x, v.y, v.z, v.w);
80}

◆ ToMatrix() [1/2]

Matrix impeller::scene::importer::ToMatrix ( const fb::Matrix &  m)

Flatbuffers -> Impeller

Definition at line 26 of file conversions.cc.

26 {
27 auto& a = *m.m();
28 return Matrix(a[0], a[1], a[2], a[3], //
29 a[4], a[5], a[6], a[7], //
30 a[8], a[9], a[10], a[11], //
31 a[12], a[13], a[14], a[15]);
32}
struct MyStruct a[10]

◆ ToMatrix() [2/2]

Matrix impeller::scene::importer::ToMatrix ( const std::vector< double > &  m)

Definition at line 15 of file conversions.cc.

15 {
16 return Matrix(m[0], m[1], m[2], m[3], //
17 m[4], m[5], m[6], m[7], //
18 m[8], m[9], m[10], m[11], //
19 m[12], m[13], m[14], m[15]);
20}

◆ ToScalar()

template<typename SourceType >
static Scalar impeller::scene::importer::ToScalar ( const void *  source,
size_t  index,
bool  normalized 
)
static

Reads a numeric component from source and returns a 32bit float. If normalized is true, signed SourceTypes convert to a range of -1 to 1, and unsigned SourceTypes convert to a range of 0 to 1.

Definition at line 41 of file vertices_builder.cc.

41 {
42 const SourceType* s = reinterpret_cast<const SourceType*>(source) + index;
43 Scalar result = static_cast<Scalar>(*s);
44 if (normalized) {
45 constexpr SourceType divisor = std::is_integral_v<SourceType>
47 : 1;
48 result = static_cast<Scalar>(*s) / static_cast<Scalar>(divisor);
49 }
50 return result;
51}
GAsyncResult * result
static float max(float r, float g, float b)
Definition: hsl.cpp:49

◆ ToVector2()

Vector2 impeller::scene::importer::ToVector2 ( const fb::Vec2 &  v)

Definition at line 34 of file conversions.cc.

34 {
35 return Vector2(v.x(), v.y());
36}
Point Vector2
Definition: point.h:326

◆ ToVector3()

Vector3 impeller::scene::importer::ToVector3 ( const fb::Vec3 &  v)

Definition at line 38 of file conversions.cc.

38 {
39 return Vector3(v.x(), v.y(), v.z());
40}

◆ ToVector4()

Vector4 impeller::scene::importer::ToVector4 ( const fb::Vec4 v)

Definition at line 42 of file conversions.cc.

42 {
43 return Vector4(v.x(), v.y(), v.z(), v.w());
44}

◆ WithinRange()

static bool impeller::scene::importer::WithinRange ( int  index,
size_t  size 
)
static

Definition at line 35 of file importer_gltf.cc.

35 {
36 return index >= 0 && static_cast<size_t>(index) < size;
37}
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259

Variable Documentation

◆ kAttributes

const std::map<std::string, VerticesBuilder::AttributeType> impeller::scene::importer::kAttributes
static
Initial value:
=
{{"POSITION", VerticesBuilder::AttributeType::kPosition},
{"TANGENT", VerticesBuilder::AttributeType::kTangent},
{"TEXCOORD_0", VerticesBuilder::AttributeType::kTextureCoords},
{"JOINTS_0", VerticesBuilder::AttributeType::kJoints},
{"WEIGHTS_0", VerticesBuilder::AttributeType::kWeights}}
static constexpr SkColor kColor
Definition: CanvasTest.cpp:265
@ kNormal
Default priority level.
Definition: embedder.h:262

Definition at line 26 of file importer_gltf.cc.

◆ kComponentTypes

std::map<VerticesBuilder::ComponentType, VerticesBuilder::ComponentProperties> impeller::scene::importer::kComponentTypes
static
Initial value:
= {
{VerticesBuilder::ComponentType::kSignedByte,
{.size_bytes = sizeof(int8_t), .convert_proc = ToScalar<int8_t>}},
{.size_bytes = sizeof(int8_t), .convert_proc = ToScalar<uint8_t>}},
{VerticesBuilder::ComponentType::kSignedShort,
{.size_bytes = sizeof(int16_t), .convert_proc = ToScalar<int16_t>}},
{VerticesBuilder::ComponentType::kUnsignedShort,
{.size_bytes = sizeof(int16_t), .convert_proc = ToScalar<uint16_t>}},
{VerticesBuilder::ComponentType::kSignedInt,
{.size_bytes = sizeof(int32_t), .convert_proc = ToScalar<int32_t>}},
{VerticesBuilder::ComponentType::kUnsignedInt,
{.size_bytes = sizeof(int32_t), .convert_proc = ToScalar<uint32_t>}},
{.size_bytes = sizeof(float), .convert_proc = ToScalar<float>}},
}

Definition at line 123 of file vertices_builder.cc.

◆ kKnownSourceTypes

const std::map<std::string, SourceType> impeller::scene::importer::kKnownSourceTypes
static
Initial value:
= {
{"gltf", SourceType::kGLTF},
}

Definition at line 20 of file switches.cc.