diff options
Diffstat (limited to 'libs/assimp/code/PostProcessing/ArmaturePopulate.cpp')
-rw-r--r-- | libs/assimp/code/PostProcessing/ArmaturePopulate.cpp | 263 |
1 files changed, 0 insertions, 263 deletions
diff --git a/libs/assimp/code/PostProcessing/ArmaturePopulate.cpp b/libs/assimp/code/PostProcessing/ArmaturePopulate.cpp deleted file mode 100644 index 3fc1e12..0000000 --- a/libs/assimp/code/PostProcessing/ArmaturePopulate.cpp +++ /dev/null @@ -1,263 +0,0 @@ -/* -Open Asset Import Library (assimp) ----------------------------------------------------------------------- - -Copyright (c) 2006-2022, assimp team - -All rights reserved. - -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the -following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of the assimp team, nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of the assimp team. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ----------------------------------------------------------------------- -*/ -#include "ArmaturePopulate.h" - -#include <assimp/BaseImporter.h> -#include <assimp/DefaultLogger.hpp> -#include <assimp/postprocess.h> -#include <assimp/scene.h> -#include <iostream> - -namespace Assimp { - -/// The default class constructor. -ArmaturePopulate::ArmaturePopulate() : - BaseProcess() { - // do nothing -} - -/// The class destructor. -ArmaturePopulate::~ArmaturePopulate() { - // do nothing -} - -bool ArmaturePopulate::IsActive(unsigned int pFlags) const { - return (pFlags & aiProcess_PopulateArmatureData) != 0; -} - -void ArmaturePopulate::SetupProperties(const Importer *) { - // do nothing -} - -void ArmaturePopulate::Execute(aiScene *out) { - - // Now convert all bone positions to the correct mOffsetMatrix - std::vector<aiBone *> bones; - std::vector<aiNode *> nodes; - std::map<aiBone *, aiNode *> bone_stack; - BuildBoneList(out->mRootNode, out->mRootNode, out, bones); - BuildNodeList(out->mRootNode, nodes); - - BuildBoneStack(out->mRootNode, out->mRootNode, out, bones, bone_stack, nodes); - - ASSIMP_LOG_DEBUG("Bone stack size: ", bone_stack.size()); - - for (std::pair<aiBone *, aiNode *> kvp : bone_stack) { - aiBone *bone = kvp.first; - aiNode *bone_node = kvp.second; - ASSIMP_LOG_VERBOSE_DEBUG("active node lookup: ", bone->mName.C_Str()); - // lcl transform grab - done in generate_nodes :) - - // bone->mOffsetMatrix = bone_node->mTransformation; - aiNode *armature = GetArmatureRoot(bone_node, bones); - - ai_assert(armature); - - // set up bone armature id - bone->mArmature = armature; - - // set this bone node to be referenced properly - ai_assert(bone_node); - bone->mNode = bone_node; - } -} - - -// Reprocess all nodes to calculate bone transforms properly based on the REAL -// mOffsetMatrix not the local. -// Before this would use mesh transforms which is wrong for bone transforms -// Before this would work for simple character skeletons but not complex meshes -// with multiple origins -// Source: sketch fab log cutter fbx -void ArmaturePopulate::BuildBoneList(aiNode *current_node, - const aiNode *root_node, - const aiScene *scene, - std::vector<aiBone *> &bones) { - ai_assert(scene); - for (unsigned int nodeId = 0; nodeId < current_node->mNumChildren; ++nodeId) { - aiNode *child = current_node->mChildren[nodeId]; - ai_assert(child); - - // check for bones - for (unsigned int meshId = 0; meshId < child->mNumMeshes; ++meshId) { - ai_assert(child->mMeshes); - unsigned int mesh_index = child->mMeshes[meshId]; - aiMesh *mesh = scene->mMeshes[mesh_index]; - ai_assert(mesh); - - for (unsigned int boneId = 0; boneId < mesh->mNumBones; ++boneId) { - aiBone *bone = mesh->mBones[boneId]; - ai_assert(nullptr != bone); - - // duplicate mehes exist with the same bones sometimes :) - // so this must be detected - if (std::find(bones.begin(), bones.end(), bone) == bones.end()) { - // add the element once - bones.emplace_back(bone); - } - } - - // find mesh and get bones - // then do recursive lookup for bones in root node hierarchy - } - - BuildBoneList(child, root_node, scene, bones); - } -} - -// Prepare flat node list which can be used for non recursive lookups later -void ArmaturePopulate::BuildNodeList(const aiNode *current_node, - std::vector<aiNode *> &nodes) { - ai_assert(nullptr != current_node); - - for (unsigned int nodeId = 0; nodeId < current_node->mNumChildren; ++nodeId) { - aiNode *child = current_node->mChildren[nodeId]; - ai_assert(child); - - if (child->mNumMeshes == 0) { - nodes.emplace_back(child); - } - - BuildNodeList(child, nodes); - } -} - -// A bone stack allows us to have multiple armatures, with the same bone names -// A bone stack allows us also to retrieve bones true transform even with -// duplicate names :) -void ArmaturePopulate::BuildBoneStack(aiNode *, - const aiNode *root_node, - const aiScene*, - const std::vector<aiBone *> &bones, - std::map<aiBone *, aiNode *> &bone_stack, - std::vector<aiNode *> &node_stack) { - if (node_stack.empty()) { - return; - } - ai_assert(nullptr != root_node); - - for (aiBone *bone : bones) { - ai_assert(bone); - aiNode *node = GetNodeFromStack(bone->mName, node_stack); - if (node == nullptr) { - node_stack.clear(); - BuildNodeList(root_node, node_stack); - ASSIMP_LOG_VERBOSE_DEBUG("Resetting bone stack: nullptr element ", bone->mName.C_Str()); - - node = GetNodeFromStack(bone->mName, node_stack); - - if (nullptr == node) { - ASSIMP_LOG_ERROR("serious import issue node for bone was not detected"); - continue; - } - } - - ASSIMP_LOG_VERBOSE_DEBUG("Successfully added bone[", bone->mName.C_Str(), "] to stack and bone node is: ", node->mName.C_Str()); - - bone_stack.insert(std::pair<aiBone *, aiNode *>(bone, node)); - } -} - -// Returns the armature root node -// This is required to be detected for a bone initially, it will recurse up -// until it cannot find another bone and return the node No known failure -// points. (yet) -aiNode *ArmaturePopulate::GetArmatureRoot(aiNode *bone_node, - std::vector<aiBone *> &bone_list) { - while (nullptr != bone_node) { - if (!IsBoneNode(bone_node->mName, bone_list)) { - ASSIMP_LOG_VERBOSE_DEBUG("GetArmatureRoot() Found valid armature: ", bone_node->mName.C_Str()); - return bone_node; - } - - bone_node = bone_node->mParent; - } - - ASSIMP_LOG_ERROR("GetArmatureRoot() can't find armature!"); - - return nullptr; -} - -// Simple IsBoneNode check if this could be a bone -bool ArmaturePopulate::IsBoneNode(const aiString &bone_name, - std::vector<aiBone *> &bones) { - for (aiBone *bone : bones) { - if (bone->mName == bone_name) { - return true; - } - } - - return false; -} - -// Pop this node by name from the stack if found -// Used in multiple armature situations with duplicate node / bone names -// Known flaw: cannot have nodes with bone names, will be fixed in later release -// (serious to be fixed) Known flaw: nodes which have more than one bone could -// be prematurely dropped from stack -aiNode *ArmaturePopulate::GetNodeFromStack(const aiString &node_name, - std::vector<aiNode *> &nodes) { - std::vector<aiNode *>::iterator iter; - aiNode *found = nullptr; - for (iter = nodes.begin(); iter < nodes.end(); ++iter) { - aiNode *element = *iter; - ai_assert(nullptr != element); - // node valid and node name matches - if (element->mName == node_name) { - found = element; - break; - } - } - - if (found != nullptr) { - ASSIMP_LOG_INFO("Removed node from stack: ", found->mName.C_Str()); - // now pop the element from the node list - nodes.erase(iter); - - return found; - } - - // unique names can cause this problem - ASSIMP_LOG_ERROR("[Serious] GetNodeFromStack() can't find node from stack!"); - - return nullptr; -} - -} // Namespace Assimp |