diff options
Diffstat (limited to 'APEX_1.4/shared/general/ConvexDecomposition/app/TestConvexDecomposition/TestConvexDecomposition.cpp')
| -rw-r--r-- | APEX_1.4/shared/general/ConvexDecomposition/app/TestConvexDecomposition/TestConvexDecomposition.cpp | 351 |
1 files changed, 351 insertions, 0 deletions
diff --git a/APEX_1.4/shared/general/ConvexDecomposition/app/TestConvexDecomposition/TestConvexDecomposition.cpp b/APEX_1.4/shared/general/ConvexDecomposition/app/TestConvexDecomposition/TestConvexDecomposition.cpp new file mode 100644 index 00000000..3eae80b9 --- /dev/null +++ b/APEX_1.4/shared/general/ConvexDecomposition/app/TestConvexDecomposition/TestConvexDecomposition.cpp @@ -0,0 +1,351 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2013 NVIDIA Corporation. All rights reserved. + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <math.h> +#include <conio.h> + +#pragma warning(disable:4996 4100) + +#include "ConvexDecomposition.h" +#include "wavefront.h" +#include "PxAllocatorCallback.h" +#include "PxErrorCallback.h" +#include "PsShare.h" +#include "PxFoundation.h" +#include "PsFoundation.h" + +namespace CONVEX_DECOMPOSITION +{ + ConvexDecomposition *gConvexDecomposition = NULL; +}; + +float getFloatArg(int arg,int argc,const char **argv) +{ + float ret = 0; + if ( arg < argc ) + { + ret = (float)atof(argv[arg]); + } + else + { + printf("Error: Missing input argument value at argument location %d.\r\n",arg+1); + } + return ret; +} + +int getIntArg(int arg,int argc,const char **argv) +{ + int ret = 0; + if ( arg < argc ) + { + ret = atoi(argv[arg]); + } + else + { + printf("Error: Missing input argument value at argument location %d.\r\n",arg+1); + } + return ret; +} + +class AppUserAllocator : public physx::PxAllocatorCallback +{ +public: + + virtual void* allocate(size_t size, const char * , const char* , int ) + { +#ifdef PX_WINDOWS + return ::_aligned_malloc(size, 16); +#else + return ::malloc(size); +#endif + } + + // this method needs to be removed + virtual void* allocate(size_t size, physx::PxU32 , const char* , int ) + { +#ifdef PX_WINDOWS + return ::_aligned_malloc(size, 16); +#else + return ::malloc(size); +#endif + } + + virtual void deallocate(void* ptr) + { +#ifdef PX_WINDOWS + ::_aligned_free(ptr); +#else + ::free(ptr); +#endif + } + +}; + +class AppUserOutputStream : public physx::PxErrorCallback +{ +public: + virtual void reportError(physx::PxErrorCode::Enum code, const char* message, const char* file, int line) + { + + } + +}; + + +static AppUserAllocator appAlloc; +static AppUserOutputStream appOutputStream; + +void main(int argc,const char ** argv) +{ + PX_UNUSED(argc); + PX_UNUSED(argv); + + physx::Foundation::createInstance(PX_PUBLIC_FOUNDATION_VERSION, appOutputStream, appAlloc); + + + if ( argc == 1 ) + { + printf("Usage: TestConvexDecomposition <wavefront.obj> (options)\r\n"); + printf("\r\n"); + printf("Options:\r\n"); + printf("\r\n"); + printf("-split : Tests mesh splitting.\r\n"); + printf("-plane A B C D : Specifies the plane equation to split the mesh by, if testing split only.\r\n"); + printf("-closed : Indicates that the mesh should be closed when it is split. Off by default; experimental.\r\n"); + printf("-depth <value> : Specify the convex decomposition depth.\r\n"); + printf("-merge <value> : Specify the merge threshold percentage. Reasonable ranges 0-10.\r\n"); + printf("-concavity <value> : Specify the concavity threshold as a percentage reasonable ranges 0-10.\r\n"); + printf("-hacd <concavity> <minCluster> : Use HACD (recommended). Specify the concavity value for HACD (default 100) and the mininum number of clusters (hulls)\r\n"); + printf("-connect : Is using HACD; this specifies the connectivity distance.\r\n"); + printf("-maxhullverts <v> : Specify the maxmium number of vertices in the output convex hulls.\r\n"); + } + else + { + const char *wavefront = argv[1]; + + bool splitOnly = false; + bool closed = false; + bool useHACD = false; + physx::PxF32 hacdConcavity = 100; + physx::PxU32 hacdMinClusterSize = 10; + physx::PxF32 connectionDistance = 0; + + physx::PxF32 plane[4] = { 1, 0, 0, 0 }; + physx::PxU32 depth = 5; + physx::PxF32 mergePercentage = 3; //1; + physx::PxF32 concavityPercentage = 3; //; + physx::PxU32 maxHullVerts = 64; + + int scan = 2; + while ( scan < argc ) + { + const char *option = argv[scan]; + if ( strcmp(option,"-split") == 0 ) + { + splitOnly = true; + printf("Testing a single split operation.\r\n"); + scan++; + } + else if ( strcmp(option,"-plane") == 0 ) + { + plane[0] = getFloatArg(scan+1,argc,argv); + plane[1] = getFloatArg(scan+2,argc,argv); + plane[2] = getFloatArg(scan+3,argc,argv); + plane[3] = getFloatArg(scan+4,argc,argv); + scan+=5; + } + else if ( strcmp(option,"-closed") == 0 ) + { + closed = true; + printf("Will produce closed split meshes.\r\n"); + scan++; + } + else if ( strcmp(option,"-depth") == 0 ) + { + depth = getIntArg(scan+1,argc,argv); + scan+=2; + } + else if ( strcmp(option,"-connect") == 0 ) + { + connectionDistance = getFloatArg(scan+1,argc,argv); + scan+=2; + } + else if ( strcmp(option,"-merge") == 0 ) + { + mergePercentage = getFloatArg(scan+1,argc,argv); + scan+=2; + } + else if ( strcmp(option,"-concavity") == 0 ) + { + concavityPercentage = getFloatArg(scan+1,argc,argv); + scan+=2; + } + else if ( strcmp(option,"-maxhullverts") == 0 ) + { + maxHullVerts = getIntArg(scan+1,argc,argv); + scan+=2; + } + else if ( strcmp(option,"-hacd")== 0) + { + useHACD = true; + hacdConcavity = getFloatArg(scan+1,argc,argv); + hacdMinClusterSize = getIntArg(scan+2,argc,argv); + scan+=3; + } + else + { + printf("Unknown option: %s\r\n", option ); + scan++; + } + + } + + CONVEX_DECOMPOSITION::gConvexDecomposition = CONVEX_DECOMPOSITION::createConvexDecomposition(); + if ( CONVEX_DECOMPOSITION::gConvexDecomposition ) + { + WavefrontObj obj; + unsigned int tcount = obj.loadObj(wavefront,false); + if ( tcount ) + { + if ( splitOnly ) + { + CONVEX_DECOMPOSITION::TriangleMesh input; + CONVEX_DECOMPOSITION::TriangleMesh left; + CONVEX_DECOMPOSITION::TriangleMesh right; + input.mVcount = obj.mVertexCount; + input.mVertices = obj.mVertices; + input.mTriCount = obj.mTriCount; + input.mIndices = (physx::PxU32 *)obj.mIndices; + CONVEX_DECOMPOSITION::gConvexDecomposition->splitMesh(plane,input,left,right,closed); + + if ( left.mTriCount ) + { + printf("Left Half of the split mesh has %d triangles. Saving as 'left.obj'\r\n", left.mTriCount); + WavefrontObj::saveObj("left.obj", left.mVcount, left.mVertices, left.mTriCount,(const int *) left.mIndices ); + } + else + { + printf("No triangles on the left half of the split mesh.\r\n"); + } + if ( right.mTriCount ) + { + printf("Left Half of the split mesh has %d triangles. Saving as 'right.obj'\r\n", right.mTriCount); + WavefrontObj::saveObj("right.obj", right.mVcount, right.mVertices, right.mTriCount, (const int *)right.mIndices ); + } + else + { + printf("No triangles on the right half of the split mesh.\r\n"); + } + + CONVEX_DECOMPOSITION::gConvexDecomposition->releaseTriangleMeshMemory(left); + CONVEX_DECOMPOSITION::gConvexDecomposition->releaseTriangleMeshMemory(right); + } + else + { + CONVEX_DECOMPOSITION::DecompDesc desc; + desc.mClosedSplit = closed; + desc.mDepth = depth; + desc.mCpercent = concavityPercentage; + desc.mPpercent = mergePercentage; + desc.mTcount = obj.mTriCount; + desc.mVcount = obj.mVertexCount; + desc.mVertices = obj.mVertices; + desc.mIndices = (physx::PxU32 *)obj.mIndices; + desc.mUseHACD = useHACD; + desc.mConcavityHACD = hacdConcavity; + desc.mMinClusterSizeHACD = hacdMinClusterSize; + desc.mConnectionDistanceHACD = connectionDistance; + + + printf("Performing convex decomposition.\r\n"); + + physx::PxU32 count = CONVEX_DECOMPOSITION::gConvexDecomposition->performConvexDecomposition(desc); + if ( count ) + { + printf("Produced %d output convex hulls.\r\n", count ); + FILE *fph = fopen("ConvexDecomposition.obj", "wb"); + if ( fph ) + { + fprintf(fph,"# Input mesh '%s' produced %d convex hulls.\r\n", wavefront, count ); + physx::PxU32 *baseVertex = new physx::PxU32[count]; + physx::PxU32 vertexCount = 0; + for (physx::PxU32 i=0; i<count; i++) + { + baseVertex[i] = vertexCount; + const CONVEX_DECOMPOSITION::ConvexResult &r = *CONVEX_DECOMPOSITION::gConvexDecomposition->getConvexResult(i); + fprintf(fph,"## Hull %d has %d vertices.\r\n", i+1, r.mHullVcount ); + for (physx::PxU32 i=0; i<r.mHullVcount; i++) + { + const physx::PxF32 *p = &r.mHullVertices[i*3]; + fprintf(fph,"v %0.9f %0.9f %0.9f\r\n", p[0], p[1], p[2] ); + } + vertexCount+=r.mHullVcount; + } + + for (physx::PxU32 i=0; i<count; i++) + { + const CONVEX_DECOMPOSITION::ConvexResult &r = *CONVEX_DECOMPOSITION::gConvexDecomposition->getConvexResult(i); + physx::PxU32 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, r.mHullTcount, r.mHullVcount, startVertex, r.mHullVolume ); + for (physx::PxU32 j=0; j<r.mHullTcount; j++) + { + physx::PxU32 i1 = r.mHullIndices[j*3+0]+startVertex+1; + physx::PxU32 i2 = r.mHullIndices[j*3+1]+startVertex+1; + physx::PxU32 i3 = r.mHullIndices[j*3+2]+startVertex+1; + fprintf(fph,"f %d %d %d\r\n", i1, i2, i3 ); + } + } + fclose(fph); + delete []baseVertex; + } + else + { + printf("Failed to open file 'ConvexDecomposition.obj' for output.\r\n"); + } + } + else + { + printf("Failed to produce any convex hull results!?\r\n"); + } + + } + } + else + { + printf("Failed to load Wavefront OBJ file '%s'\r\n",wavefront); + } + } + else + { + printf("Failed to load the convex decomposition plugin DLL.\r\n"); + } + } +} |