open_toontown_panda3d/panda/src/physx/physxManager.cxx

464 lines
9.9 KiB
C++

/**
* 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."
*
* @file physxManager.cxx
* @author enn0x
* @date 2009-09-01
*/
#include "physxManager.h"
#include "physxScene.h"
#include "physxSceneDesc.h"
using std::endl;
PhysxManager *PhysxManager::_global_ptr;
PhysxManager::PhysxOutputStream PhysxManager::_outputStream;
/**
*
*/
PhysxManager::
PhysxManager() {
// Create PhysX SDK
NxSDKCreateError error;
NxPhysicsSDKDesc desc = NxPhysicsSDKDesc();
_sdk = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, nullptr, &_outputStream, desc, &error);
if (error == NXCE_NO_ERROR) {
physx_cat.info() << "PhysX subsystem initialized. Number of PPUs="
<< _sdk->getNbPPUs() << endl;
}
else {
physx_cat.error() << "Error when setting up the PhysX subsystem: "
<< get_sdk_error_string(error) << endl;
_sdk = nullptr;
}
nassertv_always(error == NXCE_NO_ERROR);
nassertv_always(_sdk);
// Set some default parameters
_sdk->setParameter(NX_VISUALIZATION_SCALE, 0.0f);
_sdk->setParameter(NX_VISUALIZE_COLLISION_SHAPES, true);
_sdk->setParameter(NX_VISUALIZE_ACTOR_AXES, true);
_sdk->setParameter(NX_VISUALIZE_BODY_LIN_VELOCITY, true);
_sdk->setParameter(NX_VISUALIZE_COLLISION_AABBS, false);
_sdk->setParameter(NX_VISUALIZE_COLLISION_VNORMALS, false);
_sdk->setParameter(NX_VISUALIZE_COLLISION_FNORMALS, false);
_sdk->setParameter(NX_VISUALIZE_FORCE_FIELDS, false);
// Connect VDR
if(physx_want_vrd) {
physx_cat.info() << "Connecting to visual remote debugger at ("
<< physx_vrd_host << ":"
<< physx_vrd_port << ")" << endl;
NxRemoteDebugger *debugger = _sdk->getFoundationSDK().getRemoteDebugger();
debugger->connect(physx_vrd_host.c_str(),
physx_vrd_port);
if (!debugger->isConnected()) {
physx_cat.warning() << "Could not connect to visual remot debugger!" << endl;
}
}
}
/**
*
*/
PhysxManager::
~PhysxManager() {
// Disconnect VRD
if(physx_want_vrd) {
NxRemoteDebugger *debugger = _sdk->getFoundationSDK().getRemoteDebugger();
if (!debugger->isConnected()) {
debugger->disconnect();
}
}
// Release PhysX SDK
NxReleasePhysicsSDK(_sdk);
}
/**
* Returns a pointer to the global PhysxManager object.
*/
PhysxManager *PhysxManager::
get_global_ptr() {
if (_global_ptr == nullptr) {
_global_ptr = new PhysxManager;
}
if (_global_ptr->_sdk == nullptr) {
return nullptr;
}
else {
return _global_ptr;
}
}
/**
*
*/
unsigned int PhysxManager::
get_num_scenes() const {
return _sdk->getNbScenes();
}
/**
*
*/
PhysxScene *PhysxManager::
create_scene(PhysxSceneDesc &sceneDesc) {
nassertr(sceneDesc.is_valid(),nullptr);
// _desc.timeStepMethod = NX_TIMESTEP_FIXED; _desc.maxTimestep = 1.0f
// 240.0f; _desc.maxIter = 8;
sceneDesc._desc.flags |= NX_SF_ENABLE_ACTIVETRANSFORMS;
sceneDesc._desc.flags |= NX_SF_SIMULATE_SEPARATE_THREAD;
if (physx_internal_threads > 0) {
sceneDesc._desc.flags |= NX_SF_ENABLE_MULTITHREAD;
sceneDesc._desc.threadMask=0xfffffffe;
sceneDesc._desc.internalThreadCount = physx_internal_threads;
physx_cat.info() << "Multithreading enabled. "
<< "Additional threads: " << physx_internal_threads << endl;
}
PhysxScene *scene = new PhysxScene();
nassertr(scene, nullptr);
NxScene *scenePtr = _sdk->createScene(sceneDesc._desc);
nassertr(scenePtr, nullptr);
scene->link(scenePtr);
return scene;
}
/**
*
*/
PhysxScene *PhysxManager::
get_scene(unsigned int idx) const {
nassertr_always(idx < _sdk->getNbScenes(), nullptr);
NxScene *scenePtr = _sdk->getScene(idx);
PhysxScene *scene = (PhysxScene *)(scenePtr->userData);
return scene;
}
/**
*
*/
unsigned int PhysxManager::
get_num_height_fields() {
return _sdk->getNbHeightFields();
}
/**
*
*/
PhysxHeightField *PhysxManager::
create_height_field(PhysxHeightFieldDesc &desc) {
nassertr(desc.is_valid(),nullptr);
PhysxHeightField *hf = new PhysxHeightField();
nassertr(hf, nullptr);
NxHeightField *hfPtr = _sdk->createHeightField(desc._desc);
nassertr(hfPtr, nullptr);
hf->link(hfPtr);
return hf;
}
/**
*
*/
PhysxHeightField *PhysxManager::
get_height_field(unsigned int idx) {
nassertr_always(idx < _sdk->getNbHeightFields(), nullptr);
return (PhysxHeightField *)_heightfields[idx];
}
/**
*
*/
unsigned int PhysxManager::
get_num_convex_meshes() {
return _sdk->getNbConvexMeshes();
}
/**
*
*/
PhysxConvexMesh *PhysxManager::
get_convex_mesh(unsigned int idx) {
nassertr_always(idx < _sdk->getNbConvexMeshes(), nullptr);
return (PhysxConvexMesh *)_convex_meshes[idx];
}
/**
*
*/
unsigned int PhysxManager::
get_num_triangle_meshes() {
return _sdk->getNbTriangleMeshes();
}
/**
*
*/
PhysxTriangleMesh *PhysxManager::
get_triangle_mesh(unsigned int idx) {
nassertr_always(idx < _sdk->getNbTriangleMeshes(), nullptr);
return (PhysxTriangleMesh *)_triangle_meshes[idx];
}
/**
*
*/
unsigned int PhysxManager::
get_num_cloth_meshes() {
return _sdk->getNbClothMeshes();
}
/**
*
*/
PhysxClothMesh *PhysxManager::
get_cloth_mesh(unsigned int idx) {
nassertr_always(idx < _sdk->getNbClothMeshes(), nullptr);
return (PhysxClothMesh *)_cloth_meshes[idx];
}
/**
*
*/
unsigned int PhysxManager::
get_num_soft_body_meshes() {
return _sdk->getNbSoftBodyMeshes();
}
/**
*
*/
PhysxSoftBodyMesh *PhysxManager::
get_soft_body_mesh(unsigned int idx) {
nassertr_always(idx < _sdk->getNbSoftBodyMeshes(), nullptr);
return (PhysxSoftBodyMesh *)_softbody_meshes[idx];
}
/**
*
*/
unsigned int PhysxManager::
get_num_ccd_skeletons() {
return _sdk->getNbCCDSkeletons();
}
/**
*
*/
PhysxCcdSkeleton *PhysxManager::
create_ccd_skeleton(PhysxCcdSkeletonDesc &desc) {
nassertr(desc.is_valid(), nullptr);
nassertr(desc.get_desc().numVertices < 64, nullptr);
PhysxCcdSkeleton *skel = new PhysxCcdSkeleton();
nassertr(skel, nullptr);
NxCCDSkeleton *skelPtr = _sdk->createCCDSkeleton(desc.get_desc());
nassertr(skelPtr, nullptr);
skel->link(skelPtr);
return skel;
}
/**
*
*/
PhysxCcdSkeleton *PhysxManager::
get_ccd_skeleton(unsigned int idx) {
nassertr_always(idx < _sdk->getNbCCDSkeletons(), nullptr);
return (PhysxCcdSkeleton *)_ccd_skeletons[idx];
}
/**
* Returns TRUE if a physcis hardware is available on the host system.
*/
bool PhysxManager::
is_hardware_available() {
return _sdk->getHWVersion() != NX_HW_VERSION_NONE;
}
/**
* Reports the number of PPUs installed in the host system.
*/
unsigned int PhysxManager::
get_num_ppus() {
return _sdk->getNbPPUs();
}
/**
* Reports the available revision of the PhysX Hardware. Returns 0 if there
* is no hardware present in the machine, 1 for the PhysX Athena revision 1.0
* card.
*/
unsigned int PhysxManager::
get_hw_version() {
return _sdk->getHWVersion();
}
/**
* Reports the internal API version number of the SDK.
*/
const char *PhysxManager::
get_internal_version() {
NxU32 apiRev;
NxU32 descRev;
NxU32 branchId;
NxU32 v;
v = _sdk->getInternalVersion(apiRev, descRev, branchId);
std::stringstream version;
version << "version:" << (unsigned int)v
<< " apiRef:" << (unsigned int)apiRev
<< " descRev:" << (unsigned int)descRev
<< " branchId: " << (unsigned int)branchId;
return version.str().c_str();
}
/**
*
*/
void PhysxManager::
set_parameter(PhysxParameter param, float value) {
_sdk->setParameter((NxParameter)param, value);
}
/**
*
*/
float PhysxManager::
get_parameter(PhysxParameter param) {
return _sdk->getParameter((NxParameter)param);
}
/**
* Returns the NxSDKCreateError enum as string.
*/
const char *PhysxManager::
get_sdk_error_string(const NxSDKCreateError &error) {
switch (error) {
case NXCE_NO_ERROR: return "NXCE_NO_ERROR"; break;
case NXCE_PHYSX_NOT_FOUND: return "NXCE_PHYSX_NOT_FOUND"; break;
case NXCE_WRONG_VERSION: return "NXCE_WRONG_VERSION"; break;
case NXCE_DESCRIPTOR_INVALID: return "NXCE_DESCRIPTOR_INVALID"; break;
case NXCE_CONNECTION_ERROR: return "NXCE_CONNECTION_ERROR"; break;
case NXCE_RESET_ERROR: return "NXCE_RESET_ERROR"; break;
case NXCE_IN_USE_ERROR: return "NXCE_IN_USE_ERROR"; break;
case NXCE_BUNDLE_ERROR: return "NXCE_BUNDLE_ERROR"; break;
default: return "Unknown error"; break;
}
}
/**
* Reports an error code from the PhysX SDK.
*/
void PhysxManager::PhysxOutputStream::
reportError(NxErrorCode code, const char *message, const char *file, int line) {
physx_cat.error() << get_error_code_string(code) << ": "
<< message << endl;
}
/**
* Returns the NxSDKCreateError enum as string.
*/
const char *PhysxManager::PhysxOutputStream::
get_error_code_string(NxErrorCode code) {
switch (code) {
case NXE_NO_ERROR: return "NO_ERROR"; break;
case NXE_INVALID_PARAMETER: return "INVALID_PARAMETER"; break;
case NXE_INVALID_OPERATION: return "INVALID_OPERATION"; break;
case NXE_OUT_OF_MEMORY: return "OUT_OF_MEMORY"; break;
case NXE_INTERNAL_ERROR: return "INTERNAL_ERROR"; break;
case NXE_ASSERTION: return "ASSERTION"; break;
case NXE_DB_INFO: return "DB_INFO"; break;
case NXE_DB_WARNING: return "DB_WARNING"; break;
case NXE_DB_PRINT: return "DB_PRINT"; break;
default: return ""; break;
}
}
/**
* Reports an assertion violation from the PhysX SDK.
*/
NxAssertResponse PhysxManager::PhysxOutputStream::
reportAssertViolation(const char *message, const char *file, int line) {
physx_cat.error() << "AssertViolation: " << message << endl;
return NX_AR_CONTINUE;
}
/**
* Prints some debug text from the PhysX SDK.
*/
void PhysxManager::PhysxOutputStream::
print(const char *message) {
nout << message;
}