Panda3D

physxManager.cxx

00001 // Filename: physxManager.cxx
00002 // Created by:  enn0x (01Sep09)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "physxManager.h"
00016 #include "physxScene.h"
00017 #include "physxSceneDesc.h"
00018 
00019 PhysxManager *PhysxManager::_global_ptr;
00020 PhysxManager::PhysxOutputStream PhysxManager::_outputStream;
00021 
00022 ////////////////////////////////////////////////////////////////////
00023 //     Function: PhysxManager::Constructor
00024 //       Access: Protected
00025 //  Description: 
00026 ////////////////////////////////////////////////////////////////////
00027 PhysxManager::
00028 PhysxManager() {
00029 
00030   // Create PhysX SDK
00031   NxSDKCreateError error;
00032   NxPhysicsSDKDesc desc = NxPhysicsSDKDesc();
00033 
00034   _sdk = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, NULL, &_outputStream, desc, &error);
00035 
00036   if (error == NXCE_NO_ERROR) {
00037     physx_cat.info() << "PhysX subsystem initialized. Number of PPUs="
00038                      << _sdk->getNbPPUs() << endl;
00039   }
00040   else {
00041     physx_cat.error() << "Error when setting up the PhysX subsystem: "
00042                       << get_sdk_error_string(error) << endl;
00043     _sdk = NULL;
00044   }
00045 
00046   nassertv_always(error == NXCE_NO_ERROR);
00047   nassertv_always(_sdk);
00048   
00049   // Set some default parameters
00050   _sdk->setParameter(NX_VISUALIZATION_SCALE, 0.0f);
00051   _sdk->setParameter(NX_VISUALIZE_COLLISION_SHAPES, true);
00052   _sdk->setParameter(NX_VISUALIZE_ACTOR_AXES, true);
00053   _sdk->setParameter(NX_VISUALIZE_BODY_LIN_VELOCITY, true);
00054   _sdk->setParameter(NX_VISUALIZE_COLLISION_AABBS, false);
00055   _sdk->setParameter(NX_VISUALIZE_COLLISION_VNORMALS, false);
00056   _sdk->setParameter(NX_VISUALIZE_COLLISION_FNORMALS, false);
00057   _sdk->setParameter(NX_VISUALIZE_FORCE_FIELDS, false);
00058 
00059   // Connect VDR
00060   if(physx_want_vrd) {
00061     physx_cat.info() << "Connecting to visual remote debugger at ("
00062                      << physx_vrd_host << ":"
00063                      << physx_vrd_port << ")" << endl;
00064 
00065     NxRemoteDebugger *debugger = _sdk->getFoundationSDK().getRemoteDebugger();
00066 
00067     debugger->connect(physx_vrd_host.c_str(),
00068                       physx_vrd_port);
00069 
00070     if (!debugger->isConnected()) {
00071       physx_cat.warning() << "Could not connect to visual remot debugger!" << endl;
00072     }
00073   }
00074 
00075 }
00076 
00077 ////////////////////////////////////////////////////////////////////
00078 //     Function: PhysxManager::Destructor
00079 //       Access: Public
00080 //  Description: 
00081 ////////////////////////////////////////////////////////////////////
00082 PhysxManager::
00083 ~PhysxManager() {
00084 
00085   // Disconnect VRD
00086   if(physx_want_vrd) {
00087     NxRemoteDebugger *debugger = _sdk->getFoundationSDK().getRemoteDebugger();
00088     if (!debugger->isConnected()) {
00089       debugger->disconnect();
00090     }
00091   }
00092 
00093   // Release PhysX SDK
00094   NxReleasePhysicsSDK(_sdk);
00095 }
00096 
00097 ////////////////////////////////////////////////////////////////////
00098 //     Function: PhysxManager::get_global_ptr
00099 //       Access: Published
00100 //  Description: Returns a pointer to the global PhysxManager
00101 //               object.
00102 ////////////////////////////////////////////////////////////////////
00103 PhysxManager *PhysxManager::
00104 get_global_ptr() {
00105 
00106   if (_global_ptr == (PhysxManager *)NULL) {
00107     _global_ptr = new PhysxManager;
00108   }
00109 
00110   if (_global_ptr->_sdk == NULL) {
00111     return NULL;
00112   }
00113   else {
00114     return _global_ptr;
00115   }
00116 }
00117 
00118 ////////////////////////////////////////////////////////////////////
00119 //     Function: PhysxManager::get_num_scenes
00120 //       Access: Published
00121 //  Description: 
00122 ////////////////////////////////////////////////////////////////////
00123 unsigned int PhysxManager::
00124 get_num_scenes() const {
00125 
00126   return _sdk->getNbScenes();
00127 }
00128 
00129 ////////////////////////////////////////////////////////////////////
00130 //     Function: PhysxManager::create_scene
00131 //       Access: Published
00132 //  Description:
00133 ////////////////////////////////////////////////////////////////////
00134 PhysxScene *PhysxManager::
00135 create_scene(PhysxSceneDesc &sceneDesc) {
00136 
00137   nassertr(sceneDesc.is_valid(),NULL);
00138 
00139   //_desc.timeStepMethod = NX_TIMESTEP_FIXED;
00140   //_desc.maxTimestep = 1.0f / 240.0f;
00141   //_desc.maxIter = 8;
00142 
00143   sceneDesc._desc.flags |= NX_SF_ENABLE_ACTIVETRANSFORMS;
00144   sceneDesc._desc.flags |= NX_SF_SIMULATE_SEPARATE_THREAD;
00145 
00146   if (physx_internal_threads > 0) {
00147     sceneDesc._desc.flags |= NX_SF_ENABLE_MULTITHREAD;
00148     sceneDesc._desc.threadMask=0xfffffffe;
00149     sceneDesc._desc.internalThreadCount = physx_internal_threads;
00150     physx_cat.info() << "Multithreading enabled. " 
00151                      << "Additional threads: " << physx_internal_threads << endl;
00152   }
00153 
00154   PhysxScene *scene = new PhysxScene();
00155   nassertr(scene, NULL);
00156 
00157   NxScene *scenePtr = _sdk->createScene(sceneDesc._desc);
00158   nassertr(scenePtr, NULL);
00159 
00160   scene->link(scenePtr);
00161 
00162   return scene;
00163 }
00164 
00165 ////////////////////////////////////////////////////////////////////
00166 //     Function: PhysxManager::get_scene
00167 //       Access: Published
00168 //  Description: 
00169 ////////////////////////////////////////////////////////////////////
00170 PhysxScene *PhysxManager::
00171 get_scene(unsigned int idx) const {
00172 
00173   nassertr_always(idx < _sdk->getNbScenes(), NULL);
00174 
00175   NxScene *scenePtr = _sdk->getScene(idx);
00176   PhysxScene *scene = (PhysxScene *)(scenePtr->userData);
00177 
00178   return scene;
00179 }
00180 
00181 ////////////////////////////////////////////////////////////////////
00182 //     Function: PhysxManager::get_num_height_fields
00183 //       Access: Published
00184 //  Description: 
00185 ////////////////////////////////////////////////////////////////////
00186 unsigned int PhysxManager::
00187 get_num_height_fields() {
00188 
00189   return _sdk->getNbHeightFields();
00190 }
00191 
00192 ////////////////////////////////////////////////////////////////////
00193 //     Function: PhysxManager::create_height_field
00194 //       Access: Published
00195 //  Description: 
00196 ////////////////////////////////////////////////////////////////////
00197 PhysxHeightField *PhysxManager::
00198 create_height_field(PhysxHeightFieldDesc &desc) {
00199 
00200   nassertr(desc.is_valid(),NULL);
00201 
00202   PhysxHeightField *hf = new PhysxHeightField();
00203   nassertr(hf, NULL);
00204 
00205   NxHeightField *hfPtr = _sdk->createHeightField(desc._desc);
00206   nassertr(hfPtr, NULL);
00207 
00208   hf->link(hfPtr);
00209 
00210   return hf;
00211 }
00212 
00213 ////////////////////////////////////////////////////////////////////
00214 //     Function: PhysxManager::get_height_field
00215 //       Access: Public
00216 //  Description: 
00217 ////////////////////////////////////////////////////////////////////
00218 PhysxHeightField *PhysxManager::
00219 get_height_field(unsigned int idx) {
00220 
00221   nassertr_always(idx < _sdk->getNbHeightFields(), NULL);
00222 
00223   return (PhysxHeightField *)_heightfields[idx];
00224 }
00225 
00226 ////////////////////////////////////////////////////////////////////
00227 //     Function: PhysxManager::get_num_convex_meshes
00228 //       Access: Published
00229 //  Description: 
00230 ////////////////////////////////////////////////////////////////////
00231 unsigned int PhysxManager::
00232 get_num_convex_meshes() {
00233 
00234   return _sdk->getNbConvexMeshes();
00235 }
00236 
00237 ////////////////////////////////////////////////////////////////////
00238 //     Function: PhysxManager::get_convex_mesh
00239 //       Access: Public
00240 //  Description: 
00241 ////////////////////////////////////////////////////////////////////
00242 PhysxConvexMesh *PhysxManager::
00243 get_convex_mesh(unsigned int idx) {
00244 
00245   nassertr_always(idx < _sdk->getNbConvexMeshes(), NULL);
00246 
00247   return (PhysxConvexMesh *)_convex_meshes[idx];
00248 }
00249 
00250 ////////////////////////////////////////////////////////////////////
00251 //     Function: PhysxManager::get_num_triangle_meshes
00252 //       Access: Published
00253 //  Description: 
00254 ////////////////////////////////////////////////////////////////////
00255 unsigned int PhysxManager::
00256 get_num_triangle_meshes() {
00257 
00258   return _sdk->getNbTriangleMeshes();
00259 }
00260 
00261 ////////////////////////////////////////////////////////////////////
00262 //     Function: PhysxManager::get_triangle_mesh
00263 //       Access: Public
00264 //  Description: 
00265 ////////////////////////////////////////////////////////////////////
00266 PhysxTriangleMesh *PhysxManager::
00267 get_triangle_mesh(unsigned int idx) {
00268 
00269   nassertr_always(idx < _sdk->getNbTriangleMeshes(), NULL);
00270 
00271   return (PhysxTriangleMesh *)_triangle_meshes[idx];
00272 }
00273 
00274 ////////////////////////////////////////////////////////////////////
00275 //     Function: PhysxManager::get_num_cloth_meshes
00276 //       Access: Published
00277 //  Description: 
00278 ////////////////////////////////////////////////////////////////////
00279 unsigned int PhysxManager::
00280 get_num_cloth_meshes() {
00281 
00282   return _sdk->getNbClothMeshes();
00283 }
00284 
00285 ////////////////////////////////////////////////////////////////////
00286 //     Function: PhysxManager::get_cloth_mesh
00287 //       Access: Public
00288 //  Description: 
00289 ////////////////////////////////////////////////////////////////////
00290 PhysxClothMesh *PhysxManager::
00291 get_cloth_mesh(unsigned int idx) {
00292 
00293   nassertr_always(idx < _sdk->getNbClothMeshes(), NULL);
00294 
00295   return (PhysxClothMesh *)_cloth_meshes[idx];
00296 }
00297 
00298 ////////////////////////////////////////////////////////////////////
00299 //     Function: PhysxManager::get_num_soft_body_meshes
00300 //       Access: Published
00301 //  Description: 
00302 ////////////////////////////////////////////////////////////////////
00303 unsigned int PhysxManager::
00304 get_num_soft_body_meshes() {
00305 
00306   return _sdk->getNbSoftBodyMeshes();
00307 }
00308 
00309 ////////////////////////////////////////////////////////////////////
00310 //     Function: PhysxManager::get_soft_body_mesh
00311 //       Access: Public
00312 //  Description: 
00313 ////////////////////////////////////////////////////////////////////
00314 PhysxSoftBodyMesh *PhysxManager::
00315 get_soft_body_mesh(unsigned int idx) {
00316 
00317   nassertr_always(idx < _sdk->getNbSoftBodyMeshes(), NULL);
00318 
00319   return (PhysxSoftBodyMesh *)_softbody_meshes[idx];
00320 }
00321 
00322 ////////////////////////////////////////////////////////////////////
00323 //     Function: PhysxManager::is_hardware_available
00324 //       Access: Published
00325 //  Description: Returns TRUE if a physcis hardware is available
00326 //               on the host system.
00327 ////////////////////////////////////////////////////////////////////
00328 bool PhysxManager::
00329 is_hardware_available() {
00330 
00331   return _sdk->getHWVersion() != NX_HW_VERSION_NONE;
00332 }
00333 
00334 ////////////////////////////////////////////////////////////////////
00335 //     Function: PhysxManager::get_num_ppus
00336 //       Access: Published
00337 //  Description: Reports the number of PPUs installed in the host
00338 //               system.
00339 ////////////////////////////////////////////////////////////////////
00340 unsigned int PhysxManager::
00341 get_num_ppus() {
00342 
00343   return _sdk->getNbPPUs();
00344 }
00345 
00346 ////////////////////////////////////////////////////////////////////
00347 //     Function: PhysxManager::get_hw_version
00348 //       Access: Published
00349 //  Description: Reports the available revision of the PhysX
00350 //               Hardware. Returns 0 if there is no hardware present
00351 //               in the machine, 1 for the PhysX Athena revision
00352 //               1.0 card.
00353 ////////////////////////////////////////////////////////////////////
00354 unsigned int PhysxManager::
00355 get_hw_version() {
00356 
00357   return _sdk->getHWVersion();
00358 }
00359 
00360 ////////////////////////////////////////////////////////////////////
00361 //     Function: PhysxManager::get_internal_version
00362 //       Access: Published
00363 //  Description: Reports the internal API version number of the SDK.
00364 ////////////////////////////////////////////////////////////////////
00365 const char *PhysxManager::
00366 get_internal_version() {
00367 
00368   NxU32 apiRev;
00369   NxU32 descRev;
00370   NxU32 branchId;
00371   NxU32 v;
00372 
00373   v = _sdk->getInternalVersion(apiRev, descRev, branchId);
00374 
00375   stringstream version;
00376   version << "version:" << (unsigned int)v
00377           << " apiRef:" << (unsigned int)apiRev
00378           << " descRev:" << (unsigned int)descRev
00379           << " branchId: " << (unsigned int)branchId;
00380 
00381   return version.str().c_str();
00382 }
00383 
00384 ////////////////////////////////////////////////////////////////////
00385 //     Function: PhysxManager::set_parameter
00386 //       Access: Published
00387 //  Description:
00388 ////////////////////////////////////////////////////////////////////
00389 void PhysxManager::
00390 set_parameter(PhysxParameter param, float value) {
00391 
00392   _sdk->setParameter((NxParameter)param, value);
00393 }
00394 
00395 ////////////////////////////////////////////////////////////////////
00396 //     Function: PhysxManager::get_parameter
00397 //       Access: Published
00398 //  Description:
00399 ////////////////////////////////////////////////////////////////////
00400 float PhysxManager::
00401 get_parameter(PhysxParameter param) {
00402 
00403   return _sdk->getParameter((NxParameter)param);
00404 }
00405 
00406 ////////////////////////////////////////////////////////////////////
00407 //     Function: PhysxManager::get_sdk_error_string
00408 //       Access: Private
00409 //  Description: Returns the NxSDKCreateError enum as string.
00410 ////////////////////////////////////////////////////////////////////
00411 const char *PhysxManager::
00412 get_sdk_error_string(const NxSDKCreateError &error) {
00413 
00414   switch (error) {
00415   case NXCE_NO_ERROR:           return "NXCE_NO_ERROR"; break;
00416   case NXCE_PHYSX_NOT_FOUND:    return "NXCE_PHYSX_NOT_FOUND"; break;
00417   case NXCE_WRONG_VERSION:      return "NXCE_WRONG_VERSION"; break;
00418   case NXCE_DESCRIPTOR_INVALID: return "NXCE_DESCRIPTOR_INVALID"; break;
00419   case NXCE_CONNECTION_ERROR:   return "NXCE_CONNECTION_ERROR"; break;
00420   case NXCE_RESET_ERROR:        return "NXCE_RESET_ERROR"; break;
00421   case NXCE_IN_USE_ERROR:       return "NXCE_IN_USE_ERROR"; break;
00422   case NXCE_BUNDLE_ERROR:       return "NXCE_BUNDLE_ERROR"; break;
00423   default:                      return "Unknown error"; break;
00424   }
00425 }
00426 
00427 ////////////////////////////////////////////////////////////////////
00428 //     Function: PhysxOutputStream::reportError
00429 //       Access: Private
00430 //  Description: Reports an error code from the PhysX SDK.
00431 ////////////////////////////////////////////////////////////////////
00432 void PhysxManager::PhysxOutputStream::
00433 reportError(NxErrorCode code, const char *message, const char *file, int line) {
00434 
00435   physx_cat.error() << get_error_code_string(code) << ": " 
00436                     << message << endl;
00437 }
00438 
00439 ////////////////////////////////////////////////////////////////////
00440 //     Function: PhysxOutputStream::get_error_code_string
00441 //       Access: Private
00442 //  Description: Returns the NxSDKCreateError enum as string.
00443 ////////////////////////////////////////////////////////////////////
00444 const char *PhysxManager::PhysxOutputStream::
00445 get_error_code_string(NxErrorCode code) {
00446   
00447   switch (code) {
00448   case NXE_NO_ERROR:           return "NO_ERROR"; break;
00449   case NXE_INVALID_PARAMETER:  return "INVALID_PARAMETER"; break;
00450   case NXE_INVALID_OPERATION:  return "INVALID_OPERATION"; break;
00451   case NXE_OUT_OF_MEMORY:      return "OUT_OF_MEMORY"; break;
00452   case NXE_INTERNAL_ERROR:     return "INTERNAL_ERROR"; break;
00453   case NXE_ASSERTION:          return "ASSERTION"; break;
00454   case NXE_DB_INFO:            return "DB_INFO"; break;
00455   case NXE_DB_WARNING:         return "DB_WARNING"; break;
00456   case NXE_DB_PRINT:           return "DB_PRINT"; break;
00457   default:                     return ""; break;
00458   }
00459 }
00460 
00461 ////////////////////////////////////////////////////////////////////
00462 //     Function: PhysxOutputStream::reportAssertViolation
00463 //       Access: Private
00464 //  Description: Reports an assertion violation from the PhysX SDK.
00465 ////////////////////////////////////////////////////////////////////
00466 NxAssertResponse PhysxManager::PhysxOutputStream::
00467 reportAssertViolation(const char *message, const char *file, int line) {
00468 
00469   physx_cat.error() << "AssertViolation: " << message << endl;
00470 
00471   return NX_AR_CONTINUE;
00472 }
00473 
00474 ////////////////////////////////////////////////////////////////////
00475 //     Function: PhysxOutputStream::print
00476 //       Access: Private
00477 //  Description: Prints some debug text from the PhysX SDK.
00478 ////////////////////////////////////////////////////////////////////
00479 void PhysxManager::PhysxOutputStream::
00480 print(const char *message) {
00481 
00482   nout << message;
00483 }
00484 
 All Classes Functions Variables Enumerations