Exemple #1
0
bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)  // checks if mesh has supported primitive types: lines, polylist, triangles, triangle_fans
{
	COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();

	const std::string &name = bc_get_dae_name(mesh);
	int hole_count = 0;

	for (unsigned i = 0; i < prim_arr.getCount(); i++) {
		
		COLLADAFW::MeshPrimitive *mp = prim_arr[i];
		COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType();

		const char *type_str = bc_primTypeToStr(type);
		
		// OpenCollada passes POLYGONS type for <polylist>
		if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {

			COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
			COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray();
			
			for (unsigned int j = 0; j < vca.getCount(); j++) {
				int count = vca[j];
				if (abs(count) < 3) {
					fprintf(stderr, "ERROR: Primitive %s in %s has at least one face with vertex count < 3\n",
					        type_str, name.c_str());
					return false;
				}
				if (count < 0)
				{
					hole_count ++;
				}
			}

			if (hole_count > 0)
			{
				fprintf(stderr, "WARNING: Primitive %s in %s: %d holes not imported (unsupported)\n", type_str, name.c_str(), hole_count);
			}
		}

		else if (type == COLLADAFW::MeshPrimitive::LINES) {
			// TODO: Add Checker for line syntax here
		}

		else if (type != COLLADAFW::MeshPrimitive::TRIANGLES && type != COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
			fprintf(stderr, "ERROR: Primitive type %s is not supported.\n", type_str);
			return false;
		}
	}
	
	if (mesh->getPositions().empty()) {
		fprintf(stderr, "ERROR: Mesh %s has no vertices.\n", name.c_str());
		return false;
	}

	return true;
}
 static shared_ptr <GLTF::GLTFPrimitive> ConvertOpenCOLLADAMeshPrimitive(
                                                                         COLLADAFW::MeshPrimitive *openCOLLADAMeshPrimitive,
                                                                         IndicesVector &primitiveIndicesVector)
 {
     shared_ptr <GLTF::GLTFPrimitive> cvtPrimitive(new GLTF::GLTFPrimitive());
     
     // We want to match OpenGL/ES mode , as WebGL spec points to OpenGL/ES spec...
     // "Symbolic constants GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, and GL_TRIANGLES are accepted."
     std::string type;
     bool shouldTriangulate = false;
     
     switch(openCOLLADAMeshPrimitive->getPrimitiveType()) {
             //these 2 requires transforms
         case COLLADAFW::MeshPrimitive::POLYLIST:
         case COLLADAFW::MeshPrimitive::POLYGONS:
             // FIXME: perform conversion, but until not done report error
             //these mode are supported by WebGL
             shouldTriangulate = true;
             //force triangles
             type = "TRIANGLES";
             break;
         case  COLLADAFW::MeshPrimitive::LINES:
             type = "LINES";
             break;
         case  COLLADAFW::MeshPrimitive::LINE_STRIPS:
             type = "LINE_STRIP";
             break;
             
         case  COLLADAFW::MeshPrimitive::TRIANGLES:
             type = "TRIANGLES";
             break;
             
         case  COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
             type = "TRIANGLE_FANS";
             break;
             
         case  COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS:
             type = "TRIANGLE_STRIPS";
             break;
             
         case  COLLADAFW::MeshPrimitive::POINTS:
             type = "POINTS";
             break;
         default:
             break;
     }
     
     cvtPrimitive->setMaterialObjectID((unsigned int)openCOLLADAMeshPrimitive->getMaterialId());
     cvtPrimitive->setType(type);
     
     //count of indices , it must be the same for all kind of indices
     size_t count = openCOLLADAMeshPrimitive->getPositionIndices().getCount();
     
     //vertex
     //IndexList &positionIndexList = openCOLLADAMeshPrimitive->getPositionIndices();
     unsigned int *indices = openCOLLADAMeshPrimitive->getPositionIndices().getData();
     unsigned int *verticesCountArray = 0;
     unsigned int vcount = 0;   //count of elements in the array containing the count of indices per polygon & polylist.
     
     if (shouldTriangulate) {
         unsigned int triangulatedIndicesCount = 0;
         //We have to upcast to polygon to retrieve the array of vertexCount
         //OpenCOLLADA use polylist as polygon.
         COLLADAFW::Polygons *polygon = (COLLADAFW::Polygons*)openCOLLADAMeshPrimitive;
         const COLLADAFW::Polygons::VertexCountArray& vertexCountArray = polygon->getGroupedVerticesVertexCountArray();
         vcount = (unsigned int)vertexCountArray.getCount();
         verticesCountArray = (unsigned int*)malloc(sizeof(unsigned int) * vcount);
         for (size_t i = 0; i < vcount; i++) {
             verticesCountArray[i] = polygon->getGroupedVerticesVertexCount(i);;
         }
         indices = createTrianglesFromPolylist(verticesCountArray, indices, vcount, &triangulatedIndicesCount);
         count = triangulatedIndicesCount;
     }
     
     shared_ptr <GLTFBufferView> positionBuffer = createBufferViewWithAllocatedBuffer(indices, 0, count * sizeof(unsigned int), shouldTriangulate ? true : false);
     
     shared_ptr <GLTF::GLTFIndices> positionIndices(new GLTF::GLTFIndices(positionBuffer,count));
     
     __AppendIndices(cvtPrimitive, primitiveIndicesVector, positionIndices, POSITION, 0);
     
     if (openCOLLADAMeshPrimitive->hasNormalIndices()) {
         unsigned int triangulatedIndicesCount = 0;
         indices = openCOLLADAMeshPrimitive->getNormalIndices().getData();
         if (shouldTriangulate) {
             indices = createTrianglesFromPolylist(verticesCountArray, indices, vcount, &triangulatedIndicesCount);
             count = triangulatedIndicesCount;
         }
         
         shared_ptr <GLTF::GLTFBufferView> normalBuffer = createBufferViewWithAllocatedBuffer(indices, 0, count * sizeof(unsigned int), shouldTriangulate ? true : false);
         shared_ptr <GLTF::GLTFIndices> normalIndices(new GLTF::GLTFIndices(normalBuffer,
                                                                            count));
         __AppendIndices(cvtPrimitive, primitiveIndicesVector, normalIndices, NORMAL, 0);
     }
     
     if (openCOLLADAMeshPrimitive->hasColorIndices()) {
         COLLADAFW::IndexListArray& colorListArray = openCOLLADAMeshPrimitive->getColorIndicesArray();
         for (size_t i = 0 ; i < colorListArray.getCount() ; i++) {
             COLLADAFW::IndexList* indexList = openCOLLADAMeshPrimitive->getColorIndices(i);
             __HandleIndexList(i,
                               indexList,
                               GLTF::COLOR,
                               shouldTriangulate,
                               count,
                               vcount,
                               verticesCountArray,
                               cvtPrimitive,
                               primitiveIndicesVector);
         }
     }
     
     if (openCOLLADAMeshPrimitive->hasUVCoordIndices()) {
         COLLADAFW::IndexListArray& uvListArray = openCOLLADAMeshPrimitive->getUVCoordIndicesArray();
         for (size_t i = 0 ; i < uvListArray.getCount() ; i++) {
             COLLADAFW::IndexList* indexList = openCOLLADAMeshPrimitive->getUVCoordIndices(i);
             __HandleIndexList(i,
                               indexList,
                               GLTF::TEXCOORD,
                               shouldTriangulate,
                               count,
                               vcount,
                               verticesCountArray,
                               cvtPrimitive,
                               primitiveIndicesVector);
         }
     }
     
     if (verticesCountArray) {
         free(verticesCountArray);
     }
     
     return cvtPrimitive;
 }