Example #1
0
// -----------------------------------------------------------------------
bool MyCloth::generateObjMeshDesc(NxClothMeshDesc &desc, char *filename, NxReal scale)
{
	WavefrontObj wo;
	wo.loadObj(filename);
	if (wo.mVertexCount == 0) return false;

	desc.numVertices				= wo.mVertexCount;
	desc.numTriangles				= wo.mTriCount;
	desc.pointStrideBytes			= sizeof(NxVec3);
	desc.triangleStrideBytes		= 3*sizeof(NxU32);
	desc.vertexMassStrideBytes		= sizeof(NxReal);
	desc.vertexFlagStrideBytes		= sizeof(NxU32);
	desc.points						= (NxVec3*)malloc(sizeof(NxVec3)*desc.numVertices);
	desc.triangles					= (NxU32*)malloc(sizeof(NxU32)*desc.numTriangles*3);
	desc.vertexMasses				= 0;
	desc.vertexFlags				= 0;
	desc.flags						= 0;

	// copy positions and indices
	NxVec3 *vSrc = (NxVec3*)wo.mVertices;
	NxVec3 *vDest = (NxVec3*)desc.points;
	for (int i = 0; i < wo.mVertexCount; i++, vDest++, vSrc++) 
		*vDest = (*vSrc)*scale; // resize
	memcpy((NxU32*)desc.triangles, wo.mIndices, sizeof(NxU32)*desc.numTriangles*3);
	return true;
}
Example #2
0
// -----------------------------------------------------------------------
bool MyCloth::generateObjMeshDesc(NxClothMeshDesc &desc, char *filename, NxReal scale, NxVec3* offset, bool textured)
{
	WavefrontObj wo;
	wo.loadObj(filename, textured);
	if (wo.mVertexCount == 0) return false;

	NxVec3 myOffset(0.f);
	if (offset != NULL)
		myOffset = *offset;

	desc.numVertices				= wo.mVertexCount;
	desc.numTriangles				= wo.mTriCount;
	desc.pointStrideBytes			= sizeof(NxVec3);
	desc.triangleStrideBytes		= 3*sizeof(NxU32);
	desc.vertexMassStrideBytes		= sizeof(NxReal);
	desc.vertexFlagStrideBytes		= sizeof(NxU32);
	desc.points						= (NxVec3*)malloc(sizeof(NxVec3)*desc.numVertices);
	desc.triangles					= (NxU32*)malloc(sizeof(NxU32)*desc.numTriangles*3);
	desc.vertexMasses				= 0;
	desc.vertexFlags				= 0;
	desc.flags						= NX_CLOTH_MESH_WELD_VERTICES;
	desc.weldingDistance			= 0.0001f;
	//desc.numHierarchyLevels         = 3; //no idea what is best here

	mMaxVertices = wo.mVertexCount;
	mMaxIndices  = 3 * wo.mTriCount;

	// copy positions and indices
	NxVec3 *vSrc = (NxVec3*)wo.mVertices;
	NxVec3 *vDest = (NxVec3*)desc.points;
	for (int i = 0; i < wo.mVertexCount; i++, vDest++, vSrc++) 
		*vDest = (*vSrc)*scale + myOffset;
	memcpy((NxU32*)desc.triangles, wo.mIndices, sizeof(NxU32)*desc.numTriangles*3);

	if (textured)
	{
		mNumTempTexCoords = desc.numVertices;
		mTempTexCoords = (GLfloat *)malloc(sizeof(GLfloat) * mNumTempTexCoords * 2);
		memcpy((NxU32*)mTempTexCoords, wo.mTexCoords, sizeof(GLfloat)*mNumTempTexCoords*2);

		mIndexRenderBuffer = (NxU32*)malloc(sizeof(NxU32) * mMaxIndices);
		memset(mIndexRenderBuffer, 0, sizeof(NxU32) * mMaxIndices);
		for (NxU32 i = 0; i < desc.numTriangles; i++)
		{
			assert((desc.flags & NX_CF_16_BIT_INDICES) == 0);
			NxU32* tri = (NxU32*)(((char*)desc.triangles) + (desc.triangleStrideBytes * i));
			mIndexRenderBuffer[3*i+0] = tri[0];
			mIndexRenderBuffer[3*i+1] = tri[1];
			mIndexRenderBuffer[3*i+2] = tri[2];
		}
	}
	else
	{
		mNumTempTexCoords = 0;
		mTempTexCoords = NULL;
	}

	return true;
}
Example #3
0
btCollisionShape* ObjLoader::loadObject(std::string filename, btScalar objectHeight)
{
	WavefrontObj wo;

	printf("load Obj\n");
	int tcount = wo.loadObj(filename.c_str());
	printf("loading done.\n");

	if(!tcount){
		printf("Error loading obj file %s\n",filename.c_str());
		// Handling
		return 0;
	} else {
		btTriangleMesh* trimesh = new btTriangleMesh();

		btVector3 localScaling(1.f,1.f,1.f);

		int i;
		for ( i=0;i<wo.mTriCount;i++)
		{
			int index0 = wo.mIndices[i*3];
			int index1 = wo.mIndices[i*3+1];
			int index2 = wo.mIndices[i*3+2];

			btVector3 vertex0(wo.mVertices[index0*3], wo.mVertices[index0*3+1],wo.mVertices[index0*3+2]);
			btVector3 vertex1(wo.mVertices[index1*3], wo.mVertices[index1*3+1],wo.mVertices[index1*3+2]);
			btVector3 vertex2(wo.mVertices[index2*3], wo.mVertices[index2*3+1],wo.mVertices[index2*3+2]);

			vertex0 *= localScaling;
			vertex1 *= localScaling;
			vertex2 *= localScaling;

			trimesh->addTriangle(vertex0,vertex1,vertex2);
		}


		btTransform startTransform;
		startTransform.setIdentity();
		startTransform.setOrigin(btVector3(0,2,14));

		btVector3 aabbMin, aabbMax;
		trimesh->calculateAabbBruteForce(aabbMin,aabbMax);
		float height = aabbMax.y() - aabbMin.y();

		float scaling = objectHeight/height;

		trimesh->setScaling(btVector3(scaling,scaling,scaling));

		bool useQuantization = false;
		btCollisionShape* concaveShape = new btBvhTriangleMeshShape(trimesh,useQuantization);

		return concaveShape;
//		return convexShape;

	}


}
Example #4
0
int main(int argc,const char ** argv)
{
	if ( argc == 1 )
	{
		printf("Usage: TestHACD <wavefront.obj> (options)\r\n");
		printf("\r\n");
		printf("Options:\r\n");
		printf("-v	<count>	: Max Hull Vertices (default 64)\r\n");
		printf("-m	<count>	: Maximum number of hulls output from HACD (default 256)\r\n");
		printf("-merge <count> : Maximum number of hulls after merging the HACD result.\r\n");
		printf("-mergethreshold <volume> : Threshold below which hulls are merged if they are smaller than the given volume.\r\n");
		printf("-c <concavity> : Between 0 and 1 are good ranges to try; default is 0.2.  The smaller the number, the more convex hulls are produced.\r\n");
		printf("-b <backFaceDistanceFactor : The back face distance factor, default is 0.2\r\n");
		printf("-t <threadCount> : Specifies the number of threads to use for a multi-threaded implementation\r\n");
		printf("-d <decompositionDepth> : Specifies the decomposition depth; uses legacy ACD instead of HACD\r\n");
		printf("-n : Normalize the input mesh.\r\n");
		printf("-f : Use legacy 'fast' version of HACD\r\n");
		printf("\r\n");
		printf("Example: TestHACD hornbug.obj -m 40 -v 64\r\n");
		printf("\r\n");
	}
	else
	{
		HACD::HACD_API::Desc desc;
		const char *wavefront = argv[1];
		int scan = 2;
		int threadCount = 0;


		while ( scan < argc )
		{
			const char *option = argv[scan];
			if ( strcmp(option,"-v") == 0 )
			{
				desc.mMaxHullVertices = getIntArg(scan+1,argc,argv);
				scan+=2;
			}
			else if ( strcmp(option,"-t") == 0 )
			{
				threadCount  = getIntArg(scan+1,argc,argv);
				scan+=2;
			}
			else if ( strcmp(option,"-d") == 0 )
			{
				desc.mDecompositionDepth  = getIntArg(scan+1,argc,argv);
				scan+=2;
			}
			else if ( strcmp(option,"-b") == 0 )
			{
				desc.mBackFaceDistanceFactor = getFloatArg(scan+1,argc,argv);
				scan+=2;
			}
			else if ( strcmp(option,"-m") == 0 )
			{
				desc.mMaxHullCount = getIntArg(scan+1,argc,argv);
				scan+=2;
			}
			else if ( strcmp(option,"-merge") == 0 )
			{
				desc.mMaxMergeHullCount = getIntArg(scan+1,argc,argv);
				scan+=2;
			}
			else if ( strcmp(option,"-mergethreshold") == 0 )
			{
				desc.mSmallClusterThreshold = getFloatArg(scan+1,argc,argv);
				scan+=2;
			}
			else if ( strcmp(option,"-c") == 0 )
			{
				desc.mConcavity = getFloatArg(scan+1,argc,argv);
				scan+=2;
			}
			else if ( strcmp(option,"-n") == 0 )
			{
				desc.mNormalizeInputMesh = true;
				scan++;
			}
			else if ( strcmp(option,"-f") == 0 )
			{
				desc.mUseFastVersion = true;
				scan++;
			}
			else
			{
				scan++;
			}
		}
		
		HACD::gHACD = HACD::createHACD_API();
		if  ( HACD::gHACD )
		{
			MyCallback callback;
			WavefrontObj obj;
			unsigned int tcount = obj.loadObj(wavefront,false);
			if ( tcount )
			{
				desc.mTriangleCount = obj.mTriCount;
				desc.mVertexCount = obj.mVertexCount;
				desc.mIndices = (hacd::HaU32 *)obj.mIndices;
				desc.mVertices = obj.mVertices;
			}
			desc.mCallback = static_cast<hacd::ICallback*>(&callback);
			if ( desc.mTriangleCount )
			{
				printf("Performing HACD on %d input triangles.\r\n", desc.mTriangleCount );
				printf("\r\n");
				printf("TriangleCount            : %d\r\n", desc.mTriangleCount );
				printf("VertexCount              : %d\r\n", desc.mVertexCount );
				printf("Concavity                : %0.2f\r\n", desc.mConcavity );
				printf("Max Hull Vertex Count    : %3d\r\n", desc.mMaxHullVertices );
				printf("Max Convex Hulls         : %3d\r\n", desc.mMaxHullCount );
				printf("Max Merged Convex Hulls  : %3d\r\n", desc.mMaxMergeHullCount );
				printf("Merge Threshold          : %0.2f\r\n", desc.mSmallClusterThreshold);
				printf("Back Face Distance Factor: %0.2f\r\n", desc.mBackFaceDistanceFactor );
				printf("Small Cluster Threshold  : %0.2f\r\n", desc.mSmallClusterThreshold );
				if ( desc.mDecompositionDepth )
				{
					printf("DecompositionDepth       : %d\r\n", desc.mDecompositionDepth );
				}

				if ( desc.mNormalizeInputMesh )
				{
					printf("Normalizing input mesh.\r\n");
				}

				if ( desc.mUseFastVersion )
				{
					printf("Using 'fast' version of HACD.\r\n");
				}

				printf("\r\n");

				desc.mJobSwarmContext = NULL;

				hacd::HaU32 hullCount = HACD::gHACD->performHACD(desc);

				if ( hullCount != 0 )
				{
					printf("\r\n");
					printf("Produced %d output convex hulls. Saving output to 'ConvexDecomposition.obj' for review.\r\n", hullCount );
					FILE *fph = fopen("ConvexDecomposition.obj", "wb");
					if ( fph )
					{
						fprintf(fph,"# Input mesh '%s' produced %d convex hulls.\r\n", wavefront, hullCount );
						hacd::HaU32 *baseVertex = new hacd::HaU32[hullCount];
						hacd::HaU32 vertexCount = 0;
						for (hacd::HaU32 i=0; i<hullCount; i++)
						{
							const HACD::HACD_API::Hull *hull = HACD::gHACD->getHull(i);
							if ( hull )
							{
								baseVertex[i] = vertexCount;
								fprintf(fph,"## Hull %d has %d vertices.\r\n", i+1, hull->mVertexCount );
								for (hacd::HaU32 i=0; i<hull->mVertexCount; i++)
								{
									const hacd::HaF32 *p = &hull->mVertices[i*3];
									fprintf(fph,"v %0.9f %0.9f %0.9f\r\n", p[0], p[1], p[2] );
								}
								vertexCount+=hull->mVertexCount;
							}
						}
						for (hacd::HaU32 i=0; i<hullCount; i++)
						{
							const HACD::HACD_API::Hull *hull = HACD::gHACD->getHull(i);
							if ( hull )
							{
								hacd::HaU32 startVertex = baseVertex[i];
								fprintf(fph,"# Convex Hull %d contains %d triangles and %d vertices.  Starting vertex index is: %d It has a volume of: %0.9f\r\n", i+1, hull->mTriangleCount, hull->mVertexCount, startVertex);
								fprintf(fph,"g convex_hull%d\r\n", i+1);
								for (hacd::HaU32 j=0; j<hull->mTriangleCount; j++)
								{
									hacd::HaU32 i1 = hull->mIndices[j*3+0]+startVertex+1;
									hacd::HaU32 i2 = hull->mIndices[j*3+1]+startVertex+1;
									hacd::HaU32 i3 = hull->mIndices[j*3+2]+startVertex+1;
									fprintf(fph,"f %d %d %d\r\n", i1, i2, i3 );
								}
							}
						}
					}
					else
					{
						printf("Failed to open output file.\r\n");
					}
				}
			}
			else
			{
				printf("Failed to load Wavefront OBJ file '%s'\r\n",wavefront);
			}
		}
		else
		{
			printf("Failed to load the HACD DLL\r\n");
		}
	}
	
	return 0;
}