From f28d200fc005da9595035478e4fd8f2719fe8e43 Mon Sep 17 00:00:00 2001 From: Kevin Chisholm Date: Fri, 13 Jan 2023 09:05:32 -0600 Subject: [PATCH] Revert "[Impeller Scene] Change how property resolution works to fix Animation blending; add mutation log to nodes; enable backface culling; add vertex color contribution back to meshes (#38766)" This reverts commit 2b024cbb62fd4aa349d21d2ee8a86525bcefb508. --- ci/licenses_golden/licenses_flutter | 2 - impeller/geometry/quaternion.h | 2 - impeller/scene/BUILD.gn | 1 - impeller/scene/animation/animation_clip.cc | 13 +- impeller/scene/animation/animation_clip.h | 5 +- impeller/scene/animation/animation_player.cc | 57 +++----- impeller/scene/animation/animation_player.h | 14 +- .../scene/animation/animation_transforms.h | 18 --- impeller/scene/animation/property_resolver.cc | 25 ++-- impeller/scene/animation/property_resolver.h | 18 +-- impeller/scene/geometry.cc | 2 +- impeller/scene/material.cc | 2 + impeller/scene/node.cc | 81 +---------- impeller/scene/node.h | 45 +------ impeller/scene/scene.cc | 5 +- impeller/scene/scene.h | 4 +- impeller/scene/scene_context.cc | 3 - impeller/scene/scene_unittests.cc | 126 ++---------------- impeller/scene/skin.cc | 14 +- lib/ui/experiments/scene.dart | 37 +++-- lib/ui/painting/scene/scene_node.cc | 34 ++--- lib/ui/painting/scene/scene_node.h | 1 - 22 files changed, 93 insertions(+), 416 deletions(-) delete mode 100644 impeller/scene/animation/animation_transforms.h diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 809ebb4c30865..baecaa91972f5 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1641,7 +1641,6 @@ ORIGIN: ../../../flutter/impeller/scene/animation/animation_clip.cc + ../../../f ORIGIN: ../../../flutter/impeller/scene/animation/animation_clip.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/scene/animation/animation_player.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/scene/animation/animation_player.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/scene/animation/animation_transforms.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/scene/animation/property_resolver.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/scene/animation/property_resolver.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/scene/camera.cc + ../../../flutter/LICENSE @@ -4122,7 +4121,6 @@ FILE: ../../../flutter/impeller/scene/animation/animation_clip.cc FILE: ../../../flutter/impeller/scene/animation/animation_clip.h FILE: ../../../flutter/impeller/scene/animation/animation_player.cc FILE: ../../../flutter/impeller/scene/animation/animation_player.h -FILE: ../../../flutter/impeller/scene/animation/animation_transforms.h FILE: ../../../flutter/impeller/scene/animation/property_resolver.cc FILE: ../../../flutter/impeller/scene/animation/property_resolver.h FILE: ../../../flutter/impeller/scene/camera.cc diff --git a/impeller/geometry/quaternion.h b/impeller/geometry/quaternion.h index 0dacf0428fa43..0270dab9dc814 100644 --- a/impeller/geometry/quaternion.h +++ b/impeller/geometry/quaternion.h @@ -45,8 +45,6 @@ struct Quaternion { return {x * m, y * m, z * m, w * m}; } - Quaternion Invert() const { return {-x, -y, -z, w}; } - Quaternion Slerp(const Quaternion& to, double time) const; Quaternion operator*(const Quaternion& o) const { diff --git a/impeller/scene/BUILD.gn b/impeller/scene/BUILD.gn index d937166b1ff21..dbd531cf8e17d 100644 --- a/impeller/scene/BUILD.gn +++ b/impeller/scene/BUILD.gn @@ -12,7 +12,6 @@ impeller_component("scene") { "animation/animation_clip.h", "animation/animation_player.cc", "animation/animation_player.h", - "animation/animation_transforms.h", "animation/property_resolver.cc", "animation/property_resolver.h", "camera.cc", diff --git a/impeller/scene/animation/animation_clip.cc b/impeller/scene/animation/animation_clip.cc index 4a03bf58ba5b5..10019e8f52bd1 100644 --- a/impeller/scene/animation/animation_clip.cc +++ b/impeller/scene/animation/animation_clip.cc @@ -67,7 +67,7 @@ Scalar AnimationClip::GetWeight() const { } void AnimationClip::SetWeight(Scalar weight) { - weight_ = std::max(0.0f, weight); + weight_ = weight; } SecondsF AnimationClip::GetPlaybackTime() const { @@ -110,16 +110,9 @@ void AnimationClip::Advance(SecondsF delta_time) { } } -void AnimationClip::ApplyToBindings( - std::unordered_map& transform_decomps, - Scalar weight_multiplier) const { +void AnimationClip::ApplyToBindings() const { for (auto& binding : bindings_) { - auto transforms = transform_decomps.find(binding.node); - if (transforms == transform_decomps.end()) { - continue; - } - binding.channel.resolver->Apply(transforms->second, playback_time_, - weight_ * weight_multiplier); + binding.channel.resolver->Apply(*binding.node, playback_time_, weight_); } } diff --git a/impeller/scene/animation/animation_clip.h b/impeller/scene/animation/animation_clip.h index 8fe150e2061ca..cf584ae64620a 100644 --- a/impeller/scene/animation/animation_clip.h +++ b/impeller/scene/animation/animation_clip.h @@ -9,7 +9,6 @@ #include "flutter/fml/macros.h" #include "impeller/scene/animation/animation.h" -#include "impeller/scene/animation/animation_transforms.h" namespace impeller { namespace scene { @@ -61,9 +60,7 @@ class AnimationClip final { void Advance(SecondsF delta_time); /// @brief Applies the animation to all binded properties in the scene. - void ApplyToBindings( - std::unordered_map& transform_decomps, - Scalar weight_multiplier) const; + void ApplyToBindings() const; private: void BindToTarget(Node* node); diff --git a/impeller/scene/animation/animation_player.cc b/impeller/scene/animation/animation_player.cc index 9fcf53306879f..01119fb521f61 100644 --- a/impeller/scene/animation/animation_player.cc +++ b/impeller/scene/animation/animation_player.cc @@ -5,7 +5,6 @@ #include "impeller/scene/animation/animation_player.h" #include -#include #include "flutter/fml/time/time_point.h" #include "impeller/base/timing.h" @@ -20,37 +19,20 @@ AnimationPlayer::~AnimationPlayer() = default; AnimationPlayer::AnimationPlayer(AnimationPlayer&&) = default; AnimationPlayer& AnimationPlayer::operator=(AnimationPlayer&&) = default; -AnimationClip* AnimationPlayer::AddAnimation( - const std::shared_ptr& animation, +AnimationClip& AnimationPlayer::AddAnimation( + std::shared_ptr animation, Node* bind_target) { - if (!animation) { - VALIDATION_LOG << "Cannot add null animation."; - return nullptr; - } - - AnimationClip clip(animation, bind_target); + AnimationClip clip(std::move(animation), bind_target); // Record all of the unique default transforms that this AnimationClip // will mutate. for (const auto& binding : clip.bindings_) { - auto decomp = binding.node->GetLocalTransform().Decompose(); - if (!decomp.has_value()) { - continue; - } - target_transforms_.insert( - {binding.node, AnimationTransforms{.bind_pose = decomp.value()}}); + default_target_transforms_.insert( + {binding.node, binding.node->GetLocalTransform()}); } - auto result = clips_.insert({animation->GetName(), std::move(clip)}); - return &result.first->second; -} - -AnimationClip* AnimationPlayer::GetClip(const std::string& name) const { - auto result = clips_.find(name); - if (result == clips_.end()) { - return nullptr; - } - return const_cast(&result->second); + clips_.push_back(std::move(clip)); + return clips_.back(); } void AnimationPlayer::Update() { @@ -61,27 +43,18 @@ void AnimationPlayer::Update() { auto delta_time = new_time - previous_time_.value(); previous_time_ = new_time; - // Reset the animated pose state. - for (auto& [node, transforms] : target_transforms_) { - transforms.animated_pose = transforms.bind_pose; - } - - // Compute a weight multiplier for normalizing the animation. - Scalar total_weight = 0; - for (auto& [_, clip] : clips_) { - total_weight += clip.GetWeight(); - } - Scalar weight_multiplier = total_weight > 1 ? 1 / total_weight : 1; + Reset(); - // Update and apply all clips to the animation pose state. - for (auto& [_, clip] : clips_) { + // Update and apply all clips. + for (auto& clip : clips_) { clip.Advance(delta_time); - clip.ApplyToBindings(target_transforms_, weight_multiplier); + clip.ApplyToBindings(); } +} - // Apply the animated pose to the bound joints. - for (auto& [node, transforms] : target_transforms_) { - node->SetLocalTransform(Matrix(transforms.animated_pose)); +void AnimationPlayer::Reset() { + for (auto& [node, transform] : default_target_transforms_) { + node->SetLocalTransform(Matrix()); } } diff --git a/impeller/scene/animation/animation_player.h b/impeller/scene/animation/animation_player.h index bcbb678d4c619..23c7336aed371 100644 --- a/impeller/scene/animation/animation_player.h +++ b/impeller/scene/animation/animation_player.h @@ -4,9 +4,9 @@ #pragma once -#include #include #include +#include #include #include "flutter/fml/hash_combine.h" @@ -14,7 +14,6 @@ #include "flutter/fml/time/time_delta.h" #include "impeller/base/timing.h" #include "impeller/geometry/matrix.h" -#include "impeller/geometry/matrix_decomposition.h" #include "impeller/scene/animation/animation_clip.h" namespace impeller { @@ -30,18 +29,19 @@ class AnimationPlayer final { AnimationPlayer(AnimationPlayer&&); AnimationPlayer& operator=(AnimationPlayer&&); - AnimationClip* AddAnimation(const std::shared_ptr& animation, + AnimationClip& AddAnimation(std::shared_ptr animation, Node* bind_target); - AnimationClip* GetClip(const std::string& name) const; - /// @brief Advanced all clips and updates animated properties in the scene. void Update(); + /// @brief Reset all bound animation target transforms. + void Reset(); + private: - std::unordered_map target_transforms_; + std::unordered_map default_target_transforms_; - std::map clips_; + std::vector clips_; std::optional previous_time_; diff --git a/impeller/scene/animation/animation_transforms.h b/impeller/scene/animation/animation_transforms.h deleted file mode 100644 index b15c9817781d4..0000000000000 --- a/impeller/scene/animation/animation_transforms.h +++ /dev/null @@ -1,18 +0,0 @@ -// 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 "impeller/geometry/matrix_decomposition.h" - -namespace impeller { -namespace scene { - -struct AnimationTransforms { - MatrixDecomposition bind_pose; - MatrixDecomposition animated_pose; -}; - -} // namespace scene -} // namespace impeller diff --git a/impeller/scene/animation/property_resolver.cc b/impeller/scene/animation/property_resolver.cc index a43a308efdb75..d9d5db94e44e6 100644 --- a/impeller/scene/animation/property_resolver.cc +++ b/impeller/scene/animation/property_resolver.cc @@ -8,7 +8,6 @@ #include #include -#include "impeller/geometry/matrix_decomposition.h" #include "impeller/geometry/point.h" #include "impeller/scene/node.h" @@ -79,7 +78,7 @@ TranslationTimelineResolver::TranslationTimelineResolver() = default; TranslationTimelineResolver::~TranslationTimelineResolver() = default; -void TranslationTimelineResolver::Apply(AnimationTransforms& target, +void TranslationTimelineResolver::Apply(Node& target, SecondsF time, Scalar weight) { if (values_.empty()) { @@ -90,16 +89,15 @@ void TranslationTimelineResolver::Apply(AnimationTransforms& target, if (key.lerp < 1) { value = values_[key.index - 1].Lerp(value, key.lerp); } - - target.animated_pose.translation += - (value - target.bind_pose.translation) * weight; + target.SetLocalTransform(target.GetLocalTransform() * + Matrix::MakeTranslation(value * weight)); } RotationTimelineResolver::RotationTimelineResolver() = default; RotationTimelineResolver::~RotationTimelineResolver() = default; -void RotationTimelineResolver::Apply(AnimationTransforms& target, +void RotationTimelineResolver::Apply(Node& target, SecondsF time, Scalar weight) { if (values_.empty()) { @@ -110,19 +108,15 @@ void RotationTimelineResolver::Apply(AnimationTransforms& target, if (key.lerp < 1) { value = values_[key.index - 1].Slerp(value, key.lerp); } - - target.animated_pose.rotation = - target.animated_pose.rotation * - Quaternion().Slerp(target.bind_pose.rotation.Invert() * value, weight); + target.SetLocalTransform(target.GetLocalTransform() * + Matrix::MakeRotation(value * weight)); } ScaleTimelineResolver::ScaleTimelineResolver() = default; ScaleTimelineResolver::~ScaleTimelineResolver() = default; -void ScaleTimelineResolver::Apply(AnimationTransforms& target, - SecondsF time, - Scalar weight) { +void ScaleTimelineResolver::Apply(Node& target, SecondsF time, Scalar weight) { if (values_.empty()) { return; } @@ -131,9 +125,8 @@ void ScaleTimelineResolver::Apply(AnimationTransforms& target, if (key.lerp < 1) { value = values_[key.index - 1].Lerp(value, key.lerp); } - - target.animated_pose.scale *= - Vector3(1, 1, 1).Lerp(value / target.bind_pose.scale, weight); + target.SetLocalTransform(target.GetLocalTransform() * + Matrix::MakeScale(value * weight)); } } // namespace scene diff --git a/impeller/scene/animation/property_resolver.h b/impeller/scene/animation/property_resolver.h index f7b5ce2abfdff..e0cd1888a857a 100644 --- a/impeller/scene/animation/property_resolver.h +++ b/impeller/scene/animation/property_resolver.h @@ -11,11 +11,9 @@ #include "flutter/fml/hash_combine.h" #include "flutter/fml/macros.h" #include "impeller/base/timing.h" -#include "impeller/geometry/matrix_decomposition.h" #include "impeller/geometry/quaternion.h" #include "impeller/geometry/scalar.h" #include "impeller/geometry/vector.h" -#include "impeller/scene/animation/animation_transforms.h" namespace impeller { namespace scene { @@ -48,9 +46,7 @@ class PropertyResolver { /// many different PropertyResolvers prior to rendering. For example, /// an AnimationPlayer may blend multiple Animations together by /// applying several AnimationClips. - virtual void Apply(AnimationTransforms& target, - SecondsF time, - Scalar weight) = 0; + virtual void Apply(Node& target, SecondsF time, Scalar weight) = 0; }; class TimelineResolver : public PropertyResolver { @@ -78,9 +74,7 @@ class TranslationTimelineResolver final : public TimelineResolver { ~TranslationTimelineResolver(); // |Resolver| - void Apply(AnimationTransforms& target, - SecondsF time, - Scalar weight) override; + void Apply(Node& target, SecondsF time, Scalar weight) override; private: TranslationTimelineResolver(); @@ -97,9 +91,7 @@ class RotationTimelineResolver final : public TimelineResolver { ~RotationTimelineResolver(); // |Resolver| - void Apply(AnimationTransforms& target, - SecondsF time, - Scalar weight) override; + void Apply(Node& target, SecondsF time, Scalar weight) override; private: RotationTimelineResolver(); @@ -116,9 +108,7 @@ class ScaleTimelineResolver final : public TimelineResolver { ~ScaleTimelineResolver(); // |Resolver| - void Apply(AnimationTransforms& target, - SecondsF time, - Scalar weight) override; + void Apply(Node& target, SecondsF time, Scalar weight) override; private: ScaleTimelineResolver(); diff --git a/impeller/scene/geometry.cc b/impeller/scene/geometry.cc index 739d60923ba3b..099476d14202d 100644 --- a/impeller/scene/geometry.cc +++ b/impeller/scene/geometry.cc @@ -95,7 +95,7 @@ std::shared_ptr Geometry::MakeFromFlatbuffer( } DeviceBufferDescriptor buffer_desc; - buffer_desc.size = vertices_bytes + indices_bytes; + buffer_desc.size = vertices_bytes * indices_bytes; buffer_desc.storage_mode = StorageMode::kHostVisible; auto buffer = allocator.CreateBuffer(buffer_desc); diff --git a/impeller/scene/material.cc b/impeller/scene/material.cc index 87eb92e198013..73ce339babe7f 100644 --- a/impeller/scene/material.cc +++ b/impeller/scene/material.cc @@ -81,11 +81,13 @@ std::unique_ptr UnlitMaterial::MakeFromFlatbuffer( if (material.base_color_factor()) { result->SetColor(importer::ToColor(*material.base_color_factor())); + result->SetVertexColorWeight(0); } if (material.base_color_texture() >= 0 && material.base_color_texture() < static_cast(textures.size())) { result->SetColorTexture(textures[material.base_color_texture()]); + result->SetVertexColorWeight(0); } return result; diff --git a/impeller/scene/node.cc b/impeller/scene/node.cc index 8f1da38f1e559..7343adb8fa98e 100644 --- a/impeller/scene/node.cc +++ b/impeller/scene/node.cc @@ -7,11 +7,9 @@ #include #include #include -#include #include "flutter/fml/logging.h" #include "impeller/base/strings.h" -#include "impeller/base/thread.h" #include "impeller/base/validation.h" #include "impeller/geometry/matrix.h" #include "impeller/scene/animation/animation_player.h" @@ -26,24 +24,6 @@ namespace scene { static std::atomic_uint64_t kNextNodeID = 0; -void Node::MutationLog::Append(const Entry& entry) { - WriterLock lock(write_mutex_); - dirty_ = true; - entries_.push_back(entry); -} - -std::optional> -Node::MutationLog::Flush() { - WriterLock lock(write_mutex_); - if (!dirty_) { - return std::nullopt; - } - dirty_ = false; - auto result = entries_; - entries_ = {}; - return result; -} - std::shared_ptr Node::MakeFromFlatbuffer( const fml::Mapping& ipscene_mapping, Allocator& allocator) { @@ -277,7 +257,7 @@ std::shared_ptr Node::FindAnimationByName( return nullptr; } -AnimationClip* Node::AddAnimation(const std::shared_ptr& animation) { +AnimationClip& Node::AddAnimation(const std::shared_ptr& animation) { if (!animation_player_.has_value()) { animation_player_ = AnimationPlayer(); } @@ -307,11 +287,6 @@ Matrix Node::GetGlobalTransform() const { } bool Node::AddChild(std::shared_ptr node) { - if (!node) { - VALIDATION_LOG << "Cannot add null child to node."; - return false; - } - // TODO(bdero): Figure out a better paradigm/rules for nodes with multiple // parents. We should probably disallow this, make deep // copying of nodes cheap and easy, add mesh instancing, etc. @@ -353,55 +328,7 @@ bool Node::IsJoint() const { bool Node::Render(SceneEncoder& encoder, Allocator& allocator, - const Matrix& parent_transform) { - std::optional> log = mutation_log_.Flush(); - if (log.has_value()) { - for (const auto& entry : log.value()) { - if (auto e = std::get_if(&entry)) { - local_transform_ = e->transform; - } else if (auto e = - std::get_if(&entry)) { - AnimationClip* clip = - animation_player_.has_value() - ? animation_player_->GetClip(e->animation_name) - : nullptr; - if (!clip) { - auto animation = FindAnimationByName(e->animation_name); - if (!animation) { - continue; - } - clip = AddAnimation(animation); - if (!clip) { - continue; - } - } - - clip->SetPlaying(e->playing); - clip->SetLoop(e->loop); - clip->SetWeight(e->weight); - clip->SetPlaybackTimeScale(e->time_scale); - } else if (auto e = - std::get_if(&entry)) { - AnimationClip* clip = - animation_player_.has_value() - ? animation_player_->GetClip(e->animation_name) - : nullptr; - if (!clip) { - auto animation = FindAnimationByName(e->animation_name); - if (!animation) { - continue; - } - clip = AddAnimation(animation); - if (!clip) { - continue; - } - } - - clip->Seek(SecondsF(e->time)); - } - } - } - + const Matrix& parent_transform) const { if (animation_player_.has_value()) { animation_player_->Update(); } @@ -418,9 +345,5 @@ bool Node::Render(SceneEncoder& encoder, return true; } -void Node::AddMutation(const MutationLog::Entry& entry) { - mutation_log_.Append(entry); -} - } // namespace scene } // namespace impeller diff --git a/impeller/scene/node.h b/impeller/scene/node.h index 2f144397500fd..8b79e5f90fd81 100644 --- a/impeller/scene/node.h +++ b/impeller/scene/node.h @@ -5,13 +5,10 @@ #pragma once #include -#include #include #include #include "flutter/fml/macros.h" -#include "impeller/base/thread.h" -#include "impeller/base/thread_safety.h" #include "impeller/geometry/matrix.h" #include "impeller/renderer/render_target.h" #include "impeller/renderer/texture.h" @@ -28,40 +25,6 @@ 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; - - void Append(const Entry& entry); - - private: - std::optional> Flush(); - - RWMutex write_mutex_; - bool dirty_ IPLR_GUARDED_BY(write_mutex_) = false; - std::vector entries_ IPLR_GUARDED_BY(write_mutex_); - - friend Node; - }; - static std::shared_ptr MakeFromFlatbuffer( const fml::Mapping& ipscene_mapping, Allocator& allocator); @@ -81,7 +44,7 @@ class Node final { bool exclude_animation_players = false) const; std::shared_ptr FindAnimationByName(const std::string& name) const; - AnimationClip* AddAnimation(const std::shared_ptr& animation); + AnimationClip& AddAnimation(const std::shared_ptr& animation); void SetLocalTransform(Matrix transform); Matrix GetLocalTransform() const; @@ -100,9 +63,7 @@ class Node final { bool Render(SceneEncoder& encoder, Allocator& allocator, - const Matrix& parent_transform); - - void AddMutation(const MutationLog::Entry& entry); + const Matrix& parent_transform) const; private: void UnpackFromFlatbuffer( @@ -111,8 +72,6 @@ class Node final { const std::vector>& textures, Allocator& allocator); - mutable MutationLog mutation_log_; - Matrix local_transform_; std::string name_; diff --git a/impeller/scene/scene.cc b/impeller/scene/scene.cc index ca7202afb04b4..d1c8cae5002b2 100644 --- a/impeller/scene/scene.cc +++ b/impeller/scene/scene.cc @@ -31,7 +31,7 @@ Node& Scene::GetRoot() { } bool Scene::Render(const RenderTarget& render_target, - const Matrix& camera_transform) { + const Matrix& camera_transform) const { // Collect the render commands from the scene. SceneEncoder encoder; if (!root_.Render(encoder, @@ -57,7 +57,8 @@ bool Scene::Render(const RenderTarget& render_target, return true; } -bool Scene::Render(const RenderTarget& render_target, const Camera& camera) { +bool Scene::Render(const RenderTarget& render_target, + const Camera& camera) const { return Render(render_target, camera.GetTransform(render_target.GetRenderTargetSize())); } diff --git a/impeller/scene/scene.h b/impeller/scene/scene.h index 210cbd5b850c0..9ff0745befaa0 100644 --- a/impeller/scene/scene.h +++ b/impeller/scene/scene.h @@ -28,9 +28,9 @@ class Scene { Node& GetRoot(); bool Render(const RenderTarget& render_target, - const Matrix& camera_transform); + const Matrix& camera_transform) const; - bool Render(const RenderTarget& render_target, const Camera& camera); + bool Render(const RenderTarget& render_target, const Camera& camera) const; private: std::shared_ptr scene_context_; diff --git a/impeller/scene/scene_context.cc b/impeller/scene/scene_context.cc index 1ee1a7a5b3733..284d6da6b3ac1 100644 --- a/impeller/scene/scene_context.cc +++ b/impeller/scene/scene_context.cc @@ -28,9 +28,6 @@ void SceneContextOptions::ApplyToPipelineDescriptor( desc.SetSampleCount(sample_count); desc.SetPrimitiveType(primitive_type); - - desc.SetWindingOrder(WindingOrder::kCounterClockwise); - desc.SetCullMode(CullMode::kBackFace); } SceneContext::SceneContext(std::shared_ptr context) diff --git a/impeller/scene/scene_unittests.cc b/impeller/scene/scene_unittests.cc index d822c1497a8ca..f2a048f8a7f4f 100644 --- a/impeller/scene/scene_unittests.cc +++ b/impeller/scene/scene_unittests.cc @@ -27,6 +27,8 @@ #include "third_party/flatbuffers/include/flatbuffers/verifier.h" #include "third_party/imgui/imgui.h" +// #include "third_party/tinygltf/tiny_gltf.h" + namespace impeller { namespace scene { namespace testing { @@ -124,10 +126,9 @@ TEST_P(SceneTest, TwoTriangles) { auto animation = gltf_scene->FindAnimationByName("Metronome"); ASSERT_NE(animation, nullptr); - AnimationClip* metronome_clip = gltf_scene->AddAnimation(animation); - ASSERT_NE(metronome_clip, nullptr); - metronome_clip->SetLoop(true); - metronome_clip->Play(); + AnimationClip& metronome_clip = gltf_scene->AddAnimation(animation); + metronome_clip.SetLoop(true); + metronome_clip.Play(); auto scene_context = std::make_shared(GetContext()); auto scene = Scene(scene_context); @@ -144,123 +145,18 @@ TEST_P(SceneTest, TwoTriangles) { ImGui::SliderFloat("Weight", &weight, -2, 2); ImGui::Checkbox("Loop", &loop); if (ImGui::Button("Play")) { - metronome_clip->Play(); + metronome_clip.Play(); } if (ImGui::Button("Pause")) { - metronome_clip->Pause(); + metronome_clip.Pause(); } if (ImGui::Button("Stop")) { - metronome_clip->Stop(); + metronome_clip.Stop(); } - metronome_clip->SetPlaybackTimeScale(playback_time_scale); - metronome_clip->SetWeight(weight); - metronome_clip->SetLoop(loop); - } - - ImGui::End(); - Node& node = *scene.GetRoot().GetChildren()[0]; - node.SetLocalTransform(node.GetLocalTransform() * - Matrix::MakeRotation(0.02, {0, 1, 0, 0})); - - static ImVec2 mouse_pos_prev = ImGui::GetMousePos(); - ImVec2 mouse_pos = ImGui::GetMousePos(); - Vector2 mouse_diff = - Vector2(mouse_pos.x - mouse_pos_prev.x, mouse_pos.y - mouse_pos_prev.y); - - static Vector3 position(0, 1, -5); - static Vector3 cam_position = position; - auto strafe = - Vector3(ImGui::IsKeyDown(ImGuiKey_D) - ImGui::IsKeyDown(ImGuiKey_A), - ImGui::IsKeyDown(ImGuiKey_E) - ImGui::IsKeyDown(ImGuiKey_Q), - ImGui::IsKeyDown(ImGuiKey_W) - ImGui::IsKeyDown(ImGuiKey_S)); - position += strafe * 0.5; - cam_position = cam_position.Lerp(position, 0.02); - - // Face towards the +Z direction (+X right, +Y up). - auto camera = Camera::MakePerspective( - /* fov */ Degrees(60), - /* position */ cam_position) - .LookAt( - /* target */ cam_position + Vector3(0, 0, 1), - /* up */ {0, 1, 0}); - - scene.Render(render_target, camera); - return true; - }; - - OpenPlaygroundHere(callback); -} - -TEST_P(SceneTest, Dash) { - auto allocator = GetContext()->GetResourceAllocator(); - - auto mapping = flutter::testing::OpenFixtureAsMapping("dash.glb.ipscene"); - if (!mapping) { - // TODO(bdero): Just skip this playground is the dash asset isn't found. I - // haven't checked it in because it's way too big right now, - // but this is still useful to keep around for debugging - // purposes. - return; - } - ASSERT_NE(mapping, nullptr); - - std::shared_ptr gltf_scene = - Node::MakeFromFlatbuffer(*mapping, *allocator); - ASSERT_NE(gltf_scene, nullptr); - - auto walk_anim = gltf_scene->FindAnimationByName("Walk"); - ASSERT_NE(walk_anim, nullptr); - - AnimationClip* walk_clip = gltf_scene->AddAnimation(walk_anim); - ASSERT_NE(walk_clip, nullptr); - walk_clip->SetLoop(true); - walk_clip->Play(); - - auto run_anim = gltf_scene->FindAnimationByName("Run"); - ASSERT_NE(walk_anim, nullptr); - - AnimationClip* run_clip = gltf_scene->AddAnimation(run_anim); - ASSERT_NE(run_clip, nullptr); - run_clip->SetLoop(true); - run_clip->Play(); - - auto scene_context = std::make_shared(GetContext()); - auto scene = Scene(scene_context); - scene.GetRoot().AddChild(std::move(gltf_scene)); - - Renderer::RenderCallback callback = [&](RenderTarget& render_target) { - ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize); - { - static Scalar playback_time_scale = 1; - static Scalar walk = 0.5; - static Scalar run = 0.5; - static bool loop = true; - - ImGui::SliderFloat("Playback time scale", &playback_time_scale, -5, 5); - ImGui::SliderFloat("Walk weight", &walk, 0, 1); - ImGui::SliderFloat("Run weight", &run, 0, 1); - ImGui::Checkbox("Loop", &loop); - if (ImGui::Button("Play")) { - walk_clip->Play(); - run_clip->Play(); - } - if (ImGui::Button("Pause")) { - walk_clip->Pause(); - run_clip->Pause(); - } - if (ImGui::Button("Stop")) { - walk_clip->Stop(); - run_clip->Stop(); - } - - walk_clip->SetPlaybackTimeScale(playback_time_scale); - walk_clip->SetWeight(walk); - walk_clip->SetLoop(loop); - - run_clip->SetPlaybackTimeScale(playback_time_scale); - run_clip->SetWeight(run); - run_clip->SetLoop(loop); + metronome_clip.SetPlaybackTimeScale(playback_time_scale); + metronome_clip.SetWeight(weight); + metronome_clip.SetLoop(loop); } ImGui::End(); diff --git a/impeller/scene/skin.cc b/impeller/scene/skin.cc index 4407eeb5bf76f..4a4c614195289 100644 --- a/impeller/scene/skin.cc +++ b/impeller/scene/skin.cc @@ -41,14 +41,12 @@ std::unique_ptr Skin::MakeFromFlatbuffer( } result.inverse_bind_matrices_.reserve(skin.inverse_bind_matrices()->size()); - for (size_t matrix_i = 0; matrix_i < skin.inverse_bind_matrices()->size(); - matrix_i++) { - const auto* ip_matrix = skin.inverse_bind_matrices()->Get(matrix_i); - Matrix matrix = ip_matrix ? importer::ToMatrix(*ip_matrix) : Matrix(); - - result.inverse_bind_matrices_.push_back(matrix); - // Overwrite the joint transforms with the inverse bind pose. - result.joints_[matrix_i]->SetGlobalTransform(matrix.Invert()); + for (auto matrix : *skin.inverse_bind_matrices()) { + if (!matrix) { + result.inverse_bind_matrices_.push_back(Matrix()); + continue; + } + result.inverse_bind_matrices_.push_back(importer::ToMatrix(*matrix)); } return std::make_unique(std::move(result)); diff --git a/lib/ui/experiments/scene.dart b/lib/ui/experiments/scene.dart index abe610caccff7..2b2e477a4c41e 100644 --- a/lib/ui/experiments/scene.dart +++ b/lib/ui/experiments/scene.dart @@ -22,17 +22,16 @@ class SceneNode extends NativeFieldWrapperClass1 { // encoded paths (replacing ' ' with '%20', for example). We perform // the same encoding here so that users can load assets with the same // key they have written in the pubspec. - final String encodedKey = Uri(path: Uri.encodeFull(assetKey)).path; + final String encodedKey = Uri(path: Uri.encodeFull(assetKey)).path; { - final Future? futureSceneNode = _ipsceneRegistry[encodedKey]?.target; - if (futureSceneNode != null) { - return futureSceneNode; + final SceneNode? sceneNode = _ipsceneRegistry[encodedKey]?.target; + if (sceneNode != null) { + return Future.value(sceneNode); } } final SceneNode sceneNode = SceneNode._create(); - - final Future futureSceneNode = _futurize((_Callback callback) { + return _futurize((_Callback callback) { final String error = sceneNode._initFromAsset(assetKey, callback); if (error.isNotEmpty) { return error; @@ -42,11 +41,10 @@ class SceneNode extends NativeFieldWrapperClass1 { return true; }()); + _ipsceneRegistry[encodedKey] = WeakReference(sceneNode); + return null; }).then((_) => sceneNode); - - _ipsceneRegistry[encodedKey] = WeakReference>(futureSceneNode); - return futureSceneNode; } static SceneNode fromTransform(Float64List matrix4) { @@ -63,8 +61,8 @@ class SceneNode extends NativeFieldWrapperClass1 { _setTransform(matrix4); } - void setAnimationState(String animationName, bool playing, bool loop, double weight, double timeScale) { - _setAnimationState(animationName, playing, loop, weight, timeScale); + void setAnimationState(String animationName, bool playing, double weight, double timeScale) { + _setAnimationState(animationName, playing, weight, timeScale); } void seekAnimation(String animationName, double time) { @@ -75,11 +73,11 @@ class SceneNode extends NativeFieldWrapperClass1 { // SceneNode.fromAsset. It holds weak references to the SceneNodes so that the // case where an in-use ipscene is requested again can be fast, but scenes // that are no longer referenced are not retained because of the cache. - static final Map>> _ipsceneRegistry = - >>{}; + static final Map> _ipsceneRegistry = + >{}; static Future _reinitializeScene(String assetKey) async { - final WeakReference>? sceneRef = _ipsceneRegistry == null + final WeakReference? sceneRef = _ipsceneRegistry == null ? null : _ipsceneRegistry[assetKey]; @@ -89,11 +87,10 @@ class SceneNode extends NativeFieldWrapperClass1 { return; } - final Future? sceneNodeFuture = sceneRef.target; - if (sceneNodeFuture == null) { + final SceneNode? sceneNode = sceneRef.target; + if (sceneNode == null) { return; } - final SceneNode sceneNode = await sceneNodeFuture; await _futurize((_Callback callback) { final String error = sceneNode._initFromAsset(assetKey, callback); @@ -119,10 +116,10 @@ class SceneNode extends NativeFieldWrapperClass1 { @FfiNative, Handle)>('SceneNode::SetTransform') external void _setTransform(Float64List matrix4); - @FfiNative, Handle, Bool, Bool, Double, Double)>('SceneNode::SetAnimationState') - external void _setAnimationState(String animationName, bool playing, bool loop, double weight, double timeScale); + @FfiNative, Handle, Handle, Handle, Handle)>('SceneScene::SetAnimationState') + external void _setAnimationState(String animationName, bool playing, double weight, double timeScale); - @FfiNative, Handle, Double)>('SceneNode::SeekAnimation') + @FfiNative, Handle, Handle)>('SceneNode::SeekAnimation') external void _seekAnimation(String animationName, double time); /// Returns a fresh instance of [SceneShader]. diff --git a/lib/ui/painting/scene/scene_node.cc b/lib/ui/painting/scene/scene_node.cc index 914dd2c94a5f6..cc0b2bae1f04b 100644 --- a/lib/ui/painting/scene/scene_node.cc +++ b/lib/ui/painting/scene/scene_node.cc @@ -21,7 +21,6 @@ #include "third_party/tonic/dart_args.h" #include "third_party/tonic/dart_binding_macros.h" #include "third_party/tonic/dart_library_natives.h" -#include "third_party/tonic/typed_data/typed_list.h" namespace flutter { @@ -99,16 +98,13 @@ std::string SceneNode::initFromAsset(const std::string& asset_name, return ""; } -static impeller::Matrix ToMatrix(const tonic::Float64List& matrix4) { - return impeller::Matrix(matrix4[0], matrix4[1], matrix4[2], matrix4[3], // - matrix4[4], matrix4[5], matrix4[6], matrix4[7], // - matrix4[8], matrix4[9], matrix4[10], matrix4[11], // - matrix4[12], matrix4[13], matrix4[14], matrix4[15]); -} - void SceneNode::initFromTransform(const tonic::Float64List& matrix4) { node_ = std::make_shared(); - node_->SetLocalTransform(ToMatrix(matrix4)); + node_->SetLocalTransform( + impeller::Matrix(matrix4[0], matrix4[1], matrix4[2], matrix4[3], // + matrix4[4], matrix4[5], matrix4[6], matrix4[7], // + matrix4[8], matrix4[9], matrix4[10], matrix4[11], // + matrix4[12], matrix4[13], matrix4[14], matrix4[15])); } void SceneNode::AddChild(Dart_Handle scene_node_handle) { @@ -125,32 +121,18 @@ void SceneNode::AddChild(Dart_Handle scene_node_handle) { } void SceneNode::SetTransform(const tonic::Float64List& matrix4) { - impeller::scene::Node::MutationLog::SetTransformEntry entry = { - ToMatrix(matrix4)}; - node_->AddMutation(entry); + // TODO(bdero): Implement mutation log. } void SceneNode::SetAnimationState(const std::string& animation_name, bool playing, - bool loop, double weight, double time_scale) { - impeller::scene::Node::MutationLog::SetAnimationStateEntry entry = { - .animation_name = animation_name, - .playing = playing, - .loop = loop, - .weight = static_cast(weight), - .time_scale = static_cast(time_scale), - }; - node_->AddMutation(entry); + // TODO(bdero): Implement mutation log. } void SceneNode::SeekAnimation(const std::string& animation_name, double time) { - impeller::scene::Node::MutationLog::SeekAnimationEntry entry = { - .animation_name = animation_name, - .time = static_cast(time), - }; - node_->AddMutation(entry); + // TODO(bdero): Implement mutation log. } SceneNode::SceneNode() = default; diff --git a/lib/ui/painting/scene/scene_node.h b/lib/ui/painting/scene/scene_node.h index ee44e801f7de6..563b0f9232c55 100644 --- a/lib/ui/painting/scene/scene_node.h +++ b/lib/ui/painting/scene/scene_node.h @@ -48,7 +48,6 @@ class SceneNode : public RefCountedDartWrappable { void SetAnimationState(const std::string& animation_name, bool playing, - bool loop, double weight, double time_scale);