1 /*
2 ---------------------------------------------------------------------------
3 Open Asset Import Library (assimp)
4 ---------------------------------------------------------------------------
5 
6 Copyright (c) 2006-2016, assimp team
7 
8 All rights reserved.
9 
10 Redistribution and use of this software in source and binary forms,
11 with or without modification, are permitted provided that the following
12 conditions are met:
13 
14 * Redistributions of source code must retain the above
15   copyright notice, this list of conditions and the
16   following disclaimer.
17 
18 * Redistributions in binary form must reproduce the above
19   copyright notice, this list of conditions and the
20   following disclaimer in the documentation and/or other
21   materials provided with the distribution.
22 
23 * Neither the name of the assimp team, nor the names of its
24   contributors may be used to endorse or promote products
25   derived from this software without specific prior
26   written permission of the assimp team.
27 
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 ---------------------------------------------------------------------------
40 */
41 /** @file Implementation of the post processing step "MakeVerboseFormat"
42 */
43 
44 
45 #include "MakeVerboseFormat.h"
46 #include <assimp/scene.h>
47 #include <assimp/DefaultLogger.hpp>
48 
49 using namespace Assimp;
50 
51 // ------------------------------------------------------------------------------------------------
MakeVerboseFormatProcess()52 MakeVerboseFormatProcess::MakeVerboseFormatProcess()
53 {
54     // nothing to do here
55 }
56 // ------------------------------------------------------------------------------------------------
~MakeVerboseFormatProcess()57 MakeVerboseFormatProcess::~MakeVerboseFormatProcess()
58 {
59     // nothing to do here
60 }
61 // ------------------------------------------------------------------------------------------------
62 // Executes the post processing step on the given imported data.
Execute(aiScene * pScene)63 void MakeVerboseFormatProcess::Execute( aiScene* pScene)
64 {
65     ai_assert(NULL != pScene);
66     DefaultLogger::get()->debug("MakeVerboseFormatProcess begin");
67 
68     bool bHas = false;
69     for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
70     {
71         if( MakeVerboseFormat( pScene->mMeshes[a]))
72             bHas = true;
73     }
74     if (bHas) DefaultLogger::get()->info("MakeVerboseFormatProcess finished. There was much work to do ...");
75     else DefaultLogger::get()->debug("MakeVerboseFormatProcess. There was nothing to do.");
76 
77     pScene->mFlags &= ~AI_SCENE_FLAGS_NON_VERBOSE_FORMAT;
78 
79 }
80 // ------------------------------------------------------------------------------------------------
81 // Executes the post processing step on the given imported data.
MakeVerboseFormat(aiMesh * pcMesh)82 bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
83 {
84     ai_assert(NULL != pcMesh);
85 
86     unsigned int iOldNumVertices = pcMesh->mNumVertices;
87     const unsigned int iNumVerts = pcMesh->mNumFaces*3;
88 
89     aiVector3D* pvPositions = new aiVector3D[ iNumVerts ];
90 
91     aiVector3D* pvNormals = NULL;
92     if (pcMesh->HasNormals())
93     {
94         pvNormals = new aiVector3D[iNumVerts];
95     }
96     aiVector3D* pvTangents = NULL, *pvBitangents = NULL;
97     if (pcMesh->HasTangentsAndBitangents())
98     {
99         pvTangents = new aiVector3D[iNumVerts];
100         pvBitangents = new aiVector3D[iNumVerts];
101     }
102 
103     aiVector3D* apvTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS] = {0};
104     aiColor4D* apvColorSets[AI_MAX_NUMBER_OF_COLOR_SETS] = {0};
105 
106     unsigned int p = 0;
107     while (pcMesh->HasTextureCoords(p))
108         apvTextureCoords[p++] = new aiVector3D[iNumVerts];
109 
110     p = 0;
111     while (pcMesh->HasVertexColors(p))
112         apvColorSets[p++] = new aiColor4D[iNumVerts];
113 
114     // allocate enough memory to hold output bones and vertex weights ...
115     std::vector<aiVertexWeight>* newWeights = new std::vector<aiVertexWeight>[pcMesh->mNumBones];
116     for (unsigned int i = 0;i < pcMesh->mNumBones;++i) {
117         newWeights[i].reserve(pcMesh->mBones[i]->mNumWeights*3);
118     }
119 
120     // iterate through all faces and build a clean list
121     unsigned int iIndex = 0;
122     for (unsigned int a = 0; a< pcMesh->mNumFaces;++a)
123     {
124         aiFace* pcFace = &pcMesh->mFaces[a];
125         for (unsigned int q = 0; q < pcFace->mNumIndices;++q,++iIndex)
126         {
127             // need to build a clean list of bones, too
128             for (unsigned int i = 0;i < pcMesh->mNumBones;++i)
129             {
130                 for (unsigned int a = 0;  a < pcMesh->mBones[i]->mNumWeights;a++)
131                 {
132                     const aiVertexWeight& w = pcMesh->mBones[i]->mWeights[a];
133                     if(pcFace->mIndices[q] == w.mVertexId)
134                     {
135                         aiVertexWeight wNew;
136                         wNew.mVertexId = iIndex;
137                         wNew.mWeight = w.mWeight;
138                         newWeights[i].push_back(wNew);
139                     }
140                 }
141             }
142 
143             pvPositions[iIndex] = pcMesh->mVertices[pcFace->mIndices[q]];
144 
145             if (pcMesh->HasNormals())
146             {
147                 pvNormals[iIndex] = pcMesh->mNormals[pcFace->mIndices[q]];
148             }
149             if (pcMesh->HasTangentsAndBitangents())
150             {
151                 pvTangents[iIndex] = pcMesh->mTangents[pcFace->mIndices[q]];
152                 pvBitangents[iIndex] = pcMesh->mBitangents[pcFace->mIndices[q]];
153             }
154 
155             unsigned int p = 0;
156             while (pcMesh->HasTextureCoords(p))
157             {
158                 apvTextureCoords[p][iIndex] = pcMesh->mTextureCoords[p][pcFace->mIndices[q]];
159                 ++p;
160             }
161             p = 0;
162             while (pcMesh->HasVertexColors(p))
163             {
164                 apvColorSets[p][iIndex] = pcMesh->mColors[p][pcFace->mIndices[q]];
165                 ++p;
166             }
167             pcFace->mIndices[q] = iIndex;
168         }
169     }
170 
171     // build output vertex weights
172     for (unsigned int i = 0;i < pcMesh->mNumBones;++i)
173     {
174         delete pcMesh->mBones[i]->mWeights;
175         if (!newWeights[i].empty()) {
176             pcMesh->mBones[i]->mWeights = new aiVertexWeight[newWeights[i].size()];
177             aiVertexWeight *weightToCopy = &( newWeights[i][0] );
178             memcpy(pcMesh->mBones[i]->mWeights, weightToCopy,
179                 sizeof(aiVertexWeight) * newWeights[i].size());
180             delete[] newWeights;
181         } else {
182             pcMesh->mBones[i]->mWeights = NULL;
183         }
184     }
185 
186     // delete the old members
187     delete[] pcMesh->mVertices;
188     pcMesh->mVertices = pvPositions;
189 
190     p = 0;
191     while (pcMesh->HasTextureCoords(p))
192     {
193         delete pcMesh->mTextureCoords[p];
194         pcMesh->mTextureCoords[p] = apvTextureCoords[p];
195         ++p;
196     }
197     p = 0;
198     while (pcMesh->HasVertexColors(p))
199     {
200         delete pcMesh->mColors[p];
201         pcMesh->mColors[p] = apvColorSets[p];
202         ++p;
203     }
204     pcMesh->mNumVertices = iNumVerts;
205 
206     if (pcMesh->HasNormals())
207     {
208         delete[] pcMesh->mNormals;
209         pcMesh->mNormals = pvNormals;
210     }
211     if (pcMesh->HasTangentsAndBitangents())
212     {
213         delete[] pcMesh->mTangents;
214         pcMesh->mTangents = pvTangents;
215         delete[] pcMesh->mBitangents;
216         pcMesh->mBitangents = pvBitangents;
217     }
218     return (pcMesh->mNumVertices != iOldNumVertices);
219 }
220