From 127217d4fb685b68035ae58a4e67634852f48a9c Mon Sep 17 00:00:00 2001 From: Onur Berk Tore Date: Thu, 30 Jun 2022 20:32:13 +0300 Subject: [PATCH 1/8] Utilizes function to load animations Signed-off-by: Onur Berk Tore --- .../ignition/gazebo/rendering/SceneManager.hh | 6 + src/rendering/SceneManager.cc | 224 ++++++++++-------- 2 files changed, 126 insertions(+), 104 deletions(-) diff --git a/include/ignition/gazebo/rendering/SceneManager.hh b/include/ignition/gazebo/rendering/SceneManager.hh index 1ea41fb348..980e45e942 100644 --- a/include/ignition/gazebo/rendering/SceneManager.hh +++ b/include/ignition/gazebo/rendering/SceneManager.hh @@ -200,6 +200,12 @@ inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE { /// \return Pointer to requested visual public: rendering::VisualPtr VisualById(Entity _id); + /// \brief Apply Animation to Actor + /// \param[in] _actor Actor + /// \return Animation name to ID map + public: std::unordered_map + LoadAnimations(const sdf::Actor &_actor); + /// \brief Create an actor /// \param[in] _id Unique actor id /// \param[in] _actor Actor sdf dom diff --git a/src/rendering/SceneManager.cc b/src/rendering/SceneManager.cc index 3caf84c4ed..292e63066d 100644 --- a/src/rendering/SceneManager.cc +++ b/src/rendering/SceneManager.cc @@ -968,112 +968,11 @@ rendering::VisualPtr SceneManager::CreateActor(Entity _id, return rendering::VisualPtr(); } - unsigned int numAnims = 0; - std::unordered_map mapAnimNameId; - mapAnimNameId[descriptor.meshName] = numAnims++; - // Load all animations - for (unsigned i = 0; i < _actor.AnimationCount(); ++i) - { - std::string animName = _actor.AnimationByIndex(i)->Name(); - std::string animFilename = asFullPath( - _actor.AnimationByIndex(i)->Filename(), - _actor.AnimationByIndex(i)->FilePath()); - - double animScale = _actor.AnimationByIndex(i)->Scale(); - - std::string extension = animFilename.substr(animFilename.rfind('.') + 1, - animFilename.size()); - std::transform(extension.begin(), extension.end(), - extension.begin(), ::tolower); - - if (extension == "bvh") - { - // do not add duplicate animation - // start checking from index 1 since index 0 is reserved by skin mesh - bool addAnim = true; - for (unsigned int a = 1; a < meshSkel->AnimationCount(); ++a) - { - if (meshSkel->Animation(a)->Name() == animFilename) - { - addAnim = false; - break; - } - } - if (addAnim) - meshSkel->AddBvhAnimation(animFilename, animScale); - mapAnimNameId[animName] = numAnims++; - } - else if (extension == "dae") - { - // Load the mesh if it has not been loaded before - const common::Mesh *animMesh = nullptr; - if (!meshManager->HasMesh(animFilename)) - { - animMesh = meshManager->Load(animFilename); - if (animMesh->MeshSkeleton()->AnimationCount() > 1) - { - ignwarn << "File [" << animFilename - << "] has more than one animation, but only the 1st one is used." - << std::endl; - } - } - animMesh = meshManager->MeshByName(animFilename); - - // add the first animation - auto firstAnim = animMesh->MeshSkeleton()->Animation(0); - if (nullptr == firstAnim) - { - ignerr << "Failed to get animations from [" << animFilename - << "]" << std::endl; - return nullptr; - } - // do not add duplicate animation - // start checking from index 1 since index 0 is reserved by skin mesh - bool addAnim = true; - for (unsigned int a = 1; a < meshSkel->AnimationCount(); ++a) - { - if (meshSkel->Animation(a)->Name() == animName) - { - addAnim = false; - break; - } - } - if (addAnim) - { - // collada loader loads animations with name that defaults to - // "animation0", "animation"1", etc causing conflicts in names - // when multiple animations are added to meshSkel. - // We have to clone the skeleton animation before giving it a unique - // name otherwise if mulitple instances of the same animation were added - // to meshSkel, changing the name that would also change the name of - // other instances of the animation - // todo(anyone) cloning is inefficient and error-prone. We should - // add a copy constructor to animation classes in ign-common. - // The proper fix is probably to update ign-rendering to allow it to - // load multiple animations of the same name - common::SkeletonAnimation *skelAnim = - new common::SkeletonAnimation(animName); - for (unsigned int j = 0; j < meshSkel->NodeCount(); ++j) - { - common::SkeletonNode *node = meshSkel->NodeByHandle(j); - common::NodeAnimation *nodeAnim = firstAnim->NodeAnimationByName( - node->Name()); - if (!nodeAnim) - continue; - for (unsigned int k = 0; k < nodeAnim->FrameCount(); ++k) - { - std::pair keyFrame = nodeAnim->KeyFrame(k); - skelAnim->AddKeyFrame( - node->Name(), keyFrame.first, keyFrame.second); - } - } + auto mapAnimNameId = this->LoadAnimations(_actor); + if (mapAnimNameId.size() == 0) + return nullptr; - meshSkel->AddAnimation(skelAnim); - } - mapAnimNameId[animName] = numAnims++; - } - } this->dataPtr->actorSkeletons[_id] = meshSkel; std::vector trajectories; @@ -2327,3 +2226,120 @@ AnimationUpdateData SceneManagerPrivate::ActorTrajectoryAt( animData.valid = true; return animData; } + +std::unordered_map +SceneManager::LoadAnimations(const sdf::Actor &_actor) +{ + rendering::MeshDescriptor descriptor; + descriptor.meshName = asFullPath(_actor.SkinFilename(), _actor.FilePath()); + common::MeshManager *meshManager = common::MeshManager::Instance(); + descriptor.mesh = meshManager->Load(descriptor.meshName); + common::SkeletonPtr meshSkel = descriptor.mesh->MeshSkeleton(); + + unsigned int numAnims = 0; + std::unordered_map mapAnimNameId; + mapAnimNameId[descriptor.meshName] = numAnims++; + // Load all animations + for (unsigned i = 0; i < _actor.AnimationCount(); ++i) + { + std::string animName = _actor.AnimationByIndex(i)->Name(); + std::string animFilename = asFullPath( + _actor.AnimationByIndex(i)->Filename(), + _actor.AnimationByIndex(i)->FilePath()); + + double animScale = _actor.AnimationByIndex(i)->Scale(); + + std::string extension = animFilename.substr(animFilename.rfind('.') + 1, + animFilename.size()); + std::transform(extension.begin(), extension.end(), + extension.begin(), ::tolower); + + if (extension == "bvh") + { + // do not add duplicate animation + // start checking from index 1 since index 0 is reserved by skin mesh + bool addAnim = true; + for (unsigned int a = 1; a < meshSkel->AnimationCount(); ++a) + { + if (meshSkel->Animation(a)->Name() == animFilename) + { + addAnim = false; + break; + } + } + if (addAnim) + meshSkel->AddBvhAnimation(animFilename, animScale); + mapAnimNameId[animName] = numAnims++; + } + else if (extension == "dae") + { + // Load the mesh if it has not been loaded before + const common::Mesh *animMesh = nullptr; + if (!meshManager->HasMesh(animFilename)) + { + animMesh = meshManager->Load(animFilename); + if (animMesh->MeshSkeleton()->AnimationCount() > 1) + { + ignwarn << "File [" << animFilename + << "] has more than one animation, but only the 1st one is used." + << std::endl; + } + } + animMesh = meshManager->MeshByName(animFilename); + + // add the first animation + auto firstAnim = animMesh->MeshSkeleton()->Animation(0); + if (nullptr == firstAnim) + { + ignerr << "Failed to get animations from [" << animFilename + << "]" << std::endl; + return nullptr; + } + // do not add duplicate animation + // start checking from index 1 since index 0 is reserved by skin mesh + bool addAnim = true; + for (unsigned int a = 1; a < meshSkel->AnimationCount(); ++a) + { + if (meshSkel->Animation(a)->Name() == animName) + { + addAnim = false; + break; + } + } + if (addAnim) + { + // collada loader loads animations with name that defaults to + // "animation0", "animation"1", etc causing conflicts in names + // when multiple animations are added to meshSkel. + // We have to clone the skeleton animation before giving it a unique + // name otherwise if mulitple instances of the same animation were added + // to meshSkel, changing the name that would also change the name of + // other instances of the animation + // todo(anyone) cloning is inefficient and error-prone. We should + // add a copy constructor to animation classes in ign-common. + // The proper fix is probably to update ign-rendering to allow it to + // load multiple animations of the same name + common::SkeletonAnimation *skelAnim = + new common::SkeletonAnimation(animName); + for (unsigned int j = 0; j < meshSkel->NodeCount(); ++j) + { + common::SkeletonNode *node = meshSkel->NodeByHandle(j); + common::NodeAnimation *nodeAnim = firstAnim->NodeAnimationByName( + node->Name()); + if (!nodeAnim) + continue; + for (unsigned int k = 0; k < nodeAnim->FrameCount(); ++k) + { + std::pair keyFrame = nodeAnim->KeyFrame(k); + skelAnim->AddKeyFrame( + node->Name(), keyFrame.first, keyFrame.second); + } + } + + meshSkel->AddAnimation(skelAnim); + } + mapAnimNameId[animName] = numAnims++; + } + } + return mapAnimNameId; +} From 22263be35815e13e907e5e687f63dc297f31193f Mon Sep 17 00:00:00 2001 From: Onur Berk Tore Date: Thu, 30 Jun 2022 22:42:56 +0300 Subject: [PATCH 2/8] Fix space problems Signed-off-by: Onur Berk Tore --- src/rendering/SceneManager.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/rendering/SceneManager.cc b/src/rendering/SceneManager.cc index 292e63066d..6b462a64d1 100644 --- a/src/rendering/SceneManager.cc +++ b/src/rendering/SceneManager.cc @@ -2252,7 +2252,7 @@ SceneManager::LoadAnimations(const sdf::Actor &_actor) std::string extension = animFilename.substr(animFilename.rfind('.') + 1, animFilename.size()); std::transform(extension.begin(), extension.end(), - extension.begin(), ::tolower); + extension.begin(), ::tolower); if (extension == "bvh") { @@ -2281,8 +2281,8 @@ SceneManager::LoadAnimations(const sdf::Actor &_actor) if (animMesh->MeshSkeleton()->AnimationCount() > 1) { ignwarn << "File [" << animFilename - << "] has more than one animation, but only the 1st one is used." - << std::endl; + << "] has more than one animation, but only the 1st one is used." + << std::endl; } } animMesh = meshManager->MeshByName(animFilename); @@ -2292,7 +2292,7 @@ SceneManager::LoadAnimations(const sdf::Actor &_actor) if (nullptr == firstAnim) { ignerr << "Failed to get animations from [" << animFilename - << "]" << std::endl; + << "]" << std::endl; return nullptr; } // do not add duplicate animation From 3a3d8bcd0e1e532295a9c3cab3368a991e336ff2 Mon Sep 17 00:00:00 2001 From: Onur Berk Tore Date: Thu, 30 Jun 2022 23:00:21 +0300 Subject: [PATCH 3/8] Fix: CI/CD errors are fixed Long lines with more than 80 charecters fixes. Extra spaces are removed. underored_map included Signed-off-by: Onur Berk Tore --- include/ignition/gazebo/rendering/SceneManager.hh | 3 ++- src/rendering/SceneManager.cc | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/include/ignition/gazebo/rendering/SceneManager.hh b/include/ignition/gazebo/rendering/SceneManager.hh index 980e45e942..930a76a395 100644 --- a/include/ignition/gazebo/rendering/SceneManager.hh +++ b/include/ignition/gazebo/rendering/SceneManager.hh @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -203,7 +204,7 @@ inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE { /// \brief Apply Animation to Actor /// \param[in] _actor Actor /// \return Animation name to ID map - public: std::unordered_map + public: std::unordered_map LoadAnimations(const sdf::Actor &_actor); /// \brief Create an actor diff --git a/src/rendering/SceneManager.cc b/src/rendering/SceneManager.cc index 6b462a64d1..78c34b6da5 100644 --- a/src/rendering/SceneManager.cc +++ b/src/rendering/SceneManager.cc @@ -2281,7 +2281,8 @@ SceneManager::LoadAnimations(const sdf::Actor &_actor) if (animMesh->MeshSkeleton()->AnimationCount() > 1) { ignwarn << "File [" << animFilename - << "] has more than one animation, but only the 1st one is used." + << "] has more than one animation, " + << "but only the 1st one is used." << std::endl; } } From 7de80fd6b0c3db35d7ec76071c76132fbc4a93c2 Mon Sep 17 00:00:00 2001 From: Onur Berk Tore Date: Thu, 30 Jun 2022 23:29:35 +0300 Subject: [PATCH 4/8] Fix white space error Signed-off-by: Onur Berk Tore --- src/rendering/SceneManager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rendering/SceneManager.cc b/src/rendering/SceneManager.cc index 78c34b6da5..b0146ab453 100644 --- a/src/rendering/SceneManager.cc +++ b/src/rendering/SceneManager.cc @@ -2281,7 +2281,7 @@ SceneManager::LoadAnimations(const sdf::Actor &_actor) if (animMesh->MeshSkeleton()->AnimationCount() > 1) { ignwarn << "File [" << animFilename - << "] has more than one animation, " + << "] has more than one animation, " << "but only the 1st one is used." << std::endl; } From 3a17abe441c40e061b83adf276b8e75b9ae01961 Mon Sep 17 00:00:00 2001 From: Onur Berk Tore Date: Sat, 2 Jul 2022 13:50:01 +0300 Subject: [PATCH 5/8] Fix: Compilation Error Fixes compilation error by returning empty mapAnimNameId. Signed-off-by: Onur Berk Tore --- src/rendering/SceneManager.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/rendering/SceneManager.cc b/src/rendering/SceneManager.cc index b0146ab453..c285193b49 100644 --- a/src/rendering/SceneManager.cc +++ b/src/rendering/SceneManager.cc @@ -2239,9 +2239,11 @@ SceneManager::LoadAnimations(const sdf::Actor &_actor) unsigned int numAnims = 0; std::unordered_map mapAnimNameId; mapAnimNameId[descriptor.meshName] = numAnims++; + // Load all animations for (unsigned i = 0; i < _actor.AnimationCount(); ++i) { + std::string animName = _actor.AnimationByIndex(i)->Name(); std::string animFilename = asFullPath( _actor.AnimationByIndex(i)->Filename(), @@ -2294,7 +2296,8 @@ SceneManager::LoadAnimations(const sdf::Actor &_actor) { ignerr << "Failed to get animations from [" << animFilename << "]" << std::endl; - return nullptr; + mapAnimNameId.clear(); + break; } // do not add duplicate animation // start checking from index 1 since index 0 is reserved by skin mesh From 1ded4ca142c22c7c0a2efdae5bfd9002b5ac3e13 Mon Sep 17 00:00:00 2001 From: Onur Berk Tore Date: Sat, 2 Jul 2022 14:53:42 +0300 Subject: [PATCH 6/8] Fix: Include fixed Signed-off-by: Onur Berk Tore --- src/rendering/SceneManager.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rendering/SceneManager.cc b/src/rendering/SceneManager.cc index c285193b49..92217d6a9a 100644 --- a/src/rendering/SceneManager.cc +++ b/src/rendering/SceneManager.cc @@ -18,7 +18,6 @@ #include #include -#include #include #include From b84f0cc84693355be791cbc908bf2408f48c8e7b Mon Sep 17 00:00:00 2001 From: Onur Berk Tore Date: Mon, 4 Jul 2022 17:24:36 +0300 Subject: [PATCH 7/8] Alphabetizes include Signed-off-by: Onur Berk Tore --- include/ignition/gazebo/rendering/SceneManager.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/ignition/gazebo/rendering/SceneManager.hh b/include/ignition/gazebo/rendering/SceneManager.hh index 930a76a395..842ff5357b 100644 --- a/include/ignition/gazebo/rendering/SceneManager.hh +++ b/include/ignition/gazebo/rendering/SceneManager.hh @@ -21,9 +21,9 @@ #include #include #include +#include #include #include -#include #include #include From 0ca96d45d812ebf958434824ebc0a20549046442 Mon Sep 17 00:00:00 2001 From: Onur Berk Tore Date: Mon, 4 Jul 2022 17:27:28 +0300 Subject: [PATCH 8/8] Remove unnecessary line Signed-off-by: Onur Berk Tore --- src/rendering/SceneManager.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rendering/SceneManager.cc b/src/rendering/SceneManager.cc index 92217d6a9a..599fdc3b9c 100644 --- a/src/rendering/SceneManager.cc +++ b/src/rendering/SceneManager.cc @@ -2242,7 +2242,6 @@ SceneManager::LoadAnimations(const sdf::Actor &_actor) // Load all animations for (unsigned i = 0; i < _actor.AnimationCount(); ++i) { - std::string animName = _actor.AnimationByIndex(i)->Name(); std::string animFilename = asFullPath( _actor.AnimationByIndex(i)->Filename(),