rev |
line source |
nuclear@0
|
1 /*
|
nuclear@0
|
2 Open Asset Import Library (assimp)
|
nuclear@0
|
3 ----------------------------------------------------------------------
|
nuclear@0
|
4
|
nuclear@0
|
5 Copyright (c) 2006-2012, assimp team
|
nuclear@0
|
6 All rights reserved.
|
nuclear@0
|
7
|
nuclear@0
|
8 Redistribution and use of this software in source and binary forms,
|
nuclear@0
|
9 with or without modification, are permitted provided that the
|
nuclear@0
|
10 following conditions are met:
|
nuclear@0
|
11
|
nuclear@0
|
12 * Redistributions of source code must retain the above
|
nuclear@0
|
13 copyright notice, this list of conditions and the
|
nuclear@0
|
14 following disclaimer.
|
nuclear@0
|
15
|
nuclear@0
|
16 * Redistributions in binary form must reproduce the above
|
nuclear@0
|
17 copyright notice, this list of conditions and the
|
nuclear@0
|
18 following disclaimer in the documentation and/or other
|
nuclear@0
|
19 materials provided with the distribution.
|
nuclear@0
|
20
|
nuclear@0
|
21 * Neither the name of the assimp team, nor the names of its
|
nuclear@0
|
22 contributors may be used to endorse or promote products
|
nuclear@0
|
23 derived from this software without specific prior
|
nuclear@0
|
24 written permission of the assimp team.
|
nuclear@0
|
25
|
nuclear@0
|
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
nuclear@0
|
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
nuclear@0
|
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
nuclear@0
|
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
nuclear@0
|
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
nuclear@0
|
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
nuclear@0
|
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
nuclear@0
|
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
nuclear@0
|
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
nuclear@0
|
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
nuclear@0
|
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
nuclear@0
|
37
|
nuclear@0
|
38 ----------------------------------------------------------------------
|
nuclear@0
|
39 */
|
nuclear@0
|
40
|
nuclear@0
|
41 /// @file ProcessHelper.cpp
|
nuclear@0
|
42 /** Implement shared utility functions for postprocessing steps */
|
nuclear@0
|
43
|
nuclear@0
|
44 #include "AssimpPCH.h"
|
nuclear@0
|
45 #include "ProcessHelper.h"
|
nuclear@0
|
46
|
nuclear@0
|
47
|
nuclear@0
|
48 #include <limits>
|
nuclear@0
|
49
|
nuclear@0
|
50 namespace Assimp {
|
nuclear@0
|
51
|
nuclear@0
|
52 // -------------------------------------------------------------------------------
|
nuclear@0
|
53 void ConvertListToStrings(const std::string& in, std::list<std::string>& out)
|
nuclear@0
|
54 {
|
nuclear@0
|
55 const char* s = in.c_str();
|
nuclear@0
|
56 while (*s) {
|
nuclear@0
|
57 SkipSpacesAndLineEnd(&s);
|
nuclear@0
|
58 if (*s == '\'') {
|
nuclear@0
|
59 const char* base = ++s;
|
nuclear@0
|
60 while (*s != '\'') {
|
nuclear@0
|
61 ++s;
|
nuclear@0
|
62 if (*s == '\0') {
|
nuclear@0
|
63 DefaultLogger::get()->error("ConvertListToString: String list is ill-formatted");
|
nuclear@0
|
64 return;
|
nuclear@0
|
65 }
|
nuclear@0
|
66 }
|
nuclear@0
|
67 out.push_back(std::string(base,(size_t)(s-base)));
|
nuclear@0
|
68 ++s;
|
nuclear@0
|
69 }
|
nuclear@0
|
70 else {
|
nuclear@0
|
71 out.push_back(GetNextToken(s));
|
nuclear@0
|
72 }
|
nuclear@0
|
73 }
|
nuclear@0
|
74 }
|
nuclear@0
|
75
|
nuclear@0
|
76 // -------------------------------------------------------------------------------
|
nuclear@0
|
77 void FindAABBTransformed (const aiMesh* mesh, aiVector3D& min, aiVector3D& max,
|
nuclear@0
|
78 const aiMatrix4x4& m)
|
nuclear@0
|
79 {
|
nuclear@0
|
80 min = aiVector3D (10e10f, 10e10f, 10e10f);
|
nuclear@0
|
81 max = aiVector3D (-10e10f,-10e10f,-10e10f);
|
nuclear@0
|
82 for (unsigned int i = 0;i < mesh->mNumVertices;++i)
|
nuclear@0
|
83 {
|
nuclear@0
|
84 const aiVector3D v = m * mesh->mVertices[i];
|
nuclear@0
|
85 min = std::min(v,min);
|
nuclear@0
|
86 max = std::max(v,max);
|
nuclear@0
|
87 }
|
nuclear@0
|
88 }
|
nuclear@0
|
89
|
nuclear@0
|
90 // -------------------------------------------------------------------------------
|
nuclear@0
|
91 void FindMeshCenter (aiMesh* mesh, aiVector3D& out, aiVector3D& min, aiVector3D& max)
|
nuclear@0
|
92 {
|
nuclear@0
|
93 ArrayBounds(mesh->mVertices,mesh->mNumVertices, min,max);
|
nuclear@0
|
94 out = min + (max-min)*0.5f;
|
nuclear@0
|
95 }
|
nuclear@0
|
96
|
nuclear@0
|
97 // -------------------------------------------------------------------------------
|
nuclear@0
|
98 void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out, aiVector3D& min,
|
nuclear@0
|
99 aiVector3D& max, const aiMatrix4x4& m)
|
nuclear@0
|
100 {
|
nuclear@0
|
101 FindAABBTransformed(mesh,min,max,m);
|
nuclear@0
|
102 out = min + (max-min)*0.5f;
|
nuclear@0
|
103 }
|
nuclear@0
|
104
|
nuclear@0
|
105 // -------------------------------------------------------------------------------
|
nuclear@0
|
106 void FindMeshCenter (aiMesh* mesh, aiVector3D& out)
|
nuclear@0
|
107 {
|
nuclear@0
|
108 aiVector3D min,max;
|
nuclear@0
|
109 FindMeshCenter(mesh,out,min,max);
|
nuclear@0
|
110 }
|
nuclear@0
|
111
|
nuclear@0
|
112 // -------------------------------------------------------------------------------
|
nuclear@0
|
113 void FindMeshCenterTransformed (aiMesh* mesh, aiVector3D& out,
|
nuclear@0
|
114 const aiMatrix4x4& m)
|
nuclear@0
|
115 {
|
nuclear@0
|
116 aiVector3D min,max;
|
nuclear@0
|
117 FindMeshCenterTransformed(mesh,out,min,max,m);
|
nuclear@0
|
118 }
|
nuclear@0
|
119
|
nuclear@0
|
120 // -------------------------------------------------------------------------------
|
nuclear@0
|
121 float ComputePositionEpsilon(const aiMesh* pMesh)
|
nuclear@0
|
122 {
|
nuclear@0
|
123 const float epsilon = 1e-4f;
|
nuclear@0
|
124
|
nuclear@0
|
125 // calculate the position bounds so we have a reliable epsilon to check position differences against
|
nuclear@0
|
126 aiVector3D minVec, maxVec;
|
nuclear@0
|
127 ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,minVec,maxVec);
|
nuclear@0
|
128 return (maxVec - minVec).Length() * epsilon;
|
nuclear@0
|
129 }
|
nuclear@0
|
130
|
nuclear@0
|
131 // -------------------------------------------------------------------------------
|
nuclear@0
|
132 float ComputePositionEpsilon(const aiMesh* const* pMeshes, size_t num)
|
nuclear@0
|
133 {
|
nuclear@0
|
134 const float epsilon = 1e-4f;
|
nuclear@0
|
135
|
nuclear@0
|
136 // calculate the position bounds so we have a reliable epsilon to check position differences against
|
nuclear@0
|
137 aiVector3D minVec, maxVec, mi, ma;
|
nuclear@0
|
138 MinMaxChooser<aiVector3D>()(minVec,maxVec);
|
nuclear@0
|
139
|
nuclear@0
|
140 for (size_t a = 0; a < num; ++a) {
|
nuclear@0
|
141 const aiMesh* pMesh = pMeshes[a];
|
nuclear@0
|
142 ArrayBounds(pMesh->mVertices,pMesh->mNumVertices,mi,ma);
|
nuclear@0
|
143
|
nuclear@0
|
144 minVec = std::min(minVec,mi);
|
nuclear@0
|
145 maxVec = std::max(maxVec,ma);
|
nuclear@0
|
146 }
|
nuclear@0
|
147 return (maxVec - minVec).Length() * epsilon;
|
nuclear@0
|
148 }
|
nuclear@0
|
149
|
nuclear@0
|
150
|
nuclear@0
|
151 // -------------------------------------------------------------------------------
|
nuclear@0
|
152 unsigned int GetMeshVFormatUnique(const aiMesh* pcMesh)
|
nuclear@0
|
153 {
|
nuclear@0
|
154 ai_assert(NULL != pcMesh);
|
nuclear@0
|
155
|
nuclear@0
|
156 // FIX: the hash may never be 0. Otherwise a comparison against
|
nuclear@0
|
157 // nullptr could be successful
|
nuclear@0
|
158 unsigned int iRet = 1;
|
nuclear@0
|
159
|
nuclear@0
|
160 // normals
|
nuclear@0
|
161 if (pcMesh->HasNormals())iRet |= 0x2;
|
nuclear@0
|
162 // tangents and bitangents
|
nuclear@0
|
163 if (pcMesh->HasTangentsAndBitangents())iRet |= 0x4;
|
nuclear@0
|
164
|
nuclear@0
|
165 #ifdef BOOST_STATIC_ASSERT
|
nuclear@0
|
166 BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_COLOR_SETS);
|
nuclear@0
|
167 BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_TEXTURECOORDS);
|
nuclear@0
|
168 #endif
|
nuclear@0
|
169
|
nuclear@0
|
170 // texture coordinates
|
nuclear@0
|
171 unsigned int p = 0;
|
nuclear@0
|
172 while (pcMesh->HasTextureCoords(p))
|
nuclear@0
|
173 {
|
nuclear@0
|
174 iRet |= (0x100 << p);
|
nuclear@0
|
175 if (3 == pcMesh->mNumUVComponents[p])
|
nuclear@0
|
176 iRet |= (0x10000 << p);
|
nuclear@0
|
177
|
nuclear@0
|
178 ++p;
|
nuclear@0
|
179 }
|
nuclear@0
|
180 // vertex colors
|
nuclear@0
|
181 p = 0;
|
nuclear@0
|
182 while (pcMesh->HasVertexColors(p))iRet |= (0x1000000 << p++);
|
nuclear@0
|
183 return iRet;
|
nuclear@0
|
184 }
|
nuclear@0
|
185
|
nuclear@0
|
186 // -------------------------------------------------------------------------------
|
nuclear@0
|
187 VertexWeightTable* ComputeVertexBoneWeightTable(const aiMesh* pMesh)
|
nuclear@0
|
188 {
|
nuclear@0
|
189 if (!pMesh || !pMesh->mNumVertices || !pMesh->mNumBones) {
|
nuclear@0
|
190 return NULL;
|
nuclear@0
|
191 }
|
nuclear@0
|
192
|
nuclear@0
|
193 VertexWeightTable* avPerVertexWeights = new VertexWeightTable[pMesh->mNumVertices];
|
nuclear@0
|
194 for (unsigned int i = 0; i < pMesh->mNumBones;++i) {
|
nuclear@0
|
195
|
nuclear@0
|
196 aiBone* bone = pMesh->mBones[i];
|
nuclear@0
|
197 for (unsigned int a = 0; a < bone->mNumWeights;++a) {
|
nuclear@0
|
198 const aiVertexWeight& weight = bone->mWeights[a];
|
nuclear@0
|
199 avPerVertexWeights[weight.mVertexId].push_back( std::pair<unsigned int,float>(i,weight.mWeight) );
|
nuclear@0
|
200 }
|
nuclear@0
|
201 }
|
nuclear@0
|
202 return avPerVertexWeights;
|
nuclear@0
|
203 }
|
nuclear@0
|
204
|
nuclear@0
|
205
|
nuclear@0
|
206 // -------------------------------------------------------------------------------
|
nuclear@0
|
207 const char* TextureTypeToString(aiTextureType in)
|
nuclear@0
|
208 {
|
nuclear@0
|
209 switch (in)
|
nuclear@0
|
210 {
|
nuclear@0
|
211 case aiTextureType_NONE:
|
nuclear@0
|
212 return "n/a";
|
nuclear@0
|
213 case aiTextureType_DIFFUSE:
|
nuclear@0
|
214 return "Diffuse";
|
nuclear@0
|
215 case aiTextureType_SPECULAR:
|
nuclear@0
|
216 return "Specular";
|
nuclear@0
|
217 case aiTextureType_AMBIENT:
|
nuclear@0
|
218 return "Ambient";
|
nuclear@0
|
219 case aiTextureType_EMISSIVE:
|
nuclear@0
|
220 return "Emissive";
|
nuclear@0
|
221 case aiTextureType_OPACITY:
|
nuclear@0
|
222 return "Opacity";
|
nuclear@0
|
223 case aiTextureType_NORMALS:
|
nuclear@0
|
224 return "Normals";
|
nuclear@0
|
225 case aiTextureType_HEIGHT:
|
nuclear@0
|
226 return "Height";
|
nuclear@0
|
227 case aiTextureType_SHININESS:
|
nuclear@0
|
228 return "Shininess";
|
nuclear@0
|
229 case aiTextureType_DISPLACEMENT:
|
nuclear@0
|
230 return "Displacement";
|
nuclear@0
|
231 case aiTextureType_LIGHTMAP:
|
nuclear@0
|
232 return "Lightmap";
|
nuclear@0
|
233 case aiTextureType_REFLECTION:
|
nuclear@0
|
234 return "Reflection";
|
nuclear@0
|
235 case aiTextureType_UNKNOWN:
|
nuclear@0
|
236 return "Unknown";
|
nuclear@0
|
237 default:
|
nuclear@0
|
238 break;
|
nuclear@0
|
239 }
|
nuclear@0
|
240
|
nuclear@0
|
241 ai_assert(false);
|
nuclear@0
|
242 return "BUG";
|
nuclear@0
|
243 }
|
nuclear@0
|
244
|
nuclear@0
|
245 // -------------------------------------------------------------------------------
|
nuclear@0
|
246 const char* MappingTypeToString(aiTextureMapping in)
|
nuclear@0
|
247 {
|
nuclear@0
|
248 switch (in)
|
nuclear@0
|
249 {
|
nuclear@0
|
250 case aiTextureMapping_UV:
|
nuclear@0
|
251 return "UV";
|
nuclear@0
|
252 case aiTextureMapping_BOX:
|
nuclear@0
|
253 return "Box";
|
nuclear@0
|
254 case aiTextureMapping_SPHERE:
|
nuclear@0
|
255 return "Sphere";
|
nuclear@0
|
256 case aiTextureMapping_CYLINDER:
|
nuclear@0
|
257 return "Cylinder";
|
nuclear@0
|
258 case aiTextureMapping_PLANE:
|
nuclear@0
|
259 return "Plane";
|
nuclear@0
|
260 case aiTextureMapping_OTHER:
|
nuclear@0
|
261 return "Other";
|
nuclear@0
|
262 default:
|
nuclear@0
|
263 break;
|
nuclear@0
|
264 }
|
nuclear@0
|
265
|
nuclear@0
|
266 ai_assert(false);
|
nuclear@0
|
267 return "BUG";
|
nuclear@0
|
268 }
|
nuclear@0
|
269
|
nuclear@0
|
270
|
nuclear@0
|
271 // -------------------------------------------------------------------------------
|
nuclear@0
|
272 aiMesh* MakeSubmesh(const aiMesh *pMesh, const std::vector<unsigned int> &subMeshFaces, unsigned int subFlags)
|
nuclear@0
|
273 {
|
nuclear@0
|
274 aiMesh *oMesh = new aiMesh();
|
nuclear@0
|
275 std::vector<unsigned int> vMap(pMesh->mNumVertices,UINT_MAX);
|
nuclear@0
|
276
|
nuclear@0
|
277 size_t numSubVerts = 0;
|
nuclear@0
|
278 size_t numSubFaces = subMeshFaces.size();
|
nuclear@0
|
279
|
nuclear@0
|
280 for(unsigned int i=0;i<numSubFaces;i++) {
|
nuclear@0
|
281 const aiFace &f = pMesh->mFaces[subMeshFaces[i]];
|
nuclear@0
|
282
|
nuclear@0
|
283 for(unsigned int j=0;j<f.mNumIndices;j++) {
|
nuclear@0
|
284 if(vMap[f.mIndices[j]]==UINT_MAX) {
|
nuclear@0
|
285 vMap[f.mIndices[j]] = numSubVerts++;
|
nuclear@0
|
286 }
|
nuclear@0
|
287 }
|
nuclear@0
|
288 }
|
nuclear@0
|
289
|
nuclear@0
|
290 oMesh->mName = pMesh->mName;
|
nuclear@0
|
291
|
nuclear@0
|
292 oMesh->mMaterialIndex = pMesh->mMaterialIndex;
|
nuclear@0
|
293 oMesh->mPrimitiveTypes = pMesh->mPrimitiveTypes;
|
nuclear@0
|
294
|
nuclear@0
|
295 // create all the arrays for this mesh if the old mesh contained them
|
nuclear@0
|
296
|
nuclear@0
|
297 oMesh->mNumFaces = subMeshFaces.size();
|
nuclear@0
|
298 oMesh->mNumVertices = numSubVerts;
|
nuclear@0
|
299 oMesh->mVertices = new aiVector3D[numSubVerts];
|
nuclear@0
|
300 if( pMesh->HasNormals() ) {
|
nuclear@0
|
301 oMesh->mNormals = new aiVector3D[numSubVerts];
|
nuclear@0
|
302 }
|
nuclear@0
|
303
|
nuclear@0
|
304 if( pMesh->HasTangentsAndBitangents() ) {
|
nuclear@0
|
305 oMesh->mTangents = new aiVector3D[numSubVerts];
|
nuclear@0
|
306 oMesh->mBitangents = new aiVector3D[numSubVerts];
|
nuclear@0
|
307 }
|
nuclear@0
|
308
|
nuclear@0
|
309 for( size_t a = 0; pMesh->HasTextureCoords( a) ; ++a ) {
|
nuclear@0
|
310 oMesh->mTextureCoords[a] = new aiVector3D[numSubVerts];
|
nuclear@0
|
311 oMesh->mNumUVComponents[a] = pMesh->mNumUVComponents[a];
|
nuclear@0
|
312 }
|
nuclear@0
|
313
|
nuclear@0
|
314 for( size_t a = 0; pMesh->HasVertexColors( a); ++a ) {
|
nuclear@0
|
315 oMesh->mColors[a] = new aiColor4D[numSubVerts];
|
nuclear@0
|
316 }
|
nuclear@0
|
317
|
nuclear@0
|
318 // and copy over the data, generating faces with linear indices along the way
|
nuclear@0
|
319 oMesh->mFaces = new aiFace[numSubFaces];
|
nuclear@0
|
320
|
nuclear@0
|
321 for(unsigned int a = 0; a < numSubFaces; ++a ) {
|
nuclear@0
|
322
|
nuclear@0
|
323 const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
|
nuclear@0
|
324 aiFace& dstFace = oMesh->mFaces[a];
|
nuclear@0
|
325 dstFace.mNumIndices = srcFace.mNumIndices;
|
nuclear@0
|
326 dstFace.mIndices = new unsigned int[dstFace.mNumIndices];
|
nuclear@0
|
327
|
nuclear@0
|
328 // accumulate linearly all the vertices of the source face
|
nuclear@0
|
329 for( size_t b = 0; b < dstFace.mNumIndices; ++b ) {
|
nuclear@0
|
330 dstFace.mIndices[b] = vMap[srcFace.mIndices[b]];
|
nuclear@0
|
331 }
|
nuclear@0
|
332 }
|
nuclear@0
|
333
|
nuclear@0
|
334 for(unsigned int srcIndex = 0; srcIndex < pMesh->mNumVertices; ++srcIndex ) {
|
nuclear@0
|
335 unsigned int nvi = vMap[srcIndex];
|
nuclear@0
|
336 if(nvi==UINT_MAX) {
|
nuclear@0
|
337 continue;
|
nuclear@0
|
338 }
|
nuclear@0
|
339
|
nuclear@0
|
340 oMesh->mVertices[nvi] = pMesh->mVertices[srcIndex];
|
nuclear@0
|
341 if( pMesh->HasNormals() ) {
|
nuclear@0
|
342 oMesh->mNormals[nvi] = pMesh->mNormals[srcIndex];
|
nuclear@0
|
343 }
|
nuclear@0
|
344
|
nuclear@0
|
345 if( pMesh->HasTangentsAndBitangents() ) {
|
nuclear@0
|
346 oMesh->mTangents[nvi] = pMesh->mTangents[srcIndex];
|
nuclear@0
|
347 oMesh->mBitangents[nvi] = pMesh->mBitangents[srcIndex];
|
nuclear@0
|
348 }
|
nuclear@0
|
349 for( size_t c = 0, cc = pMesh->GetNumUVChannels(); c < cc; ++c ) {
|
nuclear@0
|
350 oMesh->mTextureCoords[c][nvi] = pMesh->mTextureCoords[c][srcIndex];
|
nuclear@0
|
351 }
|
nuclear@0
|
352 for( size_t c = 0, cc = pMesh->GetNumColorChannels(); c < cc; ++c ) {
|
nuclear@0
|
353 oMesh->mColors[c][nvi] = pMesh->mColors[c][srcIndex];
|
nuclear@0
|
354 }
|
nuclear@0
|
355 }
|
nuclear@0
|
356
|
nuclear@0
|
357 if(~subFlags&AI_SUBMESH_FLAGS_SANS_BONES) {
|
nuclear@0
|
358 std::vector<unsigned int> subBones(pMesh->mNumBones,0);
|
nuclear@0
|
359
|
nuclear@0
|
360 for(unsigned int a=0;a<pMesh->mNumBones;++a) {
|
nuclear@0
|
361 const aiBone* bone = pMesh->mBones[a];
|
nuclear@0
|
362
|
nuclear@0
|
363 for(unsigned int b=0;b<bone->mNumWeights;b++) {
|
nuclear@0
|
364 unsigned int v = vMap[bone->mWeights[b].mVertexId];
|
nuclear@0
|
365
|
nuclear@0
|
366 if(v!=UINT_MAX) {
|
nuclear@0
|
367 subBones[a]++;
|
nuclear@0
|
368 }
|
nuclear@0
|
369 }
|
nuclear@0
|
370 }
|
nuclear@0
|
371
|
nuclear@0
|
372 for(unsigned int a=0;a<pMesh->mNumBones;++a) {
|
nuclear@0
|
373 if(subBones[a]>0) {
|
nuclear@0
|
374 oMesh->mNumBones++;
|
nuclear@0
|
375 }
|
nuclear@0
|
376 }
|
nuclear@0
|
377
|
nuclear@0
|
378 if(oMesh->mNumBones) {
|
nuclear@0
|
379 oMesh->mBones = new aiBone*[oMesh->mNumBones]();
|
nuclear@0
|
380 unsigned int nbParanoia = oMesh->mNumBones;
|
nuclear@0
|
381
|
nuclear@0
|
382 oMesh->mNumBones = 0; //rewind
|
nuclear@0
|
383
|
nuclear@0
|
384 for(unsigned int a=0;a<pMesh->mNumBones;++a) {
|
nuclear@0
|
385 if(subBones[a]==0) {
|
nuclear@0
|
386 continue;
|
nuclear@0
|
387 }
|
nuclear@0
|
388 aiBone *newBone = new aiBone;
|
nuclear@0
|
389 oMesh->mBones[oMesh->mNumBones++] = newBone;
|
nuclear@0
|
390
|
nuclear@0
|
391 const aiBone* bone = pMesh->mBones[a];
|
nuclear@0
|
392
|
nuclear@0
|
393 newBone->mName = bone->mName;
|
nuclear@0
|
394 newBone->mOffsetMatrix = bone->mOffsetMatrix;
|
nuclear@0
|
395 newBone->mWeights = new aiVertexWeight[subBones[a]];
|
nuclear@0
|
396
|
nuclear@0
|
397 for(unsigned int b=0;b<bone->mNumWeights;b++) {
|
nuclear@0
|
398 const unsigned int v = vMap[bone->mWeights[b].mVertexId];
|
nuclear@0
|
399
|
nuclear@0
|
400 if(v!=UINT_MAX) {
|
nuclear@0
|
401 aiVertexWeight w(v,bone->mWeights[b].mWeight);
|
nuclear@0
|
402 newBone->mWeights[newBone->mNumWeights++] = w;
|
nuclear@0
|
403 }
|
nuclear@0
|
404 }
|
nuclear@0
|
405 }
|
nuclear@0
|
406
|
nuclear@0
|
407 ai_assert(nbParanoia==oMesh->mNumBones);
|
nuclear@0
|
408 (void)nbParanoia; // remove compiler warning on release build
|
nuclear@0
|
409 }
|
nuclear@0
|
410 }
|
nuclear@0
|
411
|
nuclear@0
|
412 return oMesh;
|
nuclear@0
|
413 }
|
nuclear@0
|
414
|
nuclear@0
|
415 } // namespace Assimp
|