vrshoot
diff libs/assimp/ProcessHelper.cpp @ 0:b2f14e535253
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 01 Feb 2014 19:58:19 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/assimp/ProcessHelper.cpp Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,415 @@ 1.4 +/* 1.5 +Open Asset Import Library (assimp) 1.6 +---------------------------------------------------------------------- 1.7 + 1.8 +Copyright (c) 2006-2012, assimp team 1.9 +All rights reserved. 1.10 + 1.11 +Redistribution and use of this software in source and binary forms, 1.12 +with or without modification, are permitted provided that the 1.13 +following conditions are met: 1.14 + 1.15 +* Redistributions of source code must retain the above 1.16 + copyright notice, this list of conditions and the 1.17 + following disclaimer. 1.18 + 1.19 +* Redistributions in binary form must reproduce the above 1.20 + copyright notice, this list of conditions and the 1.21 + following disclaimer in the documentation and/or other 1.22 + materials provided with the distribution. 1.23 + 1.24 +* Neither the name of the assimp team, nor the names of its 1.25 + contributors may be used to endorse or promote products 1.26 + derived from this software without specific prior 1.27 + written permission of the assimp team. 1.28 + 1.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.40 + 1.41 +---------------------------------------------------------------------- 1.42 +*/ 1.43 + 1.44 +/// @file ProcessHelper.cpp 1.45 +/** Implement shared utility functions for postprocessing steps */ 1.46 + 1.47 +#include "AssimpPCH.h" 1.48 +#include "ProcessHelper.h" 1.49 + 1.50 + 1.51 +#include <limits> 1.52 + 1.53 +namespace Assimp { 1.54 + 1.55 +// ------------------------------------------------------------------------------- 1.56 +void ConvertListToStrings(const std::string& in, std::list<std::string>& out) 1.57 +{ 1.58 + const char* s = in.c_str(); 1.59 + while (*s) { 1.60 + SkipSpacesAndLineEnd(&s); 1.61 + if (*s == '\'') { 1.62 + const char* base = ++s; 1.63 + while (*s != '\'') { 1.64 + ++s; 1.65 + if (*s == '\0') { 1.66 + DefaultLogger::get()->error("ConvertListToString: String list is ill-formatted"); 1.67 + return; 1.68 + } 1.69 + } 1.70 + out.push_back(std::string(base,(size_t)(s-base))); 1.71 + ++s; 1.72 + } 1.73 + else { 1.74 + out.push_back(GetNextToken(s)); 1.75 + } 1.76 + } 1.77 +} 1.78 + 1.79 +// ------------------------------------------------------------------------------- 1.80 +void FindAABBTransformed (const aiMesh* mesh, aiVector3D& min, aiVector3D& max, 1.81 + const aiMatrix4x4& m) 1.82 +{ 1.83 + min = aiVector3D (10e10f, 10e10f, 10e10f); 1.84 + max = aiVector3D (-10e10f,-10e10f,-10e10f); 1.85 + for (unsigned int i = 0;i < mesh->mNumVertices;++i) 1.86 + { 1.87 + const aiVector3D v = m * mesh->mVertices[i]; 1.88 + min = std::min(v,min); 1.89 + max = std::max(v,max); 1.90 + } 1.91 +} 1.92 + 1.93 +// ------------------------------------------------------------------------------- 1.94 +void FindMeshCenter (aiMesh* mesh, aiVector3D& out, aiVector3D& min, aiVector3D& max) 1.95 +{ 1.96 + ArrayBounds(mesh->mVertices,mesh->mNumVertices, min,max); 1.97 + out = min + (max-min)*0.5f; 1.98 +} 1.99 + 1.100 +// ------------------------------------------------------------------------------- 1.101 +void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out, aiVector3D& min, 1.102 + aiVector3D& max, const aiMatrix4x4& m) 1.103 +{ 1.104 + FindAABBTransformed(mesh,min,max,m); 1.105 + out = min + (max-min)*0.5f; 1.106 +} 1.107 + 1.108 +// ------------------------------------------------------------------------------- 1.109 +void FindMeshCenter (aiMesh* mesh, aiVector3D& out) 1.110 +{ 1.111 + aiVector3D min,max; 1.112 + FindMeshCenter(mesh,out,min,max); 1.113 +} 1.114 + 1.115 +// ------------------------------------------------------------------------------- 1.116 +void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out, 1.117 + const aiMatrix4x4& m) 1.118 +{ 1.119 + aiVector3D min,max; 1.120 + FindMeshCenterTransformed(mesh,out,min,max,m); 1.121 +} 1.122 + 1.123 +// ------------------------------------------------------------------------------- 1.124 +float ComputePositionEpsilon(const aiMesh* pMesh) 1.125 +{ 1.126 + const float epsilon = 1e-4f; 1.127 + 1.128 + // calculate the position bounds so we have a reliable epsilon to check position differences against 1.129 + aiVector3D minVec, maxVec; 1.130 + ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,minVec,maxVec); 1.131 + return (maxVec - minVec).Length() * epsilon; 1.132 +} 1.133 + 1.134 +// ------------------------------------------------------------------------------- 1.135 +float ComputePositionEpsilon(const aiMesh* const* pMeshes, size_t num) 1.136 +{ 1.137 + const float epsilon = 1e-4f; 1.138 + 1.139 + // calculate the position bounds so we have a reliable epsilon to check position differences against 1.140 + aiVector3D minVec, maxVec, mi, ma; 1.141 + MinMaxChooser<aiVector3D>()(minVec,maxVec); 1.142 + 1.143 + for (size_t a = 0; a < num; ++a) { 1.144 + const aiMesh* pMesh = pMeshes[a]; 1.145 + ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,mi,ma); 1.146 + 1.147 + minVec = std::min(minVec,mi); 1.148 + maxVec = std::max(maxVec,ma); 1.149 + } 1.150 + return (maxVec - minVec).Length() * epsilon; 1.151 +} 1.152 + 1.153 + 1.154 +// ------------------------------------------------------------------------------- 1.155 +unsigned int GetMeshVFormatUnique(const aiMesh* pcMesh) 1.156 +{ 1.157 + ai_assert(NULL != pcMesh); 1.158 + 1.159 + // FIX: the hash may never be 0. Otherwise a comparison against 1.160 + // nullptr could be successful 1.161 + unsigned int iRet = 1; 1.162 + 1.163 + // normals 1.164 + if (pcMesh->HasNormals())iRet |= 0x2; 1.165 + // tangents and bitangents 1.166 + if (pcMesh->HasTangentsAndBitangents())iRet |= 0x4; 1.167 + 1.168 +#ifdef BOOST_STATIC_ASSERT 1.169 + BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_COLOR_SETS); 1.170 + BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_TEXTURECOORDS); 1.171 +#endif 1.172 + 1.173 + // texture coordinates 1.174 + unsigned int p = 0; 1.175 + while (pcMesh->HasTextureCoords(p)) 1.176 + { 1.177 + iRet |= (0x100 << p); 1.178 + if (3 == pcMesh->mNumUVComponents[p]) 1.179 + iRet |= (0x10000 << p); 1.180 + 1.181 + ++p; 1.182 + } 1.183 + // vertex colors 1.184 + p = 0; 1.185 + while (pcMesh->HasVertexColors(p))iRet |= (0x1000000 << p++); 1.186 + return iRet; 1.187 +} 1.188 + 1.189 +// ------------------------------------------------------------------------------- 1.190 +VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh) 1.191 +{ 1.192 + if (!pMesh || !pMesh->mNumVertices || !pMesh->mNumBones) { 1.193 + return NULL; 1.194 + } 1.195 + 1.196 + VertexWeightTable* avPerVertexWeights = new VertexWeightTable[pMesh->mNumVertices]; 1.197 + for (unsigned int i = 0; i < pMesh->mNumBones;++i) { 1.198 + 1.199 + aiBone* bone = pMesh->mBones[i]; 1.200 + for (unsigned int a = 0; a < bone->mNumWeights;++a) { 1.201 + const aiVertexWeight& weight = bone->mWeights[a]; 1.202 + avPerVertexWeights[weight.mVertexId].push_back( std::pair<unsigned int,float>(i,weight.mWeight) ); 1.203 + } 1.204 + } 1.205 + return avPerVertexWeights; 1.206 +} 1.207 + 1.208 + 1.209 +// ------------------------------------------------------------------------------- 1.210 +const char* TextureTypeToString(aiTextureType in) 1.211 +{ 1.212 + switch (in) 1.213 + { 1.214 + case aiTextureType_NONE: 1.215 + return "n/a"; 1.216 + case aiTextureType_DIFFUSE: 1.217 + return "Diffuse"; 1.218 + case aiTextureType_SPECULAR: 1.219 + return "Specular"; 1.220 + case aiTextureType_AMBIENT: 1.221 + return "Ambient"; 1.222 + case aiTextureType_EMISSIVE: 1.223 + return "Emissive"; 1.224 + case aiTextureType_OPACITY: 1.225 + return "Opacity"; 1.226 + case aiTextureType_NORMALS: 1.227 + return "Normals"; 1.228 + case aiTextureType_HEIGHT: 1.229 + return "Height"; 1.230 + case aiTextureType_SHININESS: 1.231 + return "Shininess"; 1.232 + case aiTextureType_DISPLACEMENT: 1.233 + return "Displacement"; 1.234 + case aiTextureType_LIGHTMAP: 1.235 + return "Lightmap"; 1.236 + case aiTextureType_REFLECTION: 1.237 + return "Reflection"; 1.238 + case aiTextureType_UNKNOWN: 1.239 + return "Unknown"; 1.240 + default: 1.241 + break; 1.242 + } 1.243 + 1.244 + ai_assert(false); 1.245 + return "BUG"; 1.246 +} 1.247 + 1.248 +// ------------------------------------------------------------------------------- 1.249 +const char* MappingTypeToString(aiTextureMapping in) 1.250 +{ 1.251 + switch (in) 1.252 + { 1.253 + case aiTextureMapping_UV: 1.254 + return "UV"; 1.255 + case aiTextureMapping_BOX: 1.256 + return "Box"; 1.257 + case aiTextureMapping_SPHERE: 1.258 + return "Sphere"; 1.259 + case aiTextureMapping_CYLINDER: 1.260 + return "Cylinder"; 1.261 + case aiTextureMapping_PLANE: 1.262 + return "Plane"; 1.263 + case aiTextureMapping_OTHER: 1.264 + return "Other"; 1.265 + default: 1.266 + break; 1.267 + } 1.268 + 1.269 + ai_assert(false); 1.270 + return "BUG"; 1.271 +} 1.272 + 1.273 + 1.274 +// ------------------------------------------------------------------------------- 1.275 +aiMesh* MakeSubmesh(const aiMesh *pMesh, const std::vector<unsigned int> &subMeshFaces, unsigned int subFlags) 1.276 +{ 1.277 + aiMesh *oMesh = new aiMesh(); 1.278 + std::vector<unsigned int> vMap(pMesh->mNumVertices,UINT_MAX); 1.279 + 1.280 + size_t numSubVerts = 0; 1.281 + size_t numSubFaces = subMeshFaces.size(); 1.282 + 1.283 + for(unsigned int i=0;i<numSubFaces;i++) { 1.284 + const aiFace &f = pMesh->mFaces[subMeshFaces[i]]; 1.285 + 1.286 + for(unsigned int j=0;j<f.mNumIndices;j++) { 1.287 + if(vMap[f.mIndices[j]]==UINT_MAX) { 1.288 + vMap[f.mIndices[j]] = numSubVerts++; 1.289 + } 1.290 + } 1.291 + } 1.292 + 1.293 + oMesh->mName = pMesh->mName; 1.294 + 1.295 + oMesh->mMaterialIndex = pMesh->mMaterialIndex; 1.296 + oMesh->mPrimitiveTypes = pMesh->mPrimitiveTypes; 1.297 + 1.298 + // create all the arrays for this mesh if the old mesh contained them 1.299 + 1.300 + oMesh->mNumFaces = subMeshFaces.size(); 1.301 + oMesh->mNumVertices = numSubVerts; 1.302 + oMesh->mVertices = new aiVector3D[numSubVerts]; 1.303 + if( pMesh->HasNormals() ) { 1.304 + oMesh->mNormals = new aiVector3D[numSubVerts]; 1.305 + } 1.306 + 1.307 + if( pMesh->HasTangentsAndBitangents() ) { 1.308 + oMesh->mTangents = new aiVector3D[numSubVerts]; 1.309 + oMesh->mBitangents = new aiVector3D[numSubVerts]; 1.310 + } 1.311 + 1.312 + for( size_t a = 0; pMesh->HasTextureCoords( a) ; ++a ) { 1.313 + oMesh->mTextureCoords[a] = new aiVector3D[numSubVerts]; 1.314 + oMesh->mNumUVComponents[a] = pMesh->mNumUVComponents[a]; 1.315 + } 1.316 + 1.317 + for( size_t a = 0; pMesh->HasVertexColors( a); ++a ) { 1.318 + oMesh->mColors[a] = new aiColor4D[numSubVerts]; 1.319 + } 1.320 + 1.321 + // and copy over the data, generating faces with linear indices along the way 1.322 + oMesh->mFaces = new aiFace[numSubFaces]; 1.323 + 1.324 + for(unsigned int a = 0; a < numSubFaces; ++a ) { 1.325 + 1.326 + const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]]; 1.327 + aiFace& dstFace = oMesh->mFaces[a]; 1.328 + dstFace.mNumIndices = srcFace.mNumIndices; 1.329 + dstFace.mIndices = new unsigned int[dstFace.mNumIndices]; 1.330 + 1.331 + // accumulate linearly all the vertices of the source face 1.332 + for( size_t b = 0; b < dstFace.mNumIndices; ++b ) { 1.333 + dstFace.mIndices[b] = vMap[srcFace.mIndices[b]]; 1.334 + } 1.335 + } 1.336 + 1.337 + for(unsigned int srcIndex = 0; srcIndex < pMesh->mNumVertices; ++srcIndex ) { 1.338 + unsigned int nvi = vMap[srcIndex]; 1.339 + if(nvi==UINT_MAX) { 1.340 + continue; 1.341 + } 1.342 + 1.343 + oMesh->mVertices[nvi] = pMesh->mVertices[srcIndex]; 1.344 + if( pMesh->HasNormals() ) { 1.345 + oMesh->mNormals[nvi] = pMesh->mNormals[srcIndex]; 1.346 + } 1.347 + 1.348 + if( pMesh->HasTangentsAndBitangents() ) { 1.349 + oMesh->mTangents[nvi] = pMesh->mTangents[srcIndex]; 1.350 + oMesh->mBitangents[nvi] = pMesh->mBitangents[srcIndex]; 1.351 + } 1.352 + for( size_t c = 0, cc = pMesh->GetNumUVChannels(); c < cc; ++c ) { 1.353 + oMesh->mTextureCoords[c][nvi] = pMesh->mTextureCoords[c][srcIndex]; 1.354 + } 1.355 + for( size_t c = 0, cc = pMesh->GetNumColorChannels(); c < cc; ++c ) { 1.356 + oMesh->mColors[c][nvi] = pMesh->mColors[c][srcIndex]; 1.357 + } 1.358 + } 1.359 + 1.360 + if(~subFlags&AI_SUBMESH_FLAGS_SANS_BONES) { 1.361 + std::vector<unsigned int> subBones(pMesh->mNumBones,0); 1.362 + 1.363 + for(unsigned int a=0;a<pMesh->mNumBones;++a) { 1.364 + const aiBone* bone = pMesh->mBones[a]; 1.365 + 1.366 + for(unsigned int b=0;b<bone->mNumWeights;b++) { 1.367 + unsigned int v = vMap[bone->mWeights[b].mVertexId]; 1.368 + 1.369 + if(v!=UINT_MAX) { 1.370 + subBones[a]++; 1.371 + } 1.372 + } 1.373 + } 1.374 + 1.375 + for(unsigned int a=0;a<pMesh->mNumBones;++a) { 1.376 + if(subBones[a]>0) { 1.377 + oMesh->mNumBones++; 1.378 + } 1.379 + } 1.380 + 1.381 + if(oMesh->mNumBones) { 1.382 + oMesh->mBones = new aiBone*[oMesh->mNumBones](); 1.383 + unsigned int nbParanoia = oMesh->mNumBones; 1.384 + 1.385 + oMesh->mNumBones = 0; //rewind 1.386 + 1.387 + for(unsigned int a=0;a<pMesh->mNumBones;++a) { 1.388 + if(subBones[a]==0) { 1.389 + continue; 1.390 + } 1.391 + aiBone *newBone = new aiBone; 1.392 + oMesh->mBones[oMesh->mNumBones++] = newBone; 1.393 + 1.394 + const aiBone* bone = pMesh->mBones[a]; 1.395 + 1.396 + newBone->mName = bone->mName; 1.397 + newBone->mOffsetMatrix = bone->mOffsetMatrix; 1.398 + newBone->mWeights = new aiVertexWeight[subBones[a]]; 1.399 + 1.400 + for(unsigned int b=0;b<bone->mNumWeights;b++) { 1.401 + const unsigned int v = vMap[bone->mWeights[b].mVertexId]; 1.402 + 1.403 + if(v!=UINT_MAX) { 1.404 + aiVertexWeight w(v,bone->mWeights[b].mWeight); 1.405 + newBone->mWeights[newBone->mNumWeights++] = w; 1.406 + } 1.407 + } 1.408 + } 1.409 + 1.410 + ai_assert(nbParanoia==oMesh->mNumBones); 1.411 + (void)nbParanoia; // remove compiler warning on release build 1.412 + } 1.413 + } 1.414 + 1.415 + return oMesh; 1.416 +} 1.417 + 1.418 +} // namespace Assimp