vrshoot
diff libs/assimp/ObjFileImporter.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/ObjFileImporter.cpp Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,620 @@ 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 +#include "AssimpPCH.h" 1.46 +#ifndef ASSIMP_BUILD_NO_OBJ_IMPORTER 1.47 + 1.48 +#include "DefaultIOSystem.h" 1.49 +#include "ObjFileImporter.h" 1.50 +#include "ObjFileParser.h" 1.51 +#include "ObjFileData.h" 1.52 + 1.53 +static const aiImporterDesc desc = { 1.54 + "Wavefront Object Importer", 1.55 + "", 1.56 + "", 1.57 + "surfaces not supported", 1.58 + aiImporterFlags_SupportTextFlavour, 1.59 + 0, 1.60 + 0, 1.61 + 0, 1.62 + 0, 1.63 + "obj" 1.64 +}; 1.65 + 1.66 + 1.67 +namespace Assimp { 1.68 + 1.69 +using namespace std; 1.70 + 1.71 +// ------------------------------------------------------------------------------------------------ 1.72 +// Default constructor 1.73 +ObjFileImporter::ObjFileImporter() : 1.74 + m_Buffer(), 1.75 + m_pRootObject( NULL ), 1.76 + m_strAbsPath( "" ) 1.77 +{ 1.78 + DefaultIOSystem io; 1.79 + m_strAbsPath = io.getOsSeparator(); 1.80 +} 1.81 + 1.82 +// ------------------------------------------------------------------------------------------------ 1.83 +// Destructor. 1.84 +ObjFileImporter::~ObjFileImporter() 1.85 +{ 1.86 + // Release root object instance 1.87 + if (NULL != m_pRootObject) 1.88 + { 1.89 + delete m_pRootObject; 1.90 + m_pRootObject = NULL; 1.91 + } 1.92 +} 1.93 + 1.94 +// ------------------------------------------------------------------------------------------------ 1.95 +// Returns true, if file is an obj file. 1.96 +bool ObjFileImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler , bool checkSig ) const 1.97 +{ 1.98 + if(!checkSig) //Check File Extension 1.99 + { 1.100 + return SimpleExtensionCheck(pFile,"obj"); 1.101 + } 1.102 + else //Check file Header 1.103 + { 1.104 + static const char *pTokens[] = { "mtllib", "usemtl", "v ", "vt ", "vn ", "o ", "g ", "s ", "f " }; 1.105 + return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 9 ); 1.106 + } 1.107 +} 1.108 + 1.109 +// ------------------------------------------------------------------------------------------------ 1.110 +const aiImporterDesc* ObjFileImporter::GetInfo () const 1.111 +{ 1.112 + return &desc; 1.113 +} 1.114 + 1.115 +// ------------------------------------------------------------------------------------------------ 1.116 +// Obj-file import implementation 1.117 +void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) 1.118 +{ 1.119 + DefaultIOSystem io; 1.120 + 1.121 + // Read file into memory 1.122 + const std::string mode = "rb"; 1.123 + boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, mode)); 1.124 + if (NULL == file.get()) 1.125 + throw DeadlyImportError( "Failed to open file " + pFile + "."); 1.126 + 1.127 + // Get the file-size and validate it, throwing an exception when fails 1.128 + size_t fileSize = file->FileSize(); 1.129 + if( fileSize < 16) 1.130 + throw DeadlyImportError( "OBJ-file is too small."); 1.131 + 1.132 + // Allocate buffer and read file into it 1.133 + TextFileToBuffer(file.get(),m_Buffer); 1.134 + 1.135 + // Get the model name 1.136 + std::string strModelName; 1.137 + std::string::size_type pos = pFile.find_last_of( "\\/" ); 1.138 + if ( pos != std::string::npos ) 1.139 + { 1.140 + strModelName = pFile.substr(pos+1, pFile.size() - pos - 1); 1.141 + } 1.142 + else 1.143 + { 1.144 + strModelName = pFile; 1.145 + } 1.146 + 1.147 + // parse the file into a temporary representation 1.148 + ObjFileParser parser(m_Buffer, strModelName, pIOHandler); 1.149 + 1.150 + // And create the proper return structures out of it 1.151 + CreateDataFromImport(parser.GetModel(), pScene); 1.152 + 1.153 + // Clean up allocated storage for the next import 1.154 + m_Buffer.clear(); 1.155 +} 1.156 + 1.157 +// ------------------------------------------------------------------------------------------------ 1.158 +// Create the data from parsed obj-file 1.159 +void ObjFileImporter::CreateDataFromImport(const ObjFile::Model* pModel, aiScene* pScene) 1.160 +{ 1.161 + if (0L == pModel) 1.162 + return; 1.163 + 1.164 + // Create the root node of the scene 1.165 + pScene->mRootNode = new aiNode; 1.166 + if ( !pModel->m_ModelName.empty() ) 1.167 + { 1.168 + // Set the name of the scene 1.169 + pScene->mRootNode->mName.Set(pModel->m_ModelName); 1.170 + } 1.171 + else 1.172 + { 1.173 + // This is an error, so break down the application 1.174 + ai_assert(false); 1.175 + } 1.176 + 1.177 + // Create nodes for the whole scene 1.178 + std::vector<aiMesh*> MeshArray; 1.179 + for (size_t index = 0; index < pModel->m_Objects.size(); index++) 1.180 + { 1.181 + createNodes(pModel, pModel->m_Objects[ index ], index, pScene->mRootNode, pScene, MeshArray); 1.182 + } 1.183 + 1.184 + // Create mesh pointer buffer for this scene 1.185 + if (pScene->mNumMeshes > 0) 1.186 + { 1.187 + pScene->mMeshes = new aiMesh*[ MeshArray.size() ]; 1.188 + for (size_t index =0; index < MeshArray.size(); index++) 1.189 + { 1.190 + pScene->mMeshes [ index ] = MeshArray[ index ]; 1.191 + } 1.192 + } 1.193 + 1.194 + // Create all materials 1.195 + createMaterials( pModel, pScene ); 1.196 +} 1.197 + 1.198 +// ------------------------------------------------------------------------------------------------ 1.199 +// Creates all nodes of the model 1.200 +aiNode *ObjFileImporter::createNodes(const ObjFile::Model* pModel, const ObjFile::Object* pObject, 1.201 + unsigned int /*uiMeshIndex*/, 1.202 + aiNode *pParent, aiScene* pScene, 1.203 + std::vector<aiMesh*> &MeshArray ) 1.204 +{ 1.205 + ai_assert( NULL != pModel ); 1.206 + if ( NULL == pObject ) 1.207 + return NULL; 1.208 + 1.209 + // Store older mesh size to be able to computes mesh offsets for new mesh instances 1.210 + const size_t oldMeshSize = MeshArray.size(); 1.211 + aiNode *pNode = new aiNode; 1.212 + 1.213 + pNode->mName = pObject->m_strObjName; 1.214 + 1.215 + // If we have a parent node, store it 1.216 + if (pParent != NULL) 1.217 + appendChildToParentNode(pParent, pNode); 1.218 + 1.219 + for ( unsigned int i=0; i< pObject->m_Meshes.size(); i++ ) 1.220 + { 1.221 + unsigned int meshId = pObject->m_Meshes[ i ]; 1.222 + aiMesh *pMesh = new aiMesh; 1.223 + createTopology( pModel, pObject, meshId, pMesh ); 1.224 + if ( pMesh->mNumVertices > 0 ) 1.225 + { 1.226 + MeshArray.push_back( pMesh ); 1.227 + } 1.228 + else 1.229 + { 1.230 + delete pMesh; 1.231 + } 1.232 + } 1.233 + 1.234 + // Create all nodes from the sub-objects stored in the current object 1.235 + if ( !pObject->m_SubObjects.empty() ) 1.236 + { 1.237 + size_t numChilds = pObject->m_SubObjects.size(); 1.238 + pNode->mNumChildren = static_cast<unsigned int>( numChilds ); 1.239 + pNode->mChildren = new aiNode*[ numChilds ]; 1.240 + pNode->mNumMeshes = 1; 1.241 + pNode->mMeshes = new unsigned int[ 1 ]; 1.242 + } 1.243 + 1.244 + // Set mesh instances into scene- and node-instances 1.245 + const size_t meshSizeDiff = MeshArray.size()- oldMeshSize; 1.246 + if ( meshSizeDiff > 0 ) 1.247 + { 1.248 + pNode->mMeshes = new unsigned int[ meshSizeDiff ]; 1.249 + pNode->mNumMeshes = static_cast<unsigned int>( meshSizeDiff ); 1.250 + size_t index = 0; 1.251 + for (size_t i = oldMeshSize; i < MeshArray.size(); i++) 1.252 + { 1.253 + pNode->mMeshes[ index ] = pScene->mNumMeshes; 1.254 + pScene->mNumMeshes++; 1.255 + index++; 1.256 + } 1.257 + } 1.258 + 1.259 + return pNode; 1.260 +} 1.261 + 1.262 +// ------------------------------------------------------------------------------------------------ 1.263 +// Create topology data 1.264 +void ObjFileImporter::createTopology(const ObjFile::Model* pModel, 1.265 + const ObjFile::Object* pData, 1.266 + unsigned int uiMeshIndex, 1.267 + aiMesh* pMesh ) 1.268 +{ 1.269 + // Checking preconditions 1.270 + ai_assert( NULL != pModel ); 1.271 + if (NULL == pData) 1.272 + return; 1.273 + 1.274 + // Create faces 1.275 + ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ]; 1.276 + ai_assert( NULL != pObjMesh ); 1.277 + 1.278 + pMesh->mNumFaces = 0; 1.279 + for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) 1.280 + { 1.281 + ObjFile::Face* const inp = pObjMesh->m_Faces[ index ]; 1.282 + if (inp->m_PrimitiveType == aiPrimitiveType_LINE) { 1.283 + pMesh->mNumFaces += inp->m_pVertices->size() - 1; 1.284 + } 1.285 + else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) { 1.286 + pMesh->mNumFaces += inp->m_pVertices->size(); 1.287 + } 1.288 + else { 1.289 + ++pMesh->mNumFaces; 1.290 + } 1.291 + } 1.292 + 1.293 + unsigned int uiIdxCount = 0u; 1.294 + if ( pMesh->mNumFaces > 0 ) 1.295 + { 1.296 + pMesh->mFaces = new aiFace[ pMesh->mNumFaces ]; 1.297 + if ( pObjMesh->m_uiMaterialIndex != ObjFile::Mesh::NoMaterial ) 1.298 + { 1.299 + pMesh->mMaterialIndex = pObjMesh->m_uiMaterialIndex; 1.300 + } 1.301 + 1.302 + unsigned int outIndex = 0; 1.303 + 1.304 + // Copy all data from all stored meshes 1.305 + for (size_t index = 0; index < pObjMesh->m_Faces.size(); index++) 1.306 + { 1.307 + ObjFile::Face* const inp = pObjMesh->m_Faces[ index ]; 1.308 + if (inp->m_PrimitiveType == aiPrimitiveType_LINE) { 1.309 + for(size_t i = 0; i < inp->m_pVertices->size() - 1; ++i) { 1.310 + aiFace& f = pMesh->mFaces[ outIndex++ ]; 1.311 + uiIdxCount += f.mNumIndices = 2; 1.312 + f.mIndices = new unsigned int[2]; 1.313 + } 1.314 + continue; 1.315 + } 1.316 + else if (inp->m_PrimitiveType == aiPrimitiveType_POINT) { 1.317 + for(size_t i = 0; i < inp->m_pVertices->size(); ++i) { 1.318 + aiFace& f = pMesh->mFaces[ outIndex++ ]; 1.319 + uiIdxCount += f.mNumIndices = 1; 1.320 + f.mIndices = new unsigned int[1]; 1.321 + } 1.322 + continue; 1.323 + } 1.324 + 1.325 + aiFace *pFace = &pMesh->mFaces[ outIndex++ ]; 1.326 + const unsigned int uiNumIndices = (unsigned int) pObjMesh->m_Faces[ index ]->m_pVertices->size(); 1.327 + uiIdxCount += pFace->mNumIndices = (unsigned int) uiNumIndices; 1.328 + if (pFace->mNumIndices > 0) { 1.329 + pFace->mIndices = new unsigned int[ uiNumIndices ]; 1.330 + } 1.331 + } 1.332 + } 1.333 + 1.334 + // Create mesh vertices 1.335 + createVertexArray(pModel, pData, uiMeshIndex, pMesh, uiIdxCount); 1.336 +} 1.337 + 1.338 +// ------------------------------------------------------------------------------------------------ 1.339 +// Creates a vertex array 1.340 +void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel, 1.341 + const ObjFile::Object* pCurrentObject, 1.342 + unsigned int uiMeshIndex, 1.343 + aiMesh* pMesh, 1.344 + unsigned int uiIdxCount) 1.345 +{ 1.346 + // Checking preconditions 1.347 + ai_assert( NULL != pCurrentObject ); 1.348 + 1.349 + // Break, if no faces are stored in object 1.350 + if ( pCurrentObject->m_Meshes.empty() ) 1.351 + return; 1.352 + 1.353 + // Get current mesh 1.354 + ObjFile::Mesh *pObjMesh = pModel->m_Meshes[ uiMeshIndex ]; 1.355 + if ( NULL == pObjMesh || pObjMesh->m_uiNumIndices < 1) 1.356 + return; 1.357 + 1.358 + // Copy vertices of this mesh instance 1.359 + pMesh->mNumVertices = uiIdxCount; 1.360 + pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ]; 1.361 + 1.362 + // Allocate buffer for normal vectors 1.363 + if ( !pModel->m_Normals.empty() && pObjMesh->m_hasNormals ) 1.364 + pMesh->mNormals = new aiVector3D[ pMesh->mNumVertices ]; 1.365 + 1.366 + // Allocate buffer for texture coordinates 1.367 + if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] ) 1.368 + { 1.369 + pMesh->mNumUVComponents[ 0 ] = 2; 1.370 + pMesh->mTextureCoords[ 0 ] = new aiVector3D[ pMesh->mNumVertices ]; 1.371 + } 1.372 + 1.373 + // Copy vertices, normals and textures into aiMesh instance 1.374 + unsigned int newIndex = 0, outIndex = 0; 1.375 + for ( size_t index=0; index < pObjMesh->m_Faces.size(); index++ ) 1.376 + { 1.377 + // Get source face 1.378 + ObjFile::Face *pSourceFace = pObjMesh->m_Faces[ index ]; 1.379 + 1.380 + // Copy all index arrays 1.381 + for ( size_t vertexIndex = 0, outVertexIndex = 0; vertexIndex < pSourceFace->m_pVertices->size(); vertexIndex++ ) 1.382 + { 1.383 + const unsigned int vertex = pSourceFace->m_pVertices->at( vertexIndex ); 1.384 + if ( vertex >= pModel->m_Vertices.size() ) 1.385 + throw DeadlyImportError( "OBJ: vertex index out of range" ); 1.386 + 1.387 + pMesh->mVertices[ newIndex ] = pModel->m_Vertices[ vertex ]; 1.388 + 1.389 + // Copy all normals 1.390 + if ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty()) 1.391 + { 1.392 + const unsigned int normal = pSourceFace->m_pNormals->at( vertexIndex ); 1.393 + if ( normal >= pModel->m_Normals.size() ) 1.394 + throw DeadlyImportError("OBJ: vertex normal index out of range"); 1.395 + 1.396 + pMesh->mNormals[ newIndex ] = pModel->m_Normals[ normal ]; 1.397 + } 1.398 + 1.399 + // Copy all texture coordinates 1.400 + if ( !pModel->m_TextureCoord.empty() ) 1.401 + { 1.402 + if ( !pSourceFace->m_pTexturCoords->empty() ) 1.403 + { 1.404 + const unsigned int tex = pSourceFace->m_pTexturCoords->at( vertexIndex ); 1.405 + ai_assert( tex < pModel->m_TextureCoord.size() ); 1.406 + for ( size_t i=0; i < pMesh->GetNumUVChannels(); i++ ) 1.407 + { 1.408 + if ( tex >= pModel->m_TextureCoord.size() ) 1.409 + throw DeadlyImportError("OBJ: texture coord index out of range"); 1.410 + 1.411 + aiVector2D coord2d = pModel->m_TextureCoord[ tex ]; 1.412 + pMesh->mTextureCoords[ i ][ newIndex ] = aiVector3D( coord2d.x, coord2d.y, 0.0 ); 1.413 + } 1.414 + } 1.415 + } 1.416 + 1.417 + ai_assert( pMesh->mNumVertices > newIndex ); 1.418 + 1.419 + // Get destination face 1.420 + aiFace *pDestFace = &pMesh->mFaces[ outIndex ]; 1.421 + 1.422 + const bool last = ( vertexIndex == pSourceFace->m_pVertices->size() - 1 ); 1.423 + if (pSourceFace->m_PrimitiveType != aiPrimitiveType_LINE || !last) 1.424 + { 1.425 + pDestFace->mIndices[ outVertexIndex ] = newIndex; 1.426 + outVertexIndex++; 1.427 + } 1.428 + 1.429 + if (pSourceFace->m_PrimitiveType == aiPrimitiveType_POINT) 1.430 + { 1.431 + outIndex++; 1.432 + outVertexIndex = 0; 1.433 + } 1.434 + else if (pSourceFace->m_PrimitiveType == aiPrimitiveType_LINE) 1.435 + { 1.436 + outVertexIndex = 0; 1.437 + 1.438 + if(!last) 1.439 + outIndex++; 1.440 + 1.441 + if (vertexIndex) { 1.442 + if(!last) { 1.443 + pMesh->mVertices[ newIndex+1 ] = pMesh->mVertices[ newIndex ]; 1.444 + if ( !pSourceFace->m_pNormals->empty() && !pModel->m_Normals.empty()) { 1.445 + pMesh->mNormals[ newIndex+1 ] = pMesh->mNormals[newIndex ]; 1.446 + } 1.447 + if ( !pModel->m_TextureCoord.empty() ) { 1.448 + for ( size_t i=0; i < pMesh->GetNumUVChannels(); i++ ) { 1.449 + pMesh->mTextureCoords[ i ][ newIndex+1 ] = pMesh->mTextureCoords[ i ][ newIndex ]; 1.450 + } 1.451 + } 1.452 + ++newIndex; 1.453 + } 1.454 + 1.455 + pDestFace[-1].mIndices[1] = newIndex; 1.456 + } 1.457 + } 1.458 + else if (last) { 1.459 + outIndex++; 1.460 + } 1.461 + ++newIndex; 1.462 + } 1.463 + } 1.464 +} 1.465 + 1.466 +// ------------------------------------------------------------------------------------------------ 1.467 +// Counts all stored meshes 1.468 +void ObjFileImporter::countObjects(const std::vector<ObjFile::Object*> &rObjects, int &iNumMeshes) 1.469 +{ 1.470 + iNumMeshes = 0; 1.471 + if ( rObjects.empty() ) 1.472 + return; 1.473 + 1.474 + iNumMeshes += static_cast<unsigned int>( rObjects.size() ); 1.475 + for (std::vector<ObjFile::Object*>::const_iterator it = rObjects.begin(); 1.476 + it != rObjects.end(); 1.477 + ++it) 1.478 + { 1.479 + if (!(*it)->m_SubObjects.empty()) 1.480 + { 1.481 + countObjects((*it)->m_SubObjects, iNumMeshes); 1.482 + } 1.483 + } 1.484 +} 1.485 + 1.486 +// ------------------------------------------------------------------------------------------------ 1.487 +// Creates the material 1.488 +void ObjFileImporter::createMaterials(const ObjFile::Model* pModel, aiScene* pScene ) 1.489 +{ 1.490 + ai_assert( NULL != pScene ); 1.491 + if ( NULL == pScene ) 1.492 + return; 1.493 + 1.494 + const unsigned int numMaterials = (unsigned int) pModel->m_MaterialLib.size(); 1.495 + pScene->mNumMaterials = 0; 1.496 + if ( pModel->m_MaterialLib.empty() ) { 1.497 + DefaultLogger::get()->debug("OBJ: no materials specified"); 1.498 + return; 1.499 + } 1.500 + 1.501 + pScene->mMaterials = new aiMaterial*[ numMaterials ]; 1.502 + for ( unsigned int matIndex = 0; matIndex < numMaterials; matIndex++ ) 1.503 + { 1.504 + // Store material name 1.505 + std::map<std::string, ObjFile::Material*>::const_iterator it; 1.506 + it = pModel->m_MaterialMap.find( pModel->m_MaterialLib[ matIndex ] ); 1.507 + 1.508 + // No material found, use the default material 1.509 + if ( pModel->m_MaterialMap.end() == it ) 1.510 + continue; 1.511 + 1.512 + aiMaterial* mat = new aiMaterial; 1.513 + ObjFile::Material *pCurrentMaterial = (*it).second; 1.514 + mat->AddProperty( &pCurrentMaterial->MaterialName, AI_MATKEY_NAME ); 1.515 + 1.516 + // convert illumination model 1.517 + int sm = 0; 1.518 + switch (pCurrentMaterial->illumination_model) 1.519 + { 1.520 + case 0: 1.521 + sm = aiShadingMode_NoShading; 1.522 + break; 1.523 + case 1: 1.524 + sm = aiShadingMode_Gouraud; 1.525 + break; 1.526 + case 2: 1.527 + sm = aiShadingMode_Phong; 1.528 + break; 1.529 + default: 1.530 + sm = aiShadingMode_Gouraud; 1.531 + DefaultLogger::get()->error("OBJ: unexpected illumination model (0-2 recognized)"); 1.532 + } 1.533 + 1.534 + mat->AddProperty<int>( &sm, 1, AI_MATKEY_SHADING_MODEL); 1.535 + 1.536 + // multiplying the specular exponent with 2 seems to yield better results 1.537 + pCurrentMaterial->shineness *= 4.f; 1.538 + 1.539 + // Adding material colors 1.540 + mat->AddProperty( &pCurrentMaterial->ambient, 1, AI_MATKEY_COLOR_AMBIENT ); 1.541 + mat->AddProperty( &pCurrentMaterial->diffuse, 1, AI_MATKEY_COLOR_DIFFUSE ); 1.542 + mat->AddProperty( &pCurrentMaterial->specular, 1, AI_MATKEY_COLOR_SPECULAR ); 1.543 + mat->AddProperty( &pCurrentMaterial->shineness, 1, AI_MATKEY_SHININESS ); 1.544 + mat->AddProperty( &pCurrentMaterial->alpha, 1, AI_MATKEY_OPACITY ); 1.545 + 1.546 + // Adding refraction index 1.547 + mat->AddProperty( &pCurrentMaterial->ior, 1, AI_MATKEY_REFRACTI ); 1.548 + 1.549 + // Adding textures 1.550 + if ( 0 != pCurrentMaterial->texture.length ) 1.551 + mat->AddProperty( &pCurrentMaterial->texture, AI_MATKEY_TEXTURE_DIFFUSE(0)); 1.552 + 1.553 + if ( 0 != pCurrentMaterial->textureAmbient.length ) 1.554 + mat->AddProperty( &pCurrentMaterial->textureAmbient, AI_MATKEY_TEXTURE_AMBIENT(0)); 1.555 + 1.556 + if ( 0 != pCurrentMaterial->textureSpecular.length ) 1.557 + mat->AddProperty( &pCurrentMaterial->textureSpecular, AI_MATKEY_TEXTURE_SPECULAR(0)); 1.558 + 1.559 + if ( 0 != pCurrentMaterial->textureBump.length ) 1.560 + mat->AddProperty( &pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0)); 1.561 + 1.562 + if ( 0 != pCurrentMaterial->textureNormal.length ) 1.563 + mat->AddProperty( &pCurrentMaterial->textureNormal, AI_MATKEY_TEXTURE_NORMALS(0)); 1.564 + 1.565 + if ( 0 != pCurrentMaterial->textureDisp.length ) 1.566 + mat->AddProperty( &pCurrentMaterial->textureDisp, AI_MATKEY_TEXTURE_DISPLACEMENT(0) ); 1.567 + 1.568 + if ( 0 != pCurrentMaterial->textureOpacity.length ) 1.569 + mat->AddProperty( &pCurrentMaterial->textureOpacity, AI_MATKEY_TEXTURE_OPACITY(0)); 1.570 + 1.571 + if ( 0 != pCurrentMaterial->textureSpecularity.length ) 1.572 + mat->AddProperty( &pCurrentMaterial->textureSpecularity, AI_MATKEY_TEXTURE_SHININESS(0)); 1.573 + 1.574 + // Store material property info in material array in scene 1.575 + pScene->mMaterials[ pScene->mNumMaterials ] = mat; 1.576 + pScene->mNumMaterials++; 1.577 + } 1.578 + 1.579 + // Test number of created materials. 1.580 + ai_assert( pScene->mNumMaterials == numMaterials ); 1.581 +} 1.582 + 1.583 +// ------------------------------------------------------------------------------------------------ 1.584 +// Appends this node to the parent node 1.585 +void ObjFileImporter::appendChildToParentNode(aiNode *pParent, aiNode *pChild) 1.586 +{ 1.587 + // Checking preconditions 1.588 + ai_assert( NULL != pParent ); 1.589 + ai_assert( NULL != pChild ); 1.590 + 1.591 + // Assign parent to child 1.592 + pChild->mParent = pParent; 1.593 + size_t sNumChildren = 0; 1.594 + (void)sNumChildren; // remove warning on release build 1.595 + 1.596 + // If already children was assigned to the parent node, store them in a 1.597 + std::vector<aiNode*> temp; 1.598 + if (pParent->mChildren != NULL) 1.599 + { 1.600 + sNumChildren = pParent->mNumChildren; 1.601 + ai_assert( 0 != sNumChildren ); 1.602 + for (size_t index = 0; index < pParent->mNumChildren; index++) 1.603 + { 1.604 + temp.push_back(pParent->mChildren [ index ] ); 1.605 + } 1.606 + delete [] pParent->mChildren; 1.607 + } 1.608 + 1.609 + // Copy node instances into parent node 1.610 + pParent->mNumChildren++; 1.611 + pParent->mChildren = new aiNode*[ pParent->mNumChildren ]; 1.612 + for (size_t index = 0; index < pParent->mNumChildren-1; index++) 1.613 + { 1.614 + pParent->mChildren[ index ] = temp [ index ]; 1.615 + } 1.616 + pParent->mChildren[ pParent->mNumChildren-1 ] = pChild; 1.617 +} 1.618 + 1.619 +// ------------------------------------------------------------------------------------------------ 1.620 + 1.621 +} // Namespace Assimp 1.622 + 1.623 +#endif // !! ASSIMP_BUILD_NO_OBJ_IMPORTER