vrshoot
diff libs/assimp/Q3DLoader.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/Q3DLoader.cpp Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,611 @@ 1.4 +/* 1.5 +--------------------------------------------------------------------------- 1.6 +Open Asset Import Library (assimp) 1.7 +--------------------------------------------------------------------------- 1.8 + 1.9 +Copyright (c) 2006-2012, assimp team 1.10 + 1.11 +All rights reserved. 1.12 + 1.13 +Redistribution and use of this software in source and binary forms, 1.14 +with or without modification, are permitted provided that the following 1.15 +conditions are met: 1.16 + 1.17 +* Redistributions of source code must retain the above 1.18 + copyright notice, this list of conditions and the 1.19 + following disclaimer. 1.20 + 1.21 +* Redistributions in binary form must reproduce the above 1.22 + copyright notice, this list of conditions and the 1.23 + following disclaimer in the documentation and/or other 1.24 + materials provided with the distribution. 1.25 + 1.26 +* Neither the name of the assimp team, nor the names of its 1.27 + contributors may be used to endorse or promote products 1.28 + derived from this software without specific prior 1.29 + written permission of the assimp team. 1.30 + 1.31 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.32 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.33 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.34 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.35 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.36 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.37 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.38 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.39 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.40 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.41 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.42 +--------------------------------------------------------------------------- 1.43 +*/ 1.44 + 1.45 +/** @file Q3DLoader.cpp 1.46 + * @brief Implementation of the Q3D importer class 1.47 + */ 1.48 + 1.49 +#include "AssimpPCH.h" 1.50 +#ifndef ASSIMP_BUILD_NO_Q3D_IMPORTER 1.51 + 1.52 +// internal headers 1.53 +#include "Q3DLoader.h" 1.54 +#include "StreamReader.h" 1.55 +#include "fast_atof.h" 1.56 + 1.57 +using namespace Assimp; 1.58 + 1.59 +static const aiImporterDesc desc = { 1.60 + "Quick3D Importer", 1.61 + "", 1.62 + "", 1.63 + "http://www.quick3d.com/", 1.64 + aiImporterFlags_SupportBinaryFlavour, 1.65 + 0, 1.66 + 0, 1.67 + 0, 1.68 + 0, 1.69 + "q3o q3s" 1.70 +}; 1.71 + 1.72 +// ------------------------------------------------------------------------------------------------ 1.73 +// Constructor to be privately used by Importer 1.74 +Q3DImporter::Q3DImporter() 1.75 +{} 1.76 + 1.77 +// ------------------------------------------------------------------------------------------------ 1.78 +// Destructor, private as well 1.79 +Q3DImporter::~Q3DImporter() 1.80 +{} 1.81 + 1.82 +// ------------------------------------------------------------------------------------------------ 1.83 +// Returns whether the class can handle the format of the given file. 1.84 +bool Q3DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const 1.85 +{ 1.86 + const std::string extension = GetExtension(pFile); 1.87 + 1.88 + if (extension == "q3s" || extension == "q3o") 1.89 + return true; 1.90 + else if (!extension.length() || checkSig) { 1.91 + if (!pIOHandler) 1.92 + return true; 1.93 + const char* tokens[] = {"quick3Do","quick3Ds"}; 1.94 + return SearchFileHeaderForToken(pIOHandler,pFile,tokens,2); 1.95 + } 1.96 + return false; 1.97 +} 1.98 + 1.99 +// ------------------------------------------------------------------------------------------------ 1.100 +const aiImporterDesc* Q3DImporter::GetInfo () const 1.101 +{ 1.102 + return &desc; 1.103 +} 1.104 + 1.105 +// ------------------------------------------------------------------------------------------------ 1.106 +// Imports the given file into the given scene structure. 1.107 +void Q3DImporter::InternReadFile( const std::string& pFile, 1.108 + aiScene* pScene, IOSystem* pIOHandler) 1.109 +{ 1.110 + StreamReaderLE stream(pIOHandler->Open(pFile,"rb")); 1.111 + 1.112 + // The header is 22 bytes large 1.113 + if (stream.GetRemainingSize() < 22) 1.114 + throw DeadlyImportError("File is either empty or corrupt: " + pFile); 1.115 + 1.116 + // Check the file's signature 1.117 + if (ASSIMP_strincmp( (const char*)stream.GetPtr(), "quick3Do", 8 ) && 1.118 + ASSIMP_strincmp( (const char*)stream.GetPtr(), "quick3Ds", 8 )) 1.119 + { 1.120 + throw DeadlyImportError("Not a Quick3D file. Signature string is: " + 1.121 + std::string((const char*)stream.GetPtr(),8)); 1.122 + } 1.123 + 1.124 + // Print the file format version 1.125 + DefaultLogger::get()->info("Quick3D File format version: " + 1.126 + std::string(&((const char*)stream.GetPtr())[8],2)); 1.127 + 1.128 + // ... an store it 1.129 + char major = ((const char*)stream.GetPtr())[8]; 1.130 + char minor = ((const char*)stream.GetPtr())[9]; 1.131 + 1.132 + stream.IncPtr(10); 1.133 + unsigned int numMeshes = (unsigned int)stream.GetI4(); 1.134 + unsigned int numMats = (unsigned int)stream.GetI4(); 1.135 + unsigned int numTextures = (unsigned int)stream.GetI4(); 1.136 + 1.137 + std::vector<Material> materials; 1.138 + materials.reserve(numMats); 1.139 + 1.140 + std::vector<Mesh> meshes; 1.141 + meshes.reserve(numMeshes); 1.142 + 1.143 + // Allocate the scene root node 1.144 + pScene->mRootNode = new aiNode(); 1.145 + 1.146 + aiColor3D fgColor (0.6f,0.6f,0.6f); 1.147 + 1.148 + // Now read all file chunks 1.149 + while (true) 1.150 + { 1.151 + if (stream.GetRemainingSize() < 1)break; 1.152 + char c = stream.GetI1(); 1.153 + switch (c) 1.154 + { 1.155 + // Meshes chunk 1.156 + case 'm': 1.157 + { 1.158 + for (unsigned int quak = 0; quak < numMeshes; ++quak) 1.159 + { 1.160 + meshes.push_back(Mesh()); 1.161 + Mesh& mesh = meshes.back(); 1.162 + 1.163 + // read all vertices 1.164 + unsigned int numVerts = (unsigned int)stream.GetI4(); 1.165 + if (!numVerts) 1.166 + throw DeadlyImportError("Quick3D: Found mesh with zero vertices"); 1.167 + 1.168 + std::vector<aiVector3D>& verts = mesh.verts; 1.169 + verts.resize(numVerts); 1.170 + 1.171 + for (unsigned int i = 0; i < numVerts;++i) 1.172 + { 1.173 + verts[i].x = stream.GetF4(); 1.174 + verts[i].y = stream.GetF4(); 1.175 + verts[i].z = stream.GetF4(); 1.176 + } 1.177 + 1.178 + // read all faces 1.179 + numVerts = (unsigned int)stream.GetI4(); 1.180 + if (!numVerts) 1.181 + throw DeadlyImportError("Quick3D: Found mesh with zero faces"); 1.182 + 1.183 + std::vector<Face >& faces = mesh.faces; 1.184 + faces.reserve(numVerts); 1.185 + 1.186 + // number of indices 1.187 + for (unsigned int i = 0; i < numVerts;++i) 1.188 + { 1.189 + faces.push_back(Face(stream.GetI2()) ); 1.190 + if (faces.back().indices.empty()) 1.191 + throw DeadlyImportError("Quick3D: Found face with zero indices"); 1.192 + } 1.193 + 1.194 + // indices 1.195 + for (unsigned int i = 0; i < numVerts;++i) 1.196 + { 1.197 + Face& vec = faces[i]; 1.198 + for (unsigned int a = 0; a < (unsigned int)vec.indices.size();++a) 1.199 + vec.indices[a] = stream.GetI4(); 1.200 + } 1.201 + 1.202 + // material indices 1.203 + for (unsigned int i = 0; i < numVerts;++i) 1.204 + { 1.205 + faces[i].mat = (unsigned int)stream.GetI4(); 1.206 + } 1.207 + 1.208 + // read all normals 1.209 + numVerts = (unsigned int)stream.GetI4(); 1.210 + std::vector<aiVector3D>& normals = mesh.normals; 1.211 + normals.resize(numVerts); 1.212 + 1.213 + for (unsigned int i = 0; i < numVerts;++i) 1.214 + { 1.215 + normals[i].x = stream.GetF4(); 1.216 + normals[i].y = stream.GetF4(); 1.217 + normals[i].z = stream.GetF4(); 1.218 + } 1.219 + 1.220 + numVerts = (unsigned int)stream.GetI4(); 1.221 + if (numTextures && numVerts) 1.222 + { 1.223 + // read all texture coordinates 1.224 + std::vector<aiVector3D>& uv = mesh.uv; 1.225 + uv.resize(numVerts); 1.226 + 1.227 + for (unsigned int i = 0; i < numVerts;++i) 1.228 + { 1.229 + uv[i].x = stream.GetF4(); 1.230 + uv[i].y = stream.GetF4(); 1.231 + } 1.232 + 1.233 + // UV indices 1.234 + for (unsigned int i = 0; i < (unsigned int)faces.size();++i) 1.235 + { 1.236 + Face& vec = faces[i]; 1.237 + for (unsigned int a = 0; a < (unsigned int)vec.indices.size();++a) 1.238 + { 1.239 + vec.uvindices[a] = stream.GetI4(); 1.240 + if (!i && !a) 1.241 + mesh.prevUVIdx = vec.uvindices[a]; 1.242 + else if (vec.uvindices[a] != mesh.prevUVIdx) 1.243 + mesh.prevUVIdx = UINT_MAX; 1.244 + } 1.245 + } 1.246 + } 1.247 + 1.248 + // we don't need the rest, but we need to get to the next chunk 1.249 + stream.IncPtr(36); 1.250 + if (minor > '0' && major == '3') 1.251 + stream.IncPtr(mesh.faces.size()); 1.252 + } 1.253 + // stream.IncPtr(4); // unknown value here 1.254 + } 1.255 + break; 1.256 + 1.257 + // materials chunk 1.258 + case 'c': 1.259 + 1.260 + for (unsigned int i = 0; i < numMats; ++i) 1.261 + { 1.262 + materials.push_back(Material()); 1.263 + Material& mat = materials.back(); 1.264 + 1.265 + // read the material name 1.266 + while (( c = stream.GetI1())) 1.267 + mat.name.data[mat.name.length++] = c; 1.268 + 1.269 + // add the terminal character 1.270 + mat.name.data[mat.name.length] = '\0'; 1.271 + 1.272 + // read the ambient color 1.273 + mat.ambient.r = stream.GetF4(); 1.274 + mat.ambient.g = stream.GetF4(); 1.275 + mat.ambient.b = stream.GetF4(); 1.276 + 1.277 + // read the diffuse color 1.278 + mat.diffuse.r = stream.GetF4(); 1.279 + mat.diffuse.g = stream.GetF4(); 1.280 + mat.diffuse.b = stream.GetF4(); 1.281 + 1.282 + // read the ambient color 1.283 + mat.specular.r = stream.GetF4(); 1.284 + mat.specular.g = stream.GetF4(); 1.285 + mat.specular.b = stream.GetF4(); 1.286 + 1.287 + // read the transparency 1.288 + mat.transparency = stream.GetF4(); 1.289 + 1.290 + // unknown value here 1.291 + // stream.IncPtr(4); 1.292 + // FIX: it could be the texture index ... 1.293 + mat.texIdx = (unsigned int)stream.GetI4(); 1.294 + } 1.295 + 1.296 + break; 1.297 + 1.298 + // texture chunk 1.299 + case 't': 1.300 + 1.301 + pScene->mNumTextures = numTextures; 1.302 + if (!numTextures)break; 1.303 + pScene->mTextures = new aiTexture*[pScene->mNumTextures]; 1.304 + // to make sure we won't crash if we leave through an exception 1.305 + ::memset(pScene->mTextures,0,sizeof(void*)*pScene->mNumTextures); 1.306 + for (unsigned int i = 0; i < pScene->mNumTextures; ++i) 1.307 + { 1.308 + aiTexture* tex = pScene->mTextures[i] = new aiTexture(); 1.309 + 1.310 + // skip the texture name 1.311 + while (stream.GetI1()); 1.312 + 1.313 + // read texture width and height 1.314 + tex->mWidth = (unsigned int)stream.GetI4(); 1.315 + tex->mHeight = (unsigned int)stream.GetI4(); 1.316 + 1.317 + if (!tex->mWidth || !tex->mHeight) 1.318 + throw DeadlyImportError("Quick3D: Invalid texture. Width or height is zero"); 1.319 + 1.320 + register unsigned int mul = tex->mWidth * tex->mHeight; 1.321 + aiTexel* begin = tex->pcData = new aiTexel[mul]; 1.322 + aiTexel* const end = & begin [mul]; 1.323 + 1.324 + for (;begin != end; ++begin) 1.325 + { 1.326 + begin->r = stream.GetI1(); 1.327 + begin->g = stream.GetI1(); 1.328 + begin->b = stream.GetI1(); 1.329 + begin->a = 0xff; 1.330 + } 1.331 + } 1.332 + 1.333 + break; 1.334 + 1.335 + // scene chunk 1.336 + case 's': 1.337 + { 1.338 + // skip position and rotation 1.339 + stream.IncPtr(12); 1.340 + 1.341 + for (unsigned int i = 0; i < 4;++i) 1.342 + for (unsigned int a = 0; a < 4;++a) 1.343 + pScene->mRootNode->mTransformation[i][a] = stream.GetF4(); 1.344 + 1.345 + stream.IncPtr(16); 1.346 + 1.347 + // now setup a single camera 1.348 + pScene->mNumCameras = 1; 1.349 + pScene->mCameras = new aiCamera*[1]; 1.350 + aiCamera* cam = pScene->mCameras[0] = new aiCamera(); 1.351 + cam->mPosition.x = stream.GetF4(); 1.352 + cam->mPosition.y = stream.GetF4(); 1.353 + cam->mPosition.z = stream.GetF4(); 1.354 + cam->mName.Set("Q3DCamera"); 1.355 + 1.356 + // skip eye rotation for the moment 1.357 + stream.IncPtr(12); 1.358 + 1.359 + // read the default material color 1.360 + fgColor .r = stream.GetF4(); 1.361 + fgColor .g = stream.GetF4(); 1.362 + fgColor .b = stream.GetF4(); 1.363 + 1.364 + // skip some unimportant properties 1.365 + stream.IncPtr(29); 1.366 + 1.367 + // setup a single point light with no attenuation 1.368 + pScene->mNumLights = 1; 1.369 + pScene->mLights = new aiLight*[1]; 1.370 + aiLight* light = pScene->mLights[0] = new aiLight(); 1.371 + light->mName.Set("Q3DLight"); 1.372 + light->mType = aiLightSource_POINT; 1.373 + 1.374 + light->mAttenuationConstant = 1; 1.375 + light->mAttenuationLinear = 0; 1.376 + light->mAttenuationQuadratic = 0; 1.377 + 1.378 + light->mColorDiffuse.r = stream.GetF4(); 1.379 + light->mColorDiffuse.g = stream.GetF4(); 1.380 + light->mColorDiffuse.b = stream.GetF4(); 1.381 + 1.382 + light->mColorSpecular = light->mColorDiffuse; 1.383 + 1.384 + 1.385 + // We don't need the rest, but we need to know where this chunk ends. 1.386 + unsigned int temp = (unsigned int)(stream.GetI4() * stream.GetI4()); 1.387 + 1.388 + // skip the background file name 1.389 + while (stream.GetI1()); 1.390 + 1.391 + // skip background texture data + the remaining fields 1.392 + stream.IncPtr(temp*3 + 20); // 4 bytes of unknown data here 1.393 + 1.394 + // TODO 1.395 + goto outer; 1.396 + } 1.397 + break; 1.398 + 1.399 + default: 1.400 + throw DeadlyImportError("Quick3D: Unknown chunk"); 1.401 + break; 1.402 + }; 1.403 + } 1.404 +outer: 1.405 + 1.406 + // If we have no mesh loaded - break here 1.407 + if (meshes.empty()) 1.408 + throw DeadlyImportError("Quick3D: No meshes loaded"); 1.409 + 1.410 + // If we have no materials loaded - generate a default mat 1.411 + if (materials.empty()) 1.412 + { 1.413 + DefaultLogger::get()->info("Quick3D: No material found, generating one"); 1.414 + materials.push_back(Material()); 1.415 + materials.back().diffuse = fgColor ; 1.416 + } 1.417 + 1.418 + // find out which materials we'll need 1.419 + typedef std::pair<unsigned int, unsigned int> FaceIdx; 1.420 + typedef std::vector< FaceIdx > FaceIdxArray; 1.421 + FaceIdxArray* fidx = new FaceIdxArray[materials.size()]; 1.422 + 1.423 + unsigned int p = 0; 1.424 + for (std::vector<Mesh>::iterator it = meshes.begin(), end = meshes.end(); 1.425 + it != end; ++it,++p) 1.426 + { 1.427 + unsigned int q = 0; 1.428 + for (std::vector<Face>::iterator fit = (*it).faces.begin(), fend = (*it).faces.end(); 1.429 + fit != fend; ++fit,++q) 1.430 + { 1.431 + if ((*fit).mat >= materials.size()) 1.432 + { 1.433 + DefaultLogger::get()->warn("Quick3D: Material index overflow"); 1.434 + (*fit).mat = 0; 1.435 + } 1.436 + if (fidx[(*fit).mat].empty())++pScene->mNumMeshes; 1.437 + fidx[(*fit).mat].push_back( FaceIdx(p,q) ); 1.438 + } 1.439 + } 1.440 + pScene->mNumMaterials = pScene->mNumMeshes; 1.441 + pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]; 1.442 + pScene->mMeshes = new aiMesh*[pScene->mNumMaterials]; 1.443 + 1.444 + for (unsigned int i = 0, real = 0; i < (unsigned int)materials.size(); ++i) 1.445 + { 1.446 + if (fidx[i].empty())continue; 1.447 + 1.448 + // Allocate a mesh and a material 1.449 + aiMesh* mesh = pScene->mMeshes[real] = new aiMesh(); 1.450 + aiMaterial* mat = new aiMaterial(); 1.451 + pScene->mMaterials[real] = mat; 1.452 + 1.453 + mesh->mMaterialIndex = real; 1.454 + 1.455 + // Build the output material 1.456 + Material& srcMat = materials[i]; 1.457 + mat->AddProperty(&srcMat.diffuse, 1,AI_MATKEY_COLOR_DIFFUSE); 1.458 + mat->AddProperty(&srcMat.specular, 1,AI_MATKEY_COLOR_SPECULAR); 1.459 + mat->AddProperty(&srcMat.ambient, 1,AI_MATKEY_COLOR_AMBIENT); 1.460 + 1.461 + // NOTE: Ignore transparency for the moment - it seems 1.462 + // unclear how to interpret the data 1.463 +#if 0 1.464 + if (!(minor > '0' && major == '3')) 1.465 + srcMat.transparency = 1.0f - srcMat.transparency; 1.466 + mat->AddProperty(&srcMat.transparency, 1, AI_MATKEY_OPACITY); 1.467 +#endif 1.468 + 1.469 + // add shininess - Quick3D seems to use it ins its viewer 1.470 + srcMat.transparency = 16.f; 1.471 + mat->AddProperty(&srcMat.transparency, 1, AI_MATKEY_SHININESS); 1.472 + 1.473 + int m = (int)aiShadingMode_Phong; 1.474 + mat->AddProperty(&m, 1, AI_MATKEY_SHADING_MODEL); 1.475 + 1.476 + if (srcMat.name.length) 1.477 + mat->AddProperty(&srcMat.name,AI_MATKEY_NAME); 1.478 + 1.479 + // Add a texture 1.480 + if (srcMat.texIdx < pScene->mNumTextures || real < pScene->mNumTextures) 1.481 + { 1.482 + srcMat.name.data[0] = '*'; 1.483 + srcMat.name.length = ASSIMP_itoa10(&srcMat.name.data[1],1000, 1.484 + (srcMat.texIdx < pScene->mNumTextures ? srcMat.texIdx : real)); 1.485 + mat->AddProperty(&srcMat.name,AI_MATKEY_TEXTURE_DIFFUSE(0)); 1.486 + } 1.487 + 1.488 + mesh->mNumFaces = (unsigned int)fidx[i].size(); 1.489 + aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces]; 1.490 + 1.491 + // Now build the output mesh. First find out how many 1.492 + // vertices we'll need 1.493 + for (FaceIdxArray::const_iterator it = fidx[i].begin(),end = fidx[i].end(); 1.494 + it != end; ++it) 1.495 + { 1.496 + mesh->mNumVertices += (unsigned int)meshes[(*it).first].faces[ 1.497 + (*it).second].indices.size(); 1.498 + } 1.499 + 1.500 + aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices]; 1.501 + aiVector3D* norms = mesh->mNormals = new aiVector3D[mesh->mNumVertices]; 1.502 + aiVector3D* uv; 1.503 + if (real < pScene->mNumTextures) 1.504 + { 1.505 + uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]; 1.506 + mesh->mNumUVComponents[0] = 2; 1.507 + } 1.508 + else uv = NULL; 1.509 + 1.510 + // Build the final array 1.511 + unsigned int cnt = 0; 1.512 + for (FaceIdxArray::const_iterator it = fidx[i].begin(),end = fidx[i].end(); 1.513 + it != end; ++it, ++faces) 1.514 + { 1.515 + Mesh& m = meshes[(*it).first]; 1.516 + Face& face = m.faces[(*it).second]; 1.517 + faces->mNumIndices = (unsigned int)face.indices.size(); 1.518 + faces->mIndices = new unsigned int [faces->mNumIndices]; 1.519 + 1.520 + 1.521 + aiVector3D faceNormal; 1.522 + bool fnOK = false; 1.523 + 1.524 + for (unsigned int n = 0; n < faces->mNumIndices;++n, ++cnt, ++norms, ++verts) 1.525 + { 1.526 + if (face.indices[n] >= m.verts.size()) 1.527 + { 1.528 + DefaultLogger::get()->warn("Quick3D: Vertex index overflow"); 1.529 + face.indices[n] = 0; 1.530 + } 1.531 + 1.532 + // copy vertices 1.533 + *verts = m.verts[ face.indices[n] ]; 1.534 + 1.535 + if (face.indices[n] >= m.normals.size() && faces->mNumIndices >= 3) 1.536 + { 1.537 + // we have no normal here - assign the face normal 1.538 + if (!fnOK) 1.539 + { 1.540 + const aiVector3D& pV1 = m.verts[ face.indices[0] ]; 1.541 + const aiVector3D& pV2 = m.verts[ face.indices[1] ]; 1.542 + const aiVector3D& pV3 = m.verts[ face.indices.size() - 1 ]; 1.543 + faceNormal = (pV2 - pV1) ^ (pV3 - pV1).Normalize(); 1.544 + fnOK = true; 1.545 + } 1.546 + *norms = faceNormal; 1.547 + } 1.548 + else *norms = m.normals[ face.indices[n] ]; 1.549 + 1.550 + // copy texture coordinates 1.551 + if (uv && m.uv.size()) 1.552 + { 1.553 + if (m.prevUVIdx != 0xffffffff && m.uv.size() >= m.verts.size()) // workaround 1.554 + { 1.555 + *uv = m.uv[face.indices[n]]; 1.556 + } 1.557 + else 1.558 + { 1.559 + if (face.uvindices[n] >= m.uv.size()) 1.560 + { 1.561 + DefaultLogger::get()->warn("Quick3D: Texture coordinate index overflow"); 1.562 + face.uvindices[n] = 0; 1.563 + } 1.564 + *uv = m.uv[face.uvindices[n]]; 1.565 + } 1.566 + uv->y = 1.f - uv->y; 1.567 + ++uv; 1.568 + } 1.569 + 1.570 + // setup the new vertex index 1.571 + faces->mIndices[n] = cnt; 1.572 + } 1.573 + 1.574 + } 1.575 + ++real; 1.576 + } 1.577 + 1.578 + // Delete our nice helper array 1.579 + delete[] fidx; 1.580 + 1.581 + // Now we need to attach the meshes to the root node of the scene 1.582 + pScene->mRootNode->mNumMeshes = pScene->mNumMeshes; 1.583 + pScene->mRootNode->mMeshes = new unsigned int [pScene->mNumMeshes]; 1.584 + for (unsigned int i = 0; i < pScene->mNumMeshes;++i) 1.585 + pScene->mRootNode->mMeshes[i] = i; 1.586 + 1.587 + /*pScene->mRootNode->mTransformation *= aiMatrix4x4( 1.588 + 1.f, 0.f, 0.f, 0.f, 1.589 + 0.f, -1.f,0.f, 0.f, 1.590 + 0.f, 0.f, 1.f, 0.f, 1.591 + 0.f, 0.f, 0.f, 1.f);*/ 1.592 + 1.593 + // Add cameras and light sources to the scene root node 1.594 + pScene->mRootNode->mNumChildren = pScene->mNumLights+pScene->mNumCameras; 1.595 + if (pScene->mRootNode->mNumChildren) 1.596 + { 1.597 + pScene->mRootNode->mChildren = new aiNode* [ pScene->mRootNode->mNumChildren ]; 1.598 + 1.599 + // the light source 1.600 + aiNode* nd = pScene->mRootNode->mChildren[0] = new aiNode(); 1.601 + nd->mParent = pScene->mRootNode; 1.602 + nd->mName.Set("Q3DLight"); 1.603 + nd->mTransformation = pScene->mRootNode->mTransformation; 1.604 + nd->mTransformation.Inverse(); 1.605 + 1.606 + // camera 1.607 + nd = pScene->mRootNode->mChildren[1] = new aiNode(); 1.608 + nd->mParent = pScene->mRootNode; 1.609 + nd->mName.Set("Q3DCamera"); 1.610 + nd->mTransformation = pScene->mRootNode->mChildren[0]->mTransformation; 1.611 + } 1.612 +} 1.613 + 1.614 +#endif // !! ASSIMP_BUILD_NO_Q3D_IMPORTER