Panda3D
physxScene.cxx
1 // Filename: physxScene.cxx
2 // Created by: enn0x (14Sep09)
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 "physxScene.h"
16 #include "physxManager.h"
17 #include "physxActorDesc.h"
18 #include "physxForceFieldDesc.h"
19 #include "physxForceFieldShapeGroupDesc.h"
20 #include "physxControllerDesc.h"
21 #include "physxSceneStats2.h"
22 #include "physxConstraintDominance.h"
23 #include "physxVehicle.h"
24 #include "physxVehicleDesc.h"
25 #include "physxCloth.h"
26 #include "physxClothDesc.h"
27 #include "physxSoftBody.h"
28 #include "physxSoftBodyDesc.h"
29 
30 TypeHandle PhysxScene::_type_handle;
31 
32 PStatCollector PhysxScene::_pcollector_fetch_results("App:PhysX:Fetch Results");
33 PStatCollector PhysxScene::_pcollector_update_transforms("App:PhysX:Update Transforms");
34 PStatCollector PhysxScene::_pcollector_debug_renderer("App:PhysX:Debug Renderer");
35 PStatCollector PhysxScene::_pcollector_simulate("App:PhysX:Simulate");
36 PStatCollector PhysxScene::_pcollector_cloth("App:PhysX:Cloth");
37 PStatCollector PhysxScene::_pcollector_softbody("App:PhysX:Softbody");
38 
39 ////////////////////////////////////////////////////////////////////
40 // Function: PhysxScene::link
41 // Access: Public
42 // Description:
43 ////////////////////////////////////////////////////////////////////
44 void PhysxScene::
45 link(NxScene *scenePtr) {
46 
47  // Link self
48  _ptr = scenePtr;
49  _ptr->userData = this;
50  _error_type = ET_ok;
51  PhysxManager::get_global_ptr()->_scenes.add(this);
52 
53  _cm = NxCreateControllerManager(NxGetPhysicsSDKAllocator());
54  nassertv_always(_cm);
55 
56  // Link materials
57  NxMaterial *materials[5];
58  NxU32 iterator = 0;
59 
60  while (NxU32 i=_ptr->getMaterialArray(materials, 5, iterator)) {
61  while(i--) {
62  PhysxMaterial *material = new PhysxMaterial();
63  material->link(materials[i]);
64  }
65  }
66 }
67 
68 ////////////////////////////////////////////////////////////////////
69 // Function: PhysxScene::unlink
70 // Access: Public
71 // Description:
72 ////////////////////////////////////////////////////////////////////
73 void PhysxScene::
74 unlink() {
75 
76  // Unlink vehicles
77  for (unsigned int i=0; i < _vehicles.size(); i++) {
78  _vehicles[i]->release();
79  }
80 
81  // Unlink controllers
82  NxU32 nControllers = _cm->getNbControllers();
83 
84  for (NxU32 i=0; i < nControllers; i++) {
85  NxController *controllerPtr = _cm->getController(i);
86  PhysxController *controller = (PhysxController *)controllerPtr->getUserData();
87  controller->unlink();
88  }
89 
90  // Unlink actors
91  NxActor **actors = _ptr->getActors();
92  NxU32 nActors = _ptr->getNbActors();
93 
94  for (NxU32 i=0; i < nActors; i++) {
95  PhysxActor *actor = (PhysxActor *)actors[i]->userData;
96 
97  // Actor could have already been unlinked by controller
98  if (actor) {
99  actor->unlink();
100  }
101  }
102 
103  // Unlink joints
104  NxU32 nJoints = _ptr->getNbJoints();
105 
106  _ptr->resetJointIterator();
107  for (NxU32 i=0; i < nJoints; i++) {
108  NxJoint *jointPtr = _ptr->getNextJoint();
109  PhysxJoint *joint = (PhysxJoint *)jointPtr->userData;
110  joint->unlink();
111  }
112 
113  // Unlink force fields
114  NxForceField **fields = _ptr->getForceFields();
115  NxU32 nFields = _ptr->getNbForceFields();
116 
117  for (NxU32 i=0; i < nFields; i++) {
118  PhysxForceField *field = (PhysxForceField *)fields[i]->userData;
119  field->unlink();
120  }
121 
122  // Unlink force field shape groups
123  NxU32 nGroups = _ptr->getNbForceFieldShapeGroups();
124 
125  _ptr->resetForceFieldShapeGroupsIterator();
126  for (NxU32 i=0; i < nGroups; i++) {
127  NxForceFieldShapeGroup *groupPtr = _ptr->getNextForceFieldShapeGroup();
128  PhysxForceFieldShapeGroup *group = (PhysxForceFieldShapeGroup *)groupPtr->userData;
129  group->unlink();
130  }
131 
132  // Unlink cloths
133  NxCloth **cloths = _ptr->getCloths();
134  NxU32 nCloths = _ptr->getNbCloths();
135 
136  for (NxU32 i=0; i < nCloths; i++) {
137  PhysxCloth *cloth = (PhysxCloth *)cloths[i]->userData;
138  cloth->unlink();
139  }
140 
141  // Unlink softbodies
142  NxSoftBody **softbodies = _ptr->getSoftBodies();
143  NxU32 nSoftbodies = _ptr->getNbSoftBodies();
144 
145  for (NxU32 i=0; i < nSoftbodies; i++) {
146  PhysxSoftBody *softbody = (PhysxSoftBody *)softbodies[i]->userData;
147  softbody->unlink();
148  }
149 
150  // Unlink materials
151  NxMaterial *materials[5];
152  NxU32 iterator = 0;
153 
154  while (NxU32 i=_ptr->getMaterialArray(materials, 5, iterator)) {
155  while(i--) {
156  PhysxMaterial *material = (PhysxMaterial *)materials[i]->userData;
157  material->unlink();
158  }
159  }
160 
161  // Unlink self
162  _cm->purgeControllers();
163  NxReleaseControllerManager(_cm);
164 
165  _ptr->userData = NULL;
166  _error_type = ET_released;
167 
168  PhysxManager::get_global_ptr()->_scenes.remove(this);
169 }
170 
171 ////////////////////////////////////////////////////////////////////
172 // Function: PhysxScene::release
173 // Access: Published
174 // Description:
175 ////////////////////////////////////////////////////////////////////
176 void PhysxScene::
177 release() {
178 
179  nassertv(_error_type == ET_ok);
180 
181  unlink();
182  NxPhysicsSDK *sdk = NxGetPhysicsSDK();
183  sdk->releaseScene(*_ptr);
184  _ptr = NULL;
185 }
186 
187 ////////////////////////////////////////////////////////////////////
188 // Function: PhysxScene::simulate
189 // Access: Published
190 // Description: Advances the simulation by an elapsedTime time.
191 // The elapsed time has to be in the range (0, inf).
192 //
193 // It is not allowed to modify the physics scene in
194 // between the simulate(dt) and the fetch_results
195 // calls! But it is allowed to read from the scene
196 // and do additional computations, e. g. AI, in
197 // between these calls.
198 ////////////////////////////////////////////////////////////////////
199 void PhysxScene::
200 simulate(float dt) {
201 
202  nassertv(_error_type == ET_ok);
203 
204  _pcollector_simulate.start();
205 
206  // Update all vehicles
207  for (unsigned int i=0; i < _vehicles.size(); i++) {
208  PhysxVehicle *vehicle = _vehicles[i];
209  vehicle->update_vehicle(dt);
210  }
211 
212  // Update all controllers
213  for (NxU32 i=0; i < _cm->getNbControllers(); i++) {
214  NxController *controllerPtr = _cm->getController(i);
215  PhysxController *controller = (PhysxController *)controllerPtr->getUserData();
216  controller->update_controller(dt);
217  }
218 
219  _cm->updateControllers();
220 
221  // Simulate and flush streams
222  _ptr->simulate(dt);
223  _ptr->flushStream();
224 
225  _pcollector_simulate.stop();
226 }
227 
228 ////////////////////////////////////////////////////////////////////
229 // Function: PhysxScene::fetch_results
230 // Access: Published
231 // Description: Waits until the simulation has finished, and then
232 // updates the scene graph with with simulation
233 // results.
234 //
235 // It is not allowed to modify the physics scene in
236 // between the simulate(dt) and the fetch_results
237 // calls! But it is allowed to read from the scene
238 // and do additional computations, e. g. AI, in
239 // between these calls.
240 ////////////////////////////////////////////////////////////////////
241 void PhysxScene::
243 
244  nassertv(_error_type == ET_ok);
245  nassertv(_ptr != NULL);
246 
247  _pcollector_fetch_results.start();
248  _ptr->fetchResults(NX_RIGID_BODY_FINISHED, true);
249  _pcollector_fetch_results.stop();
250 
251  // Update node transforms
252  _pcollector_update_transforms.start();
253 
254  NxU32 nbTransforms = 0;
255  NxActiveTransform *activeTransforms = _ptr->getActiveTransforms(nbTransforms);
256 
257  if (nbTransforms && activeTransforms) {
258  for (NxU32 i=0; i<nbTransforms; ++i) {
259 
260  // Objects created by the Visual Remote Debugger might not have
261  // user data. So check if user data ist set.
262  void *userData = activeTransforms[i].userData;
263  if (userData) {
264  LMatrix4f m = PhysxManager::nxMat34_to_mat4(activeTransforms[i].actor2World);
265  PhysxActor *actor = (PhysxActor *)userData;
266  actor->update_transform(m);
267  }
268  }
269  }
270  _pcollector_update_transforms.stop();
271 
272  // Update debug node
273  _pcollector_debug_renderer.start();
274  _debugNode->update(_ptr);
275  _pcollector_debug_renderer.stop();
276 
277  nassertv(_ptr->isWritable());
278 
279  // Update cloth nodes
280  _pcollector_cloth.start();
281 
282  NxCloth **cloths = _ptr->getCloths();
283  for (NxU32 i=0; i < _ptr->getNbCloths(); i++) {
284  PT(PhysxCloth) cloth = (PhysxCloth *)cloths[i]->userData;
285  cloth->update();
286  }
287 
288  _pcollector_cloth.stop();
289 
290  // Update softbody nodes
291  _pcollector_softbody.start();
292 
293  NxSoftBody **softbodies = _ptr->getSoftBodies();
294  for (NxU32 i=0; i < _ptr->getNbSoftBodies(); i++) {
295  PT(PhysxSoftBody) softbody = (PhysxSoftBody *)softbodies[i]->userData;
296  softbody->update();
297  }
298 
299  _pcollector_softbody.stop();
300 }
301 
302 ////////////////////////////////////////////////////////////////////
303 // Function: PhysxScene::set_timing_variable
304 // Access: Published
305 // Description: Sets simulation timing parameters used in simulate.
306 
307 ////////////////////////////////////////////////////////////////////
308 void PhysxScene::
310 
311  nassertv(_error_type == ET_ok);
312  _ptr->setTiming(0, 0, NX_TIMESTEP_VARIABLE);
313 }
314 
315 ////////////////////////////////////////////////////////////////////
316 // Function: PhysxScene::set_timing_fixed
317 // Access: Published
318 // Description: Sets simulation timing parameters used in simulate.
319 // The elapsed time (parameter "dt" in simulate()) is
320 // internally subdivided into up to maxIter substeps
321 // no larger than maxTimestep. If the elapsed time is
322 // not a multiple of maxTimestep then any remaining
323 // time is accumulated to be added onto the elapsed
324 // time for the next time step. If more sub steps than
325 // maxIter are needed to advance the simulation by
326 // elapsed time, then the remaining time is also
327 // accumulated for the next call to simulate().
328 //
329 // This timing method is strongly preferred for
330 // stable, reproducible simulation.
331 ////////////////////////////////////////////////////////////////////
332 void PhysxScene::
333 set_timing_fixed(float maxTimestep, unsigned int maxIter) {
334 
335  nassertv(_error_type == ET_ok);
336  _ptr->setTiming(maxTimestep, maxIter, NX_TIMESTEP_FIXED);
337 }
338 
339 ////////////////////////////////////////////////////////////////////
340 // Function: PhysxScene::set_gravity
341 // Access: Published
342 // Description: Sets a constant gravity for the entire scene.
343 ////////////////////////////////////////////////////////////////////
344 void PhysxScene::
345 set_gravity(const LVector3f &gravity) {
346 
347  nassertv(_error_type == ET_ok);
348  nassertv_always(!gravity.is_nan());
349 
350  _ptr->setGravity(PhysxManager::vec3_to_nxVec3(gravity));
351 }
352 
353 ////////////////////////////////////////////////////////////////////
354 // Function: PhysxScene::get_gravity
355 // Access: Published
356 // Description: Retrieves the current gravity setting.
357 ////////////////////////////////////////////////////////////////////
359 get_gravity() const {
360 
361  nassertr(_error_type == ET_ok, LVector3f::zero());
362 
363  NxVec3 gravity;
364  _ptr->getGravity(gravity);
365  return PhysxManager::nxVec3_to_vec3(gravity);
366 }
367 
368 ////////////////////////////////////////////////////////////////////
369 // Function: PhysxScene::get_num_actors
370 // Access: Published
371 // Description:
372 ////////////////////////////////////////////////////////////////////
373 unsigned int PhysxScene::
374 get_num_actors() const {
375 
376  nassertr(_error_type == ET_ok,-1);
377 
378  return _ptr->getNbActors();
379 }
380 
381 ////////////////////////////////////////////////////////////////////
382 // Function: PhysxScene::create_actor
383 // Access: Published
384 // Description:
385 ////////////////////////////////////////////////////////////////////
386 PhysxActor *PhysxScene::
387 create_actor(PhysxActorDesc &desc) {
388 
389  nassertr(_error_type == ET_ok, NULL);
390  nassertr(desc.is_valid(), NULL);
391 
392  PhysxActor *actor = new PhysxActor();
393  nassertr(actor, NULL);
394 
395  NxActor *actorPtr = _ptr->createActor(desc._desc);
396  nassertr(actorPtr, NULL);
397 
398  actor->link(actorPtr);
399 
400  return actor;
401 }
402 
403 ////////////////////////////////////////////////////////////////////
404 // Function: PhysxScene::get_actor
405 // Access: Published
406 // Description:
407 ////////////////////////////////////////////////////////////////////
408 PhysxActor *PhysxScene::
409 get_actor(unsigned int idx) const {
410 
411  nassertr(_error_type == ET_ok, NULL);
412  nassertr_always(idx < _ptr->getNbActors(), NULL);
413 
414  NxActor *actorPtr = _ptr->getActors()[idx];
415  PhysxActor *actor = (PhysxActor *)(actorPtr->userData);
416 
417  return actor;
418 }
419 
420 ////////////////////////////////////////////////////////////////////
421 // Function: PhysxScene::get_debug_node
422 // Access: Published
423 // Description: Retrieves the debug geom node for this scene. The
424 // debug geom node is used to visualize information
425 // about the physical scene which can be useful for
426 // debugging an application.
427 //
428 // The debug geom node geometry is generated in global
429 // coordinates. In order to see correct information
430 // it is important not to dislocate the debug node.
431 // Reparent it to render and leave position at
432 // (0,0,0).
433 ////////////////////////////////////////////////////////////////////
436 
437  nassertr(_error_type == ET_ok, NULL);
438  return _debugNode;
439 }
440 
441 ////////////////////////////////////////////////////////////////////
442 // Function: PhysxScene::enable_contact_reporting
443 // Access: Published
444 // Description:
445 ////////////////////////////////////////////////////////////////////
446 void PhysxScene::
447 enable_contact_reporting(bool enabled) {
448 
449  nassertv(_error_type == ET_ok);
450 
451  if (enabled) {
452  _ptr->setUserContactReport(&_contact_report);
453  _contact_report.enable();
454  }
455  else {
456  _ptr->setUserContactReport(NULL);
457  _contact_report.disable();
458  }
459 }
460 
461 ////////////////////////////////////////////////////////////////////
462 // Function: PhysxScene::is_contact_reporting_enabled
463 // Access: Published
464 // Description:
465 ////////////////////////////////////////////////////////////////////
466 bool PhysxScene::
467 is_contact_reporting_enabled() const {
468 
469  nassertr(_error_type == ET_ok, false);
470 
471  return _contact_report.is_enabled();
472 }
473 
474 ////////////////////////////////////////////////////////////////////
475 // Function: PhysxScene::enable_trigger_reporting
476 // Access: Published
477 // Description:
478 ////////////////////////////////////////////////////////////////////
479 void PhysxScene::
480 enable_trigger_reporting(bool enabled) {
481 
482  nassertv(_error_type == ET_ok);
483 
484  if (enabled) {
485  _ptr->setUserTriggerReport(&_trigger_report);
486  _trigger_report.enable();
487  }
488  else {
489  _ptr->setUserTriggerReport(NULL);
490  _trigger_report.disable();
491  }
492 }
493 
494 ////////////////////////////////////////////////////////////////////
495 // Function: PhysxScene::is_trigger_reporting_enabled
496 // Access: Published
497 // Description:
498 ////////////////////////////////////////////////////////////////////
499 bool PhysxScene::
500 is_trigger_reporting_enabled() const {
501 
502  nassertr(_error_type == ET_ok, false);
503 
504  return _trigger_report.is_enabled();
505 }
506 
507 ////////////////////////////////////////////////////////////////////
508 // Function: PhysxScene::enable_controller_reporting
509 // Access: Published
510 // Description:
511 ////////////////////////////////////////////////////////////////////
512 void PhysxScene::
513 enable_controller_reporting(bool enabled) {
514 
515  nassertv(_error_type == ET_ok);
516 
517  if (enabled) {
518  _controller_report.enable();
519  }
520  else {
521  _controller_report.disable();
522  }
523 }
524 
525 ////////////////////////////////////////////////////////////////////
526 // Function: PhysxScene::is_controller_reporting_enabled
527 // Access: Published
528 // Description:
529 ////////////////////////////////////////////////////////////////////
530 bool PhysxScene::
531 is_controller_reporting_enabled() const {
532 
533  nassertr(_error_type == ET_ok, false);
534 
535  return _controller_report.is_enabled();
536 }
537 
538 ////////////////////////////////////////////////////////////////////
539 // Function: PhysxScene::get_num_materials
540 // Access: Published
541 // Description: Return the number of materials in the scene.
542 //
543 // Note that the returned value is not related to
544 // material indices. Those may not be allocated
545 // continuously, and its values may be higher than
546 // get_num_materials(). This will also include the
547 // default material which exists without having to
548 // be created.
549 ////////////////////////////////////////////////////////////////////
550 unsigned int PhysxScene::
552 
553  nassertr(_error_type == ET_ok, -1);
554  return _ptr->getNbMaterials();
555 }
556 
557 ////////////////////////////////////////////////////////////////////
558 // Function: PhysxScene::create_material
559 // Access: Published
560 // Description: Creates a new PhysxMaterial.
561 //
562 // The material library consists of an array of
563 // material objects. Each material has a well defined
564 // index that can be used to refer to it. If an object
565 // references an undefined material, the default
566 // material with index 0 is used instead.
567 ////////////////////////////////////////////////////////////////////
570 
571  nassertr(_error_type == ET_ok, NULL);
572  nassertr(desc.is_valid(), NULL);
573 
574  PhysxMaterial *material = new PhysxMaterial();
575  nassertr(material, NULL);
576 
577  NxMaterial *materialPtr = _ptr->createMaterial(desc._desc);
578  nassertr(materialPtr, NULL);
579 
580  material->link(materialPtr);
581 
582  return material;
583 }
584 
585 ////////////////////////////////////////////////////////////////////
586 // Function: PhysxScene::create_material
587 // Access: Published
588 // Description: Creates a new PhysxMaterial using the default
589 // settings of PhysxMaterialDesc.
590 ////////////////////////////////////////////////////////////////////
593 
594  nassertr(_error_type == ET_ok, NULL);
595 
596  PhysxMaterial *material = new PhysxMaterial();
597  nassertr(material, NULL);
598 
599  NxMaterialDesc desc;
600  desc.setToDefault();
601  NxMaterial *materialPtr = _ptr->createMaterial(desc);
602  nassertr(materialPtr, NULL);
603 
604  material->link(materialPtr);
605 
606  return material;
607 }
608 
609 ////////////////////////////////////////////////////////////////////
610 // Function: PhysxScene::get_hightest_material_index
611 // Access: Published
612 // Description: Returns current highest valid material index.
613 //
614 // Note that not all indices below this are valid if
615 // some of them belong to meshes that have beed
616 // freed.
617 ////////////////////////////////////////////////////////////////////
618 unsigned int PhysxScene::
620 
621  nassertr(_error_type == ET_ok, -1);
622  return _ptr->getHighestMaterialIndex();
623 }
624 
625 ////////////////////////////////////////////////////////////////////
626 // Function: PhysxScene::get_material_from_index
627 // Access: Published
628 // Description: Retrieves the material with the given material
629 // index.
630 //
631 // There is always at least one material in the Scene,
632 // the default material (index 0). If the specified
633 // material index is out of range (larger than
634 // get_hightest_material_index) or belongs to a
635 // material that has been released, then the default
636 // material is returned, but no error is reported.
637 ////////////////////////////////////////////////////////////////////
639 get_material_from_index(unsigned int idx) const {
640 
641  nassertr(_error_type == ET_ok, NULL);
642 
643  NxMaterial *materialPtr = _ptr->getMaterialFromIndex(idx);
644 
645  return (PhysxMaterial *)(materialPtr->userData);
646 }
647 
648 ////////////////////////////////////////////////////////////////////
649 // Function: PhysxScene::get_material
650 // Access: Published
651 // Description: Retrieves the n-th material from the array of
652 // materials. See also get_material_from_index,
653 // which retrieves a material by it's material index.
654 ////////////////////////////////////////////////////////////////////
656 get_material(unsigned int idx) const {
657 
658  nassertr(_error_type == ET_ok, NULL);
659  nassertr_always(idx < _ptr->getNbMaterials(), NULL);
660 
661  NxU32 n = _ptr->getNbMaterials();
662  NxMaterial **materials = new NxMaterial *[n];
663  NxU32 materialCount;
664  NxU32 iterator = 0;
665 
666  materialCount = _ptr->getMaterialArray(materials, n, iterator);
667  nassertr((materialCount == n), NULL);
668 
669  NxMaterial *materialPtr = materials[idx];
670  delete[] materials;
671 
672  return (PhysxMaterial *)(materialPtr->userData);
673 }
674 
675 ////////////////////////////////////////////////////////////////////
676 // Function: PhysxScene::get_num_controllers
677 // Access: Published
678 // Description: Return the number of controllers in the scene.
679 ////////////////////////////////////////////////////////////////////
680 unsigned int PhysxScene::
682 
683  nassertr(_error_type == ET_ok, -1);
684  return _cm->getNbControllers();
685 }
686 
687 
688 ////////////////////////////////////////////////////////////////////
689 // Function: PhysxScene::create_controller
690 // Access: Published
691 // Description: Creates a new character controller.
692 ////////////////////////////////////////////////////////////////////
695 
696  nassertr(_error_type == ET_ok, NULL);
697  nassertr(desc.is_valid(), NULL);
698 
699  PhysxController *controller = PhysxController::factory(desc.ptr()->getType());
700  nassertr(controller, NULL);
701 
702  desc.ptr()->callback = &_controller_report;
703  desc.ptr()->userData = controller;
704 
705  NxController *controllerPtr = _cm->createController(_ptr,*desc.ptr());
706  nassertr(controllerPtr, NULL);
707 
708  controller->link(controllerPtr);
709  controller->get_actor()->set_name("");
710 
711  return controller;
712 }
713 
714 ////////////////////////////////////////////////////////////////////
715 // Function: PhysxScene::get_controller
716 // Access: Published
717 // Description: Retrieves the n-th controller within the scene.
718 ////////////////////////////////////////////////////////////////////
720 get_controller(unsigned int idx) const {
721 
722  nassertr(_error_type == ET_ok, NULL);
723  nassertr_always(idx < _cm->getNbControllers(), NULL);
724 
725  NxController *controllerPtr = _cm->getController(idx);
726  PhysxController *controller = (PhysxController *)(controllerPtr->getUserData());
727 
728  return controller;
729 }
730 
731 ////////////////////////////////////////////////////////////////////
732 // Function: PhysxScene::get_num_joints
733 // Access: Published
734 // Description: Returns the number of joints in the scene
735 // (excluding "dead" joints). Note that this includes
736 // compartments.
737 ////////////////////////////////////////////////////////////////////
738 unsigned int PhysxScene::
739 get_num_joints() const {
740 
741  nassertr(_error_type == ET_ok, -1);
742  return _ptr->getNbJoints();
743 }
744 
745 ////////////////////////////////////////////////////////////////////
746 // Function: PhysxScene::create_joint
747 // Access: Published
748 // Description: Creates a joint in this scene.
749 ////////////////////////////////////////////////////////////////////
752 
753  nassertr(_error_type == ET_ok, NULL);
754  nassertr(desc.is_valid(), NULL);
755 
756  PhysxJoint *joint = PhysxJoint::factory(desc.ptr()->getType());
757  nassertr(joint, NULL);
758 
759  NxJoint *jointPtr = _ptr->createJoint(*desc.ptr());
760  nassertr(jointPtr, NULL);
761 
762  joint->link(jointPtr);
763 
764  return joint;
765 }
766 
767 ////////////////////////////////////////////////////////////////////
768 // Function: PhysxScene::get_joint
769 // Access: Published
770 // Description: Retrieve the n-th joint from the array of all the
771 // joints in the scene.
772 ////////////////////////////////////////////////////////////////////
774 get_joint(unsigned int idx) const {
775 
776  nassertr(_error_type == ET_ok, NULL);
777  nassertr_always(idx < _ptr->getNbJoints(), NULL);
778 
779  NxJoint *jointPtr;
780  NxU32 nJoints = _ptr->getNbJoints();
781 
782  _ptr->resetJointIterator();
783  for (NxU32 i=0; i <= idx; i++) {
784  jointPtr = _ptr->getNextJoint();
785  }
786 
787  return (PhysxJoint *)(jointPtr->userData);
788 }
789 
790 ////////////////////////////////////////////////////////////////////
791 // Function: PhysxScene::get_num_force_fields
792 // Access: Published
793 // Description: Gets the number of force fields in the scene.
794 ////////////////////////////////////////////////////////////////////
795 unsigned int PhysxScene::
797 
798  nassertr(_error_type == ET_ok, -1);
799  return _ptr->getNbForceFields();
800 }
801 
802 ////////////////////////////////////////////////////////////////////
803 // Function: PhysxScene::create_force_field
804 // Access: Published
805 // Description: Creates a force field in this scene.
806 ////////////////////////////////////////////////////////////////////
809 
810  nassertr(_error_type == ET_ok, NULL);
811 
812  // Create the kernel
813  desc.create_kernel(_ptr);
814  nassertr(desc.is_valid(), NULL);
815 
816  // Create the force field
817  PhysxForceField *field = new PhysxForceField();
818  nassertr(field, NULL);
819 
820  NxForceField *fieldPtr = _ptr->createForceField(desc._desc);
821  nassertr(fieldPtr, NULL);
822 
823  field->link(fieldPtr);
824 
825  return field;
826 }
827 
828 ////////////////////////////////////////////////////////////////////
829 // Function: PhysxScene::get_force_field
830 // Access: Published
831 // Description: Returns the n-th force field from the array of
832 // all the force fields in the scene.
833 ////////////////////////////////////////////////////////////////////
835 get_force_field(unsigned int idx) const {
836 
837  nassertr(_error_type == ET_ok, NULL);
838  nassertr_always(idx < _ptr->getNbForceFields(), NULL);
839 
840  NxForceField **fields = _ptr->getForceFields();
841  NxForceField *fieldPtr = fields[idx];
842 
843  return (PhysxForceField *)(fieldPtr->userData);
844 }
845 
846 ////////////////////////////////////////////////////////////////////
847 // Function: PhysxScene::get_num_force_field_shape_groups
848 // Access: Published
849 // Description: Gets the number of force field shape groups in
850 // the scene.
851 ////////////////////////////////////////////////////////////////////
852 unsigned int PhysxScene::
854 
855  nassertr(_error_type == ET_ok, -1);
856  return _ptr->getNbForceFieldShapeGroups();
857 }
858 
859 ////////////////////////////////////////////////////////////////////
860 // Function: PhysxScene::create_force_field_shape_group
861 // Access: Published
862 // Description: Creates a new force field shape group in this
863 // scene.
864 ////////////////////////////////////////////////////////////////////
867 
868  nassertr(_error_type == ET_ok, NULL);
869 
871  nassertr(group, NULL);
872 
873  NxForceFieldShapeGroup *groupPtr = _ptr->createForceFieldShapeGroup(desc._desc);
874  nassertr(groupPtr, NULL);
875 
876  group->link(groupPtr);
877 
878  return group;
879 }
880 
881 ////////////////////////////////////////////////////////////////////
882 // Function: PhysxScene::get_force_field_shape_group
883 // Access: Published
884 // Description: Returns the n-th force field shape group in this
885 // scene
886 ////////////////////////////////////////////////////////////////////
888 get_force_field_shape_group(unsigned int idx) const {
889 
890  nassertr(_error_type == ET_ok, NULL);
891  nassertr_always(idx < _ptr->getNbForceFieldShapeGroups(), NULL);
892 
893  _ptr->resetForceFieldShapeGroupsIterator();
894  NxForceFieldShapeGroup *groupPtr = NULL;
895  idx++;
896  while (idx-- > 0) {
897  groupPtr = _ptr->getNextForceFieldShapeGroup();
898  }
899 
900  return groupPtr ? (PhysxForceFieldShapeGroup *)groupPtr->userData : NULL;
901 }
902 
903 ////////////////////////////////////////////////////////////////////
904 // Function: PhysxScene::get_num_cloths
905 // Access: Published
906 // Description: Gets the number of cloths in the scene.
907 ////////////////////////////////////////////////////////////////////
908 unsigned int PhysxScene::
909 get_num_cloths() const {
910 
911  nassertr(_error_type == ET_ok, -1);
912  return _ptr->getNbCloths();
913 }
914 
915 ////////////////////////////////////////////////////////////////////
916 // Function: PhysxScene::create_cloth
917 // Access: Published
918 // Description: Creates a cloth in this scene.
919 ////////////////////////////////////////////////////////////////////
922 
923  nassertr(_error_type == ET_ok, NULL);
924 
925  PhysxCloth *cloth = new PhysxCloth();
926  nassertr(cloth, NULL);
927 
928  NxCloth *clothPtr = _ptr->createCloth(desc._desc);
929  nassertr(clothPtr, NULL);
930 
931  cloth->link(clothPtr);
932 
933  return cloth;
934 }
935 
936 ////////////////////////////////////////////////////////////////////
937 // Function: PhysxScene::get_cloth
938 // Access: Published
939 // Description: Returns the n-th cloth from the array of
940 // all the cloths in the scene.
941 ////////////////////////////////////////////////////////////////////
943 get_cloth(unsigned int idx) const {
944 
945  nassertr(_error_type == ET_ok, NULL);
946  nassertr_always(idx < _ptr->getNbCloths(), NULL);
947 
948  NxCloth **cloths = _ptr->getCloths();
949  NxCloth *clothPtr = cloths[idx];
950 
951  return (PhysxCloth *)(clothPtr->userData);
952 }
953 
954 ////////////////////////////////////////////////////////////////////
955 // Function: PhysxScene::get_num_soft_bodies
956 // Access: Published
957 // Description: Gets the number of soft bodies in the scene.
958 ////////////////////////////////////////////////////////////////////
959 unsigned int PhysxScene::
961 
962  nassertr(_error_type == ET_ok, -1);
963  return _ptr->getNbSoftBodies();
964 }
965 
966 ////////////////////////////////////////////////////////////////////
967 // Function: PhysxScene::create_soft_body
968 // Access: Published
969 // Description: Creates a soft body in this scene.
970 ////////////////////////////////////////////////////////////////////
973 
974  nassertr(_error_type == ET_ok, NULL);
975 
976  PhysxSoftBody *softbody = new PhysxSoftBody();
977  nassertr(softbody, NULL);
978 
979  NxSoftBody *softbodyPtr = _ptr->createSoftBody(desc._desc);
980  nassertr(softbodyPtr, NULL);
981 
982  softbody->link(softbodyPtr);
983 
984  return softbody;
985 }
986 
987 ////////////////////////////////////////////////////////////////////
988 // Function: PhysxScene::get_soft_body
989 // Access: Published
990 // Description: Returns the n-th soft body from the array of
991 // all the soft bodies in the scene.
992 ////////////////////////////////////////////////////////////////////
994 get_soft_body(unsigned int idx) const {
995 
996  nassertr(_error_type == ET_ok, NULL);
997  nassertr_always(idx < _ptr->getNbSoftBodies(), NULL);
998 
999  NxSoftBody **softbodies = _ptr->getSoftBodies();
1000  NxSoftBody *softbodyPtr = softbodies[idx];
1001 
1002  return (PhysxSoftBody *)(softbodyPtr->userData);
1003 }
1004 
1005 ////////////////////////////////////////////////////////////////////
1006 // Function: PhysxScene::get_num_vehicles
1007 // Access: Published
1008 // Description: Returns the number of vehicles in the scene.
1009 ////////////////////////////////////////////////////////////////////
1010 unsigned int PhysxScene::
1012 
1013  nassertr(_error_type == ET_ok, -1);
1014  return _vehicles.size();
1015 }
1016 
1017 ////////////////////////////////////////////////////////////////////
1018 // Function: PhysxScene::create_vehicle
1019 // Access: Published
1020 // Description: Creates a vehicle in this scene.
1021 ////////////////////////////////////////////////////////////////////
1024 
1025  nassertr(_error_type == ET_ok, NULL);
1026  nassertr(desc.is_valid(), NULL);
1027 
1028  PhysxVehicle *vehicle = new PhysxVehicle();
1029  nassertr(vehicle, NULL);
1030 
1031  vehicle->create(this, desc);
1032 
1033  return vehicle;
1034 }
1035 
1036 ////////////////////////////////////////////////////////////////////
1037 // Function: PhysxScene::get_vehicle
1038 // Access: Published
1039 // Description: Returns the n-th vehicle from the array of all
1040 // the vehicles in the scene.
1041 ////////////////////////////////////////////////////////////////////
1043 get_vehicle(unsigned int idx) const {
1044 
1045  nassertr(_error_type == ET_ok, NULL);
1046  nassertr_always(idx < _vehicles.size(), NULL);
1047 
1048  return _vehicles[idx];
1049 }
1050 
1051 ////////////////////////////////////////////////////////////////////
1052 // Function: PhysxScene::get_stats2
1053 // Access: Published
1054 // Description:
1055 ////////////////////////////////////////////////////////////////////
1056 PhysxSceneStats2 PhysxScene::
1057 get_stats2() const {
1058 
1059  nassertr(_error_type == ET_ok, NULL);
1060  return PhysxSceneStats2(_ptr->getStats2());
1061 }
1062 
1063 ////////////////////////////////////////////////////////////////////
1064 // Function: PhysxScene::raycast_any_shape
1065 // Access: Published
1066 // Description: Returns true if any shape is intersected by the
1067 // ray.
1068 ////////////////////////////////////////////////////////////////////
1069 bool PhysxScene::
1071  PhysxShapesType shapesType,
1072  PhysxMask mask,
1073  PhysxGroupsMask *groups) const {
1074 
1075  nassertr(_error_type == ET_ok, false);
1076 
1077  NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
1078 
1079  return _ptr->raycastAnyShape(ray._ray, (NxShapesType)shapesType,
1080  mask.get_mask(), ray._length, groupsPtr);
1081 }
1082 
1083 ////////////////////////////////////////////////////////////////////
1084 // Function: PhysxScene::raycast_closest_shape
1085 // Access: Published
1086 // Description: Returns the first shape that is hit along the ray.
1087 // If not shape is hit then an empty raycast hit
1088 // is returned (is_empty() == true).
1089 ////////////////////////////////////////////////////////////////////
1092  PhysxShapesType shapesType,
1093  PhysxMask mask,
1094  PhysxGroupsMask *groups, bool smoothNormal) const {
1095 
1096  NxRaycastHit hit;
1097 
1098  nassertr(_error_type == ET_ok, hit);
1099 
1100  NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
1101 
1102  NxU32 hints = NX_RAYCAST_SHAPE | NX_RAYCAST_IMPACT | NX_RAYCAST_DISTANCE;
1103  if (smoothNormal == true) {
1104  hints |= NX_RAYCAST_NORMAL;
1105  }
1106  else {
1107  hints |= NX_RAYCAST_FACE_NORMAL;
1108  }
1109 
1110  _ptr->raycastClosestShape(ray._ray, (NxShapesType)shapesType, hit,
1111  mask.get_mask(), ray._length, hints, groupsPtr);
1112 
1113 
1114  return PhysxRaycastHit(hit);
1115 }
1116 
1117 ////////////////////////////////////////////////////////////////////
1118 // Function: PhysxScene::raycast_all_shapes
1119 // Access: Published
1120 // Description: Returns a PhysxRaycastReport object which can be
1121 // used to iterate over all shapes that have been
1122 // hit by the ray.
1123 ////////////////////////////////////////////////////////////////////
1126  PhysxShapesType shapesType,
1127  PhysxMask mask,
1128  PhysxGroupsMask *groups, bool smoothNormal) const {
1129 
1130  PhysxRaycastReport report;
1131 
1132  nassertr(_error_type == ET_ok, report);
1133 
1134  NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
1135 
1136  NxU32 hints = NX_RAYCAST_SHAPE | NX_RAYCAST_IMPACT | NX_RAYCAST_DISTANCE;
1137  if (smoothNormal == true) {
1138  hints |= NX_RAYCAST_NORMAL;
1139  }
1140  else {
1141  hints |= NX_RAYCAST_FACE_NORMAL;
1142  }
1143 
1144  _ptr->raycastAllShapes(ray._ray, report, (NxShapesType)shapesType,
1145  mask.get_mask(), ray._length, hints, groupsPtr);
1146 
1147  return report;
1148 }
1149 
1150 ////////////////////////////////////////////////////////////////////
1151 // Function: PhysxScene::raycast_any_bounds
1152 // Access: Published
1153 // Description: Returns true if any axis aligned bounding box
1154 // enclosing a shape is intersected by the ray.
1155 ////////////////////////////////////////////////////////////////////
1156 bool PhysxScene::
1158  PhysxShapesType shapesType,
1159  PhysxMask mask,
1160  PhysxGroupsMask *groups) const {
1161 
1162  nassertr(_error_type == ET_ok, false);
1163 
1164  NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
1165 
1166  return _ptr->raycastAnyBounds(ray._ray, (NxShapesType)shapesType,
1167  mask.get_mask(), ray._length, groupsPtr);
1168 }
1169 
1170 ////////////////////////////////////////////////////////////////////
1171 // Function: PhysxScene::raycast_closest_bounds
1172 // Access: Published
1173 // Description: Returns the first axis aligned bounding box
1174 // enclosing a shape that is hit along the ray.
1175 // If not shape is hit then an empty raycast hit
1176 // is returned (is_empty() == true).
1177 ////////////////////////////////////////////////////////////////////
1179 raycast_closest_bounds(const PhysxRay &ray, PhysxShapesType shapesType, PhysxMask mask, PhysxGroupsMask *groups, bool smoothNormal) const {
1180 
1181  NxRaycastHit hit;
1182 
1183  nassertr(_error_type == ET_ok, hit);
1184 
1185  NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
1186 
1187  NxU32 hints = NX_RAYCAST_SHAPE | NX_RAYCAST_IMPACT | NX_RAYCAST_DISTANCE;
1188  if (smoothNormal == true) {
1189  hints |= NX_RAYCAST_NORMAL;
1190  }
1191  else {
1192  hints |= NX_RAYCAST_FACE_NORMAL;
1193  }
1194 
1195  _ptr->raycastClosestBounds(ray._ray, (NxShapesType)shapesType, hit,
1196  mask.get_mask(), ray._length, hints, groupsPtr);
1197 
1198 
1199  return PhysxRaycastHit(hit);
1200 }
1201 
1202 ////////////////////////////////////////////////////////////////////
1203 // Function: PhysxScene::raycast_all_bounds
1204 // Access: Published
1205 // Description: Returns a PhysxRaycastReport object which can be
1206 // used to iterate over all shapes that have been
1207 // enclosed by axis aligned bounding boxes hit by
1208 // the ray.
1209 ////////////////////////////////////////////////////////////////////
1212  PhysxShapesType shapesType,
1213  PhysxMask mask,
1214  PhysxGroupsMask *groups, bool smoothNormal) const {
1215 
1216  PhysxRaycastReport report;
1217 
1218  nassertr(_error_type == ET_ok, report);
1219 
1220  NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
1221 
1222  NxU32 hints = NX_RAYCAST_SHAPE | NX_RAYCAST_IMPACT | NX_RAYCAST_DISTANCE;
1223  if (smoothNormal == true) {
1224  hints |= NX_RAYCAST_NORMAL;
1225  }
1226  else {
1227  hints |= NX_RAYCAST_FACE_NORMAL;
1228  }
1229 
1230  _ptr->raycastAllBounds(ray._ray, report, (NxShapesType)shapesType,
1231  mask.get_mask(), ray._length, hints, groupsPtr);
1232 
1233  return report;
1234 }
1235 
1236 ////////////////////////////////////////////////////////////////////
1237 // Function: PhysxScene::overlap_sphere_shapes
1238 // Access: Published
1239 // Description: Returns the set of shapes overlapped by the
1240 // world-space sphere.
1241 // You can test against static and/or dynamic objects
1242 // by adjusting 'shapeType'.
1243 ////////////////////////////////////////////////////////////////////
1245 overlap_sphere_shapes(const LPoint3f &center, float radius,
1246  PhysxShapesType shapesType,
1247  PhysxMask mask, bool accurateCollision) const {
1248 
1249  PhysxOverlapReport report;
1250 
1251  nassertr(_error_type == ET_ok, report);
1252 
1253  NxSphere worldSphere(PhysxManager::point3_to_nxVec3(center), radius);
1254 
1255  _ptr->overlapSphereShapes(worldSphere, (NxShapesType)shapesType, 0, NULL, &report,
1256  mask.get_mask(), NULL, accurateCollision);
1257 
1258  return report;
1259 }
1260 
1261 ////////////////////////////////////////////////////////////////////
1262 // Function: PhysxScene::overlap_capsule_shapes
1263 // Access: Published
1264 // Description: Returns the set of shapes overlapped by the
1265 // world-space capsule.
1266 // You can test against static and/or dynamic objects
1267 // by adjusting 'shapeType'.
1268 ////////////////////////////////////////////////////////////////////
1270 overlap_capsule_shapes(const LPoint3f &p0, const LPoint3f &p1, float radius,
1271  PhysxShapesType shapesType,
1272  PhysxMask mask, bool accurateCollision) const {
1273 
1274  PhysxOverlapReport report;
1275 
1276  nassertr(_error_type == ET_ok, report);
1277 
1278  NxSegment segment(PhysxManager::point3_to_nxVec3(p0),
1280  NxCapsule worldCapsule(segment, radius);
1281 
1282  _ptr->overlapCapsuleShapes(worldCapsule, (NxShapesType)shapesType, 0, NULL, &report,
1283  mask.get_mask(), NULL, accurateCollision);
1284 
1285  return report;
1286 }
1287 
1288 ////////////////////////////////////////////////////////////////////
1289 // Function: PhysxScene::set_actor_pair_flag
1290 // Access: Published
1291 // Description: Sets the pair flags for the given pair of actors.
1292 //
1293 // Calling this on an actor that has no shape(s) has
1294 // no effect. The two actor references must not
1295 // reference the same actor.
1296 //
1297 // It is important to note that the engine stores
1298 // pair flags per shape, even for actor pair flags.
1299 // This means that shapes should be created before
1300 // actor pair flags are set, otherwise the pair flags
1301 // will be ignored.
1302 ////////////////////////////////////////////////////////////////////
1303 void PhysxScene::
1305  PhysxContactPairFlag flag, bool value) {
1306 
1307  nassertv(_error_type == ET_ok);
1308 
1309  NxActor *ptrA = actorA.ptr();
1310  NxActor *ptrB = actorB.ptr();
1311  NxU32 flags = _ptr->getActorPairFlags(*ptrA, *ptrB);
1312 
1313  if (value == true) {
1314  flags |= flag;
1315  }
1316  else {
1317  flags &= ~(flag);
1318  }
1319 
1320  _ptr->setActorPairFlags(*ptrA, *ptrB, flags);
1321 }
1322 
1323 ////////////////////////////////////////////////////////////////////
1324 // Function: PhysxScene::get_actor_pair_flag
1325 // Access: Published
1326 // Description: Retrieves a single flag for the given pair of
1327 // actors.
1328 //
1329 // The two actor references must not reference the
1330 // same actor.
1331 ////////////////////////////////////////////////////////////////////
1332 bool PhysxScene::
1334  PhysxContactPairFlag flag) {
1335 
1336  nassertr(_error_type == ET_ok, false);
1337 
1338  NxActor *ptrA = actorA.ptr();
1339  NxActor *ptrB = actorB.ptr();
1340  NxU32 flags = _ptr->getActorPairFlags(*ptrA, *ptrB);
1341 
1342  return (flags && flag) ? true : false;
1343 }
1344 
1345 ////////////////////////////////////////////////////////////////////
1346 // Function: PhysxScene::set_shape_pair_flag
1347 // Access: Published
1348 // Description: Disables or enables contact generation for a pair
1349 // of shapes.
1350 //
1351 // The two shape references must not reference the
1352 // same shape.
1353 ////////////////////////////////////////////////////////////////////
1354 void PhysxScene::
1355 set_shape_pair_flag(PhysxShape &shapeA, PhysxShape &shapeB, bool value) {
1356 
1357  nassertv(_error_type == ET_ok);
1358 
1359  NxShape *ptrA = shapeA.ptr();
1360  NxShape *ptrB = shapeB.ptr();
1361  NxU32 flags = _ptr->getShapePairFlags(*ptrA, *ptrB);
1362 
1363  if (value == true) {
1364  flags |= NX_IGNORE_PAIR;
1365  }
1366  else {
1367  flags &= ~(NX_IGNORE_PAIR);
1368  }
1369 
1370  _ptr->setShapePairFlags(*ptrA, *ptrB, flags);
1371 }
1372 
1373 ////////////////////////////////////////////////////////////////////
1374 // Function: PhysxScene::get_shape_pair_flag
1375 // Access: Published
1376 // Description: Returns /true/ if contact generation between a pair
1377 // of shapes is enabled, and /false/ if contact
1378 // generation is disables.
1379 //
1380 // The two shape references must not reference the
1381 // same shape.
1382 ////////////////////////////////////////////////////////////////////
1383 bool PhysxScene::
1385 
1386  nassertr(_error_type == ET_ok, false);
1387 
1388  NxShape *ptrA = shapeA.ptr();
1389  NxShape *ptrB = shapeB.ptr();
1390  NxU32 flags = _ptr->getShapePairFlags(*ptrA, *ptrB);
1391 
1392  return (flags && NX_IGNORE_PAIR) ? true : false;
1393 }
1394 
1395 ////////////////////////////////////////////////////////////////////
1396 // Function: PhysxScene::set_actor_group_pair_flag
1397 // Access: Published
1398 // Description: With this method one can set contact reporting
1399 // flags between actors belonging to a pair of groups.
1400 //
1401 // It is possible to assign each actor to a group
1402 // using PhysxActor::set_group(). This is a different
1403 // set of groups from the shape groups despite the
1404 // similar name. Here up to 0xffff different groups
1405 // are permitted, With this method one can set
1406 // contact reporting flags between actors belonging
1407 // to a pair of groups.
1408 //
1409 // The following flags are permitted:
1410 // - CPF_start_touch
1411 // - CPF_end_touch
1412 // - CPF_touch
1413 // - CPF_start_touch_treshold
1414 // - CPF_end_touch_treshold
1415 // - CPF_touch_treshold
1416 //
1417 // Note that finer grain control of pairwise flags is
1418 // possible using the function
1419 // PhysxScene::set_actor_pair_flags().
1420 ////////////////////////////////////////////////////////////////////
1421 void PhysxScene::
1422 set_actor_group_pair_flag(unsigned int g1, unsigned int g2,
1423  PhysxContactPairFlag flag, bool value) {
1424 
1425  nassertv(_error_type == ET_ok);
1426 
1427  NxU32 flags = _ptr->getActorGroupPairFlags(g1, g2);
1428  if (value == true) {
1429  flags |= flag;
1430  }
1431  else {
1432  flags &= ~(flag);
1433  }
1434  _ptr->setActorGroupPairFlags(g1, g2, flags);
1435 }
1436 
1437 ////////////////////////////////////////////////////////////////////
1438 // Function: PhysxScene::get_actor_group_pair_flag
1439 // Access: Published
1440 // Description: Retrieves a single flag set with
1441 // PhysxScene::set_actor_group_pair_flag()
1442 ////////////////////////////////////////////////////////////////////
1443 bool PhysxScene::
1444 get_actor_group_pair_flag(unsigned int g1, unsigned int g2,
1445  PhysxContactPairFlag flag) {
1446 
1447  nassertr(_error_type == ET_ok, false);
1448  NxU32 flags = _ptr->getActorGroupPairFlags(g1, g2);
1449  return (flags && flag) ? true : false;
1450 }
1451 
1452 ////////////////////////////////////////////////////////////////////
1453 // Function: PhysxScene::set_filter_ops
1454 // Access: Published
1455 // Description: Setups filtering operations.
1456 ////////////////////////////////////////////////////////////////////
1457 void PhysxScene::
1458 set_filter_ops(PhysxFilterOp op0, PhysxFilterOp op1, PhysxFilterOp op2) {
1459 
1460  nassertv(_error_type == ET_ok);
1461  _ptr->setFilterOps((NxFilterOp)op0, (NxFilterOp)op1, (NxFilterOp)op2);
1462 }
1463 
1464 ////////////////////////////////////////////////////////////////////
1465 // Function: PhysxScene::set_filter_bool
1466 // Access: Published
1467 // Description: Setups filtering's boolean value.
1468 ////////////////////////////////////////////////////////////////////
1469 void PhysxScene::
1470 set_filter_bool(bool flag) {
1471 
1472  nassertv(_error_type == ET_ok);
1473  _ptr->setFilterBool(flag);
1474 }
1475 
1476 ////////////////////////////////////////////////////////////////////
1477 // Function: PhysxScene::set_filter_constant0
1478 // Access: Published
1479 // Description: Setups filtering's K0 value.
1480 ////////////////////////////////////////////////////////////////////
1481 void PhysxScene::
1483 
1484  nassertv(_error_type == ET_ok);
1485  _ptr->setFilterConstant0(mask.get_mask());
1486 }
1487 
1488 ////////////////////////////////////////////////////////////////////
1489 // Function: PhysxScene::set_filter_constant1
1490 // Access: Published
1491 // Description: Setups filtering's K1 value.
1492 ////////////////////////////////////////////////////////////////////
1493 void PhysxScene::
1495 
1496  nassertv(_error_type == ET_ok);
1497  _ptr->setFilterConstant1(mask.get_mask());
1498 }
1499 
1500 ////////////////////////////////////////////////////////////////////
1501 // Function: PhysxScene::get_filter_bool
1502 // Access: Published
1503 // Description: Retrieves filtering's boolean value.
1504 ////////////////////////////////////////////////////////////////////
1505 bool PhysxScene::
1507 
1508  nassertr(_error_type == ET_ok, false);
1509  return _ptr->getFilterBool();
1510 }
1511 
1512 ////////////////////////////////////////////////////////////////////
1513 // Function: PhysxScene::get_filter_constant0
1514 // Access: Published
1515 // Description: Gets filtering constant K0.
1516 ////////////////////////////////////////////////////////////////////
1519 
1520  PhysxGroupsMask mask;
1521 
1522  nassertr(_error_type == ET_ok, mask);
1523 
1524  NxGroupsMask _mask = ptr()->getFilterConstant0();
1525  mask.set_mask(_mask);
1526 
1527  return mask;
1528 }
1529 
1530 ////////////////////////////////////////////////////////////////////
1531 // Function: PhysxScene::get_filter_constant1
1532 // Access: Published
1533 // Description: Gets filtering constant K1.
1534 ////////////////////////////////////////////////////////////////////
1537 
1538  PhysxGroupsMask mask;
1539 
1540  nassertr(_error_type == ET_ok, mask);
1541 
1542  NxGroupsMask _mask = ptr()->getFilterConstant1();
1543  mask.set_mask(_mask);
1544 
1545  return mask;
1546 }
1547 
1548 ////////////////////////////////////////////////////////////////////
1549 // Function: PhysxScene::get_filter_op0
1550 // Access: Published
1551 // Description: Retrieves the op0 filtering operation.
1552 ////////////////////////////////////////////////////////////////////
1553 PhysxEnums::PhysxFilterOp PhysxScene::
1555 
1556  nassertr(_error_type == ET_ok, FO_and);
1557 
1558  NxFilterOp op0;
1559  NxFilterOp op1;
1560  NxFilterOp op2;
1561 
1562  _ptr->getFilterOps(op0, op1, op2);
1563 
1564  return (PhysxFilterOp)op0;
1565 }
1566 
1567 ////////////////////////////////////////////////////////////////////
1568 // Function: PhysxScene::get_filter_op1
1569 // Access: Published
1570 // Description: Retrieves the op1 filtering operation.
1571 ////////////////////////////////////////////////////////////////////
1572 PhysxEnums::PhysxFilterOp PhysxScene::
1574 
1575  nassertr(_error_type == ET_ok, FO_and);
1576 
1577  NxFilterOp op0;
1578  NxFilterOp op1;
1579  NxFilterOp op2;
1580 
1581  _ptr->getFilterOps(op0, op1, op2);
1582 
1583  return (PhysxFilterOp)op1;
1584 }
1585 
1586 ////////////////////////////////////////////////////////////////////
1587 // Function: PhysxScene::get_filter_op2
1588 // Access: Published
1589 // Description: Retrieves the op2 filtering operation.
1590 ////////////////////////////////////////////////////////////////////
1591 PhysxEnums::PhysxFilterOp PhysxScene::
1593 
1594  nassertr(_error_type == ET_ok, FO_and);
1595 
1596  NxFilterOp op0;
1597  NxFilterOp op1;
1598  NxFilterOp op2;
1599 
1600  _ptr->getFilterOps(op0, op1, op2);
1601 
1602  return (PhysxFilterOp)op2;
1603 }
1604 
1605 ////////////////////////////////////////////////////////////////////
1606 // Function: PhysxScene::set_group_collision_flag
1607 // Access: Published
1608 // Description: Specifies if collision should be performed by a
1609 // pair of shape groups.
1610 //
1611 // It is possible to assign each shape to a collision
1612 // groups using PhysxShape::set_group(). With this
1613 // method one can set whether collisions should be
1614 // detected between shapes belonging to a given pair
1615 // of groups. Initially all pairs are enabled.
1616 //
1617 // Fluids can be assigned to collision groups as well.
1618 //
1619 // Collision groups are integers between 0 and 31.
1620 ////////////////////////////////////////////////////////////////////
1621 void PhysxScene::
1622 set_group_collision_flag(unsigned int g1, unsigned int g2, bool enable) {
1623 
1624  nassertv(_error_type == ET_ok);
1625  nassertv(g1 >= 0 && g1 < 32);
1626  nassertv(g2 >= 0 && g2 < 32);
1627 
1628  _ptr->setGroupCollisionFlag((NxCollisionGroup)g1, (NxCollisionGroup)g2, enable);
1629 }
1630 
1631 ////////////////////////////////////////////////////////////////////
1632 // Function: PhysxScene::get_group_collision_flag
1633 // Access: Published
1634 // Description: Determines if collision detection is performed
1635 // between a pair of groups. Collision groups are
1636 // integers between 0 and 31.
1637 ////////////////////////////////////////////////////////////////////
1638 bool PhysxScene::
1639 get_group_collision_flag(unsigned int g1, unsigned int g2) {
1640 
1641  nassertr(_error_type == ET_ok, false);
1642  nassertr(g1 >= 0 && g1 < 32, false);
1643  nassertr(g2 >= 0 && g2 < 32, false);
1644 
1645  return _ptr->getGroupCollisionFlag((NxCollisionGroup)g1, (NxCollisionGroup)g2);
1646 }
1647 
1648 ////////////////////////////////////////////////////////////////////
1649 // Function: PhysxScene::get_flag
1650 // Access: Published
1651 // Description: Return the specified scene flag flag.
1652 ////////////////////////////////////////////////////////////////////
1653 bool PhysxScene::
1654 get_flag(PhysxSceneFlag flag) const {
1655 
1656  nassertr(_error_type == ET_ok, false);
1657  return (_ptr->getFlags() & flag) ? true : false;
1658 }
1659 
1660 ////////////////////////////////////////////////////////////////////
1661 // Function: PhysxScene::is_hardware_scene
1662 // Access: Published
1663 // Description: Returns TRUE if the the scene is simulated in
1664 // hardware. FALSE if the scene is simulated in
1665 // software.
1666 ////////////////////////////////////////////////////////////////////
1667 bool PhysxScene::
1669 
1670  nassertr(_error_type == ET_ok, false);
1671  return (_ptr->getSimType() & NX_SIMULATION_HW) ? true : false;
1672 }
1673 
1674 ////////////////////////////////////////////////////////////////////
1675 // Function: PhysxScene::set_dominance_group_pair
1676 // Access: Published
1677 // Description: Specifies the dominance behavior of constraints
1678 // between two actors with two certain dominance
1679 // groups.
1680 //
1681 // It is possible to assign each actor to a dominance
1682 // groups using PhysxActor::set_dominance_group().
1683 //
1684 // With dominance groups one can have all constraints
1685 // (contacts and joints) created between actors act in
1686 // one direction only. This is useful if you want to
1687 // make sure that the movement of the rider of a
1688 // vehicle or the pony tail of a character doesn't
1689 // influence the object it is attached to, while
1690 // keeping the motion of both inherently physical.
1691 //
1692 // Whenever a constraint (i.e. joint or contact)
1693 // between two actors (a0, a1) needs to be solved, the
1694 // groups (g0, g1) of both actors are retrieved. Then
1695 // the constraint dominance setting for this group
1696 // pair is retrieved.
1697 //
1698 // In the constraint, PhysxConstraintDominance::get_0()
1699 // becomes the dominance setting for a0, and
1700 // PhysxConstraintDominance::get_1() becomes the
1701 // dominance setting for a1. A dominance setting of
1702 // 1.0f, the default, will permit the actor to be
1703 // pushed or pulled by the other actor. A dominance
1704 // setting of 0.0f will however prevent the actor to
1705 // be pushed or pulled by the other actor. Thus, a
1706 // PhysxConstraintDominance of (1.0f, 0.0f) makes the
1707 // interaction one-way.
1708 //
1709 // The dominance matrix is initialised by default such
1710 // that:
1711 // - if g1 == g2, then (1.0f, 1.0f) is returned
1712 // - if g1 < g2, then (0.0f, 1.0f) is returned
1713 // - if g1 > g2, then (1.0f, 0.0f) is returned
1714 //
1715 // In other words, actors in higher groups can be
1716 // pushed around by actors in lower groups by default.
1717 //
1718 // These settings should cover most applications, and
1719 // in fact not overriding these settings may likely
1720 // result in higher performance.
1721 //
1722 // Dominance settings are currently specified as
1723 // floats 0.0f or 1.0f because in the future PhysX may
1724 // permit arbitrary fractional settings to express
1725 // 'partly-one-way' interactions.
1726 ////////////////////////////////////////////////////////////////////
1727 void PhysxScene::
1728 set_dominance_group_pair(unsigned int g1, unsigned int g2, PhysxConstraintDominance dominance ) {
1729 
1730  nassertv(_error_type == ET_ok);
1731  nassertv(g1 < 32);
1732  nassertv(g2 < 32);
1733 
1734  NxConstraintDominance d = dominance.get_dominance();
1735  _ptr->setDominanceGroupPair((NxDominanceGroup)g1, (NxDominanceGroup)g2, d);
1736 }
1737 
1738 ////////////////////////////////////////////////////////////////////
1739 // Function: PhysxScene::get_dominance_group_pair
1740 // Access: Published
1741 // Description: Samples the dominance matrix.
1742 ////////////////////////////////////////////////////////////////////
1744 get_dominance_group_pair(unsigned int g1, unsigned int g2) {
1745 
1746  PhysxConstraintDominance result(1.0f, 1.0f);
1747 
1748  nassertr(_error_type == ET_ok, result);
1749  nassertr(g1 < 32, result);
1750  nassertr(g2 < 32, result);
1751 
1752  result.set_dominance(_ptr->getDominanceGroupPair((NxDominanceGroup)g1, (NxDominanceGroup)g2));
1753  return result;
1754 }
1755 
1756 ////////////////////////////////////////////////////////////////////
1757 // Function: PhysxScene::get_wheel_shape_material
1758 // Access: Published
1759 // Description: Gets the shared material for all wheel shapes.
1760 //
1761 // If this material is not already created then
1762 // calling this method will create the material.
1763 //
1764 // Normally users don't need to call this method. It
1765 // is used internally by PhysWheel::create_wheel.
1766 ////////////////////////////////////////////////////////////////////
1769 
1770  nassertr(_error_type == ET_ok, NULL);
1771 
1772  if (_wheelShapeMaterial == NULL) {
1773  PhysxMaterialDesc materialDesc;
1774  materialDesc.set_flag(PhysxMaterialDesc::MF_disable_friction, true);
1775  _wheelShapeMaterial = create_material(materialDesc);
1776  }
1777 
1778  return _wheelShapeMaterial;
1779 }
1780 
Objects of this class are returned by the &#39;overlap shape&#39; methods, for example overlapSphereShapes.
bool get_group_collision_flag(unsigned int g1, unsigned int g2)
Determines if collision detection is performed between a pair of groups.
Descriptor class for materials.
PhysxMaterial * get_wheel_shape_material()
Gets the shared material for all wheel shapes.
PhysxRaycastHit raycast_closest_shape(const PhysxRay &ray, PhysxShapesType shapesType=ST_all, PhysxMask mask=PhysxMask::all_on(), PhysxGroupsMask *groups=NULL, bool smoothNormal=true) const
Returns the first shape that is hit along the ray.
void set_filter_constant1(const PhysxGroupsMask &mask)
Setups filtering&#39;s K1 value.
PhysxVehicle * get_vehicle(unsigned int idx) const
Returns the n-th vehicle from the array of all the vehicles in the scene.
PhysxRaycastReport raycast_all_bounds(const PhysxRay &ray, PhysxShapesType shapesType=ST_all, PhysxMask mask=PhysxMask::all_on(), PhysxGroupsMask *groups=NULL, bool smoothNormal=true) const
Returns a PhysxRaycastReport object which can be used to iterate over all shapes that have been enclo...
unsigned int get_num_materials() const
Return the number of materials in the scene.
Definition: physxScene.cxx:551
void set_group_collision_flag(unsigned int g1, unsigned int g2, bool enable)
Specifies if collision should be performed by a pair of shape groups.
unsigned int get_num_joints() const
Returns the number of joints in the scene (excluding "dead" joints).
Definition: physxScene.cxx:739
unsigned int get_num_force_fields() const
Gets the number of force fields in the scene.
Definition: physxScene.cxx:796
void set_flag(PhysxMaterialFlag flag, bool value)
Sets flags which control the behavior of a material.
bool is_valid() const
Returns true if the descriptor is valid.
unsigned int get_num_soft_bodies() const
Gets the number of soft bodies in the scene.
Definition: physxScene.cxx:960
PhysxGroupsMask get_filter_constant1() const
Gets filtering constant K1.
static PhysxManager * get_global_ptr()
Returns a pointer to the global PhysxManager object.
static NxVec3 point3_to_nxVec3(const LPoint3f &p)
Converts from LPoint3f to NxVec3.
Definition: physxManager.I:77
Abstract base class for the different types of joints.
Definition: physxJoint.h:35
bool is_valid() const
Returns true if the descriptor is valid.
Abstract base class for shapes.
Definition: physxShape.h:41
static const LVector3f & zero()
Returns a zero-length vector.
Definition: lvector3.h:270
void set_filter_bool(bool flag)
Setups filtering&#39;s boolean value.
This is a three-component vector distance (as opposed to a three-component point, which represents a ...
Definition: lvector3.h:100
Descriptor for PhysxCloth.
bool is_valid() const
Returns true if the descriptor is valid.
Abstract base class for joint descriptors.
PhysxSoftBody * create_soft_body(PhysxSoftBodyDesc &desc)
Creates a soft body in this scene.
Definition: physxScene.cxx:972
unsigned int get_num_vehicles() const
Returns the number of vehicles in the scene.
This is a three-component point in space (as opposed to a three-component vector, which represents a ...
Definition: lpoint3.h:99
unsigned int get_num_cloths() const
Gets the number of cloths in the scene.
Definition: physxScene.cxx:909
Descriptor class for force fields.
void set_filter_constant0(const PhysxGroupsMask &mask)
Setups filtering&#39;s K0 value.
bool is_nan() const
Returns true if any component of the vector is not-a-number, false otherwise.
Definition: lvecBase3.h:464
void update_transform(const LMatrix4f &m)
Updates the transform of an assigned NodePath.
Definition: physxActor.cxx:166
PhysxGroupsMask get_filter_constant0() const
Gets filtering constant K0.
bool get_actor_pair_flag(PhysxActor &actorA, PhysxActor &actorB, PhysxContactPairFlag flag)
Retrieves a single flag for the given pair of actors.
PhysxController * get_controller(unsigned int idx) const
Retrieves the n-th controller within the scene.
Definition: physxScene.cxx:720
A class for describing a shape&#39;s surface properties.
Definition: physxMaterial.h:51
PhysxCloth * create_cloth(PhysxClothDesc &desc)
Creates a cloth in this scene.
Definition: physxScene.cxx:921
Descriptor class for a character controller.
PhysxMaterial * get_material_from_index(unsigned int idx) const
Retrieves the material with the given material index.
Definition: physxScene.cxx:639
void set_timing_variable()
Sets simulation timing parameters used in simulate.
Definition: physxScene.cxx:309
This structure captures results for a single raycast query.
A lightweight class that represents a single element that may be timed and/or counted via stats...
bool get_actor_group_pair_flag(unsigned int g1, unsigned int g2, PhysxContactPairFlag flag)
Retrieves a single flag set with PhysxScene::set_actor_group_pair_flag()
bool raycast_any_bounds(const PhysxRay &ray, PhysxShapesType shapesType=ST_all, PhysxMask mask=PhysxMask::all_on(), PhysxGroupsMask *groups=NULL) const
Returns true if any axis aligned bounding box enclosing a shape is intersected by the ray...
PhysxForceFieldShapeGroup * create_force_field_shape_group(PhysxForceFieldShapeGroupDesc &desc)
Creates a new force field shape group in this scene.
Definition: physxScene.cxx:866
bool is_hardware_scene() const
Returns TRUE if the the scene is simulated in hardware.
PhysxOverlapReport overlap_capsule_shapes(const LPoint3f &p0, const LPoint3f &p1, float radius, PhysxShapesType shapesType=ST_all, PhysxMask mask=PhysxMask::all_on(), bool accurateCollision=true) const
Returns the set of shapes overlapped by the world-space capsule.
PhysxFilterOp get_filter_op1() const
Retrieves the op1 filtering operation.
PhysxConstraintDominance get_dominance_group_pair(unsigned int g1, unsigned int g2)
Samples the dominance matrix.
Abstract base class for character controllers.
Descriptor for PhysxSoftBody.
PhysxForceFieldShapeGroup * get_force_field_shape_group(unsigned int idx) const
Returns the n-th force field shape group in this scene.
Definition: physxScene.cxx:888
bool get_flag(PhysxSceneFlag flag) const
Return the specified scene flag flag.
This is a 4-by-4 transform matrix.
Definition: lmatrix.h:451
static NxVec3 vec3_to_nxVec3(const LVector3f &v)
Converts from LVector3f to NxVec3.
Definition: physxManager.I:33
32-bit bitmask class.
Definition: physxMask.h:26
void fetch_results()
Waits until the simulation has finished, and then updates the scene graph with with simulation result...
Definition: physxScene.cxx:242
PhysxRaycastReport raycast_all_shapes(const PhysxRay &ray, PhysxShapesType shapesType=ST_all, PhysxMask mask=PhysxMask::all_on(), PhysxGroupsMask *groups=NULL, bool smoothNormal=true) const
Returns a PhysxRaycastReport object which can be used to iterate over all shapes that have been hit b...
static LVector3f nxVec3_to_vec3(const NxVec3 &v)
Converts from NxVec3 to LVector3f.
Definition: physxManager.I:44
Descriptor for PhysxActor.
void set_dominance_group_pair(unsigned int g1, unsigned int g2, PhysxConstraintDominance dominance)
Specifies the dominance behavior of constraints between two actors with two certain dominance groups...
Actors are the main simulation objects.
Definition: physxActor.h:48
void set_actor_pair_flag(PhysxActor &actorA, PhysxActor &actorB, PhysxContactPairFlag flag, bool value)
Sets the pair flags for the given pair of actors.
PhysxMaterial * get_material(unsigned int idx) const
Retrieves the n-th material from the array of materials.
Definition: physxScene.cxx:656
PhysxMaterial * create_material()
Creates a new PhysxMaterial using the default settings of PhysxMaterialDesc.
Definition: physxScene.cxx:592
PhysxRaycastHit raycast_closest_bounds(const PhysxRay &ray, PhysxShapesType shapesType=ST_all, PhysxMask mask=PhysxMask::all_on(), PhysxGroupsMask *groups=NULL, bool smoothNormal=true) const
Returns the first axis aligned bounding box enclosing a shape that is hit along the ray...
void set_shape_pair_flag(PhysxShape &shapeA, PhysxShape &shapeB, bool value)
Disables or enables contact generation for a pair of shapes.
PhysxCloth * get_cloth(unsigned int idx) const
Returns the n-th cloth from the array of all the cloths in the scene.
Definition: physxScene.cxx:943
PhysxFilterOp get_filter_op0() const
Retrieves the op0 filtering operation.
PhysxJoint * get_joint(unsigned int idx) const
Retrieve the n-th joint from the array of all the joints in the scene.
Definition: physxScene.cxx:774
void set_actor_group_pair_flag(unsigned int g1, unsigned int g2, PhysxContactPairFlag flag, bool value)
With this method one can set contact reporting flags between actors belonging to a pair of groups...
PhysxJoint * create_joint(PhysxJointDesc &desc)
Creates a joint in this scene.
Definition: physxScene.cxx:751
void simulate(float dt)
Advances the simulation by an elapsedTime time.
Definition: physxScene.cxx:200
A force field effector.
LVector3f get_gravity() const
Retrieves the current gravity setting.
Definition: physxScene.cxx:359
PhysxSoftBody * get_soft_body(unsigned int idx) const
Returns the n-th soft body from the array of all the soft bodies in the scene.
Definition: physxScene.cxx:994
bool is_valid() const
Returns true if the descriptor is valid.
void set_gravity(const LVector3f &gravity)
Sets a constant gravity for the entire scene.
Definition: physxScene.cxx:345
PhysxController * create_controller(PhysxControllerDesc &controllerDesc)
Creates a new character controller.
Definition: physxScene.cxx:694
void set_timing_fixed(float maxTimestep=1.0f/60.0f, unsigned int maxIter=8)
Sets simulation timing parameters used in simulate.
Definition: physxScene.cxx:333
PhysxOverlapReport overlap_sphere_shapes(const LPoint3f &center, float radius, PhysxShapesType shapesType=ST_all, PhysxMask mask=PhysxMask::all_on(), bool accurateCollision=true) const
Returns the set of shapes overlapped by the world-space sphere.
PhysxForceField * create_force_field(PhysxForceFieldDesc &desc)
Creates a force field in this scene.
Definition: physxScene.cxx:808
PhysxDebugGeomNode * get_debug_geom_node()
Retrieves the debug geom node for this scene.
Definition: physxScene.cxx:435
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
unsigned int get_hightest_material_index() const
Returns current highest valid material index.
Definition: physxScene.cxx:619
bool raycast_any_shape(const PhysxRay &ray, PhysxShapesType shapesType=ST_all, PhysxMask mask=PhysxMask::all_on(), PhysxGroupsMask *groups=NULL) const
Returns true if any shape is intersected by the ray.
PhysxForceField * get_force_field(unsigned int idx) const
Returns the n-th force field from the array of all the force fields in the scene. ...
Definition: physxScene.cxx:835
void set_filter_ops(PhysxFilterOp op0, PhysxFilterOp op1, PhysxFilterOp op2)
Setups filtering operations.
PhysxFilterOp get_filter_op2() const
Retrieves the op2 filtering operation.
static LMatrix4f nxMat34_to_mat4(const NxMat34 &m)
Converts from NxMat34 to LMatrix4f.
Definition: physxManager.I:158
unsigned int get_num_force_field_shape_groups() const
Gets the number of force field shape groups in the scene.
Definition: physxScene.cxx:853
Objects of this class are returned by the &#39;raycast all&#39; methods.
Represents an ray as an origin and direction.
Definition: physxRay.h:28
PhysxVehicle * create_vehicle(PhysxVehicleDesc &desc)
Creates a vehicle in this scene.
unsigned int get_num_controllers() const
Return the number of controllers in the scene.
Definition: physxScene.cxx:681
Renderable geometry which represents visualizations of physics objects.
128-bit bitmask class.
Expresses the dominance relationship of a constraint.
bool get_shape_pair_flag(PhysxShape &shapeA, PhysxShape &shapeB)
Returns /true/ if contact generation between a pair of shapes is enabled, and /false/ if contact gene...
bool get_filter_bool() const
Retrieves filtering&#39;s boolean value.