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