12 #include "flutter/fml/logging.h"
19 #include "impeller/scene/importer/scene_flatbuffers.h"
32 entries_.push_back(entry);
35 std::optional<std::vector<Node::MutationLog::Entry>>
36 Node::MutationLog::Flush() {
42 auto result = entries_;
48 const fml::Mapping& ipscene_mapping,
50 flatbuffers::Verifier verifier(ipscene_mapping.GetMapping(),
51 ipscene_mapping.GetSize());
52 if (!fb::VerifySceneBuffer(verifier)) {
53 VALIDATION_LOG <<
"Failed to unpack scene: Scene flatbuffer is invalid.";
62 const fb::Texture* iptexture,
64 if (iptexture ==
nullptr || iptexture->embedded_image() ==
nullptr ||
65 iptexture->embedded_image()->bytes() ==
nullptr) {
69 auto embedded = iptexture->embedded_image();
71 uint8_t bytes_per_component = 0;
72 switch (embedded->component_type()) {
73 case fb::ComponentType::k8Bit:
74 bytes_per_component = 1;
76 case fb::ComponentType::k16Bit:
78 FML_LOG(WARNING) <<
"16 bit textures not yet supported.";
83 switch (embedded->component_count()) {
94 FML_LOG(WARNING) <<
"Textures with " << embedded->component_count()
95 <<
" components are not supported." << std::endl;
98 if (embedded->bytes()->size() != bytes_per_component *
99 embedded->component_count() *
100 embedded->width() * embedded->height()) {
101 FML_LOG(WARNING) <<
"Embedded texture has an unexpected size. Skipping."
106 auto image_mapping = std::make_shared<fml::NonOwnedMapping>(
107 embedded->bytes()->Data(), embedded->bytes()->size());
108 auto decompressed_image =
116 texture_descriptor.size = decompressed_image.GetSize();
118 texture_descriptor.mip_count = 1u;
122 FML_LOG(ERROR) <<
"Could not allocate texture.";
126 auto uploaded = texture->SetContents(decompressed_image.GetAllocation());
128 FML_LOG(ERROR) <<
"Could not upload texture to device memory.";
138 std::vector<std::shared_ptr<Texture>> textures;
139 if (scene.textures()) {
140 for (
const auto iptexture : *scene.textures()) {
148 auto result = std::make_shared<Node>();
151 if (!scene.nodes() || !scene.children()) {
156 std::vector<std::shared_ptr<Node>> scene_nodes;
157 scene_nodes.reserve(scene.nodes()->size());
158 for (
size_t node_i = 0; node_i < scene.nodes()->size(); node_i++) {
159 scene_nodes.push_back(std::make_shared<Node>());
163 for (
int child : *scene.children()) {
164 if (child < 0 ||
static_cast<size_t>(child) >= scene_nodes.size()) {
168 result->AddChild(scene_nodes[child]);
172 for (
size_t node_i = 0; node_i < scene.nodes()->size(); node_i++) {
173 scene_nodes[node_i]->UnpackFromFlatbuffer(*scene.nodes()->Get(node_i),
174 scene_nodes, textures, allocator);
178 if (scene.animations()) {
179 for (
const auto animation : *scene.animations()) {
180 if (
auto out_animation =
182 result->animations_.push_back(out_animation);
190 void Node::UnpackFromFlatbuffer(
191 const fb::Node& source_node,
192 const std::vector<std::shared_ptr<Node>>& scene_nodes,
193 const std::vector<std::shared_ptr<Texture>>& textures,
195 name_ = source_node.name()->str();
200 if (source_node.mesh_primitives()) {
202 for (
const auto* primitives : *source_node.mesh_primitives()) {
205 primitives->material()
208 mesh.
AddPrimitive({std::move(geometry), std::move(material)});
215 if (source_node.children()) {
217 for (
int child : *source_node.children()) {
218 if (child < 0 ||
static_cast<size_t>(child) >= scene_nodes.size()) {
228 if (source_node.skin()) {
254 const std::string& name,
255 bool exclude_animation_players)
const {
256 for (
auto& child : children_) {
257 if (exclude_animation_players && child->animation_player_.has_value()) {
260 if (child->GetName() == name) {
263 if (
auto found = child->FindChildByName(name)) {
271 const std::string& name)
const {
272 for (
const auto& animation : animations_) {
273 if (animation->GetName() == name) {
281 if (!animation_player_.has_value()) {
284 return animation_player_->AddAnimation(animation,
this);
288 local_transform_ = transform;
292 return local_transform_;
296 Matrix inverse_global_transform =
299 local_transform_ = inverse_global_transform * transform;
306 return local_transform_;
328 node->parent_ =
this;
329 children_.push_back(std::move(node));
339 mesh_ = std::move(mesh);
347 is_joint_ = is_joint;
356 const Matrix& parent_transform) {
357 std::optional<std::vector<MutationLog::Entry>> log = mutation_log_.Flush();
358 if (log.has_value()) {
359 for (
const auto& entry : log.value()) {
360 if (
auto e = std::get_if<MutationLog::SetTransformEntry>(&entry)) {
361 local_transform_ = e->transform;
363 std::get_if<MutationLog::SetAnimationStateEntry>(&entry)) {
365 animation_player_.has_value()
366 ? animation_player_->GetClip(e->animation_name)
384 std::get_if<MutationLog::SeekAnimationEntry>(&entry)) {
386 animation_player_.has_value()
387 ? animation_player_->GetClip(e->animation_name)
405 if (animation_player_.has_value()) {
406 animation_player_->Update();
409 Matrix transform = parent_transform * local_transform_;
410 mesh_.
Render(encoder, transform,
411 skin_ ? skin_->GetJointsTexture(allocator) :
nullptr);
413 for (
auto& child : children_) {
414 if (!child->Render(encoder, allocator, transform)) {
422 mutation_log_.
Append(entry);