vrshoot

view libs/assimp/ScenePreprocessor.cpp @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line source
1 /*
2 Open Asset Import Library (assimp)
3 ----------------------------------------------------------------------
5 Copyright (c) 2006-2012, assimp team
6 All rights reserved.
8 Redistribution and use of this software in source and binary forms,
9 with or without modification, are permitted provided that the
10 following conditions are met:
12 * Redistributions of source code must retain the above
13 copyright notice, this list of conditions and the
14 following disclaimer.
16 * Redistributions in binary form must reproduce the above
17 copyright notice, this list of conditions and the
18 following disclaimer in the documentation and/or other
19 materials provided with the distribution.
21 * Neither the name of the assimp team, nor the names of its
22 contributors may be used to endorse or promote products
23 derived from this software without specific prior
24 written permission of the assimp team.
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 ----------------------------------------------------------------------
39 */
41 #include "AssimpPCH.h"
42 #include "ScenePreprocessor.h"
44 using namespace Assimp;
46 // ---------------------------------------------------------------------------------------------
47 void ScenePreprocessor::ProcessScene ()
48 {
49 ai_assert(scene != NULL);
51 // Process all meshes
52 for (unsigned int i = 0; i < scene->mNumMeshes;++i)
53 ProcessMesh(scene->mMeshes[i]);
55 // - nothing to do for nodes for the moment
56 // - nothing to do for textures for the moment
57 // - nothing to do for lights for the moment
58 // - nothing to do for cameras for the moment
60 // Process all animations
61 for (unsigned int i = 0; i < scene->mNumAnimations;++i)
62 ProcessAnimation(scene->mAnimations[i]);
64 // Generate a default material if none was specified
65 if (!scene->mNumMaterials && scene->mNumMeshes) {
66 scene->mMaterials = new aiMaterial*[2];
67 aiMaterial* helper;
69 aiString name;
71 scene->mMaterials[scene->mNumMaterials] = helper = new aiMaterial();
72 aiColor3D clr(0.6f,0.6f,0.6f);
73 helper->AddProperty(&clr,1,AI_MATKEY_COLOR_DIFFUSE);
75 // setup the default name to make this material identifyable
76 name.Set(AI_DEFAULT_MATERIAL_NAME);
77 helper->AddProperty(&name,AI_MATKEY_NAME);
79 DefaultLogger::get()->debug("ScenePreprocessor: Adding default material \'" AI_DEFAULT_MATERIAL_NAME "\'");
81 for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
82 scene->mMeshes[i]->mMaterialIndex = scene->mNumMaterials;
83 }
85 scene->mNumMaterials++;
86 }
87 }
89 // ---------------------------------------------------------------------------------------------
90 void ScenePreprocessor::ProcessMesh (aiMesh* mesh)
91 {
92 // If aiMesh::mNumUVComponents is *not* set assign the default value of 2
93 for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
94 if (!mesh->mTextureCoords[i])
95 mesh->mNumUVComponents[i] = 0;
97 else {
98 if( !mesh->mNumUVComponents[i])
99 mesh->mNumUVComponents[i] = 2;
101 aiVector3D* p = mesh->mTextureCoords[i], *end = p+mesh->mNumVertices;
103 // Ensure unsued components are zeroed. This will make 1D texture channels work
104 // as if they were 2D channels .. just in case an application doesn't handle
105 // this case
106 if (2 == mesh->mNumUVComponents[i]) {
107 for (; p != end; ++p)
108 p->z = 0.f;
109 }
110 else if (1 == mesh->mNumUVComponents[i]) {
111 for (; p != end; ++p)
112 p->z = p->y = 0.f;
113 }
114 else if (3 == mesh->mNumUVComponents[i]) {
116 // Really 3D coordinates? Check whether the third coordinate is != 0 for at least one element
117 for (; p != end; ++p) {
118 if (p->z != 0)
119 break;
120 }
121 if (p == end) {
122 DefaultLogger::get()->warn("ScenePreprocessor: UVs are declared to be 3D but they're obviously not. Reverting to 2D.");
123 mesh->mNumUVComponents[i] = 2;
124 }
125 }
126 }
127 }
129 // If the information which primitive types are there in the
130 // mesh is currently not available, compute it.
131 if (!mesh->mPrimitiveTypes) {
132 for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
133 aiFace& face = mesh->mFaces[a];
134 switch (face.mNumIndices)
135 {
136 case 3u:
137 mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
138 break;
140 case 2u:
141 mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
142 break;
144 case 1u:
145 mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
146 break;
148 default:
149 mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
150 break;
151 }
152 }
153 }
155 // If tangents and normals are given but no bitangents compute them
156 if (mesh->mTangents && mesh->mNormals && !mesh->mBitangents) {
158 mesh->mBitangents = new aiVector3D[mesh->mNumVertices];
159 for (unsigned int i = 0; i < mesh->mNumVertices;++i) {
160 mesh->mBitangents[i] = mesh->mNormals[i] ^ mesh->mTangents[i];
161 }
162 }
163 }
165 // ---------------------------------------------------------------------------------------------
166 void ScenePreprocessor::ProcessAnimation (aiAnimation* anim)
167 {
168 double first = 10e10, last = -10e10;
169 for (unsigned int i = 0; i < anim->mNumChannels;++i) {
170 aiNodeAnim* channel = anim->mChannels[i];
172 /* If the exact duration of the animation is not given
173 * compute it now.
174 */
175 if (anim->mDuration == -1.) {
177 // Position keys
178 for (unsigned int i = 0; i < channel->mNumPositionKeys;++i) {
179 aiVectorKey& key = channel->mPositionKeys[i];
180 first = std::min (first, key.mTime);
181 last = std::max (last, key.mTime);
182 }
184 // Scaling keys
185 for (unsigned int i = 0; i < channel->mNumScalingKeys;++i) {
186 aiVectorKey& key = channel->mScalingKeys[i];
187 first = std::min (first, key.mTime);
188 last = std::max (last, key.mTime);
189 }
191 // Rotation keys
192 for (unsigned int i = 0; i < channel->mNumRotationKeys;++i) {
193 aiQuatKey& key = channel->mRotationKeys[i];
194 first = std::min (first, key.mTime);
195 last = std::max (last, key.mTime);
196 }
197 }
199 /* Check whether the animation channel has no rotation
200 * or position tracks. In this case we generate a dummy
201 * track from the information we have in the transformation
202 * matrix of the corresponding node.
203 */
204 if (!channel->mNumRotationKeys || !channel->mNumPositionKeys || !channel->mNumScalingKeys) {
205 // Find the node that belongs to this animation
206 aiNode* node = scene->mRootNode->FindNode(channel->mNodeName);
207 if (node) // ValidateDS will complain later if 'node' is NULL
208 {
209 // Decompose the transformation matrix of the node
210 aiVector3D scaling, position;
211 aiQuaternion rotation;
213 node->mTransformation.Decompose(scaling, rotation,position);
215 // No rotation keys? Generate a dummy track
216 if (!channel->mNumRotationKeys) {
217 channel->mNumRotationKeys = 1;
218 channel->mRotationKeys = new aiQuatKey[1];
219 aiQuatKey& q = channel->mRotationKeys[0];
221 q.mTime = 0.;
222 q.mValue = rotation;
224 DefaultLogger::get()->debug("ScenePreprocessor: Dummy rotation track has been generated");
225 }
227 // No scaling keys? Generate a dummy track
228 if (!channel->mNumScalingKeys) {
229 channel->mNumScalingKeys = 1;
230 channel->mScalingKeys = new aiVectorKey[1];
231 aiVectorKey& q = channel->mScalingKeys[0];
233 q.mTime = 0.;
234 q.mValue = scaling;
236 DefaultLogger::get()->debug("ScenePreprocessor: Dummy scaling track has been generated");
237 }
239 // No position keys? Generate a dummy track
240 if (!channel->mNumPositionKeys) {
241 channel->mNumPositionKeys = 1;
242 channel->mPositionKeys = new aiVectorKey[1];
243 aiVectorKey& q = channel->mPositionKeys[0];
245 q.mTime = 0.;
246 q.mValue = position;
248 DefaultLogger::get()->debug("ScenePreprocessor: Dummy position track has been generated");
249 }
250 }
251 }
252 }
254 if (anim->mDuration == -1.) {
255 DefaultLogger::get()->debug("ScenePreprocessor: Setting animation duration");
256 anim->mDuration = last - std::min( first, 0. );
257 }
258 }