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.";
82 switch (embedded->component_count()) {
89 FML_LOG(WARNING) <<
"Textures with " << embedded->component_count()
90 <<
" components are not supported." << std::endl;
93 if (embedded->bytes()->size() != bytes_per_component *
94 embedded->component_count() *
95 embedded->width() * embedded->height()) {
96 FML_LOG(WARNING) <<
"Embedded texture has an unexpected size. Skipping."
101 auto image_mapping = std::make_shared<fml::NonOwnedMapping>(
102 embedded->bytes()->Data(), embedded->bytes()->size());
107 texture_descriptor.size =
ISize(embedded->width(), embedded->height());
109 texture_descriptor.mip_count = 1u;
113 FML_LOG(ERROR) <<
"Could not allocate texture.";
117 auto uploaded = texture->SetContents(image_mapping);
119 FML_LOG(ERROR) <<
"Could not upload texture to device memory.";
129 std::vector<std::shared_ptr<Texture>>
textures;
130 if (scene.textures()) {
131 for (
const auto iptexture : *scene.textures()) {
139 auto result = std::make_shared<Node>();
142 if (!scene.nodes() || !scene.children()) {
147 std::vector<std::shared_ptr<Node>> scene_nodes;
148 scene_nodes.reserve(scene.nodes()->size());
149 for (
size_t node_i = 0; node_i < scene.nodes()->size(); node_i++) {
150 scene_nodes.push_back(std::make_shared<Node>());
154 for (
int child : *scene.children()) {
155 if (child < 0 ||
static_cast<size_t>(child) >= scene_nodes.size()) {
159 result->AddChild(scene_nodes[child]);
163 for (
size_t node_i = 0; node_i < scene.nodes()->size(); node_i++) {
164 scene_nodes[node_i]->UnpackFromFlatbuffer(*scene.nodes()->Get(node_i),
169 if (scene.animations()) {
170 for (
const auto animation : *scene.animations()) {
171 if (
auto out_animation =
173 result->animations_.push_back(out_animation);
181 void Node::UnpackFromFlatbuffer(
182 const fb::Node& source_node,
183 const std::vector<std::shared_ptr<Node>>& scene_nodes,
184 const std::vector<std::shared_ptr<Texture>>&
textures,
186 name_ = source_node.name()->str();
191 if (source_node.mesh_primitives()) {
193 for (
const auto* primitives : *source_node.mesh_primitives()) {
196 primitives->material()
199 mesh.
AddPrimitive({std::move(geometry), std::move(material)});
206 if (source_node.children()) {
208 for (
int child : *source_node.children()) {
209 if (child < 0 ||
static_cast<size_t>(child) >= scene_nodes.size()) {
219 if (source_node.skin()) {
245 const std::string& name,
246 bool exclude_animation_players)
const {
247 for (
auto& child : children_) {
248 if (exclude_animation_players && child->animation_player_.has_value()) {
251 if (child->GetName() == name) {
254 if (
auto found = child->FindChildByName(name)) {
262 const std::string& name)
const {
263 for (
const auto& animation : animations_) {
264 if (animation->GetName() == name) {
272 if (!animation_player_.has_value()) {
275 return animation_player_->AddAnimation(animation,
this);
279 local_transform_ = transform;
283 return local_transform_;
287 Matrix inverse_global_transform =
290 local_transform_ = inverse_global_transform * transform;
297 return local_transform_;
319 node->parent_ =
this;
320 children_.push_back(std::move(node));
330 mesh_ = std::move(mesh);
338 is_joint_ = is_joint;
347 const Matrix& parent_transform) {
348 std::optional<std::vector<MutationLog::Entry>> log = mutation_log_.Flush();
349 if (log.has_value()) {
350 for (
const auto& entry : log.value()) {
351 if (
auto e = std::get_if<MutationLog::SetTransformEntry>(&entry)) {
352 local_transform_ = e->transform;
354 std::get_if<MutationLog::SetAnimationStateEntry>(&entry)) {
356 animation_player_.has_value()
357 ? animation_player_->GetClip(e->animation_name)
375 std::get_if<MutationLog::SeekAnimationEntry>(&entry)) {
377 animation_player_.has_value()
378 ? animation_player_->GetClip(e->animation_name)
396 if (animation_player_.has_value()) {
397 animation_player_->Update();
400 Matrix transform = parent_transform * local_transform_;
401 mesh_.
Render(encoder, transform,
402 skin_ ? skin_->GetJointsTexture(allocator) :
nullptr);
404 for (
auto& child : children_) {
405 if (!child->Render(encoder, allocator, transform)) {
413 mutation_log_.
Append(entry);