From ae6a8cc47a0f985416b78b7fbe794cba9c044381 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Sat, 31 Dec 2022 04:16:58 -0800 Subject: [PATCH 1/5] [Impeller Scene] Import animation data --- impeller/fixtures/two_triangles.glb | Bin 3376 -> 10180 bytes impeller/scene/importer/conversions.cc | 10 +- impeller/scene/importer/conversions.h | 4 +- impeller/scene/importer/importer_gltf.cc | 164 +++++++++++++++++- impeller/scene/importer/importer_unittests.cc | 15 +- impeller/scene/importer/scene.fbs | 6 +- impeller/scene/node.cc | 29 +++- impeller/scene/node.h | 7 + 8 files changed, 223 insertions(+), 12 deletions(-) diff --git a/impeller/fixtures/two_triangles.glb b/impeller/fixtures/two_triangles.glb index 3937ac6969769d9b2c5f274ecb6f72c541a40a26..4c7b8803bc92781621e8ce3607149971becdaba0 100644 GIT binary patch literal 10180 zcmeHMYit}>6d< zW@p#CI~4d4d6KLB?w#|UbM86kK6X7B9Xj#>m&^6*2AAt&pLV&94fglVF=8SisZ84( zGbzO-MO0;lX=A=TrO0tPQ9B7r?ct~tAD5Kc?z{SHXS^-G7GH?*Ff)>ph{$mW^DQhh z?_m;QC}7&yG)gdSBXdk#jA4u!G~RibxI8Y=7v9nN(OfSpHY86&vm&daYN#GzVas@Y ztT*KM`u)6zZSk|l;|~Q`U%=-JdYUt192er*5FZQ$AZBO6U?MC=;m!z$*QVZ3PB8}o zRT1NfXx6%?nQO_Y^!wS?AjkWqX13MCj?R1LnDA62I<82F!3ayIW6t%ktg3P>e;)AA z?oQ5YHaC<1(nP3pF)1-+WFzg?kP;E&lTm~paX1-))2wX{yoZJ$E#9ugL^Y{M3{8|6 zkD!N?m`M#!iSf7;H9HA0HXW5vG)TNEDwAe0(L^(CoQIhfRk)EC*m-IzRvam5agt43I%919Wh!RGlGs8A*T%9s75FA;JNwqD%`Ecw%n$fU-%BIu~$;* z#*aO_cuDeDd1XtI_ga!)8N=t8;djiiE|ki=vM!X$7(tXI);2av3EORYha8uaV^L`^ zGA@lXZK{%#vYYGxMz9TyDTuomjYh%)a&mGiE+w!J%rRqPLh6vCvT{TW8^}}&>`C8|9HTWhtwdrGH8PWa zDXOXx8B40PJICDJKiECg-QQ;%Ekm8hJNo+vzVtQLI9B@l2YTCkm^ReoPFYC+wON5WKdAeW%@A-I#>R%o}_4SJZ2-H^pDhv4T7 zb2!i}mO0*PnuCv-;=nx2YN4lbX5*)~D(Ns>?G+IU!(9$jxlhKbqcVs-;#u^J4nsO2 zE2gHgRy?9FHJ`gt&0nQ)fe7IW~=2b%pb5Cc77Z*Pis>K*)U&dID%@?qd&WhQEwlR~6*}ekX2y-FZ zm`)~4InN8(*k}vcc|k74HU#Y{GNxm*J=oFSgY(}WbrfnD>oL(xvDcPTTgq|2Mt$X6 zEetXiK^apyc430CZYpLM+NLY5VtQeY=+Z2tSDa$bNp%*nUbH+NB$;jmh3@BS4DO{v z-`hS^#D19)MI6i`VOv-q7sz{jC<=31*x_Z`@DAn46|L`_=P;csnj&d0Q{H*>A`>rD zvU&6(*2~mv89HC4X7lKU&hvO*D(QLjLg(qVr4-!<@6uaCOJ2qUf!6nzbG~S~=WD~2?x31_ zZLM^F!1(26Cu!Td@CQq|UEoQ`i6;Tpi6?=Q0p#e$VV!2cTgnw*&?eqm((?e_SgqPQ zzSWU>F2p&K=e^GS;e*cn@%rIU_Hala4A#>i1pA}&wYA^7-Q_ym-G{#rq=?yEDSYZV z>~j5U`xN?goIX^p*r#=@7|!tW^c#W}dzL2^7)b8U5%>J@;6;o)Jb2cM6kzY2UA z_!{t=z%KakQ8GOIN!X~R{s8-d4*?$o9tJ)Ed>?Sq@MC!R8|W_pe;Z?u0-pnZ9QcR8 ztH4hKKL@-4d>MEX_$A=0z}N7(``pSAu-EWzKYvZ{#^Zk*59^+}i_Np+R*Hl59Nfj` zec)D#gL<%m{QmTUfTmG=(cM5EySX5sX%s(r!%hAwEefwmiyFmmb-Brv0}lzC2OiQW zesQ3l+&1%w@S&MUG>Tt-@lKLzJ|~=NKBv6|eCN^6k&*Ey1T?JpZv`~%4&Xn#K1hySzbSNGzo}8Ya^br0_49iPn!XJD_zTYq{WI01Z>C!R z0WkmWs_>ho8uIc|jm`o8Zg@qwc$y(UKF#P9ACH|Co{QFz^=O^`72u8A&Iqw5>Is_u zGhlXVNtlYc$z;r}-v#^*vnV|LhMS=2Zv+47%>_YgY#^5!8+3}VB384AQ}SSgPH_*$ zUd4Mfo#KYtMWJ!aO+LTn*4@B&pI8z;CA-N1*{xH&@z%qF^i(|=f2v-m`2Mc5!pUSE zLDMO|{*e{oSIZ3fgTTiZOdw?6K8S?t(itxA16^-K8zFJ3aK66%h=b5wGUw~izZasO-b4K`%=Ztm( z_=^!Y`RUw}@a)`@M)5yicas;I7KJNKi`qYcM-iK+|GprgX%yS*&AM08yZ3w9`*(S4 q<=QdrXIkb?Z-^)oYXtDc>3CHmiw|NjQXJ+3i!j#7wggtNbYkPAq?xsH;be~_=EkCK&zjuOHgOB8bq z4Ui2oG@RVZY0PM}c_*hW<79DO&B^lIqLV*x^G>ekmYEz2WN+Zso;({Y7B=}dw-QjC zYjP2f&}26royi-3bPJCtP@mT1!#p8iwGO-rlOOO3OujF8cd~$(z~nPRI+O2<2rwBM zO#UchHQ7~IaI%f4%;W|k0cJxplgS5#tr-m_PZZJyix?S!M6^H}8I2}S5VDzUA)-53 zMwFk~*vMeAo~SjDwwU}|T!!1k)T}nPRzX4G1mk2SiHynXBxNSAl9ZeL1<3A^JOTi5 C;by-8 diff --git a/impeller/scene/importer/conversions.cc b/impeller/scene/importer/conversions.cc index bd74f04ebb04e..ceef0ef187096 100644 --- a/impeller/scene/importer/conversions.cc +++ b/impeller/scene/importer/conversions.cc @@ -51,7 +51,15 @@ Color ToColor(const fb::Color& c) { /// Impeller -> Flatbuffers /// -std::unique_ptr ToFBMatrix(const Matrix& m) { +fb::Matrix ToFBMatrix(const Matrix& m) { + auto array = std::array{m.m[0], m.m[1], m.m[2], m.m[3], // + m.m[4], m.m[5], m.m[6], m.m[7], // + m.m[8], m.m[9], m.m[10], m.m[11], // + m.m[12], m.m[13], m.m[14], m.m[15]}; + return fb::Matrix(array); +} + +std::unique_ptr ToFBMatrixUniquePtr(const Matrix& m) { auto array = std::array{m.m[0], m.m[1], m.m[2], m.m[3], // m.m[4], m.m[5], m.m[6], m.m[7], // m.m[8], m.m[9], m.m[10], m.m[11], // diff --git a/impeller/scene/importer/conversions.h b/impeller/scene/importer/conversions.h index b5fe119674d57..cb11d3c42f147 100644 --- a/impeller/scene/importer/conversions.h +++ b/impeller/scene/importer/conversions.h @@ -35,7 +35,9 @@ Color ToColor(const fb::Color& c); /// Impeller -> Flatbuffers /// -std::unique_ptr ToFBMatrix(const Matrix& m); +fb::Matrix ToFBMatrix(const Matrix& m); + +std::unique_ptr ToFBMatrixUniquePtr(const Matrix& m); fb::Vec2 ToFBVec2(const Vector2 v); diff --git a/impeller/scene/importer/importer_gltf.cc b/impeller/scene/importer/importer_gltf.cc index 83c33c0a06e2b..2a1a7389cbb85 100644 --- a/impeller/scene/importer/importer_gltf.cc +++ b/impeller/scene/importer/importer_gltf.cc @@ -226,7 +226,7 @@ static void ProcessNode(const tinygltf::Model& gltf, } transform = ToMatrix(in_node.matrix); } - out_node.transform = ToFBMatrix(transform); + out_node.transform = ToFBMatrixUniquePtr(transform); //--------------------------------------------------------------------------- /// Static meshes. @@ -242,13 +242,42 @@ static void ProcessNode(const tinygltf::Model& gltf, out_node.mesh_primitives.push_back(std::move(mesh_primitive)); } } + + //--------------------------------------------------------------------------- + /// Skin. + /// + + if (WithinRange(in_node.skin, gltf.skins.size())) { + auto& skin = gltf.skins[in_node.skin]; + + auto ipskin = std::make_unique(); + ipskin->joints = skin.joints; + { + std::vector matrices; + auto& matrix_accessor = gltf.accessors[skin.inverseBindMatrices]; + auto& matrix_view = gltf.bufferViews[matrix_accessor.bufferView]; + auto& matrix_buffer = gltf.buffers[matrix_view.buffer]; + for (size_t matrix_i = 0; matrix_i < matrix_accessor.count; matrix_i++) { + auto* s = reinterpret_cast( + matrix_buffer.data.data() + matrix_view.byteOffset + + matrix_accessor.ByteStride(matrix_view) * matrix_i); + Matrix m(s[0], s[1], s[2], s[3], // + s[4], s[5], s[6], s[7], // + s[8], s[9], s[10], s[11], // + s[12], s[13], s[14], s[15]); + matrices.push_back(ToFBMatrix(m)); + } + ipskin->inverse_bind_matrices = std::move(matrices); + } + ipskin->skeleton = skin.skeleton; + out_node.skin = std::move(ipskin); + } } static void ProcessTexture(const tinygltf::Model& gltf, const tinygltf::Texture& in_texture, fb::TextureT& out_texture) { - if (in_texture.source < 0 || - in_texture.source >= static_cast(gltf.images.size())) { + if (!WithinRange(in_texture.source, gltf.images.size())) { return; } auto& image = gltf.images[in_texture.source]; @@ -283,6 +312,128 @@ static void ProcessTexture(const tinygltf::Model& gltf, out_texture.uri = image.uri; } +static void ProcessAnimation(const tinygltf::Model& gltf, + const tinygltf::Animation& in_animation, + fb::AnimationT& out_animation) { + out_animation.name = in_animation.name; + + std::vector> channels; + for (auto& in_channel : in_animation.channels) { + auto out_channel = std::make_unique(); + + out_channel->node = in_channel.target_node; + auto& sampler = in_animation.samplers[in_channel.sampler]; + + /// Keyframe times. + auto& times_accessor = gltf.accessors[sampler.input]; + if (times_accessor.count <= 0) { + continue; // Nothing to record. + } + { + auto& times_bufferview = gltf.bufferViews[times_accessor.bufferView]; + auto& times_buffer = gltf.buffers[times_bufferview.buffer]; + if (times_accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) { + std::cerr << "Unexpected component type \"" + << times_accessor.componentType + << "\" for animation channel times accessor. Skipping." + << std::endl; + continue; + } + if (times_accessor.type != TINYGLTF_TYPE_SCALAR) { + std::cerr << "Unexpected type \"" << times_accessor.type + << "\" for animation channel times accessor. Skipping." + << std::endl; + continue; + } + for (size_t time_i = 0; time_i < times_accessor.count; time_i++) { + const float* time_p = reinterpret_cast( + times_buffer.data.data() + times_bufferview.byteOffset + + times_accessor.ByteStride(times_bufferview) * time_i); + out_channel->timeline.push_back(*time_p); + } + } + + /// Keyframe values. + auto& values_accessor = gltf.accessors[sampler.output]; + if (values_accessor.count != times_accessor.count) { + std::cerr << "Mismatch between time and value accessors for animation " + "channel. Skipping." + << std::endl; + continue; + } + { + auto& values_bufferview = gltf.bufferViews[values_accessor.bufferView]; + auto& values_buffer = gltf.buffers[values_bufferview.buffer]; + if (values_accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) { + std::cerr << "Unexpected component type \"" + << values_accessor.componentType + << "\" for animation channel values accessor. Skipping." + << std::endl; + continue; + } + if (in_channel.target_path == "translation") { + if (values_accessor.type != TINYGLTF_TYPE_VEC3) { + std::cerr << "Unexpected type \"" << values_accessor.type + << "\" for animation channel \"translation\" accessor. " + "Skipping." + << std::endl; + continue; + } + fb::TranslationKeyframesT keyframes; + for (size_t value_i = 0; value_i < values_accessor.count; value_i++) { + const float* value_p = reinterpret_cast( + values_buffer.data.data() + values_bufferview.byteOffset + + values_accessor.ByteStride(values_bufferview) * value_i); + keyframes.values.push_back( + fb::Vec3(value_p[0], value_p[1], value_p[2])); + } + out_channel->keyframes.Set(std::move(keyframes)); + } else if (in_channel.target_path == "rotation") { + if (values_accessor.type != TINYGLTF_TYPE_VEC4) { + std::cerr << "Unexpected type \"" << values_accessor.type + << "\" for animation channel \"rotation\" accessor. " + "Skipping." + << std::endl; + continue; + } + fb::RotationKeyframesT keyframes; + for (size_t value_i = 0; value_i < values_accessor.count; value_i++) { + const float* value_p = reinterpret_cast( + values_buffer.data.data() + values_bufferview.byteOffset + + values_accessor.ByteStride(values_bufferview) * value_i); + keyframes.values.push_back( + fb::Vec4(value_p[0], value_p[1], value_p[2], value_p[3])); + } + out_channel->keyframes.Set(std::move(keyframes)); + } else if (in_channel.target_path == "scale") { + if (values_accessor.type != TINYGLTF_TYPE_VEC3) { + std::cerr << "Unexpected type \"" << values_accessor.type + << "\" for animation channel \"scale\" accessor. " + "Skipping." + << std::endl; + continue; + } + fb::ScaleKeyframesT keyframes; + for (size_t value_i = 0; value_i < values_accessor.count; value_i++) { + const float* value_p = reinterpret_cast( + values_buffer.data.data() + values_bufferview.byteOffset + + values_accessor.ByteStride(values_bufferview) * value_i); + keyframes.values.push_back( + fb::Vec3(value_p[0], value_p[1], value_p[2])); + } + out_channel->keyframes.Set(std::move(keyframes)); + } else { + std::cerr << "Unsupported animation channel target path \"" + << in_channel.target_path << "\". Skipping." << std::endl; + continue; + } + } + + channels.push_back(std::move(out_channel)); + } + out_animation.channels = std::move(channels); +} + bool ParseGLTF(const fml::Mapping& source_mapping, fb::SceneT& out_scene) { tinygltf::Model gltf; @@ -319,6 +470,13 @@ bool ParseGLTF(const fml::Mapping& source_mapping, fb::SceneT& out_scene) { out_scene.nodes.push_back(std::move(node)); } + for (size_t animation_i = 0; animation_i < gltf.animations.size(); + animation_i++) { + auto animation = std::make_unique(); + ProcessAnimation(gltf, gltf.animations[animation_i], *animation); + out_scene.animations.push_back(std::move(animation)); + } + return true; } diff --git a/impeller/scene/importer/importer_unittests.cc b/impeller/scene/importer/importer_unittests.cc index 77ffca8e43cb4..1c98623068554 100644 --- a/impeller/scene/importer/importer_unittests.cc +++ b/impeller/scene/importer/importer_unittests.cc @@ -91,7 +91,7 @@ TEST(ImporterTest, CanParseSkinnedGLTF) { ASSERT_VECTOR3_NEAR(normal, Vector3(0, 0, 1)); Vector4 tangent = ToVector4(vertex.vertex().tangent()); - ASSERT_VECTOR4_NEAR(tangent, Vector4(0, 0, 0, 1)); + ASSERT_VECTOR4_NEAR(tangent, Vector4(1, 0, 0, -1)); Vector2 texture_coords = ToVector2(vertex.vertex().texture_coords()); ASSERT_POINT_NEAR(texture_coords, Vector2(0, 1)); @@ -104,6 +104,19 @@ TEST(ImporterTest, CanParseSkinnedGLTF) { Vector4 weights = ToVector4(vertex.weights()); ASSERT_COLOR_NEAR(weights, Vector4(1, 0, 0, 0)); + + ASSERT_EQ(scene.animations.size(), 2u); + ASSERT_EQ(scene.animations[0]->name, "Idle"); + ASSERT_EQ(scene.animations[1]->name, "Metronome"); + ASSERT_EQ(scene.animations[1]->channels.size(), 6u); + auto& channel = scene.animations[1]->channels[4]; + ASSERT_EQ(channel->keyframes.type, fb::Keyframes::RotationKeyframes); + auto* keyframes = channel->keyframes.AsRotationKeyframes(); + ASSERT_EQ(keyframes->values.size(), 40u); + ASSERT_VECTOR4_NEAR(ToVector4(keyframes->values[0]), + Vector4(0.653281, 0.270598, -0.270598, 0.653281)); + ASSERT_VECTOR4_NEAR(ToVector4(keyframes->values[10]), + Vector4(0.425122, 0.565041, -0.565041, 0.425122)); } } // namespace testing diff --git a/impeller/scene/importer/scene.fbs b/impeller/scene/importer/scene.fbs index de2d1b11b5a08..bfc949ae7d334 100644 --- a/impeller/scene/importer/scene.fbs +++ b/impeller/scene/importer/scene.fbs @@ -164,7 +164,7 @@ table Animation { } table Skin { - joints: [int]; // Index into `Scene`->`nodes`. + joints: [int]; // Indices into `Scene`->`nodes`. inverse_bind_matrices: [Matrix]; /// The root joint of the skeleton. skeleton: int; // Index into `Scene`->`nodes`. @@ -180,14 +180,14 @@ struct Matrix { table Node { name: string; - children: [int]; // Index into `Scene`->`nodes`. + children: [int]; // Indices into `Scene`->`nodes`. transform: Matrix; mesh_primitives: [MeshPrimitive]; skin: Skin; } table Scene { - children: [int]; // Index into `Scene`->`nodes`. + children: [int]; // Indices into `Scene`->`nodes`. nodes: [Node]; textures: [Texture]; // Textures may be reused across different materials. animations: [Animation]; diff --git a/impeller/scene/node.cc b/impeller/scene/node.cc index cabdb197c27f7..6c3536c54fa51 100644 --- a/impeller/scene/node.cc +++ b/impeller/scene/node.cc @@ -4,9 +4,11 @@ #include "impeller/scene/node.h" +#include #include #include "flutter/fml/logging.h" +#include "impeller/base/strings.h" #include "impeller/base/validation.h" #include "impeller/geometry/matrix.h" #include "impeller/scene/importer/conversions.h" @@ -18,6 +20,8 @@ namespace impeller { namespace scene { +static std::atomic_uint64_t kNextNodeID = 0; + std::shared_ptr Node::MakeFromFlatbuffer( const fml::Mapping& ipscene_mapping, Allocator& allocator) { @@ -155,8 +159,7 @@ void Node::UnpackFromFlatbuffer( const std::vector>& scene_nodes, const std::vector>& textures, Allocator& allocator) { - /// Transform. - + name_ = source_node.name()->str(); SetLocalTransform(importer::ToMatrix(*source_node.transform())); /// Meshes. @@ -190,7 +193,7 @@ void Node::UnpackFromFlatbuffer( } } -Node::Node() = default; +Node::Node() : name_(SPrintF("__node%llu", kNextNodeID.fetch_add(1))){}; Node::~Node() = default; @@ -202,6 +205,26 @@ Node::Node(Node&& node) = default; Node& Node::operator=(Node&& node) = default; +const std::string& Node::GetName() const { + return name_; +} + +void Node::SetName(const std::string& new_name) { + name_ = new_name; +} + +std::shared_ptr Node::FindNodeByName(const std::string& name) const { + for (auto& child : children_) { + if (child->GetName() == name) { + return child; + } + if (auto found = child->FindNodeByName(name)) { + return found; + } + } + return nullptr; +} + void Node::SetLocalTransform(Matrix transform) { local_transform_ = transform; } diff --git a/impeller/scene/node.h b/impeller/scene/node.h index a64fa9b8d9d84..56290e9d1678c 100644 --- a/impeller/scene/node.h +++ b/impeller/scene/node.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include "flutter/fml/macros.h" @@ -33,6 +34,11 @@ class Node final { Node(Node&& node); Node& operator=(Node&& node); + const std::string& GetName() const; + void SetName(const std::string& new_name); + + std::shared_ptr FindNodeByName(const std::string& name) const; + void SetLocalTransform(Matrix transform); Matrix GetLocalTransform() const; @@ -57,6 +63,7 @@ class Node final { const std::vector>& textures, Allocator& allocator); + std::string name_; bool is_root_ = false; Node* parent_ = nullptr; std::vector> children_; From e2baafc1a5919fd912610b0302eab03d7cd3fbc6 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Sat, 31 Dec 2022 11:44:41 -0800 Subject: [PATCH 2/5] Cast --- impeller/scene/node.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/impeller/scene/node.cc b/impeller/scene/node.cc index 6c3536c54fa51..889f74b2c6e0e 100644 --- a/impeller/scene/node.cc +++ b/impeller/scene/node.cc @@ -193,7 +193,9 @@ void Node::UnpackFromFlatbuffer( } } -Node::Node() : name_(SPrintF("__node%llu", kNextNodeID.fetch_add(1))){}; +Node::Node() + : name_(SPrintF("__node%llu", + static_cast(kNextNodeID.fetch_add(1)))){}; Node::~Node() = default; From 6654f3bb6164bb1713367ce7c1d7e44d24cbd553 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Sat, 31 Dec 2022 12:02:58 -0800 Subject: [PATCH 3/5] Use correct length modifier --- impeller/scene/node.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/impeller/scene/node.cc b/impeller/scene/node.cc index 889f74b2c6e0e..c1120c7f78246 100644 --- a/impeller/scene/node.cc +++ b/impeller/scene/node.cc @@ -4,6 +4,7 @@ #include "impeller/scene/node.h" +#include #include #include @@ -193,9 +194,7 @@ void Node::UnpackFromFlatbuffer( } } -Node::Node() - : name_(SPrintF("__node%llu", - static_cast(kNextNodeID.fetch_add(1)))){}; +Node::Node() : name_(SPrintF("__node%" PRIu64, kNextNodeID.fetch_add(1))){}; Node::~Node() = default; From 6408ed4323793bbe225829d16db32c9c038de71d Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 2 Jan 2023 00:10:11 -0800 Subject: [PATCH 4/5] Fix translation import --- impeller/scene/importer/importer_gltf.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/scene/importer/importer_gltf.cc b/impeller/scene/importer/importer_gltf.cc index 2a1a7389cbb85..2b6ab6322c69c 100644 --- a/impeller/scene/importer/importer_gltf.cc +++ b/impeller/scene/importer/importer_gltf.cc @@ -202,8 +202,8 @@ static void ProcessNode(const tinygltf::Model& gltf, if (in_node.translation.size() == 3) { transform = transform * Matrix::MakeTranslation( {static_cast(in_node.translation[0]), - static_cast(in_node.translation[0]), - static_cast(in_node.translation[0])}); + static_cast(in_node.translation[1]), + static_cast(in_node.translation[2])}); } if (in_node.rotation.size() == 4) { transform = transform * Matrix::MakeRotation(Quaternion( From ba950b2d236151df05bc5d611a8a5dc39b3bea40 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 2 Jan 2023 13:43:22 -0800 Subject: [PATCH 5/5] Use ++ instead of fetch_add --- impeller/scene/node.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/scene/node.cc b/impeller/scene/node.cc index c1120c7f78246..cc1a847356da3 100644 --- a/impeller/scene/node.cc +++ b/impeller/scene/node.cc @@ -194,7 +194,7 @@ void Node::UnpackFromFlatbuffer( } } -Node::Node() : name_(SPrintF("__node%" PRIu64, kNextNodeID.fetch_add(1))){}; +Node::Node() : name_(SPrintF("__node%" PRIu64, kNextNodeID++)){}; Node::~Node() = default;