12#include "flutter/fml/logging.h"
19#include "impeller/scene/importer/scene_flatbuffers.h"
32 entries_.push_back(entry);
35std::optional<std::vector<Node::MutationLog::Entry>>
36Node::MutationLog::Flush() {
50 flatbuffers::Verifier verifier(ipscene_mapping.
GetMapping(),
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;
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);
181void 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);
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)
370 clip->SetPlaying(e->playing);
371 clip->SetLoop(e->loop);
372 clip->SetWeight(e->weight);
373 clip->SetPlaybackTimeScale(e->time_scale);
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();
402 skin_ ? skin_->GetJointsTexture(allocator) :
nullptr);
404 for (
auto& child : children_) {
413 mutation_log_.
Append(entry);
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
virtual const uint8_t * GetMapping() const =0
virtual size_t GetSize() const =0
An object that allocates device memory.
std::shared_ptr< Texture > CreateTexture(const TextureDescriptor &desc)
static std::shared_ptr< Animation > MakeFromFlatbuffer(const fb::Animation &animation, const std::vector< std::shared_ptr< Node > > &scene_nodes)
static std::shared_ptr< Geometry > MakeFromFlatbuffer(const fb::MeshPrimitive &mesh, Allocator &allocator)
static std::unique_ptr< Material > MakeFromFlatbuffer(const fb::Material &material, const std::vector< std::shared_ptr< Texture > > &textures)
bool Render(SceneEncoder &encoder, const Matrix &transform, const std::shared_ptr< Texture > &joints) const
Mesh & operator=(Mesh &&mesh)
std::variant< SetTransformEntry, SetAnimationStateEntry, SeekAnimationEntry > Entry
void Append(const Entry &entry)
void SetIsJoint(bool is_joint)
bool AddChild(std::shared_ptr< Node > child)
void SetLocalTransform(Matrix transform)
void SetGlobalTransform(Matrix transform)
std::shared_ptr< Animation > FindAnimationByName(const std::string &name) const
Matrix GetGlobalTransform() const
AnimationClip * AddAnimation(const std::shared_ptr< Animation > &animation)
void AddMutation(const MutationLog::Entry &entry)
bool Render(SceneEncoder &encoder, Allocator &allocator, const Matrix &parent_transform)
const std::string & GetName() const
void SetName(const std::string &new_name)
std::shared_ptr< Node > FindChildByName(const std::string &name, bool exclude_animation_players=false) const
std::vector< std::shared_ptr< Node > > & GetChildren()
Matrix GetLocalTransform() const
static std::shared_ptr< Node > MakeFromFlatbuffer(const fml::Mapping &ipscene_mapping, Allocator &allocator)
static std::unique_ptr< Skin > MakeFromFlatbuffer(const fb::Skin &skin, const std::vector< std::shared_ptr< Node > > &scene_nodes)
std::vector< std::shared_ptr< FakeTexture > > textures
#define FML_LOG(severity)
Matrix ToMatrix(const std::vector< double > &m)
static std::shared_ptr< Texture > UnpackTextureFromFlatbuffer(const fb::Texture *iptexture, Allocator &allocator)
static std::atomic_uint64_t kNextNodeID
std::string SPrintF(const char *format,...)
std::chrono::duration< float > SecondsF
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
A 4x4 matrix using column-major storage.
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...