Panda3D
|
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 ¢er, 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