| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #pragma once |
| |
| #include <memory> |
| #include <mutex> |
| #include <optional> |
| #include <vector> |
| |
| #include "flutter/fml/macros.h" |
| #include "impeller/base/thread.h" |
| #include "impeller/base/thread_safety.h" |
| #include "impeller/core/texture.h" |
| #include "impeller/geometry/matrix.h" |
| #include "impeller/renderer/render_target.h" |
| #include "impeller/scene/animation/animation.h" |
| #include "impeller/scene/animation/animation_clip.h" |
| #include "impeller/scene/animation/animation_player.h" |
| #include "impeller/scene/camera.h" |
| #include "impeller/scene/mesh.h" |
| #include "impeller/scene/scene_encoder.h" |
| #include "impeller/scene/skin.h" |
| |
| namespace impeller { |
| namespace scene { |
| |
| class Node final { |
| public: |
| class MutationLog { |
| public: |
| struct SetTransformEntry { |
| Matrix transform; |
| }; |
| |
| struct SetAnimationStateEntry { |
| std::string animation_name; |
| bool playing = false; |
| bool loop = false; |
| Scalar weight = 0; |
| Scalar time_scale = 1; |
| }; |
| |
| struct SeekAnimationEntry { |
| std::string animation_name; |
| float time = 0; |
| }; |
| |
| using Entry = std:: |
| variant<SetTransformEntry, SetAnimationStateEntry, SeekAnimationEntry>; |
| |
| void Append(const Entry& entry); |
| |
| private: |
| std::optional<std::vector<Entry>> Flush(); |
| |
| RWMutex write_mutex_; |
| bool dirty_ IPLR_GUARDED_BY(write_mutex_) = false; |
| std::vector<Entry> entries_ IPLR_GUARDED_BY(write_mutex_); |
| |
| friend Node; |
| }; |
| |
| 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); |
| |
| 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); |
| |
| private: |
| void UnpackFromFlatbuffer( |
| const fb::Node& node, |
| const std::vector<std::shared_ptr<Node>>& scene_nodes, |
| const std::vector<std::shared_ptr<Texture>>& textures, |
| Allocator& allocator); |
| |
| mutable MutationLog mutation_log_; |
| |
| Matrix local_transform_; |
| |
| std::string name_; |
| bool is_root_ = false; |
| bool is_joint_ = false; |
| Node* parent_ = nullptr; |
| std::vector<std::shared_ptr<Node>> children_; |
| Mesh mesh_; |
| |
| // For convenience purposes, deserialized nodes hang onto an animation library |
| std::vector<std::shared_ptr<Animation>> animations_; |
| mutable std::optional<AnimationPlayer> animation_player_; |
| |
| std::unique_ptr<Skin> skin_; |
| |
| FML_DISALLOW_COPY_AND_ASSIGN(Node); |
| |
| friend Scene; |
| }; |
| |
| } // namespace scene |
| } // namespace impeller |