Panda3D
physxManager.cxx
1 // Filename: physxManager.cxx
2 // Created by: enn0x (01Sep09)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "physxManager.h"
16 #include "physxScene.h"
17 #include "physxSceneDesc.h"
18 
19 PhysxManager *PhysxManager::_global_ptr;
20 PhysxManager::PhysxOutputStream PhysxManager::_outputStream;
21 
22 ////////////////////////////////////////////////////////////////////
23 // Function: PhysxManager::Constructor
24 // Access: Protected
25 // Description:
26 ////////////////////////////////////////////////////////////////////
27 PhysxManager::
28 PhysxManager() {
29 
30  // Create PhysX SDK
31  NxSDKCreateError error;
32  NxPhysicsSDKDesc desc = NxPhysicsSDKDesc();
33 
34  _sdk = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, NULL, &_outputStream, desc, &error);
35 
36  if (error == NXCE_NO_ERROR) {
37  physx_cat.info() << "PhysX subsystem initialized. Number of PPUs="
38  << _sdk->getNbPPUs() << endl;
39  }
40  else {
41  physx_cat.error() << "Error when setting up the PhysX subsystem: "
42  << get_sdk_error_string(error) << endl;
43  _sdk = NULL;
44  }
45 
46  nassertv_always(error == NXCE_NO_ERROR);
47  nassertv_always(_sdk);
48 
49  // Set some default parameters
50  _sdk->setParameter(NX_VISUALIZATION_SCALE, 0.0f);
51  _sdk->setParameter(NX_VISUALIZE_COLLISION_SHAPES, true);
52  _sdk->setParameter(NX_VISUALIZE_ACTOR_AXES, true);
53  _sdk->setParameter(NX_VISUALIZE_BODY_LIN_VELOCITY, true);
54  _sdk->setParameter(NX_VISUALIZE_COLLISION_AABBS, false);
55  _sdk->setParameter(NX_VISUALIZE_COLLISION_VNORMALS, false);
56  _sdk->setParameter(NX_VISUALIZE_COLLISION_FNORMALS, false);
57  _sdk->setParameter(NX_VISUALIZE_FORCE_FIELDS, false);
58 
59  // Connect VDR
60  if(physx_want_vrd) {
61  physx_cat.info() << "Connecting to visual remote debugger at ("
62  << physx_vrd_host << ":"
63  << physx_vrd_port << ")" << endl;
64 
65  NxRemoteDebugger *debugger = _sdk->getFoundationSDK().getRemoteDebugger();
66 
67  debugger->connect(physx_vrd_host.c_str(),
68  physx_vrd_port);
69 
70  if (!debugger->isConnected()) {
71  physx_cat.warning() << "Could not connect to visual remot debugger!" << endl;
72  }
73  }
74 
75 }
76 
77 ////////////////////////////////////////////////////////////////////
78 // Function: PhysxManager::Destructor
79 // Access: Public
80 // Description:
81 ////////////////////////////////////////////////////////////////////
82 PhysxManager::
83 ~PhysxManager() {
84 
85  // Disconnect VRD
86  if(physx_want_vrd) {
87  NxRemoteDebugger *debugger = _sdk->getFoundationSDK().getRemoteDebugger();
88  if (!debugger->isConnected()) {
89  debugger->disconnect();
90  }
91  }
92 
93  // Release PhysX SDK
94  NxReleasePhysicsSDK(_sdk);
95 }
96 
97 ////////////////////////////////////////////////////////////////////
98 // Function: PhysxManager::get_global_ptr
99 // Access: Published
100 // Description: Returns a pointer to the global PhysxManager
101 // object.
102 ////////////////////////////////////////////////////////////////////
105 
106  if (_global_ptr == (PhysxManager *)NULL) {
107  _global_ptr = new PhysxManager;
108  }
109 
110  if (_global_ptr->_sdk == NULL) {
111  return NULL;
112  }
113  else {
114  return _global_ptr;
115  }
116 }
117 
118 ////////////////////////////////////////////////////////////////////
119 // Function: PhysxManager::get_num_scenes
120 // Access: Published
121 // Description:
122 ////////////////////////////////////////////////////////////////////
123 unsigned int PhysxManager::
124 get_num_scenes() const {
125 
126  return _sdk->getNbScenes();
127 }
128 
129 ////////////////////////////////////////////////////////////////////
130 // Function: PhysxManager::create_scene
131 // Access: Published
132 // Description:
133 ////////////////////////////////////////////////////////////////////
134 PhysxScene *PhysxManager::
135 create_scene(PhysxSceneDesc &sceneDesc) {
136 
137  nassertr(sceneDesc.is_valid(),NULL);
138 
139  //_desc.timeStepMethod = NX_TIMESTEP_FIXED;
140  //_desc.maxTimestep = 1.0f / 240.0f;
141  //_desc.maxIter = 8;
142 
143  sceneDesc._desc.flags |= NX_SF_ENABLE_ACTIVETRANSFORMS;
144  sceneDesc._desc.flags |= NX_SF_SIMULATE_SEPARATE_THREAD;
145 
146  if (physx_internal_threads > 0) {
147  sceneDesc._desc.flags |= NX_SF_ENABLE_MULTITHREAD;
148  sceneDesc._desc.threadMask=0xfffffffe;
149  sceneDesc._desc.internalThreadCount = physx_internal_threads;
150  physx_cat.info() << "Multithreading enabled. "
151  << "Additional threads: " << physx_internal_threads << endl;
152  }
153 
154  PhysxScene *scene = new PhysxScene();
155  nassertr(scene, NULL);
156 
157  NxScene *scenePtr = _sdk->createScene(sceneDesc._desc);
158  nassertr(scenePtr, NULL);
159 
160  scene->link(scenePtr);
161 
162  return scene;
163 }
164 
165 ////////////////////////////////////////////////////////////////////
166 // Function: PhysxManager::get_scene
167 // Access: Published
168 // Description:
169 ////////////////////////////////////////////////////////////////////
170 PhysxScene *PhysxManager::
171 get_scene(unsigned int idx) const {
172 
173  nassertr_always(idx < _sdk->getNbScenes(), NULL);
174 
175  NxScene *scenePtr = _sdk->getScene(idx);
176  PhysxScene *scene = (PhysxScene *)(scenePtr->userData);
177 
178  return scene;
179 }
180 
181 ////////////////////////////////////////////////////////////////////
182 // Function: PhysxManager::get_num_height_fields
183 // Access: Published
184 // Description:
185 ////////////////////////////////////////////////////////////////////
186 unsigned int PhysxManager::
187 get_num_height_fields() {
188 
189  return _sdk->getNbHeightFields();
190 }
191 
192 ////////////////////////////////////////////////////////////////////
193 // Function: PhysxManager::create_height_field
194 // Access: Published
195 // Description:
196 ////////////////////////////////////////////////////////////////////
197 PhysxHeightField *PhysxManager::
198 create_height_field(PhysxHeightFieldDesc &desc) {
199 
200  nassertr(desc.is_valid(),NULL);
201 
203  nassertr(hf, NULL);
204 
205  NxHeightField *hfPtr = _sdk->createHeightField(desc._desc);
206  nassertr(hfPtr, NULL);
207 
208  hf->link(hfPtr);
209 
210  return hf;
211 }
212 
213 ////////////////////////////////////////////////////////////////////
214 // Function: PhysxManager::get_height_field
215 // Access: Public
216 // Description:
217 ////////////////////////////////////////////////////////////////////
218 PhysxHeightField *PhysxManager::
219 get_height_field(unsigned int idx) {
220 
221  nassertr_always(idx < _sdk->getNbHeightFields(), NULL);
222 
223  return (PhysxHeightField *)_heightfields[idx];
224 }
225 
226 ////////////////////////////////////////////////////////////////////
227 // Function: PhysxManager::get_num_convex_meshes
228 // Access: Published
229 // Description:
230 ////////////////////////////////////////////////////////////////////
231 unsigned int PhysxManager::
232 get_num_convex_meshes() {
233 
234  return _sdk->getNbConvexMeshes();
235 }
236 
237 ////////////////////////////////////////////////////////////////////
238 // Function: PhysxManager::get_convex_mesh
239 // Access: Public
240 // Description:
241 ////////////////////////////////////////////////////////////////////
242 PhysxConvexMesh *PhysxManager::
243 get_convex_mesh(unsigned int idx) {
244 
245  nassertr_always(idx < _sdk->getNbConvexMeshes(), NULL);
246 
247  return (PhysxConvexMesh *)_convex_meshes[idx];
248 }
249 
250 ////////////////////////////////////////////////////////////////////
251 // Function: PhysxManager::get_num_triangle_meshes
252 // Access: Published
253 // Description:
254 ////////////////////////////////////////////////////////////////////
255 unsigned int PhysxManager::
256 get_num_triangle_meshes() {
257 
258  return _sdk->getNbTriangleMeshes();
259 }
260 
261 ////////////////////////////////////////////////////////////////////
262 // Function: PhysxManager::get_triangle_mesh
263 // Access: Public
264 // Description:
265 ////////////////////////////////////////////////////////////////////
266 PhysxTriangleMesh *PhysxManager::
267 get_triangle_mesh(unsigned int idx) {
268 
269  nassertr_always(idx < _sdk->getNbTriangleMeshes(), NULL);
270 
271  return (PhysxTriangleMesh *)_triangle_meshes[idx];
272 }
273 
274 ////////////////////////////////////////////////////////////////////
275 // Function: PhysxManager::get_num_cloth_meshes
276 // Access: Published
277 // Description:
278 ////////////////////////////////////////////////////////////////////
279 unsigned int PhysxManager::
280 get_num_cloth_meshes() {
281 
282  return _sdk->getNbClothMeshes();
283 }
284 
285 ////////////////////////////////////////////////////////////////////
286 // Function: PhysxManager::get_cloth_mesh
287 // Access: Public
288 // Description:
289 ////////////////////////////////////////////////////////////////////
290 PhysxClothMesh *PhysxManager::
291 get_cloth_mesh(unsigned int idx) {
292 
293  nassertr_always(idx < _sdk->getNbClothMeshes(), NULL);
294 
295  return (PhysxClothMesh *)_cloth_meshes[idx];
296 }
297 
298 ////////////////////////////////////////////////////////////////////
299 // Function: PhysxManager::get_num_soft_body_meshes
300 // Access: Published
301 // Description:
302 ////////////////////////////////////////////////////////////////////
303 unsigned int PhysxManager::
304 get_num_soft_body_meshes() {
305 
306  return _sdk->getNbSoftBodyMeshes();
307 }
308 
309 ////////////////////////////////////////////////////////////////////
310 // Function: PhysxManager::get_soft_body_mesh
311 // Access: Public
312 // Description:
313 ////////////////////////////////////////////////////////////////////
314 PhysxSoftBodyMesh *PhysxManager::
315 get_soft_body_mesh(unsigned int idx) {
316 
317  nassertr_always(idx < _sdk->getNbSoftBodyMeshes(), NULL);
318 
319  return (PhysxSoftBodyMesh *)_softbody_meshes[idx];
320 }
321 
322 ////////////////////////////////////////////////////////////////////
323 // Function: PhysxManager::get_num_ccd_skeletons
324 // Access: Published
325 // Description:
326 ////////////////////////////////////////////////////////////////////
327 unsigned int PhysxManager::
328 get_num_ccd_skeletons() {
329 
330  return _sdk->getNbCCDSkeletons();
331 }
332 
333 ////////////////////////////////////////////////////////////////////
334 // Function: PhysxManager::create_ccd_skeleton
335 // Access: Published
336 // Description:
337 ////////////////////////////////////////////////////////////////////
338 PhysxCcdSkeleton *PhysxManager::
339 create_ccd_skeleton(PhysxCcdSkeletonDesc &desc) {
340 
341  nassertr(desc.is_valid(), NULL);
342  nassertr(desc.get_desc().numVertices < 64, NULL);
343 
344  PhysxCcdSkeleton *skel = new PhysxCcdSkeleton();
345  nassertr(skel, NULL);
346 
347  NxCCDSkeleton *skelPtr = _sdk->createCCDSkeleton(desc.get_desc());
348  nassertr(skelPtr, NULL);
349 
350  skel->link(skelPtr);
351 
352  return skel;
353 }
354 
355 ////////////////////////////////////////////////////////////////////
356 // Function: PhysxManager::get_ccd_skeleton
357 // Access: Public
358 // Description:
359 ////////////////////////////////////////////////////////////////////
360 PhysxCcdSkeleton *PhysxManager::
361 get_ccd_skeleton(unsigned int idx) {
362 
363  nassertr_always(idx < _sdk->getNbCCDSkeletons(), NULL);
364 
365  return (PhysxCcdSkeleton *)_ccd_skeletons[idx];
366 }
367 
368 ////////////////////////////////////////////////////////////////////
369 // Function: PhysxManager::is_hardware_available
370 // Access: Published
371 // Description: Returns TRUE if a physcis hardware is available
372 // on the host system.
373 ////////////////////////////////////////////////////////////////////
374 bool PhysxManager::
376 
377  return _sdk->getHWVersion() != NX_HW_VERSION_NONE;
378 }
379 
380 ////////////////////////////////////////////////////////////////////
381 // Function: PhysxManager::get_num_ppus
382 // Access: Published
383 // Description: Reports the number of PPUs installed in the host
384 // system.
385 ////////////////////////////////////////////////////////////////////
386 unsigned int PhysxManager::
388 
389  return _sdk->getNbPPUs();
390 }
391 
392 ////////////////////////////////////////////////////////////////////
393 // Function: PhysxManager::get_hw_version
394 // Access: Published
395 // Description: Reports the available revision of the PhysX
396 // Hardware. Returns 0 if there is no hardware present
397 // in the machine, 1 for the PhysX Athena revision
398 // 1.0 card.
399 ////////////////////////////////////////////////////////////////////
400 unsigned int PhysxManager::
402 
403  return _sdk->getHWVersion();
404 }
405 
406 ////////////////////////////////////////////////////////////////////
407 // Function: PhysxManager::get_internal_version
408 // Access: Published
409 // Description: Reports the internal API version number of the SDK.
410 ////////////////////////////////////////////////////////////////////
411 const char *PhysxManager::
413 
414  NxU32 apiRev;
415  NxU32 descRev;
416  NxU32 branchId;
417  NxU32 v;
418 
419  v = _sdk->getInternalVersion(apiRev, descRev, branchId);
420 
421  stringstream version;
422  version << "version:" << (unsigned int)v
423  << " apiRef:" << (unsigned int)apiRev
424  << " descRev:" << (unsigned int)descRev
425  << " branchId: " << (unsigned int)branchId;
426 
427  return version.str().c_str();
428 }
429 
430 ////////////////////////////////////////////////////////////////////
431 // Function: PhysxManager::set_parameter
432 // Access: Published
433 // Description:
434 ////////////////////////////////////////////////////////////////////
435 void PhysxManager::
436 set_parameter(PhysxParameter param, float value) {
437 
438  _sdk->setParameter((NxParameter)param, value);
439 }
440 
441 ////////////////////////////////////////////////////////////////////
442 // Function: PhysxManager::get_parameter
443 // Access: Published
444 // Description:
445 ////////////////////////////////////////////////////////////////////
446 float PhysxManager::
447 get_parameter(PhysxParameter param) {
448 
449  return _sdk->getParameter((NxParameter)param);
450 }
451 
452 ////////////////////////////////////////////////////////////////////
453 // Function: PhysxManager::get_sdk_error_string
454 // Access: Private
455 // Description: Returns the NxSDKCreateError enum as string.
456 ////////////////////////////////////////////////////////////////////
457 const char *PhysxManager::
458 get_sdk_error_string(const NxSDKCreateError &error) {
459 
460  switch (error) {
461  case NXCE_NO_ERROR: return "NXCE_NO_ERROR"; break;
462  case NXCE_PHYSX_NOT_FOUND: return "NXCE_PHYSX_NOT_FOUND"; break;
463  case NXCE_WRONG_VERSION: return "NXCE_WRONG_VERSION"; break;
464  case NXCE_DESCRIPTOR_INVALID: return "NXCE_DESCRIPTOR_INVALID"; break;
465  case NXCE_CONNECTION_ERROR: return "NXCE_CONNECTION_ERROR"; break;
466  case NXCE_RESET_ERROR: return "NXCE_RESET_ERROR"; break;
467  case NXCE_IN_USE_ERROR: return "NXCE_IN_USE_ERROR"; break;
468  case NXCE_BUNDLE_ERROR: return "NXCE_BUNDLE_ERROR"; break;
469  default: return "Unknown error"; break;
470  }
471 }
472 
473 ////////////////////////////////////////////////////////////////////
474 // Function: PhysxOutputStream::reportError
475 // Access: Private
476 // Description: Reports an error code from the PhysX SDK.
477 ////////////////////////////////////////////////////////////////////
478 void PhysxManager::PhysxOutputStream::
479 reportError(NxErrorCode code, const char *message, const char *file, int line) {
480 
481  physx_cat.error() << get_error_code_string(code) << ": "
482  << message << endl;
483 }
484 
485 ////////////////////////////////////////////////////////////////////
486 // Function: PhysxOutputStream::get_error_code_string
487 // Access: Private
488 // Description: Returns the NxSDKCreateError enum as string.
489 ////////////////////////////////////////////////////////////////////
490 const char *PhysxManager::PhysxOutputStream::
491 get_error_code_string(NxErrorCode code) {
492 
493  switch (code) {
494  case NXE_NO_ERROR: return "NO_ERROR"; break;
495  case NXE_INVALID_PARAMETER: return "INVALID_PARAMETER"; break;
496  case NXE_INVALID_OPERATION: return "INVALID_OPERATION"; break;
497  case NXE_OUT_OF_MEMORY: return "OUT_OF_MEMORY"; break;
498  case NXE_INTERNAL_ERROR: return "INTERNAL_ERROR"; break;
499  case NXE_ASSERTION: return "ASSERTION"; break;
500  case NXE_DB_INFO: return "DB_INFO"; break;
501  case NXE_DB_WARNING: return "DB_WARNING"; break;
502  case NXE_DB_PRINT: return "DB_PRINT"; break;
503  default: return ""; break;
504  }
505 }
506 
507 ////////////////////////////////////////////////////////////////////
508 // Function: PhysxOutputStream::reportAssertViolation
509 // Access: Private
510 // Description: Reports an assertion violation from the PhysX SDK.
511 ////////////////////////////////////////////////////////////////////
512 NxAssertResponse PhysxManager::PhysxOutputStream::
513 reportAssertViolation(const char *message, const char *file, int line) {
514 
515  physx_cat.error() << "AssertViolation: " << message << endl;
516 
517  return NX_AR_CONTINUE;
518 }
519 
520 ////////////////////////////////////////////////////////////////////
521 // Function: PhysxOutputStream::print
522 // Access: Private
523 // Description: Prints some debug text from the PhysX SDK.
524 ////////////////////////////////////////////////////////////////////
525 void PhysxManager::PhysxOutputStream::
526 print(const char *message) {
527 
528  nout << message;
529 }
530 
Descriptor for PhysxScene.
The central interface to the PhysX subsystem.
Definition: physxManager.h:44
static PhysxManager * get_global_ptr()
Returns a pointer to the global PhysxManager object.
A scene is a collection of bodies, constraints, and effectors which can interact. ...
Definition: physxScene.h:73
bool is_hardware_available()
Returns TRUE if a physcis hardware is available on the host system.
bool is_valid() const
Returns true if the descriptor is valid.
unsigned int get_hw_version()
Reports the available revision of the PhysX Hardware.
Descriptor class for height fields.
unsigned int get_num_ppus()
Reports the number of PPUs installed in the host system.
A height field object.
const char * get_internal_version()
Reports the internal API version number of the SDK.
A Convex Mesh.
A Convex Mesh.
bool is_valid() const
Returns true if the descriptor is valid.
bool is_valid() const
Returns true if the descriptor is valid.