1635 lines
53 KiB
C++
1635 lines
53 KiB
C++
// Filename: physxScene.cxx
|
|
// Created by: enn0x (14Sep09)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
|
//
|
|
// All use of this software is subject to the terms of the revised BSD
|
|
// license. You should have received a copy of this license along
|
|
// with this source code in a file named "LICENSE."
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
#include "physxScene.h"
|
|
#include "physxManager.h"
|
|
#include "physxActorDesc.h"
|
|
#include "physxForceFieldDesc.h"
|
|
#include "physxForceFieldShapeGroupDesc.h"
|
|
#include "physxControllerDesc.h"
|
|
#include "physxSceneStats2.h"
|
|
#include "physxConstraintDominance.h"
|
|
#include "physxVehicle.h"
|
|
#include "physxVehicleDesc.h"
|
|
|
|
TypeHandle PhysxScene::_type_handle;
|
|
|
|
PStatCollector PhysxScene::_pcollector_fetch_results("App:PhysX:Fetch Results");
|
|
PStatCollector PhysxScene::_pcollector_update_transforms("App:PhysX:Update Transforms");
|
|
PStatCollector PhysxScene::_pcollector_debug_renderer("App:PhysX:Debug Renderer");
|
|
PStatCollector PhysxScene::_pcollector_simulate("App:PhysX:Simulate");
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::link
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
link(NxScene *scenePtr) {
|
|
|
|
// Link self
|
|
_ptr = scenePtr;
|
|
_ptr->userData = this;
|
|
_error_type = ET_ok;
|
|
PhysxManager::get_global_ptr()->_scenes.add(this);
|
|
|
|
_cm = NxCreateControllerManager(NxGetPhysicsSDKAllocator());
|
|
nassertv_always(_cm);
|
|
|
|
// Link materials
|
|
NxMaterial *materials[5];
|
|
NxU32 iterator = 0;
|
|
|
|
while (NxU32 i=_ptr->getMaterialArray(materials, 5, iterator)) {
|
|
while(i--) {
|
|
PhysxMaterial *material = new PhysxMaterial();
|
|
material->link(materials[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::unlink
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
unlink() {
|
|
|
|
// Unlink vehicles
|
|
for (unsigned int i=0; i < _vehicles.size(); i++) {
|
|
_vehicles[i]->release();
|
|
}
|
|
|
|
// Unlink controllers
|
|
NxU32 nControllers = _cm->getNbControllers();
|
|
|
|
for (NxU32 i=0; i < nControllers; i++) {
|
|
NxController *controllerPtr = _cm->getController(i);
|
|
PhysxController *controller = (PhysxController *)controllerPtr->getUserData();
|
|
controller->unlink();
|
|
}
|
|
|
|
// Unlink actors
|
|
NxActor **actors = _ptr->getActors();
|
|
NxU32 nActors = _ptr->getNbActors();
|
|
|
|
for (NxU32 i=0; i < nActors; i++) {
|
|
PhysxActor *actor = (PhysxActor *)actors[i]->userData;
|
|
|
|
// Actor could have already been unlinked by controller
|
|
if (actor) {
|
|
actor->unlink();
|
|
}
|
|
}
|
|
|
|
// Unlink joints
|
|
NxU32 nJoints = _ptr->getNbJoints();
|
|
|
|
_ptr->resetJointIterator();
|
|
for (NxU32 i=0; i < nJoints; i++) {
|
|
NxJoint *jointPtr = _ptr->getNextJoint();
|
|
PhysxJoint *joint = (PhysxJoint *)jointPtr->userData;
|
|
joint->unlink();
|
|
}
|
|
|
|
// Unlink force fields
|
|
NxForceField **fields = _ptr->getForceFields();
|
|
NxU32 nFields = _ptr->getNbForceFields();
|
|
|
|
for (NxU32 i=0; i < nFields; i++) {
|
|
PhysxForceField *field = (PhysxForceField *)fields[i]->userData;
|
|
field->unlink();
|
|
}
|
|
|
|
// Unlink force field shape groups
|
|
NxU32 nGroups = _ptr->getNbForceFieldShapeGroups();
|
|
|
|
_ptr->resetForceFieldShapeGroupsIterator();
|
|
for (NxU32 i=0; i < nGroups; i++) {
|
|
NxForceFieldShapeGroup *groupPtr = _ptr->getNextForceFieldShapeGroup();
|
|
PhysxForceFieldShapeGroup *group = (PhysxForceFieldShapeGroup *)groupPtr->userData;
|
|
group->unlink();
|
|
}
|
|
|
|
// Unlink cloths TODO
|
|
// Unlink softbodies TODO
|
|
|
|
// Unlink materials
|
|
NxMaterial *materials[5];
|
|
NxU32 iterator = 0;
|
|
|
|
while (NxU32 i=_ptr->getMaterialArray(materials, 5, iterator)) {
|
|
while(i--) {
|
|
PhysxMaterial *material = (PhysxMaterial *)materials[i]->userData;
|
|
material->unlink();
|
|
}
|
|
}
|
|
|
|
// Unlink self
|
|
_cm->purgeControllers();
|
|
NxReleaseControllerManager(_cm);
|
|
|
|
_ptr->userData = NULL;
|
|
_error_type = ET_released;
|
|
|
|
PhysxManager::get_global_ptr()->_scenes.remove(this);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::release
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
release() {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
|
|
unlink();
|
|
NxPhysicsSDK *sdk = NxGetPhysicsSDK();
|
|
sdk->releaseScene(*_ptr);
|
|
_ptr = NULL;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::simulate
|
|
// Access: Published
|
|
// Description: Advances the simulation by an elapsedTime time.
|
|
// The elapsed time has to be in the range (0, inf).
|
|
//
|
|
// It is not allowed to modify the physics scene in
|
|
// between the simulate(dt) and the fetch_results
|
|
// calls! But it is allowed to read from the scene
|
|
// and do additional computations, e. g. AI, in
|
|
// between these calls.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
simulate(float dt) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
|
|
_pcollector_simulate.start();
|
|
|
|
// Update all vehicles
|
|
for (unsigned int i=0; i < _vehicles.size(); i++) {
|
|
PhysxVehicle *vehicle = _vehicles[i];
|
|
vehicle->update_vehicle(dt);
|
|
}
|
|
|
|
// Update all controllers
|
|
for (NxU32 i=0; i < _cm->getNbControllers(); i++) {
|
|
NxController *controllerPtr = _cm->getController(i);
|
|
PhysxController *controller = (PhysxController *)controllerPtr->getUserData();
|
|
controller->update_controller(dt);
|
|
}
|
|
|
|
_cm->updateControllers();
|
|
|
|
// Simulate and flush streams
|
|
_ptr->simulate(dt);
|
|
_ptr->flushStream();
|
|
|
|
_pcollector_simulate.stop();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::fetch_results
|
|
// Access: Published
|
|
// Description: Waits until the simulation has finished, and then
|
|
// updates the scene graph with with simulation
|
|
// results.
|
|
//
|
|
// It is not allowed to modify the physics scene in
|
|
// between the simulate(dt) and the fetch_results
|
|
// calls! But it is allowed to read from the scene
|
|
// and do additional computations, e. g. AI, in
|
|
// between these calls.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
fetch_results() {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
|
|
_pcollector_fetch_results.start();
|
|
_ptr->fetchResults(NX_RIGID_BODY_FINISHED, true);
|
|
_pcollector_fetch_results.stop();
|
|
|
|
// Update node transforms
|
|
_pcollector_update_transforms.start();
|
|
|
|
NxU32 nbTransforms = 0;
|
|
NxActiveTransform *activeTransforms = _ptr->getActiveTransforms(nbTransforms);
|
|
|
|
if (nbTransforms && activeTransforms) {
|
|
for (NxU32 i=0; i<nbTransforms; ++i) {
|
|
|
|
// Objects created by the Visual Remote Debugger might not have
|
|
// user data. So check if user data ist set.
|
|
void *userData = activeTransforms[i].userData;
|
|
if (userData) {
|
|
LMatrix4f m = PhysxManager::nxMat34_to_mat4(activeTransforms[i].actor2World);
|
|
PhysxActor *actor = (PhysxActor *)userData;
|
|
actor->update_transform(m);
|
|
}
|
|
}
|
|
}
|
|
_pcollector_update_transforms.stop();
|
|
|
|
// Update debug node
|
|
_pcollector_debug_renderer.start();
|
|
_debugNode->update(_ptr);
|
|
_pcollector_debug_renderer.stop();
|
|
|
|
nassertv(_ptr->isWritable());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::set_timing_variable
|
|
// Access: Published
|
|
// Description: Sets simulation timing parameters used in simulate.
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
set_timing_variable() {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
_ptr->setTiming(NULL, NULL, NX_TIMESTEP_VARIABLE);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::set_timing_fixed
|
|
// Access: Published
|
|
// Description: Sets simulation timing parameters used in simulate.
|
|
// The elapsed time (parameter "dt" in simulate()) is
|
|
// internally subdivided into up to maxIter substeps
|
|
// no larger than maxTimestep. If the elapsed time is
|
|
// not a multiple of maxTimestep then any remaining
|
|
// time is accumulated to be added onto the elapsed
|
|
// time for the next time step. If more sub steps than
|
|
// maxIter are needed to advance the simulation by
|
|
// elapsed time, then the remaining time is also
|
|
// accumulated for the next call to simulate().
|
|
//
|
|
// This timing method is strongly preferred for
|
|
// stable, reproducible simulation.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
set_timing_fixed(float maxTimestep, unsigned int maxIter) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
_ptr->setTiming(maxTimestep, maxIter, NX_TIMESTEP_FIXED);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::set_gravity
|
|
// Access: Published
|
|
// Description: Sets a constant gravity for the entire scene.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
set_gravity(const LVector3f &gravity) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
nassertv_always(!gravity.is_nan());
|
|
|
|
_ptr->setGravity(PhysxManager::vec3_to_nxVec3(gravity));
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_gravity
|
|
// Access: Published
|
|
// Description: Retrieves the current gravity setting.
|
|
////////////////////////////////////////////////////////////////////
|
|
LVector3f PhysxScene::
|
|
get_gravity() const {
|
|
|
|
nassertr(_error_type == ET_ok, LVector3f::zero());
|
|
|
|
NxVec3 gravity;
|
|
_ptr->getGravity(gravity);
|
|
return PhysxManager::nxVec3_to_vec3(gravity);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_num_actors
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
unsigned int PhysxScene::
|
|
get_num_actors() const {
|
|
|
|
nassertr(_error_type == ET_ok,-1);
|
|
|
|
return _ptr->getNbActors();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::create_actor
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxActor *PhysxScene::
|
|
create_actor(PhysxActorDesc &desc) {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
nassertr(desc.is_valid(), NULL);
|
|
|
|
PhysxActor *actor = new PhysxActor();
|
|
nassertr(actor, NULL);
|
|
|
|
NxActor *actorPtr = _ptr->createActor(desc._desc);
|
|
nassertr(actorPtr, NULL);
|
|
|
|
actor->link(actorPtr);
|
|
|
|
return actor;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_actor
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxActor *PhysxScene::
|
|
get_actor(unsigned int idx) const {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
nassertr_always(idx < _ptr->getNbActors(), NULL);
|
|
|
|
NxActor *actorPtr = _ptr->getActors()[idx];
|
|
PhysxActor *actor = (PhysxActor *)(actorPtr->userData);
|
|
|
|
return actor;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_debug_node
|
|
// Access: Published
|
|
// Description: Retrieves the debug geom node for this scene. The
|
|
// debug geom node is used to visualize information
|
|
// about the physical scene which can be useful for
|
|
// debugging an application.
|
|
//
|
|
// The debug geom node geometry is generated in global
|
|
// coordinates. In order to see correct information
|
|
// it is important not to dislocate the debug node.
|
|
// Reparent it to render and leave position at
|
|
// (0,0,0).
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxDebugGeomNode *PhysxScene::
|
|
get_debug_geom_node() {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
return _debugNode;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::enable_contact_reporting
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
enable_contact_reporting(bool enabled) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
|
|
if (enabled) {
|
|
_ptr->setUserContactReport(&_contact_report);
|
|
_contact_report.enable();
|
|
}
|
|
else {
|
|
_ptr->setUserContactReport(NULL);
|
|
_contact_report.disable();
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::is_contact_reporting_enabled
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PhysxScene::
|
|
is_contact_reporting_enabled() const {
|
|
|
|
nassertr(_error_type == ET_ok, false);
|
|
|
|
return _contact_report.is_enabled();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::enable_trigger_reporting
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
enable_trigger_reporting(bool enabled) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
|
|
if (enabled) {
|
|
_ptr->setUserTriggerReport(&_trigger_report);
|
|
_trigger_report.enable();
|
|
}
|
|
else {
|
|
_ptr->setUserTriggerReport(NULL);
|
|
_trigger_report.disable();
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::is_trigger_reporting_enabled
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PhysxScene::
|
|
is_trigger_reporting_enabled() const {
|
|
|
|
nassertr(_error_type == ET_ok, false);
|
|
|
|
return _trigger_report.is_enabled();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::enable_controller_reporting
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
enable_controller_reporting(bool enabled) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
|
|
if (enabled) {
|
|
_controller_report.enable();
|
|
}
|
|
else {
|
|
_controller_report.disable();
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::is_controller_reporting_enabled
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PhysxScene::
|
|
is_controller_reporting_enabled() const {
|
|
|
|
nassertr(_error_type == ET_ok, false);
|
|
|
|
return _controller_report.is_enabled();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_num_materials
|
|
// Access: Published
|
|
// Description: Return the number of materials in the scene.
|
|
//
|
|
// Note that the returned value is not related to
|
|
// material indices. Those may not be allocated
|
|
// continuously, and its values may be higher than
|
|
// get_num_materials(). This will also include the
|
|
// default material which exists without having to
|
|
// be created.
|
|
////////////////////////////////////////////////////////////////////
|
|
unsigned int PhysxScene::
|
|
get_num_materials() const {
|
|
|
|
nassertr(_error_type == ET_ok, -1);
|
|
return _ptr->getNbMaterials();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::create_material
|
|
// Access: Published
|
|
// Description: Creates a new PhysxMaterial.
|
|
//
|
|
// The material library consists of an array of
|
|
// material objects. Each material has a well defined
|
|
// index that can be used to refer to it. If an object
|
|
// references an undefined material, the default
|
|
// material with index 0 is used instead.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxMaterial *PhysxScene::
|
|
create_material(PhysxMaterialDesc &desc) {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
nassertr(desc.is_valid(), NULL);
|
|
|
|
PhysxMaterial *material = new PhysxMaterial();
|
|
nassertr(material, NULL);
|
|
|
|
NxMaterial *materialPtr = _ptr->createMaterial(desc._desc);
|
|
nassertr(materialPtr, NULL);
|
|
|
|
material->link(materialPtr);
|
|
|
|
return material;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::create_material
|
|
// Access: Published
|
|
// Description: Creates a new PhysxMaterial using the default
|
|
// settings of PhysxMaterialDesc.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxMaterial *PhysxScene::
|
|
create_material() {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
|
|
PhysxMaterial *material = new PhysxMaterial();
|
|
nassertr(material, NULL);
|
|
|
|
NxMaterialDesc desc;
|
|
desc.setToDefault();
|
|
NxMaterial *materialPtr = _ptr->createMaterial(desc);
|
|
nassertr(materialPtr, NULL);
|
|
|
|
material->link(materialPtr);
|
|
|
|
return material;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_hightest_material_index
|
|
// Access: Published
|
|
// Description: Returns current highest valid material index.
|
|
//
|
|
// Note that not all indices below this are valid if
|
|
// some of them belong to meshes that have beed
|
|
// freed.
|
|
////////////////////////////////////////////////////////////////////
|
|
unsigned int PhysxScene::
|
|
get_hightest_material_index() const {
|
|
|
|
nassertr(_error_type == ET_ok, -1);
|
|
return _ptr->getHighestMaterialIndex();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_material_from_index
|
|
// Access: Published
|
|
// Description: Retrieves the material with the given material
|
|
// index.
|
|
//
|
|
// There is always at least one material in the Scene,
|
|
// the default material (index 0). If the specified
|
|
// material index is out of range (larger than
|
|
// get_hightest_material_index) or belongs to a
|
|
// material that has been released, then the default
|
|
// material is returned, but no error is reported.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxMaterial *PhysxScene::
|
|
get_material_from_index(unsigned int idx) const {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
|
|
NxMaterial *materialPtr = _ptr->getMaterialFromIndex(idx);
|
|
|
|
return (PhysxMaterial *)(materialPtr->userData);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_material
|
|
// Access: Published
|
|
// Description: Retrieves the n-th material from the array of
|
|
// materials. See also get_material_from_index,
|
|
// which retrieves a material by it's material index.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxMaterial *PhysxScene::
|
|
get_material(unsigned int idx) const {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
nassertr_always(idx < _ptr->getNbMaterials(), NULL);
|
|
|
|
NxU32 n = _ptr->getNbMaterials();
|
|
NxMaterial **materials = new NxMaterial *[n];
|
|
NxU32 materialCount;
|
|
NxU32 iterator = 0;
|
|
|
|
materialCount = _ptr->getMaterialArray(materials, n, iterator);
|
|
nassertr((materialCount == n), NULL);
|
|
|
|
NxMaterial *materialPtr = materials[idx];
|
|
delete[] materials;
|
|
|
|
return (PhysxMaterial *)(materialPtr->userData);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_num_controllers
|
|
// Access: Published
|
|
// Description: Return the number of controllers in the scene.
|
|
////////////////////////////////////////////////////////////////////
|
|
unsigned int PhysxScene::
|
|
get_num_controllers() const {
|
|
|
|
nassertr(_error_type == ET_ok, -1);
|
|
return _cm->getNbControllers();
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::create_controller
|
|
// Access: Published
|
|
// Description: Creates a new character controller.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxController *PhysxScene::
|
|
create_controller(PhysxControllerDesc &desc) {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
nassertr(desc.is_valid(), NULL);
|
|
|
|
PhysxController *controller = PhysxController::factory(desc.ptr()->getType());
|
|
nassertr(controller, NULL);
|
|
|
|
desc.ptr()->callback = &_controller_report;
|
|
desc.ptr()->userData = controller;
|
|
|
|
NxController *controllerPtr = _cm->createController(_ptr,*desc.ptr());
|
|
nassertr(controllerPtr, NULL);
|
|
|
|
controller->link(controllerPtr);
|
|
controllerPtr->getActor()->setName("");
|
|
|
|
return controller;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_controller
|
|
// Access: Published
|
|
// Description: Retrieves the n-th controller within the scene.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxController *PhysxScene::
|
|
get_controller(unsigned int idx) const {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
nassertr_always(idx < _cm->getNbControllers(), NULL);
|
|
|
|
NxController *controllerPtr = _cm->getController(idx);
|
|
PhysxController *controller = (PhysxController *)(controllerPtr->getUserData());
|
|
|
|
return controller;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_num_joints
|
|
// Access: Published
|
|
// Description: Returns the number of joints in the scene
|
|
// (excluding "dead" joints). Note that this includes
|
|
// compartments.
|
|
////////////////////////////////////////////////////////////////////
|
|
unsigned int PhysxScene::
|
|
get_num_joints() const {
|
|
|
|
nassertr(_error_type == ET_ok, -1);
|
|
return _ptr->getNbJoints();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::create_joint
|
|
// Access: Published
|
|
// Description: Creates a joint in this scene.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxJoint *PhysxScene::
|
|
create_joint(PhysxJointDesc &desc) {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
nassertr(desc.is_valid(), NULL);
|
|
|
|
PhysxJoint *joint = PhysxJoint::factory(desc.ptr()->getType());
|
|
nassertr(joint, NULL);
|
|
|
|
NxJoint *jointPtr = _ptr->createJoint(*desc.ptr());
|
|
nassertr(jointPtr, NULL);
|
|
|
|
joint->link(jointPtr);
|
|
|
|
return joint;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_joint
|
|
// Access: Published
|
|
// Description: Retrieve the n-th joint from the array of all the
|
|
// joints in the scene.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxJoint *PhysxScene::
|
|
get_joint(unsigned int idx) const {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
nassertr_always(idx < _ptr->getNbJoints(), NULL);
|
|
|
|
NxJoint *jointPtr;
|
|
NxU32 nJoints = _ptr->getNbJoints();
|
|
|
|
_ptr->resetJointIterator();
|
|
for (NxU32 i=0; i <= idx; i++) {
|
|
jointPtr = _ptr->getNextJoint();
|
|
}
|
|
|
|
return (PhysxJoint *)(jointPtr->userData);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_num_force_fields
|
|
// Access: Published
|
|
// Description: Gets the number of force fields in the scene.
|
|
////////////////////////////////////////////////////////////////////
|
|
unsigned int PhysxScene::
|
|
get_num_force_fields() const {
|
|
|
|
nassertr(_error_type == ET_ok, -1);
|
|
return _ptr->getNbForceFields();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::create_force_field
|
|
// Access: Published
|
|
// Description: Creates a force field in this scene.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxForceField *PhysxScene::
|
|
create_force_field(PhysxForceFieldDesc &desc) {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
|
|
// Create the kernel
|
|
desc.create_kernel(_ptr);
|
|
nassertr(desc.is_valid(), NULL);
|
|
|
|
// Create the force field
|
|
PhysxForceField *field = new PhysxForceField();
|
|
nassertr(field, NULL);
|
|
|
|
NxForceField *fieldPtr = _ptr->createForceField(desc._desc);
|
|
nassertr(fieldPtr, NULL);
|
|
|
|
field->link(fieldPtr);
|
|
|
|
return field;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_force_field
|
|
// Access: Published
|
|
// Description: Returns the n-th force field from the array of
|
|
// all the force fields in the scene.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxForceField *PhysxScene::
|
|
get_force_field(unsigned int idx) const {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
nassertr_always(idx < _ptr->getNbForceFields(), NULL);
|
|
|
|
NxForceField **fields = _ptr->getForceFields();
|
|
NxForceField *fieldPtr = fields[idx];
|
|
|
|
return (PhysxForceField *)(fieldPtr->userData);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_num_force_field_shape_groups
|
|
// Access: Published
|
|
// Description: Gets the number of force field shape groups in
|
|
// the scene.
|
|
////////////////////////////////////////////////////////////////////
|
|
unsigned int PhysxScene::
|
|
get_num_force_field_shape_groups() const {
|
|
|
|
nassertr(_error_type == ET_ok, -1);
|
|
return _ptr->getNbForceFieldShapeGroups();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::create_force_field_shape_group
|
|
// Access: Published
|
|
// Description: Creates a new force field shape group in this
|
|
// scene.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxForceFieldShapeGroup *PhysxScene::
|
|
create_force_field_shape_group(PhysxForceFieldShapeGroupDesc &desc) {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
|
|
PhysxForceFieldShapeGroup *group = new PhysxForceFieldShapeGroup();
|
|
nassertr(group, NULL);
|
|
|
|
NxForceFieldShapeGroup *groupPtr = _ptr->createForceFieldShapeGroup(desc._desc);
|
|
nassertr(groupPtr, NULL);
|
|
|
|
group->link(groupPtr);
|
|
|
|
return group;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_force_field_shape_group
|
|
// Access: Published
|
|
// Description: Returns the n-th force field shape group in this
|
|
// scene
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxForceFieldShapeGroup *PhysxScene::
|
|
get_force_field_shape_group(unsigned int idx) const {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
nassertr_always(idx < _ptr->getNbForceFieldShapeGroups(), NULL);
|
|
|
|
_ptr->resetForceFieldShapeGroupsIterator();
|
|
NxForceFieldShapeGroup *groupPtr = NULL;
|
|
idx++;
|
|
while (idx-- > 0) {
|
|
groupPtr = _ptr->getNextForceFieldShapeGroup();
|
|
}
|
|
|
|
return groupPtr ? (PhysxForceFieldShapeGroup *)groupPtr->userData : NULL;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_num_vehicles
|
|
// Access: Published
|
|
// Description: Returns the number of vehicles in the scene.
|
|
////////////////////////////////////////////////////////////////////
|
|
unsigned int PhysxScene::
|
|
get_num_vehicles() const {
|
|
|
|
nassertr(_error_type == ET_ok, -1);
|
|
return _vehicles.size();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::create_vehicle
|
|
// Access: Published
|
|
// Description: Creates a vehicle in this scene.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxVehicle *PhysxScene::
|
|
create_vehicle(PhysxVehicleDesc &desc) {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
nassertr(desc.is_valid(), NULL);
|
|
|
|
PhysxVehicle *vehicle = new PhysxVehicle();
|
|
nassertr(vehicle, NULL);
|
|
|
|
vehicle->create(this, desc);
|
|
|
|
return vehicle;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_vehicle
|
|
// Access: Published
|
|
// Description: Returns the n-th vehicle from the array of all
|
|
// the vehicles in the scene.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxVehicle *PhysxScene::
|
|
get_vehicle(unsigned int idx) const {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
nassertr_always(idx < _vehicles.size(), NULL);
|
|
|
|
return _vehicles[idx];
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_stats2
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxSceneStats2 PhysxScene::
|
|
get_stats2() const {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
return PhysxSceneStats2(_ptr->getStats2());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::raycast_any_shape
|
|
// Access: Published
|
|
// Description: Returns true if any shape is intersected by the
|
|
// ray.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PhysxScene::
|
|
raycast_any_shape(const PhysxRay &ray,
|
|
PhysxShapesType shapesType,
|
|
PhysxMask mask,
|
|
PhysxGroupsMask *groups) const {
|
|
|
|
nassertr(_error_type == ET_ok, false);
|
|
|
|
NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
|
|
|
|
return _ptr->raycastAnyShape(ray._ray, (NxShapesType)shapesType,
|
|
mask.get_mask(), ray._length, groupsPtr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::raycast_closest_shape
|
|
// Access: Published
|
|
// Description: Returns the first shape that is hit along the ray.
|
|
// If not shape is hit then an empty raycast hit
|
|
// is returned (is_empty() == true).
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxRaycastHit PhysxScene::
|
|
raycast_closest_shape(const PhysxRay &ray,
|
|
PhysxShapesType shapesType,
|
|
PhysxMask mask,
|
|
PhysxGroupsMask *groups, bool smoothNormal) const {
|
|
|
|
NxRaycastHit hit;
|
|
|
|
nassertr(_error_type == ET_ok, hit);
|
|
|
|
NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
|
|
|
|
NxU32 hints = NX_RAYCAST_SHAPE | NX_RAYCAST_IMPACT | NX_RAYCAST_DISTANCE;
|
|
if (smoothNormal == true) {
|
|
hints |= NX_RAYCAST_NORMAL;
|
|
}
|
|
else {
|
|
hints |= NX_RAYCAST_FACE_NORMAL;
|
|
}
|
|
|
|
_ptr->raycastClosestShape(ray._ray, (NxShapesType)shapesType, hit,
|
|
mask.get_mask(), ray._length, hints);
|
|
|
|
|
|
return PhysxRaycastHit(hit);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::raycast_all_shapes
|
|
// Access: Published
|
|
// Description: Returns a PhysxRaycastReport object which can be
|
|
// used to iterate over all shapes that have been
|
|
// hit by the ray.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxRaycastReport PhysxScene::
|
|
raycast_all_shapes(const PhysxRay &ray,
|
|
PhysxShapesType shapesType,
|
|
PhysxMask mask,
|
|
PhysxGroupsMask *groups, bool smoothNormal) const {
|
|
|
|
PhysxRaycastReport report;
|
|
|
|
nassertr(_error_type == ET_ok, report);
|
|
|
|
NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
|
|
|
|
NxU32 hints = NX_RAYCAST_SHAPE | NX_RAYCAST_IMPACT | NX_RAYCAST_DISTANCE;
|
|
if (smoothNormal == true) {
|
|
hints |= NX_RAYCAST_NORMAL;
|
|
}
|
|
else {
|
|
hints |= NX_RAYCAST_FACE_NORMAL;
|
|
}
|
|
|
|
_ptr->raycastAllShapes(ray._ray, report, (NxShapesType)shapesType,
|
|
mask.get_mask(), ray._length, hints);
|
|
|
|
return report;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::raycast_any_bounds
|
|
// Access: Published
|
|
// Description: Returns true if any axis aligned bounding box
|
|
// enclosing a shape is intersected by the ray.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PhysxScene::
|
|
raycast_any_bounds(const PhysxRay &ray,
|
|
PhysxShapesType shapesType,
|
|
PhysxMask mask,
|
|
PhysxGroupsMask *groups) const {
|
|
|
|
nassertr(_error_type == ET_ok, false);
|
|
|
|
NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
|
|
|
|
return _ptr->raycastAnyBounds(ray._ray, (NxShapesType)shapesType,
|
|
mask.get_mask(), ray._length, groupsPtr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::raycast_closest_bounds
|
|
// Access: Published
|
|
// Description: Returns the first axis aligned bounding box
|
|
// enclosing a shape that is hit along the ray.
|
|
// If not shape is hit then an empty raycast hit
|
|
// is returned (is_empty() == true).
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxRaycastHit PhysxScene::
|
|
raycast_closest_bounds(const PhysxRay &ray, PhysxShapesType shapesType, PhysxMask mask, PhysxGroupsMask *groups, bool smoothNormal) const {
|
|
|
|
NxRaycastHit hit;
|
|
|
|
nassertr(_error_type == ET_ok, hit);
|
|
|
|
NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
|
|
|
|
NxU32 hints = NX_RAYCAST_SHAPE | NX_RAYCAST_IMPACT | NX_RAYCAST_DISTANCE;
|
|
if (smoothNormal == true) {
|
|
hints |= NX_RAYCAST_NORMAL;
|
|
}
|
|
else {
|
|
hints |= NX_RAYCAST_FACE_NORMAL;
|
|
}
|
|
|
|
_ptr->raycastClosestBounds(ray._ray, (NxShapesType)shapesType, hit,
|
|
mask.get_mask(), ray._length, hints);
|
|
|
|
|
|
return PhysxRaycastHit(hit);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::raycast_all_bounds
|
|
// Access: Published
|
|
// Description: Returns a PhysxRaycastReport object which can be
|
|
// used to iterate over all shapes that have been
|
|
// enclosed by axis aligned bounding boxes hit by
|
|
// the ray.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxRaycastReport PhysxScene::
|
|
raycast_all_bounds(const PhysxRay &ray,
|
|
PhysxShapesType shapesType,
|
|
PhysxMask mask,
|
|
PhysxGroupsMask *groups, bool smoothNormal) const {
|
|
|
|
PhysxRaycastReport report;
|
|
|
|
nassertr(_error_type == ET_ok, report);
|
|
|
|
NxGroupsMask *groupsPtr = groups ? &(groups->_mask) : NULL;
|
|
|
|
NxU32 hints = NX_RAYCAST_SHAPE | NX_RAYCAST_IMPACT | NX_RAYCAST_DISTANCE;
|
|
if (smoothNormal == true) {
|
|
hints |= NX_RAYCAST_NORMAL;
|
|
}
|
|
else {
|
|
hints |= NX_RAYCAST_FACE_NORMAL;
|
|
}
|
|
|
|
_ptr->raycastAllBounds(ray._ray, report, (NxShapesType)shapesType,
|
|
mask.get_mask(), ray._length, hints);
|
|
|
|
return report;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::overlap_sphere_shapes
|
|
// Access: Published
|
|
// Description: Returns the set of shapes overlapped by the
|
|
// world-space sphere.
|
|
// You can test against static and/or dynamic objects
|
|
// by adjusting 'shapeType'.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxOverlapReport PhysxScene::
|
|
overlap_sphere_shapes(const LPoint3f ¢er, float radius,
|
|
PhysxShapesType shapesType,
|
|
PhysxMask mask, bool accurateCollision) const {
|
|
|
|
PhysxOverlapReport report;
|
|
|
|
nassertr(_error_type == ET_ok, report);
|
|
|
|
NxSphere worldSphere(PhysxManager::point3_to_nxVec3(center), radius);
|
|
|
|
_ptr->overlapSphereShapes(worldSphere, (NxShapesType)shapesType, 0, NULL, &report,
|
|
mask.get_mask(), NULL, accurateCollision);
|
|
|
|
return report;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::overlap_capsule_shapes
|
|
// Access: Published
|
|
// Description: Returns the set of shapes overlapped by the
|
|
// world-space capsule.
|
|
// You can test against static and/or dynamic objects
|
|
// by adjusting 'shapeType'.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxOverlapReport PhysxScene::
|
|
overlap_capsule_shapes(const LPoint3f &p0, const LPoint3f &p1, float radius,
|
|
PhysxShapesType shapesType,
|
|
PhysxMask mask, bool accurateCollision) const {
|
|
|
|
PhysxOverlapReport report;
|
|
|
|
nassertr(_error_type == ET_ok, report);
|
|
|
|
NxSegment segment(PhysxManager::point3_to_nxVec3(p0),
|
|
PhysxManager::point3_to_nxVec3(p1));
|
|
NxCapsule worldCapsule(segment, radius);
|
|
|
|
_ptr->overlapCapsuleShapes(worldCapsule, (NxShapesType)shapesType, 0, NULL, &report,
|
|
mask.get_mask(), NULL, accurateCollision);
|
|
|
|
return report;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::set_actor_pair_flag
|
|
// Access: Published
|
|
// Description: Sets the pair flags for the given pair of actors.
|
|
//
|
|
// Calling this on an actor that has no shape(s) has
|
|
// no effect. The two actor references must not
|
|
// reference the same actor.
|
|
//
|
|
// It is important to note that the engine stores
|
|
// pair flags per shape, even for actor pair flags.
|
|
// This means that shapes should be created before
|
|
// actor pair flags are set, otherwise the pair flags
|
|
// will be ignored.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
set_actor_pair_flag(PhysxActor &actorA, PhysxActor &actorB,
|
|
PhysxContactPairFlag flag, bool value) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
|
|
NxActor *ptrA = actorA.ptr();
|
|
NxActor *ptrB = actorB.ptr();
|
|
NxU32 flags = _ptr->getActorPairFlags(*ptrA, *ptrB);
|
|
|
|
if (value == true) {
|
|
flags |= flag;
|
|
}
|
|
else {
|
|
flags &= ~(flag);
|
|
}
|
|
|
|
_ptr->setActorPairFlags(*ptrA, *ptrB, flags);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_actor_pair_flag
|
|
// Access: Published
|
|
// Description: Retrieves a single flag for the given pair of
|
|
// actors.
|
|
//
|
|
// The two actor references must not reference the
|
|
// same actor.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PhysxScene::
|
|
get_actor_pair_flag(PhysxActor &actorA, PhysxActor &actorB,
|
|
PhysxContactPairFlag flag) {
|
|
|
|
nassertr(_error_type == ET_ok, false);
|
|
|
|
NxActor *ptrA = actorA.ptr();
|
|
NxActor *ptrB = actorB.ptr();
|
|
NxU32 flags = _ptr->getActorPairFlags(*ptrA, *ptrB);
|
|
|
|
return (flags && flag) ? true : false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::set_shape_pair_flag
|
|
// Access: Published
|
|
// Description: Disables or enables contact generation for a pair
|
|
// of shapes.
|
|
//
|
|
// The two shape references must not reference the
|
|
// same shape.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
set_shape_pair_flag(PhysxShape &shapeA, PhysxShape &shapeB, bool value) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
|
|
NxShape *ptrA = shapeA.ptr();
|
|
NxShape *ptrB = shapeB.ptr();
|
|
NxU32 flags = _ptr->getShapePairFlags(*ptrA, *ptrB);
|
|
|
|
if (value == true) {
|
|
flags |= NX_IGNORE_PAIR;
|
|
}
|
|
else {
|
|
flags &= ~(NX_IGNORE_PAIR);
|
|
}
|
|
|
|
_ptr->setShapePairFlags(*ptrA, *ptrB, flags);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_shape_pair_flag
|
|
// Access: Published
|
|
// Description: Returns /true/ if contact generation between a pair
|
|
// of shapes is enabled, and /false/ if contact
|
|
// generation is disables.
|
|
//
|
|
// The two shape references must not reference the
|
|
// same shape.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PhysxScene::
|
|
get_shape_pair_flag(PhysxShape &shapeA, PhysxShape &shapeB) {
|
|
|
|
nassertr(_error_type == ET_ok, false);
|
|
|
|
NxShape *ptrA = shapeA.ptr();
|
|
NxShape *ptrB = shapeB.ptr();
|
|
NxU32 flags = _ptr->getShapePairFlags(*ptrA, *ptrB);
|
|
|
|
return (flags && NX_IGNORE_PAIR) ? true : false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::set_actor_group_pair_flag
|
|
// Access: Published
|
|
// Description: With this method one can set contact reporting
|
|
// flags between actors belonging to a pair of groups.
|
|
//
|
|
// It is possible to assign each actor to a group
|
|
// using PhysxActor::set_group(). This is a different
|
|
// set of groups from the shape groups despite the
|
|
// similar name. Here up to 0xffff different groups
|
|
// are permitted, With this method one can set
|
|
// contact reporting flags between actors belonging
|
|
// to a pair of groups.
|
|
//
|
|
// The following flags are permitted:
|
|
// - CPF_start_touch
|
|
// - CPF_end_touch
|
|
// - CPF_touch
|
|
// - CPF_start_touch_treshold
|
|
// - CPF_end_touch_treshold
|
|
// - CPF_touch_treshold
|
|
//
|
|
// Note that finer grain control of pairwise flags is
|
|
// possible using the function
|
|
// PhysxScene::set_actor_pair_flags().
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
set_actor_group_pair_flag(unsigned int g1, unsigned int g2,
|
|
PhysxContactPairFlag flag, bool value) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
|
|
NxU32 flags = _ptr->getActorGroupPairFlags(g1, g2);
|
|
if (value == true) {
|
|
flags |= flag;
|
|
}
|
|
else {
|
|
flags &= ~(flag);
|
|
}
|
|
_ptr->setActorGroupPairFlags(g1, g2, flags);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_actor_group_pair_flag
|
|
// Access: Published
|
|
// Description: Retrieves a single flag set with
|
|
// PhysxScene::set_actor_group_pair_flag()
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PhysxScene::
|
|
get_actor_group_pair_flag(unsigned int g1, unsigned int g2,
|
|
PhysxContactPairFlag flag) {
|
|
|
|
nassertr(_error_type == ET_ok, false);
|
|
NxU32 flags = _ptr->getActorGroupPairFlags(g1, g2);
|
|
return (flags && flag) ? true : false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::set_filter_ops
|
|
// Access: Published
|
|
// Description: Setups filtering operations.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
set_filter_ops(PhysxFilterOp op0, PhysxFilterOp op1, PhysxFilterOp op2) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
_ptr->setFilterOps((NxFilterOp)op0, (NxFilterOp)op1, (NxFilterOp)op2);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::set_filter_bool
|
|
// Access: Published
|
|
// Description: Setups filtering's boolean value.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
set_filter_bool(bool flag) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
_ptr->setFilterBool(flag);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::set_filter_constant0
|
|
// Access: Published
|
|
// Description: Setups filtering's K0 value.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
set_filter_constant0(const PhysxGroupsMask &mask) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
_ptr->setFilterConstant0(mask.get_mask());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::set_filter_constant1
|
|
// Access: Published
|
|
// Description: Setups filtering's K1 value.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
set_filter_constant1(const PhysxGroupsMask &mask) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
_ptr->setFilterConstant1(mask.get_mask());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_filter_bool
|
|
// Access: Published
|
|
// Description: Retrieves filtering's boolean value.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PhysxScene::
|
|
get_filter_bool() const {
|
|
|
|
nassertr(_error_type == ET_ok, false);
|
|
return _ptr->getFilterBool();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_filter_constant0
|
|
// Access: Published
|
|
// Description: Gets filtering constant K0.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxGroupsMask PhysxScene::
|
|
get_filter_constant0() const {
|
|
|
|
PhysxGroupsMask mask;
|
|
|
|
nassertr(_error_type == ET_ok, mask);
|
|
|
|
NxGroupsMask _mask = ptr()->getFilterConstant0();
|
|
mask.set_mask(_mask);
|
|
|
|
return mask;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_filter_constant1
|
|
// Access: Published
|
|
// Description: Gets filtering constant K1.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxGroupsMask PhysxScene::
|
|
get_filter_constant1() const {
|
|
|
|
PhysxGroupsMask mask;
|
|
|
|
nassertr(_error_type == ET_ok, mask);
|
|
|
|
NxGroupsMask _mask = ptr()->getFilterConstant1();
|
|
mask.set_mask(_mask);
|
|
|
|
return mask;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_filter_op0
|
|
// Access: Published
|
|
// Description: Retrieves the op0 filtering operation.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxEnums::PhysxFilterOp PhysxScene::
|
|
get_filter_op0() const {
|
|
|
|
nassertr(_error_type == ET_ok, FO_and);
|
|
|
|
NxFilterOp op0;
|
|
NxFilterOp op1;
|
|
NxFilterOp op2;
|
|
|
|
_ptr->getFilterOps(op0, op1, op2);
|
|
|
|
return (PhysxFilterOp)op0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_filter_op1
|
|
// Access: Published
|
|
// Description: Retrieves the op1 filtering operation.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxEnums::PhysxFilterOp PhysxScene::
|
|
get_filter_op1() const {
|
|
|
|
nassertr(_error_type == ET_ok, FO_and);
|
|
|
|
NxFilterOp op0;
|
|
NxFilterOp op1;
|
|
NxFilterOp op2;
|
|
|
|
_ptr->getFilterOps(op0, op1, op2);
|
|
|
|
return (PhysxFilterOp)op1;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_filter_op2
|
|
// Access: Published
|
|
// Description: Retrieves the op2 filtering operation.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxEnums::PhysxFilterOp PhysxScene::
|
|
get_filter_op2() const {
|
|
|
|
nassertr(_error_type == ET_ok, FO_and);
|
|
|
|
NxFilterOp op0;
|
|
NxFilterOp op1;
|
|
NxFilterOp op2;
|
|
|
|
_ptr->getFilterOps(op0, op1, op2);
|
|
|
|
return (PhysxFilterOp)op2;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::set_group_collision_flag
|
|
// Access: Published
|
|
// Description: Specifies if collision should be performed by a
|
|
// pair of shape groups.
|
|
//
|
|
// It is possible to assign each shape to a collision
|
|
// groups using PhysxShape::set_group(). With this
|
|
// method one can set whether collisions should be
|
|
// detected between shapes belonging to a given pair
|
|
// of groups. Initially all pairs are enabled.
|
|
//
|
|
// Fluids can be assigned to collision groups as well.
|
|
//
|
|
// Collision groups are integers between 0 and 31.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
set_group_collision_flag(unsigned int g1, unsigned int g2, bool enable) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
nassertv(g1 >= 0 && g1 < 32);
|
|
nassertv(g2 >= 0 && g2 < 32);
|
|
|
|
_ptr->setGroupCollisionFlag((NxCollisionGroup)g1, (NxCollisionGroup)g2, enable);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_group_collision_flag
|
|
// Access: Published
|
|
// Description: Determines if collision detection is performed
|
|
// between a pair of groups. Collision groups are
|
|
// integers between 0 and 31.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PhysxScene::
|
|
get_group_collision_flag(unsigned int g1, unsigned int g2) {
|
|
|
|
nassertr(_error_type == ET_ok, false);
|
|
nassertr(g1 >= 0 && g1 < 32, false);
|
|
nassertr(g2 >= 0 && g2 < 32, false);
|
|
|
|
return _ptr->getGroupCollisionFlag((NxCollisionGroup)g1, (NxCollisionGroup)g2);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_flag
|
|
// Access: Published
|
|
// Description: Return the specified scene flag flag.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PhysxScene::
|
|
get_flag(PhysxSceneFlag flag) const {
|
|
|
|
nassertr(_error_type == ET_ok, false);
|
|
return (_ptr->getFlags() & flag) ? true : false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::is_hardware_scene
|
|
// Access: Published
|
|
// Description: Returns TRUE if the the scene is simulated in
|
|
// hardware. FALSE if the scene is simulated in
|
|
// software.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool PhysxScene::
|
|
is_hardware_scene() const {
|
|
|
|
nassertr(_error_type == ET_ok, false);
|
|
return (_ptr->getSimType() & NX_SIMULATION_HW) ? true : false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::set_dominance_group_pair
|
|
// Access: Published
|
|
// Description: Specifies the dominance behavior of constraints
|
|
// between two actors with two certain dominance
|
|
// groups.
|
|
//
|
|
// It is possible to assign each actor to a dominance
|
|
// groups using PhysxActor::set_dominance_group().
|
|
//
|
|
// With dominance groups one can have all constraints
|
|
// (contacts and joints) created between actors act in
|
|
// one direction only. This is useful if you want to
|
|
// make sure that the movement of the rider of a
|
|
// vehicle or the pony tail of a character doesn't
|
|
// influence the object it is attached to, while
|
|
// keeping the motion of both inherently physical.
|
|
//
|
|
// Whenever a constraint (i.e. joint or contact)
|
|
// between two actors (a0, a1) needs to be solved, the
|
|
// groups (g0, g1) of both actors are retrieved. Then
|
|
// the constraint dominance setting for this group
|
|
// pair is retrieved.
|
|
//
|
|
// In the constraint, PhysxConstraintDominance::get_0()
|
|
// becomes the dominance setting for a0, and
|
|
// PhysxConstraintDominance::get_1() becomes the
|
|
// dominance setting for a1. A dominance setting of
|
|
// 1.0f, the default, will permit the actor to be
|
|
// pushed or pulled by the other actor. A dominance
|
|
// setting of 0.0f will however prevent the actor to
|
|
// be pushed or pulled by the other actor. Thus, a
|
|
// PhysxConstraintDominance of (1.0f, 0.0f) makes the
|
|
// interaction one-way.
|
|
//
|
|
// The dominance matrix is initialised by default such
|
|
// that:
|
|
// - if g1 == g2, then (1.0f, 1.0f) is returned
|
|
// - if g1 < g2, then (0.0f, 1.0f) is returned
|
|
// - if g1 > g2, then (1.0f, 0.0f) is returned
|
|
//
|
|
// In other words, actors in higher groups can be
|
|
// pushed around by actors in lower groups by default.
|
|
//
|
|
// These settings should cover most applications, and
|
|
// in fact not overriding these settings may likely
|
|
// result in higher performance.
|
|
//
|
|
// Dominance settings are currently specified as
|
|
// floats 0.0f or 1.0f because in the future PhysX may
|
|
// permit arbitrary fractional settings to express
|
|
// 'partly-one-way' interactions.
|
|
////////////////////////////////////////////////////////////////////
|
|
void PhysxScene::
|
|
set_dominance_group_pair(unsigned int g1, unsigned int g2, PhysxConstraintDominance dominance ) {
|
|
|
|
nassertv(_error_type == ET_ok);
|
|
nassertv(g1 < 32);
|
|
nassertv(g2 < 32);
|
|
|
|
NxConstraintDominance d = dominance.get_dominance();
|
|
_ptr->setDominanceGroupPair((NxDominanceGroup)g1, (NxDominanceGroup)g2, d);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_dominance_group_pair
|
|
// Access: Published
|
|
// Description: Samples the dominance matrix.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxConstraintDominance PhysxScene::
|
|
get_dominance_group_pair(unsigned int g1, unsigned int g2) {
|
|
|
|
PhysxConstraintDominance result(1.0f, 1.0f);
|
|
|
|
nassertr(_error_type == ET_ok, result);
|
|
nassertr(g1 < 32, result);
|
|
nassertr(g2 < 32, result);
|
|
|
|
result.set_dominance(_ptr->getDominanceGroupPair((NxDominanceGroup)g1, (NxDominanceGroup)g2));
|
|
return result;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: PhysxScene::get_wheel_shape_material
|
|
// Access: Published
|
|
// Description: Gets the shared material for all wheel shapes.
|
|
//
|
|
// If this material is not already created then
|
|
// calling this method will create the material.
|
|
//
|
|
// Normally users don't need to call this method. It
|
|
// is used internally by PhysWheel::create_wheel.
|
|
////////////////////////////////////////////////////////////////////
|
|
PhysxMaterial *PhysxScene::
|
|
get_wheel_shape_material() {
|
|
|
|
nassertr(_error_type == ET_ok, NULL);
|
|
|
|
if (_wheelShapeMaterial == NULL) {
|
|
PhysxMaterialDesc materialDesc;
|
|
materialDesc.set_flag(PhysxMaterialDesc::MF_disable_friction, true);
|
|
_wheelShapeMaterial = create_material(materialDesc);
|
|
}
|
|
|
|
return _wheelShapeMaterial;
|
|
}
|
|
|