Flutter Impeller
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)
 
NodeGetParent () const
 
std::shared_ptr< NodeFindChildByName (const std::string &name, bool exclude_animation_players=false) const
 
std::shared_ptr< AnimationFindAnimationByName (const std::string &name) const
 
AnimationClipAddAnimation (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)
 
MeshGetMesh ()
 
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< NodeMakeFromFlatbuffer (const fml::Mapping &ipscene_mapping, Allocator &allocator)
 
static std::shared_ptr< NodeMakeFromFlatbuffer (const fb::Scene &scene, Allocator &allocator)
 

Detailed Description

Definition at line 30 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(), textures, 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(), and impeller::scene::AnimationClip::SetWeight().

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(), and impeller::Matrix::Invert().

◆ 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 }

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::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
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
textures
std::vector< std::shared_ptr< FakeTexture > > textures
Definition: content_context_unittests.cc:92
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