| Flutter Impeller |

Classes | Public Member Functions | Static Public Member Functions | List of all members
impeller::scene::Node Class Referencefinal

`#include <node.h>`

## Classes
class | MutationLog

## Public Member Functions
| Node ()
| ~Node ()
const std::string & | GetName () const
void | SetName (const std::string &new_name)
Node * | GetParent () const
std::shared_ptr< Node > | FindChildByName (const std::string &name, bool exclude_animation_players=false) const
std::shared_ptr< Animation > | FindAnimationByName (const std::string &name) const
AnimationClip * | AddAnimation (const std::shared_ptr< Animation > &animation)
void | SetLocalTransform (Matrix transform)
Matrix | GetLocalTransform () const
void | SetGlobalTransform (Matrix transform)
Matrix | GetGlobalTransform () const
bool | AddChild (std::shared_ptr< Node > child)
std::vector< std::shared_ptr< Node > > & | GetChildren ()
void | SetMesh (Mesh mesh)
Mesh & | GetMesh ()
void | SetIsJoint (bool is_joint)
bool | IsJoint () const
bool | Render (SceneEncoder &encoder, Allocator &allocator, const Matrix &parent_transform)
void | AddMutation (const MutationLog::Entry &entry)

## Static Public Member Functions
static std::shared_ptr< Node > | MakeFromFlatbuffer (const fml::Mapping &ipscene_mapping, Allocator &allocator)
static std::shared_ptr< Node > | MakeFromFlatbuffer (const fb::Scene &scene, Allocator &allocator)

## Detailed Description

Definition at line 26 of file node.h.

## Constructor & Destructor Documentation

## ◆ Node()

impeller::scene::Node::Node | ( |  | ) |

Definition at line 224 of file node.cc.

224 : name_(SPrintF("__node%" PRIu64, kNextNodeID++)){};

## ◆ ~Node()

impeller::scene::Node::~Node | ( |  | ) |
| default

## Member Function Documentation

## ◆ AddAnimation()

AnimationClip * impeller::scene::Node::AddAnimation | ( | const std::shared_ptr< Animation > & | animation | ) |

Definition at line 271 of file node.cc.

271 {
272 if (!animation_player_.has_value()) {
273 animation_player_ = AnimationPlayer();
274 }
275 return animation_player_->AddAnimation(animation, this);
276 }

Referenced by Render().

## ◆ AddChild()

bool impeller::scene::Node::AddChild | ( | std::shared_ptr< Node > | child | ) |

Definition at line 300 of file node.cc.

300 {
301 if (!node) {
302 VALIDATION_LOG << "Cannot add null child to node.";
303 return false;
304 }
305
306 // TODO(bdero): Figure out a better paradigm/rules for nodes with multiple
307 // parents. We should probably disallow this, make deep
308 // copying of nodes cheap and easy, add mesh instancing, etc.
309 // Today, the parent link is only used for skin posing, and so
310 // it's reasonable to not have a check and allow multi-parenting.
311 // Even still, there should still be some kind of cycle
312 // prevention/detection, ideally at the protocol level.
313 //
314 // if (node->parent_ != nullptr) {
315 // VALIDATION_LOG
316 // << "Cannot add a node as a child which already has a parent.";
317 // return false;
318 // }
319 node->parent_ = this;
320 children_.push_back(std::move(node));
321
322 return true;
323 }

References VALIDATION_LOG.

Referenced by impeller::SceneContents::Render().

## ◆ AddMutation()

void impeller::scene::Node::AddMutation | ( | const MutationLog::Entry & | entry | ) |

Definition at line 412 of file node.cc.

412 {
413 mutation_log_.Append(entry);
414 }

References impeller::scene::Node::MutationLog::Append().

## ◆ FindAnimationByName()

std::shared_ptr< Animation > impeller::scene::Node::FindAnimationByName | ( | const std::string & | name | ) | const

Definition at line 261 of file node.cc.

262 {
263 for (const auto& animation : animations_) {
264 if (animation->GetName() == name) {
265 return animation;
266 }
267 }
268 return nullptr;
269 }

Referenced by Render().

## ◆ FindChildByName()

std::shared_ptr< Node > impeller::scene::Node::FindChildByName | ( | const std::string & | name,
|  | bool | exclude_animation_players = `false`
| ) |  | const

Definition at line 244 of file node.cc.

246 {
247 for (auto& child : children_) {
248 if (exclude_animation_players && child->animation_player_.has_value()) {
249 continue;
250 }
251 if (child->GetName() == name) {
252 return child;
253 }
254 if (auto found = child->FindChildByName(name)) {
255 return found;
256 }
257 }
258 return nullptr;
259 }

## ◆ GetChildren()

std::vector< std::shared_ptr< Node > > & impeller::scene::Node::GetChildren | ( |  | ) |

Definition at line 325 of file node.cc.

325 {
326 return children_;
327 }

Referenced by impeller::scene::testing::TEST_P().

## ◆ GetGlobalTransform()

Matrix impeller::scene::Node::GetGlobalTransform | ( |  | ) | const

Definition at line 293 of file node.cc.

293 {
294 if (parent_) {
295 return parent_->GetGlobalTransform() * local_transform_;
296 }
297 return local_transform_;
298 }

References GetGlobalTransform().

Referenced by GetGlobalTransform(), and SetGlobalTransform().

## ◆ GetLocalTransform()

Matrix impeller::scene::Node::GetLocalTransform | ( |  | ) | const

Definition at line 282 of file node.cc.

282 {
283 return local_transform_;
284 }

Referenced by impeller::scene::Skin::GetJointsTexture(), and impeller::scene::testing::TEST_P().

## ◆ GetMesh()

Mesh & impeller::scene::Node::GetMesh | ( |  | ) |

Definition at line 333 of file node.cc.

333 {
334 return mesh_;
335 }

## ◆ GetName()

const std::string & impeller::scene::Node::GetName | ( |  | ) | const

Definition at line 232 of file node.cc.

232 {
233 return name_;
234 }

## ◆ GetParent()

Node * impeller::scene::Node::GetParent | ( |  | ) | const

Definition at line 240 of file node.cc.

240 {
241 return parent_;
242 }

Referenced by impeller::scene::Skin::GetJointsTexture().

## ◆ IsJoint()

bool impeller::scene::Node::IsJoint | ( |  | ) | const

Definition at line 341 of file node.cc.

341 {
342 return is_joint_;
343 }

Referenced by impeller::scene::Skin::GetJointsTexture().

## ◆ MakeFromFlatbuffer() [1/2]

std::shared_ptr< Node > impeller::scene::Node::MakeFromFlatbuffer | ( | const fb::Scene & | scene,
|  | Allocator & | allocator
| ) |  |
| static

Definition at line 126 of file node.cc.

127 {
128 // Unpack textures.
129 std::vector<std::shared_ptr<Texture>> textures;
130 if (scene.textures()) {
131 for (const auto iptexture : *scene.textures()) {
132 // The elements of the unpacked texture array must correspond exactly with
133 // the ipscene texture array. So if a texture is empty or invalid, a
134 // nullptr is inserted as a placeholder.
135 textures.push_back(UnpackTextureFromFlatbuffer(iptexture, allocator));
136 }
137 }
138
139 auto result = std::make_shared<Node>();
140 result->SetLocalTransform(importer::ToMatrix(*scene.transform()));
141
142 if (!scene.nodes() || !scene.children()) {
143 return result; // The scene is empty.
144 }
145
146 // Initialize nodes for unpacking the entire scene.
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>());
151 }
152
153 // Connect children to the root node.
154 for (int child : *scene.children()) {
155 if (child < 0 || static_cast<size_t>(child) >= scene_nodes.size()) {
156 VALIDATION_LOG << "Scene child index out of range.";
157 continue;
158 }
159 result->AddChild(scene_nodes[child]);
160 }
161
162 // Unpack each node.
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),
165 scene_nodes, textures, allocator);
166 }
167
168 // Unpack animations.
169 if (scene.animations()) {
170 for (const auto animation : *scene.animations()) {
171 if (auto out_animation =
172 Animation::MakeFromFlatbuffer(*animation, scene_nodes)) {
173 result->animations_.push_back(out_animation);
174 }
175 }
176 }
177
178 return result;
179 }

References impeller::scene::Animation::MakeFromFlatbuffer(), impeller::scene::importer::ToMatrix(), impeller::scene::UnpackTextureFromFlatbuffer(), and VALIDATION_LOG.

## ◆ MakeFromFlatbuffer() [2/2]

std::shared_ptr< Node > impeller::scene::Node::MakeFromFlatbuffer | ( | const fml::Mapping & | ipscene_mapping,
|  | Allocator & | allocator
| ) |  |
| static

Definition at line 47 of file node.cc.

49 {
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.";
54 return nullptr;
55 }
56
57 return Node::MakeFromFlatbuffer(*fb::GetScene(ipscene_mapping.GetMapping()),
58 allocator);
59 }

References VALIDATION_LOG.

Referenced by impeller::scene::testing::TEST_P().

## ◆ Render()

bool impeller::scene::Node::Render | ( | SceneEncoder & | encoder,
|  | Allocator & | allocator,
|  | const Matrix & | parent_transform
| ) |  |

Definition at line 345 of file node.cc.

347 {
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;
353 } else if (auto e =
354 std::get_if<MutationLog::SetAnimationStateEntry>(&entry)) {
355 AnimationClip* clip =
356 animation_player_.has_value()
357 ? animation_player_->GetClip(e->animation_name)
358 : nullptr;
359 if (!clip) {
360 auto animation = FindAnimationByName(e->animation_name);
361 if (!animation) {
362 continue;
363 }
364 clip = AddAnimation(animation);
365 if (!clip) {
366 continue;
367 }
368 }
369
370 clip->SetPlaying(e->playing);
371 clip->SetLoop(e->loop);
372 clip->SetWeight(e->weight);
373 clip->SetPlaybackTimeScale(e->time_scale);
374 } else if (auto e =
375 std::get_if<MutationLog::SeekAnimationEntry>(&entry)) {
376 AnimationClip* clip =
377 animation_player_.has_value()
378 ? animation_player_->GetClip(e->animation_name)
379 : nullptr;
380 if (!clip) {
381 auto animation = FindAnimationByName(e->animation_name);
382 if (!animation) {
383 continue;
384 }
385 clip = AddAnimation(animation);
386 if (!clip) {
387 continue;
388 }
389 }
390
391 clip->Seek(SecondsF(e->time));
392 }
393 }
394 }
395
396 if (animation_player_.has_value()) {
397 animation_player_->Update();
398 }
399
400 Matrix transform = parent_transform * local_transform_;
401 mesh_.Render(encoder, transform,
402 skin_ ? skin_->GetJointsTexture(allocator) : nullptr);
403
404 for (auto& child : children_) {
405 if (!child->Render(encoder, allocator, transform)) {
406 return false;
407 }
408 }
409 return true;
410 }

References AddAnimation(), FindAnimationByName(), impeller::scene::Mesh::Render(), impeller::scene::AnimationClip::Seek(), impeller::scene::AnimationClip::SetLoop(), impeller::scene::AnimationClip::SetPlaybackTimeScale(), impeller::scene::AnimationClip::SetPlaying(), impeller::scene::AnimationClip::SetWeight(), and transform.

Referenced by impeller::scene::Scene::Render().

## ◆ SetGlobalTransform()

void impeller::scene::Node::SetGlobalTransform | ( | Matrix | transform | ) |

Definition at line 286 of file node.cc.

286 {
287 Matrix inverse_global_transform =
288 parent_ ? parent_->GetGlobalTransform().Invert() : Matrix();
289
290 local_transform_ = inverse_global_transform * transform;
291 }

References GetGlobalTransform(), impeller::Matrix::Invert(), and transform.

## ◆ SetIsJoint()

void impeller::scene::Node::SetIsJoint | ( | bool | is_joint | ) |

Definition at line 337 of file node.cc.

337 {
338 is_joint_ = is_joint;
339 }

## ◆ SetLocalTransform()

void impeller::scene::Node::SetLocalTransform | ( | Matrix | transform | ) |

Definition at line 278 of file node.cc.

278 {
279 local_transform_ = transform;
280 }

References transform.

Referenced by impeller::scene::testing::TEST_P().

## ◆ SetMesh()

void impeller::scene::Node::SetMesh | ( | Mesh | mesh | ) |

Definition at line 329 of file node.cc.

329 {
330 mesh_ = std::move(mesh);
331 }

Referenced by impeller::scene::testing::TEST_P().

## ◆ SetName()

void impeller::scene::Node::SetName | ( | const std::string & | new_name | ) |

Definition at line 236 of file node.cc.

236 {
237 name_ = new_name;
238 }

The documentation for this class was generated from the following files:

- impeller/scene/node.h
- impeller/scene/node.cc

impeller::scene::Animation::MakeFromFlatbuffer
static std::shared_ptr< Animation > MakeFromFlatbuffer(const fb::Animation &animation, const std::vector< std::shared_ptr< Node >> &scene_nodes)
Definition: animation.cc:19
impeller::scene::Mesh::Render
bool Render(SceneEncoder &encoder, const Matrix &transform, const std::shared_ptr< Texture > &joints) const
Definition: mesh.cc:36
impeller::SecondsF
std::chrono::duration< float > SecondsF
Definition: timing.h:13
impeller::scene::Node::FindAnimationByName
std::shared_ptr< Animation > FindAnimationByName(const std::string &name) const
Definition: node.cc:261
impeller::SPrintF
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:231
impeller::scene::UnpackTextureFromFlatbuffer
static std::shared_ptr< Texture > UnpackTextureFromFlatbuffer(const fb::Texture *iptexture, Allocator &allocator)
Definition: node.cc:61
impeller::scene::kNextNodeID
static std::atomic_uint64_t kNextNodeID
Definition: node.cc:27
impeller::Matrix::Invert
Matrix Invert() const
Definition: matrix.cc:97
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:73
impeller::scene::Node::AddAnimation
AnimationClip * AddAnimation(const std::shared_ptr< Animation > &animation)
Definition: node.cc:271
impeller::scene::Node::MakeFromFlatbuffer
static std::shared_ptr< Node > MakeFromFlatbuffer(const fml::Mapping &ipscene_mapping, Allocator &allocator)
Definition: node.cc:47
impeller::scene::Node::MutationLog::Append
void Append(const Entry &entry)
Definition: node.cc:29
impeller::scene::Node::GetGlobalTransform
Matrix GetGlobalTransform() const
Definition: node.cc:293
impeller::scene::importer::ToMatrix
Matrix ToMatrix(const std::vector< double > &m)
Definition: conversions.cc:15