12 #include "flutter/fml/logging.h"
20 #include "impeller/scene/importer/scene_flatbuffers.h"
33 entries_.push_back(entry);
36 std::optional<std::vector<Node::MutationLog::Entry>>
37 Node::MutationLog::Flush() {
43 auto result = entries_;
49 const fml::Mapping& ipscene_mapping,
51 flatbuffers::Verifier verifier(ipscene_mapping.GetMapping(),
52 ipscene_mapping.GetSize());
53 if (!fb::VerifySceneBuffer(verifier)) {
54 VALIDATION_LOG <<
"Failed to unpack scene: Scene flatbuffer is invalid.";
63 const fb::Texture* iptexture,
65 if (iptexture ==
nullptr || iptexture->embedded_image() ==
nullptr ||
66 iptexture->embedded_image()->bytes() ==
nullptr) {
70 auto embedded = iptexture->embedded_image();
72 uint8_t bytes_per_component = 0;
73 switch (embedded->component_type()) {
74 case fb::ComponentType::k8Bit:
75 bytes_per_component = 1;
77 case fb::ComponentType::k16Bit:
79 FML_LOG(WARNING) <<
"16 bit textures not yet supported.";
84 switch (embedded->component_count()) {
95 FML_LOG(WARNING) <<
"Textures with " << embedded->component_count()
96 <<
" components are not supported." << std::endl;
99 if (embedded->bytes()->size() != bytes_per_component *
100 embedded->component_count() *
101 embedded->width() * embedded->height()) {
102 FML_LOG(WARNING) <<
"Embedded texture has an unexpected size. Skipping."
107 auto image_mapping = std::make_shared<fml::NonOwnedMapping>(
108 embedded->bytes()->Data(), embedded->bytes()->size());
109 auto decompressed_image =
117 texture_descriptor.size = decompressed_image.GetSize();
119 texture_descriptor.mip_count = 1u;
123 FML_LOG(ERROR) <<
"Could not allocate texture.";
127 auto uploaded = texture->SetContents(decompressed_image.GetAllocation());
129 FML_LOG(ERROR) <<
"Could not upload texture to device memory.";
139 std::vector<std::shared_ptr<Texture>> textures;
140 if (scene.textures()) {
141 for (
const auto iptexture : *scene.textures()) {
149 auto result = std::make_shared<Node>();
152 if (!scene.nodes() || !scene.children()) {
157 std::vector<std::shared_ptr<Node>> scene_nodes;
158 scene_nodes.reserve(scene.nodes()->size());
159 for (
size_t node_i = 0; node_i < scene.nodes()->size(); node_i++) {
160 scene_nodes.push_back(std::make_shared<Node>());
164 for (
int child : *scene.children()) {
165 if (child < 0 ||
static_cast<size_t>(child) >= scene_nodes.size()) {
169 result->AddChild(scene_nodes[child]);
173 for (
size_t node_i = 0; node_i < scene.nodes()->size(); node_i++) {
174 scene_nodes[node_i]->UnpackFromFlatbuffer(*scene.nodes()->Get(node_i),
175 scene_nodes, textures, allocator);
179 if (scene.animations()) {
180 for (
const auto animation : *scene.animations()) {
181 if (
auto out_animation =
183 result->animations_.push_back(out_animation);
191 void Node::UnpackFromFlatbuffer(
192 const fb::Node& source_node,
193 const std::vector<std::shared_ptr<Node>>& scene_nodes,
194 const std::vector<std::shared_ptr<Texture>>& textures,
196 name_ = source_node.name()->str();
201 if (source_node.mesh_primitives()) {
203 for (
const auto* primitives : *source_node.mesh_primitives()) {
206 primitives->material()
209 mesh.
AddPrimitive({std::move(geometry), std::move(material)});
216 if (source_node.children()) {
218 for (
int child : *source_node.children()) {
219 if (child < 0 ||
static_cast<size_t>(child) >= scene_nodes.size()) {
229 if (source_node.skin()) {
255 const std::string& name,
256 bool exclude_animation_players)
const {
257 for (
auto& child : children_) {
258 if (exclude_animation_players && child->animation_player_.has_value()) {
261 if (child->GetName() == name) {
264 if (
auto found = child->FindChildByName(name)) {
272 const std::string& name)
const {
273 for (
const auto& animation : animations_) {
274 if (animation->GetName() == name) {
282 if (!animation_player_.has_value()) {
285 return animation_player_->AddAnimation(animation,
this);
289 local_transform_ = transform;
293 return local_transform_;
297 Matrix inverse_global_transform =
300 local_transform_ = inverse_global_transform * transform;
307 return local_transform_;
329 node->parent_ =
this;
330 children_.push_back(std::move(node));
340 mesh_ = std::move(mesh);
348 is_joint_ = is_joint;
357 const Matrix& parent_transform) {
358 std::optional<std::vector<MutationLog::Entry>> log = mutation_log_.Flush();
359 if (log.has_value()) {
360 for (
const auto& entry : log.value()) {
361 if (
auto e = std::get_if<MutationLog::SetTransformEntry>(&entry)) {
362 local_transform_ = e->transform;
364 std::get_if<MutationLog::SetAnimationStateEntry>(&entry)) {
366 animation_player_.has_value()
367 ? animation_player_->GetClip(e->animation_name)
385 std::get_if<MutationLog::SeekAnimationEntry>(&entry)) {
387 animation_player_.has_value()
388 ? animation_player_->GetClip(e->animation_name)
406 if (animation_player_.has_value()) {
407 animation_player_->Update();
410 Matrix transform = parent_transform * local_transform_;
411 mesh_.
Render(encoder, transform,
412 skin_ ? skin_->GetJointsTexture(allocator) :
nullptr);
414 for (
auto& child : children_) {
415 if (!child->Render(encoder, allocator, transform)) {
423 mutation_log_.
Append(entry);