Added ArmaturePopulate scale process for all formats
parent
93efe4197a
commit
46cdd81d75
|
@ -670,6 +670,8 @@ SET( PostProcessing_SRCS
|
||||||
PostProcessing/MakeVerboseFormat.h
|
PostProcessing/MakeVerboseFormat.h
|
||||||
PostProcessing/ScaleProcess.cpp
|
PostProcessing/ScaleProcess.cpp
|
||||||
PostProcessing/ScaleProcess.h
|
PostProcessing/ScaleProcess.h
|
||||||
|
PostProcessing/ArmaturePopulate.cpp
|
||||||
|
PostProcessing/ArmaturePopulate.h
|
||||||
PostProcessing/GenBoundingBoxesProcess.cpp
|
PostProcessing/GenBoundingBoxesProcess.cpp
|
||||||
PostProcessing/GenBoundingBoxesProcess.h
|
PostProcessing/GenBoundingBoxesProcess.h
|
||||||
)
|
)
|
||||||
|
|
|
@ -121,39 +121,6 @@ namespace Assimp {
|
||||||
ConvertGlobalSettings();
|
ConvertGlobalSettings();
|
||||||
TransferDataToScene();
|
TransferDataToScene();
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
std::cout << "Bone stack size: " << bone_stack.size() << std::endl;
|
|
||||||
|
|
||||||
for( std::pair<aiBone*, aiNode*> kvp : bone_stack )
|
|
||||||
{
|
|
||||||
aiBone *bone = kvp.first;
|
|
||||||
aiNode *bone_node = kvp.second;
|
|
||||||
std::cout << "active node lookup: " << bone->mName.C_Str() << std::endl;
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE
|
// if we didn't read any meshes set the AI_SCENE_FLAGS_INCOMPLETE
|
||||||
// to make sure the scene passes assimp's validation. FBX files
|
// to make sure the scene passes assimp's validation. FBX files
|
||||||
// need not contain geometry (i.e. camera animations, raw armatures).
|
// need not contain geometry (i.e. camera animations, raw armatures).
|
||||||
|
@ -172,167 +139,6 @@ namespace Assimp {
|
||||||
std::for_each(textures.begin(), textures.end(), Util::delete_fun<aiTexture>());
|
std::for_each(textures.begin(), textures.end(), Util::delete_fun<aiTexture>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 * FBXConverter::GetArmatureRoot(aiNode *bone_node, std::vector<aiBone*> &bone_list)
|
|
||||||
{
|
|
||||||
while(bone_node)
|
|
||||||
{
|
|
||||||
if(!IsBoneNode(bone_node->mName, bone_list))
|
|
||||||
{
|
|
||||||
std::cout << "Found valid armature: " << bone_node->mName.C_Str() << std::endl;
|
|
||||||
return bone_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
bone_node = bone_node->mParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "can't find armature! node: " << bone_node << std::endl;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Simple IsBoneNode check if this could be a bone */
|
|
||||||
bool FBXConverter::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* FBXConverter::GetNodeFromStack(const aiString &node_name, std::vector<aiNode*> &nodes)
|
|
||||||
{
|
|
||||||
std::vector<aiNode*>::iterator iter;
|
|
||||||
aiNode *found = NULL;
|
|
||||||
for( iter = nodes.begin(); iter < nodes.end(); ++iter )
|
|
||||||
{
|
|
||||||
aiNode *element = *iter;
|
|
||||||
ai_assert(element);
|
|
||||||
// node valid and node name matches
|
|
||||||
if(element->mName == node_name)
|
|
||||||
{
|
|
||||||
found = element;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(found != NULL) {
|
|
||||||
// now pop the element from the node list
|
|
||||||
nodes.erase(iter);
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepare flat node list which can be used for non recursive lookups later */
|
|
||||||
void FBXConverter::BuildNodeList(aiNode *current_node, std::vector<aiNode *> &nodes)
|
|
||||||
{
|
|
||||||
ai_assert(current_node);
|
|
||||||
|
|
||||||
for( unsigned int nodeId = 0; nodeId < current_node->mNumChildren; ++nodeId)
|
|
||||||
{
|
|
||||||
aiNode *child = current_node->mChildren[nodeId];
|
|
||||||
ai_assert(child);
|
|
||||||
|
|
||||||
nodes.push_back(child);
|
|
||||||
|
|
||||||
BuildNodeList(child, nodes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 FBXConverter::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(bone);
|
|
||||||
|
|
||||||
// duplicate meshes 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.push_back(bone);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// find mesh and get bones
|
|
||||||
// then do recursive lookup for bones in root node hierarchy
|
|
||||||
}
|
|
||||||
|
|
||||||
BuildBoneList(child, root_node, scene, bones);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 FBXConverter::BuildBoneStack(aiNode *current_node, const aiNode *root_node, const aiScene *scene,
|
|
||||||
const std::vector<aiBone *> &bones,
|
|
||||||
std::map<aiBone *, aiNode *> &bone_stack,
|
|
||||||
std::vector<aiNode*> &node_stack )
|
|
||||||
{
|
|
||||||
ai_assert(scene);
|
|
||||||
ai_assert(root_node);
|
|
||||||
ai_assert(!node_stack.empty());
|
|
||||||
|
|
||||||
for( aiBone * bone : bones)
|
|
||||||
{
|
|
||||||
ai_assert(bone);
|
|
||||||
aiNode* node = GetNodeFromStack(bone->mName, node_stack);
|
|
||||||
if(node == NULL)
|
|
||||||
{
|
|
||||||
node_stack.clear();
|
|
||||||
BuildNodeList(out->mRootNode, node_stack );
|
|
||||||
std::cout << "Resetting bone stack: null element " << bone->mName.C_Str() << std::endl;
|
|
||||||
|
|
||||||
node = GetNodeFromStack(bone->mName, node_stack);
|
|
||||||
|
|
||||||
if(!node) {
|
|
||||||
std::cout << "serious import issue armature failed to be detected?" << std::endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "Successfully added bone to stack and have valid armature: " << bone->mName.C_Str() << std::endl;
|
|
||||||
|
|
||||||
bone_stack.insert(std::pair<aiBone*, aiNode*>(bone, node));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FBXConverter::ConvertRootNode() {
|
void FBXConverter::ConvertRootNode() {
|
||||||
out->mRootNode = new aiNode();
|
out->mRootNode = new aiNode();
|
||||||
std::string unique_name;
|
std::string unique_name;
|
||||||
|
|
|
@ -0,0 +1,247 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2019, 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>
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
bool ArmaturePopulate::IsActive(unsigned int pFlags) const {
|
||||||
|
return (pFlags & aiProcess_PopulateArmatureData) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ArmaturePopulate::SetupProperties(const Importer *pImp) {
|
||||||
|
// 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_F("Bone stack size: %ld\n", bone_stack.size());
|
||||||
|
|
||||||
|
for (std::pair<aiBone *, aiNode *> kvp : bone_stack) {
|
||||||
|
aiBone *bone = kvp.first;
|
||||||
|
aiNode *bone_node = kvp.second;
|
||||||
|
ASSIMP_LOG_DEBUG_F("active node lookup: %s\n", 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 (bone_node) {
|
||||||
|
if (!IsBoneNode(bone_node->mName, bone_list)) {
|
||||||
|
ASSIMP_LOG_DEBUG_F("Found valid armature: %s\n", bone_node->mName.C_Str());
|
||||||
|
return bone_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
bone_node = bone_node->mParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSIMP_LOG_WARN_F("can't find armature! node: %s\n", bone_node->mName.C_Str());
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 = NULL;
|
||||||
|
for (iter = nodes.begin(); iter < nodes.end(); ++iter) {
|
||||||
|
aiNode *element = *iter;
|
||||||
|
ai_assert(element);
|
||||||
|
// node valid and node name matches
|
||||||
|
if (element->mName == node_name) {
|
||||||
|
found = element;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found != NULL) {
|
||||||
|
// now pop the element from the node list
|
||||||
|
nodes.erase(iter);
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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(current_node);
|
||||||
|
|
||||||
|
for (unsigned int nodeId = 0; nodeId < current_node->mNumChildren; ++nodeId) {
|
||||||
|
aiNode *child = current_node->mChildren[nodeId];
|
||||||
|
ai_assert(child);
|
||||||
|
|
||||||
|
nodes.push_back(child);
|
||||||
|
|
||||||
|
BuildNodeList(child, nodes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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(bone);
|
||||||
|
|
||||||
|
// duplicate meshes 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.push_back(bone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// find mesh and get bones
|
||||||
|
// then do recursive lookup for bones in root node hierarchy
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildBoneList(child, root_node, scene, bones);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 *current_node,
|
||||||
|
const aiNode *root_node,
|
||||||
|
const aiScene *scene,
|
||||||
|
const std::vector<aiBone *> &bones,
|
||||||
|
std::map<aiBone *, aiNode *> &bone_stack,
|
||||||
|
std::vector<aiNode *> &node_stack) {
|
||||||
|
ai_assert(scene);
|
||||||
|
ai_assert(root_node);
|
||||||
|
ai_assert(!node_stack.empty());
|
||||||
|
|
||||||
|
for (aiBone *bone : bones) {
|
||||||
|
ai_assert(bone);
|
||||||
|
aiNode *node = GetNodeFromStack(bone->mName, node_stack);
|
||||||
|
if (node == NULL) {
|
||||||
|
node_stack.clear();
|
||||||
|
BuildNodeList(root_node, node_stack);
|
||||||
|
ASSIMP_LOG_DEBUG_F("Resetting bone stack: null element %s\n", bone->mName.C_Str());
|
||||||
|
|
||||||
|
node = GetNodeFromStack(bone->mName, node_stack);
|
||||||
|
|
||||||
|
if (!node) {
|
||||||
|
ASSIMP_LOG_ERROR("serious import issue armature failed to be detected");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSIMP_LOG_DEBUG_F("Successfully added bone to stack and have valid armature: %s\n", bone->mName.C_Str());
|
||||||
|
|
||||||
|
bone_stack.insert(std::pair<aiBone *, aiNode *>(bone, node));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Namespace Assimp
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2019, 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.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#ifndef SCALE_PROCESS_H_
|
||||||
|
#define SCALE_PROCESS_H_
|
||||||
|
|
||||||
|
#include "Common/BaseProcess.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
struct aiNode;
|
||||||
|
struct aiBone;
|
||||||
|
|
||||||
|
#if (!defined AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT)
|
||||||
|
# define AI_CONFIG_GLOBAL_SCALE_FACTOR_DEFAULT 1.0f
|
||||||
|
#endif // !! AI_DEBONE_THRESHOLD
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
/** ScaleProcess: Class to rescale the whole model.
|
||||||
|
* Now rescales animations, bones, and blend shapes properly.
|
||||||
|
* Please note this will not write to 'scale' transform it will rewrite mesh
|
||||||
|
* and matrixes so that your scale values
|
||||||
|
* from your model package are preserved, so this is completely intentional
|
||||||
|
* bugs should be reported as soon as they are found.
|
||||||
|
*/
|
||||||
|
class ASSIMP_API ArmaturePopulate : public BaseProcess {
|
||||||
|
public:
|
||||||
|
/// The default class constructor.
|
||||||
|
ArmaturePopulate() : BaseProcess()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/// The class destructor.
|
||||||
|
virtual ~ArmaturePopulate()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/// Overwritten, @see BaseProcess
|
||||||
|
virtual bool IsActive( unsigned int pFlags ) const;
|
||||||
|
|
||||||
|
/// Overwritten, @see BaseProcess
|
||||||
|
virtual void SetupProperties( const Importer* pImp );
|
||||||
|
|
||||||
|
/// Overwritten, @see BaseProcess
|
||||||
|
virtual void Execute( aiScene* pScene );
|
||||||
|
|
||||||
|
static aiNode *GetArmatureRoot(aiNode *bone_node,
|
||||||
|
std::vector<aiBone *> &bone_list);
|
||||||
|
|
||||||
|
static bool IsBoneNode(const aiString &bone_name,
|
||||||
|
std::vector<aiBone *> &bones);
|
||||||
|
|
||||||
|
static aiNode *GetNodeFromStack(const aiString &node_name,
|
||||||
|
std::vector<aiNode *> &nodes);
|
||||||
|
|
||||||
|
static void BuildNodeList(const aiNode *current_node,
|
||||||
|
std::vector<aiNode *> &nodes);
|
||||||
|
|
||||||
|
static void BuildBoneList(aiNode *current_node, const aiNode *root_node,
|
||||||
|
const aiScene *scene,
|
||||||
|
std::vector<aiBone *> &bones);
|
||||||
|
|
||||||
|
static void BuildBoneStack(aiNode *current_node, const aiNode *root_node,
|
||||||
|
const aiScene *scene,
|
||||||
|
const std::vector<aiBone *> &bones,
|
||||||
|
std::map<aiBone *, aiNode *> &bone_stack,
|
||||||
|
std::vector<aiNode *> &node_stack);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // Namespace Assimp
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SCALE_PROCESS_H_
|
|
@ -537,6 +537,18 @@ enum aiPostProcessSteps
|
||||||
*/
|
*/
|
||||||
aiProcess_Debone = 0x4000000,
|
aiProcess_Debone = 0x4000000,
|
||||||
|
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* This step generically populates aiBone->mArmature and aiBone->mNode generically
|
||||||
|
* The point of these is it saves you later having to calculate these elements
|
||||||
|
* This is useful when handling rest information or skin information
|
||||||
|
* If you have multiple armatures on your models we strongly recommend enabling this
|
||||||
|
* Instead of writing your own multi-root, multi-armature lookups we have done the
|
||||||
|
* hard work for you :)
|
||||||
|
*/
|
||||||
|
aiProcess_PopulateArmatureData = 0x5000000,
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
/** <hr>This step will perform a global scale of the model.
|
/** <hr>This step will perform a global scale of the model.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue