diff options
Diffstat (limited to 'src/3rdparty/assimp/code/SkeletonMeshBuilder.cpp')
-rw-r--r-- | src/3rdparty/assimp/code/SkeletonMeshBuilder.cpp | 413 |
1 files changed, 207 insertions, 206 deletions
diff --git a/src/3rdparty/assimp/code/SkeletonMeshBuilder.cpp b/src/3rdparty/assimp/code/SkeletonMeshBuilder.cpp index 7e0d68a9f..ec7aa8985 100644 --- a/src/3rdparty/assimp/code/SkeletonMeshBuilder.cpp +++ b/src/3rdparty/assimp/code/SkeletonMeshBuilder.cpp @@ -2,11 +2,11 @@ Open Asset Import Library (assimp) ---------------------------------------------------------------------- -Copyright (c) 2006-2012, assimp team +Copyright (c) 2006-2016, 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 +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 @@ -23,245 +23,246 @@ 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 +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 +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 +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 +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. ---------------------------------------------------------------------- */ /** @file SkeletonMeshBuilder.cpp - * @brief Implementation of a little class to construct a dummy mesh for a skeleton + * @brief Implementation of a little class to construct a dummy mesh for a skeleton */ -#include "AssimpPCH.h" -#include "../include/assimp/scene.h" +#include <assimp/scene.h> #include "SkeletonMeshBuilder.h" using namespace Assimp; // ------------------------------------------------------------------------------------------------ -// The constructor processes the given scene and adds a mesh there. +// The constructor processes the given scene and adds a mesh there. SkeletonMeshBuilder::SkeletonMeshBuilder( aiScene* pScene, aiNode* root, bool bKnobsOnly) { - // nothing to do if there's mesh data already present at the scene - if( pScene->mNumMeshes > 0 || pScene->mRootNode == NULL) - return; - - if (!root) - root = pScene->mRootNode; - - mKnobsOnly = bKnobsOnly; - - // build some faces around each node - CreateGeometry( root ); - - // create a mesh to hold all the generated faces - pScene->mNumMeshes = 1; - pScene->mMeshes = new aiMesh*[1]; - pScene->mMeshes[0] = CreateMesh(); - // and install it at the root node - root->mNumMeshes = 1; - root->mMeshes = new unsigned int[1]; - root->mMeshes[0] = 0; - - // create a dummy material for the mesh - pScene->mNumMaterials = 1; - pScene->mMaterials = new aiMaterial*[1]; - pScene->mMaterials[0] = CreateMaterial(); + // nothing to do if there's mesh data already present at the scene + if( pScene->mNumMeshes > 0 || pScene->mRootNode == NULL) + return; + + if (!root) + root = pScene->mRootNode; + + mKnobsOnly = bKnobsOnly; + + // build some faces around each node + CreateGeometry( root ); + + // create a mesh to hold all the generated faces + pScene->mNumMeshes = 1; + pScene->mMeshes = new aiMesh*[1]; + pScene->mMeshes[0] = CreateMesh(); + // and install it at the root node + root->mNumMeshes = 1; + root->mMeshes = new unsigned int[1]; + root->mMeshes[0] = 0; + + // create a dummy material for the mesh + if(pScene->mNumMaterials==0){ + pScene->mNumMaterials = 1; + pScene->mMaterials = new aiMaterial*[1]; + pScene->mMaterials[0] = CreateMaterial(); + } } // ------------------------------------------------------------------------------------------------ -// Recursively builds a simple mesh representation for the given node +// Recursively builds a simple mesh representation for the given node void SkeletonMeshBuilder::CreateGeometry( const aiNode* pNode) { - // add a joint entry for the node. - const unsigned int vertexStartIndex = mVertices.size(); - - // now build the geometry. - if( pNode->mNumChildren > 0 && !mKnobsOnly) - { - // If the node has children, we build little pointers to each of them - for( unsigned int a = 0; a < pNode->mNumChildren; a++) - { - // find a suitable coordinate system - const aiMatrix4x4& childTransform = pNode->mChildren[a]->mTransformation; - aiVector3D childpos( childTransform.a4, childTransform.b4, childTransform.c4); - float distanceToChild = childpos.Length(); - if( distanceToChild < 0.0001f) - continue; - aiVector3D up = aiVector3D( childpos).Normalize(); - - aiVector3D orth( 1.0f, 0.0f, 0.0f); - if( std::fabs( orth * up) > 0.99f) - orth.Set( 0.0f, 1.0f, 0.0f); - - aiVector3D front = (up ^ orth).Normalize(); - aiVector3D side = (front ^ up).Normalize(); - - unsigned int localVertexStart = mVertices.size(); - mVertices.push_back( -front * distanceToChild * 0.1f); - mVertices.push_back( childpos); - mVertices.push_back( -side * distanceToChild * 0.1f); - mVertices.push_back( -side * distanceToChild * 0.1f); - mVertices.push_back( childpos); - mVertices.push_back( front * distanceToChild * 0.1f); - mVertices.push_back( front * distanceToChild * 0.1f); - mVertices.push_back( childpos); - mVertices.push_back( side * distanceToChild * 0.1f); - mVertices.push_back( side * distanceToChild * 0.1f); - mVertices.push_back( childpos); - mVertices.push_back( -front * distanceToChild * 0.1f); - - mFaces.push_back( Face( localVertexStart + 0, localVertexStart + 1, localVertexStart + 2)); - mFaces.push_back( Face( localVertexStart + 3, localVertexStart + 4, localVertexStart + 5)); - mFaces.push_back( Face( localVertexStart + 6, localVertexStart + 7, localVertexStart + 8)); - mFaces.push_back( Face( localVertexStart + 9, localVertexStart + 10, localVertexStart + 11)); - } - } - else - { - // if the node has no children, it's an end node. Put a little knob there instead - aiVector3D ownpos( pNode->mTransformation.a4, pNode->mTransformation.b4, pNode->mTransformation.c4); - float sizeEstimate = ownpos.Length() * 0.18f; - - mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f)); - mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f)); - mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate)); - mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f)); - mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f)); - mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate)); - mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f)); - mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f)); - mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate)); - mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f)); - mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f)); - mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate)); - - mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f)); - mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate)); - mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f)); - mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f)); - mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate)); - mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f)); - mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f)); - mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate)); - mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f)); - mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f)); - mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate)); - mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f)); - - mFaces.push_back( Face( vertexStartIndex + 0, vertexStartIndex + 1, vertexStartIndex + 2)); - mFaces.push_back( Face( vertexStartIndex + 3, vertexStartIndex + 4, vertexStartIndex + 5)); - mFaces.push_back( Face( vertexStartIndex + 6, vertexStartIndex + 7, vertexStartIndex + 8)); - mFaces.push_back( Face( vertexStartIndex + 9, vertexStartIndex + 10, vertexStartIndex + 11)); - mFaces.push_back( Face( vertexStartIndex + 12, vertexStartIndex + 13, vertexStartIndex + 14)); - mFaces.push_back( Face( vertexStartIndex + 15, vertexStartIndex + 16, vertexStartIndex + 17)); - mFaces.push_back( Face( vertexStartIndex + 18, vertexStartIndex + 19, vertexStartIndex + 20)); - mFaces.push_back( Face( vertexStartIndex + 21, vertexStartIndex + 22, vertexStartIndex + 23)); - } - - unsigned int numVertices = mVertices.size() - vertexStartIndex; - if( numVertices > 0) - { - // create a bone affecting all the newly created vertices - aiBone* bone = new aiBone; - mBones.push_back( bone); - bone->mName = pNode->mName; - - // calculate the bone offset matrix by concatenating the inverse transformations of all parents - bone->mOffsetMatrix = aiMatrix4x4( pNode->mTransformation).Inverse(); - for( aiNode* parent = pNode->mParent; parent != NULL; parent = parent->mParent) - bone->mOffsetMatrix = aiMatrix4x4( parent->mTransformation).Inverse() * bone->mOffsetMatrix; - - // add all the vertices to the bone's influences - bone->mNumWeights = numVertices; - bone->mWeights = new aiVertexWeight[numVertices]; - for( unsigned int a = 0; a < numVertices; a++) - bone->mWeights[a] = aiVertexWeight( vertexStartIndex + a, 1.0f); - - // HACK: (thom) transform all vertices to the bone's local space. Should be done before adding - // them to the array, but I'm tired now and I'm annoyed. - aiMatrix4x4 boneToMeshTransform = aiMatrix4x4( bone->mOffsetMatrix).Inverse(); - for( unsigned int a = vertexStartIndex; a < mVertices.size(); a++) - mVertices[a] = boneToMeshTransform * mVertices[a]; - } - - // and finally recurse into the children list - for( unsigned int a = 0; a < pNode->mNumChildren; a++) - CreateGeometry( pNode->mChildren[a]); + // add a joint entry for the node. + const unsigned int vertexStartIndex = mVertices.size(); + + // now build the geometry. + if( pNode->mNumChildren > 0 && !mKnobsOnly) + { + // If the node has children, we build little pointers to each of them + for( unsigned int a = 0; a < pNode->mNumChildren; a++) + { + // find a suitable coordinate system + const aiMatrix4x4& childTransform = pNode->mChildren[a]->mTransformation; + aiVector3D childpos( childTransform.a4, childTransform.b4, childTransform.c4); + float distanceToChild = childpos.Length(); + if( distanceToChild < 0.0001f) + continue; + aiVector3D up = aiVector3D( childpos).Normalize(); + + aiVector3D orth( 1.0f, 0.0f, 0.0f); + if( std::fabs( orth * up) > 0.99f) + orth.Set( 0.0f, 1.0f, 0.0f); + + aiVector3D front = (up ^ orth).Normalize(); + aiVector3D side = (front ^ up).Normalize(); + + unsigned int localVertexStart = mVertices.size(); + mVertices.push_back( -front * distanceToChild * 0.1f); + mVertices.push_back( childpos); + mVertices.push_back( -side * distanceToChild * 0.1f); + mVertices.push_back( -side * distanceToChild * 0.1f); + mVertices.push_back( childpos); + mVertices.push_back( front * distanceToChild * 0.1f); + mVertices.push_back( front * distanceToChild * 0.1f); + mVertices.push_back( childpos); + mVertices.push_back( side * distanceToChild * 0.1f); + mVertices.push_back( side * distanceToChild * 0.1f); + mVertices.push_back( childpos); + mVertices.push_back( -front * distanceToChild * 0.1f); + + mFaces.push_back( Face( localVertexStart + 0, localVertexStart + 1, localVertexStart + 2)); + mFaces.push_back( Face( localVertexStart + 3, localVertexStart + 4, localVertexStart + 5)); + mFaces.push_back( Face( localVertexStart + 6, localVertexStart + 7, localVertexStart + 8)); + mFaces.push_back( Face( localVertexStart + 9, localVertexStart + 10, localVertexStart + 11)); + } + } + else + { + // if the node has no children, it's an end node. Put a little knob there instead + aiVector3D ownpos( pNode->mTransformation.a4, pNode->mTransformation.b4, pNode->mTransformation.c4); + float sizeEstimate = ownpos.Length() * 0.18f; + + mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f)); + mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f)); + mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate)); + mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f)); + mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f)); + mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate)); + mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f)); + mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f)); + mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate)); + mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f)); + mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f)); + mVertices.push_back( aiVector3D( 0.0f, 0.0f, -sizeEstimate)); + + mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f)); + mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate)); + mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f)); + mVertices.push_back( aiVector3D( 0.0f, sizeEstimate, 0.0f)); + mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate)); + mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f)); + mVertices.push_back( aiVector3D( sizeEstimate, 0.0f, 0.0f)); + mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate)); + mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f)); + mVertices.push_back( aiVector3D( 0.0f, -sizeEstimate, 0.0f)); + mVertices.push_back( aiVector3D( 0.0f, 0.0f, sizeEstimate)); + mVertices.push_back( aiVector3D( -sizeEstimate, 0.0f, 0.0f)); + + mFaces.push_back( Face( vertexStartIndex + 0, vertexStartIndex + 1, vertexStartIndex + 2)); + mFaces.push_back( Face( vertexStartIndex + 3, vertexStartIndex + 4, vertexStartIndex + 5)); + mFaces.push_back( Face( vertexStartIndex + 6, vertexStartIndex + 7, vertexStartIndex + 8)); + mFaces.push_back( Face( vertexStartIndex + 9, vertexStartIndex + 10, vertexStartIndex + 11)); + mFaces.push_back( Face( vertexStartIndex + 12, vertexStartIndex + 13, vertexStartIndex + 14)); + mFaces.push_back( Face( vertexStartIndex + 15, vertexStartIndex + 16, vertexStartIndex + 17)); + mFaces.push_back( Face( vertexStartIndex + 18, vertexStartIndex + 19, vertexStartIndex + 20)); + mFaces.push_back( Face( vertexStartIndex + 21, vertexStartIndex + 22, vertexStartIndex + 23)); + } + + unsigned int numVertices = mVertices.size() - vertexStartIndex; + if( numVertices > 0) + { + // create a bone affecting all the newly created vertices + aiBone* bone = new aiBone; + mBones.push_back( bone); + bone->mName = pNode->mName; + + // calculate the bone offset matrix by concatenating the inverse transformations of all parents + bone->mOffsetMatrix = aiMatrix4x4( pNode->mTransformation).Inverse(); + for( aiNode* parent = pNode->mParent; parent != NULL; parent = parent->mParent) + bone->mOffsetMatrix = aiMatrix4x4( parent->mTransformation).Inverse() * bone->mOffsetMatrix; + + // add all the vertices to the bone's influences + bone->mNumWeights = numVertices; + bone->mWeights = new aiVertexWeight[numVertices]; + for( unsigned int a = 0; a < numVertices; a++) + bone->mWeights[a] = aiVertexWeight( vertexStartIndex + a, 1.0f); + + // HACK: (thom) transform all vertices to the bone's local space. Should be done before adding + // them to the array, but I'm tired now and I'm annoyed. + aiMatrix4x4 boneToMeshTransform = aiMatrix4x4( bone->mOffsetMatrix).Inverse(); + for( unsigned int a = vertexStartIndex; a < mVertices.size(); a++) + mVertices[a] = boneToMeshTransform * mVertices[a]; + } + + // and finally recurse into the children list + for( unsigned int a = 0; a < pNode->mNumChildren; a++) + CreateGeometry( pNode->mChildren[a]); } // ------------------------------------------------------------------------------------------------ // Creates the mesh from the internally accumulated stuff and returns it. aiMesh* SkeletonMeshBuilder::CreateMesh() { - aiMesh* mesh = new aiMesh(); - - // add points - mesh->mNumVertices = mVertices.size(); - mesh->mVertices = new aiVector3D[mesh->mNumVertices]; - std::copy( mVertices.begin(), mVertices.end(), mesh->mVertices); - - mesh->mNormals = new aiVector3D[mesh->mNumVertices]; - - // add faces - mesh->mNumFaces = mFaces.size(); - mesh->mFaces = new aiFace[mesh->mNumFaces]; - for( unsigned int a = 0; a < mesh->mNumFaces; a++) - { - const Face& inface = mFaces[a]; - aiFace& outface = mesh->mFaces[a]; - outface.mNumIndices = 3; - outface.mIndices = new unsigned int[3]; - outface.mIndices[0] = inface.mIndices[0]; - outface.mIndices[1] = inface.mIndices[1]; - outface.mIndices[2] = inface.mIndices[2]; - - // Compute per-face normals ... we don't want the bones to be smoothed ... they're built to visualize - // the skeleton, so it's good if there's a visual difference to the rest of the geometry - aiVector3D nor = ((mVertices[inface.mIndices[2]] - mVertices[inface.mIndices[0]]) ^ - (mVertices[inface.mIndices[1]] - mVertices[inface.mIndices[0]])); - - if (nor.Length() < 1e-5f) /* ensure that FindInvalidData won't remove us ...*/ - nor = aiVector3D(1.f,0.f,0.f); - - for (unsigned int n = 0; n < 3; ++n) - mesh->mNormals[inface.mIndices[n]] = nor; - } - - // add the bones - mesh->mNumBones = mBones.size(); - mesh->mBones = new aiBone*[mesh->mNumBones]; - std::copy( mBones.begin(), mBones.end(), mesh->mBones); - - // default - mesh->mMaterialIndex = 0; - - return mesh; + aiMesh* mesh = new aiMesh(); + + // add points + mesh->mNumVertices = mVertices.size(); + mesh->mVertices = new aiVector3D[mesh->mNumVertices]; + std::copy( mVertices.begin(), mVertices.end(), mesh->mVertices); + + mesh->mNormals = new aiVector3D[mesh->mNumVertices]; + + // add faces + mesh->mNumFaces = mFaces.size(); + mesh->mFaces = new aiFace[mesh->mNumFaces]; + for( unsigned int a = 0; a < mesh->mNumFaces; a++) + { + const Face& inface = mFaces[a]; + aiFace& outface = mesh->mFaces[a]; + outface.mNumIndices = 3; + outface.mIndices = new unsigned int[3]; + outface.mIndices[0] = inface.mIndices[0]; + outface.mIndices[1] = inface.mIndices[1]; + outface.mIndices[2] = inface.mIndices[2]; + + // Compute per-face normals ... we don't want the bones to be smoothed ... they're built to visualize + // the skeleton, so it's good if there's a visual difference to the rest of the geometry + aiVector3D nor = ((mVertices[inface.mIndices[2]] - mVertices[inface.mIndices[0]]) ^ + (mVertices[inface.mIndices[1]] - mVertices[inface.mIndices[0]])); + + if (nor.Length() < 1e-5f) /* ensure that FindInvalidData won't remove us ...*/ + nor = aiVector3D(1.f,0.f,0.f); + + for (unsigned int n = 0; n < 3; ++n) + mesh->mNormals[inface.mIndices[n]] = nor; + } + + // add the bones + mesh->mNumBones = mBones.size(); + mesh->mBones = new aiBone*[mesh->mNumBones]; + std::copy( mBones.begin(), mBones.end(), mesh->mBones); + + // default + mesh->mMaterialIndex = 0; + + return mesh; } // ------------------------------------------------------------------------------------------------ // Creates a dummy material and returns it. aiMaterial* SkeletonMeshBuilder::CreateMaterial() { - aiMaterial* matHelper = new aiMaterial; + aiMaterial* matHelper = new aiMaterial; - // Name - aiString matName( std::string( "SkeletonMaterial")); - matHelper->AddProperty( &matName, AI_MATKEY_NAME); + // Name + aiString matName( std::string( "SkeletonMaterial")); + matHelper->AddProperty( &matName, AI_MATKEY_NAME); - // Prevent backface culling - const int no_cull = 1; - matHelper->AddProperty(&no_cull,1,AI_MATKEY_TWOSIDED); + // Prevent backface culling + const int no_cull = 1; + matHelper->AddProperty(&no_cull,1,AI_MATKEY_TWOSIDED); - return matHelper; + return matHelper; } |