1 /* 2 Copyright (c) 2008-2009 NetAllied Systems GmbH 3 4 This file is part of COLLADAMax. 5 6 Portions of the code are: 7 Copyright (c) 2005-2007 Feeling Software Inc. 8 Copyright (c) 2005-2007 Sony Computer Entertainment America 9 10 Based on the 3dsMax COLLADASW Tools: 11 Copyright (c) 2005-2006 Autodesk Media Entertainment 12 13 Licensed under the MIT Open Source License, 14 for details please see LICENSE file or the website 15 http://www.opensource.org/licenses/mit-license.php 16 */ 17 18 #include "COLLADAMaxStableHeaders.h" 19 #include "COLLADAMaxGeometryImporter.h" 20 21 #include "COLLADAFWTypes.h" 22 #include "COLLADAFWGeometry.h" 23 #include "COLLADAFWMesh.h" 24 #include "COLLADAFWTriangles.h" 25 #include "COLLADAFWTristrips.h" 26 #include "COLLADAFWTrifans.h" 27 #include "COLLADAFWPolygons.h" 28 #include "COLLADAFWPolylist.h" 29 #include "COLLADAFWUniqueId.h" 30 31 32 namespace COLLADAMax 33 { 34 35 isSupportedMeshPrimitive(const COLLADAFW::MeshPrimitive * meshPrimitive)36 bool isSupportedMeshPrimitive(const COLLADAFW::MeshPrimitive* meshPrimitive) 37 { 38 COLLADAFW::MeshPrimitive::PrimitiveType type = meshPrimitive->getPrimitiveType(); 39 return (type == COLLADAFW::MeshPrimitive::TRIANGLES) 40 || (type == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) 41 || (type == COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS) 42 || (type == COLLADAFW::MeshPrimitive::POLYGONS) 43 || (type == COLLADAFW::MeshPrimitive::POLYLIST); 44 } 45 GeometryImporter(DocumentImporter * documentImporter,const COLLADAFW::Geometry * geometry)46 GeometryImporter::GeometryImporter( DocumentImporter* documentImporter, const COLLADAFW::Geometry* geometry ) 47 : ImporterBase(documentImporter) 48 , mGeometry(geometry) 49 , mTotalTrianglesCount(0) 50 , mLargestMapChannel(0) 51 , mHasVertexColor(false) 52 { 53 54 } 55 56 //------------------------------ ~GeometryImporter()57 GeometryImporter::~GeometryImporter() 58 { 59 } 60 61 //------------------------------ import()62 bool GeometryImporter::import() 63 { 64 if ( mGeometry->getType() == COLLADAFW::Geometry::GEO_TYPE_MESH ) 65 { 66 importMesh(); 67 } 68 return true; 69 } 70 71 //------------------------------ importMesh()72 bool GeometryImporter::importMesh( ) 73 { 74 COLLADAFW::Mesh* mesh = (COLLADAFW::Mesh*) mGeometry; 75 76 bool success = true; 77 mTotalTrianglesCount = mesh->getTrianglesTriangleCount() + mesh->getTristripsTriangleCount() + mesh->getTrifansTriangleCount(); 78 79 if ( mesh->getPolygonsPolygonCount() > 0 || mesh->getPolylistPolygonCount() > 0 ) 80 { 81 success = importPolygonMesh(); 82 } 83 else if ( mTotalTrianglesCount > 0 ) 84 { 85 success = importTriangleMesh(); 86 } 87 88 if ( mHasVertexColor && success) 89 { 90 addVertexColorObjects( mGeometry->getUniqueId() ); 91 } 92 93 94 return success; 95 } 96 97 //------------------------------ importTriangleMesh()98 bool GeometryImporter::importTriangleMesh( ) 99 { 100 101 COLLADAFW::Mesh* mesh = (COLLADAFW::Mesh*) mGeometry; 102 103 TriObject* triangleObject = CreateNewTriObject(); 104 105 Mesh& triangleMesh = triangleObject->GetMesh(); 106 107 108 if ( !importTriangleMeshPositions(triangleObject) ) 109 return false; 110 111 if ( !importTriangleMeshNormals(triangleObject) ) 112 return false; 113 114 if ( !importTriangleMeshUVCoords(triangleObject) ) 115 return false; 116 117 triangleMesh.InvalidateGeomCache(); 118 triangleMesh.InvalidateTopologyCache(); 119 120 handleObjectReferences(mesh, triangleObject); 121 122 return true; 123 } 124 125 126 //------------------------------ importTriangleMeshPositions(TriObject * triangleObject)127 bool GeometryImporter::importTriangleMeshPositions( TriObject* triangleObject ) 128 { 129 COLLADAFW::Mesh* mesh = (COLLADAFW::Mesh*) mGeometry; 130 131 Mesh& triangleMesh = triangleObject->GetMesh(); 132 133 const COLLADAFW::MeshVertexData& meshPositions = mesh->getPositions(); 134 135 int positionsCount = (int)meshPositions.getValuesCount() / 3; 136 137 triangleMesh.setNumVerts(positionsCount); 138 139 if ( meshPositions.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE ) 140 { 141 const COLLADAFW::DoubleArray* positionsArray = meshPositions.getDoubleValues(); 142 for ( int i = 0; i < positionsCount; ++i) 143 { 144 triangleMesh.setVert(i, convertSpaceUnit((float)(*positionsArray)[3*i]), 145 convertSpaceUnit((float)(*positionsArray)[3*i + 1]), 146 convertSpaceUnit((float)(*positionsArray)[3*i + 2])); 147 } 148 } 149 else 150 { 151 const COLLADAFW::FloatArray* positionsArray = meshPositions.getFloatValues(); 152 for ( int i = 0; i < positionsCount; ++i) 153 { 154 triangleMesh.setVert(i, convertSpaceUnit((*positionsArray)[3*i]), 155 convertSpaceUnit((*positionsArray)[3*i + 1]), 156 convertSpaceUnit((*positionsArray)[3*i + 2])); 157 } 158 } 159 160 triangleMesh.setNumFaces((int)mTotalTrianglesCount); 161 COLLADAFW::MeshPrimitiveArray& meshPrimitiveArray = mesh->getMeshPrimitives(); 162 size_t faceIndex = 0; 163 DocumentImporter::FWMaterialIdMaxMtlIdMap& fWMaterialIdMaxMtlIdMap = getMaterialIdMapByGeometryUniqueId(mGeometry->getUniqueId()); 164 createFWMaterialIdMaxMtlIdMap( meshPrimitiveArray, fWMaterialIdMaxMtlIdMap); 165 for ( size_t i = 0, count = meshPrimitiveArray.getCount(); i < count; ++i) 166 { 167 const COLLADAFW::MeshPrimitive* meshPrimitive = meshPrimitiveArray[i]; 168 if ( ! meshPrimitive ) 169 continue; 170 // We use the frame work material id as max material id 171 MtlID maxMaterialId = (MtlID)meshPrimitive->getMaterialId(); 172 switch (meshPrimitive->getPrimitiveType()) 173 { 174 case COLLADAFW::MeshPrimitive::TRIANGLES: 175 { 176 const COLLADAFW::Triangles* triangles = (const COLLADAFW::Triangles*) meshPrimitive; 177 const COLLADAFW::UIntValuesArray& positionIndices = triangles->getPositionIndices(); 178 for ( size_t j = 0, count = positionIndices.getCount() ; j < count; j+=3 ) 179 { 180 Face& face = triangleMesh.faces[faceIndex]; 181 // face.setMatID(fWMaterialIdMaxMtlIdMap[meshPrimitive->getMaterialId()]); 182 if ( maxMaterialId != 0 ) 183 face.setMatID(maxMaterialId); 184 face.setEdgeVisFlags(1, 1, 1); 185 face.setVerts(positionIndices[j], positionIndices[j + 1], positionIndices[j + 2]); 186 ++faceIndex; 187 } 188 break; 189 } 190 case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: 191 { 192 const COLLADAFW::Tristrips* tristrips = (const COLLADAFW::Tristrips*) meshPrimitive; 193 const COLLADAFW::UIntValuesArray& positionIndices = tristrips->getPositionIndices(); 194 const COLLADAFW::UIntValuesArray& faceVertexCountArray = tristrips->getGroupedVerticesVertexCountArray(); 195 size_t nextTristripStartIndex = 0; 196 for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k) 197 { 198 unsigned int faceVertexCount = faceVertexCountArray[k]; 199 bool switchOrientation = false; 200 for ( size_t j = nextTristripStartIndex + 2, lastVertex = nextTristripStartIndex + faceVertexCount; j < lastVertex; ++j ) 201 { 202 Face& face = triangleMesh.faces[faceIndex]; 203 // face.setMatID(fWMaterialIdMaxMtlIdMap[meshPrimitive->getMaterialId()]); 204 face.setEdgeVisFlags(1, 1, 1); 205 if ( maxMaterialId != 0 ) 206 face.setMatID(maxMaterialId); 207 if ( switchOrientation ) 208 { 209 face.setVerts(positionIndices[j - 1], positionIndices[j - 2], positionIndices[j]); 210 switchOrientation = false; 211 } 212 else 213 { 214 face.setVerts(positionIndices[j - 2], positionIndices[j - 1], positionIndices[j]); 215 switchOrientation = true; 216 } 217 ++faceIndex; 218 } 219 nextTristripStartIndex += faceVertexCount; 220 } 221 break; 222 } 223 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: 224 { 225 const COLLADAFW::Trifans* trifans = (const COLLADAFW::Trifans*) meshPrimitive; 226 const COLLADAFW::UIntValuesArray& positionIndices = trifans->getPositionIndices(); 227 const COLLADAFW::UIntValuesArray& faceVertexCountArray = trifans->getGroupedVerticesVertexCountArray(); 228 size_t nextTrifanStartIndex = 0; 229 for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k) 230 { 231 unsigned int faceVertexCount = faceVertexCountArray[k]; 232 unsigned int commonVertexIndex = positionIndices[nextTrifanStartIndex]; 233 for ( size_t j = nextTrifanStartIndex + 2, lastVertex = nextTrifanStartIndex + faceVertexCount; j < lastVertex; ++j ) 234 { 235 Face& face = triangleMesh.faces[faceIndex]; 236 // face.setMatID(fWMaterialIdMaxMtlIdMap[meshPrimitive->getMaterialId()]); 237 if ( maxMaterialId != 0 ) 238 face.setMatID(maxMaterialId); 239 face.setEdgeVisFlags(1, 1, 1); 240 face.setVerts(commonVertexIndex, positionIndices[j - 1], positionIndices[j]); 241 ++faceIndex; 242 } 243 nextTrifanStartIndex += faceVertexCount; 244 } 245 break; 246 } 247 default: 248 continue; 249 } 250 251 252 } 253 return true; 254 } 255 256 //------------------------------ importTriangleMeshNormals(TriObject * triangleObject)257 bool GeometryImporter::importTriangleMeshNormals( TriObject* triangleObject ) 258 { 259 COLLADAFW::Mesh* mesh = (COLLADAFW::Mesh*) mGeometry; 260 261 if ( !mesh->hasNormals() ) 262 return true; 263 264 Mesh& triangleMesh = triangleObject->GetMesh(); 265 266 triangleMesh.SpecifyNormals(); 267 MeshNormalSpec* normalsSpecifier = triangleMesh.GetSpecifiedNormals(); 268 269 normalsSpecifier->ClearNormals(); 270 size_t numFaces = triangleMesh.getNumFaces(); 271 normalsSpecifier->SetNumFaces((int)numFaces); 272 273 // fill in the normals 274 const COLLADAFW::MeshVertexData& meshNormals = mesh->getNormals(); 275 int normalCount = (int)meshNormals.getValuesCount()/3; 276 277 normalsSpecifier->SetNumNormals(normalCount); 278 279 if ( meshNormals.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE ) 280 { 281 const COLLADAFW::DoubleArray* normalsArray = meshNormals.getDoubleValues(); 282 for ( int i = 0; i < normalCount; ++i) 283 { 284 Point3 normal((*normalsArray)[i*3], (*normalsArray)[i*3 + 1], (*normalsArray)[i*3 + 2]); 285 normalsSpecifier->Normal(i) = normal.Normalize(); 286 normalsSpecifier->SetNormalExplicit(i, true); 287 } 288 } 289 else 290 { 291 const COLLADAFW::FloatArray* normalsArray = meshNormals.getFloatValues(); 292 for ( int i = 0; i < normalCount; ++i) 293 { 294 Point3 normal((*normalsArray)[i*3], (*normalsArray)[i*3 + 1], (*normalsArray)[i*3 + 2]); 295 normalsSpecifier->Normal(i) = normal.Normalize(); 296 normalsSpecifier->SetNormalExplicit(i, true); 297 } 298 } 299 300 //assign normals to faces (triangles) 301 const COLLADAFW::MeshPrimitiveArray& meshPrimitives = mesh->getMeshPrimitives(); 302 size_t faceIndex = 0; 303 for ( size_t i = 0, count = meshPrimitives.getCount(); i < count; ++i ) 304 { 305 const COLLADAFW::MeshPrimitive* meshPrimitive = meshPrimitives[i]; 306 size_t trianglesCount = meshPrimitive->getFaceCount(); 307 308 const COLLADAFW::UIntValuesArray& normalIndices = meshPrimitive->getNormalIndices(); 309 if (isSupportedMeshPrimitive(meshPrimitive)) 310 { 311 if ( skipMeshData( meshPrimitive, normalIndices, faceIndex ) ) 312 { 313 continue; 314 } 315 } 316 else 317 { 318 continue; 319 } 320 321 switch (meshPrimitive->getPrimitiveType()) 322 { 323 case COLLADAFW::MeshPrimitive::TRIANGLES: 324 { 325 for ( size_t j = 0; j < trianglesCount; ++j) 326 { 327 MeshNormalFace& normalFace = normalsSpecifier->Face((int) faceIndex); 328 normalFace.SpecifyAll(); 329 normalFace.SetNormalID(0, normalIndices[3*j]); 330 normalFace.SetNormalID(1, normalIndices[3*j + 1]); 331 normalFace.SetNormalID(2, normalIndices[3*j + 2]); 332 ++faceIndex; 333 } 334 break; 335 } 336 case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: 337 { 338 const COLLADAFW::Tristrips* tristrips = (const COLLADAFW::Tristrips*) meshPrimitive; 339 assert(tristrips); 340 const COLLADAFW::UIntValuesArray& faceVertexCountArray = tristrips->getGroupedVerticesVertexCountArray(); 341 size_t nextTristripStartIndex = 0; 342 for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k) 343 { 344 unsigned int faceVertexCount = faceVertexCountArray[k]; 345 bool switchOrientation = false; 346 for ( size_t j = nextTristripStartIndex + 2, lastVertex = nextTristripStartIndex + faceVertexCount; j < lastVertex; ++j ) 347 { 348 MeshNormalFace& normalFace = normalsSpecifier->Face((int) faceIndex); 349 normalFace.SpecifyAll(); 350 if ( switchOrientation ) 351 { 352 normalFace.SetNormalID(0, normalIndices[j - 1]); 353 normalFace.SetNormalID(1, normalIndices[j - 2]); 354 normalFace.SetNormalID(2, normalIndices[j]); 355 switchOrientation = false; 356 } 357 else 358 { 359 normalFace.SetNormalID(0, normalIndices[j - 2]); 360 normalFace.SetNormalID(1, normalIndices[j - 1]); 361 normalFace.SetNormalID(2, normalIndices[j]); 362 switchOrientation = true; 363 } 364 ++faceIndex; 365 } 366 nextTristripStartIndex += faceVertexCount; 367 } 368 break; 369 } 370 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: 371 { 372 const COLLADAFW::Trifans* trifans = (const COLLADAFW::Trifans*) meshPrimitive; 373 assert(trifans); 374 const COLLADAFW::UIntValuesArray& faceVertexCountArray = trifans->getGroupedVerticesVertexCountArray(); 375 size_t nextTrifanStartIndex = 0; 376 for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k) 377 { 378 unsigned int faceVertexCount = faceVertexCountArray[k]; 379 unsigned int commonVertexIndex = normalIndices[nextTrifanStartIndex]; 380 for ( size_t j = nextTrifanStartIndex + 2, lastVertex = nextTrifanStartIndex + faceVertexCount; j < lastVertex; ++j ) 381 { 382 MeshNormalFace& normalFace = normalsSpecifier->Face((int) faceIndex); 383 normalFace.SpecifyAll(); 384 normalFace.SetNormalID(0, commonVertexIndex); 385 normalFace.SetNormalID(1, normalIndices[j - 1]); 386 normalFace.SetNormalID(2, normalIndices[j]); 387 ++faceIndex; 388 } 389 nextTrifanStartIndex += faceVertexCount; 390 } 391 break; 392 } 393 default: 394 continue; 395 } 396 } 397 398 // TODO uncomment 399 // normalsSpecifier->CheckNormals(); 400 401 return true; 402 } 403 404 //------------------------------ 405 template<class NumberArray> setTriangleMeshUVVertices(const NumberArray & uvArray,MeshMap & meshMap,size_t stride,size_t startPosition,size_t vertsCount)406 void GeometryImporter::setTriangleMeshUVVertices(const NumberArray& uvArray, MeshMap& meshMap, size_t stride, size_t startPosition, size_t vertsCount) 407 { 408 size_t uvIndex = startPosition; 409 410 switch ( stride ) 411 { 412 case 1: 413 { 414 for ( size_t i = 0; i < vertsCount; ++i) 415 { 416 UVVert& textureVertex = meshMap.tv[i]; 417 textureVertex.x = (float)uvArray[uvIndex++]; 418 } 419 break; 420 } 421 case 2: 422 { 423 for ( size_t i = 0; i < vertsCount; ++i) 424 { 425 UVVert& textureVertex = meshMap.tv[i]; 426 textureVertex.x = (float)uvArray[uvIndex++]; 427 textureVertex.y = (float)uvArray[uvIndex++]; 428 } 429 break; 430 } 431 case 3: 432 { 433 for ( size_t i = 0; i < vertsCount; ++i) 434 { 435 UVVert& textureVertex = meshMap.tv[i]; 436 float x = (float)uvArray[uvIndex++]; 437 float y = (float)uvArray[uvIndex++]; 438 float z = (float)uvArray[uvIndex++]; 439 textureVertex.Set(x, y, z); 440 } 441 break; 442 } 443 case 4: 444 { 445 for ( size_t i = 0; i < vertsCount; ++i) 446 { 447 UVVert& textureVertex = meshMap.tv[i]; 448 float x = (float)uvArray[uvIndex++]; 449 float y = (float)uvArray[uvIndex++]; 450 float z = (float)uvArray[uvIndex++]; 451 textureVertex.Set(x, y, z); 452 uvIndex++; 453 } 454 break; 455 } 456 default: 457 assert(false); 458 } 459 460 } 461 462 463 464 //------------------------------ fillTriangleMeshMapPerSet(const COLLADAFW::MeshVertexData & uvCoordinates,const COLLADAFW::MeshVertexData::InputInfosArray & inputInfos,size_t sourceIndex,MeshMap & meshMap)465 void GeometryImporter::fillTriangleMeshMapPerSet( const COLLADAFW::MeshVertexData& uvCoordinates, 466 const COLLADAFW::MeshVertexData::InputInfosArray& inputInfos, 467 size_t sourceIndex, 468 MeshMap& meshMap) 469 { 470 const COLLADAFW::MeshVertexData::InputInfos* inputInfo = inputInfos[ sourceIndex ]; 471 472 size_t stride = inputInfo->mStride; 473 size_t vertsCount = inputInfo->mLength / stride; 474 475 // calculate first index position 476 size_t startPosition = 0; 477 for ( size_t i = 0; i < sourceIndex; ++i) 478 { 479 const COLLADAFW::MeshVertexData::InputInfos* inputInfo = inputInfos[ sourceIndex ]; 480 startPosition += inputInfo->mLength; 481 } 482 483 meshMap.setNumVerts((int)vertsCount); 484 485 if ( uvCoordinates.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE ) 486 { 487 const COLLADAFW::DoubleArray& uvArray = *uvCoordinates.getDoubleValues(); 488 setTriangleMeshUVVertices(uvArray, meshMap, stride, startPosition, vertsCount); 489 } 490 else 491 { 492 const COLLADAFW::FloatArray& uvArray = *uvCoordinates.getFloatValues(); 493 setTriangleMeshUVVertices(uvArray, meshMap, stride, startPosition, vertsCount); 494 } 495 496 } 497 498 499 500 //------------------------------ setTriangleMeshUVVerticesPerPrimitiveAndChannel(const COLLADAFW::MeshPrimitive * meshPrimitive,MeshMap & meshMap,const COLLADAFW::UIntValuesArray & uvIndices,unsigned int initialIndex,size_t & currentFaceIndex)501 void GeometryImporter::setTriangleMeshUVVerticesPerPrimitiveAndChannel( const COLLADAFW::MeshPrimitive* meshPrimitive, 502 MeshMap& meshMap, 503 const COLLADAFW::UIntValuesArray& uvIndices, 504 unsigned int initialIndex, 505 size_t& currentFaceIndex) 506 { 507 switch (meshPrimitive->getPrimitiveType()) 508 { 509 case COLLADAFW::MeshPrimitive::TRIANGLES: 510 { 511 for ( size_t j = 0, count = uvIndices.getCount() ; j < count; j+=3 ) 512 { 513 TVFace& face = meshMap.tf[currentFaceIndex]; 514 face.setTVerts( uvIndices[j] - initialIndex, uvIndices[j + 1] - initialIndex, uvIndices[j + 2] - initialIndex); 515 ++currentFaceIndex; 516 } 517 break; 518 } 519 case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: 520 { 521 const COLLADAFW::Tristrips* tristrips = (const COLLADAFW::Tristrips*) meshPrimitive; 522 const COLLADAFW::UIntValuesArray& faceVertexCountArray = tristrips->getGroupedVerticesVertexCountArray(); 523 size_t nextTristripStartIndex = 0; 524 for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k) 525 { 526 unsigned int faceVertexCount = faceVertexCountArray[k]; 527 bool switchOrientation = false; 528 for ( size_t j = nextTristripStartIndex + 2, lastVertex = nextTristripStartIndex + faceVertexCount; j < lastVertex; ++j ) 529 { 530 TVFace& face = meshMap.tf[currentFaceIndex]; 531 if ( switchOrientation ) 532 { 533 face.setTVerts( uvIndices[j - 1] - initialIndex, uvIndices[j - 2] - initialIndex, uvIndices[j] - initialIndex); 534 switchOrientation = false; 535 } 536 else 537 { 538 face.setTVerts( uvIndices[j - 2] - initialIndex, uvIndices[j - 1] - initialIndex, uvIndices[j] - initialIndex); 539 switchOrientation = true; 540 } 541 ++currentFaceIndex; 542 } 543 nextTristripStartIndex += faceVertexCount; 544 } 545 break; 546 } 547 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: 548 { 549 const COLLADAFW::Trifans* trifans = (const COLLADAFW::Trifans*) meshPrimitive; 550 const COLLADAFW::UIntValuesArray& faceVertexCountArray = trifans->getGroupedVerticesVertexCountArray(); 551 size_t nextTrifanStartIndex = 0; 552 for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k) 553 { 554 unsigned int faceVertexCount = faceVertexCountArray[k]; 555 unsigned int commonVertexIndex = uvIndices[nextTrifanStartIndex] - initialIndex; 556 for ( size_t j = nextTrifanStartIndex + 2, lastVertex = nextTrifanStartIndex + faceVertexCount; j < lastVertex; ++j ) 557 { 558 TVFace& face = meshMap.tf[currentFaceIndex]; 559 face.setTVerts( commonVertexIndex, uvIndices[j - 1] - initialIndex, uvIndices[j] - initialIndex); 560 ++currentFaceIndex; 561 } 562 nextTrifanStartIndex += faceVertexCount; 563 } 564 break; 565 } 566 default: 567 return; 568 } 569 } 570 571 572 //------------------------------ getTriangleMeshPrimitiveTriangleCount(const COLLADAFW::MeshPrimitive * meshPrimitive)573 size_t getTriangleMeshPrimitiveTriangleCount( const COLLADAFW::MeshPrimitive* meshPrimitive) 574 { 575 const COLLADAFW::UIntValuesArray& faceVertexCountArray = meshPrimitive->getPositionIndices(); 576 577 switch (meshPrimitive->getPrimitiveType()) 578 { 579 case COLLADAFW::MeshPrimitive::TRIANGLES: 580 { 581 return meshPrimitive->getPositionIndices().getCount()/3; 582 } 583 case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: 584 { 585 const COLLADAFW::Tristrips* tristrips = (const COLLADAFW::Tristrips*) meshPrimitive; 586 const COLLADAFW::UIntValuesArray& faceVertexCountArray = tristrips->getGroupedVerticesVertexCountArray(); 587 size_t triangleCount = 0; 588 for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k) 589 { 590 unsigned int faceVertexCount = faceVertexCountArray[k]; 591 triangleCount += (faceVertexCount > 2) ? (faceVertexCount - 2) : 0; 592 } 593 return triangleCount; 594 } 595 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: 596 { 597 const COLLADAFW::Trifans* trifans = (const COLLADAFW::Trifans*) meshPrimitive; 598 const COLLADAFW::UIntValuesArray& faceVertexCountArray = trifans->getGroupedVerticesVertexCountArray(); 599 size_t triangleCount = 0; 600 for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k) 601 { 602 unsigned int faceVertexCount = faceVertexCountArray[k]; 603 triangleCount += (faceVertexCount > 2) ? (faceVertexCount - 2) : 0; 604 } 605 return triangleCount; 606 } 607 default: 608 return 0; 609 } 610 } 611 612 //------------------------------ importTriangleMeshUVCoords(TriObject * triangleObject)613 bool GeometryImporter::importTriangleMeshUVCoords( TriObject* triangleObject ) 614 { 615 COLLADAFW::Mesh* mesh = (COLLADAFW::Mesh*) mGeometry; 616 617 createSetSourcePairMapChannelMap(); 618 619 Mesh& triangleMesh = triangleObject->GetMesh(); 620 621 triangleMesh.setNumMaps( mLargestMapChannel + 1 ); 622 623 int facesCount = (int)mTotalTrianglesCount; 624 625 // reset all texture indices of all used maps 626 for ( int i = 0; i <= mLargestMapChannel; ++i ) 627 { 628 MeshMap& meshMap = triangleMesh.Map(i); 629 meshMap.setNumFaces( facesCount ); 630 memset( meshMap.tf, 0, sizeof(TVFace) * facesCount); 631 } 632 633 const COLLADAFW::MeshVertexData& uvCoordinates = mesh->getUVCoords(); 634 const COLLADAFW::MeshVertexData& vertexColors = mesh->getColors(); 635 const COLLADAFW::MeshVertexData::InputInfosArray& uvInputInfos = uvCoordinates.getInputInfosArray(); 636 const COLLADAFW::MeshVertexData::InputInfosArray& vertexColorInputInfos = vertexColors.getInputInfosArray(); 637 638 SetSourcePairMapChannelMap::const_iterator it = mSetSourcePairMapChannelMap.begin(); 639 for ( ; it != mSetSourcePairMapChannelMap.end(); ++it ) 640 { 641 const SetSourcePair& setSourcePair = it->first; 642 const size_t& sourceIndex = setSourcePair.second; 643 // check that the channel is a texture channel and not a color channel 644 long setIndex = setSourcePair.first; 645 int mapChannel = it->second; 646 triangleMesh.setMapSupport(mapChannel, true); 647 648 assert( (mapChannel != 0) || ( setIndex < 0) ); 649 MeshMap& meshMap = triangleMesh.Map(mapChannel); 650 if ( setIndex >= 0 ) 651 { 652 fillTriangleMeshMapPerSet( uvCoordinates, uvInputInfos, sourceIndex, meshMap); 653 } 654 else if ( mapChannel == 0 ) 655 { 656 fillTriangleMeshMapPerSet( vertexColors, vertexColorInputInfos, sourceIndex, meshMap); 657 } 658 } 659 660 661 COLLADAFW::MeshPrimitiveArray& meshPrimitiveArray = mesh->getMeshPrimitives(); 662 size_t faceIndex = 0; 663 for ( size_t i = 0, count = meshPrimitiveArray.getCount(); i < count; ++i) 664 { 665 const COLLADAFW::MeshPrimitive* meshPrimitive = meshPrimitiveArray[i]; 666 if ( ! meshPrimitive ) 667 continue; 668 669 if (isSupportedMeshPrimitive(meshPrimitive)) 670 { 671 size_t currentFaceIndex = faceIndex; 672 673 //uv 674 const COLLADAFW::IndexListArray& uvIndexArray = meshPrimitive->getUVCoordIndicesArray(); 675 for ( size_t j = 0, count = uvIndexArray.getCount(); j < count; ++j) 676 { 677 const COLLADAFW::IndexList& uvIndexList = *uvIndexArray[j]; 678 size_t sourceIndex = mUVInitialIndexSourceIndexMap[uvIndexList.getInitialIndex()]; 679 size_t setIndex = uvIndexList.getSetIndex(); 680 SetSourcePair setSourcePair( (long)setIndex, sourceIndex); 681 int mapChannel = mSetSourcePairMapChannelMap[ setSourcePair ]; 682 683 unsigned int initialIndex = (unsigned int)uvIndexList.getInitialIndex(); 684 685 const COLLADAFW::UIntValuesArray& uvIndices = uvIndexList.getIndices(); 686 687 MeshMap& meshMap = triangleMesh.Map(mapChannel); 688 689 currentFaceIndex = faceIndex; 690 691 setTriangleMeshUVVerticesPerPrimitiveAndChannel( meshPrimitive, meshMap, uvIndices, initialIndex, currentFaceIndex); 692 } 693 694 // vertex color color 695 const COLLADAFW::IndexListArray& colorIndexArray = meshPrimitive->getColorIndicesArray(); 696 for ( size_t j = 0, count = colorIndexArray.getCount(); j < count; ++j) 697 { 698 const COLLADAFW::IndexList& colorIndexList = *colorIndexArray[j]; 699 size_t sourceIndex = mColorInitialIndexSourceIndexMap[colorIndexList.getInitialIndex()]; 700 size_t setIndex = colorIndexList.getSetIndex(); 701 SetSourcePair setSourcePair( -(long)(setIndex + 1), sourceIndex); 702 int mapChannel = mSetSourcePairMapChannelMap[ setSourcePair ]; 703 if ( mapChannel != 0) 704 continue; 705 706 unsigned int initialIndex = (unsigned int)colorIndexList.getInitialIndex(); 707 708 const COLLADAFW::UIntValuesArray& colorIndices = colorIndexList.getIndices(); 709 710 MeshMap& meshMap = triangleMesh.Map(mapChannel); 711 712 currentFaceIndex = faceIndex; 713 714 setTriangleMeshUVVerticesPerPrimitiveAndChannel( meshPrimitive, meshMap, colorIndices, initialIndex, currentFaceIndex); 715 mHasVertexColor = true; 716 } 717 718 if ( faceIndex == currentFaceIndex ) 719 { 720 // setTriangleMeshUVVerticesPerPrimitiveAndChannel was never called. we need to count triangle here 721 faceIndex += getTriangleMeshPrimitiveTriangleCount(meshPrimitive); 722 } 723 else 724 { 725 // currentFaceIndex was properly set by the last setTriangleMeshUVVerticesPerPrimitiveAndChannel call 726 faceIndex = currentFaceIndex; 727 } 728 } 729 730 } 731 return true; 732 } 733 734 735 //------------------------------ importPolygonMesh()736 bool GeometryImporter::importPolygonMesh( ) 737 { 738 739 COLLADAFW::Mesh* mesh = (COLLADAFW::Mesh*) mGeometry; 740 741 PolyObject* polygonObject = CreateEditablePolyObject(); 742 MNMesh& polygonMesh = polygonObject->GetMesh(); 743 744 745 if ( !importPolygonMeshPositions(polygonObject) ) 746 return false; 747 748 if ( !importPolygonMeshNormals(polygonObject) ) 749 return false; 750 751 if ( !importPolygonMeshUVCoords(polygonObject) ) 752 return false; 753 754 755 polygonMesh.InvalidateGeomCache(); 756 757 handleObjectReferences(mesh, polygonObject); 758 759 return true; 760 } 761 762 //------------------------------ importPolygonMeshPositions(PolyObject * polygonObject)763 bool GeometryImporter::importPolygonMeshPositions( PolyObject* polygonObject ) 764 { 765 COLLADAFW::Mesh* mesh = (COLLADAFW::Mesh*) mGeometry; 766 767 MNMesh& polgonMesh = polygonObject->GetMesh(); 768 769 const COLLADAFW::MeshVertexData& meshPositions = mesh->getPositions(); 770 771 int positionsCount = (int)meshPositions.getValuesCount() / 3; 772 773 polgonMesh.setNumVerts(positionsCount); 774 775 if ( meshPositions.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE ) 776 { 777 const COLLADAFW::DoubleArray* positionsArray = meshPositions.getDoubleValues(); 778 for ( int i = 0; i < positionsCount; ++i) 779 { 780 MNVert* vertex = polgonMesh.V(i); 781 vertex->p = Point3( convertSpaceUnit((float)(*positionsArray)[3*i]), 782 convertSpaceUnit((float)(*positionsArray)[3*i + 1]), 783 convertSpaceUnit((float)(*positionsArray)[3*i + 2])); 784 } 785 } 786 else 787 { 788 const COLLADAFW::FloatArray* positionsArray = meshPositions.getFloatValues(); 789 for ( int i = 0; i < positionsCount; ++i) 790 { 791 MNVert* vertex = polgonMesh.V(i); 792 vertex->p = Point3( convertSpaceUnit((*positionsArray)[3*i]), 793 convertSpaceUnit((*positionsArray)[3*i + 1]), 794 convertSpaceUnit((*positionsArray)[3*i + 2])); 795 } 796 } 797 798 size_t polygonsCount = mTotalTrianglesCount + mesh->getPolygonsPolygonCount() + mesh->getPolylistPolygonCount(); 799 polgonMesh.setNumFaces((int)polygonsCount); 800 COLLADAFW::MeshPrimitiveArray& meshPrimitiveArray = mesh->getMeshPrimitives(); 801 size_t faceIndex = 0; 802 for ( size_t i = 0, count = meshPrimitiveArray.getCount(); i < count; ++i) 803 { 804 const COLLADAFW::MeshPrimitive* meshPrimitive = meshPrimitiveArray[i]; 805 if ( ! meshPrimitive ) 806 continue; 807 MtlID maxMaterialId = (MtlID)meshPrimitive->getMaterialId(); 808 switch ( meshPrimitive->getPrimitiveType() ) 809 { 810 case COLLADAFW::MeshPrimitive::TRIANGLES: 811 { 812 const COLLADAFW::Triangles* triangles = (const COLLADAFW::Triangles*) meshPrimitive; 813 const COLLADAFW::UIntValuesArray& positionIndices = triangles->getPositionIndices(); 814 for ( size_t j = 0, count = positionIndices.getCount() ; j < count; j+=3 ) 815 { 816 MNFace* face = polgonMesh.F((int)faceIndex); 817 face->MakePoly(3, (int*) (&positionIndices[j])); 818 if ( maxMaterialId != 0 ) 819 face->material = maxMaterialId; 820 821 ++faceIndex; 822 } 823 break; 824 } 825 case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: 826 { 827 const COLLADAFW::Tristrips* tristrips = (const COLLADAFW::Tristrips*) meshPrimitive; 828 const COLLADAFW::UIntValuesArray& positionIndices = tristrips->getPositionIndices(); 829 const COLLADAFW::UIntValuesArray& faceVertexCountArray = tristrips->getGroupedVerticesVertexCountArray(); 830 size_t nextTristripStartIndex = 0; 831 for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k) 832 { 833 unsigned int faceVertexCount = faceVertexCountArray[k]; 834 bool switchOrientation = false; 835 for ( size_t j = nextTristripStartIndex + 2, lastVertex = nextTristripStartIndex + faceVertexCount; j < lastVertex; ++j ) 836 { 837 MNFace* face = polgonMesh.F((int)faceIndex); 838 if ( switchOrientation ) 839 { 840 int indices[3]; 841 indices[0] = (int)positionIndices[j - 1]; 842 indices[1] = (int)positionIndices[j - 2]; 843 indices[2] = (int)positionIndices[j ]; 844 face->MakePoly(3, indices); 845 if ( maxMaterialId != 0 ) 846 face->material = maxMaterialId; 847 switchOrientation = false; 848 } 849 else 850 { 851 face->MakePoly(3, (int*) (&positionIndices[j - 2])); 852 if ( maxMaterialId != 0 ) 853 face->material = maxMaterialId; 854 switchOrientation = true; 855 } 856 857 ++faceIndex; 858 } 859 nextTristripStartIndex += faceVertexCount; 860 } 861 break; 862 } 863 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: 864 { 865 const COLLADAFW::Trifans* trifans = (const COLLADAFW::Trifans*) meshPrimitive; 866 const COLLADAFW::UIntValuesArray& positionIndices = trifans->getPositionIndices(); 867 const COLLADAFW::UIntValuesArray& faceVertexCountArray = trifans->getGroupedVerticesVertexCountArray(); 868 size_t nextTrifanStartIndex = 0; 869 for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k) 870 { 871 unsigned int faceVertexCount = faceVertexCountArray[k]; 872 int trianglePositionsIndices[3]; 873 //the first vertex is the same for all fans 874 trianglePositionsIndices[0] = (int)positionIndices[nextTrifanStartIndex]; 875 for ( size_t j = nextTrifanStartIndex + 2, lastVertex = nextTrifanStartIndex + faceVertexCount; j < lastVertex; ++j ) 876 { 877 trianglePositionsIndices[1] = (int)positionIndices[j - 1]; 878 trianglePositionsIndices[2] = (int)positionIndices[j]; 879 MNFace* face = polgonMesh.F((int)faceIndex); 880 face->MakePoly(3, trianglePositionsIndices); 881 if ( maxMaterialId != 0 ) 882 face->material = maxMaterialId; 883 884 ++faceIndex; 885 } 886 nextTrifanStartIndex += faceVertexCount; 887 } 888 break; 889 } 890 case COLLADAFW::MeshPrimitive::POLYGONS: 891 { 892 const COLLADAFW::Polygons* polygons = (const COLLADAFW::Polygons*) meshPrimitive; 893 const COLLADAFW::UIntValuesArray& positionIndices = polygons->getPositionIndices(); 894 const COLLADAFW::IntValuesArray& faceVertexCountArray = polygons->getGroupedVerticesVertexCountArray(); 895 size_t currentIndex = 0; 896 for ( size_t j = 0, count = faceVertexCountArray.getCount() ; j < count; ++j ) 897 { 898 int faceVertexCount = faceVertexCountArray[j]; 899 // TODO for now, we ignore holes in polygons 900 if ( faceVertexCount <= 0 ) 901 continue; 902 MNFace* face = polgonMesh.F((int)faceIndex); 903 face->MakePoly(faceVertexCount, (int*) (&positionIndices[currentIndex])); 904 if ( maxMaterialId != 0 ) 905 face->material = maxMaterialId; 906 currentIndex += faceVertexCount; 907 ++faceIndex; 908 } 909 break; 910 } 911 case COLLADAFW::MeshPrimitive::POLYLIST: 912 { 913 const COLLADAFW::Polylist* polylist = (const COLLADAFW::Polylist*) meshPrimitive; 914 const COLLADAFW::UIntValuesArray& positionIndices = polylist->getPositionIndices(); 915 const COLLADAFW::IntValuesArray& faceVertexCountArray = polylist->getGroupedVerticesVertexCountArray(); 916 size_t currentIndex = 0; 917 for ( size_t j = 0, count = faceVertexCountArray.getCount() ; j < count; ++j ) 918 { 919 int faceVertexCount = faceVertexCountArray[j]; 920 // polylist does not support holes! 921 if ( faceVertexCount <= 0 ) 922 continue; 923 MNFace* face = polgonMesh.F((int)faceIndex); 924 face->MakePoly(faceVertexCount, (int*) (&positionIndices[currentIndex])); 925 if ( maxMaterialId != 0 ) 926 face->material = maxMaterialId; 927 currentIndex += faceVertexCount; 928 ++faceIndex; 929 } 930 break; 931 } 932 } 933 934 } 935 return true; 936 } 937 938 //------------------------------ importPolygonMeshNormals(PolyObject * polygonObject)939 bool GeometryImporter::importPolygonMeshNormals( PolyObject* polygonObject ) 940 { 941 COLLADAFW::Mesh* mesh = (COLLADAFW::Mesh*) mGeometry; 942 943 if ( !mesh->hasNormals() ) 944 return true; 945 946 MNMesh& polygonMesh = polygonObject->GetMesh(); 947 948 polygonMesh.SpecifyNormals(); 949 MNNormalSpec* normalsSpecifier = polygonMesh.GetSpecifiedNormals(); 950 951 normalsSpecifier->ClearNormals(); 952 size_t numFaces = polygonMesh.FNum(); 953 normalsSpecifier->SetNumFaces((int)numFaces); 954 955 // fill in the normals 956 const COLLADAFW::MeshVertexData& meshNormals = mesh->getNormals(); 957 int normalCount = (int)meshNormals.getValuesCount()/3; 958 959 normalsSpecifier->SetNumNormals(normalCount); 960 961 if ( meshNormals.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE ) 962 { 963 const COLLADAFW::DoubleArray* normalsArray = meshNormals.getDoubleValues(); 964 for ( int i = 0; i < normalCount; ++i) 965 { 966 Point3 normal((*normalsArray)[i*3], (*normalsArray)[i*3 + 1], (*normalsArray)[i*3 + 2]); 967 normalsSpecifier->Normal(i) = normal.Normalize(); 968 normalsSpecifier->SetNormalExplicit(i, true); 969 } 970 } 971 else 972 { 973 const COLLADAFW::FloatArray* normalsArray = meshNormals.getFloatValues(); 974 for ( int i = 0; i < normalCount; ++i) 975 { 976 Point3 normal((*normalsArray)[i*3], (*normalsArray)[i*3 + 1], (*normalsArray)[i*3 + 2]); 977 normalsSpecifier->Normal(i) = normal.Normalize(); 978 normalsSpecifier->SetNormalExplicit(i, true); 979 } 980 } 981 982 //assign normals to faces (polygons) 983 const COLLADAFW::MeshPrimitiveArray& meshPrimitives = mesh->getMeshPrimitives(); 984 size_t faceIndex = 0; 985 for ( size_t i = 0, count = meshPrimitives.getCount(); i < count; ++i ) 986 { 987 const COLLADAFW::MeshPrimitive* meshPrimitive = meshPrimitives[i]; 988 const COLLADAFW::UIntValuesArray& normalIndices = meshPrimitive->getNormalIndices(); 989 990 991 if (isSupportedMeshPrimitive(meshPrimitive)) 992 { 993 if ( skipMeshData( meshPrimitive, normalIndices, faceIndex ) ) 994 { 995 continue; 996 } 997 } 998 else 999 { 1000 continue; 1001 } 1002 1003 switch ( meshPrimitive->getPrimitiveType() ) 1004 { 1005 case COLLADAFW::MeshPrimitive::TRIANGLES: 1006 { 1007 size_t faceCount = meshPrimitive->getFaceCount(); 1008 for ( size_t j = 0; j < faceCount; ++j) 1009 { 1010 MNNormalFace& normalFace = normalsSpecifier->Face((int) faceIndex); 1011 normalFace.SetDegree(3); 1012 normalFace.SpecifyAll(); 1013 normalFace.SetNormalID(0, normalIndices[3*j]); 1014 normalFace.SetNormalID(1, normalIndices[3*j + 1]); 1015 normalFace.SetNormalID(2, normalIndices[3*j + 2]); 1016 ++faceIndex; 1017 } 1018 } 1019 break; 1020 case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: 1021 { 1022 const COLLADAFW::Tristrips* tristrips = (const COLLADAFW::Tristrips*) meshPrimitive; 1023 const COLLADAFW::UIntValuesArray& faceVertexCountArray = tristrips->getGroupedVerticesVertexCountArray(); 1024 size_t nextTristripStartIndex = 0; 1025 for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k) 1026 { 1027 unsigned int faceVertexCount = faceVertexCountArray[k]; 1028 bool switchOrientation = false; 1029 for ( size_t j = nextTristripStartIndex + 2, lastVertex = nextTristripStartIndex + faceVertexCount; j < lastVertex; ++j ) 1030 { 1031 MNNormalFace& normalFace = normalsSpecifier->Face((int) faceIndex); 1032 normalFace.SetDegree(3); 1033 normalFace.SpecifyAll(); 1034 if ( switchOrientation ) 1035 { 1036 normalFace.SetNormalID(0, normalIndices[j - 1]); 1037 normalFace.SetNormalID(1, normalIndices[j - 2]); 1038 normalFace.SetNormalID(2, normalIndices[j]); 1039 switchOrientation = false; 1040 } 1041 else 1042 { 1043 normalFace.SetNormalID(0, normalIndices[j - 2]); 1044 normalFace.SetNormalID(1, normalIndices[j - 1]); 1045 normalFace.SetNormalID(2, normalIndices[j]); 1046 switchOrientation = true; 1047 } 1048 ++faceIndex; 1049 } 1050 nextTristripStartIndex += faceVertexCount; 1051 } 1052 break; 1053 } 1054 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: 1055 { 1056 const COLLADAFW::Trifans* trifans = (const COLLADAFW::Trifans*) meshPrimitive; 1057 const COLLADAFW::UIntValuesArray& faceVertexCountArray = trifans->getGroupedVerticesVertexCountArray(); 1058 size_t nextTrifanStartIndex = 0; 1059 for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k) 1060 { 1061 unsigned int faceVertexCount = faceVertexCountArray[k]; 1062 unsigned int commonVertexIndex = normalIndices[nextTrifanStartIndex]; 1063 for ( size_t j = nextTrifanStartIndex + 2, lastVertex = nextTrifanStartIndex + faceVertexCount; j < lastVertex; ++j ) 1064 { 1065 MNNormalFace& normalFace = normalsSpecifier->Face((int) faceIndex); 1066 normalFace.SetDegree(3); 1067 normalFace.SpecifyAll(); 1068 normalFace.SetNormalID(0, commonVertexIndex); 1069 normalFace.SetNormalID(1, normalIndices[j - 1]); 1070 normalFace.SetNormalID(2, normalIndices[j]); 1071 ++faceIndex; 1072 } 1073 nextTrifanStartIndex += faceVertexCount; 1074 } 1075 break; 1076 } 1077 case COLLADAFW::MeshPrimitive::POLYGONS: 1078 { 1079 COLLADAFW::Polygons* polygons = (COLLADAFW::Polygons*) meshPrimitive; 1080 1081 COLLADAFW::IntValuesArray& faceVertexCountArray = polygons->getGroupedVerticesVertexCountArray(); 1082 size_t currentIndex = 0; 1083 for ( size_t j = 0, count = faceVertexCountArray.getCount(); j < count; ++j) 1084 { 1085 int faceVertexCount = faceVertexCountArray[j]; 1086 1087 // TODO for now, we ignore holes in polygons 1088 if ( faceVertexCount <= 0 ) 1089 continue; 1090 1091 MNNormalFace& normalFace = normalsSpecifier->Face((int) faceIndex); 1092 normalFace.SetDegree((int)faceVertexCount); 1093 normalFace.SpecifyAll(); 1094 for ( int k = 0; k < faceVertexCount; ++k) 1095 { 1096 normalFace.SetNormalID(k, normalIndices[currentIndex + k]); 1097 } 1098 currentIndex += faceVertexCount; 1099 ++faceIndex; 1100 } 1101 } 1102 break; 1103 case COLLADAFW::MeshPrimitive::POLYLIST: 1104 { 1105 COLLADAFW::Polylist* polylist = (COLLADAFW::Polylist*) meshPrimitive; 1106 1107 COLLADAFW::IntValuesArray& faceVertexCountArray = polylist->getGroupedVerticesVertexCountArray(); 1108 size_t currentIndex = 0; 1109 for ( size_t j = 0, count = faceVertexCountArray.getCount(); j < count; ++j) 1110 { 1111 int faceVertexCount = faceVertexCountArray[j]; 1112 1113 // polylist does not support holes! 1114 if ( faceVertexCount <= 0 ) 1115 continue; 1116 1117 MNNormalFace& normalFace = normalsSpecifier->Face((int) faceIndex); 1118 normalFace.SetDegree((int)faceVertexCount); 1119 normalFace.SpecifyAll(); 1120 for ( int k = 0; k < faceVertexCount; ++k) 1121 { 1122 normalFace.SetNormalID(k, normalIndices[currentIndex + k]); 1123 } 1124 currentIndex += faceVertexCount; 1125 ++faceIndex; 1126 } 1127 } 1128 break; 1129 default: 1130 continue; 1131 } 1132 1133 } 1134 1135 normalsSpecifier->CheckNormals(); 1136 1137 return true; 1138 } 1139 1140 //------------------------------ 1141 template<class NumberArray> setPolygonMeshUVVertices(const NumberArray & uvArray,MNMap * meshMap,size_t stride,size_t startPosition,size_t vertsCount)1142 void GeometryImporter::setPolygonMeshUVVertices( const NumberArray& uvArray, MNMap* meshMap, size_t stride, size_t startPosition, size_t vertsCount ) 1143 { 1144 size_t uvIndex = startPosition; 1145 1146 switch ( stride ) 1147 { 1148 case 1: 1149 { 1150 for ( size_t i = 0; i < vertsCount; ++i) 1151 { 1152 UVVert& textureVertex = meshMap->v[i]; 1153 textureVertex.x = (float)uvArray[uvIndex++]; 1154 } 1155 break; 1156 } 1157 case 2: 1158 { 1159 for ( size_t i = 0; i < vertsCount; ++i) 1160 { 1161 UVVert& textureVertex = meshMap->v[i]; 1162 textureVertex.x = (float)uvArray[uvIndex++]; 1163 textureVertex.y = (float)uvArray[uvIndex++]; 1164 } 1165 break; 1166 } 1167 case 3: 1168 { 1169 for ( size_t i = 0; i < vertsCount; ++i) 1170 { 1171 UVVert& textureVertex = meshMap->v[i]; 1172 float x = (float)uvArray[uvIndex++]; 1173 float y = (float)uvArray[uvIndex++]; 1174 float z = (float)uvArray[uvIndex++]; 1175 textureVertex.Set(x, y, z); 1176 } 1177 break; 1178 } 1179 case 4: 1180 { 1181 for ( size_t i = 0; i < vertsCount; ++i) 1182 { 1183 UVVert& textureVertex = meshMap->v[i]; 1184 float x = (float)uvArray[uvIndex++]; 1185 float y = (float)uvArray[uvIndex++]; 1186 float z = (float)uvArray[uvIndex++]; 1187 textureVertex.Set(x, y, z); 1188 uvIndex++; 1189 } 1190 break; 1191 } 1192 default: 1193 assert(false); 1194 } 1195 1196 } 1197 1198 //------------------------------ setPolygonMeshUVVerticesPerPrimitiveAndChannel(const COLLADAFW::MeshPrimitive * meshPrimitive,MNMap * meshMap,const COLLADAFW::UIntValuesArray & uvIndices,unsigned int initialIndex,size_t & currentFaceIndex)1199 void GeometryImporter::setPolygonMeshUVVerticesPerPrimitiveAndChannel( const COLLADAFW::MeshPrimitive* meshPrimitive, 1200 MNMap* meshMap, 1201 const COLLADAFW::UIntValuesArray& uvIndices, 1202 unsigned int initialIndex, 1203 size_t& currentFaceIndex) 1204 { 1205 1206 if ( skipMeshData( meshPrimitive, uvIndices, currentFaceIndex ) ) 1207 { 1208 return; 1209 } 1210 1211 int indices[3]; 1212 switch (meshPrimitive->getPrimitiveType()) 1213 { 1214 case COLLADAFW::MeshPrimitive::TRIANGLES: 1215 { 1216 for ( size_t j = 0, count = uvIndices.getCount() ; j < count; j+=3 ) 1217 { 1218 MNMapFace* face = meshMap->F((int)currentFaceIndex); 1219 indices[0] = (int)(uvIndices[j] - initialIndex); 1220 indices[1] = (int)(uvIndices[j+1] - initialIndex); 1221 indices[2] = (int)(uvIndices[j+2] - initialIndex); 1222 face->MakePoly( 3, indices ); 1223 ++currentFaceIndex; 1224 } 1225 break; 1226 } 1227 case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: 1228 { 1229 const COLLADAFW::Tristrips* tristrips = (const COLLADAFW::Tristrips*) meshPrimitive; 1230 const COLLADAFW::UIntValuesArray& faceVertexCountArray = tristrips->getGroupedVerticesVertexCountArray(); 1231 size_t nextTristripStartIndex = 0; 1232 int indices[3]; 1233 for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k) 1234 { 1235 unsigned int faceVertexCount = faceVertexCountArray[k]; 1236 bool switchOrientation = false; 1237 for ( size_t j = nextTristripStartIndex + 2, lastVertex = nextTristripStartIndex + faceVertexCount; j < lastVertex; ++j ) 1238 { 1239 MNMapFace* face = meshMap->F((int)currentFaceIndex); 1240 if ( switchOrientation ) 1241 { 1242 indices[0] = (int)(uvIndices[j - 1] - initialIndex); 1243 indices[1] = (int)(uvIndices[j - 2] - initialIndex); 1244 indices[2] = (int)(uvIndices[j] - initialIndex); 1245 face->MakePoly( 3, indices ); 1246 switchOrientation = false; 1247 } 1248 else 1249 { 1250 indices[0] = (int)(uvIndices[j - 2] - initialIndex); 1251 indices[1] = (int)(uvIndices[j - 1] - initialIndex); 1252 indices[2] = (int)(uvIndices[j] - initialIndex); 1253 face->MakePoly( 3, indices ); 1254 switchOrientation = true; 1255 } 1256 ++currentFaceIndex; 1257 } 1258 nextTristripStartIndex += faceVertexCount; 1259 } 1260 break; 1261 } 1262 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: 1263 { 1264 const COLLADAFW::Trifans* trifans = (const COLLADAFW::Trifans*) meshPrimitive; 1265 const COLLADAFW::UIntValuesArray& faceVertexCountArray = trifans->getGroupedVerticesVertexCountArray(); 1266 size_t nextTrifanStartIndex = 0; 1267 int indices[3]; 1268 for ( size_t k = 0, count = faceVertexCountArray.getCount(); k < count; ++k) 1269 { 1270 unsigned int faceVertexCount = faceVertexCountArray[k]; 1271 unsigned int commonVertexIndex = uvIndices[nextTrifanStartIndex] - initialIndex; 1272 indices[0] = (int)(commonVertexIndex); 1273 for ( size_t j = nextTrifanStartIndex + 2, lastVertex = nextTrifanStartIndex + faceVertexCount; j < lastVertex; ++j ) 1274 { 1275 MNMapFace* face = meshMap->F((int)currentFaceIndex); 1276 indices[1] = (int)(uvIndices[j - 1] - initialIndex); 1277 indices[2] = (int)(uvIndices[j] - initialIndex); 1278 face->MakePoly( 3, indices ); 1279 ++currentFaceIndex; 1280 } 1281 nextTrifanStartIndex += faceVertexCount; 1282 } 1283 break; 1284 } 1285 case COLLADAFW::MeshPrimitive::POLYGONS: 1286 { 1287 const COLLADAFW::Polygons* polygons = (const COLLADAFW::Polygons*) meshPrimitive; 1288 const COLLADAFW::IntValuesArray& faceVertexCountArray = polygons->getGroupedVerticesVertexCountArray(); 1289 size_t currentIndex = 0; 1290 for ( size_t j = 0, count = faceVertexCountArray.getCount() ; j < count; ++j ) 1291 { 1292 int faceVertexCount = faceVertexCountArray[j]; 1293 // TODO for now, we ignore holes in polygons 1294 if ( faceVertexCount <= 0 ) 1295 continue; 1296 MNMapFace* face = meshMap->F((int)currentFaceIndex); 1297 int* indices = new int[faceVertexCount]; 1298 for ( int j = 0; j < faceVertexCount; ++j) 1299 { 1300 indices[j] = uvIndices[ currentIndex + j ] - initialIndex; 1301 } 1302 1303 face->MakePoly(faceVertexCount, indices); 1304 currentIndex += faceVertexCount; 1305 ++currentFaceIndex; 1306 delete[] indices; 1307 } 1308 break; 1309 } 1310 case COLLADAFW::MeshPrimitive::POLYLIST: 1311 { 1312 const COLLADAFW::Polylist* polylist = (const COLLADAFW::Polylist*) meshPrimitive; 1313 const COLLADAFW::IntValuesArray& faceVertexCountArray = polylist->getGroupedVerticesVertexCountArray(); 1314 size_t currentIndex = 0; 1315 for ( size_t j = 0, count = faceVertexCountArray.getCount() ; j < count; ++j ) 1316 { 1317 int faceVertexCount = faceVertexCountArray[j]; 1318 // polylist does not support holes! 1319 if ( faceVertexCount <= 0 ) 1320 continue; 1321 MNMapFace* face = meshMap->F((int)currentFaceIndex); 1322 int* indices = new int[faceVertexCount]; 1323 for ( int j = 0; j < faceVertexCount; ++j) 1324 { 1325 indices[j] = uvIndices[ currentIndex + j ] - initialIndex; 1326 } 1327 1328 face->MakePoly(faceVertexCount, indices); 1329 currentIndex += faceVertexCount; 1330 ++currentFaceIndex; 1331 delete[] indices; 1332 } 1333 break; 1334 } 1335 default: 1336 return; 1337 } 1338 } 1339 1340 //------------------------------ getPolygonMeshPrimitiveFaceCount(const COLLADAFW::MeshPrimitive * meshPrimitive)1341 size_t getPolygonMeshPrimitiveFaceCount( const COLLADAFW::MeshPrimitive* meshPrimitive) 1342 { 1343 1344 switch (meshPrimitive->getPrimitiveType()) 1345 { 1346 case COLLADAFW::MeshPrimitive::TRIANGLES: 1347 case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: 1348 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: 1349 return getTriangleMeshPrimitiveTriangleCount( meshPrimitive ); 1350 case COLLADAFW::MeshPrimitive::POLYGONS: 1351 { 1352 const COLLADAFW::Polygons* polygons = (const COLLADAFW::Polygons*) meshPrimitive; 1353 const COLLADAFW::IntValuesArray& faceVertexCountArray = polygons->getGroupedVerticesVertexCountArray(); 1354 size_t faceCount = 0; 1355 for ( size_t j = 0, count = faceVertexCountArray.getCount() ; j < count; ++j ) 1356 { 1357 int faceVertexCount = faceVertexCountArray[j]; 1358 // TODO for now, we ignore holes in polygons 1359 if ( faceVertexCount > 0 ) 1360 { 1361 faceCount++; 1362 } 1363 } 1364 return faceCount; 1365 } 1366 case COLLADAFW::MeshPrimitive::POLYLIST: 1367 { 1368 const COLLADAFW::Polylist* polylist = (const COLLADAFW::Polylist*) meshPrimitive; 1369 const COLLADAFW::IntValuesArray& faceVertexCountArray = polylist->getGroupedVerticesVertexCountArray(); 1370 size_t faceCount = 0; 1371 for ( size_t j = 0, count = faceVertexCountArray.getCount() ; j < count; ++j ) 1372 { 1373 int faceVertexCount = faceVertexCountArray[j]; 1374 // polylist does not support holes 1375 if ( faceVertexCount > 0 ) 1376 faceCount++; 1377 } 1378 return faceCount; 1379 } 1380 default: 1381 return 0; 1382 } 1383 } 1384 1385 1386 //------------------------------ fillPolygonMeshMapPerSet(const COLLADAFW::MeshVertexData & uvCoordinates,const COLLADAFW::MeshVertexData::InputInfosArray & inputInfos,size_t sourceIndex,MNMap * meshMap)1387 void GeometryImporter::fillPolygonMeshMapPerSet( const COLLADAFW::MeshVertexData& uvCoordinates, 1388 const COLLADAFW::MeshVertexData::InputInfosArray& inputInfos, 1389 size_t sourceIndex, 1390 MNMap* meshMap) 1391 { 1392 const COLLADAFW::MeshVertexData::InputInfos* inputInfo = inputInfos[ sourceIndex ]; 1393 1394 size_t stride = inputInfo->mStride; 1395 size_t vertsCount = inputInfo->mLength / stride; 1396 1397 // calculate first index position 1398 size_t startPosition = 0; 1399 for ( size_t i = 0; i < sourceIndex; ++i) 1400 { 1401 const COLLADAFW::MeshVertexData::InputInfos* inputInfo = inputInfos[ i ]; 1402 startPosition += inputInfo->mLength; 1403 } 1404 1405 meshMap->setNumVerts((int)vertsCount); 1406 1407 1408 if ( uvCoordinates.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE ) 1409 { 1410 const COLLADAFW::DoubleArray& uvArray = *uvCoordinates.getDoubleValues(); 1411 setPolygonMeshUVVertices(uvArray, meshMap, stride, startPosition, vertsCount); 1412 } 1413 else 1414 { 1415 const COLLADAFW::FloatArray& uvArray = *uvCoordinates.getFloatValues(); 1416 setPolygonMeshUVVertices(uvArray, meshMap, stride, startPosition, vertsCount); 1417 } 1418 1419 } 1420 1421 1422 //------------------------------ importPolygonMeshUVCoords(PolyObject * polygonObject)1423 bool GeometryImporter::importPolygonMeshUVCoords( PolyObject* polygonObject ) 1424 { 1425 COLLADAFW::Mesh* mesh = (COLLADAFW::Mesh*) mGeometry; 1426 1427 createSetSourcePairMapChannelMap(); 1428 1429 MNMesh& polygonMesh = polygonObject->GetMesh(); 1430 1431 polygonMesh.SetMapNum( mLargestMapChannel + 1 ); 1432 1433 int facesCount = polygonMesh.FNum();; 1434 1435 // reset all texture indices of all used maps 1436 for ( int i = 0; i <= mLargestMapChannel; ++i ) 1437 { 1438 // enable / initialize the Map 1439 polygonMesh.InitMap(i); 1440 // MNMap& meshMap = polygonMesh.M(i); 1441 // meshMap.setNumFaces( facesCount ); 1442 // memset( meshMap.tf, 0, sizeof(TVFace) * facesCount); 1443 } 1444 1445 const COLLADAFW::MeshVertexData& uvCoordinates = mesh->getUVCoords(); 1446 const COLLADAFW::MeshVertexData& vertexColors = mesh->getColors(); 1447 const COLLADAFW::MeshVertexData::InputInfosArray& uvInputInfos = uvCoordinates.getInputInfosArray(); 1448 const COLLADAFW::MeshVertexData::InputInfosArray& vertexColorInputInfos = vertexColors.getInputInfosArray(); 1449 1450 1451 SetSourcePairMapChannelMap::const_iterator it = mSetSourcePairMapChannelMap.begin(); 1452 bool hasColorChannel = false; 1453 for ( ; it != mSetSourcePairMapChannelMap.end(); ++it ) 1454 { 1455 const SetSourcePair& setSourcePair = it->first; 1456 const size_t& sourceIndex = setSourcePair.second; 1457 // check that the channel is a texture channel and not a color channel 1458 long setIndex = setSourcePair.first; 1459 int mapChannel = it->second; 1460 MNMap* meshMap = polygonMesh.M(mapChannel); 1461 1462 assert( (mapChannel != 0) || ( setIndex < 0) ); 1463 if ( setIndex >= 0 ) 1464 { 1465 fillPolygonMeshMapPerSet( uvCoordinates, uvInputInfos, sourceIndex, meshMap); 1466 } 1467 else if ( !hasColorChannel ) 1468 { 1469 fillPolygonMeshMapPerSet( vertexColors, vertexColorInputInfos, sourceIndex, meshMap); 1470 hasColorChannel = true; 1471 } 1472 1473 } 1474 1475 1476 COLLADAFW::MeshPrimitiveArray& meshPrimitiveArray = mesh->getMeshPrimitives(); 1477 size_t faceIndex = 0; 1478 for ( size_t i = 0, count = meshPrimitiveArray.getCount(); i < count; ++i) 1479 { 1480 const COLLADAFW::MeshPrimitive* meshPrimitive = meshPrimitiveArray[i]; 1481 if ( ! meshPrimitive ) 1482 continue; 1483 1484 if (isSupportedMeshPrimitive(meshPrimitive)) 1485 { 1486 size_t currentFaceIndex = faceIndex; 1487 1488 const COLLADAFW::IndexListArray& uvIndexArray = meshPrimitive->getUVCoordIndicesArray(); 1489 for ( size_t j = 0, count = uvIndexArray.getCount(); j < count; ++j) 1490 { 1491 const COLLADAFW::IndexList& uvIndexList = *uvIndexArray[j]; 1492 size_t sourceIndex = mUVInitialIndexSourceIndexMap[uvIndexList.getInitialIndex()]; 1493 size_t setIndex = uvIndexList.getSetIndex(); 1494 SetSourcePair setSourcePair( (long)setIndex, sourceIndex); 1495 int mapChannel = mSetSourcePairMapChannelMap[ setSourcePair ]; 1496 1497 unsigned int initialIndex = (unsigned int)uvIndexList.getInitialIndex(); 1498 1499 const COLLADAFW::UIntValuesArray& uvIndices = uvIndexList.getIndices(); 1500 1501 MNMap* meshMap = polygonMesh.M(mapChannel); 1502 1503 currentFaceIndex = faceIndex; 1504 1505 setPolygonMeshUVVerticesPerPrimitiveAndChannel( meshPrimitive, meshMap, uvIndices, initialIndex, currentFaceIndex); 1506 1507 1508 } 1509 1510 // vertex color color 1511 const COLLADAFW::IndexListArray& colorIndexArray = meshPrimitive->getColorIndicesArray(); 1512 for ( size_t j = 0, count = colorIndexArray.getCount(); j < count; ++j) 1513 { 1514 const COLLADAFW::IndexList& colorIndexList = *colorIndexArray[j]; 1515 size_t sourceIndex = mColorInitialIndexSourceIndexMap[colorIndexList.getInitialIndex()]; 1516 size_t setIndex = colorIndexList.getSetIndex(); 1517 SetSourcePair setSourcePair( -(long)(setIndex + 1), sourceIndex); 1518 int mapChannel = mSetSourcePairMapChannelMap[ setSourcePair ]; 1519 if ( mapChannel != 0) 1520 continue; 1521 1522 unsigned int initialIndex = (unsigned int)colorIndexList.getInitialIndex(); 1523 1524 const COLLADAFW::UIntValuesArray& colorIndices = colorIndexList.getIndices(); 1525 1526 MNMap* meshMap = polygonMesh.M(mapChannel); 1527 1528 currentFaceIndex = faceIndex; 1529 1530 setPolygonMeshUVVerticesPerPrimitiveAndChannel( meshPrimitive, meshMap, colorIndices, initialIndex, currentFaceIndex); 1531 polygonMesh.SetDisplayVertexColors(0); 1532 mHasVertexColor = true; 1533 } 1534 1535 if ( faceIndex == currentFaceIndex ) 1536 { 1537 // setTriangleMeshUVVerticesPerPrimitiveAndChannel was never called. we need to count triangle here 1538 faceIndex += getPolygonMeshPrimitiveFaceCount(meshPrimitive); 1539 } 1540 else 1541 { 1542 // currentFaceIndex was properly set by the last setTriangleMeshUVVerticesPerPrimitiveAndChannel call 1543 faceIndex = currentFaceIndex; 1544 } 1545 } 1546 } 1547 return true; 1548 } 1549 1550 1551 //------------------------------ createFWMaterialIdMaxMtlIdMap(const COLLADAFW::MeshPrimitiveArray & primitiveArray,DocumentImporter::FWMaterialIdMaxMtlIdMap & materialMap)1552 void GeometryImporter::createFWMaterialIdMaxMtlIdMap( const COLLADAFW::MeshPrimitiveArray& primitiveArray, DocumentImporter::FWMaterialIdMaxMtlIdMap& materialMap ) 1553 { 1554 MtlID nextMaxMaterialId = 1; 1555 for ( size_t i = 0, count = primitiveArray.getCount(); i < count; ++i ) 1556 { 1557 const COLLADAFW::MeshPrimitive* primitive = primitiveArray[i]; 1558 1559 if (isSupportedMeshPrimitive(primitive)) 1560 { 1561 COLLADAFW::MaterialId fWMaterialId = primitive->getMaterialId(); 1562 if ( materialMap.count(fWMaterialId) == 0 ) 1563 { 1564 materialMap[fWMaterialId] = nextMaxMaterialId++; 1565 } 1566 } 1567 } 1568 } 1569 1570 //------------------------------ createSetSourcePairMapChannelMap()1571 void GeometryImporter::createSetSourcePairMapChannelMap() 1572 { 1573 if ( mGeometry->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH ) 1574 return; 1575 1576 bool usedMapChannels[MAX_MESHMAPS + NUM_HIDDENMAPS]; 1577 memset(usedMapChannels, false, sizeof(bool) * (MAX_MESHMAPS + NUM_HIDDENMAPS)); 1578 1579 COLLADAFW::Mesh* mesh = (COLLADAFW::Mesh*) mGeometry; 1580 1581 const COLLADAFW::MeshVertexData& colors = mesh->getColors(); 1582 const COLLADAFW::MeshVertexData::InputInfosArray& colorInputInfos = colors.getInputInfosArray(); 1583 size_t colorInitialIndex = 0; 1584 for ( size_t i = 0, count = colorInputInfos.getCount(); i < count; ++i) 1585 { 1586 const COLLADAFW::MeshVertexData::InputInfos* inputInfo = colorInputInfos[i]; 1587 size_t& sourceIndex = i; 1588 mColorInitialIndexSourceIndexMap.insert(std::make_pair(colorInitialIndex, sourceIndex)); 1589 mColorSourceIndexInitialIndexMap.insert(std::make_pair(sourceIndex, colorInitialIndex)); 1590 colorInitialIndex += (inputInfo->mLength / inputInfo->mStride); 1591 } 1592 1593 const COLLADAFW::MeshVertexData& uvCoords = mesh->getUVCoords(); 1594 const COLLADAFW::MeshVertexData::InputInfosArray& uVInputInfos = uvCoords.getInputInfosArray(); 1595 size_t uVInitialIndex = 0; 1596 for ( size_t i = 0, count = uVInputInfos.getCount(); i < count; ++i) 1597 { 1598 size_t& sourceIndex = i; 1599 const COLLADAFW::MeshVertexData::InputInfos* inputInfo = uVInputInfos[sourceIndex]; 1600 mUVInitialIndexSourceIndexMap.insert(std::make_pair(uVInitialIndex, sourceIndex)); 1601 mUVSourceIndexInitialIndexMap.insert(std::make_pair(sourceIndex, uVInitialIndex)); 1602 uVInitialIndex += (inputInfo->mLength / inputInfo->mStride); 1603 } 1604 1605 1606 const COLLADAFW::MeshPrimitiveArray& meshPrimitives = mesh->getMeshPrimitives(); 1607 1608 // first try 1609 for ( size_t i = 0, count = meshPrimitives.getCount(); i < count; ++i ) 1610 { 1611 const COLLADAFW::MeshPrimitive* meshPrimitive = meshPrimitives[i]; 1612 1613 if (isSupportedMeshPrimitive(meshPrimitive)) 1614 { 1615 const COLLADAFW::IndexListArray& uvIndices = meshPrimitive->getUVCoordIndicesArray(); 1616 const COLLADAFW::IndexListArray& colorIndices = meshPrimitive->getColorIndicesArray(); 1617 1618 assignMapChannels<true, true>( colorIndices, mColorInitialIndexSourceIndexMap, usedMapChannels); 1619 assignMapChannels<false, true>( uvIndices, mUVInitialIndexSourceIndexMap, usedMapChannels); 1620 } 1621 } 1622 1623 // second try 1624 for ( size_t i = 0, count = meshPrimitives.getCount(); i < count; ++i ) 1625 { 1626 const COLLADAFW::MeshPrimitive* meshPrimitive = meshPrimitives[i]; 1627 if (isSupportedMeshPrimitive(meshPrimitive)) 1628 { 1629 const COLLADAFW::IndexListArray& uvIndices = meshPrimitive->getUVCoordIndicesArray(); 1630 const COLLADAFW::IndexListArray& colorIndices = meshPrimitive->getColorIndicesArray(); 1631 1632 if ( !assignMapChannels<true, false>( colorIndices, mColorInitialIndexSourceIndexMap, usedMapChannels) ) 1633 { 1634 break; 1635 } 1636 if ( !assignMapChannels<false, false>( uvIndices, mUVInitialIndexSourceIndexMap, usedMapChannels) ) 1637 { 1638 break; 1639 } 1640 } 1641 } 1642 1643 // fill the setMapChannelMap for this geometry 1644 DocumentImporter::SetMapChannelMap& setMapChannelMap = getSetMapChannelByGeometryUniqueId( mGeometry->getUniqueId() ); 1645 SetSourcePairMapChannelMap::const_iterator it = mSetSourcePairMapChannelMap.begin(); 1646 for ( ; it != mSetSourcePairMapChannelMap.end(); ++it ) 1647 { 1648 const SetSourcePair& setSourcePair = it->first; 1649 long setIndex = setSourcePair.first; 1650 if ( setIndex >= 0) 1651 { 1652 setMapChannelMap[setIndex] = it->second; 1653 } 1654 } 1655 } 1656 1657 template<bool isColorChannel, bool isFirstTry> assignMapChannels(const COLLADAFW::IndexListArray & indices,const InitialIndexSourceIndexMap & initialIndexSourceIndexMap,bool usedMapChannels[MAX_MESHMAPS+NUM_HIDDENMAPS])1658 bool GeometryImporter::assignMapChannels( const COLLADAFW::IndexListArray& indices, 1659 const InitialIndexSourceIndexMap& initialIndexSourceIndexMap, 1660 bool usedMapChannels[MAX_MESHMAPS + NUM_HIDDENMAPS]) 1661 { 1662 for ( size_t j = 0, count = indices.getCount(); j < count; ++j) 1663 { 1664 const COLLADAFW::IndexList* indexList = indices[j]; 1665 size_t setIndex = indexList->getSetIndex(); 1666 size_t initialIndex = indexList->getInitialIndex(); 1667 InitialIndexSourceIndexMap::const_iterator sourecIndexIt = initialIndexSourceIndexMap.find(initialIndex); 1668 assert(sourecIndexIt != initialIndexSourceIndexMap.end()); 1669 size_t sourceIndex = sourecIndexIt->second; 1670 SetSourcePair setSourcePair( isColorChannel ? -(long)(setIndex+1) : (long)setIndex, sourceIndex); 1671 SetSourcePairMapChannelMap::const_iterator it = mSetSourcePairMapChannelMap.find( setSourcePair ); 1672 1673 // check if we have already assigned a map channel to this color set/ source combination 1674 if ( it != mSetSourcePairMapChannelMap.end() ) 1675 continue; 1676 1677 // assign a map channel 1678 int favoredMapChannel = isColorChannel ? ((setIndex == 1) ? 0 : (int)setIndex) : ((setIndex == 0) ? 1 : (int)setIndex); 1679 1680 if ( isFirstTry ) 1681 { 1682 if ( favoredMapChannel <= MAX_MESHMAPS) 1683 { 1684 if ( !usedMapChannels[favoredMapChannel + NUM_HIDDENMAPS]) 1685 { 1686 mSetSourcePairMapChannelMap.insert( std::make_pair(setSourcePair, favoredMapChannel)); 1687 1688 if ( favoredMapChannel > mLargestMapChannel ) 1689 mLargestMapChannel = favoredMapChannel; 1690 1691 usedMapChannels[favoredMapChannel + NUM_HIDDENMAPS] = true; 1692 } 1693 } 1694 } 1695 else 1696 { 1697 // assign a map channel 1698 int mapChannelIndex = 1; 1699 1700 // Use the next unused map channel 1701 while ( true ) 1702 { 1703 if ( mapChannelIndex > MAX_MESHMAPS) 1704 return false; 1705 1706 if ( !usedMapChannels[mapChannelIndex + NUM_HIDDENMAPS] ) 1707 { 1708 mSetSourcePairMapChannelMap.insert( std::make_pair(setSourcePair, mapChannelIndex)); 1709 1710 if ( mapChannelIndex > mLargestMapChannel ) 1711 mLargestMapChannel = mapChannelIndex; 1712 1713 usedMapChannels[mapChannelIndex + NUM_HIDDENMAPS] = true; 1714 break; 1715 } 1716 1717 ++mapChannelIndex; 1718 } 1719 } 1720 } 1721 return true; 1722 } 1723 skipMeshData(const COLLADAFW::MeshPrimitive * meshPrimitive,const COLLADAFW::UIntValuesArray & dataIndices,size_t & faceIndex)1724 bool GeometryImporter::skipMeshData( const COLLADAFW::MeshPrimitive* meshPrimitive, 1725 const COLLADAFW::UIntValuesArray& dataIndices, 1726 size_t& faceIndex) 1727 { 1728 const COLLADAFW::UIntValuesArray& positionIndices = meshPrimitive->getPositionIndices(); 1729 1730 size_t positionIndicesCount = positionIndices.getCount(); 1731 1732 if ( dataIndices.getCount() != positionIndicesCount ) 1733 { 1734 switch (meshPrimitive->getPrimitiveType()) 1735 { 1736 case COLLADAFW::MeshPrimitive::TRIANGLES: 1737 { 1738 faceIndex += positionIndicesCount/3; 1739 break; 1740 } 1741 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: 1742 case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: 1743 { 1744 faceIndex += (positionIndicesCount > 2) ? (positionIndicesCount - 2) : 0; 1745 break; 1746 } 1747 } 1748 // todo handle error 1749 return true; 1750 } 1751 else 1752 { 1753 return false; 1754 } 1755 } 1756 1757 1758 } // namespace COLLADAMax 1759