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