diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 3545381e7f..4b72cc0f10 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -707,9 +707,9 @@ def CompileCxx(obj,src,opts): cmd += "/wd4996 /wd4275 /wd4267 /wd4101 /wd4273 " # Enables Windows 7 mode if SDK is detected. - platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v7.0", "InstallationFolder") - if platsdk and os.path.isdir(platsdk): - cmd += "/DPANDA_WIN7 /DWINVER=0x601 " + #platsdk = GetRegistryKey("SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows\\v7.0", "InstallationFolder") + #if platsdk and os.path.isdir(platsdk): + # cmd += "/DPANDA_WIN7 /DWINVER=0x601 " cmd += "/Fo" + obj + " /nologo /c" for x in ipath: cmd += " /I" + x diff --git a/makepanda/makepandacore.py b/makepanda/makepandacore.py index ab06f4a056..e1c276c378 100644 --- a/makepanda/makepandacore.py +++ b/makepanda/makepandacore.py @@ -1469,6 +1469,7 @@ def SdkLocateMacOSX(osxtarget=None): PHYSXVERSIONINFO=[ ("PHYSX281","v2.8.1"), ("PHYSX283","v2.8.3"), + ("PHYSX284","v2.8.4"), ] def SdkLocatePhysX(): @@ -1476,7 +1477,8 @@ def SdkLocatePhysX(): if (sys.platform == "win32"): folders = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\Folders" for folder in ListRegistryValues(folders): - if folder.endswith("NVIDIA PhysX SDK\\%s\\SDKs\\" % key): + if folder.endswith("NVIDIA PhysX SDK\\%s\\SDKs\\" % key) or \ + folder.endswith("NVIDIA PhysX SDK\\%s_win\\SDKs\\" % key): SDK["PHYSX"] = folder SDK["PHYSXVERSION"] = ver elif (sys.platform.startswith("linux")): diff --git a/panda/src/physx/Sources.pp b/panda/src/physx/Sources.pp index ccbb483113..2752de21d2 100644 --- a/panda/src/physx/Sources.pp +++ b/panda/src/physx/Sources.pp @@ -84,6 +84,7 @@ physxMemoryReadBuffer.h \ physxMemoryWriteBuffer.h \ physxMeshPool.I physxMeshPool.h \ + physxMeshHash.I physxMeshHash.h \ physxMotorDesc.I physxMotorDesc.h \ physxObject.I physxObject.h \ physxObjectCollection.I physxObjectCollection.h \ @@ -110,6 +111,11 @@ physxSegment.I physxSegment.h \ physxShape.I physxShape.h \ physxShapeDesc.I physxShapeDesc.h \ + physxSoftBody.I physxSoftBody.h \ + physxSoftBodyDesc.I physxSoftBodyDesc.h \ + physxSoftMeshBody.I physxSoftMeshBody.h \ + physxSoftBodyMeshDesc.I physxSoftBodyMeshDesc.h \ + physxSoftBodyNode.I physxSoftBodyNode.h \ physxSphere.I physxSphere.h \ physxSphereForceFieldShape.I physxSphereForceFieldShape.h \ physxSphereForceFieldShapeDesc.I physxSphereForceFieldShapeDesc.h \ @@ -205,6 +211,7 @@ physxMemoryReadBuffer.cxx \ physxMemoryWriteBuffer.cxx \ physxMeshPool.cxx \ + physxMeshHash.cxx \ physxMotorDesc.cxx \ physxObject.cxx \ physxObjectCollection.cxx \ @@ -231,6 +238,11 @@ physxSegment.cxx \ physxShape.cxx \ physxShapeDesc.cxx \ + physxSoftBody.cxx \ + physxSoftBodyDesc.cxx \ + physxSoftMeshBody.cxx \ + physxSoftBodyMeshDesc.cxx \ + physxSoftBodyNode.cxx \ physxSphere.cxx \ physxSphereForceFieldShape.cxx \ physxSphereForceFieldShapeDesc.cxx \ @@ -326,6 +338,7 @@ physxMemoryReadBuffer.h \ physxMemoryWriteBuffer.h \ physxMeshPool.I physxMeshPool.h \ + physxMeshHash.I physxMeshHash.h \ physxMotorDesc.I physxMotorDesc.h \ physxObject.I physxObject.h \ physxObjectCollection.I physxObjectCollection.h \ @@ -352,6 +365,11 @@ physxSegment.I physxSegment.h \ physxShape.I physxShape.h \ physxShapeDesc.I physxShapeDesc.h \ + physxSoftBody.I physxSoftBody.h \ + physxSoftBodyDesc.I physxSoftBodyDesc.h \ + physxSoftMeshBody.I physxSoftMeshBody.h \ + physxSoftBodyMeshDesc.I physxSoftBodyMeshDesc.h \ + physxSoftBodyNode.I physxSoftBodyNode.h \ physxSphere.I physxSphere.h \ physxSphereForceFieldShape.I physxSphereForceFieldShape.h \ physxSphereForceFieldShapeDesc.I physxSphereForceFieldShapeDesc.h \ diff --git a/panda/src/physx/config_physx.cxx b/panda/src/physx/config_physx.cxx index d25990723f..d138905a44 100644 --- a/panda/src/physx/config_physx.cxx +++ b/panda/src/physx/config_physx.cxx @@ -52,6 +52,9 @@ #include "physxRevoluteJoint.h" #include "physxScene.h" #include "physxShape.h" +#include "physxSoftBody.h" +#include "physxSoftBodyMesh.h" +#include "physxSoftBodyNode.h" #include "physxSphereForceFieldShape.h" #include "physxSphereShape.h" #include "physxSphericalJoint.h" @@ -150,6 +153,9 @@ init_libphysx() { PhysxRevoluteJoint::init_type(); PhysxScene::init_type(); PhysxShape::init_type(); + PhysxSoftBody::init_type(); + PhysxSoftBodyMesh::init_type(); + PhysxSoftBodyNode::init_type(); PhysxSphereForceFieldShape::init_type(); PhysxSphereShape::init_type(); PhysxSphericalJoint::init_type(); diff --git a/panda/src/physx/physxCloth.cxx b/panda/src/physx/physxCloth.cxx index a18ae60876..0b95626a28 100644 --- a/panda/src/physx/physxCloth.cxx +++ b/panda/src/physx/physxCloth.cxx @@ -83,16 +83,19 @@ release() { void PhysxCloth:: update() { - // Update node mesh data - _node->update(); + if (_node) { - // Update node bounding volume - NxBounds3 bounds; - _ptr->getWorldBounds(bounds); + // Update node mesh data + _node->update(); - BoundingBox bb(PhysxManager::nxVec3_to_point3(bounds.min), - PhysxManager::nxVec3_to_point3(bounds.max)); - _node->set_bounds(&bb); + // Update node bounding volume + NxBounds3 bounds; + _ptr->getWorldBounds(bounds); + + BoundingBox bb(PhysxManager::nxVec3_to_point3(bounds.min), + PhysxManager::nxVec3_to_point3(bounds.max)); + _node->set_bounds(&bb); + } } //////////////////////////////////////////////////////////////////// @@ -200,7 +203,7 @@ void PhysxCloth:: set_thickness(float thickness) { nassertv(_error_type == ET_ok); - _ptr->setFriction(thickness); + _ptr->setThickness(thickness); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/physx/physxEnums.h b/panda/src/physx/physxEnums.h index c5cf0d1fbd..7b3aff8334 100644 --- a/panda/src/physx/physxEnums.h +++ b/panda/src/physx/physxEnums.h @@ -107,10 +107,10 @@ #define NX_FORCE_FIELD_CUSTOM_KERNEL_EPSILON 97 #define NX_IMPROVED_SPRING_SOLVER 98 -#ifdef PHYSX283 +#ifndef PHYSX281 #define NX_FAST_MASSIVE_BP_VOLUME_DELETION 99 #define NX_LEGACY_JOINT_DRIVE 100 -#endif /* PHYSX283 */ +#endif /* PHYSX281 */ // PhysxActorFlag #define NX_AF_DISABLE_COLLISION 1<<0 @@ -297,6 +297,23 @@ #define NX_DYNAMIC_SHAPES 1<<1 #define NX_ALL_SHAPES (1<<0|1<<1) +// PhysxSoftBodyFlag +#define NX_SBF_STATIC 1<<1 +#define NX_SBF_DISABLE_COLLISION 1<<2 +#define NX_SBF_SELFCOLLISION 1<<3 +#define NX_SBF_VISUALIZATION 1<<4 +#define NX_SBF_GRAVITY 1<<5 +#define NX_SBF_VOLUME_CONSERVATION 1<<6 +#define NX_SBF_DAMPING 1<<7 +#define NX_SBF_COLLISION_TWOWAY 1<<8 +#define NX_SBF_TEARABLE 1<<9 +#define NX_SBF_HARDWARE 1<<10 +#define NX_SBF_COMDAMPING 1<<11 +#define NX_SBF_VALIDBOUNDS 1<<12 +#define NX_SBF_FLUID_COLLISION 1<<13 +#define NX_SBF_DISABLE_DYNAMIC_CCD 1<<14 +#define NX_SBF_ADHERE 1<<15 + // PhysxSphericalJointFlag #define NX_SJF_TWIST_LIMIT_ENABLED 1<<0 #define NX_SJF_SWING_LIMIT_ENABLED 1<<1 @@ -634,6 +651,24 @@ PUBLISHED: SF_softbody_twoway = NX_SF_SOFTBODY_TWOWAY }; + enum PhysxSoftBodyFlag { + SBF_static = NX_SBF_STATIC, + SBF_disable_collision = NX_SBF_DISABLE_COLLISION, + SBF_selfcollision = NX_SBF_SELFCOLLISION, + SBF_visualization = NX_SBF_VISUALIZATION, + SBF_gravity = NX_SBF_GRAVITY, + SBF_volume_conservtion = NX_SBF_VOLUME_CONSERVATION, + SBF_damping = NX_SBF_DAMPING, + SBF_collision_twoway = NX_SBF_COLLISION_TWOWAY, + SBF_tearable = NX_SBF_TEARABLE, + SBF_hardware = NX_SBF_HARDWARE, + SBF_comdamping = NX_SBF_COMDAMPING, + SBF_validbounds = NX_SBF_VALIDBOUNDS, + SBF_fluid_collision = NX_SBF_FLUID_COLLISION, + SBF_disable_dynamic_ccd = NX_SBF_DISABLE_DYNAMIC_CCD, + SBF_adhere = NX_SBF_ADHERE + }; + enum PhysxShapesType { ST_static = NX_STATIC_SHAPES , ST_dynamic = NX_DYNAMIC_SHAPES , diff --git a/panda/src/physx/physxKitchen.cxx b/panda/src/physx/physxKitchen.cxx index 379caa184b..883a52911f 100644 --- a/panda/src/physx/physxKitchen.cxx +++ b/panda/src/physx/physxKitchen.cxx @@ -22,6 +22,8 @@ #include "physxMemoryWriteBuffer.h" #include "physxClothMesh.h" #include "physxClothMeshDesc.h" +#include "physxSoftBodyMesh.h" +#include "physxSoftBodyMeshDesc.h" //////////////////////////////////////////////////////////////////// // Function: PhysxKitchen::set_cooking_params @@ -101,6 +103,22 @@ cook_cloth_mesh(const PhysxClothMeshDesc &meshDesc, const Filename &filename) { return _cooking->NxCookClothMesh(meshDesc.get_desc(), fs); } +//////////////////////////////////////////////////////////////////// +// Function: PhysxKitchen::cook_soft_body_mesh +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +bool PhysxKitchen:: +cook_soft_body_mesh(const PhysxSoftBodyMeshDesc &meshDesc, const Filename &filename) { + + nassertr_always(!filename.empty(), false); + nassertr_always(filename.touch(), false); + nassertr_always(meshDesc.is_valid(), false); + + PhysxFileStream fs = PhysxFileStream(filename, false); + return _cooking->NxCookSoftBodyMesh(meshDesc.get_desc(), fs); +} + //////////////////////////////////////////////////////////////////// // Function: PhysxKitchen::cook_texcoords // Access: Published @@ -229,3 +247,32 @@ cook_cloth_mesh(const PhysxClothMeshDesc &meshDesc) { return mesh; } +//////////////////////////////////////////////////////////////////// +// Function: PhysxKitchen::cook_soft_body_mesh +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +PhysxSoftBodyMesh *PhysxKitchen:: +cook_soft_body_mesh(const PhysxSoftBodyMeshDesc &meshDesc) { + + nassertr_always(meshDesc.is_valid(), false); + + PhysxMemoryWriteBuffer wbuffer; + bool status = _cooking->NxCookSoftBodyMesh(meshDesc.get_desc(), wbuffer); + nassertr(status, NULL); + + NxPhysicsSDK *sdk = NxGetPhysicsSDK(); + nassertr(sdk, NULL); + + PhysxSoftBodyMesh *mesh = new PhysxSoftBodyMesh(); + nassertr(mesh, NULL); + + PhysxMemoryReadBuffer rbuffer(wbuffer.data); + NxSoftBodyMesh *meshPtr = sdk->createSoftBodyMesh(rbuffer); + nassertr(meshPtr, NULL); + + mesh->link(meshPtr); + + return mesh; +} + diff --git a/panda/src/physx/physxKitchen.h b/panda/src/physx/physxKitchen.h index c7afadbb53..0b4b438f22 100644 --- a/panda/src/physx/physxKitchen.h +++ b/panda/src/physx/physxKitchen.h @@ -26,6 +26,8 @@ class PhysxTriangleMesh; class PhysxTriangleMeshDesc; class PhysxClothMesh; class PhysxClothMeshDesc; +class PhysxSoftBodyMesh; +class PhysxSoftBodyMeshDesc; //////////////////////////////////////////////////////////////////// // Class : PhysxKitchen @@ -42,11 +44,13 @@ PUBLISHED: bool cook_convex_mesh(const PhysxConvexMeshDesc &meshDesc, const Filename &filename); bool cook_triangle_mesh(const PhysxTriangleMeshDesc &meshDesc, const Filename &filename); bool cook_cloth_mesh(const PhysxClothMeshDesc &meshDesc, const Filename &filename); + bool cook_soft_body_mesh(const PhysxSoftBodyMeshDesc &meshDesc, const Filename &filename); bool cook_texcoords(const PhysxClothMeshDesc &meshDesc, const Filename &filename); PhysxConvexMesh *cook_convex_mesh(const PhysxConvexMeshDesc &meshDesc); PhysxTriangleMesh *cook_triangle_mesh(const PhysxTriangleMeshDesc &meshDesc); PhysxClothMesh *cook_cloth_mesh(const PhysxClothMeshDesc &meshDesc); + PhysxSoftBodyMesh *cook_soft_body_mesh(const PhysxSoftBodyMeshDesc &meshDesc); private: NxCookingInterface *_cooking; diff --git a/panda/src/physx/physxManager.cxx b/panda/src/physx/physxManager.cxx index b775962379..93d67f9cfb 100644 --- a/panda/src/physx/physxManager.cxx +++ b/panda/src/physx/physxManager.cxx @@ -295,6 +295,30 @@ get_cloth_mesh(unsigned int idx) { return (PhysxClothMesh *)_cloth_meshes[idx]; } +//////////////////////////////////////////////////////////////////// +// Function: PhysxManager::get_num_soft_body_meshes +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +unsigned int PhysxManager:: +get_num_soft_body_meshes() { + + return _sdk->getNbSoftBodyMeshes(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxManager::get_soft_body_mesh +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +PhysxSoftBodyMesh *PhysxManager:: +get_soft_body_mesh(unsigned int idx) { + + nassertr_always(idx < _sdk->getNbSoftBodyMeshes(), NULL); + + return (PhysxSoftBodyMesh *)_softbody_meshes[idx]; +} + //////////////////////////////////////////////////////////////////// // Function: PhysxManager::is_hardware_available // Access: Published diff --git a/panda/src/physx/physxManager.h b/panda/src/physx/physxManager.h index ae7fb5b936..31fb06f932 100644 --- a/panda/src/physx/physxManager.h +++ b/panda/src/physx/physxManager.h @@ -27,6 +27,11 @@ class PhysxScene; class PhysxSceneDesc; class PhysxHeightField; class PhysxHeightFieldDesc; +class PhysxTriangleMesh; +class PhysxConvexMesh; +class PhysxClothMesh; +class PhysxSoftBodyMesh; +class PhysxOutputStream; //////////////////////////////////////////////////////////////////// // Class : PhysxManager @@ -75,6 +80,10 @@ PUBLISHED: PhysxClothMesh *get_cloth_mesh(unsigned int idx); MAKE_SEQ(get_cloth_meshes, get_num_cloth_meshes, get_cloth_mesh); + unsigned int get_num_soft_body_meshes(); + PhysxSoftBodyMesh *get_soft_body_mesh(unsigned int idx); + MAKE_SEQ(get_soft_body_meshes, get_num_soft_body_meshes, get_soft_body_mesh); + INLINE void ls() const; INLINE void ls(ostream &out, int indent_level=0) const; @@ -86,6 +95,7 @@ public: PhysxObjectCollection _convex_meshes; PhysxObjectCollection _triangle_meshes; PhysxObjectCollection _cloth_meshes; + PhysxObjectCollection _softbody_meshes; INLINE static NxVec3 vec3_to_nxVec3(const LVector3f &v); INLINE static LVector3f nxVec3_to_vec3(const NxVec3 &v); diff --git a/panda/src/physx/physxMeshHash.I b/panda/src/physx/physxMeshHash.I new file mode 100644 index 0000000000..91c2a30acd --- /dev/null +++ b/panda/src/physx/physxMeshHash.I @@ -0,0 +1,84 @@ +// Filename: physMeshHash.I +// Created by: enn0x (13Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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." +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxMeshHash:: +PhysxMeshHash() { + + _time = 1; + MeshHashRoot *r = _hashIndex; + + for (int i=0; i < _hashIndexSize; i++) { + r->first = -1; + r->timeStamp = 0; + r++; + } + + _spacing = 0.25f; + _invSpacing = 1.0f / _spacing; + +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxMeshHash:: +~PhysxMeshHash() { + +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::hash_function +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +INLINE int PhysxMeshHash:: +hash_function(int xi, int yi, int zi) const { + + unsigned int h = (xi * 92837111)^(yi * 689287499)^(zi * 283923481); + return h % _hashIndexSize; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::cell_coord_of +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void PhysxMeshHash:: +cell_coord_of(const NxVec3 &v, int &xi, int &yi, int &zi) const { + + xi = (int)(v.x * _invSpacing); if (v.x < 0.0f) xi--; + yi = (int)(v.y * _invSpacing); if (v.y < 0.0f) yi--; + zi = (int)(v.z * _invSpacing); if (v.z < 0.0f) zi--; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::get_grid_spacing +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE NxF32 PhysxMeshHash:: +get_grid_spacing() const { + + return 1.0f / _invSpacing; +} + + diff --git a/panda/src/physx/physxMeshHash.cxx b/panda/src/physx/physxMeshHash.cxx new file mode 100644 index 0000000000..ee486680bb --- /dev/null +++ b/panda/src/physx/physxMeshHash.cxx @@ -0,0 +1,263 @@ +// Filename: physxMeshHash.cxx +// Created by: enn0x (13Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "physxMeshHash.h" + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::quick_sort +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxMeshHash:: +quick_sort(pvector &itemIndices, int l, int r) { + + int i, j, mi; + int k, m; + + i = l; j = r; mi = (l + r)/2; + m = itemIndices[mi]; + + while (i <= j) { + while(itemIndices[i] < m) i++; + while(m < itemIndices[j]) j--; + + if (i <= j) { + k = itemIndices[i]; itemIndices[i] = itemIndices[j]; itemIndices[j] = k; + i++; j--; + } + } + + if (l < j) quick_sort(itemIndices, l, j); + if (i < r) quick_sort(itemIndices, i, r); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::compress_indices +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxMeshHash:: +compress_indices(pvector &itemIndices) { + + if (itemIndices.size() == 0) return; + + // Sort results + quick_sort(itemIndices, 0, itemIndices.size() - 1); + + // Mark duplicates + int i = 0; + while (i < (int)itemIndices.size()) { + int j = i+1; + while (j < (int)itemIndices.size() && itemIndices[i] == itemIndices[j]) { + itemIndices[j] = -1; j++; + } + i = j; + } + + // Remove duplicates + i = 0; + while (i < (int)itemIndices.size()) { + if (itemIndices[i] < 0) { + itemIndices[i] = itemIndices[itemIndices.size()-1]; + itemIndices.pop_back(); + } + else i++; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::set_grid_spacing +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxMeshHash:: +set_grid_spacing(float spacing) { + + _spacing = spacing; + _invSpacing = 1.0f / spacing; + + reset(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::reset +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxMeshHash:: +reset() { + + _time++; + _entries.clear(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::add +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxMeshHash:: +add(const NxBounds3 &bounds, int itemIndex) { + + int x1,y1,z1; + int x2,y2,z2; + int x,y,z; + + cell_coord_of(bounds.min, x1, y1, z1); + cell_coord_of(bounds.max, x2, y2, z2); + + MeshHashEntry entry; + entry.itemIndex = itemIndex; + + for (x = x1; x <= x2; x++) { + for (y = y1; y <= y2; y++) { + for (z = z1; z <= z2; z++) { + + int h = hash_function(x, y, z); + MeshHashRoot &r = _hashIndex[h]; + int n = _entries.size(); + + if (r.timeStamp != _time || r.first < 0) + entry.next = -1; + else + entry.next = r.first; + + r.first = n; + r.timeStamp = _time; + + _entries.push_back(entry); + } + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::add +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxMeshHash:: +add(const NxVec3 &pos, int itemIndex) { + + int x, y, z; + + cell_coord_of(pos, x, y, z); + + MeshHashEntry entry; + entry.itemIndex = itemIndex; + + int h = hash_function(x, y, z); + MeshHashRoot &r = _hashIndex[h]; + int n = _entries.size(); + + if (r.timeStamp != _time || r.first < 0) + entry.next = -1; + else + entry.next = r.first; + + r.first = n; + r.timeStamp = _time; + + _entries.push_back(entry); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::query +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxMeshHash:: +query(const NxBounds3 &bounds, pvector &itemIndices, int maxIndices) { + + int x1, y1, z1; + int x2, y2, z2; + int x, y, z; + + cell_coord_of(bounds.min, x1, y1, z1); + cell_coord_of(bounds.max, x2, y2, z2); + + itemIndices.clear(); + + for (x=x1; x<=x2; x++) { + for (y=y1; y<=y2; y++) { + for (z=z1; z<=z2; z++) { + + int h = hash_function(x, y, z); + + MeshHashRoot &r = _hashIndex[h]; + if (r.timeStamp != _time) continue; + int i = r.first; + + while (i >= 0) { + MeshHashEntry &entry = _entries[i]; + itemIndices.push_back(entry.itemIndex); + if (maxIndices >= 0 && (int)itemIndices.size() >= maxIndices) return; + i = entry.next; + } + } + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::query_unique +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxMeshHash:: +query_unique(const NxBounds3 &bounds, pvector &itemIndices, int maxIndices) { + + query(bounds, itemIndices, maxIndices); + compress_indices(itemIndices); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::query +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxMeshHash:: +query(const NxVec3 &pos, pvector &itemIndices, int maxIndices) { + + int x, y, z; + + cell_coord_of(pos, x, y, z); + + itemIndices.clear(); + + int h = hash_function(x, y, z); + MeshHashRoot &r = _hashIndex[h]; + if (r.timeStamp != _time) return; + int i = r.first; + + while (i >= 0) { + MeshHashEntry &entry = _entries[i]; + itemIndices.push_back(entry.itemIndex); + if (maxIndices >= 0 && (int)itemIndices.size() >= maxIndices) return; + i = entry.next; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshHash::query_unique +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxMeshHash:: +query_unique(const NxVec3 &pos, pvector &itemIndices, int maxIndices) { + + query(pos, itemIndices, maxIndices); + compress_indices(itemIndices); +} + diff --git a/panda/src/physx/physxMeshHash.h b/panda/src/physx/physxMeshHash.h new file mode 100644 index 0000000000..1281fc612c --- /dev/null +++ b/panda/src/physx/physxMeshHash.h @@ -0,0 +1,78 @@ +// Filename: physMeshHash.h +// Created by: enn0x (13Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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." +// +//////////////////////////////////////////////////////////////////// + +#ifndef PHYSXMESHHASH_H +#define PHYSXMESHHASH_H + +#include "config_physx.h" + +#include "pvector.h" + +//////////////////////////////////////////////////////////////////// +// Class : PhysxMeshHash +// Description : Utility class used in building links between a +// tetrahedron mesh (soft body) and a triangle mesh +// used for rendering the soft body. +//////////////////////////////////////////////////////////////////// +class PhysxMeshHash { + +public: + PhysxMeshHash(); + ~PhysxMeshHash(); + + void reset(); + + void set_grid_spacing(float spacing); + INLINE NxF32 get_grid_spacing() const; + + void add(const NxBounds3 &bounds, int itemIndex); + void add(const NxVec3 &pos, int itemIndex); + + void query(const NxBounds3 &bounds, pvector &itemIndices, int maxIndices=-1); + void query_unique(const NxBounds3 &bounds, pvector &itemIndices, int maxIndices=-1); + + void query(const NxVec3 &pos, pvector &itemIndices, int maxIndices=-1); + void query_unique(const NxVec3 &pos, pvector &itemIndices, int maxIndices=-1); + +private: + struct MeshHashRoot { + int first; + int timeStamp; + }; + + struct MeshHashEntry { + int itemIndex; + int next; + }; + + NxI32 _time; + NxF32 _spacing; + NxF32 _invSpacing; + + static const int _hashIndexSize = 17011; + MeshHashRoot _hashIndex[_hashIndexSize]; + + pvector _entries; + + INLINE int hash_function(int xi, int yi, int zi) const; + INLINE void cell_coord_of(const NxVec3 &v, int &xi, int &yi, int &zi) const; + + void compress_indices(pvector &itemIndices); + void quick_sort(pvector &itemIndices, int l, int r); + +}; + +#include "physxMeshHash.I" + +#endif // PHYSXMESHHASH_H diff --git a/panda/src/physx/physxMeshPool.cxx b/panda/src/physx/physxMeshPool.cxx index 2e41b5262f..4e89624cc0 100644 --- a/panda/src/physx/physxMeshPool.cxx +++ b/panda/src/physx/physxMeshPool.cxx @@ -16,6 +16,7 @@ #include "physxConvexMesh.h" #include "physxTriangleMesh.h" #include "physxClothMesh.h" +#include "physxSoftBodyMesh.h" #include "physxFileStream.h" #include "virtualFileSystem.h" @@ -23,7 +24,7 @@ PhysxMeshPool::ConvexMeshes PhysxMeshPool::_convex_meshes; PhysxMeshPool::TriangleMeshes PhysxMeshPool::_triangle_meshes; PhysxMeshPool::ClothMeshes PhysxMeshPool::_cloth_meshes; -//PhysxMeshPool::SoftbodyMeshes PhysxMeshPool::_softbody_meshes; +PhysxMeshPool::SoftbodyMeshes PhysxMeshPool::_softbody_meshes; //////////////////////////////////////////////////////////////////// // Function: PhysxMeshPool::check_file @@ -163,6 +164,45 @@ load_cloth_mesh(const Filename &fn) { return mesh; } +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshPool::load_soft_body_mesh +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +PhysxSoftBodyMesh *PhysxMeshPool:: +load_soft_body_mesh(const Filename &fn) { + + if (!check_filename(fn)) return NULL; + + PhysxSoftBodyMesh *mesh; + + SoftbodyMeshes::iterator it = _softbody_meshes.find(fn); + if (it == _softbody_meshes.end()) { + // Not found; load mesh. + NxSoftBodyMesh *meshPtr; + PhysxFileStream stream = PhysxFileStream(fn, true); + + mesh = new PhysxSoftBodyMesh(); + nassertr_always(mesh, NULL); + + NxPhysicsSDK *sdk = NxGetPhysicsSDK(); + nassertr_always(sdk, NULL); + + meshPtr = sdk->createSoftBodyMesh(stream); + nassertr_always(meshPtr, NULL); + + mesh->link(meshPtr); + + _softbody_meshes.insert(SoftbodyMeshes::value_type(fn, mesh)); + } + else { + // Found; return previously loaded mesh. + mesh = (*it).second; + } + + return mesh; +} + //////////////////////////////////////////////////////////////////// // Function: PhysxMeshPool::release_convex_mesh // Access: Published @@ -220,6 +260,25 @@ release_cloth_mesh(PhysxClothMesh *mesh) { return false; } +//////////////////////////////////////////////////////////////////// +// Function: PhysxMeshPool::release_soft_body_mesh +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +bool PhysxMeshPool:: +release_soft_body_mesh(PhysxSoftBodyMesh *mesh) { + + SoftbodyMeshes::iterator it; + for (it=_softbody_meshes.begin(); it != _softbody_meshes.end(); ++it) { + if (mesh == (*it).second) { + _softbody_meshes.erase(it); + return true; + } + } + + return false; +} + //////////////////////////////////////////////////////////////////// // Function: PhysxMeshPool::list_content // Access: Published @@ -279,6 +338,19 @@ list_contents(ostream &out) { } } + // Soft body meshes + { + SoftbodyMeshes::const_iterator it; + for (it=_softbody_meshes.begin(); it != _softbody_meshes.end(); ++it) { + Filename fn = (*it).first; + PhysxSoftBodyMesh *mesh = (*it).second; + + out << " " << fn.get_fullpath() + << " (soft body mesh, " << mesh->ptr()->getReferenceCount() + << " references)\n"; + } + } + // Summary NxPhysicsSDK *sdk = NxGetPhysicsSDK(); @@ -290,5 +362,8 @@ list_contents(ostream &out) { out << " Total number of cloth meshes: " << sdk->getNbClothMeshes() << " created, " << _cloth_meshes.size() << " registred\n"; + + out << " Total number of soft body meshes: " << sdk->getNbSoftBodyMeshes() + << " created, " << _softbody_meshes.size() << " registred\n"; } diff --git a/panda/src/physx/physxMeshPool.h b/panda/src/physx/physxMeshPool.h index 096ea92099..5dd14ff656 100644 --- a/panda/src/physx/physxMeshPool.h +++ b/panda/src/physx/physxMeshPool.h @@ -26,6 +26,7 @@ class PhysxConvexMesh; class PhysxTriangleMesh; class PhysxClothMesh; +class PhysxSoftBodyMesh; //////////////////////////////////////////////////////////////////// // Class : PhysxMeshPool @@ -44,12 +45,12 @@ PUBLISHED: static PhysxConvexMesh *load_convex_mesh(const Filename &filename); static PhysxTriangleMesh *load_triangle_mesh(const Filename &filename); static PhysxClothMesh *load_cloth_mesh(const Filename &filename); - //static PhysxSoftBodyMesh *load_softbody_mesh(const Filename &filename); + static PhysxSoftBodyMesh *load_soft_body_mesh(const Filename &filename); static bool release_convex_mesh(PhysxConvexMesh *mesh); static bool release_triangle_mesh(PhysxTriangleMesh *mesh); static bool release_cloth_mesh(PhysxClothMesh *mesh); - //static bool release_softbody_mesh(PhysxSoftBodyMesh *mesh); + static bool release_soft_body_mesh(PhysxSoftBodyMesh *mesh); static void list_contents(); static void list_contents(ostream &out); @@ -66,8 +67,8 @@ private: typedef pmap ClothMeshes; static ClothMeshes _cloth_meshes; - //typedef pmap SoftbodyMeshes; - //static SoftbodyMeshes _softbody_meshes; + typedef pmap SoftbodyMeshes; + static SoftbodyMeshes _softbody_meshes; }; #include "physxMeshPool.I" diff --git a/panda/src/physx/physxScene.I b/panda/src/physx/physxScene.I index d645f807fb..6ae4bcf86b 100644 --- a/panda/src/physx/physxScene.I +++ b/panda/src/physx/physxScene.I @@ -66,6 +66,6 @@ ls(ostream &out, int indent_level) const { _controllers.ls(out, indent_level); _vehicles.ls(out, indent_level); _cloths.ls(out, indent_level); - //_softbodies.ls(out, indent_level); + _softbodies.ls(out, indent_level); } diff --git a/panda/src/physx/physxScene.cxx b/panda/src/physx/physxScene.cxx index 768be5a148..440d1a36a4 100644 --- a/panda/src/physx/physxScene.cxx +++ b/panda/src/physx/physxScene.cxx @@ -24,6 +24,8 @@ #include "physxVehicleDesc.h" #include "physxCloth.h" #include "physxClothDesc.h" +#include "physxSoftBody.h" +#include "physxSoftBodyDesc.h" TypeHandle PhysxScene::_type_handle; @@ -32,7 +34,7 @@ PStatCollector PhysxScene::_pcollector_update_transforms("App:PhysX:Update Trans PStatCollector PhysxScene::_pcollector_debug_renderer("App:PhysX:Debug Renderer"); PStatCollector PhysxScene::_pcollector_simulate("App:PhysX:Simulate"); PStatCollector PhysxScene::_pcollector_cloth("App:PhysX:Cloth"); -//PStatCollector PhysxScene::_pcollector_softbody("App:PhysX:Softbody"); +PStatCollector PhysxScene::_pcollector_softbody("App:PhysX:Softbody"); //////////////////////////////////////////////////////////////////// // Function: PhysxScene::link @@ -137,15 +139,13 @@ unlink() { } // Unlink softbodies -/* - NxSoftBody **sbs = _ptr->getSoftBodies(); - NxU32 nSbs = _ptr->getNbSoftBodies(); + NxSoftBody **softbodies = _ptr->getSoftBodies(); + NxU32 nSoftbodies = _ptr->getNbSoftBodies(); - for (NxU32 i=0; i < nSbs; i++) { - PhysxSoftBody *sb = (PhysxSoftBody *)sb[i]->userData; - sb->unlink(); + for (NxU32 i=0; i < nSoftbodies; i++) { + PhysxSoftBody *softbody = (PhysxSoftBody *)softbodies[i]->userData; + softbody->unlink(); } -*/ // Unlink materials NxMaterial *materials[5]; @@ -241,6 +241,12 @@ simulate(float dt) { void PhysxScene:: fetch_results() { +#ifdef NX64 + cout << "<64bit>"; +#else + cout << "<32bit>"; +#endif + nassertv(_error_type == ET_ok); nassertv(_ptr != NULL); @@ -288,15 +294,15 @@ fetch_results() { _pcollector_cloth.stop(); // Update softbody nodes -/* _pcollector_softbody.start(); + NxSoftBody **softbodies = _ptr->getSoftBodies(); for (NxU32 i=0; i < _ptr->getNbSoftBodies(); i++) { PT(PhysxSoftBody) softbody = (PhysxSoftBody *)softbodies[i]->userData; softbody->update(); } + _pcollector_softbody.stop(); -*/ } //////////////////////////////////////////////////////////////////// @@ -951,6 +957,57 @@ get_cloth(unsigned int idx) const { return (PhysxCloth *)(clothPtr->userData); } +//////////////////////////////////////////////////////////////////// +// Function: PhysxScene::get_num_soft_bodies +// Access: Published +// Description: Gets the number of soft bodies in the scene. +//////////////////////////////////////////////////////////////////// +unsigned int PhysxScene:: +get_num_soft_bodies() const { + + nassertr(_error_type == ET_ok, -1); + return _ptr->getNbSoftBodies(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxScene::create_soft_body +// Access: Published +// Description: Creates a soft body in this scene. +//////////////////////////////////////////////////////////////////// +PhysxSoftBody *PhysxScene:: +create_soft_body(PhysxSoftBodyDesc &desc) { + + nassertr(_error_type == ET_ok, NULL); + + PhysxSoftBody *softbody = new PhysxSoftBody(); + nassertr(softbody, NULL); + + NxSoftBody *softbodyPtr = _ptr->createSoftBody(desc._desc); + nassertr(softbodyPtr, NULL); + + softbody->link(softbodyPtr); + + return softbody; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxScene::get_soft_body +// Access: Published +// Description: Returns the n-th soft body from the array of +// all the soft bodies in the scene. +//////////////////////////////////////////////////////////////////// +PhysxSoftBody *PhysxScene:: +get_soft_body(unsigned int idx) const { + + nassertr(_error_type == ET_ok, NULL); + nassertr_always(idx < _ptr->getNbSoftBodies(), NULL); + + NxSoftBody **softbodies = _ptr->getSoftBodies(); + NxSoftBody *softbodyPtr = softbodies[idx]; + + return (PhysxSoftBody *)(softbodyPtr->userData); +} + //////////////////////////////////////////////////////////////////// // Function: PhysxScene::get_num_vehicles // Access: Published diff --git a/panda/src/physx/physxScene.h b/panda/src/physx/physxScene.h index 0ebb232f6b..db48421070 100644 --- a/panda/src/physx/physxScene.h +++ b/panda/src/physx/physxScene.h @@ -52,6 +52,8 @@ class PhysxVehicle; class PhysxVehicleDesc; class PhysxCloth; class PhysxClothDesc; +class PhysxSoftBody; +class PhysxSoftBodyDesc; //////////////////////////////////////////////////////////////////// // Class : PhysxScene @@ -139,6 +141,12 @@ PUBLISHED: PhysxCloth *get_cloth(unsigned int idx) const; MAKE_SEQ(get_cloths, get_num_cloths, get_cloth); + // Soft bodies + unsigned int get_num_soft_bodies() const; + PhysxSoftBody *create_soft_body(PhysxSoftBodyDesc &desc); + PhysxSoftBody *get_soft_body(unsigned int idx) const; + MAKE_SEQ(get_soft_bodies, get_num_soft_bodies, get_soft_body); + // Vehicles unsigned int get_num_vehicles() const; PhysxVehicle *create_vehicle(PhysxVehicleDesc &desc); @@ -230,6 +238,7 @@ public: PhysxObjectCollection _controllers; PhysxObjectCollection _vehicles; PhysxObjectCollection _cloths; + PhysxObjectCollection _softbodies; PhysxMaterial *get_wheel_shape_material(); @@ -248,7 +257,7 @@ private: static PStatCollector _pcollector_debug_renderer; static PStatCollector _pcollector_simulate; static PStatCollector _pcollector_cloth; - //static PStatCollector _pcollector_softbody; + static PStatCollector _pcollector_softbody; //////////////////////////////////////////////////////////////////// public: diff --git a/panda/src/physx/physxSoftBody.I b/panda/src/physx/physxSoftBody.I new file mode 100644 index 0000000000..92ea648ff8 --- /dev/null +++ b/panda/src/physx/physxSoftBody.I @@ -0,0 +1,66 @@ +// Filename: physxSoftBody.I +// Created by: enn0x (13Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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." +// +//////////////////////////////////////////////////////////////////// + + + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxSoftBody:: +PhysxSoftBody() : PhysxObject() { + +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::Destructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxSoftBody:: +~PhysxSoftBody() { + +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::ls +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void PhysxSoftBody:: +ls() const { + + ls(nout); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::ls +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void PhysxSoftBody:: +ls(ostream &out, int indent_level) const { + + indent(out, indent_level) << get_type().get_name() + << " " << _name + << " (at 0x" << this << ")"; + + if (_node) { + out << " N:0x" << _node; + } + + out << "\n"; +} + diff --git a/panda/src/physx/physxSoftBody.cxx b/panda/src/physx/physxSoftBody.cxx new file mode 100644 index 0000000000..10e75d9b69 --- /dev/null +++ b/panda/src/physx/physxSoftBody.cxx @@ -0,0 +1,914 @@ +// Filename: physxSoftBody.cxx +// Created by: enn0x (13Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "physxSoftBody.h" +#include "physxSoftBodyDesc.h" +#include "physxSoftBodyNode.h" +#include "physxScene.h" +#include "physxGroupsMask.h" + +#include "boundingBox.h" + +TypeHandle PhysxSoftBody::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::link +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +link(NxSoftBody *softbodyPtr) { + + // Link self + _ptr = softbodyPtr; + _error_type = ET_ok; + _ptr->userData = this; + + set_name(softbodyPtr->getName()); + + PhysxScene *scene = (PhysxScene *)_ptr->getScene().userData; + scene->_softbodies.add(this); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::unlink +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +unlink() { + + // Unlink self + _ptr->userData = NULL; + _error_type = ET_released; + + PhysxScene *scene = (PhysxScene *)_ptr->getScene().userData; + scene->_softbodies.remove(this); + + _node = NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::release +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +release() { + + nassertv(_error_type == ET_ok); + + unlink(); + _ptr->getScene().releaseSoftBody(*_ptr); + _ptr = NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::update +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +update() { + + if (_node) { + + // Update node mesh data + _node->update(); + + // Update node bounding volume + NxBounds3 bounds; + _ptr->getWorldBounds(bounds); + + BoundingBox bb(PhysxManager::nxVec3_to_point3(bounds.min), + PhysxManager::nxVec3_to_point3(bounds.max)); + _node->set_bounds(&bb); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_scene +// Access: Published +// Description: Returns the scene which this soft body belongs to. +//////////////////////////////////////////////////////////////////// +PhysxScene *PhysxSoftBody:: +get_scene() const { + + nassertr(_error_type == ET_ok, NULL); + return (PhysxScene *)_ptr->getScene().userData; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_soft_body_node +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +PhysxSoftBodyNode *PhysxSoftBody:: +get_soft_body_node() const { + + nassertr(_error_type == ET_ok, NULL); + return _node; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::create_soft_body_node +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +PhysxSoftBodyNode *PhysxSoftBody:: +create_soft_body_node(const char *name) { + + nassertr(_error_type == ET_ok, NULL); + + _node = new PhysxSoftBodyNode(name); + _node->allocate(this); + + return _node; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_name +// Access: Published +// Description: Sets a name string for the object that can be +// retrieved with get_name(). +// This is for debugging and is not used by the +// engine. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_name(const char *name) { + + nassertv(_error_type == ET_ok); + + _name = name ? name : ""; + _ptr->setName(_name.c_str()); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_name +// Access: Published +// Description: Retrieves the name string. +//////////////////////////////////////////////////////////////////// +const char *PhysxSoftBody:: +get_name() const { + + nassertr(_error_type == ET_ok, ""); + return _ptr->getName(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_group +// Access: Published +// Description: Sets which collision group this soft body is part +// of. Collision group must be between 0 and 31. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_group(unsigned int group) { + + nassertv(_error_type == ET_ok); + nassertv(group >= 0 && group < 32); + _ptr->setGroup(group); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_group +// Access: Published +// Description: Retrieves the collision group this soft body is +// part of. +//////////////////////////////////////////////////////////////////// +unsigned int PhysxSoftBody:: +get_group() const { + + nassertr(_error_type == ET_ok, 0); + return _ptr->getGroup(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_groups_mask +// Access: Published +// Description: Sets 128-bit mask used for collision filtering. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_groups_mask(const PhysxGroupsMask &mask) { + + nassertv(_error_type == ET_ok); + + NxGroupsMask _mask = mask.get_mask(); + _ptr->setGroupsMask(_mask); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_groups_mask +// Access: Published +// Description: Gets the 128-bit groups mask used for collision +// filtering. +//////////////////////////////////////////////////////////////////// +PhysxGroupsMask PhysxSoftBody:: +get_groups_mask() const { + + PhysxGroupsMask mask; + + nassertr(_error_type == ET_ok, mask); + + NxGroupsMask _mask = _ptr->getGroupsMask(); + mask.set_mask(_mask); + + return mask; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_num_particles +// Access: Published +// Description: Gets the number of cloth particles. +//////////////////////////////////////////////////////////////////// +unsigned int PhysxSoftBody:: +get_num_particles() { + + nassertr(_error_type == ET_ok, 0); + return _ptr->getNumberOfParticles(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_particle_radius +// Access: Published +// Description: Sets the soft body particle radius (must be +// positive). +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_particle_radius(float radius) { + + nassertv(_error_type == ET_ok); + _ptr->setParticleRadius(radius); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_particle_radius +// Access: Published +// Description: Gets the soft body particle radius. +//////////////////////////////////////////////////////////////////// +float PhysxSoftBody:: +get_particle_radius() const { + + nassertr(_error_type == ET_ok, 0.0f); + return _ptr->getParticleRadius(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_flag +// Access: Published +// Description: Sets the value of a single flag. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_flag(PhysxSoftBodyFlag flag, bool value) { + + nassertv(_error_type == ET_ok); + + NxU32 flags = _ptr->getFlags(); + + if (value == true) { + flags |= flag; + } + else { + flags &= ~(flag); + } + + _ptr->setFlags(flags); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_flag +// Access: Published +// Description: Retrieves the value of a single flag. +//////////////////////////////////////////////////////////////////// +bool PhysxSoftBody:: +get_flag(PhysxSoftBodyFlag flag) const { + + nassertr(_error_type == ET_ok, false); + + return (_ptr->getFlags() & flag) ? true : false; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_density +// Access: Published +// Description: Gets the soft body density. +//////////////////////////////////////////////////////////////////// +float PhysxSoftBody:: +get_density() const { + + nassertr(_error_type == ET_ok, 0.0f); + return _ptr->getDensity(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_relative_grid_spacing +// Access: Published +// Description: Gets the relative grid spacing for the broad +// phase. The cloth is represented by a set of +// world aligned cubical cells in broad phase. The +// size of these cells is determined by multiplying +// the length of the diagonal of the AABB of the +// initial soft body size with this constant. +//////////////////////////////////////////////////////////////////// +float PhysxSoftBody:: +get_relative_grid_spacing() const { + + nassertr(_error_type == ET_ok, 0.0f); + return _ptr->getRelativeGridSpacing(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_volume_stiffness +// Access: Published +// Description: Sets the soft body volume stiffness in the range +// from 0 to 1. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_volume_stiffness(float stiffness) { + + nassertv(_error_type == ET_ok); + ptr()->setVolumeStiffness(stiffness); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_volume_stiffness +// Access: Published +// Description: Retrieves the soft body volume stiffness. +//////////////////////////////////////////////////////////////////// +float PhysxSoftBody:: +get_volume_stiffness() const { + + nassertr(_error_type == ET_ok, 0.0f); + return ptr()->getVolumeStiffness(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_stretching_stiffness +// Access: Published +// Description: Sets the soft body stretching stiffness in the +// range from 0 to 1. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_stretching_stiffness(float stiffness) { + + nassertv(_error_type == ET_ok); + ptr()->setStretchingStiffness(stiffness); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_stretching_stiffness +// Access: Published +// Description: Retrieves the soft body stretching stiffness. +//////////////////////////////////////////////////////////////////// +float PhysxSoftBody:: +get_stretching_stiffness() const { + + nassertr(_error_type == ET_ok, 0.0f); + return ptr()->getStretchingStiffness(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_damping_coefficient +// Access: Published +// Description: Sets the damping coefficient in the range from 0 +// to 1. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_damping_coefficient(float coef) { + + nassertv(_error_type == ET_ok); + ptr()->setDampingCoefficient(coef); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_damping_coefficient +// Access: Published +// Description: Retrieves the damping coefficient. +//////////////////////////////////////////////////////////////////// +float PhysxSoftBody:: +get_damping_coefficient() const { + + nassertr(_error_type == ET_ok, 0.0f); + return ptr()->getDampingCoefficient(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_friction +// Access: Published +// Description: Sets the soft body friction coefficient in the +// range from 0 to 1. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_friction(float friction) { + + nassertv(_error_type == ET_ok); + ptr()->setFriction(friction); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_friction +// Access: Published +// Description: Retrieves the soft body friction coefficient. +//////////////////////////////////////////////////////////////////// +float PhysxSoftBody:: +get_friction() const { + + nassertr(_error_type == ET_ok, 0.0f); + return ptr()->getFriction(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_tear_factor +// Access: Published +// Description: Sets the soft body tear factor (must be larger +// than one). +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_tear_factor(float factor) { + + nassertv(_error_type == ET_ok); + nassertv(factor > 1.0f); + ptr()->setTearFactor(factor); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_tear_factor +// Access: Published +// Description: Retrieves the soft body tear factor. +//////////////////////////////////////////////////////////////////// +float PhysxSoftBody:: +get_tear_factor() const { + + nassertr(_error_type == ET_ok, 0.0f); + return ptr()->getTearFactor(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_attachment_tear_factor +// Access: Published +// Description: Sets the soft body attachment tear factor (must be +// larger than one). +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_attachment_tear_factor(float factor) { + + nassertv(_error_type == ET_ok); + nassertv(factor > 1.0f); + ptr()->setAttachmentTearFactor(factor); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_attachment_tear_factor +// Access: Published +// Description: Retrieves the attachment soft body tear factor. +//////////////////////////////////////////////////////////////////// +float PhysxSoftBody:: +get_attachment_tear_factor() const { + + nassertr(_error_type == ET_ok, 0.0f); + return ptr()->getAttachmentTearFactor(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_solver_iterations +// Access: Published +// Description: Sets the soft body solver iterations. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_solver_iterations(unsigned int iterations) { + + nassertv(_error_type == ET_ok); + ptr()->setSolverIterations(iterations); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_solver_iterations +// Access: Published +// Description: Retrieves the soft body solver iterations. +//////////////////////////////////////////////////////////////////// +unsigned int PhysxSoftBody:: +get_solver_iterations() const { + + nassertr(_error_type == ET_ok, 0); + return ptr()->getSolverIterations(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::is_sleeping +// Access: Published +// Description: Returns true if this soft body is sleeping. +// +// When a soft body does not move for a period of +// time, it is no longer simulated in order to save +// time. This state is called sleeping. However, +// because the object automatically wakes up when it +// is either touched by an awake object, or one of its +// properties is changed by the user, the entire sleep +// mechanism should be transparent to the user. +//////////////////////////////////////////////////////////////////// +bool PhysxSoftBody:: +is_sleeping() const { + + nassertr(_error_type == ET_ok, false); + return _ptr->isSleeping(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::wake_up +// Access: Published +// Description: Wakes up the soft body if it is sleeping. +// +// The wakeCounterValue determines how long until the +// body is put to sleep, a value of zero means that +// the body is sleeping. wake_up(0) is equivalent to +// PhysxSoftBody::put_to_sleep(). +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +wake_up(float wakeCounterValue) { + + nassertv(_error_type == ET_ok); + _ptr->wakeUp(wakeCounterValue); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::put_to_sleep +// Access: Published +// Description: Forces the soft body to sleep. +// +// The soft body will stay asleep until the next +// call to simulate, and will not wake up until then +// even when otherwise it would (for example a force +// is applied to it). It can however wake up during +// the next do_physics call. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +put_to_sleep() { + + nassertv(_error_type == ET_ok); + _ptr->putToSleep(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_sleep_linear_velocity +// Access: Published +// Description: Sets the linear velocity below which an soft body +// may go to sleep. SoftBodys whose linear velocity is +// above this threshold will not be put to sleep. +// +// Setting the sleep angular/linear velocity only +// makes sense when the BF_energy_sleep_test is not +// set. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_sleep_linear_velocity(float threshold) { + + nassertv(_error_type == ET_ok); + _ptr->setSleepLinearVelocity(threshold); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_sleep_linear_velocity +// Access: Published +// Description: Returns the linear velocity below which an soft +// body may go to sleep. Soft bodies whose linear +// velocity is above this threshold will not be put +// to sleep. +//////////////////////////////////////////////////////////////////// +float PhysxSoftBody:: +get_sleep_linear_velocity() const { + + nassertr(_error_type == ET_ok, 0.0f); + return _ptr->getSleepLinearVelocity(); +} + +#ifndef PHYSX281 +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_self_collision_thickness +// Access: Published +// Description: Sets the soft body self collision thickness (must +// be positive). +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_self_collision_thickness(float thickness) { + + nassertv(_error_type == ET_ok); + _ptr->setSelfCollisionThickness(thickness); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_self_collision_thickness +// Access: Published +// Description: Gets the soft body self collision thickness. +//////////////////////////////////////////////////////////////////// +float PhysxSoftBody:: +get_self_collision_thickness() const { + + nassertr(_error_type == ET_ok, 0.0f); + return _ptr->getSelfCollisionThickness(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_hard_stretch_limitation_factor +// Access: Published +// Description: Sets the soft body hard stretch elongation limit. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_hard_stretch_limitation_factor(float factor) { + + nassertv(_error_type == ET_ok); + ptr()->setHardStretchLimitationFactor(factor); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_hard_stretch_limitation_factor +// Access: Published +// Description: Retrieves the soft body hard stretch elongation +// limit. +//////////////////////////////////////////////////////////////////// +float PhysxSoftBody:: +get_hard_stretch_limitation_factor() const { + + nassertr(_error_type == ET_ok, 0.0f); + return ptr()->getHardStretchLimitationFactor(); +} +#endif // PHYSX281 + + + + + + + + +/* +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::attach_vertex_to_global_pos +// Access: Published +// Description: Attaches a cloth vertex to a position in world +// space. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +attach_vertex_to_global_pos(unsigned int vertexId, LPoint3f const &pos) { + + nassertv(_error_type == ET_ok); + nassertv(!pos.is_nan()); + + _ptr->attachVertexToGlobalPosition(vertexId, PhysxManager::point3_to_nxVec3(pos)); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::attach_to_shape +// Access: Published +// Description: Attaches the cloth to a shape. All cloth points +// currently inside the shape are attached. +// +// This method only works with primitive and convex +// shapes. Since the inside of a general triangle mesh +// is not clearly defined. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +attach_to_shape(PhysxShape *shape) { + + nassertv(_error_type == ET_ok); + nassertv(shape); + + NxU32 attachmentFlags = 0; // --TODO-- + _ptr->attachToShape(shape->ptr(), attachmentFlags); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::attach_to_colliding_shapes +// Access: Published +// Description: Attaches the cloth to all shapes, currently +// colliding. +// +// This method only works with primitive and convex +// shapes. Since the inside of a general triangle mesh +// is not clearly defined. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +attach_to_colliding_shapes() { + + nassertv(_error_type == ET_ok); + + NxU32 attachmentFlags = 0; // --TODO-- + _ptr->attachToCollidingShapes(attachmentFlags); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::detach_from_shape +// Access: Published +// Description: Detaches the cloth from a shape it has been +// attached to before. +// +// If the cloth has not been attached to the shape +// before, the call has no effect. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +detach_from_shape(PhysxShape *shape) { + + nassertv(_error_type == ET_ok); + nassertv(shape); + + _ptr->detachFromShape(shape->ptr()); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::free_vertex +// Access: Published +// Description: Frees a previously attached cloth point. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +free_vertex(unsigned int vertexId) { + + nassertv(_error_type == ET_ok); + _ptr->freeVertex(vertexId); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::attach_vertex_to_shape +// Access: Published +// Description: Attaches a cloth vertex to a local position within +// a shape. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +attach_vertex_to_shape(unsigned int vertexId, PhysxShape *shape, LPoint3f const &localPos) { + + nassertv(_error_type == ET_ok); + nassertv(!localPos.is_nan()); + nassertv(shape); + + NxU32 attachmentFlags = 0; // --TODO-- + _ptr->attachVertexToShape(vertexId, shape->ptr(), + PhysxManager::point3_to_nxVec3(localPos), + attachmentFlags); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_vertex_attachment_status +// Access: Published +// Description: Return the attachment status of the given vertex. +//////////////////////////////////////////////////////////////////// +PhysxEnums::PhysxVertexAttachmentStatus PhysxSoftBody:: +get_vertex_attachment_status(unsigned int vertexId) const { + + nassertr(_error_type == ET_ok, VAS_none); + // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(), VAS_none); + + return (PhysxVertexAttachmentStatus) _ptr->getVertexAttachmentStatus(vertexId); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_vertex_attachment_shape +// Access: Published +// Description: Returns the pointer to an attached shape pointer +// of the given vertex. If the vertex is not attached +// or attached to a global position, NULL is returned. +//////////////////////////////////////////////////////////////////// +PhysxShape *PhysxSoftBody:: +get_vertex_attachment_shape(unsigned int vertexId) const { + + nassertr(_error_type == ET_ok, NULL); + // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(), NULL); + + NxShape *shapePtr = _ptr->getVertexAttachmentShape(vertexId); + PhysxShape *shape = shapePtr ? (PhysxShape *)(shapePtr->userData) : NULL; + + return shape; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_vertex_attachment_pos +// Access: Published +// Description: Returns the attachment position of the given +// vertex. If the vertex is attached to shape, the +// position local to the shape's pose is returned. If +// the vertex is not attached, the return value is +// undefined. +//////////////////////////////////////////////////////////////////// +LPoint3f PhysxSoftBody:: +get_vertex_attachment_pos(unsigned int vertexId) const { + + nassertr(_error_type == ET_ok, LPoint3f::zero()); + // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(), LPoint3f::zero()); + + return PhysxManager::nxVec3_to_point3(_ptr->getVertexAttachmentPosition(vertexId)); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_external_acceleration +// Access: Published +// Description: Sets an external acceleration which affects all non +// attached particles of the cloth. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_external_acceleration(LVector3f const &acceleration) { + + nassertv(_error_type == ET_ok); + nassertv_always(!acceleration.is_nan()); + + _ptr->setExternalAcceleration(PhysxManager::vec3_to_nxVec3(acceleration)); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::set_wind_acceleration +// Access: Published +// Description: Sets an acceleration acting normal to the cloth +// surface at each vertex. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +set_wind_acceleration(LVector3f const &acceleration) { + + nassertv(_error_type == ET_ok); + nassertv_always(!acceleration.is_nan()); + + _ptr->setWindAcceleration(PhysxManager::vec3_to_nxVec3(acceleration)); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_external_acceleration +// Access: Published +// Description: Retrieves the external acceleration which affects +// all non attached particles of the cloth. +//////////////////////////////////////////////////////////////////// +LVector3f PhysxSoftBody:: +get_external_acceleration() const { + + nassertr(_error_type == ET_ok, LVector3f::zero()); + return PhysxManager::nxVec3_to_vec3(_ptr->getExternalAcceleration()); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::get_wind_acceleration +// Access: Published +// Description: Retrieves the acceleration acting normal to the +// cloth surface at each vertex +//////////////////////////////////////////////////////////////////// +LVector3f PhysxSoftBody:: +get_wind_acceleration() const { + + nassertr(_error_type == ET_ok, LVector3f::zero()); + return PhysxManager::nxVec3_to_vec3(_ptr->getWindAcceleration()); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::add_force_at_vertex +// Access: Published +// Description: Applies a force (or impulse) defined in the +// global coordinate frame, to a particular vertex +// of the cloth. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +add_force_at_vertex(LVector3f const &force, int vertexId, PhysxForceMode mode) { + + nassertv(_error_type == ET_ok); + _ptr->addForceAtVertex(PhysxManager::vec3_to_nxVec3(force), + vertexId, + (NxForceMode) mode); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::add_force_at_pos +// Access: Published +// Description: Applies a radial force (or impulse) at a +// particular position. All vertices within radius +// will be affected with a quadratic drop-off. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +add_force_at_pos(LPoint3f const &pos, float magnitude, float radius, PhysxForceMode mode) { + + nassertv(_error_type == ET_ok); + _ptr->addForceAtPos(PhysxManager::point3_to_nxVec3(pos), + magnitude, + radius, + (NxForceMode) mode); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBody::add_directed_force_at_pos +// Access: Published +// Description: Applies a directed force (or impulse) at a +// particular position. All vertices within radius +// will be affected with a quadratic drop-off. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBody:: +add_directed_force_at_pos(LPoint3f const &pos, LVector3f const &force, float radius, PhysxForceMode mode) { + + nassertv(_error_type == ET_ok); + _ptr->addDirectedForceAtPos(PhysxManager::point3_to_nxVec3(pos), + PhysxManager::vec3_to_nxVec3(force), + radius, + (NxForceMode) mode); +} +*/ + diff --git a/panda/src/physx/physxSoftBody.h b/panda/src/physx/physxSoftBody.h new file mode 100644 index 0000000000..c973b3e313 --- /dev/null +++ b/panda/src/physx/physxSoftBody.h @@ -0,0 +1,218 @@ +// Filename: physxSoftBody.h +// Created by: enn0x (13Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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." +// +//////////////////////////////////////////////////////////////////// + +#ifndef PHYSXSOFTBODY_H +#define PHYSXSOFTBODY_H + +#include "pandabase.h" +#include "lvector3.h" +#include "lpoint3.h" + +#include "physxObject.h" +#include "physxObjectCollection.h" +#include "physxEnums.h" +#include "physx_includes.h" + +class PhysxScene; +class PhysxGroupsMask; +class PhysxSoftBodyNode; + +//////////////////////////////////////////////////////////////////// +// Class : PhysxSoftBody +// Description : +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAPHYSX PhysxSoftBody : public PhysxObject, public PhysxEnums { + +PUBLISHED: + INLINE PhysxSoftBody(); + INLINE ~PhysxSoftBody(); + + PhysxScene *get_scene() const; + PhysxSoftBodyNode *get_soft_body_node() const; + PhysxSoftBodyNode *create_soft_body_node(const char *name); + + void set_name(const char *name); + void set_flag(PhysxSoftBodyFlag flag, bool value); + void set_groups_mask(const PhysxGroupsMask &mask); + void set_group(unsigned int group); + void set_solver_iterations(unsigned int iterations); + void set_particle_radius(float radius); +#ifndef PHYSX281 + void set_self_collision_thickness(float thickness); + void set_hard_stretch_limitation_factor(float factor); +#endif + void set_volume_stiffness(float stiffness); + void set_stretching_stiffness(float stiffness); + void set_damping_coefficient(float coef); + void set_friction(float friction); + void set_tear_factor(float factor); + void set_attachment_tear_factor(float factor); + + const char *get_name() const; + bool get_flag(PhysxSoftBodyFlag flag) const; + PhysxGroupsMask get_groups_mask() const; + unsigned int get_group() const; + unsigned int get_num_particles(); + unsigned int get_solver_iterations() const; + float get_particle_radius() const; + float get_density() const; + float get_relative_grid_spacing() const; +#ifndef PHYSX281 + float get_self_collision_thickness() const; + float get_hard_stretch_limitation_factor() const; +#endif + float get_volume_stiffness() const; + float get_stretching_stiffness() const; + float get_damping_coefficient() const; + float get_friction() const; + float get_tear_factor() const; + float get_attachment_tear_factor() const; + +/* + // Attachment + void attach_vertex_to_global_pos(unsigned int vertexId, LPoint3f const &pos); + void free_vertex(unsigned int vertexId); + void attach_to_shape(PhysxShape *shape); + void attach_to_colliding_shapes(); + void detach_from_shape(PhysxShape *shape); + void attach_vertex_to_shape(unsigned int vertexId, PhysxShape *shape, LPoint3f const &localPos); + PhysxVertexAttachmentStatus get_vertex_attachment_status(unsigned int vertexId) const; + PhysxShape *get_vertex_attachment_shape(unsigned int vertexId) const; + LPoint3f get_vertex_attachment_pos(unsigned int vertexId) const; +*/ + + // Sleeping + bool is_sleeping() const; + void wake_up(float wakeCounterValue=NX_SLEEP_INTERVAL); + void put_to_sleep(); + void set_sleep_linear_velocity(float threshold); + float get_sleep_linear_velocity() const; + +/* + // Forces + void set_external_acceleration(LVector3f const &acceleration); + LVector3f get_external_acceleration() const; + + void set_wind_acceleration(LVector3f const &acceleration); + LVector3f get_wind_acceleration() const; + + void add_force_at_vertex(LVector3f const &force, int vertexId, + PhysxForceMode mode=FM_force); + void add_force_at_pos(LPoint3f const &pos, float magnitude, float radius, + PhysxForceMode mode=FM_force); + void add_directed_force_at_pos(LPoint3f const &pos, LVector3f const &force, float radius, + PhysxForceMode mode=FM_force); +*/ + + +/* +virtual void getWorldBounds (NxBounds3 &bounds) const =0 +virtual void attachToShape (const NxShape *shape, NxU32 attachmentFlags)=0 +virtual void attachToCollidingShapes (NxU32 attachmentFlags)=0 +virtual void detachFromShape (const NxShape *shape)=0 +virtual void attachVertexToShape (NxU32 vertexId, const NxShape *shape, const NxVec3 &localPos, NxU32 attachmentFlags)=0 +virtual void attachVertexToGlobalPosition (const NxU32 vertexId, const NxVec3 &pos)=0 +virtual void freeVertex (const NxU32 vertexId)=0 +virtual bool tearVertex (const NxU32 vertexId, const NxVec3 &normal)=0 +virtual bool raycast (const NxRay &worldRay, NxVec3 &hit, NxU32 &vertexId)=0 +virtual void setMeshData (NxMeshData &meshData)=0 +virtual NxMeshData getMeshData ()=0 +virtual void setSplitPairData (NxSoftBodySplitPairData &splitPairData)=0 +virtual NxSoftBodySplitPairData getSplitPairData ()=0 +virtual void setValidBounds (const NxBounds3 &validBounds)=0 +virtual void getValidBounds (NxBounds3 &validBounds) const =0 +virtual void setPosition (const NxVec3 &position, NxU32 vertexId)=0 +virtual void setPositions (void *buffer, NxU32 byteStride=sizeof(NxVec3))=0 +virtual NxVec3 getPosition (NxU32 vertexId) const =0 +virtual void getPositions (void *buffer, NxU32 byteStride=sizeof(NxVec3))=0 +virtual void setVelocity (const NxVec3 &velocity, NxU32 vertexId)=0 +virtual void setVelocities (void *buffer, NxU32 byteStride=sizeof(NxVec3))=0 +virtual NxVec3 getVelocity (NxU32 vertexId) const =0 +virtual void getVelocities (void *buffer, NxU32 byteStride=sizeof(NxVec3))=0 +virtual void setConstrainPositions (void *buffer, NxU32 byteStride=sizeof(NxVec3))=0 +virtual void setConstrainNormals (void *buffer, NxU32 byteStride=sizeof(NxVec3))=0 +virtual void setConstrainCoefficients (const NxSoftBodyConstrainCoefficients *coefficients, NxU32 byteStride=sizeof(NxSoftBodyConstrainCoefficients))=0 +virtual NxU32 queryShapePointers ()=0 +virtual NxU32 getStateByteSize ()=0 +virtual void getShapePointers (NxShape **shapePointers, NxU32 *flags)=0 +virtual void setShapePointers (NxShape **shapePointers, unsigned int numShapes)=0 +virtual void saveStateToStream (NxStream &stream, bool permute=false)=0 +virtual void loadStateFromStream (NxStream &stream)=0 +virtual void setCollisionResponseCoefficient (NxReal coefficient)=0 +virtual NxReal getCollisionResponseCoefficient () const =0 +virtual void setAttachmentResponseCoefficient (NxReal coefficient)=0 +virtual NxReal getAttachmentResponseCoefficient () const =0 +virtual void setFromFluidResponseCoefficient (NxReal coefficient)=0 +virtual NxReal getFromFluidResponseCoefficient () const =0 +virtual void setToFluidResponseCoefficient (NxReal coefficient)=0 +virtual NxReal getToFluidResponseCoefficient () const =0 +virtual void setExternalAcceleration (NxVec3 acceleration)=0 +virtual NxVec3 getExternalAcceleration () const =0 +virtual void setMinAdhereVelocity (NxReal velocity)=0 +virtual NxReal getMinAdhereVelocity () const =0 +virtual void addForceAtVertex (const NxVec3 &force, NxU32 vertexId, NxForceMode mode=NX_FORCE)=0 +virtual void addForceAtPos (const NxVec3 &position, NxReal magnitude, NxReal radius, NxForceMode mode=NX_FORCE)=0 +virtual void addDirectedForceAtPos (const NxVec3 &position, const NxVec3 &force, NxReal radius, NxForceMode mode=NX_FORCE)=0 +virtual bool overlapAABBTetrahedra (const NxBounds3 &bounds, NxU32 &nb, const NxU32 *&indices) const =0 +virtual NxCompartment * getCompartment () const =0 +virtual NxForceFieldMaterial getForceFieldMaterial () const =0 +virtual void setForceFieldMaterial (NxForceFieldMaterial)=0 +*/ + + INLINE void ls() const; + INLINE void ls(ostream &out, int indent_level=0) const; + +public: + void update(); + +//////////////////////////////////////////////////////////////////// +PUBLISHED: + void release(); + +public: + INLINE NxSoftBody *ptr() const { return _ptr; }; + + void link(NxSoftBody *ptr); + void unlink(); + +private: + NxSoftBody *_ptr; + PT(PhysxSoftBodyNode) _node; + string _name; + +//////////////////////////////////////////////////////////////////// +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + PhysxObject::init_type(); + register_type(_type_handle, "PhysxSoftBody", + PhysxObject::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() { + init_type(); + return get_class_type(); + } + +private: + static TypeHandle _type_handle; +}; + +#include "physxSoftBody.I" + +#endif // PHYSXSOFTBODY_H diff --git a/panda/src/physx/physxSoftBodyDesc.I b/panda/src/physx/physxSoftBodyDesc.I new file mode 100644 index 0000000000..e26d546be1 --- /dev/null +++ b/panda/src/physx/physxSoftBodyDesc.I @@ -0,0 +1,60 @@ +// Filename: physxSoftBodyDesc.I +// Created by: enn0x (12Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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." +// +//////////////////////////////////////////////////////////////////// + + + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxSoftBodyDesc:: +PhysxSoftBodyDesc() { + + set_to_default(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::Destructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxSoftBodyDesc:: +~PhysxSoftBodyDesc() { + +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_to_default +// Access: Published +// Description: (re)sets the structure to the default. +//////////////////////////////////////////////////////////////////// +INLINE void PhysxSoftBodyDesc:: +set_to_default() { + + _desc.setToDefault(); + set_name(""); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::is_valid +// Access: Published +// Description: Returns true if the descriptor is valid. +//////////////////////////////////////////////////////////////////// +INLINE bool PhysxSoftBodyDesc:: +is_valid() const { + + return _desc.isValid(); +} + diff --git a/panda/src/physx/physxSoftBodyDesc.cxx b/panda/src/physx/physxSoftBodyDesc.cxx new file mode 100644 index 0000000000..f9485e5b57 --- /dev/null +++ b/panda/src/physx/physxSoftBodyDesc.cxx @@ -0,0 +1,403 @@ +// Filename: physxSoftBodyDesc.cxx +// Created by: enn0x (12Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "physxSoftBodyDesc.h" +#include "physxSoftBodyMesh.h" +#include "physxManager.h" + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_name +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_name(const char *name) { + + _name = name ? name : ""; + _desc.name = _name.c_str(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_global_pos +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_global_pos(const LPoint3f &pos) { + + _desc.globalPose.t = PhysxManager::point3_to_nxVec3(pos); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_global_mat +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_global_mat(const LMatrix4f &mat) { + + _desc.globalPose = PhysxManager::mat4_to_nxMat34(mat); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_global_hpr +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_global_hpr(float h, float p, float r) { + + LQuaternionf q; + LMatrix3f rot; + NxMat34 m; + + q.set_hpr(LVector3f(h, p, r)); + q.extract_to_matrix(rot); + + _desc.globalPose.M = PhysxManager::mat3_to_nxMat33(rot); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_particle_radius +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_particle_radius(float radius) { + + _desc.particleRadius = radius; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_relative_grid_spacing +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_relative_grid_spacing(float spacing) { + + _desc.relativeGridSpacing = spacing; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_collision_response_coefficient +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_collision_response_coefficient(float coef) { + + _desc.collisionResponseCoefficient = coef; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_attachment_response_coefficient +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_attachment_response_coefficient(float coef) { + + _desc.attachmentResponseCoefficient = coef; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_density +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_density(float density) { + + _desc.density = density; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_volume_stiffness +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_volume_stiffness(float stiffness) { + + _desc.volumeStiffness = stiffness; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_stretching_stiffness +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_stretching_stiffness(float stiffness) { + + _desc.stretchingStiffness = stiffness; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_damping_coefficient +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_damping_coefficient(float damping) { + + _desc.dampingCoefficient = damping; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_friction +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_friction(float friction) { + + _desc.friction = friction; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_tear_factor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_tear_factor(float tearFactor) { + + _desc.tearFactor = tearFactor; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_flag +// Access: Published +// Description: Raise or lower individual SoftBodyFlag flags. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_flag(PhysxSoftBodyFlag flag, bool value) { + + if (value == true) { + _desc.flags |= flag; + } + else { + _desc.flags &= ~(flag); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_solver_iterations +// Access: Published +// Description: Number of solver iterations. +// Small numbers make the simulation faster while +// the soft body gets less stiff. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_solver_iterations(unsigned int iterations) { + + _desc.solverIterations = iterations; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::set_soft_body_mesh +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +set_soft_body_mesh(PhysxSoftBodyMesh *mesh) { + + _desc.softBodyMesh = mesh->ptr(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_name +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +const char *PhysxSoftBodyDesc:: +get_name() const { + + return _desc.name; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_global_pos +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +LPoint3f PhysxSoftBodyDesc:: +get_global_pos() const { + + return PhysxManager::nxVec3_to_point3(_desc.globalPose.t); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_global_mat +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +LMatrix4f PhysxSoftBodyDesc:: +get_global_mat() const { + + return PhysxManager::nxMat34_to_mat4(_desc.globalPose); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_particle_radius +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxSoftBodyDesc:: +get_particle_radius() const { + + return _desc.particleRadius; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_relative_grid_spacing +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxSoftBodyDesc:: +get_relative_grid_spacing() const { + + return _desc.relativeGridSpacing; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_collision_response_coefficient +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxSoftBodyDesc:: +get_collision_response_coefficient() const { + + return _desc.collisionResponseCoefficient; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_attachment_response_coefficient +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxSoftBodyDesc:: +get_attachment_response_coefficient() const { + + return _desc.attachmentResponseCoefficient; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_density +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxSoftBodyDesc:: +get_density() const { + + return _desc.density; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_volume_stiffness +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxSoftBodyDesc:: +get_volume_stiffness() const { + + return _desc.volumeStiffness; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_stretching_stiffness +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxSoftBodyDesc:: +get_stretching_stiffness() const { + + return _desc.stretchingStiffness; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_damping_coefficient +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxSoftBodyDesc:: +get_damping_coefficient() const { + + return _desc.dampingCoefficient; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_friction +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxSoftBodyDesc:: +get_friction() const { + + return _desc.friction; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_tear_factor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxSoftBodyDesc:: +get_tear_factor() const { + + return _desc.tearFactor; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_flag +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +bool PhysxSoftBodyDesc:: +get_flag(PhysxSoftBodyFlag flag) const { + + return (_desc.flags & flag) ? true : false; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_solver_iterations +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +unsigned int PhysxSoftBodyDesc:: +get_solver_iterations() const { + + return _desc.solverIterations; +} + +/* +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyDesc::get_mesh_numbers +// Access: Public +// Description: Used by PhysScene to query the sizes of arrays +// to allocate for the user buffers in PhysxSoftBodyNode. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyDesc:: +get_mesh_numbers(NxU32 &numVertices, NxU32 &numTriangles) { + + NxSoftBodyMeshDesc meshDesc; + _desc.clothMesh->saveToDesc(meshDesc); + + numVertices = meshDesc.numVertices; + numTriangles = meshDesc.numTriangles; +} +*/ + diff --git a/panda/src/physx/physxSoftBodyDesc.h b/panda/src/physx/physxSoftBodyDesc.h new file mode 100644 index 0000000000..f86cd9d46e --- /dev/null +++ b/panda/src/physx/physxSoftBodyDesc.h @@ -0,0 +1,84 @@ +// Filename: physxSoftBodyDesc.h +// Created by: enn0x (12Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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." +// +//////////////////////////////////////////////////////////////////// + +#ifndef PHYSXSOFTBODYDESC_H +#define PHYSXSOFTBODYDESC_H + +#include "pandabase.h" +#include "lpoint3.h" +#include "lmatrix.h" + +#include "physxEnums.h" +#include "physx_includes.h" + +class PhysxSoftBodyMesh; + +//////////////////////////////////////////////////////////////////// +// Class : PhysxSoftBodyDesc +// Description : Descriptor for PhysxSoftBody. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAPHYSX PhysxSoftBodyDesc : public PhysxEnums { + +PUBLISHED: + INLINE PhysxSoftBodyDesc(); + INLINE ~PhysxSoftBodyDesc(); + + INLINE void set_to_default(); + INLINE bool is_valid() const; + + void set_soft_body_mesh(PhysxSoftBodyMesh *mesh); + + void set_name(const char *name); + void set_global_pos(const LPoint3f &pos); + void set_global_mat(const LMatrix4f &mat); + void set_global_hpr(float h, float p, float r); + void set_density(float density); + void set_volume_stiffness(float stiffness); + void set_stretching_stiffness(float stiffness); + void set_damping_coefficient(float damping); + void set_friction(float friction); + void set_tear_factor(float tearFactor); + void set_particle_radius(float radius); + void set_relative_grid_spacing(float spacing); + void set_collision_response_coefficient(float coef); + void set_attachment_response_coefficient(float coef); + void set_solver_iterations(unsigned int interations); + void set_flag(PhysxSoftBodyFlag flag, bool value); + + const char *get_name() const; + LPoint3f get_global_pos() const; + LMatrix4f get_global_mat() const; + float get_density() const; + float get_volume_stiffness() const; + float get_stretching_stiffness() const; + float get_damping_coefficient() const; + float get_friction() const; + float get_tear_factor() const; + float get_particle_radius() const; + float get_relative_grid_spacing() const; + float get_collision_response_coefficient() const; + float get_attachment_response_coefficient() const; + unsigned int get_solver_iterations() const; + bool get_flag(PhysxSoftBodyFlag flag) const; + +public: + NxSoftBodyDesc _desc; + +private: + string _name; +}; + +#include "physxSoftBodyDesc.I" + +#endif // PHYSXSOFTBODYDESC_H diff --git a/panda/src/physx/physxSoftBodyMesh.I b/panda/src/physx/physxSoftBodyMesh.I new file mode 100644 index 0000000000..302d1dec15 --- /dev/null +++ b/panda/src/physx/physxSoftBodyMesh.I @@ -0,0 +1,59 @@ +// Filename: physxSoftBodyMesh.I +// Created by: enn0x (12Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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." +// +//////////////////////////////////////////////////////////////////// + + + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMesh::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxSoftBodyMesh:: +PhysxSoftBodyMesh() : PhysxObject() { + +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMesh::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxSoftBodyMesh:: +~PhysxSoftBodyMesh() { + +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMesh::ls +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void PhysxSoftBodyMesh:: +ls() const { + + ls(nout); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMesh::ls +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void PhysxSoftBodyMesh:: +ls(ostream &out, int indent_level) const { + + indent(out, indent_level) << get_type().get_name() + << " (at 0x" << this << ")\n"; +} + diff --git a/panda/src/physx/physxSoftBodyMesh.cxx b/panda/src/physx/physxSoftBodyMesh.cxx new file mode 100644 index 0000000000..fbdb5c05d5 --- /dev/null +++ b/panda/src/physx/physxSoftBodyMesh.cxx @@ -0,0 +1,76 @@ +// Filename: physxSoftBodyMesh.cxx +// Created by: enn0x (12Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "physxSoftBodyMesh.h" +#include "physxMeshPool.h" + +TypeHandle PhysxSoftBodyMesh::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMesh::link +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyMesh:: +link(NxSoftBodyMesh *meshPtr) { + + // Link self + PhysxManager::get_global_ptr()->_softbody_meshes.add(this); + _ptr = meshPtr; + _error_type = ET_ok; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMesh::unlink +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyMesh:: +unlink() { + + // Unlink self + _error_type = ET_released; + PhysxManager::get_global_ptr()->_softbody_meshes.remove(this); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMesh::release +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyMesh:: +release() { + + nassertv(_error_type == ET_ok); + + unlink(); + NxGetPhysicsSDK()->releaseSoftBodyMesh(*_ptr); + _ptr = NULL; + + PhysxMeshPool::release_soft_body_mesh(this); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMesh::get_reference_count +// Access: Published +// Description: Returns the reference count for shared meshes. +//////////////////////////////////////////////////////////////////// +unsigned int PhysxSoftBodyMesh:: +get_reference_count() const { + + nassertr(_error_type == ET_ok, 0); + + return _ptr->getReferenceCount(); +} + diff --git a/panda/src/physx/physxSoftBodyMesh.h b/panda/src/physx/physxSoftBodyMesh.h new file mode 100644 index 0000000000..93d01c92d4 --- /dev/null +++ b/panda/src/physx/physxSoftBodyMesh.h @@ -0,0 +1,75 @@ +// Filename: physxSoftBodyMesh.h +// Created by: enn0x (12Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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." +// +//////////////////////////////////////////////////////////////////// + +#ifndef PHYSXSOFTBODYMESH_H +#define PHYSXSOFTBODYMESH_H + +#include "pandabase.h" + +#include "physxObject.h" +#include "physx_includes.h" + +//////////////////////////////////////////////////////////////////// +// Class : PhysxSoftBodyMesh +// Description : +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAPHYSX PhysxSoftBodyMesh : public PhysxObject { + +PUBLISHED: + unsigned int get_reference_count() const; + +//////////////////////////////////////////////////////////////////// +PUBLISHED: + void release(); + + INLINE void ls() const; + INLINE void ls(ostream &out, int indent_level=0) const; + +public: + INLINE PhysxSoftBodyMesh(); + INLINE ~PhysxSoftBodyMesh(); + + INLINE NxSoftBodyMesh *ptr() const { return _ptr; }; + + void link(NxSoftBodyMesh *meshPtr); + void unlink(); + +private: + NxSoftBodyMesh *_ptr; + +//////////////////////////////////////////////////////////////////// +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + PhysxObject::init_type(); + register_type(_type_handle, "PhysxSoftBodyMesh", + PhysxObject::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() { + init_type(); + return get_class_type(); + } + +private: + static TypeHandle _type_handle; +}; + +#include "physxSoftBodyMesh.I" + +#endif // PHYSXSOFTBODYMESH_H diff --git a/panda/src/physx/physxSoftBodyMeshDesc.I b/panda/src/physx/physxSoftBodyMeshDesc.I new file mode 100644 index 0000000000..ee96ad5121 --- /dev/null +++ b/panda/src/physx/physxSoftBodyMeshDesc.I @@ -0,0 +1,72 @@ +// Filename: physxSoftBodyMeshDesc.I +// Created by: enn0x (12Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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." +// +//////////////////////////////////////////////////////////////////// + + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMeshDesc::Constructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxSoftBodyMeshDesc:: +PhysxSoftBodyMeshDesc() { + + _desc.flags = 0; + _desc.vertexStrideBytes = sizeof(NxVec3); + _desc.tetrahedronStrideBytes = 4*sizeof(NxU32); + _desc.vertices = NULL; + _desc.tetrahedra = NULL; + + _vertices = NULL; + _tetrahedra = NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMeshDesc::Destructor +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxSoftBodyMeshDesc:: +~PhysxSoftBodyMeshDesc() { + + if (_vertices) { + delete [] _vertices; + } + + if (_tetrahedra) { + delete [] _tetrahedra; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMeshDesc::is_valid +// Access: Published +// Description: Returns true if the descriptor is valid. +//////////////////////////////////////////////////////////////////// +INLINE bool PhysxSoftBodyMeshDesc:: +is_valid() const { + + return _desc.isValid(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMeshDesc::get_desc +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE const NxSoftBodyMeshDesc &PhysxSoftBodyMeshDesc:: +get_desc() const { + + return _desc; +} + diff --git a/panda/src/physx/physxSoftBodyMeshDesc.cxx b/panda/src/physx/physxSoftBodyMeshDesc.cxx new file mode 100644 index 0000000000..f82ca09b00 --- /dev/null +++ b/panda/src/physx/physxSoftBodyMeshDesc.cxx @@ -0,0 +1,96 @@ +// Filename: physxSoftBodyMeshDesc.cxx +// Created by: enn0x (12Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "physxSoftBodyMeshDesc.h" +#include "physxManager.h" + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMeshDesc::set_num_vertices +// Access: Published +// Description: Sets the number of vertices to be stored within +// this soft body mesh. The function allocates memory +// for the vertices, but it does not set any vertices. +// +// This method must be called before any calls to +// set_vertex are done! +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyMeshDesc:: +set_num_vertices(unsigned int numVertices) { + + // Vertices + if (_desc.vertices) { + delete [] _vertices; + } + + _vertices = new NxVec3[numVertices]; + + _desc.numVertices = numVertices; + _desc.vertices = _vertices; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMeshDesc::set_vertex +// Access: Published +// Description: Sets a single vertex. You have to call the function +// set_num_vertices before you can call this function. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyMeshDesc:: +set_vertex(unsigned int idx, const LPoint3f &vert) { + + nassertv(_desc.numVertices > idx); + + _vertices[idx] = PhysxManager::point3_to_nxVec3(vert); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMeshDesc::set_num_tetrahedra +// Access: Published +// Description: Sets the number of tetrahedra to be stored in this +// soft body mesh. +// +// This method must be called before any calls to +// set_tetrahedron are done! +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyMeshDesc:: +set_num_tetrahedra(unsigned int numTetrahedra) { + + if (_desc.tetrahedra) { + delete [] _tetrahedra; + } + + _tetrahedra = new NxU32[4 * numTetrahedra]; + + _desc.numTetrahedra = numTetrahedra; + _desc.tetrahedra = _tetrahedra; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyMeshDesc::set_tetrahedron +// Access: Published +// Description: Sets a single tetrahedron, by providing the three +// indices i1, i2, i3, i4. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyMeshDesc:: +set_tetrahedron(unsigned int idx, + unsigned int i1, unsigned int i2, unsigned int i3, unsigned int i4) { + + nassertv(_desc.numTetrahedra > idx); + + idx = 4 * idx; + _tetrahedra[idx] = i1; + _tetrahedra[idx + 1] = i2; + _tetrahedra[idx + 2] = i3; + _tetrahedra[idx + 3] = i4; +} + diff --git a/panda/src/physx/physxSoftBodyMeshDesc.h b/panda/src/physx/physxSoftBodyMeshDesc.h new file mode 100644 index 0000000000..db59dcecdf --- /dev/null +++ b/panda/src/physx/physxSoftBodyMeshDesc.h @@ -0,0 +1,57 @@ +// Filename: physxSoftBodyMeshDesc.h +// Created by: enn0x (12Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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." +// +//////////////////////////////////////////////////////////////////// + +#ifndef PHYSXSOFTBODYMESHDESC_H +#define PHYSXSOFTBODYMESHDESC_H + +#include "pandabase.h" +#include "lpoint3.h" + +#include "physx_includes.h" + +//////////////////////////////////////////////////////////////////// +// Class : PhysxSoftBodyMeshDesc +// Description : +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAPHYSX PhysxSoftBodyMeshDesc { + +PUBLISHED: + INLINE PhysxSoftBodyMeshDesc(); + INLINE ~PhysxSoftBodyMeshDesc(); + + INLINE bool is_valid() const; + + void set_num_vertices(unsigned int n); + void set_vertex(unsigned int idx, + const LPoint3f &vert); + + void set_num_tetrahedra(unsigned int n); + void set_tetrahedron(unsigned int idx, + unsigned int i1, + unsigned int i2, + unsigned int i3, + unsigned int i4); + +public: + INLINE const NxSoftBodyMeshDesc &get_desc() const; + +private: + NxSoftBodyMeshDesc _desc; + NxVec3 *_vertices; + NxU32 *_tetrahedra; +}; + +#include "physxSoftBodyMeshDesc.I" + +#endif // PHYSXSOFTBODYMESHDESC_H diff --git a/panda/src/physx/physxSoftBodyNode.I b/panda/src/physx/physxSoftBodyNode.I new file mode 100644 index 0000000000..3f0c65e66b --- /dev/null +++ b/panda/src/physx/physxSoftBodyNode.I @@ -0,0 +1,45 @@ +// Filename: physxSoftBodyNode.I +// Created by: enn0x (13Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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." +// +//////////////////////////////////////////////////////////////////// + + + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyNode::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxSoftBodyNode:: +PhysxSoftBodyNode(const char *name) : GeomNode(name) { + + _vdata = new GeomVertexData("", GeomVertexFormat::get_v3n3t2(), Geom::UH_stream); + + _prim = new GeomTriangles(Geom::UH_stream); + _prim->set_shade_model(Geom::SM_uniform); + + _geom = new Geom(_vdata); + _geom->add_primitive(_prim); + + this->add_geom(_geom); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyNode::Destructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxSoftBodyNode:: +~PhysxSoftBodyNode() { + +} + diff --git a/panda/src/physx/physxSoftBodyNode.cxx b/panda/src/physx/physxSoftBodyNode.cxx new file mode 100644 index 0000000000..fb8a132e71 --- /dev/null +++ b/panda/src/physx/physxSoftBodyNode.cxx @@ -0,0 +1,414 @@ +// Filename: physxSoftBodyNode.cxx +// Created by: enn0x (13Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "physxSoftBodyNode.h" +#include "physxSoftBody.h" +#include "physxFileStream.h" +#include "physxManager.h" +#include "physxMeshHash.h" + +#include "geomVertexFormat.h" +#include "geomVertexWriter.h" +#include "geomVertexRewriter.h" + +TypeHandle PhysxSoftBodyNode::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyNode::allocate +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyNode:: +allocate(PhysxSoftBody *softbody) { + + _softbody = softbody; + + // Retrieve number of vertices and triangles the hard way + NxSoftBodyMeshDesc meshDesc; + _softbody->ptr()->getSoftBodyMesh()->saveToDesc(meshDesc); + + NxU32 numVertices = meshDesc.numVertices; + NxU32 numTetrahedra = meshDesc.numTetrahedra; + + float factor = 1.0f; // TODO max(1.0f, factor); + + // Reserve more memory for vertices than the initial mesh takes because + // tearing creates new vertices + NxU32 maxVertices = factor * numVertices; + _mesh.verticesPosBegin = (NxVec3 *)malloc(sizeof(NxVec3) * maxVertices); + _mesh.verticesPosByteStride = sizeof(NxVec3); + _mesh.maxVertices = maxVertices; + _mesh.numVerticesPtr = (NxU32 *)malloc(sizeof(NxU32)); + + // The number of tetrahedra is constant, even if the softbody is torn + NxU32 maxIndices = 4 * numTetrahedra; + _mesh.indicesBegin = (NxU32 *)malloc(sizeof(NxU32) * maxIndices); + _mesh.indicesByteStride = sizeof(NxU32); + _mesh.maxIndices = maxIndices; + _mesh.numIndicesPtr = (NxU32 *)malloc(sizeof(NxU32)); + + *(_mesh.numVerticesPtr) = 0; + *(_mesh.numIndicesPtr) = 0; + + _softbody->ptr()->setMeshData(_mesh); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyNode::set_from_geom +// Access: Published +// Description: Reads the vertices and indices from an existing +// Geom and makes a decomposed copy of the data. +// Then computes links between the owning soft body +// tetrahedron mesh in order to render an updated +// geometry every simulation frame. +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyNode:: +set_from_geom(const Geom *geom) { + + _prim->clear_vertices(); + + GeomVertexWriter vwriter = GeomVertexWriter(_vdata, InternalName::get_vertex()); + GeomVertexWriter nwriter = GeomVertexWriter(_vdata, InternalName::get_normal()); + GeomVertexWriter twriter = GeomVertexWriter(_vdata, InternalName::get_texcoord()); + + CPT(GeomVertexData) vdata = geom->get_vertex_data(); + GeomVertexReader vreader = GeomVertexReader(vdata, InternalName::get_vertex()); + GeomVertexReader nreader = GeomVertexReader(vdata, InternalName::get_normal()); + GeomVertexReader treader = GeomVertexReader(vdata, InternalName::get_texcoord()); + + while (!vreader.is_at_end()) { + LVecBase3f v = vreader.get_data3f(); + vwriter.add_data3f(v.get_x(), v.get_y(), v.get_z()); + } + + while (!nreader.is_at_end()) { + LVecBase3f n = nreader.get_data3f(); + nwriter.add_data3f(n.get_x(), n.get_y(), n.get_z()); + } + + while (!treader.is_at_end()) { + LVecBase2f t = treader.get_data2f(); + twriter.add_data2f(t.get_x(), t.get_y()); + } + + for (int i=0; iget_num_primitives(); i++) { + + CPT(GeomPrimitive) prim = geom->get_primitive(i); + prim = prim->decompose(); + + for (int j=0; jget_num_primitives(); j++) { + + int s = prim->get_primitive_start(j); + int e = prim->get_primitive_end(j); + + for (int l=s; ladd_vertex(prim->get_vertex(l)); + } + } + } + + _prim->close_primitive(); + + update_bounds(); + build_tetra_links(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyNode::build_tetra_links +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyNode:: +build_tetra_links() { + + NxSoftBodyMeshDesc meshDesc; + _softbody->ptr()->getSoftBodyMesh()->saveToDesc(meshDesc); + const NxVec3 *vertices = (const NxVec3 *) meshDesc.vertices; + const NxU32 *indices = (const NxU32 *) meshDesc.tetrahedra; + const NxU32 numTets = meshDesc.numTetrahedra; + + _tetraLinks.clear(); + + PhysxMeshHash* hash = new PhysxMeshHash(); + hash->set_grid_spacing(_bounds.min.distance(_bounds.max) * 0.1f); + + for (NxU32 i=0; iadd(tetraBounds, i); + } + + GeomVertexReader vreader = GeomVertexReader(_vdata, InternalName::get_vertex()); + + while (!vreader.is_at_end()) { + + // Prepare datastructure for drained tetras + _drainedTriVertices.push_back(false); + + TetraLink tmpLink; + + LVecBase3f v = vreader.get_data3f(); + NxVec3 triVert = PhysxManager::vec3_to_nxVec3(v); + pvector itemIndices; + hash->query_unique(triVert, itemIndices); + + NxReal minDist = 0.0f; + NxVec3 b; + int num, isize; + num = isize = itemIndices.size(); + if (num == 0) { + num = numTets; + } + + for (int i=0; i 0) { + j = itemIndices[i]; + } + + const NxU32 *ix = &indices[j*4]; + const NxVec3 &p0 = vertices[*ix++]; + const NxVec3 &p1 = vertices[*ix++]; + const NxVec3 &p2 = vertices[*ix++]; + const NxVec3 &p3 = vertices[*ix++]; + + NxVec3 b = compute_bary_coords(triVert, p0, p1, p2, p3); + + // Is the vertex inside the tetrahedron? If yes we take it + if (b.x >= 0.0f && b.y >= 0.0f && b.z >= 0.0f && (b.x + b.y + b.z) <= 1.0f) { + tmpLink.barycentricCoords = b; + tmpLink.tetraNr = j; + break; + } + + // Otherwise, if we are not in any tetrahedron we take the closest one + NxReal dist = 0.0f; + if (b.x + b.y + b.z > 1.0f) dist = b.x + b.y + b.z - 1.0f; + if (b.x < 0.0f) dist = (-b.x < dist) ? dist : -b.x; + if (b.y < 0.0f) dist = (-b.y < dist) ? dist : -b.y; + if (b.z < 0.0f) dist = (-b.z < dist) ? dist : -b.z; + + if (i == 0 || dist < minDist) { + minDist = dist; + tmpLink.barycentricCoords = b; + tmpLink.tetraNr = j; + } + } + + _tetraLinks.push_back(tmpLink); + } + + delete hash; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyNode::remove_tris_related_to_vertex +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyNode:: +remove_tris_related_to_vertex(const int vertexIndex) { + + GeomVertexRewriter vrewriter = GeomVertexRewriter(_vdata, InternalName::get_vertex()); + LVecBase3f v; + + for (int j=0; j<_prim->get_num_primitives(); j++) { + + int s = _prim->get_primitive_start(j); + int idx0 = _prim->get_vertex(s); + int idx1 = _prim->get_vertex(s+1); + int idx2 = _prim->get_vertex(s+2); + + if (vertexIndex == idx0 || vertexIndex == idx1 || vertexIndex == idx2) { + + // Make this triangle degenerated + vrewriter.set_row(idx0); v = vrewriter.get_data3f(); + vrewriter.set_row(idx1); vrewriter.set_data3f(v.get_x(), v.get_y(), v.get_z()); + vrewriter.set_row(idx2); vrewriter.set_data3f(v.get_x(), v.get_y(), v.get_z()); + } + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyNode::update_bounds +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyNode:: +update_bounds() { + + _bounds.setEmpty(); + + GeomVertexReader vreader = GeomVertexReader(_vdata, InternalName::get_vertex()); + + while (!vreader.is_at_end()) { + LVecBase3f v = vreader.get_data3f(); + _bounds.include(PhysxManager::vec3_to_nxVec3(v)); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyNode::update_normals +// Access: Public +// Description:_bounds.include(mVertices[i]); +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyNode:: +update_normals() { + + _normals.resize(_vdata->get_num_rows()); + + int i; + for (i=0; i<(int)_normals.size(); i++) { + _normals[i] = LVector3f::zero(); + } + + LVecBase3f n, v0, v1, v2; + GeomVertexReader vreader = GeomVertexReader(_vdata, InternalName::get_vertex()); + + for (int j=0; j<_prim->get_num_primitives(); j++) { + + int s = _prim->get_primitive_start(j); + int idx0 = _prim->get_vertex(s); + int idx1 = _prim->get_vertex(s+1); + int idx2 = _prim->get_vertex(s+2); + + vreader.set_row(idx0); v0 = vreader.get_data3f(); + vreader.set_row(idx1); v1 = vreader.get_data3f(); + vreader.set_row(idx2); v2 = vreader.get_data3f(); + + n = (v1 - v0).cross(v2 - v0); + + _normals[idx0] += n; + _normals[idx1] += n; + _normals[idx2] += n; + } + + for (i=0; i<(int)_normals.size(); i++) { + _normals[i].normalize(); + } + + GeomVertexWriter nwriter = GeomVertexWriter(_vdata, InternalName::get_normal()); + for (i=0; i<(int)_normals.size(); i++) { + n = _normals[i]; + nwriter.add_data3f(n.get_x(), n.get_y(), n.get_z()); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyNode::compute_bary_coords +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +NxVec3 PhysxSoftBodyNode:: +compute_bary_coords(NxVec3 vertex, NxVec3 p0, NxVec3 p1, NxVec3 p2, NxVec3 p3) const { + + NxVec3 baryCoords; + + NxVec3 q = vertex - p3; + NxVec3 q0 = p0 - p3; + NxVec3 q1 = p1 - p3; + NxVec3 q2 = p2 - p3; + + NxMat33 m; + m.setColumn(0, q0); + m.setColumn(1, q1); + m.setColumn(2, q2); + + NxReal det = m.determinant(); + + m.setColumn(0, q); + baryCoords.x = m.determinant(); + + m.setColumn(0, q0); + m.setColumn(1, q); + baryCoords.y = m.determinant(); + + m.setColumn(1, q1); + m.setColumn(2,q); + baryCoords.z = m.determinant(); + + if (det != 0.0f) { + baryCoords /= det; + } + + return baryCoords; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyNode::update +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxSoftBodyNode:: +update() { + + update_tetra_links(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxSoftBodyNode::update_tetra_links +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +bool PhysxSoftBodyNode:: +update_tetra_links() { + + if (_tetraLinks.size() != _vdata->get_num_rows()) + { + return false; + } + + NxU32 numVertices = *_mesh.numVerticesPtr; + NxU32 numTetrahedra = *_mesh.numIndicesPtr / 4; + const NxVec3 *vertices = (NxVec3*)_mesh.verticesPosBegin; + NxU32* indices = (NxU32*)_mesh.indicesBegin; + + GeomVertexRewriter vwriter = GeomVertexRewriter(_vdata, InternalName::get_vertex()); + + int i = 0; + while (!vwriter.is_at_end()) { + + TetraLink &link = _tetraLinks[i]; + + if (!_drainedTriVertices[i]) { + const NxU32 *ix = &indices[4*link.tetraNr]; + + if (*ix == *(ix + 1)) { + remove_tris_related_to_vertex(i); + _drainedTriVertices[i] = true; + continue; + } + + const NxVec3 &p0 = vertices[*ix++]; + const NxVec3 &p1 = vertices[*ix++]; + const NxVec3 &p2 = vertices[*ix++]; + const NxVec3 &p3 = vertices[*ix++]; + + NxVec3 &b = link.barycentricCoords; + NxVec3 tmp = p0 * b.x + p1 * b.y + p2 * b.z + p3 * (1.0f - b.x - b.y - b.z); + vwriter.set_data3f(tmp.x, tmp.y, tmp.z); + } + i++; + } + + update_normals(); + + return true; +} + diff --git a/panda/src/physx/physxSoftBodyNode.h b/panda/src/physx/physxSoftBodyNode.h new file mode 100644 index 0000000000..f5af8723c1 --- /dev/null +++ b/panda/src/physx/physxSoftBodyNode.h @@ -0,0 +1,99 @@ +// Filename: physxSoftBodyNode.h +// Created by: enn0x (13Sep10) +// +//////////////////////////////////////////////////////////////////// +// +// 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." +// +//////////////////////////////////////////////////////////////////// + +#ifndef PHYSXSOFTBODYNODE_H +#define PHYSXSOFTBODYNODE_H + +#include "pandabase.h" +#include "pointerTo.h" +#include "geomNode.h" +#include "transformState.h" +#include "geom.h" +#include "geomVertexData.h" +#include "geomTriangles.h" +#include "filename.h" + +#include "physx_includes.h" + +class PhysxSoftBody; + +//////////////////////////////////////////////////////////////////// +// Class : PhysxSoftBodyNode +// Description : Renderable geometry which represents a soft body +// mesh. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAPHYSX PhysxSoftBodyNode : public GeomNode { + +PUBLISHED: + INLINE PhysxSoftBodyNode(const char *name); + INLINE ~PhysxSoftBodyNode(); + + void set_from_geom(const Geom *geom); + +public: + void allocate(PhysxSoftBody *cloth); + void update(); + +private: + + struct TetraLink { + int tetraNr; + NxVec3 barycentricCoords; + }; + + void update_bounds(); + void build_tetra_links(); + bool update_tetra_links(); + void update_normals(); + void remove_tris_related_to_vertex(const int vertexIndex); + NxVec3 compute_bary_coords(NxVec3 vertex, NxVec3 p0, NxVec3 p1, NxVec3 p2, NxVec3 p3) const; + + pvector _tetraLinks; + pvector _drainedTriVertices; + pvector _normals; + + NxBounds3 _bounds; + NxMeshData _mesh; + + PT(GeomVertexData) _vdata; + PT(Geom) _geom; + PT(GeomTriangles) _prim; + + PT(PhysxSoftBody) _softbody; + +//////////////////////////////////////////////////////////////////// +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + GeomNode::init_type(); + register_type(_type_handle, "PhysxSoftBodyNode", + GeomNode::get_class_type()); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() { + init_type(); + return get_class_type(); + } + +private: + static TypeHandle _type_handle; +}; + +#include "physxSoftBodyNode.I" + +#endif // PHYSXSOFTBODYNODE_H diff --git a/panda/src/physx/physxVehicle.h b/panda/src/physx/physxVehicle.h index 2dc08dbf67..160f94660f 100644 --- a/panda/src/physx/physxVehicle.h +++ b/panda/src/physx/physxVehicle.h @@ -23,6 +23,7 @@ class PhysxActor; class PhysxWheel; +class PhysxVehicleDesc; class PhysxScene; //////////////////////////////////////////////////////////////////// diff --git a/panda/src/physx/physxWheelShape.h b/panda/src/physx/physxWheelShape.h index c1d9618fcc..313648e01e 100644 --- a/panda/src/physx/physxWheelShape.h +++ b/panda/src/physx/physxWheelShape.h @@ -21,6 +21,7 @@ #include "physx_includes.h" class PhysxWheelShapeDesc; +class PhysxSpringDesc; //////////////////////////////////////////////////////////////////// // Class : PhysxWheelShape diff --git a/panda/src/physx/physx_composite.cxx b/panda/src/physx/physx_composite.cxx index e2a4d92803..8eb94d9972 100644 --- a/panda/src/physx/physx_composite.cxx +++ b/panda/src/physx/physx_composite.cxx @@ -70,6 +70,7 @@ #include "physxMaterialDesc.cxx" #include "physxMemoryReadBuffer.cxx" #include "physxMemoryWriteBuffer.cxx" +#include "physxMeshHash.cxx" #include "physxMeshPool.cxx" #include "physxMotorDesc.cxx" #include "physxObject.cxx" @@ -97,6 +98,11 @@ #include "physxSegment.cxx" #include "physxShape.cxx" #include "physxShapeDesc.cxx" +#include "physxSoftBody.cxx" +#include "physxSoftBodyDesc.cxx" +#include "physxSoftBodyMesh.cxx" +#include "physxSoftBodyMeshDesc.cxx" +#include "physxSoftBodyNode.cxx" #include "physxSphere.cxx" #include "physxSphereForceFieldShape.cxx" #include "physxSphereForceFieldShapeDesc.cxx" diff --git a/panda/src/physx/physx_includes.h b/panda/src/physx/physx_includes.h index a7fb072502..f7337e426b 100644 --- a/panda/src/physx/physx_includes.h +++ b/panda/src/physx/physx_includes.h @@ -18,8 +18,12 @@ // Platform-specific defines #ifdef WIN32 +#if _WIN64 || __amd64__ +#define NX64 1 +#else #define NX32 1 #endif +#endif #ifdef IS_LINUX #define LINUX 1 @@ -30,6 +34,7 @@ #endif #define CORELIB 1 #define NX_DISABLE_FLUIDS 1 +#define NX_DISABLE_HARDWARE 1 #endif #ifdef IS_FREEBSD