physxWrapper.cpp

00001 
00002 #include "main.h"
00003 #include "NXU_helper.h"
00004 #include "registry.h"
00005 #include "physxDebugHelper.h"
00006 #include "physxWrapper.h"
00007 
00008 
00009 
00010 // only visible within this file
00011 static NxDebugOutput*   nxDebugOutput   = NULL;
00012 static NxuDebugOutput*  nxuDebugOutput  = NULL;
00013 static NxuUserNotify*   nxuUserNotify   = NULL;
00014 
00015 
00016 // init physX and setup global symbols from main.h
00017 ERR_TYPE physxInit()
00018 {
00019         // check if physX is installed on this machine
00020         Registry reg;
00021         stringc corePath("");
00022         u32 version = 0;
00023         ERR_TYPE result = ERR_OK;
00024         stringc logOutput("");
00025         result = reg.queryValue( "SOFTWARE\\AGEIA Technologies", "PhysXCore Path", &corePath );
00026         if ( ERR_OK == result )
00027         {
00028                 logOutput = "Found PhysXCore Path: ";
00029                 logOutput += corePath;
00030                 logger->log( logOutput.c_str() );
00031         }
00032         result = reg.queryValue( "SOFTWARE\\AGEIA Technologies", "PhysX Version", &version );
00033         if ( ERR_OK == result )
00034         {
00035                 logOutput = "Found PhysX Version: ";
00036                 logOutput += version;
00037                 logger->log( logOutput.c_str() );
00038         }
00039 
00040         logOutput = "Compiled PhysX version = ";
00041         logOutput += NX_SDK_VERSION_MAJOR;
00042         logOutput += ".";
00043         logOutput += NX_SDK_VERSION_MINOR;
00044         logOutput += ".";
00045         logOutput += NX_SDK_VERSION_BUGFIX;
00046         logger->log( logOutput.c_str() );
00047 
00048         if ( ERR_OK != result )
00049         {
00050                 // physiX is not installed
00051                 logger->log( "PhysX is not installed..." );
00052                 {
00053                         // set fake "PhysXCore Path"
00054                         logger->log( "Trying to create temporary key in registry: HKEY_LOCAL_MACHINE\\SOFTWARE\\AGEIA Technologies\\PhysXCore Path" );
00055                         stringc key("SOFTWARE\\AGEIA Technologies");
00056                         stringc name("PhysXCore Path");
00057                         stringc value("");
00058                         reg.getProcessPath( &value );
00059                         result = reg.addValue( key.c_str(), name.c_str(), value.c_str() );
00060                         if ( ERR_OK != result )
00061                         {
00062                                 logger->log( "Failed to create fake-key: PhysXCore Path" );
00063                         }
00064                 }
00065                 {
00066                         // set fake "PhysX Version"
00067                         logger->log( "Trying to create temporary key in registry: HKEY_LOCAL_MACHINE\\SOFTWARE\\AGEIA Technologies\\PhysX Version" );
00068                         stringc key("SOFTWARE\\AGEIA Technologies");
00069                         stringc name("PhysX Version");
00070                         u32 value = 70625;      // seems to be some magic number :)
00071                         result = reg.addValue( key.c_str(), name.c_str(), value );
00072                         if ( ERR_OK != result )
00073                         {
00074                                 logger->log( "Failed to create fake-key: PhysX Version" );
00075                         }
00076                 }
00077                 {
00078                         // set fake "enableLocalPhysXCore"
00079                         logger->log( "Trying to create temporary key in registry: HKEY_LOCAL_MACHINE\\SOFTWARE\\AGEIA Technologies\\enableLocalPhysXCore" );
00080                         stringc key("SOFTWARE\\AGEIA Technologies");
00081                         stringc name("enableLocalPhysXCore");
00082                         u32 value = 1;
00083                         result = reg.addValue( key.c_str(), name.c_str(), value );
00084                         if ( ERR_OK != result )
00085                         {
00086                                 logger->log( "Failed to create fake-key: enableLocalPhysXCore" );
00087                         }
00088                 }
00089         }
00090 
00091     // Create the physics SDK
00092         NxUserAllocator* allocator = NULL;
00093         const NxPhysicsSDKDesc& desc = NxPhysicsSDKDesc();
00094         NxSDKCreateError errorCode = NXCE_NO_ERROR;
00095         
00096         nxDebugOutput = new NxDebugOutput();
00097 
00098         // searchs for several keys in: hkey_local_machine\software\ageia technologies
00099         // if not found errorCode is: NXCE_PHYSX_NOT_FOUND
00100         // and returns NULL
00101         nxSDK = NxCreatePhysicsSDK( NX_PHYSICS_SDK_VERSION,             // version 2.7.2
00102                                                                 allocator,
00103                                                                 nxDebugOutput,
00104                                                                 desc,
00105                                                                 &errorCode );
00106     if ( NULL == nxSDK )
00107     {
00108                 stringc error("*** physX createSDK() failed *** errorCode = ");
00109         error += errorCode;
00110 
00111         logger->log( error.c_str() );
00112 
00113         return ERR_PHYSX_INIT_FAILED;
00114     }
00115 
00116 
00117 
00118 #if(0) // below is replaced by XML file
00119         
00120         // Set physical parameters
00121     NxReal scale = 1.0f;   // scale is meters per PhysX units
00122     nxSDK->setParameter( NX_SKIN_WIDTH, 0.05f *(1.0f / scale) );
00123     nxSDK->setParameter( NX_DEFAULT_SLEEP_LIN_VEL_SQUARED, 1.41f * 1.41f * (1.0f/scale)*(1.0f/scale) );
00124     nxSDK->setParameter( NX_BOUNCE_THRESHOLD, -2.0f * (1.0f / scale) );
00125 
00126     // Set the debug visualization parameters
00127     nxSDK->setParameter( NX_VISUALIZATION_SCALE, 60.0f * (1.0f / scale) );
00128         nxSDK->setParameter( NX_VISUALIZE_COLLISION_SHAPES, 1 );
00129     nxSDK->setParameter( NX_VISUALIZE_ACTOR_AXES, 1 );
00130         nxSDK->setParameter( NX_VISUALIZE_COLLISION_FNORMALS, 1 );
00131         nxSDK->setParameter( NX_VISUALIZE_JOINT_LIMITS, 1 );
00132         nxSDK->setParameter( NX_VISUALIZE_JOINT_WORLD_AXES, 1 );
00133 
00134 #endif
00135 
00136 
00137 
00138         // setup XLM data error output handler
00139         nxuDebugOutput = new NxuDebugOutput();
00140         NXU::setErrorReport( nxuDebugOutput );
00141 
00142         // create XML create/preCreate/failed notification callback
00143         nxuUserNotify = new NxuUserNotify();
00144 
00145         // load XML data-driven scene
00146         NXU::NxuPhysicsCollection* nxuCollection = NULL;
00147         nxuCollection = NXU::loadCollection( "../../media/table_v5.xml", NXU::FT_XML );
00148         if ( NULL == nxuCollection )
00149         {
00150                 logger->log( "Failed loading PhysX XML dataset" );
00151                 return ERR_PHYSX_INIT_FAILED;
00152         }
00153 
00154         // create scene from XML data
00155         NxScene* dummyScene = NULL;
00156         NxMat34* dummyRootNode = NULL;
00157         bool status = NXU::instantiateCollection(       nxuCollection,
00158                                                                                                 *nxSDK,
00159                                                                                                 dummyScene,
00160                                                                                                 dummyRootNode,
00161                                                                                                 nxuUserNotify );
00162         if ( status != true )
00163         {
00164                 logger->log( "Cannot create NxScene from PhysX XML dataset" );
00165                 return ERR_PHYSX_INIT_FAILED;   
00166         }
00167 
00168         // get the XML created scene
00169         nxScene = nxSDK->getScene( 0 );
00170     if ( NULL == nxScene )
00171     {
00172         return ERR_PHYSX_INIT_FAILED;
00173     }
00174 
00175 
00176 #if(0)
00177         // dump some info about loaded actors
00178         u32 nActors = nxScene->getNbActors();
00179         NxActor** actors = nxScene->getActors();
00180         for (u32 i=0; i<nActors; i++)
00181         {
00182                 NxActor* tempActor = *actors;
00183                 stringc actorName( tempActor->getName() );
00184 
00185                 stringc info( "found actor[" );
00186                 info += i;
00187                 info += "] name=";
00188                 info += actorName;
00189                 info += "  mass=";
00190                 info += tempActor->getMass();
00191                 logger->log( info.c_str() );
00192 
00193                 if ( actorName.equals_ignore_case( "Box01" ) )
00194                 {
00195                                 // temp tweak
00196                                 //tempActor->setGlobalOrientation( 3*PI/2 );
00197                 }
00198 
00199                 *actors++;
00200         }
00201 #endif  
00202 
00203 
00204 #if(0)  // below is replaced by XML file
00205     
00206         // Create the scene
00207     NxSceneDesc sceneDesc;
00208 
00209         // set gravity
00210     sceneDesc.gravity = NxVec3(0.0f, -9.8f, 0.0f);;
00211 
00212         // we use software physics, no hardware accelerator
00213     sceneDesc.simType = NX_SIMULATION_SW;
00214 
00215         // setting proper scene bounds speeds up raycasts against dynamic actors
00216         NxBounds3 sceneBounds;
00217         sceneBounds.min = NxVec3( -1000.0f, -1000.0f, -1000.0f );       // 1k left from center, 1k down, 1k to user
00218         sceneBounds.max = NxVec3(  1000.0f,  1000.0f,  1000.0f );       // 1k right from center, 1k up, 1k into space
00219         sceneDesc.maxBounds = &sceneBounds;
00220         sceneDesc.boundsPlanes = true;
00221     
00222     nxScene = nxSDK->createScene(sceneDesc);
00223     if ( NULL == nxScene )
00224     {
00225         return ERR_PHYSX_INIT_FAILED;
00226     }
00227 
00228     // Create the default material
00229     NxMaterial* defaultMaterial = nxScene->getMaterialFromIndex( 0 );
00230     defaultMaterial->setRestitution( 0.5f );            // bounce of objects
00231     defaultMaterial->setStaticFriction( 0.5f );         // friction causes heat
00232     defaultMaterial->setDynamicFriction( 0.5f );
00233 
00234 #endif  // testing scene loading from XML dataset
00235 
00236 
00237         // iterate all found materials in XML and apply own settings
00238         for ( NxMaterialIndex i=0; i<nxScene->getHighestMaterialIndex(); i++ )
00239         {
00240                 NxMaterial* material = nxScene->getMaterialFromIndex( i );
00241                 if ( NULL != material )
00242                 {
00243                         material->setRestitution( 0.2f );               // bounce of objects
00244                         material->setStaticFriction( 0.1f );    // friction causes heat
00245                         material->setDynamicFriction( 0.1f );
00246                 }
00247         }
00248 
00249         // lets talk to physX remote debugger by socket communication
00250         nxSDK->getFoundationSDK().getRemoteDebugger()->connect( "localhost", 5425 );
00251 
00252     return ERR_OK;
00253 }
00254 
00255 
00256 // to be called every frame
00257 ERR_TYPE physxUpdate()
00258 {
00259     // Start collision and dynamics for delta time since the last frame
00260         nxScene->simulate( physxGetDeltaTime() / 100.0f );
00261     nxScene->flushStream();
00262 
00263         // Get results from nxScene->simulate(deltaTime)
00264         while ( ! nxScene->fetchResults(NX_RIGID_BODY_FINISHED, false) )
00265         {
00266                 // loops usually up to 20 times
00267         }
00268 
00269     return ERR_OK;
00270 }
00271 
00272 
00273 // destroy physX
00274 ERR_TYPE physxDeinit()
00275 {
00276     if ( nxScene && nxSDK )
00277     {
00278         //TODO GetPhysicsResults();  // Make sure to fetchResults() before shutting down
00279         nxSDK->releaseScene( *nxScene );
00280                 nxScene = NULL;
00281     }
00282     if ( nxSDK )
00283     {
00284         nxSDK->release();
00285                 nxSDK = NULL;
00286     }
00287         if ( nxDebugOutput )
00288         {
00289                 delete nxDebugOutput;
00290                 nxDebugOutput = NULL;
00291         }
00292         if ( nxuDebugOutput )
00293         {
00294                 delete nxuDebugOutput;
00295                 nxuDebugOutput = NULL;
00296         }
00297         if ( nxuUserNotify )
00298         {
00299                 delete nxuUserNotify;
00300                 nxuUserNotify = NULL;
00301         }
00302         
00303     return ERR_OK;
00304 }
00305 
00306 
00307 // returns milliseconds since last call
00308 u32 physxGetDeltaTime()
00309 {
00310         static u32 oldTime = timer->getRealTime();
00311 
00312     // Update the time step
00313         // getRealTime() is the irrlicht QueryPerformancCounter() Win32 imlpementation
00314         u32 now = timer->getRealTime();
00315         u32 deltaTime = now - oldTime;
00316         oldTime = now;
00317 
00318         return deltaTime;
00319 }

Generated on Sun Dec 2 03:10:23 2007 for TableTop by  doxygen 1.5.4