Panda3D

physxScene.cxx

00001 // Filename: physxScene.cxx
00002 // Created by:  enn0x (14Sep09)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "physxScene.h"
00016 #include "physxManager.h"
00017 #include "physxActorDesc.h"
00018 #include "physxForceFieldDesc.h"
00019 #include "physxForceFieldShapeGroupDesc.h"
00020 #include "physxControllerDesc.h"
00021 #include "physxSceneStats2.h"
00022 #include "physxConstraintDominance.h"
00023 #include "physxVehicle.h"
00024 #include "physxVehicleDesc.h"
00025 #include "physxCloth.h"
00026 #include "physxClothDesc.h"
00027 #include "physxSoftBody.h"
00028 #include "physxSoftBodyDesc.h"
00029 
00030 TypeHandle PhysxScene::_type_handle;
00031 
00032 PStatCollector PhysxScene::_pcollector_fetch_results("App:PhysX:Fetch Results");
00033 PStatCollector PhysxScene::_pcollector_update_transforms("App:PhysX:Update Transforms");
00034 PStatCollector PhysxScene::_pcollector_debug_renderer("App:PhysX:Debug Renderer");
00035 PStatCollector PhysxScene::_pcollector_simulate("App:PhysX:Simulate");
00036 PStatCollector PhysxScene::_pcollector_cloth("App:PhysX:Cloth");
00037 PStatCollector PhysxScene::_pcollector_softbody("App:PhysX:Softbody");
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //     Function: PhysxScene::link
00041 //       Access: Public
00042 //  Description: 
00043 ////////////////////////////////////////////////////////////////////
00044 void PhysxScene::
00045 link(NxScene *scenePtr) {
00046 
00047   // Link self
00048   _ptr = scenePtr;
00049   _ptr->userData = this;
00050   _error_type = ET_ok;
00051   PhysxManager::get_global_ptr()->_scenes.add(this);
00052 
00053   _cm = NxCreateControllerManager(NxGetPhysicsSDKAllocator());
00054   nassertv_always(_cm);
00055 
00056   // Link materials
00057   NxMaterial *materials[5];
00058   NxU32 iterator = 0;
00059 
00060   while (NxU32 i=_ptr->getMaterialArray(materials, 5, iterator)) {
00061     while(i--) {
00062       PhysxMaterial *material = new PhysxMaterial();
00063       material->link(materials[i]);
00064     }
00065   }
00066 }
00067 
00068 ////////////////////////////////////////////////////////////////////
00069 //     Function: PhysxScene::unlink
00070 //       Access: Public
00071 //  Description: 
00072 ////////////////////////////////////////////////////////////////////
00073 void PhysxScene::
00074 unlink() {
00075 
00076   // Unlink vehicles
00077   for (unsigned int i=0; i < _vehicles.size(); i++) {
00078     _vehicles[i]->release();
00079   }
00080 
00081   // Unlink controllers
00082   NxU32 nControllers = _cm->getNbControllers();
00083 
00084   for (NxU32 i=0; i < nControllers; i++) {
00085     NxController *controllerPtr = _cm->getController(i);
00086     PhysxController *controller = (PhysxController *)controllerPtr->getUserData();
00087     controller->unlink();
00088   }
00089 
00090   // Unlink actors
00091   NxActor **actors = _ptr->getActors();
00092   NxU32 nActors = _ptr->getNbActors();
00093 
00094   for (NxU32 i=0; i < nActors; i++) {
00095     PhysxActor *actor = (PhysxActor *)actors[i]->userData;
00096 
00097     // Actor could have already been unlinked by controller
00098     if (actor) {
00099       actor->unlink();
00100     }
00101   }
00102 
00103   // Unlink joints
00104   NxU32 nJoints = _ptr->getNbJoints();
00105 
00106   _ptr->resetJointIterator();
00107   for (NxU32 i=0; i < nJoints; i++) {
00108     NxJoint *jointPtr = _ptr->getNextJoint();
00109     PhysxJoint *joint = (PhysxJoint *)jointPtr->userData;
00110     joint->unlink();
00111   }
00112 
00113   // Unlink force fields
00114   NxForceField **fields = _ptr->getForceFields();
00115   NxU32 nFields = _ptr->getNbForceFields();
00116 
00117   for (NxU32 i=0; i < nFields; i++) {
00118     PhysxForceField *field = (PhysxForceField *)fields[i]->userData;
00119     field->unlink();
00120   }
00121 
00122   // Unlink force field shape groups
00123   NxU32 nGroups = _ptr->getNbForceFieldShapeGroups();
00124 
00125   _ptr->resetForceFieldShapeGroupsIterator();
00126   for (NxU32 i=0; i < nGroups; i++) {
00127     NxForceFieldShapeGroup *groupPtr = _ptr->getNextForceFieldShapeGroup();
00128     PhysxForceFieldShapeGroup *group = (PhysxForceFieldShapeGroup *)groupPtr->userData;
00129     group->unlink();
00130   }
00131 
00132   // Unlink cloths
00133   NxCloth **cloths = _ptr->getCloths();
00134   NxU32 nCloths = _ptr->getNbCloths();
00135 
00136   for (NxU32 i=0; i < nCloths; i++) {
00137     PhysxCloth *cloth = (PhysxCloth *)cloths[i]->userData;
00138     cloth->unlink();
00139   }
00140 
00141   // Unlink softbodies
00142   NxSoftBody **softbodies = _ptr->getSoftBodies();
00143   NxU32 nSoftbodies = _ptr->getNbSoftBodies();
00144 
00145   for (NxU32 i=0; i < nSoftbodies; i++) {
00146     PhysxSoftBody *softbody = (PhysxSoftBody *)softbodies[i]->userData;
00147     softbody->unlink();
00148   }
00149 
00150   // Unlink materials
00151   NxMaterial *materials[5];
00152   NxU32 iterator = 0;
00153 
00154   while (NxU32 i=_ptr->getMaterialArray(materials, 5, iterator)) {
00155     while(i--) {
00156       PhysxMaterial *material = (PhysxMaterial *)materials[i]->userData;
00157       material->unlink();
00158     }
00159   }
00160 
00161   // Unlink self
00162   _cm->purgeControllers();
00163   NxReleaseControllerManager(_cm);
00164 
00165   _ptr->userData = NULL;
00166   _error_type = ET_released;
00167 
00168   PhysxManager::get_global_ptr()->_scenes.remove(this);
00169 }
00170 
00171 ////////////////////////////////////////////////////////////////////
00172 //     Function: PhysxScene::release
00173 //       Access: Published
00174 //  Description: 
00175 ////////////////////////////////////////////////////////////////////
00176 void PhysxScene::
00177 release() {
00178 
00179   nassertv(_error_type == ET_ok);
00180 
00181   unlink();
00182   NxPhysicsSDK *sdk = NxGetPhysicsSDK();
00183   sdk->releaseScene(*_ptr);
00184   _ptr = NULL;
00185 }
00186 
00187 ////////////////////////////////////////////////////////////////////
00188 //     Function: PhysxScene::simulate
00189 //       Access: Published
00190 //  Description: Advances the simulation by an elapsedTime time.
00191 //               The elapsed time has to be in the range (0, inf).
00192 //
00193 //               It is not allowed to modify the physics scene in
00194 //               between the simulate(dt) and the fetch_results
00195 //               calls!  But it is allowed to read from the scene
00196 //               and do additional computations, e. g. AI, in
00197 //               between these calls.
00198 ////////////////////////////////////////////////////////////////////
00199 void PhysxScene::
00200 simulate(float dt) {
00201 
00202   nassertv(_error_type == ET_ok);
00203 
00204   _pcollector_simulate.start();
00205 
00206   // Update all vehicles
00207   for (unsigned int i=0; i < _vehicles.size(); i++) {
00208     PhysxVehicle *vehicle = _vehicles[i];
00209     vehicle->update_vehicle(dt);
00210   }
00211 
00212   // Update all controllers
00213   for (NxU32 i=0; i < _cm->getNbControllers(); i++) {
00214     NxController *controllerPtr = _cm->getController(i);
00215     PhysxController *controller = (PhysxController *)controllerPtr->getUserData();
00216     controller->update_controller(dt);
00217   }
00218 
00219   _cm->updateControllers();
00220 
00221   // Simulate and flush streams
00222   _ptr->simulate(dt);
00223   _ptr->flushStream();
00224 
00225   _pcollector_simulate.stop();
00226 }
00227 
00228 ////////////////////////////////////////////////////////////////////
00229 //     Function: PhysxScene::fetch_results
00230 //       Access: Published
00231 //  Description: Waits until the simulation has finished, and then
00232 //               updates the scene graph with with simulation
00233 //               results.
00234 //
00235 //               It is not allowed to modify the physics scene in
00236 //               between the simulate(dt) and the fetch_results
00237 //               calls!  But it is allowed to read from the scene
00238 //               and do additional computations, e. g. AI, in
00239 //               between these calls.
00240 ////////////////////////////////////////////////////////////////////
00241 void PhysxScene::
00242 fetch_results() {
00243 
00244   nassertv(_error_type == ET_ok);
00245   nassertv(_ptr != NULL);
00246 
00247   _pcollector_fetch_results.start();
00248   _ptr->fetchResults(NX_RIGID_BODY_FINISHED, true);
00249   _pcollector_fetch_results.stop();
00250 
00251   // Update node transforms
00252   _pcollector_update_transforms.start();
00253 
00254   NxU32 nbTransforms = 0;
00255   NxActiveTransform *activeTransforms = _ptr->getActiveTransforms(nbTransforms);
00256 
00257   if (nbTransforms && activeTransforms) {
00258     for (NxU32 i=0; i<nbTransforms; ++i) {
00259 
00260       // Objects created by the Visual Remote Debugger might not have
00261       // user data. So check if user data ist set.
00262       void *userData = activeTransforms[i].userData;
00263       if (userData) {
00264         LMatrix4f m = PhysxManager::nxMat34_to_mat4(activeTransforms[i].actor2World);
00265         PhysxActor *actor = (PhysxActor *)userData;
00266         actor->update_transform(m);
00267       }
00268     }
00269   }
00270   _pcollector_update_transforms.stop();
00271 
00272   // Update debug node
00273   _pcollector_debug_renderer.start();
00274   _debugNode->update(_ptr);
00275   _pcollector_debug_renderer.stop();
00276 
00277   nassertv(_ptr->isWritable());
00278 
00279   // Update cloth nodes
00280   _pcollector_cloth.start();
00281 
00282   NxCloth **cloths = _ptr->getCloths();
00283   for (NxU32 i=0; i < _ptr->getNbCloths(); i++) {
00284     PT(PhysxCloth) cloth = (PhysxCloth *)cloths[i]->userData;
00285     cloth->update();
00286   }
00287 
00288   _pcollector_cloth.stop();
00289 
00290   // Update softbody nodes
00291   _pcollector_softbody.start();
00292 
00293   NxSoftBody **softbodies = _ptr->getSoftBodies();
00294   for (NxU32 i=0; i < _ptr->getNbSoftBodies(); i++) {
00295     PT(PhysxSoftBody) softbody = (PhysxSoftBody *)softbodies[i]->userData;
00296     softbody->update();
00297   }
00298 
00299   _pcollector_softbody.stop();
00300 }
00301 
00302 ////////////////////////////////////////////////////////////////////
00303 //     Function: PhysxScene::set_timing_variable
00304 //       Access: Published
00305 //  Description: Sets simulation timing parameters used in simulate.
00306 
00307 ////////////////////////////////////////////////////////////////////
00308 void PhysxScene::
00309 set_timing_variable() {
00310 
00311   nassertv(_error_type == ET_ok);
00312   _ptr->setTiming(NULL, NULL, NX_TIMESTEP_VARIABLE);
00313 }
00314 
00315 ////////////////////////////////////////////////////////////////////
00316 //     Function: PhysxScene::set_timing_fixed
00317 //       Access: Published
00318 //  Description: Sets simulation timing parameters used in simulate.
00319 //               The elapsed time (parameter "dt" in simulate()) is
00320 //               internally subdivided into up to maxIter substeps
00321 //               no larger than maxTimestep. If the elapsed time is
00322 //               not a multiple of maxTimestep then any remaining
00323 //               time is accumulated to be added onto the elapsed
00324 //               time for the next time step. If more sub steps than
00325 //               maxIter are needed to advance the simulation by
00326 //               elapsed time, then the remaining time is also
00327 //               accumulated for the next call to simulate().
00328 //
00329 //               This timing method is strongly preferred for
00330 //               stable, reproducible simulation.
00331 ////////////////////////////////////////////////////////////////////
00332 void PhysxScene::
00333 set_timing_fixed(float maxTimestep, unsigned int maxIter) {
00334 
00335   nassertv(_error_type == ET_ok);
00336   _ptr->setTiming(maxTimestep, maxIter, NX_TIMESTEP_FIXED);
00337 }
00338 
00339 ////////////////////////////////////////////////////////////////////
00340 //     Function: PhysxScene::set_gravity
00341 //       Access: Published
00342 //  Description: Sets a constant gravity for the entire scene.
00343 ////////////////////////////////////////////////////////////////////
00344 void PhysxScene::
00345 set_gravity(const LVector3f &gravity) {
00346 
00347   nassertv(_error_type == ET_ok);
00348   nassertv_always(!gravity.is_nan());
00349 
00350   _ptr->setGravity(PhysxManager::vec3_to_nxVec3(gravity));
00351 }
00352 
00353 ////////////////////////////////////////////////////////////////////
00354 //     Function: PhysxScene::get_gravity
00355 //       Access: Published
00356 //  Description: Retrieves the current gravity setting.
00357 ////////////////////////////////////////////////////////////////////
00358 LVector3f PhysxScene::
00359 get_gravity() const {
00360 
00361   nassertr(_error_type == ET_ok, LVector3f::zero());
00362 
00363   NxVec3 gravity;
00364   _ptr->getGravity(gravity);
00365   return PhysxManager::nxVec3_to_vec3(gravity);
00366 }
00367 
00368 ////////////////////////////////////////////////////////////////////
00369 //     Function: PhysxScene::get_num_actors
00370 //       Access: Published
00371 //  Description: 
00372 ////////////////////////////////////////////////////////////////////
00373 unsigned int PhysxScene::
00374 get_num_actors() const {
00375 
00376   nassertr(_error_type == ET_ok,-1);
00377 
00378   return _ptr->getNbActors();
00379 }
00380 
00381 ////////////////////////////////////////////////////////////////////
00382 //     Function: PhysxScene::create_actor
00383 //       Access: Published
00384 //  Description:
00385 ////////////////////////////////////////////////////////////////////
00386 PhysxActor *PhysxScene::
00387 create_actor(PhysxActorDesc &desc) {
00388 
00389   nassertr(_error_type == ET_ok, NULL);
00390   nassertr(desc.is_valid(), NULL);
00391 
00392   PhysxActor *actor = new PhysxActor();
00393   nassertr(actor, NULL);
00394 
00395   NxActor *actorPtr = _ptr->createActor(desc._desc);
00396   nassertr(actorPtr, NULL);
00397 
00398   actor->link(actorPtr);
00399 
00400   return actor;
00401 }
00402 
00403 ////////////////////////////////////////////////////////////////////
00404 //     Function: PhysxScene::get_actor
00405 //       Access: Published
00406 //  Description: 
00407 ////////////////////////////////////////////////////////////////////
00408 PhysxActor *PhysxScene::
00409 get_actor(unsigned int idx) const {
00410 
00411   nassertr(_error_type == ET_ok, NULL);
00412   nassertr_always(idx < _ptr->getNbActors(), NULL);
00413 
00414   NxActor *actorPtr = _ptr->getActors()[idx];
00415   PhysxActor *actor = (PhysxActor *)(actorPtr->userData);
00416 
00417   return actor;
00418 }
00419 
00420 ////////////////////////////////////////////////////////////////////
00421 //     Function: PhysxScene::get_debug_node
00422 //       Access: Published
00423 //  Description: Retrieves the debug geom node for this scene. The
00424 //               debug geom node is used to visualize information
00425 //               about the physical scene which can be useful for
00426 //               debugging an application.
00427 //
00428 //               The debug geom node geometry is generated in global
00429 //               coordinates. In order to see correct information
00430 //               it is important not to dislocate the debug node.
00431 //               Reparent it to render and leave position at
00432 //               (0,0,0).
00433 ////////////////////////////////////////////////////////////////////
00434 PhysxDebugGeomNode *PhysxScene::
00435 get_debug_geom_node() {
00436 
00437   nassertr(_error_type == ET_ok, NULL);
00438   return _debugNode;
00439 }
00440 
00441 ////////////////////////////////////////////////////////////////////
00442 //     Function: PhysxScene::enable_contact_reporting
00443 //       Access: Published
00444 //  Description:
00445 ////////////////////////////////////////////////////////////////////
00446 void PhysxScene::
00447 enable_contact_reporting(bool enabled) {
00448 
00449   nassertv(_error_type == ET_ok);
00450 
00451   if (enabled) {
00452     _ptr->setUserContactReport(&_contact_report);
00453     _contact_report.enable();
00454   }
00455   else {
00456     _ptr->setUserContactReport(NULL);
00457     _contact_report.disable();
00458   }
00459 }
00460 
00461 ////////////////////////////////////////////////////////////////////
00462 //     Function: PhysxScene::is_contact_reporting_enabled
00463 //       Access: Published
00464 //  Description:
00465 ////////////////////////////////////////////////////////////////////
00466 bool PhysxScene::
00467 is_contact_reporting_enabled() const {
00468 
00469   nassertr(_error_type == ET_ok, false);
00470 
00471   return _contact_report.is_enabled();
00472 }
00473 
00474 ////////////////////////////////////////////////////////////////////
00475 //     Function: PhysxScene::enable_trigger_reporting
00476 //       Access: Published
00477 //  Description:
00478 ////////////////////////////////////////////////////////////////////
00479 void PhysxScene::
00480 enable_trigger_reporting(bool enabled) {
00481 
00482   nassertv(_error_type == ET_ok);
00483 
00484   if (enabled) {
00485     _ptr->setUserTriggerReport(&_trigger_report);
00486     _trigger_report.enable();
00487   }
00488   else {
00489     _ptr->setUserTriggerReport(NULL);
00490     _trigger_report.disable();
00491   }
00492 }
00493 
00494 ////////////////////////////////////////////////////////////////////
00495 //     Function: PhysxScene::is_trigger_reporting_enabled
00496 //       Access: Published
00497 //  Description:
00498 ////////////////////////////////////////////////////////////////////
00499 bool PhysxScene::
00500 is_trigger_reporting_enabled() const {
00501 
00502   nassertr(_error_type == ET_ok, false);
00503 
00504   return _trigger_report.is_enabled();
00505 }
00506 
00507 ////////////////////////////////////////////////////////////////////
00508 //     Function: PhysxScene::enable_controller_reporting
00509 //       Access: Published
00510 //  Description:
00511 ////////////////////////////////////////////////////////////////////
00512 void PhysxScene::
00513 enable_controller_reporting(bool enabled) {
00514 
00515   nassertv(_error_type == ET_ok);
00516 
00517   if (enabled) {
00518     _controller_report.enable();
00519   }
00520   else {
00521     _controller_report.disable();
00522   }
00523 }
00524 
00525 ////////////////////////////////////////////////////////////////////
00526 //     Function: PhysxScene::is_controller_reporting_enabled
00527 //       Access: Published
00528 //  Description:
00529 ////////////////////////////////////////////////////////////////////
00530 bool PhysxScene::
00531 is_controller_reporting_enabled() const {
00532 
00533   nassertr(_error_type == ET_ok, false);
00534 
00535   return _controller_report.is_enabled();
00536 }
00537 
00538 ////////////////////////////////////////////////////////////////////
00539 //     Function: PhysxScene::get_num_materials
00540 //       Access: Published
00541 //  Description: Return the number of materials in the scene. 
00542 //
00543 //               Note that the returned value is not related to
00544 //               material indices. Those may not be allocated
00545 //               continuously, and its values may be higher than
00546 //               get_num_materials(). This will also include the
00547 //               default material which exists without having to
00548 //               be created.
00549 ////////////////////////////////////////////////////////////////////
00550 unsigned int PhysxScene::
00551 get_num_materials() const {
00552 
00553   nassertr(_error_type == ET_ok, -1);
00554   return _ptr->getNbMaterials();
00555 }
00556 
00557 ////////////////////////////////////////////////////////////////////
00558 //     Function: PhysxScene::create_material
00559 //       Access: Published
00560 //  Description: Creates a new PhysxMaterial.
00561 //
00562 //               The material library consists of an array of
00563 //               material objects. Each material has a well defined
00564 //               index that can be used to refer to it. If an object
00565 //               references an undefined material, the default
00566 //               material with index 0 is used instead.
00567 ////////////////////////////////////////////////////////////////////
00568 PhysxMaterial *PhysxScene::
00569 create_material(PhysxMaterialDesc &desc) {
00570 
00571   nassertr(_error_type == ET_ok, NULL);
00572   nassertr(desc.is_valid(), NULL);
00573 
00574   PhysxMaterial *material = new PhysxMaterial();
00575   nassertr(material, NULL);
00576 
00577   NxMaterial *materialPtr = _ptr->createMaterial(desc._desc);
00578   nassertr(materialPtr, NULL);
00579 
00580   material->link(materialPtr);
00581 
00582   return material;
00583 }
00584 
00585 ////////////////////////////////////////////////////////////////////
00586 //     Function: PhysxScene::create_material
00587 //       Access: Published
00588 //  Description: Creates a new PhysxMaterial using the default
00589 //               settings of PhysxMaterialDesc.
00590 ////////////////////////////////////////////////////////////////////
00591 PhysxMaterial *PhysxScene::
00592 create_material() {
00593 
00594   nassertr(_error_type == ET_ok, NULL);
00595 
00596   PhysxMaterial *material = new PhysxMaterial();
00597   nassertr(material, NULL);
00598 
00599   NxMaterialDesc desc;
00600   desc.setToDefault();
00601   NxMaterial *materialPtr = _ptr->createMaterial(desc);
00602   nassertr(materialPtr, NULL);
00603 
00604   material->link(materialPtr);
00605 
00606   return material;
00607 }
00608 
00609 ////////////////////////////////////////////////////////////////////
00610 //     Function: PhysxScene::get_hightest_material_index
00611 //       Access: Published
00612 //  Description: Returns current highest valid material index.
00613 //
00614 //               Note that not all indices below this are valid if
00615 //               some of them belong to meshes that have beed
00616 //               freed.
00617 ////////////////////////////////////////////////////////////////////
00618 unsigned int PhysxScene::
00619 get_hightest_material_index() const {
00620 
00621   nassertr(_error_type == ET_ok, -1);
00622   return _ptr->getHighestMaterialIndex();
00623 }
00624 
00625 ////////////////////////////////////////////////////////////////////
00626 //     Function: PhysxScene::get_material_from_index
00627 //       Access: Published
00628 //  Description: Retrieves the material with the given material
00629 //               index. 
00630 //
00631 //               There is always at least one material in the Scene,
00632 //               the default material (index 0). If the specified
00633 //               material index is out of range (larger than
00634 //               get_hightest_material_index) or belongs to a
00635 //               material that has been released, then the default
00636 //               material is returned, but no error is reported.
00637 ////////////////////////////////////////////////////////////////////
00638 PhysxMaterial *PhysxScene::
00639 get_material_from_index(unsigned int idx) const {
00640 
00641   nassertr(_error_type == ET_ok, NULL);
00642 
00643   NxMaterial *materialPtr = _ptr->getMaterialFromIndex(idx);
00644 
00645   return (PhysxMaterial *)(materialPtr->userData);
00646 }
00647 
00648 ////////////////////////////////////////////////////////////////////
00649 //     Function: PhysxScene::get_material
00650 //       Access: Published
00651 //  Description: Retrieves the n-th material from the array of
00652 //               materials. See also get_material_from_index,
00653 //               which retrieves a material by it's material index.
00654 ////////////////////////////////////////////////////////////////////
00655 PhysxMaterial *PhysxScene::
00656 get_material(unsigned int idx) const {
00657 
00658   nassertr(_error_type == ET_ok, NULL);
00659   nassertr_always(idx < _ptr->getNbMaterials(), NULL);
00660 
00661   NxU32 n = _ptr->getNbMaterials();
00662   NxMaterial **materials = new NxMaterial *[n];
00663   NxU32 materialCount;
00664   NxU32 iterator = 0;
00665 
00666   materialCount = _ptr->getMaterialArray(materials, n, iterator);
00667   nassertr((materialCount == n), NULL);
00668 
00669   NxMaterial *materialPtr = materials[idx];
00670   delete[] materials;
00671 
00672   return (PhysxMaterial *)(materialPtr->userData);
00673 }
00674 
00675 ////////////////////////////////////////////////////////////////////
00676 //     Function: PhysxScene::get_num_controllers
00677 //       Access: Published
00678 //  Description: Return the number of controllers in the scene. 
00679 ////////////////////////////////////////////////////////////////////
00680 unsigned int PhysxScene::
00681 get_num_controllers() const {
00682 
00683   nassertr(_error_type == ET_ok, -1);
00684   return _cm->getNbControllers();
00685 }
00686 
00687 
00688 ////////////////////////////////////////////////////////////////////
00689 //     Function: PhysxScene::create_controller
00690 //       Access: Published
00691 //  Description: Creates a new character controller.
00692 ////////////////////////////////////////////////////////////////////
00693 PhysxController *PhysxScene::
00694 create_controller(PhysxControllerDesc &desc) {
00695 
00696   nassertr(_error_type == ET_ok, NULL);
00697   nassertr(desc.is_valid(), NULL);
00698 
00699   PhysxController *controller = PhysxController::factory(desc.ptr()->getType());
00700   nassertr(controller, NULL);
00701 
00702   desc.ptr()->callback = &_controller_report;
00703   desc.ptr()->userData = controller;
00704 
00705   NxController *controllerPtr = _cm->createController(_ptr,*desc.ptr());
00706   nassertr(controllerPtr, NULL);
00707 
00708   controller->link(controllerPtr);
00709   controller->get_actor()->set_name("");
00710 
00711   return controller;
00712 }
00713 
00714 ////////////////////////////////////////////////////////////////////
00715 //     Function: PhysxScene::get_controller
00716 //       Access: Published
00717 //  Description: Retrieves the n-th controller within the scene.
00718 ////////////////////////////////////////////////////////////////////
00719 PhysxController *PhysxScene::
00720 get_controller(unsigned int idx) const {
00721 
00722   nassertr(_error_type == ET_ok, NULL);
00723   nassertr_always(idx < _cm->getNbControllers(), NULL);
00724 
00725   NxController *controllerPtr = _cm->getController(idx);
00726   PhysxController *controller = (PhysxController *)(controllerPtr->getUserData());
00727 
00728   return controller;
00729 }
00730 
00731 ////////////////////////////////////////////////////////////////////
00732 //     Function: PhysxScene::get_num_joints
00733 //       Access: Published
00734 //  Description: Returns the number of joints in the scene
00735 //               (excluding "dead" joints). Note that this includes
00736 //               compartments.
00737 ////////////////////////////////////////////////////////////////////
00738 unsigned int PhysxScene::
00739 get_num_joints() const {
00740 
00741   nassertr(_error_type == ET_ok, -1);
00742   return _ptr->getNbJoints();
00743 }
00744 
00745 ////////////////////////////////////////////////////////////////////
00746 //     Function: PhysxScene::create_joint
00747 //       Access: Published
00748 //  Description: Creates a joint in this scene.
00749 ////////////////////////////////////////////////////////////////////
00750 PhysxJoint *PhysxScene::
00751 create_joint(PhysxJointDesc &desc) {
00752 
00753   nassertr(_error_type == ET_ok, NULL);
00754   nassertr(desc.is_valid(), NULL);
00755 
00756   PhysxJoint *joint = PhysxJoint::factory(desc.ptr()->getType());
00757   nassertr(joint, NULL);
00758 
00759   NxJoint *jointPtr = _ptr->createJoint(*desc.ptr());
00760   nassertr(jointPtr, NULL);
00761 
00762   joint->link(jointPtr);
00763 
00764   return joint;
00765 }
00766 
00767 ////////////////////////////////////////////////////////////////////
00768 //     Function: PhysxScene::get_joint
00769 //       Access: Published
00770 //  Description: Retrieve the n-th joint from the array of all the
00771 //               joints in the scene.
00772 ////////////////////////////////////////////////////////////////////
00773 PhysxJoint *PhysxScene::
00774 get_joint(unsigned int idx) const {
00775 
00776   nassertr(_error_type == ET_ok, NULL);
00777   nassertr_always(idx < _ptr->getNbJoints(), NULL);
00778 
00779   NxJoint *jointPtr;
00780   NxU32 nJoints = _ptr->getNbJoints();
00781 
00782   _ptr->resetJointIterator();
00783   for (NxU32 i=0; i <= idx; i++) {
00784     jointPtr = _ptr->getNextJoint();
00785   }
00786 
00787   return (PhysxJoint *)(jointPtr->userData);
00788 }
00789 
00790 ////////////////////////////////////////////////////////////////////
00791 //     Function: PhysxScene::get_num_force_fields
00792 //       Access: Published
00793 //  Description: Gets the number of force fields in the scene.
00794 ////////////////////////////////////////////////////////////////////
00795 unsigned int PhysxScene::
00796 get_num_force_fields() const {
00797 
00798   nassertr(_error_type == ET_ok, -1);
00799   return _ptr->getNbForceFields();
00800 }
00801 
00802 ////////////////////////////////////////////////////////////////////
00803 //     Function: PhysxScene::create_force_field
00804 //       Access: Published
00805 //  Description: Creates a force field in this scene.
00806 ////////////////////////////////////////////////////////////////////
00807 PhysxForceField *PhysxScene::
00808 create_force_field(PhysxForceFieldDesc &desc) {
00809 
00810   nassertr(_error_type == ET_ok, NULL);
00811 
00812   // Create the kernel
00813   desc.create_kernel(_ptr);
00814   nassertr(desc.is_valid(), NULL);
00815 
00816   // Create the force field
00817   PhysxForceField *field = new PhysxForceField();
00818   nassertr(field, NULL);
00819 
00820   NxForceField *fieldPtr = _ptr->createForceField(desc._desc);
00821   nassertr(fieldPtr, NULL);
00822 
00823   field->link(fieldPtr);
00824 
00825   return field;
00826 }
00827 
00828 ////////////////////////////////////////////////////////////////////
00829 //     Function: PhysxScene::get_force_field
00830 //       Access: Published
00831 //  Description: Returns the n-th force field from the array of
00832 //               all the force fields in the scene.
00833 ////////////////////////////////////////////////////////////////////
00834 PhysxForceField *PhysxScene::
00835 get_force_field(unsigned int idx) const {
00836 
00837   nassertr(_error_type == ET_ok, NULL);
00838   nassertr_always(idx < _ptr->getNbForceFields(), NULL);
00839 
00840   NxForceField **fields = _ptr->getForceFields();
00841   NxForceField *fieldPtr = fields[idx];
00842 
00843   return (PhysxForceField *)(fieldPtr->userData);
00844 }
00845 
00846 ////////////////////////////////////////////////////////////////////
00847 //     Function: PhysxScene::get_num_force_field_shape_groups
00848 //       Access: Published
00849 //  Description: Gets the number of force field shape groups in
00850 //               the scene.
00851 ////////////////////////////////////////////////////////////////////
00852 unsigned int PhysxScene::
00853 get_num_force_field_shape_groups() const {
00854 
00855   nassertr(_error_type == ET_ok, -1);
00856   return _ptr->getNbForceFieldShapeGroups();
00857 }
00858 
00859 ////////////////////////////////////////////////////////////////////
00860 //     Function: PhysxScene::create_force_field_shape_group
00861 //       Access: Published
00862 //  Description: Creates a new force field shape group in this
00863 //               scene.
00864 ////////////////////////////////////////////////////////////////////
00865 PhysxForceFieldShapeGroup *PhysxScene::
00866 create_force_field_shape_group(PhysxForceFieldShapeGroupDesc &desc) {
00867 
00868   nassertr(_error_type == ET_ok, NULL);
00869 
00870   PhysxForceFieldShapeGroup *group = new PhysxForceFieldShapeGroup();
00871   nassertr(group, NULL);
00872 
00873   NxForceFieldShapeGroup *groupPtr = _ptr->createForceFieldShapeGroup(desc._desc);
00874   nassertr(groupPtr, NULL);
00875 
00876   group->link(groupPtr);
00877 
00878   return group;
00879 }
00880 
00881 ////////////////////////////////////////////////////////////////////
00882 //     Function: PhysxScene::get_force_field_shape_group
00883 //       Access: Published
00884 //  Description: Returns the n-th force field shape group in this
00885 //               scene
00886 ////////////////////////////////////////////////////////////////////
00887 PhysxForceFieldShapeGroup *PhysxScene::
00888 get_force_field_shape_group(unsigned int idx) const {
00889 
00890   nassertr(_error_type == ET_ok, NULL);
00891   nassertr_always(idx < _ptr->getNbForceFieldShapeGroups(), NULL);
00892 
00893   _ptr->resetForceFieldShapeGroupsIterator();
00894   NxForceFieldShapeGroup *groupPtr = NULL;
00895   idx++;
00896   while (idx-- > 0) {
00897     groupPtr = _ptr->getNextForceFieldShapeGroup();
00898   }
00899 
00900   return groupPtr ? (PhysxForceFieldShapeGroup *)groupPtr->userData : NULL;
00901 }
00902 
00903 ////////////////////////////////////////////////////////////////////
00904 //     Function: PhysxScene::get_num_cloths
00905 //       Access: Published
00906 //  Description: Gets the number of cloths in the scene.
00907 ////////////////////////////////////////////////////////////////////
00908 unsigned int PhysxScene::
00909 get_num_cloths() const {
00910 
00911   nassertr(_error_type == ET_ok, -1);
00912   return _ptr->getNbCloths();
00913 }
00914 
00915 ////////////////////////////////////////////////////////////////////
00916 //     Function: PhysxScene::create_cloth
00917 //       Access: Published
00918 //  Description: Creates a cloth in this scene.
00919 ////////////////////////////////////////////////////////////////////
00920 PhysxCloth *PhysxScene::
00921 create_cloth(PhysxClothDesc &desc) {
00922 
00923   nassertr(_error_type == ET_ok, NULL);
00924 
00925   PhysxCloth *cloth = new PhysxCloth();
00926   nassertr(cloth, NULL);
00927 
00928   NxCloth *clothPtr = _ptr->createCloth(desc._desc);
00929   nassertr(clothPtr, NULL);
00930 
00931   cloth->link(clothPtr);
00932 
00933   return cloth;
00934 }
00935 
00936 ////////////////////////////////////////////////////////////////////
00937 //     Function: PhysxScene::get_cloth
00938 //       Access: Published
00939 //  Description: Returns the n-th cloth from the array of
00940 //               all the cloths in the scene.
00941 ////////////////////////////////////////////////////////////////////
00942 PhysxCloth *PhysxScene::
00943 get_cloth(unsigned int idx) const {
00944 
00945   nassertr(_error_type == ET_ok, NULL);
00946   nassertr_always(idx < _ptr->getNbCloths(), NULL);
00947 
00948   NxCloth **cloths = _ptr->getCloths();
00949   NxCloth *clothPtr = cloths[idx];
00950 
00951   return (PhysxCloth *)(clothPtr->userData);
00952 }
00953 
00954 ////////////////////////////////////////////////////////////////////
00955 //     Function: PhysxScene::get_num_soft_bodies
00956 //       Access: Published
00957 //  Description: Gets the number of soft bodies in the scene.
00958 ////////////////////////////////////////////////////////////////////
00959 unsigned int PhysxScene::
00960 get_num_soft_bodies() const {
00961 
00962   nassertr(_error_type == ET_ok, -1);
00963   return _ptr->getNbSoftBodies();
00964 }
00965 
00966 ////////////////////////////////////////////////////////////////////
00967 //     Function: PhysxScene::create_soft_body
00968 //       Access: Published
00969 //  Description: Creates a soft body in this scene.
00970 ////////////////////////////////////////////////////////////////////
00971 PhysxSoftBody *PhysxScene::
00972 create_soft_body(PhysxSoftBodyDesc &desc) {
00973 
00974   nassertr(_error_type == ET_ok, NULL);
00975 
00976   PhysxSoftBody *softbody = new PhysxSoftBody();
00977   nassertr(softbody, NULL);
00978 
00979   NxSoftBody *softbodyPtr = _ptr->createSoftBody(desc._desc);
00980   nassertr(softbodyPtr, NULL);
00981 
00982   softbody->link(softbodyPtr);
00983 
00984   return softbody;
00985 }
00986 
00987 ////////////////////////////////////////////////////////////////////
00988 //     Function: PhysxScene::get_soft_body
00989 //       Access: Published
00990 //  Description: Returns the n-th soft body from the array of
00991 //               all the soft bodies in the scene.
00992 ////////////////////////////////////////////////////////////////////
00993 PhysxSoftBody *PhysxScene::
00994 get_soft_body(unsigned int idx) const {
00995 
00996   nassertr(_error_type == ET_ok, NULL);
00997   nassertr_always(idx < _ptr->getNbSoftBodies(), NULL);
00998 
00999   NxSoftBody **softbodies = _ptr->getSoftBodies();
01000   NxSoftBody *softbodyPtr = softbodies[idx];
01001 
01002   return (PhysxSoftBody *)(softbodyPtr->userData);
01003 }
01004 
01005 ////////////////////////////////////////////////////////////////////
01006 //     Function: PhysxScene::get_num_vehicles
01007 //       Access: Published
01008 //  Description: Returns the number of vehicles in the scene.
01009 ////////////////////////////////////////////////////////////////////
01010 unsigned int PhysxScene::
01011 get_num_vehicles() const {
01012 
01013   nassertr(_error_type == ET_ok, -1);
01014   return _vehicles.size();
01015 }
01016 
01017 ////////////////////////////////////////////////////////////////////
01018 //     Function: PhysxScene::create_vehicle
01019 //       Access: Published
01020 //  Description: Creates a vehicle in this scene.
01021 ////////////////////////////////////////////////////////////////////
01022 PhysxVehicle *PhysxScene::
01023 create_vehicle(PhysxVehicleDesc &desc) {
01024 
01025   nassertr(_error_type == ET_ok, NULL);
01026   nassertr(desc.is_valid(), NULL);
01027 
01028   PhysxVehicle *vehicle = new PhysxVehicle();
01029   nassertr(vehicle, NULL);
01030 
01031   vehicle->create(this, desc);
01032 
01033   return vehicle;
01034 }
01035 
01036 ////////////////////////////////////////////////////////////////////
01037 //     Function: PhysxScene::get_vehicle
01038 //       Access: Published
01039 //  Description: Returns the n-th vehicle from the array of all
01040 //               the vehicles in the scene.
01041 ////////////////////////////////////////////////////////////////////
01042 PhysxVehicle *PhysxScene::
01043 get_vehicle(unsigned int idx) const {
01044 
01045   nassertr(_error_type == ET_ok, NULL);
01046   nassertr_always(idx < _vehicles.size(), NULL);
01047 
01048   return _vehicles[idx];
01049 }
01050 
01051 ////////////////////////////////////////////////////////////////////
01052 //     Function: PhysxScene::get_stats2
01053 //       Access: Published
01054 //  Description:
01055 ////////////////////////////////////////////////////////////////////
01056 PhysxSceneStats2 PhysxScene::
01057 get_stats2() const {
01058 
01059   nassertr(_error_type == ET_ok, NULL);
01060   return PhysxSceneStats2(_ptr->getStats2());
01061 }
01062 
01063 ////////////////////////////////////////////////////////////////////
01064 //     Function: PhysxScene::raycast_any_shape
01065 //       Access: Published
01066 //  Description: Returns true if any shape is intersected by the
01067 //               ray.
01068 ////////////////////////////////////////////////////////////////////
01069 bool PhysxScene::
01070 raycast_any_shape(const PhysxRay &ray,
01071                         PhysxShapesType shapesType,
01072                         PhysxMask mask,
01073                         PhysxGroupsMask *groups) const {
01074 
01075   nassertr(_error_type == ET_ok, false);
01076 
01077   NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
01078 
01079   return _ptr->raycastAnyShape(ray._ray, (NxShapesType)shapesType, 
01080                                mask.get_mask(), ray._length, groupsPtr);
01081 }
01082 
01083 ////////////////////////////////////////////////////////////////////
01084 //     Function: PhysxScene::raycast_closest_shape
01085 //       Access: Published
01086 //  Description: Returns the first shape that is hit along the ray.
01087 //               If not shape is hit then an empty raycast hit
01088 //               is returned (is_empty() == true).
01089 ////////////////////////////////////////////////////////////////////
01090 PhysxRaycastHit PhysxScene::
01091 raycast_closest_shape(const PhysxRay &ray,
01092                             PhysxShapesType shapesType,
01093                             PhysxMask mask,
01094                             PhysxGroupsMask *groups, bool smoothNormal) const {
01095 
01096   NxRaycastHit hit;
01097 
01098   nassertr(_error_type == ET_ok, hit);
01099 
01100   NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
01101 
01102   NxU32 hints = NX_RAYCAST_SHAPE | NX_RAYCAST_IMPACT | NX_RAYCAST_DISTANCE;
01103   if (smoothNormal == true) {
01104     hints |= NX_RAYCAST_NORMAL;
01105   }
01106   else {
01107     hints |= NX_RAYCAST_FACE_NORMAL;
01108   }
01109 
01110   _ptr->raycastClosestShape(ray._ray, (NxShapesType)shapesType, hit, 
01111                             mask.get_mask(), ray._length, hints, groupsPtr);
01112 
01113 
01114   return PhysxRaycastHit(hit);
01115 }
01116 
01117 ////////////////////////////////////////////////////////////////////
01118 //     Function: PhysxScene::raycast_all_shapes
01119 //       Access: Published
01120 //  Description: Returns a PhysxRaycastReport object which can be
01121 //               used to iterate over all shapes that have been
01122 //               hit by the ray.
01123 ////////////////////////////////////////////////////////////////////
01124 PhysxRaycastReport PhysxScene::
01125 raycast_all_shapes(const PhysxRay &ray,
01126                    PhysxShapesType shapesType,
01127                    PhysxMask mask,
01128                    PhysxGroupsMask *groups, bool smoothNormal) const {
01129 
01130   PhysxRaycastReport report;
01131 
01132   nassertr(_error_type == ET_ok, report);
01133 
01134   NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
01135 
01136   NxU32 hints = NX_RAYCAST_SHAPE | NX_RAYCAST_IMPACT | NX_RAYCAST_DISTANCE;
01137   if (smoothNormal == true) {
01138     hints |= NX_RAYCAST_NORMAL;
01139   }
01140   else {
01141     hints |= NX_RAYCAST_FACE_NORMAL;
01142   }
01143 
01144   _ptr->raycastAllShapes(ray._ray, report, (NxShapesType)shapesType,
01145                          mask.get_mask(), ray._length, hints, groupsPtr);
01146 
01147   return report;
01148 }
01149 
01150 ////////////////////////////////////////////////////////////////////
01151 //     Function: PhysxScene::raycast_any_bounds
01152 //       Access: Published
01153 //  Description: Returns true if any axis aligned bounding box
01154 //               enclosing a shape is intersected by the ray.
01155 ////////////////////////////////////////////////////////////////////
01156 bool PhysxScene::
01157 raycast_any_bounds(const PhysxRay &ray,
01158                          PhysxShapesType shapesType,
01159                          PhysxMask mask,
01160                          PhysxGroupsMask *groups) const {
01161 
01162   nassertr(_error_type == ET_ok, false);
01163 
01164   NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
01165 
01166   return _ptr->raycastAnyBounds(ray._ray, (NxShapesType)shapesType, 
01167                                 mask.get_mask(), ray._length, groupsPtr);
01168 }
01169 
01170 ////////////////////////////////////////////////////////////////////
01171 //     Function: PhysxScene::raycast_closest_bounds
01172 //       Access: Published
01173 //  Description: Returns the first axis aligned bounding box
01174 //               enclosing a shape that is hit along the ray.
01175 //               If not shape is hit then an empty raycast hit
01176 //               is returned (is_empty() == true).
01177 ////////////////////////////////////////////////////////////////////
01178 PhysxRaycastHit PhysxScene::
01179 raycast_closest_bounds(const PhysxRay &ray, PhysxShapesType shapesType, PhysxMask mask, PhysxGroupsMask *groups, bool smoothNormal) const {
01180 
01181   NxRaycastHit hit;
01182 
01183   nassertr(_error_type == ET_ok, hit);
01184 
01185   NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
01186 
01187   NxU32 hints = NX_RAYCAST_SHAPE | NX_RAYCAST_IMPACT | NX_RAYCAST_DISTANCE;
01188   if (smoothNormal == true) {
01189     hints |= NX_RAYCAST_NORMAL;
01190   }
01191   else {
01192     hints |= NX_RAYCAST_FACE_NORMAL;
01193   }
01194 
01195   _ptr->raycastClosestBounds(ray._ray, (NxShapesType)shapesType, hit, 
01196                              mask.get_mask(), ray._length, hints, groupsPtr);
01197 
01198 
01199   return PhysxRaycastHit(hit);
01200 }
01201 
01202 ////////////////////////////////////////////////////////////////////
01203 //     Function: PhysxScene::raycast_all_bounds
01204 //       Access: Published
01205 //  Description: Returns a PhysxRaycastReport object which can be
01206 //               used to iterate over all shapes that have been
01207 //               enclosed by axis aligned bounding boxes hit by
01208 //               the ray.
01209 ////////////////////////////////////////////////////////////////////
01210 PhysxRaycastReport PhysxScene::
01211 raycast_all_bounds(const PhysxRay &ray,
01212                          PhysxShapesType shapesType,
01213                          PhysxMask mask,
01214                          PhysxGroupsMask *groups, bool smoothNormal) const {
01215 
01216   PhysxRaycastReport report;
01217 
01218   nassertr(_error_type == ET_ok, report);
01219 
01220   NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
01221 
01222   NxU32 hints = NX_RAYCAST_SHAPE | NX_RAYCAST_IMPACT | NX_RAYCAST_DISTANCE;
01223   if (smoothNormal == true) {
01224     hints |= NX_RAYCAST_NORMAL;
01225   }
01226   else {
01227     hints |= NX_RAYCAST_FACE_NORMAL;
01228   }
01229 
01230   _ptr->raycastAllBounds(ray._ray, report, (NxShapesType)shapesType,
01231                          mask.get_mask(), ray._length, hints, groupsPtr);
01232 
01233   return report;
01234 }
01235 
01236 ////////////////////////////////////////////////////////////////////
01237 //     Function: PhysxScene::overlap_sphere_shapes
01238 //       Access: Published
01239 //  Description: Returns the set of shapes overlapped by the
01240 //               world-space sphere. 
01241 //               You can test against static and/or dynamic objects
01242 //               by adjusting 'shapeType'.
01243 ////////////////////////////////////////////////////////////////////
01244 PhysxOverlapReport PhysxScene::
01245 overlap_sphere_shapes(const LPoint3f &center, float radius,
01246                       PhysxShapesType shapesType,
01247                       PhysxMask mask, bool accurateCollision) const {
01248 
01249   PhysxOverlapReport report;
01250 
01251   nassertr(_error_type == ET_ok, report);
01252 
01253   NxSphere worldSphere(PhysxManager::point3_to_nxVec3(center), radius);
01254 
01255   _ptr->overlapSphereShapes(worldSphere, (NxShapesType)shapesType, 0, NULL, &report,
01256                             mask.get_mask(), NULL, accurateCollision);
01257 
01258   return report;
01259 }
01260 
01261 ////////////////////////////////////////////////////////////////////
01262 //     Function: PhysxScene::overlap_capsule_shapes
01263 //       Access: Published
01264 //  Description: Returns the set of shapes overlapped by the
01265 //               world-space capsule. 
01266 //               You can test against static and/or dynamic objects
01267 //               by adjusting 'shapeType'.
01268 ////////////////////////////////////////////////////////////////////
01269 PhysxOverlapReport PhysxScene::
01270 overlap_capsule_shapes(const LPoint3f &p0, const LPoint3f &p1, float radius,
01271                        PhysxShapesType shapesType,
01272                        PhysxMask mask, bool accurateCollision) const {
01273 
01274   PhysxOverlapReport report;
01275 
01276   nassertr(_error_type == ET_ok, report);
01277 
01278   NxSegment segment(PhysxManager::point3_to_nxVec3(p0),
01279                     PhysxManager::point3_to_nxVec3(p1));
01280   NxCapsule worldCapsule(segment, radius);
01281 
01282   _ptr->overlapCapsuleShapes(worldCapsule, (NxShapesType)shapesType, 0, NULL, &report,
01283                              mask.get_mask(), NULL, accurateCollision);
01284 
01285   return report;
01286 }
01287 
01288 ////////////////////////////////////////////////////////////////////
01289 //     Function: PhysxScene::set_actor_pair_flag
01290 //       Access: Published
01291 //  Description: Sets the pair flags for the given pair of actors. 
01292 //
01293 //               Calling this on an actor that has no shape(s) has
01294 //               no effect. The two actor references must not
01295 //               reference the same actor.
01296 //
01297 //               It is important to note that the engine stores
01298 //               pair flags per shape, even for actor pair flags.
01299 //               This means that shapes should be created before
01300 //               actor pair flags are set, otherwise the pair flags
01301 //               will be ignored.
01302 ////////////////////////////////////////////////////////////////////
01303 void PhysxScene::
01304 set_actor_pair_flag(PhysxActor &actorA, PhysxActor &actorB,
01305                     PhysxContactPairFlag flag, bool value) {
01306 
01307   nassertv(_error_type == ET_ok);
01308 
01309   NxActor *ptrA = actorA.ptr();
01310   NxActor *ptrB = actorB.ptr();
01311   NxU32 flags = _ptr->getActorPairFlags(*ptrA, *ptrB); 
01312 
01313   if (value == true) {
01314     flags |= flag;
01315   }
01316   else {
01317     flags &= ~(flag);
01318   }
01319 
01320   _ptr->setActorPairFlags(*ptrA, *ptrB, flags);
01321 }
01322 
01323 ////////////////////////////////////////////////////////////////////
01324 //     Function: PhysxScene::get_actor_pair_flag
01325 //       Access: Published
01326 //  Description: Retrieves a single flag for the given pair of
01327 //               actors.
01328 // 
01329 //               The two actor references must not reference the
01330 //               same actor.
01331 ////////////////////////////////////////////////////////////////////
01332 bool PhysxScene::
01333 get_actor_pair_flag(PhysxActor &actorA, PhysxActor &actorB,
01334                     PhysxContactPairFlag flag) {
01335 
01336   nassertr(_error_type == ET_ok, false);
01337 
01338   NxActor *ptrA = actorA.ptr();
01339   NxActor *ptrB = actorB.ptr();
01340   NxU32 flags = _ptr->getActorPairFlags(*ptrA, *ptrB); 
01341 
01342   return (flags && flag) ? true : false;
01343 }
01344 
01345 ////////////////////////////////////////////////////////////////////
01346 //     Function: PhysxScene::set_shape_pair_flag
01347 //       Access: Published
01348 //  Description: Disables or enables contact generation for a pair
01349 //               of shapes.
01350 //
01351 //               The two shape references must not reference the
01352 //               same shape.
01353 ////////////////////////////////////////////////////////////////////
01354 void PhysxScene::
01355 set_shape_pair_flag(PhysxShape &shapeA, PhysxShape &shapeB, bool value) {
01356 
01357   nassertv(_error_type == ET_ok);
01358 
01359   NxShape *ptrA = shapeA.ptr();
01360   NxShape *ptrB = shapeB.ptr();
01361   NxU32 flags = _ptr->getShapePairFlags(*ptrA, *ptrB); 
01362 
01363   if (value == true) {
01364     flags |= NX_IGNORE_PAIR;
01365   }
01366   else {
01367     flags &= ~(NX_IGNORE_PAIR);
01368   }
01369 
01370   _ptr->setShapePairFlags(*ptrA, *ptrB, flags);
01371 }
01372 
01373 ////////////////////////////////////////////////////////////////////
01374 //     Function: PhysxScene::get_shape_pair_flag
01375 //       Access: Published
01376 //  Description: Returns /true/ if contact generation between a pair
01377 //               of shapes is enabled, and /false/ if contact
01378 //               generation is disables.
01379 //
01380 //               The two shape references must not reference the
01381 //               same shape.
01382 ////////////////////////////////////////////////////////////////////
01383 bool PhysxScene::
01384 get_shape_pair_flag(PhysxShape &shapeA, PhysxShape &shapeB) {
01385 
01386   nassertr(_error_type == ET_ok, false);
01387 
01388   NxShape *ptrA = shapeA.ptr();
01389   NxShape *ptrB = shapeB.ptr();
01390   NxU32 flags = _ptr->getShapePairFlags(*ptrA, *ptrB); 
01391 
01392   return (flags && NX_IGNORE_PAIR) ? true : false;
01393 }
01394 
01395 ////////////////////////////////////////////////////////////////////
01396 //     Function: PhysxScene::set_actor_group_pair_flag
01397 //       Access: Published
01398 //  Description: With this method one can set contact reporting
01399 //               flags between actors belonging to a pair of groups. 
01400 //
01401 //               It is possible to assign each actor to a group
01402 //               using PhysxActor::set_group(). This is a different
01403 //               set of groups from the shape groups despite the
01404 //               similar name. Here up to 0xffff different groups
01405 //               are permitted, With this method one can set
01406 //               contact reporting flags between actors belonging
01407 //               to a pair of groups.
01408 //
01409 //               The following flags are permitted:
01410 //               - CPF_start_touch
01411 //               - CPF_end_touch
01412 //               - CPF_touch
01413 //               - CPF_start_touch_treshold
01414 //               - CPF_end_touch_treshold
01415 //               - CPF_touch_treshold
01416 //
01417 //               Note that finer grain control of pairwise flags is
01418 //               possible using the function
01419 //               PhysxScene::set_actor_pair_flags().
01420 ////////////////////////////////////////////////////////////////////
01421 void PhysxScene::
01422 set_actor_group_pair_flag(unsigned int g1, unsigned int g2,
01423                           PhysxContactPairFlag flag, bool value) {
01424 
01425   nassertv(_error_type == ET_ok);
01426 
01427   NxU32 flags = _ptr->getActorGroupPairFlags(g1, g2); 
01428   if (value == true) {
01429     flags |= flag;
01430   }
01431   else {
01432     flags &= ~(flag);
01433   }
01434   _ptr->setActorGroupPairFlags(g1, g2, flags);
01435 }
01436 
01437 ////////////////////////////////////////////////////////////////////
01438 //     Function: PhysxScene::get_actor_group_pair_flag
01439 //       Access: Published
01440 //  Description: Retrieves a single flag set with
01441 //               PhysxScene::set_actor_group_pair_flag()
01442 ////////////////////////////////////////////////////////////////////
01443 bool PhysxScene::
01444 get_actor_group_pair_flag(unsigned int g1, unsigned int g2,
01445                           PhysxContactPairFlag flag) {
01446 
01447   nassertr(_error_type == ET_ok, false);
01448   NxU32 flags = _ptr->getActorGroupPairFlags(g1, g2); 
01449   return (flags && flag) ? true : false;
01450 }
01451 
01452 ////////////////////////////////////////////////////////////////////
01453 //     Function: PhysxScene::set_filter_ops
01454 //       Access: Published
01455 //  Description: Setups filtering operations.
01456 ////////////////////////////////////////////////////////////////////
01457 void PhysxScene::
01458 set_filter_ops(PhysxFilterOp op0, PhysxFilterOp op1, PhysxFilterOp op2) {
01459 
01460   nassertv(_error_type == ET_ok);
01461   _ptr->setFilterOps((NxFilterOp)op0, (NxFilterOp)op1, (NxFilterOp)op2);
01462 }
01463 
01464 ////////////////////////////////////////////////////////////////////
01465 //     Function: PhysxScene::set_filter_bool
01466 //       Access: Published
01467 //  Description: Setups filtering's boolean value.
01468 ////////////////////////////////////////////////////////////////////
01469 void PhysxScene::
01470 set_filter_bool(bool flag) {
01471 
01472   nassertv(_error_type == ET_ok);
01473   _ptr->setFilterBool(flag);
01474 }
01475 
01476 ////////////////////////////////////////////////////////////////////
01477 //     Function: PhysxScene::set_filter_constant0
01478 //       Access: Published
01479 //  Description: Setups filtering's K0 value.
01480 ////////////////////////////////////////////////////////////////////
01481 void PhysxScene::
01482 set_filter_constant0(const PhysxGroupsMask &mask) {
01483 
01484   nassertv(_error_type == ET_ok);
01485   _ptr->setFilterConstant0(mask.get_mask());
01486 }
01487 
01488 ////////////////////////////////////////////////////////////////////
01489 //     Function: PhysxScene::set_filter_constant1
01490 //       Access: Published
01491 //  Description: Setups filtering's K1 value.
01492 ////////////////////////////////////////////////////////////////////
01493 void PhysxScene::
01494 set_filter_constant1(const PhysxGroupsMask &mask) {
01495 
01496   nassertv(_error_type == ET_ok);
01497   _ptr->setFilterConstant1(mask.get_mask());
01498 }
01499 
01500 ////////////////////////////////////////////////////////////////////
01501 //     Function: PhysxScene::get_filter_bool
01502 //       Access: Published
01503 //  Description: Retrieves filtering's boolean value.
01504 ////////////////////////////////////////////////////////////////////
01505 bool PhysxScene::
01506 get_filter_bool() const {
01507 
01508   nassertr(_error_type == ET_ok, false);
01509   return _ptr->getFilterBool();
01510 }
01511 
01512 ////////////////////////////////////////////////////////////////////
01513 //     Function: PhysxScene::get_filter_constant0
01514 //       Access: Published
01515 //  Description: Gets filtering constant K0.
01516 ////////////////////////////////////////////////////////////////////
01517 PhysxGroupsMask PhysxScene::
01518 get_filter_constant0() const {
01519 
01520   PhysxGroupsMask mask;
01521 
01522   nassertr(_error_type == ET_ok, mask);
01523 
01524   NxGroupsMask _mask = ptr()->getFilterConstant0();
01525   mask.set_mask(_mask);
01526 
01527   return mask;
01528 }
01529 
01530 ////////////////////////////////////////////////////////////////////
01531 //     Function: PhysxScene::get_filter_constant1
01532 //       Access: Published
01533 //  Description: Gets filtering constant K1.
01534 ////////////////////////////////////////////////////////////////////
01535 PhysxGroupsMask PhysxScene::
01536 get_filter_constant1() const {
01537 
01538   PhysxGroupsMask mask;
01539 
01540   nassertr(_error_type == ET_ok, mask);
01541 
01542   NxGroupsMask _mask = ptr()->getFilterConstant1();
01543   mask.set_mask(_mask);
01544 
01545   return mask;
01546 }
01547 
01548 ////////////////////////////////////////////////////////////////////
01549 //     Function: PhysxScene::get_filter_op0
01550 //       Access: Published
01551 //  Description: Retrieves the op0 filtering operation.
01552 ////////////////////////////////////////////////////////////////////
01553 PhysxEnums::PhysxFilterOp PhysxScene::
01554 get_filter_op0() const {
01555 
01556   nassertr(_error_type == ET_ok, FO_and);
01557 
01558   NxFilterOp op0;
01559   NxFilterOp op1;
01560   NxFilterOp op2;
01561 
01562   _ptr->getFilterOps(op0, op1, op2);
01563 
01564   return (PhysxFilterOp)op0;
01565 }
01566 
01567 ////////////////////////////////////////////////////////////////////
01568 //     Function: PhysxScene::get_filter_op1
01569 //       Access: Published
01570 //  Description: Retrieves the op1 filtering operation.
01571 ////////////////////////////////////////////////////////////////////
01572 PhysxEnums::PhysxFilterOp PhysxScene::
01573 get_filter_op1() const {
01574 
01575   nassertr(_error_type == ET_ok, FO_and);
01576 
01577   NxFilterOp op0;
01578   NxFilterOp op1;
01579   NxFilterOp op2;
01580 
01581   _ptr->getFilterOps(op0, op1, op2);
01582 
01583   return (PhysxFilterOp)op1;
01584 }
01585 
01586 ////////////////////////////////////////////////////////////////////
01587 //     Function: PhysxScene::get_filter_op2
01588 //       Access: Published
01589 //  Description: Retrieves the op2 filtering operation.
01590 ////////////////////////////////////////////////////////////////////
01591 PhysxEnums::PhysxFilterOp PhysxScene::
01592 get_filter_op2() const {
01593 
01594   nassertr(_error_type == ET_ok, FO_and);
01595 
01596   NxFilterOp op0;
01597   NxFilterOp op1;
01598   NxFilterOp op2;
01599 
01600   _ptr->getFilterOps(op0, op1, op2);
01601 
01602   return (PhysxFilterOp)op2;
01603 }
01604 
01605 ////////////////////////////////////////////////////////////////////
01606 //     Function: PhysxScene::set_group_collision_flag
01607 //       Access: Published
01608 //  Description: Specifies if collision should be performed by a
01609 //               pair of shape groups. 
01610 //
01611 //               It is possible to assign each shape to a collision
01612 //               groups using PhysxShape::set_group(). With this
01613 //               method one can set whether collisions should be
01614 //               detected between shapes belonging to a given pair
01615 //               of groups. Initially all pairs are enabled.
01616 //
01617 //               Fluids can be assigned to collision groups as well.
01618 //
01619 //               Collision groups are integers between 0 and 31.
01620 ////////////////////////////////////////////////////////////////////
01621 void PhysxScene::
01622 set_group_collision_flag(unsigned int g1, unsigned int g2, bool enable) {
01623 
01624   nassertv(_error_type == ET_ok);
01625   nassertv(g1 >= 0 && g1 < 32);
01626   nassertv(g2 >= 0 && g2 < 32);
01627 
01628   _ptr->setGroupCollisionFlag((NxCollisionGroup)g1, (NxCollisionGroup)g2, enable);
01629 }
01630 
01631 ////////////////////////////////////////////////////////////////////
01632 //     Function: PhysxScene::get_group_collision_flag
01633 //       Access: Published
01634 //  Description: Determines if collision detection is performed
01635 //               between a pair of groups. Collision groups are
01636 //               integers between 0 and 31.
01637 ////////////////////////////////////////////////////////////////////
01638 bool PhysxScene::
01639 get_group_collision_flag(unsigned int g1, unsigned int g2) {
01640 
01641   nassertr(_error_type == ET_ok, false);
01642   nassertr(g1 >= 0 && g1 < 32, false);
01643   nassertr(g2 >= 0 && g2 < 32, false);
01644 
01645   return _ptr->getGroupCollisionFlag((NxCollisionGroup)g1, (NxCollisionGroup)g2);
01646 }
01647 
01648 ////////////////////////////////////////////////////////////////////
01649 //     Function: PhysxScene::get_flag
01650 //       Access: Published
01651 //  Description: Return the specified scene flag flag.
01652 ////////////////////////////////////////////////////////////////////
01653 bool PhysxScene::
01654 get_flag(PhysxSceneFlag flag) const {
01655 
01656   nassertr(_error_type == ET_ok, false);
01657   return (_ptr->getFlags() & flag) ? true : false;
01658 }
01659 
01660 ////////////////////////////////////////////////////////////////////
01661 //     Function: PhysxScene::is_hardware_scene
01662 //       Access: Published
01663 //  Description: Returns TRUE if the the scene is simulated in
01664 //               hardware. FALSE if the scene is simulated in
01665 //               software.
01666 ////////////////////////////////////////////////////////////////////
01667 bool PhysxScene::
01668 is_hardware_scene() const {
01669 
01670   nassertr(_error_type == ET_ok, false);
01671   return (_ptr->getSimType() & NX_SIMULATION_HW) ? true : false;
01672 }
01673 
01674 ////////////////////////////////////////////////////////////////////
01675 //     Function: PhysxScene::set_dominance_group_pair
01676 //       Access: Published
01677 //  Description: Specifies the dominance behavior of constraints 
01678 //               between two actors with two certain dominance
01679 //               groups. 
01680 //
01681 //               It is possible to assign each actor to a dominance
01682 //               groups using PhysxActor::set_dominance_group().
01683 //
01684 //               With dominance groups one can have all constraints
01685 //               (contacts and joints) created between actors act in
01686 //               one direction only. This is useful if you want to
01687 //               make sure that the movement of the rider of a
01688 //               vehicle or the pony tail of a character doesn't
01689 //               influence the object it is attached to, while
01690 //               keeping the motion of both inherently physical.
01691 //
01692 //               Whenever a constraint (i.e. joint or contact)
01693 //               between two actors (a0, a1) needs to be solved, the
01694 //               groups (g0, g1) of both actors are retrieved. Then
01695 //               the constraint dominance setting for this group
01696 //               pair is retrieved.
01697 //
01698 //               In the constraint, PhysxConstraintDominance::get_0()
01699 //               becomes the dominance setting for a0, and
01700 //               PhysxConstraintDominance::get_1() becomes the
01701 //               dominance setting for a1. A dominance setting of
01702 //               1.0f, the default, will permit the actor to be
01703 //               pushed or pulled by the other actor. A dominance
01704 //               setting of 0.0f will however prevent the actor to
01705 //               be pushed or pulled by the other actor. Thus, a
01706 //               PhysxConstraintDominance of (1.0f, 0.0f) makes the
01707 //               interaction one-way.
01708 //
01709 //               The dominance matrix is initialised by default such
01710 //               that:
01711 //               - if g1 == g2, then (1.0f, 1.0f) is returned
01712 //               - if g1 < g2, then (0.0f, 1.0f) is returned
01713 //               - if g1 > g2, then (1.0f, 0.0f) is returned
01714 //
01715 //               In other words, actors in higher groups can be
01716 //               pushed around by actors in lower groups by default.
01717 //
01718 //               These settings should cover most applications, and
01719 //               in fact not overriding these settings may likely
01720 //               result in higher performance.
01721 //
01722 //               Dominance settings are currently specified as
01723 //               floats 0.0f or 1.0f because in the future PhysX may
01724 //               permit arbitrary fractional settings to express
01725 //               'partly-one-way' interactions.
01726 ////////////////////////////////////////////////////////////////////
01727 void PhysxScene::
01728 set_dominance_group_pair(unsigned int g1, unsigned int g2, PhysxConstraintDominance dominance ) {
01729 
01730   nassertv(_error_type == ET_ok);
01731   nassertv(g1 < 32);
01732   nassertv(g2 < 32);
01733 
01734   NxConstraintDominance d = dominance.get_dominance();
01735   _ptr->setDominanceGroupPair((NxDominanceGroup)g1, (NxDominanceGroup)g2, d);
01736 }
01737 
01738 ////////////////////////////////////////////////////////////////////
01739 //     Function: PhysxScene::get_dominance_group_pair
01740 //       Access: Published
01741 //  Description: Samples the dominance matrix.
01742 ////////////////////////////////////////////////////////////////////
01743 PhysxConstraintDominance PhysxScene::
01744 get_dominance_group_pair(unsigned int g1, unsigned int g2) {
01745 
01746   PhysxConstraintDominance result(1.0f, 1.0f);
01747 
01748   nassertr(_error_type == ET_ok, result);
01749   nassertr(g1 < 32, result);
01750   nassertr(g2 < 32, result);
01751 
01752   result.set_dominance(_ptr->getDominanceGroupPair((NxDominanceGroup)g1, (NxDominanceGroup)g2));
01753   return result;
01754 }
01755 
01756 ////////////////////////////////////////////////////////////////////
01757 //     Function: PhysxScene::get_wheel_shape_material
01758 //       Access: Published
01759 //  Description: Gets the shared material for all wheel shapes.
01760 //
01761 //               If this material is not already created then
01762 //               calling this method will create the material.
01763 //
01764 //               Normally users don't need to call this method. It
01765 //               is used internally by PhysWheel::create_wheel.
01766 ////////////////////////////////////////////////////////////////////
01767 PhysxMaterial *PhysxScene::
01768 get_wheel_shape_material() {
01769 
01770   nassertr(_error_type == ET_ok, NULL);
01771 
01772   if (_wheelShapeMaterial == NULL) {
01773     PhysxMaterialDesc materialDesc;
01774     materialDesc.set_flag(PhysxMaterialDesc::MF_disable_friction, true);
01775     _wheelShapeMaterial = create_material(materialDesc);
01776   }
01777 
01778   return _wheelShapeMaterial;
01779 }
01780 
 All Classes Functions Variables Enumerations