diff options
Diffstat (limited to 'src/3rdparty/assimp/code/XFileImporter.cpp')
-rw-r--r-- | src/3rdparty/assimp/code/XFileImporter.cpp | 699 |
1 files changed, 0 insertions, 699 deletions
diff --git a/src/3rdparty/assimp/code/XFileImporter.cpp b/src/3rdparty/assimp/code/XFileImporter.cpp deleted file mode 100644 index d100692d3..000000000 --- a/src/3rdparty/assimp/code/XFileImporter.cpp +++ /dev/null @@ -1,699 +0,0 @@ -/* ---------------------------------------------------------------------------- -Open Asset Import Library (assimp) ---------------------------------------------------------------------------- - -Copyright (c) 2006-2012, 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. ---------------------------------------------------------------------------- -*/ -/** @file XFileImporter.cpp - * @brief Implementation of the XFile importer class - */ - -#include "AssimpPCH.h" -#ifndef ASSIMP_BUILD_NO_X_IMPORTER - -#include "XFileImporter.h" -#include "XFileParser.h" -#include "ConvertToLHProcess.h" - -using namespace Assimp; - -static const aiImporterDesc desc = { - "Direct3D XFile Importer", - "", - "", - "", - aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportCompressedFlavour, - 1, - 3, - 1, - 5, - "x" -}; - -// ------------------------------------------------------------------------------------------------ -// Constructor to be privately used by Importer -XFileImporter::XFileImporter() -{} - -// ------------------------------------------------------------------------------------------------ -// Destructor, private as well -XFileImporter::~XFileImporter() -{} - -// ------------------------------------------------------------------------------------------------ -// Returns whether the class can handle the format of the given file. -bool XFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const -{ - std::string extension = GetExtension(pFile); - if(extension == "x") { - return true; - } - if (!extension.length() || checkSig) { - uint32_t token[1]; - token[0] = AI_MAKE_MAGIC("xof "); - return CheckMagicToken(pIOHandler,pFile,token,1,0); - } - return false; -} - -// ------------------------------------------------------------------------------------------------ -// Get file extension list -const aiImporterDesc* XFileImporter::GetInfo () const -{ - return &desc; -} - -// ------------------------------------------------------------------------------------------------ -// Imports the given file into the given scene structure. -void XFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) -{ - // read file into memory - boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile)); - if( file.get() == NULL) - throw DeadlyImportError( "Failed to open file " + pFile + "."); - - size_t fileSize = file->FileSize(); - if( fileSize < 16) - throw DeadlyImportError( "XFile is too small."); - - // in the hope that binary files will never start with a BOM ... - mBuffer.resize( fileSize + 1); - file->Read( &mBuffer.front(), 1, fileSize); - ConvertToUTF8(mBuffer); - - // parse the file into a temporary representation - XFileParser parser( mBuffer); - - // and create the proper return structures out of it - CreateDataRepresentationFromImport( pScene, parser.GetImportedData()); - - // if nothing came from it, report it as error - if( !pScene->mRootNode) - throw DeadlyImportError( "XFile is ill-formatted - no content imported."); -} - -// ------------------------------------------------------------------------------------------------ -// Constructs the return data structure out of the imported data. -void XFileImporter::CreateDataRepresentationFromImport( aiScene* pScene, XFile::Scene* pData) -{ - // Read the global materials first so that meshes referring to them can find them later - ConvertMaterials( pScene, pData->mGlobalMaterials); - - // copy nodes, extracting meshes and materials on the way - pScene->mRootNode = CreateNodes( pScene, NULL, pData->mRootNode); - - // extract animations - CreateAnimations( pScene, pData); - - // read the global meshes that were stored outside of any node - if( pData->mGlobalMeshes.size() > 0) - { - // create a root node to hold them if there isn't any, yet - if( pScene->mRootNode == NULL) - { - pScene->mRootNode = new aiNode; - pScene->mRootNode->mName.Set( "$dummy_node"); - } - - // convert all global meshes and store them in the root node. - // If there was one before, the global meshes now suddenly have its transformation matrix... - // Don't know what to do there, I don't want to insert another node under the present root node - // just to avoid this. - CreateMeshes( pScene, pScene->mRootNode, pData->mGlobalMeshes); - } - - // Convert everything to OpenGL space... it's the same operation as the conversion back, so we can reuse the step directly - MakeLeftHandedProcess convertProcess; - convertProcess.Execute( pScene); - - FlipWindingOrderProcess flipper; - flipper.Execute(pScene); - - // finally: create a dummy material if not material was imported - if( pScene->mNumMaterials == 0) - { - pScene->mNumMaterials = 1; - // create the Material - aiMaterial* mat = new aiMaterial; - int shadeMode = (int) aiShadingMode_Gouraud; - mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL); - // material colours - int specExp = 1; - - aiColor3D clr = aiColor3D( 0, 0, 0); - mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_EMISSIVE); - mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_SPECULAR); - - clr = aiColor3D( 0.5f, 0.5f, 0.5f); - mat->AddProperty( &clr, 1, AI_MATKEY_COLOR_DIFFUSE); - mat->AddProperty( &specExp, 1, AI_MATKEY_SHININESS); - - pScene->mMaterials = new aiMaterial*[1]; - pScene->mMaterials[0] = mat; - } -} - -// ------------------------------------------------------------------------------------------------ -// Recursively creates scene nodes from the imported hierarchy. -aiNode* XFileImporter::CreateNodes( aiScene* pScene, aiNode* pParent, const XFile::Node* pNode) -{ - if( !pNode) - return NULL; - - // create node - aiNode* node = new aiNode; - node->mName.length = pNode->mName.length(); - node->mParent = pParent; - memcpy( node->mName.data, pNode->mName.c_str(), pNode->mName.length()); - node->mName.data[node->mName.length] = 0; - node->mTransformation = pNode->mTrafoMatrix; - - // convert meshes from the source node - CreateMeshes( pScene, node, pNode->mMeshes); - - // handle childs - if( pNode->mChildren.size() > 0) - { - node->mNumChildren = (unsigned int)pNode->mChildren.size(); - node->mChildren = new aiNode* [node->mNumChildren]; - - for( unsigned int a = 0; a < pNode->mChildren.size(); a++) - node->mChildren[a] = CreateNodes( pScene, node, pNode->mChildren[a]); - } - - return node; -} - -// ------------------------------------------------------------------------------------------------ -// Creates the meshes for the given node. -void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vector<XFile::Mesh*>& pMeshes) -{ - if( pMeshes.size() == 0) - return; - - // create a mesh for each mesh-material combination in the source node - std::vector<aiMesh*> meshes; - for( unsigned int a = 0; a < pMeshes.size(); a++) - { - XFile::Mesh* sourceMesh = pMeshes[a]; - // first convert its materials so that we can find them with their index afterwards - ConvertMaterials( pScene, sourceMesh->mMaterials); - - unsigned int numMaterials = std::max( (unsigned int)sourceMesh->mMaterials.size(), 1u); - for( unsigned int b = 0; b < numMaterials; b++) - { - // collect the faces belonging to this material - std::vector<unsigned int> faces; - unsigned int numVertices = 0; - if( sourceMesh->mFaceMaterials.size() > 0) - { - // if there is a per-face material defined, select the faces with the corresponding material - for( unsigned int c = 0; c < sourceMesh->mFaceMaterials.size(); c++) - { - if( sourceMesh->mFaceMaterials[c] == b) - { - faces.push_back( c); - numVertices += (unsigned int)sourceMesh->mPosFaces[c].mIndices.size(); - } - } - } else - { - // if there is no per-face material, place everything into one mesh - for( unsigned int c = 0; c < sourceMesh->mPosFaces.size(); c++) - { - faces.push_back( c); - numVertices += (unsigned int)sourceMesh->mPosFaces[c].mIndices.size(); - } - } - - // no faces/vertices using this material? strange... - if( numVertices == 0) - continue; - - // create a submesh using this material - aiMesh* mesh = new aiMesh; - meshes.push_back( mesh); - - // find the material in the scene's material list. Either own material - // or referenced material, it should already have a valid index - if( sourceMesh->mFaceMaterials.size() > 0) - { - mesh->mMaterialIndex = sourceMesh->mMaterials[b].sceneIndex; - } else - { - mesh->mMaterialIndex = 0; - } - - // Create properly sized data arrays in the mesh. We store unique vertices per face, - // as specified - mesh->mNumVertices = numVertices; - mesh->mVertices = new aiVector3D[numVertices]; - mesh->mNumFaces = (unsigned int)faces.size(); - mesh->mFaces = new aiFace[mesh->mNumFaces]; - - // normals? - if( sourceMesh->mNormals.size() > 0) - mesh->mNormals = new aiVector3D[numVertices]; - // texture coords - for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS; c++) - { - if( sourceMesh->mTexCoords[c].size() > 0) - mesh->mTextureCoords[c] = new aiVector3D[numVertices]; - } - // vertex colors - for( unsigned int c = 0; c < AI_MAX_NUMBER_OF_COLOR_SETS; c++) - { - if( sourceMesh->mColors[c].size() > 0) - mesh->mColors[c] = new aiColor4D[numVertices]; - } - - // now collect the vertex data of all data streams present in the imported mesh - unsigned int newIndex = 0; - std::vector<unsigned int> orgPoints; // from which original point each new vertex stems - orgPoints.resize( numVertices, 0); - - for( unsigned int c = 0; c < faces.size(); c++) - { - unsigned int f = faces[c]; // index of the source face - const XFile::Face& pf = sourceMesh->mPosFaces[f]; // position source face - - // create face. either triangle or triangle fan depending on the index count - aiFace& df = mesh->mFaces[c]; // destination face - df.mNumIndices = (unsigned int)pf.mIndices.size(); - df.mIndices = new unsigned int[ df.mNumIndices]; - - // collect vertex data for indices of this face - for( unsigned int d = 0; d < df.mNumIndices; d++) - { - df.mIndices[d] = newIndex; - orgPoints[newIndex] = pf.mIndices[d]; - - // Position - mesh->mVertices[newIndex] = sourceMesh->mPositions[pf.mIndices[d]]; - // Normal, if present - if( mesh->HasNormals()) - mesh->mNormals[newIndex] = sourceMesh->mNormals[sourceMesh->mNormFaces[f].mIndices[d]]; - - // texture coord sets - for( unsigned int e = 0; e < AI_MAX_NUMBER_OF_TEXTURECOORDS; e++) - { - if( mesh->HasTextureCoords( e)) - { - aiVector2D tex = sourceMesh->mTexCoords[e][pf.mIndices[d]]; - mesh->mTextureCoords[e][newIndex] = aiVector3D( tex.x, 1.0f - tex.y, 0.0f); - } - } - // vertex color sets - for( unsigned int e = 0; e < AI_MAX_NUMBER_OF_COLOR_SETS; e++) - if( mesh->HasVertexColors( e)) - mesh->mColors[e][newIndex] = sourceMesh->mColors[e][pf.mIndices[d]]; - - newIndex++; - } - } - - // there should be as much new vertices as we calculated before - ai_assert( newIndex == numVertices); - - // convert all bones of the source mesh which influence vertices in this newly created mesh - const std::vector<XFile::Bone>& bones = sourceMesh->mBones; - std::vector<aiBone*> newBones; - for( unsigned int c = 0; c < bones.size(); c++) - { - const XFile::Bone& obone = bones[c]; - // set up a vertex-linear array of the weights for quick searching if a bone influences a vertex - std::vector<float> oldWeights( sourceMesh->mPositions.size(), 0.0f); - for( unsigned int d = 0; d < obone.mWeights.size(); d++) - oldWeights[obone.mWeights[d].mVertex] = obone.mWeights[d].mWeight; - - // collect all vertex weights that influence a vertex in the new mesh - std::vector<aiVertexWeight> newWeights; - newWeights.reserve( numVertices); - for( unsigned int d = 0; d < orgPoints.size(); d++) - { - // does the new vertex stem from an old vertex which was influenced by this bone? - float w = oldWeights[orgPoints[d]]; - if( w > 0.0f) - newWeights.push_back( aiVertexWeight( d, w)); - } - - // if the bone has no weights in the newly created mesh, ignore it - if( newWeights.size() == 0) - continue; - - // create - aiBone* nbone = new aiBone; - newBones.push_back( nbone); - // copy name and matrix - nbone->mName.Set( obone.mName); - nbone->mOffsetMatrix = obone.mOffsetMatrix; - nbone->mNumWeights = (unsigned int)newWeights.size(); - nbone->mWeights = new aiVertexWeight[nbone->mNumWeights]; - for( unsigned int d = 0; d < newWeights.size(); d++) - nbone->mWeights[d] = newWeights[d]; - } - - // store the bones in the mesh - mesh->mNumBones = (unsigned int)newBones.size(); - if( newBones.size() > 0) - { - mesh->mBones = new aiBone*[mesh->mNumBones]; - std::copy( newBones.begin(), newBones.end(), mesh->mBones); - } - } - } - - // reallocate scene mesh array to be large enough - aiMesh** prevArray = pScene->mMeshes; - pScene->mMeshes = new aiMesh*[pScene->mNumMeshes + meshes.size()]; - if( prevArray) - { - memcpy( pScene->mMeshes, prevArray, pScene->mNumMeshes * sizeof( aiMesh*)); - delete [] prevArray; - } - - // allocate mesh index array in the node - pNode->mNumMeshes = (unsigned int)meshes.size(); - pNode->mMeshes = new unsigned int[pNode->mNumMeshes]; - - // store all meshes in the mesh library of the scene and store their indices in the node - for( unsigned int a = 0; a < meshes.size(); a++) - { - pScene->mMeshes[pScene->mNumMeshes] = meshes[a]; - pNode->mMeshes[a] = pScene->mNumMeshes; - pScene->mNumMeshes++; - } -} - -// ------------------------------------------------------------------------------------------------ -// Converts the animations from the given imported data and creates them in the scene. -void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData) -{ - std::vector<aiAnimation*> newAnims; - - for( unsigned int a = 0; a < pData->mAnims.size(); a++) - { - const XFile::Animation* anim = pData->mAnims[a]; - // some exporters mock me with empty animation tags. - if( anim->mAnims.size() == 0) - continue; - - // create a new animation to hold the data - aiAnimation* nanim = new aiAnimation; - newAnims.push_back( nanim); - nanim->mName.Set( anim->mName); - // duration will be determined by the maximum length - nanim->mDuration = 0; - nanim->mTicksPerSecond = pData->mAnimTicksPerSecond; - nanim->mNumChannels = (unsigned int)anim->mAnims.size(); - nanim->mChannels = new aiNodeAnim*[nanim->mNumChannels]; - - for( unsigned int b = 0; b < anim->mAnims.size(); b++) - { - const XFile::AnimBone* bone = anim->mAnims[b]; - aiNodeAnim* nbone = new aiNodeAnim; - nbone->mNodeName.Set( bone->mBoneName); - nanim->mChannels[b] = nbone; - - // keyframes are given as combined transformation matrix keys - if( bone->mTrafoKeys.size() > 0) - { - nbone->mNumPositionKeys = (unsigned int)bone->mTrafoKeys.size(); - nbone->mPositionKeys = new aiVectorKey[nbone->mNumPositionKeys]; - nbone->mNumRotationKeys = (unsigned int)bone->mTrafoKeys.size(); - nbone->mRotationKeys = new aiQuatKey[nbone->mNumRotationKeys]; - nbone->mNumScalingKeys = (unsigned int)bone->mTrafoKeys.size(); - nbone->mScalingKeys = new aiVectorKey[nbone->mNumScalingKeys]; - - for( unsigned int c = 0; c < bone->mTrafoKeys.size(); c++) - { - // deconstruct each matrix into separate position, rotation and scaling - double time = bone->mTrafoKeys[c].mTime; - aiMatrix4x4 trafo = bone->mTrafoKeys[c].mMatrix; - - // extract position - aiVector3D pos( trafo.a4, trafo.b4, trafo.c4); - - nbone->mPositionKeys[c].mTime = time; - nbone->mPositionKeys[c].mValue = pos; - - // extract scaling - aiVector3D scale; - scale.x = aiVector3D( trafo.a1, trafo.b1, trafo.c1).Length(); - scale.y = aiVector3D( trafo.a2, trafo.b2, trafo.c2).Length(); - scale.z = aiVector3D( trafo.a3, trafo.b3, trafo.c3).Length(); - nbone->mScalingKeys[c].mTime = time; - nbone->mScalingKeys[c].mValue = scale; - - // reconstruct rotation matrix without scaling - aiMatrix3x3 rotmat( - trafo.a1 / scale.x, trafo.a2 / scale.y, trafo.a3 / scale.z, - trafo.b1 / scale.x, trafo.b2 / scale.y, trafo.b3 / scale.z, - trafo.c1 / scale.x, trafo.c2 / scale.y, trafo.c3 / scale.z); - - // and convert it into a quaternion - nbone->mRotationKeys[c].mTime = time; - nbone->mRotationKeys[c].mValue = aiQuaternion( rotmat); - } - - // longest lasting key sequence determines duration - nanim->mDuration = std::max( nanim->mDuration, bone->mTrafoKeys.back().mTime); - } else - { - // separate key sequences for position, rotation, scaling - nbone->mNumPositionKeys = (unsigned int)bone->mPosKeys.size(); - nbone->mPositionKeys = new aiVectorKey[nbone->mNumPositionKeys]; - for( unsigned int c = 0; c < nbone->mNumPositionKeys; c++) - { - aiVector3D pos = bone->mPosKeys[c].mValue; - - nbone->mPositionKeys[c].mTime = bone->mPosKeys[c].mTime; - nbone->mPositionKeys[c].mValue = pos; - } - - // rotation - nbone->mNumRotationKeys = (unsigned int)bone->mRotKeys.size(); - nbone->mRotationKeys = new aiQuatKey[nbone->mNumRotationKeys]; - for( unsigned int c = 0; c < nbone->mNumRotationKeys; c++) - { - aiMatrix3x3 rotmat = bone->mRotKeys[c].mValue.GetMatrix(); - - nbone->mRotationKeys[c].mTime = bone->mRotKeys[c].mTime; - nbone->mRotationKeys[c].mValue = aiQuaternion( rotmat); - nbone->mRotationKeys[c].mValue.w *= -1.0f; // needs quat inversion - } - - // scaling - nbone->mNumScalingKeys = (unsigned int)bone->mScaleKeys.size(); - nbone->mScalingKeys = new aiVectorKey[nbone->mNumScalingKeys]; - for( unsigned int c = 0; c < nbone->mNumScalingKeys; c++) - nbone->mScalingKeys[c] = bone->mScaleKeys[c]; - - // longest lasting key sequence determines duration - if( bone->mPosKeys.size() > 0) - nanim->mDuration = std::max( nanim->mDuration, bone->mPosKeys.back().mTime); - if( bone->mRotKeys.size() > 0) - nanim->mDuration = std::max( nanim->mDuration, bone->mRotKeys.back().mTime); - if( bone->mScaleKeys.size() > 0) - nanim->mDuration = std::max( nanim->mDuration, bone->mScaleKeys.back().mTime); - } - } - } - - // store all converted animations in the scene - if( newAnims.size() > 0) - { - pScene->mNumAnimations = (unsigned int)newAnims.size(); - pScene->mAnimations = new aiAnimation* [pScene->mNumAnimations]; - for( unsigned int a = 0; a < newAnims.size(); a++) - pScene->mAnimations[a] = newAnims[a]; - } -} - -// ------------------------------------------------------------------------------------------------ -// Converts all materials in the given array and stores them in the scene's material list. -void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector<XFile::Material>& pMaterials) -{ - // count the non-referrer materials in the array - unsigned int numNewMaterials = 0; - for( unsigned int a = 0; a < pMaterials.size(); a++) - if( !pMaterials[a].mIsReference) - numNewMaterials++; - - // resize the scene's material list to offer enough space for the new materials - if( numNewMaterials > 0 ) - { - aiMaterial** prevMats = pScene->mMaterials; - pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials + numNewMaterials]; - if( prevMats) - { - memcpy( pScene->mMaterials, prevMats, pScene->mNumMaterials * sizeof( aiMaterial*)); - delete [] prevMats; - } - } - - // convert all the materials given in the array - for( unsigned int a = 0; a < pMaterials.size(); a++) - { - XFile::Material& oldMat = pMaterials[a]; - if( oldMat.mIsReference) - { - // find the material it refers to by name, and store its index - for( size_t a = 0; a < pScene->mNumMaterials; ++a ) - { - aiString name; - pScene->mMaterials[a]->Get( AI_MATKEY_NAME, name); - if( strcmp( name.C_Str(), oldMat.mName.data()) == 0 ) - { - oldMat.sceneIndex = a; - break; - } - } - - if( oldMat.sceneIndex == SIZE_MAX ) - { - DefaultLogger::get()->warn( boost::str( boost::format( "Could not resolve global material reference \"%s\"") % oldMat.mName)); - oldMat.sceneIndex = 0; - } - - continue; - } - - aiMaterial* mat = new aiMaterial; - aiString name; - name.Set( oldMat.mName); - mat->AddProperty( &name, AI_MATKEY_NAME); - - // Shading model: hardcoded to PHONG, there is no such information in an XFile - // FIX (aramis): If the specular exponent is 0, use gouraud shading. This is a bugfix - // for some models in the SDK (e.g. good old tiny.x) - int shadeMode = (int)oldMat.mSpecularExponent == 0.0f - ? aiShadingMode_Gouraud : aiShadingMode_Phong; - - mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL); - // material colours - // Unclear: there's no ambient colour, but emissive. What to put for ambient? - // Probably nothing at all, let the user select a suitable default. - mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE); - mat->AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE); - mat->AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR); - mat->AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS); - - - // texture, if there is one - if (1 == oldMat.mTextures.size()) - { - const XFile::TexEntry& otex = oldMat.mTextures.back(); - if (otex.mName.length()) - { - // if there is only one texture assume it contains the diffuse color - aiString tex( otex.mName); - if( otex.mIsNormalMap) - mat->AddProperty( &tex, AI_MATKEY_TEXTURE_NORMALS(0)); - else - mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(0)); - } - } - else - { - // Otherwise ... try to search for typical strings in the - // texture's file name like 'bump' or 'diffuse' - unsigned int iHM = 0,iNM = 0,iDM = 0,iSM = 0,iAM = 0,iEM = 0; - for( unsigned int b = 0; b < oldMat.mTextures.size(); b++) - { - const XFile::TexEntry& otex = oldMat.mTextures[b]; - std::string sz = otex.mName; - if (!sz.length())continue; - - - // find the file name - //const size_t iLen = sz.length(); - std::string::size_type s = sz.find_last_of("\\/"); - if (std::string::npos == s) - s = 0; - - // cut off the file extension - std::string::size_type sExt = sz.find_last_of('.'); - if (std::string::npos != sExt){ - sz[sExt] = '\0'; - } - - // convert to lower case for easier comparision - for( unsigned int c = 0; c < sz.length(); c++) - if( isalpha( sz[c])) - sz[c] = tolower( sz[c]); - - - // Place texture filename property under the corresponding name - aiString tex( oldMat.mTextures[b].mName); - - // bump map - if (std::string::npos != sz.find("bump", s) || std::string::npos != sz.find("height", s)) - { - mat->AddProperty( &tex, AI_MATKEY_TEXTURE_HEIGHT(iHM++)); - } else - if (otex.mIsNormalMap || std::string::npos != sz.find( "normal", s) || std::string::npos != sz.find("nm", s)) - { - mat->AddProperty( &tex, AI_MATKEY_TEXTURE_NORMALS(iNM++)); - } else - if (std::string::npos != sz.find( "spec", s) || std::string::npos != sz.find( "glanz", s)) - { - mat->AddProperty( &tex, AI_MATKEY_TEXTURE_SPECULAR(iSM++)); - } else - if (std::string::npos != sz.find( "ambi", s) || std::string::npos != sz.find( "env", s)) - { - mat->AddProperty( &tex, AI_MATKEY_TEXTURE_AMBIENT(iAM++)); - } else - if (std::string::npos != sz.find( "emissive", s) || std::string::npos != sz.find( "self", s)) - { - mat->AddProperty( &tex, AI_MATKEY_TEXTURE_EMISSIVE(iEM++)); - } else - { - // Assume it is a diffuse texture - mat->AddProperty( &tex, AI_MATKEY_TEXTURE_DIFFUSE(iDM++)); - } - } - } - - pScene->mMaterials[pScene->mNumMaterials] = mat; - oldMat.sceneIndex = pScene->mNumMaterials; - pScene->mNumMaterials++; - } -} - -#endif // !! ASSIMP_BUILD_NO_X_IMPORTER - |