diff --git a/panda/src/physx/config_physx.cxx b/panda/src/physx/config_physx.cxx index 072145ca42..d25990723f 100644 --- a/panda/src/physx/config_physx.cxx +++ b/panda/src/physx/config_physx.cxx @@ -22,7 +22,9 @@ #include "physxCapsuleController.h" #include "physxCapsuleForceFieldShape.h" #include "physxCapsuleShape.h" +#include "physxCloth.h" #include "physxClothMesh.h" +#include "physxClothNode.h" #include "physxContactPair.h" #include "physxContactPoint.h" #include "physxController.h" @@ -118,7 +120,9 @@ init_libphysx() { PhysxCapsuleController::init_type(); PhysxCapsuleForceFieldShape::init_type(); PhysxCapsuleShape::init_type(); + PhysxCloth::init_type(); PhysxClothMesh::init_type(); + PhysxClothNode::init_type(); PhysxContactPair::init_type(); PhysxContactPoint::init_type(); PhysxController::init_type(); diff --git a/panda/src/physx/physxCloth.I b/panda/src/physx/physxCloth.I new file mode 100644 index 0000000000..bb783f2226 --- /dev/null +++ b/panda/src/physx/physxCloth.I @@ -0,0 +1,61 @@ +// Filename: physxCloth.I +// Created by: enn0x (30Mar10) +// +//////////////////////////////////////////////////////////////////// +// +// 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: PhysxCloth::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxCloth:: +PhysxCloth() : PhysxObject() { + +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::Destructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxCloth:: +~PhysxCloth() { + +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::ls +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void PhysxCloth:: +ls() const { + + ls(nout); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::ls +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE void PhysxCloth:: +ls(ostream &out, int indent_level) const { + + indent(out, indent_level) << get_type().get_name() + << " (at 0x" << this << ")"; + //out << " N:0x" << _node; + out << "\n"; +} + diff --git a/panda/src/physx/physxCloth.cxx b/panda/src/physx/physxCloth.cxx new file mode 100644 index 0000000000..37256ff662 --- /dev/null +++ b/panda/src/physx/physxCloth.cxx @@ -0,0 +1,669 @@ +// Filename: physxCloth.cxx +// Created by: enn0x (30Mar10) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "physxCloth.h" +#include "physxClothDesc.h" +#include "physxScene.h" +#include "physxGroupsMask.h" +#include "physxShape.h" +#include "physxManager.h" + +#include "boundingBox.h" + +TypeHandle PhysxCloth::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::link +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxCloth:: +link(NxCloth *ptr) { + + // Link self + _ptr = ptr; + _error_type = ET_ok; + _ptr->userData = this; + + PhysxScene *scene = (PhysxScene *)_ptr->getScene().userData; + scene->_cloths.add(this); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::unlink +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxCloth:: +unlink() { + + // Unlink self + _ptr->userData = NULL; + _error_type = ET_released; + + PhysxScene *scene = (PhysxScene *)_ptr->getScene().userData; + scene->_cloths.remove(this); + + _node = NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::release +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxCloth:: +release() { + + nassertv(_error_type == ET_ok); + + unlink(); + _ptr->getScene().releaseCloth(*_ptr); + _ptr = NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::update +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxCloth:: +update() { + + // 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: PhysxCloth::get_scene +// Access: Published +// Description: Returns the scene which this cloth belongs to. +//////////////////////////////////////////////////////////////////// +PhysxScene *PhysxCloth:: +get_scene() const { + + nassertr(_error_type == ET_ok, NULL); + return (PhysxScene *)_ptr->getScene().userData; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::get_cloth_node +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +PhysxClothNode *PhysxCloth:: +get_cloth_node() const { + + nassertr(_error_type == ET_ok, NULL); + return _node; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::create_cloth_node +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +PhysxClothNode *PhysxCloth:: +create_cloth_node(const char *name) { + + nassertr(_error_type == ET_ok, NULL); + + _node = new PhysxClothNode(name); + _node->allocate(this); + + return _node; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::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 PhysxCloth:: +set_name(const char *name) { + + nassertv(_error_type == ET_ok); + _ptr->setName(name); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::get_name +// Access: Published +// Description: Retrieves the name string. +//////////////////////////////////////////////////////////////////// +const char *PhysxCloth:: +get_name() const { + + nassertr(_error_type == ET_ok, ""); + return _ptr->getName(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::set_group +// Access: Published +// Description: Sets which collision group this cloth is part of. +// Collision group must be between 0 and 31. +//////////////////////////////////////////////////////////////////// +void PhysxCloth:: +set_group(unsigned int group) { + + nassertv(_error_type == ET_ok); + nassertv(group >= 0 && group < 32); + _ptr->setGroup(group); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::get_group +// Access: Published +// Description: Retrieves the collision group this cloth is part +// of. +//////////////////////////////////////////////////////////////////// +unsigned int PhysxCloth:: +get_group() const { + + nassertr(_error_type == ET_ok, 0); + return _ptr->getGroup(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::set_thickness +// Access: Published +// Description: Sets the cloth thickness (must be positive). +//////////////////////////////////////////////////////////////////// +void PhysxCloth:: +set_thickness(float thickness) { + + nassertv(_error_type == ET_ok); + _ptr->setFriction(thickness); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::get_thickness +// Access: Published +// Description: Gets the cloth thickness. +//////////////////////////////////////////////////////////////////// +float PhysxCloth:: +get_thickness() const { + + nassertr(_error_type == ET_ok, 0.0f); + return _ptr->getThickness(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::get_density +// Access: Published +// Description: Gets the cloth density. +//////////////////////////////////////////////////////////////////// +float PhysxCloth:: +get_density() const { + + nassertr(_error_type == ET_ok, 0.0f); + return _ptr->getDensity(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::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 PhysxCloth:: +get_relative_grid_spacing() const { + + nassertr(_error_type == ET_ok, 0.0f); + return _ptr->getRelativeGridSpacing(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::get_num_particles +// Access: Published +// Description: Gets the number of cloth particles. +//////////////////////////////////////////////////////////////////// +unsigned int PhysxCloth:: +get_num_particles() { + + nassertr(_error_type == ET_ok, 0); + return _ptr->getNumberOfParticles(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::set_flag +// Access: Published +// Description: Sets the value of a single flag. +//////////////////////////////////////////////////////////////////// +void PhysxCloth:: +set_flag(PhysxClothFlag flag, bool value) { + + nassertv(_error_type == ET_ok); + + NxU32 flags = _ptr->getFlags(); + + if (value == true) { + flags |= flag; + } + else { + flags &= ~(flag); + } + + _ptr->setFlags(flags); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::get_flag +// Access: Published +// Description: Retrieves the value of a single flag. +//////////////////////////////////////////////////////////////////// +bool PhysxCloth:: +get_flag(PhysxClothFlag flag) const { + + nassertr(_error_type == ET_ok, false); + + return (_ptr->getFlags() & flag) ? true : false; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::set_groups_mask +// Access: Published +// Description: Sets 128-bit mask used for collision filtering. +//////////////////////////////////////////////////////////////////// +void PhysxCloth:: +set_groups_mask(const PhysxGroupsMask &mask) { + + nassertv(_error_type == ET_ok); + + NxGroupsMask _mask = mask.get_mask(); + _ptr->setGroupsMask(_mask); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::get_groups_mask +// Access: Published +// Description: Gets the 128-bit groups mask used for collision +// filtering. +//////////////////////////////////////////////////////////////////// +PhysxGroupsMask PhysxCloth:: +get_groups_mask() const { + + PhysxGroupsMask mask; + + nassertr(_error_type == ET_ok, mask); + + NxGroupsMask _mask = _ptr->getGroupsMask(); + mask.set_mask(_mask); + + return mask; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::is_sleeping +// Access: Published +// Description: Returns true if this cloth is sleeping. +// +// When a cloth 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 PhysxCloth:: +is_sleeping() const { + + nassertr(_error_type == ET_ok, false); + return _ptr->isSleeping(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::wake_up +// Access: Published +// Description: Wakes up the cloth 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 +// PhysxCloth::put_to_sleep(). +//////////////////////////////////////////////////////////////////// +void PhysxCloth:: +wake_up(float wakeCounterValue) { + + nassertv(_error_type == ET_ok); + _ptr->wakeUp(wakeCounterValue); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::put_to_sleep +// Access: Published +// Description: Forces the cloth to sleep. +// +// The cloth 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 PhysxCloth:: +put_to_sleep() { + + nassertv(_error_type == ET_ok); + _ptr->putToSleep(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::set_sleep_linear_velocity +// Access: Published +// Description: Sets the linear velocity below which an cloth +// may go to sleep. Cloths 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 PhysxCloth:: +set_sleep_linear_velocity(float threshold) { + + nassertv(_error_type == ET_ok); + _ptr->setSleepLinearVelocity(threshold); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::get_sleep_linear_velocity +// Access: Published +// Description: Returns the linear velocity below which an soft +// body may go to sleep. cloths whose linear velocity +// is above this threshold will not be put to sleep. +//////////////////////////////////////////////////////////////////// +float PhysxCloth:: +get_sleep_linear_velocity() const { + + nassertr(_error_type == ET_ok, 0.0f); + return _ptr->getSleepLinearVelocity(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::attach_vertex_to_global_pos +// Access: Published +// Description: Attaches a cloth vertex to a position in world +// space. +//////////////////////////////////////////////////////////////////// +void PhysxCloth:: +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: PhysxCloth::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 PhysxCloth:: +attach_to_shape(PhysxShape *shape) { + + nassertv(_error_type == ET_ok); + nassertv(shape); + + NxU32 attachmentFlags = 0; // --TODO-- + _ptr->attachToShape(shape->ptr(), attachmentFlags); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::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 PhysxCloth:: +attach_to_colliding_shapes() { + + nassertv(_error_type == ET_ok); + + NxU32 attachmentFlags = 0; // --TODO-- + _ptr->attachToCollidingShapes(attachmentFlags); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::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 PhysxCloth:: +detach_from_shape(PhysxShape *shape) { + + nassertv(_error_type == ET_ok); + nassertv(shape); + + _ptr->detachFromShape(shape->ptr()); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::free_vertex +// Access: Published +// Description: Frees a previously attached cloth point. +//////////////////////////////////////////////////////////////////// +void PhysxCloth:: +free_vertex(unsigned int vertexId) { + + nassertv(_error_type == ET_ok); + _ptr->freeVertex(vertexId); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::attach_vertex_to_shape +// Access: Published +// Description: Attaches a cloth vertex to a local position within +// a shape. +//////////////////////////////////////////////////////////////////// +void PhysxCloth:: +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: PhysxCloth::get_vertex_attachment_status +// Access: Published +// Description: Return the attachment status of the given vertex. +//////////////////////////////////////////////////////////////////// +PhysxEnums::PhysxVertexAttachmentStatus PhysxCloth:: +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: PhysxCloth::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 *PhysxCloth:: +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: PhysxCloth::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 PhysxCloth:: +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: PhysxCloth::set_external_acceleration +// Access: Published +// Description: Sets an external acceleration which affects all non +// attached particles of the cloth. +//////////////////////////////////////////////////////////////////// +void PhysxCloth:: +set_external_acceleration(LVector3f const &acceleration) { + + nassertv(_error_type == ET_ok); + nassertv_always(!acceleration.is_nan()); + + _ptr->setExternalAcceleration(PhysxManager::vec3_to_nxVec3(acceleration)); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::set_wind_acceleration +// Access: Published +// Description: Sets an acceleration acting normal to the cloth +// surface at each vertex. +//////////////////////////////////////////////////////////////////// +void PhysxCloth:: +set_wind_acceleration(LVector3f const &acceleration) { + + nassertv(_error_type == ET_ok); + nassertv_always(!acceleration.is_nan()); + + _ptr->setWindAcceleration(PhysxManager::vec3_to_nxVec3(acceleration)); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::get_external_acceleration +// Access: Published +// Description: Retrieves the external acceleration which affects +// all non attached particles of the cloth. +//////////////////////////////////////////////////////////////////// +LVector3f PhysxCloth:: +get_external_acceleration() const { + + nassertr(_error_type == ET_ok, LVector3f::zero()); + return PhysxManager::nxVec3_to_vec3(_ptr->getExternalAcceleration()); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::get_wind_acceleration +// Access: Published +// Description: Retrieves the acceleration acting normal to the +// cloth surface at each vertex +//////////////////////////////////////////////////////////////////// +LVector3f PhysxCloth:: +get_wind_acceleration() const { + + nassertr(_error_type == ET_ok, LVector3f::zero()); + return PhysxManager::nxVec3_to_vec3(_ptr->getWindAcceleration()); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxCloth::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 PhysxCloth:: +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: PhysxCloth::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 PhysxCloth:: +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: PhysxCloth::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 PhysxCloth:: +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/physxCloth.h b/panda/src/physx/physxCloth.h new file mode 100644 index 0000000000..444eb80127 --- /dev/null +++ b/panda/src/physx/physxCloth.h @@ -0,0 +1,136 @@ +// Filename: physxCloth.h +// Created by: enn0x (30Mar10) +// +//////////////////////////////////////////////////////////////////// +// +// 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 PHYSXCLOTH_H +#define PHYSXCLOTH_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 PhysxClothNode; + +//////////////////////////////////////////////////////////////////// +// Class : PhysxCloth +// Description : +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAPHYSX PhysxCloth : public PhysxObject, public PhysxEnums { + +PUBLISHED: + INLINE PhysxCloth(); + INLINE ~PhysxCloth(); + + PhysxScene *get_scene() const; + PhysxClothNode *get_cloth_node() const; + PhysxClothNode *create_cloth_node(const char *name); + + void set_name(const char *name); + void set_group(unsigned int group); + void set_groups_mask(const PhysxGroupsMask &mask); + void set_flag(PhysxClothFlag flag, bool value); + void set_thickness(float thickness); + + const char *get_name() const; + unsigned int get_num_particles(); + unsigned int get_group() const; + PhysxGroupsMask get_groups_mask() const; + bool get_flag(PhysxClothFlag flag) const; + float get_thickness() const; + float get_density() const; + float get_relative_grid_spacing() 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); + + INLINE void ls() const; + INLINE void ls(ostream &out, int indent_level=0) const; + +public: + void update(); + +//////////////////////////////////////////////////////////////////// +PUBLISHED: + void release(); + +public: + INLINE NxCloth *ptr() const { return _ptr; }; + + void link(NxCloth *ptr); + void unlink(); + +private: + NxCloth *_ptr; + PT(PhysxClothNode) _node; + +//////////////////////////////////////////////////////////////////// +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + PhysxObject::init_type(); + register_type(_type_handle, "PhysxCloth", + 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 "physxCloth.I" + +#endif // PHYSXCLOTH_H diff --git a/panda/src/physx/physxClothDesc.I b/panda/src/physx/physxClothDesc.I new file mode 100644 index 0000000000..0fc310ff3d --- /dev/null +++ b/panda/src/physx/physxClothDesc.I @@ -0,0 +1,59 @@ +// Filename: physxClothDesc.I +// Created by: enn0x (30Mar10) +// +//////////////////////////////////////////////////////////////////// +// +// 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: PhysxClothDesc::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxClothDesc:: +PhysxClothDesc() { + + _desc.name = ""; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::Destructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxClothDesc:: +~PhysxClothDesc() { + +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_to_default +// Access: Published +// Description: (re)sets the structure to the default. +//////////////////////////////////////////////////////////////////// +INLINE void PhysxClothDesc:: +set_to_default() { + + _desc.setToDefault(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::is_valid +// Access: Published +// Description: Returns true if the descriptor is valid. +//////////////////////////////////////////////////////////////////// +INLINE bool PhysxClothDesc:: +is_valid() const { + + return _desc.isValid(); +} + diff --git a/panda/src/physx/physxClothDesc.cxx b/panda/src/physx/physxClothDesc.cxx new file mode 100644 index 0000000000..d8931beb66 --- /dev/null +++ b/panda/src/physx/physxClothDesc.cxx @@ -0,0 +1,358 @@ +// Filename: physxClothDesc.cxx +// Created by: enn0x (30Mar10) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "physxClothDesc.h" +#include "physxClothMesh.h" +#include "physxManager.h" + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_name +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +set_name(const char *name) { + + _desc.name = name; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_global_pos +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +set_global_pos(const LPoint3f &pos) { + + _desc.globalPose.t = PhysxManager::point3_to_nxVec3(pos); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_global_mat +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +set_global_mat(const LMatrix4f &mat) { + + _desc.globalPose = PhysxManager::mat4_to_nxMat34(mat); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_global_hpr +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +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: PhysxClothDesc::set_thickness +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +set_thickness(float thickness) { + + _desc.thickness = thickness; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_density +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +set_density(float density) { + + _desc.density = density; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_bending_stiffness +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +set_bending_stiffness(float stiffness) { + + _desc.bendingStiffness = stiffness; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_stretching_stiffness +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +set_stretching_stiffness(float stiffness) { + + _desc.stretchingStiffness = stiffness; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_damping_coefficient +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +set_damping_coefficient(float damping) { + + _desc.dampingCoefficient = damping; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_friction +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +set_friction(float friction) { + + _desc.friction = friction; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_pressure +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +set_pressure(float pressure) { + + _desc.pressure = pressure; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_tear_factor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +set_tear_factor(float tearFactor) { + + _desc.tearFactor = tearFactor; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_flag +// Access: Published +// Description: Raise or lower individual ClothFlag flags. +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +set_flag(PhysxClothFlag flag, bool value) { + + if (value == true) { + _desc.flags |= flag; + } + else { + _desc.flags &= ~(flag); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_solver_iterations +// Access: Published +// Description: Number of solver iterations. +// Small numbers make the simulation faster while +// the cloth gets less stiff. +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +set_solver_iterations(unsigned int iterations) { + + _desc.solverIterations = iterations; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::set_cloth_mesh +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +set_cloth_mesh(PhysxClothMesh *mesh) { + + _desc.clothMesh = mesh->ptr(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::get_name +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +const char *PhysxClothDesc:: +get_name() const { + + return _desc.name; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::get_global_pos +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +LPoint3f PhysxClothDesc:: +get_global_pos() const { + + return PhysxManager::nxVec3_to_point3(_desc.globalPose.t); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::get_global_mat +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +LMatrix4f PhysxClothDesc:: +get_global_mat() const { + + return PhysxManager::nxMat34_to_mat4(_desc.globalPose); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::get_thickness +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxClothDesc:: +get_thickness() const { + + return _desc.thickness; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::get_density +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxClothDesc:: +get_density() const { + + return _desc.density; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::get_bending_stiffness +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxClothDesc:: +get_bending_stiffness() const { + + return _desc.bendingStiffness; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::get_stretching_stiffness +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxClothDesc:: +get_stretching_stiffness() const { + + return _desc.stretchingStiffness; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::get_damping_coefficient +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxClothDesc:: +get_damping_coefficient() const { + + return _desc.dampingCoefficient; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::get_friction +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxClothDesc:: +get_friction() const { + + return _desc.friction; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::get_pressure +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxClothDesc:: +get_pressure() const { + + return _desc.pressure; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::get_tear_factor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +float PhysxClothDesc:: +get_tear_factor() const { + + return _desc.tearFactor; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::get_flag +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +bool PhysxClothDesc:: +get_flag(PhysxClothFlag flag) const { + + return (_desc.flags & flag) ? true : false; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::get_solver_iterations +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +unsigned int PhysxClothDesc:: +get_solver_iterations() const { + + return _desc.solverIterations; +} + +/* +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothDesc::get_mesh_numbers +// Access: Public +// Description: Used by PhysScene to query the sizes of arrays +// to allocate for the user buffers in PhysxClothNode. +//////////////////////////////////////////////////////////////////// +void PhysxClothDesc:: +get_mesh_numbers(NxU32 &numVertices, NxU32 &numTriangles) { + + NxClothMeshDesc meshDesc; + _desc.clothMesh->saveToDesc(meshDesc); + + numVertices = meshDesc.numVertices; + numTriangles = meshDesc.numTriangles; +} +*/ + diff --git a/panda/src/physx/physxClothDesc.h b/panda/src/physx/physxClothDesc.h new file mode 100644 index 0000000000..88615f0e89 --- /dev/null +++ b/panda/src/physx/physxClothDesc.h @@ -0,0 +1,80 @@ +// Filename: physxClothDesc.h +// Created by: enn0x (30Mar10) +// +//////////////////////////////////////////////////////////////////// +// +// 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 PHYSXCLOTHDESC_H +#define PHYSXCLOTHDESC_H + +#include "pandabase.h" +#include "lpoint3.h" +#include "lmatrix.h" + +#include "physxEnums.h" +#include "physx_includes.h" + +class PhysxClothMesh; + +//////////////////////////////////////////////////////////////////// +// Class : PhysxClothDesc +// Description : Descriptor for PhysxCloth. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAPHYSX PhysxClothDesc : public PhysxEnums { + +PUBLISHED: + INLINE PhysxClothDesc(); + INLINE ~PhysxClothDesc(); + + INLINE void set_to_default(); + INLINE bool is_valid() const; + + void set_cloth_mesh(PhysxClothMesh *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_thickness(float thickness); + void set_density(float density); + void set_bending_stiffness(float stiffness); + void set_stretching_stiffness(float stiffness); + void set_damping_coefficient(float damping); + void set_friction(float friction); + void set_pressure(float pressure); + void set_tear_factor(float tearFactor); + void set_solver_iterations(unsigned int interations); + void set_flag(PhysxClothFlag flag, bool value); + + const char *get_name() const; + LPoint3f get_global_pos() const; + LMatrix4f get_global_mat() const; + float get_thickness() const; + float get_density() const; + float get_bending_stiffness() const; + float get_stretching_stiffness() const; + float get_damping_coefficient() const; + float get_friction() const; + float get_pressure() const; + float get_tear_factor() const; + unsigned int get_solver_iterations() const; + bool get_flag(PhysxClothFlag flag) const; + +public: + //void get_mesh_numbers(NxU32 &numVertices, NxU32 &numTriangles); + +public: + NxClothDesc _desc; +}; + +#include "physxClothDesc.I" + +#endif // PHYSXCLOTHDESC_H diff --git a/panda/src/physx/physxClothMeshDesc.I b/panda/src/physx/physxClothMeshDesc.I index 2c314ed016..88a5ebb2da 100644 --- a/panda/src/physx/physxClothMeshDesc.I +++ b/panda/src/physx/physxClothMeshDesc.I @@ -22,13 +22,14 @@ INLINE PhysxClothMeshDesc:: PhysxClothMeshDesc() { _desc.flags = 0; - _desc.pointStrideBytes = 5*sizeof(NxReal); + _desc.pointStrideBytes = sizeof(NxVec3); _desc.triangleStrideBytes = 3*sizeof(NxU32); _desc.points = NULL; _desc.triangles = NULL; _points = NULL; _triangles = NULL; + _texcoords = NULL; } //////////////////////////////////////////////////////////////////// @@ -46,6 +47,10 @@ INLINE PhysxClothMeshDesc:: if (_triangles) { delete [] _triangles; } + + if (_texcoords) { + delete [] _texcoords; + } } //////////////////////////////////////////////////////////////////// @@ -59,3 +64,32 @@ is_valid() const { return _desc.isValid(); } +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothMeshDesc::get_desc +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE const NxClothMeshDesc &PhysxClothMeshDesc:: +get_desc() const { + + return _desc; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothMeshDesc::get_texcoords +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +INLINE const plist PhysxClothMeshDesc:: +get_texcoords() const { + + plist texcoords; + + for (unsigned int i=0; i < _desc.numVertices; i++) { + LPoint2f uv = _texcoords[i]; + texcoords.push_back(uv); + } + + return texcoords; +} + diff --git a/panda/src/physx/physxClothMeshDesc.cxx b/panda/src/physx/physxClothMeshDesc.cxx index b7aa3c4a91..e0319d5c6c 100644 --- a/panda/src/physx/physxClothMeshDesc.cxx +++ b/panda/src/physx/physxClothMeshDesc.cxx @@ -32,14 +32,22 @@ void PhysxClothMeshDesc:: set_num_vertices(unsigned int numVertices) { + // Vertices if (_desc.points) { delete [] _points; } - _points = new NxReal[5 * numVertices]; + _points = new NxVec3[numVertices]; _desc.numVertices = numVertices; _desc.points = _points; + + // Texture coordinates + if (_texcoords) { + delete [] _texcoords; + } + + _texcoords = new LPoint2f[numVertices]; } //////////////////////////////////////////////////////////////////// @@ -53,12 +61,8 @@ set_vertex(unsigned int idx, const LPoint3f &vert, const LPoint2f &texcoord) { nassertv(_desc.numVertices > idx); - idx = 5 * idx; - _points[idx] = vert.get_x(); - _points[idx + 1] = vert.get_y(); - _points[idx + 2] = vert.get_z(); - _points[idx + 3] = texcoord.get_x(); - _points[idx + 4] = texcoord.get_y(); + _points[idx] = PhysxManager::point3_to_nxVec3(vert); + _texcoords[idx] = texcoord; } //////////////////////////////////////////////////////////////////// @@ -101,17 +105,6 @@ set_triangle(unsigned int idx, _triangles[idx + 2] = i3; } -//////////////////////////////////////////////////////////////////// -// Function: PhysxClothMeshDesc::get_desc -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -const NxClothMeshDesc &PhysxClothMeshDesc:: -get_desc() const { - - return _desc; -} - //////////////////////////////////////////////////////////////////// // Function: PhysxClothMeshDesc::set_from_node_path // Access: Published @@ -182,17 +175,16 @@ set_from_node_path(const NodePath &np) { NxU32 numVertices = dataVertices.size(); NxU32 numTriangles = dataIndices.size() / 3; - _points = new NxReal[5 * numVertices]; + _points = new NxVec3[numVertices]; _triangles = new NxU32[3 * numTriangles]; + _texcoords = new LPoint2f[numVertices]; i = 0; pvector::const_iterator vit; for (vit=dataVertices.begin(); vit!=dataVertices.end(); vit++) { LPoint3f v = *vit; - _points[5*i] = v.get_x(); - _points[5*i+1] = v.get_y(); - _points[5*i+2] = v.get_z(); + _points[i] = PhysxManager::point3_to_nxVec3(v); i++; } @@ -201,8 +193,7 @@ set_from_node_path(const NodePath &np) { for (tcit=dataTexcoords.begin(); tcit!=dataTexcoords.end(); tcit++) { LPoint2f tc = *tcit; - _points[5*i+3] = tc.get_x(); - _points[5*i+4] = tc.get_y(); + _texcoords[i] = tc; i++; } diff --git a/panda/src/physx/physxClothMeshDesc.h b/panda/src/physx/physxClothMeshDesc.h index 536170578a..aafe1b1326 100644 --- a/panda/src/physx/physxClothMeshDesc.h +++ b/panda/src/physx/physxClothMeshDesc.h @@ -19,6 +19,7 @@ #include "lpoint3.h" #include "lpoint2.h" #include "nodePath.h" +#include "plist.h" #include "physx_includes.h" @@ -35,7 +36,8 @@ PUBLISHED: INLINE bool is_valid() const; void set_num_vertices(unsigned int n); - void set_vertex(unsigned int idx, const LPoint3f &vert, const LPoint2f &texcoord); + void set_vertex(unsigned int idx, + const LPoint3f &vert, const LPoint2f &texcoord); void set_num_triangles(unsigned int n); void set_triangle(unsigned int idx, @@ -44,12 +46,15 @@ PUBLISHED: void set_from_node_path(const NodePath &np); public: - const NxClothMeshDesc &get_desc() const; + INLINE const NxClothMeshDesc &get_desc() const; + INLINE const plist get_texcoords() const; private: - NxReal *_points; - NxU32 *_triangles; NxClothMeshDesc _desc; + NxVec3 *_points; + NxU32 *_triangles; + + LPoint2f *_texcoords; }; #include "physxClothMeshDesc.I" diff --git a/panda/src/physx/physxClothNode.I b/panda/src/physx/physxClothNode.I new file mode 100644 index 0000000000..b11eb93cb4 --- /dev/null +++ b/panda/src/physx/physxClothNode.I @@ -0,0 +1,53 @@ +// Filename: physxClothNode.I +// Created by: enn0x (05Apr10) +// +//////////////////////////////////////////////////////////////////// +// +// 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: PhysxClothNode::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxClothNode:: +PhysxClothNode(const char *name) : GeomNode(name) { + + _numVertices = 0; + + _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); + + _numTexcoords = 0; + _texcoords = NULL; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothNode::Destructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE PhysxClothNode:: +~PhysxClothNode() { + + if (_texcoords) { + delete [] _texcoords; + } +} + diff --git a/panda/src/physx/physxClothNode.cxx b/panda/src/physx/physxClothNode.cxx new file mode 100644 index 0000000000..0aa76c4afa --- /dev/null +++ b/panda/src/physx/physxClothNode.cxx @@ -0,0 +1,229 @@ +// Filename: physxClothNode.cxx +// Created by: enn0x (05Apr10) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "physxClothNode.h" +#include "physxCloth.h" +#include "physxFileStream.h" + +#include "geomVertexFormat.h" +#include "geomVertexWriter.h" + +TypeHandle PhysxClothNode::_type_handle; + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothNode::allocate +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothNode:: +allocate(PhysxCloth *cloth) { + + _cloth = cloth; + + // Retrieve number of vertices and triangles the hard way + NxClothMeshDesc meshDesc; + _cloth->ptr()->getClothMesh()->saveToDesc(meshDesc); + + NxU32 numVertices = meshDesc.numVertices; + NxU32 numTriangles = meshDesc.numTriangles; + + NxReal 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.verticesNormalBegin = (NxVec3 *)malloc(sizeof(NxVec3) * maxVertices); + _mesh.verticesPosByteStride = sizeof(NxVec3); + _mesh.verticesNormalByteStride = sizeof(NxVec3); + _mesh.maxVertices = maxVertices; + _mesh.numVerticesPtr = (NxU32 *)malloc(sizeof(NxU32)); + + // The number of triangles is constant, even if the cloth is torn + NxU32 maxIndices = 3 * numTriangles; + _mesh.indicesBegin = (NxU32 *)malloc(sizeof(NxU32) * maxIndices); + _mesh.indicesByteStride = sizeof(NxU32); + _mesh.maxIndices = maxIndices; + _mesh.numIndicesPtr = (NxU32 *)malloc(sizeof(NxU32)); + + NxU32 maxParentIndices = maxVertices; + _mesh.parentIndicesBegin = (NxU32 *)malloc(sizeof(NxU32)*maxParentIndices); + _mesh.parentIndicesByteStride = sizeof(NxU32); + _mesh.maxParentIndices = maxParentIndices; + _mesh.numParentIndicesPtr = (NxU32 *)malloc(sizeof(NxU32)); + + *(_mesh.numVerticesPtr) = 0; + *(_mesh.numIndicesPtr) = 0; + + _cloth->ptr()->setMeshData(_mesh); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothNode::update +// Access: Public +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothNode:: +update() { + + NxU32 numVertices = *(_mesh.numVerticesPtr); + + if (numVertices == _numVertices) { + update_geom(); + } + else { + update_texcoords(); + create_geom(); + _numVertices = numVertices; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothNode::create_geom +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothNode:: +create_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()); + + // Vertices and normals + NxU32 numVertices = *(_mesh.numVerticesPtr); + NxVec3 *v = (NxVec3 *)_mesh.verticesPosBegin; + NxVec3 *n = (NxVec3 *)_mesh.verticesNormalBegin; + + for (unsigned int i=0; i < numVertices; i++) { + vwriter.add_data3f(v->x, v->y, v->z); + v++; + nwriter.add_data3f(n->x, n->y, n->z); + n++; + } + + // Texture coordinates + NxReal tex_u; + NxReal tex_v; + + if (_texcoords) { + for (unsigned int i=0; i < numVertices; i++) { + tex_u = _texcoords[2*i]; + tex_v = _texcoords[2*i+1]; + twriter.add_data2f(tex_u, tex_v); + } + } + + // Indices + NxU32 numIndices = *(_mesh.numIndicesPtr); + NxU32 *idx = (NxU32 *)_mesh.indicesBegin; + + for (unsigned int i=0; i < numIndices; i++) { + _prim->add_vertex(*idx); + idx++; + } + + _prim->close_primitive(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothNode::update_geom +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothNode:: +update_geom() { + + GeomVertexWriter vwriter = GeomVertexWriter(_vdata, InternalName::get_vertex()); + GeomVertexWriter nwriter = GeomVertexWriter(_vdata, InternalName::get_normal()); + + NxU32 numVertices = *(_mesh.numVerticesPtr); + NxVec3 *v = (NxVec3 *)_mesh.verticesPosBegin; + NxVec3 *n = (NxVec3 *)_mesh.verticesNormalBegin; + + for (unsigned int i=0; i < numVertices; i++) { + vwriter.set_data3f(v->x, v->y, v->z); + v++; + nwriter.set_data3f(n->x, n->y, n->z); + n++; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothNode::update_texcoords +// Access: Private +// Description: +//////////////////////////////////////////////////////////////////// +void PhysxClothNode:: +update_texcoords() { + + if (!_texcoords) { + return; + } + + NxU32 numVertices = *(_mesh.numVerticesPtr); + NxU32 *parent = (NxU32 *)_mesh.parentIndicesBegin + _numTexcoords; + + for (NxU32 i=_numTexcoords; i < numVertices; i++, parent++) { + _texcoords[2*i] = _texcoords[2*(*parent)]; + _texcoords[2*i+1] = _texcoords[2*(*parent)+1]; + } + + _numTexcoords = numVertices; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxClothNode::set_texcoords +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +bool PhysxClothNode:: +set_texcoords(const Filename &filename) { + + if (filename.empty()) { + return false; + } + + Filename fn(filename); + fn.resolve_filename(get_model_path()); + + if (!filename.exists()) { + return false; + } + + PhysxFileStream fs(filename.c_str(), true); + + fs.readByte(); // N + fs.readByte(); // X + fs.readByte(); // X + fs.readByte(); // 1 + fs.readByte(); // T + fs.readByte(); // E + fs.readByte(); // X + fs.readByte(); // C + fs.readByte(); // 1 + + _numTexcoords = fs.readDword(); + _texcoords = new float[2 * _numTexcoords]; + + for (unsigned int i=0; i<_numTexcoords; i++) { + _texcoords[2*i] = fs.readFloat(); + _texcoords[2*i+1] = fs.readFloat(); + } + + return true; +} + diff --git a/panda/src/physx/physxClothNode.h b/panda/src/physx/physxClothNode.h new file mode 100644 index 0000000000..27706709be --- /dev/null +++ b/panda/src/physx/physxClothNode.h @@ -0,0 +1,89 @@ +// Filename: physxClothNode.h +// Created by: enn0x (05Apr10) +// +//////////////////////////////////////////////////////////////////// +// +// 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 PHYSXCLOTHNODE_H +#define PHYSXCLOTHNODE_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 PhysxCloth; + +//////////////////////////////////////////////////////////////////// +// Class : PhysxClothNode +// Description : Renderable geometry which represents a cloth mesh. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDAPHYSX PhysxClothNode : public GeomNode { + +PUBLISHED: + INLINE PhysxClothNode(const char *name); + INLINE ~PhysxClothNode(); + + bool set_texcoords(const Filename &filename); + +public: + void allocate(PhysxCloth *cloth); + void update(); + +private: + void create_geom(); + void update_geom(); + void update_texcoords(); + + unsigned int _numVertices; + + NxMeshData _mesh; + + PT(GeomVertexData) _vdata; + PT(Geom) _geom; + PT(GeomTriangles) _prim; + + PT(PhysxCloth) _cloth; + + unsigned int _numTexcoords; + float *_texcoords; + +//////////////////////////////////////////////////////////////////// +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + GeomNode::init_type(); + register_type(_type_handle, "PhysxClothNode", + 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 "physxClothNode.I" + +#endif // PHYSXCLOTHNODE_H diff --git a/panda/src/physx/physxEnums.h b/panda/src/physx/physxEnums.h index 59ca51b8a9..c5cf0d1fbd 100644 --- a/panda/src/physx/physxEnums.h +++ b/panda/src/physx/physxEnums.h @@ -141,6 +141,26 @@ #define NX_BP_TYPE_SAP_SINGLE 0 #define NX_BP_TYPE_SAP_MULTI 1 +// PhysxClothFlag +#define NX_CLF_PRESSURE 1<<0 +#define NX_CLF_STATIC 1<<1 +#define NX_CLF_DISABLE_COLLISION 1<<2 +#define NX_CLF_SELFCOLLISION 1<<3 +#define NX_CLF_VISUALIZATION 1<<4 +#define NX_CLF_GRAVITY 1<<5 +#define NX_CLF_BENDING 1<<6 +#define NX_CLF_BENDING_ORTHO 1<<7 +#define NX_CLF_DAMPING 1<<8 +#define NX_CLF_COLLISION_TWOWAY 1<<9 +#define NX_CLF_TRIANGLE_COLLISION 1<<11 +#define NX_CLF_TEARABLE 1<<12 +#define NX_CLF_HARDWARE 1<<13 +#define NX_CLF_COMDAMPING 1<<14 +#define NX_CLF_VALIDBOUNDS 1<<15 +#define NX_CLF_FLUID_COLLISION 1<<16 +#define NX_CLF_DISABLE_DYNAMIC_CCD 1<<17 +#define NX_CLF_ADHERE 1<<18 + // PhysxContactPairFlag #define NX_IGNORE_PAIR 1<<0 #define NX_NOTIFY_ON_START_TOUCH 1<<1 @@ -290,6 +310,11 @@ #define NX_Y 2 #define NX_Z 3 +// PhysxVertexAttachmentStatus +#define NX_CLOTH_VERTEX_ATTACHMENT_NONE 0 +#define NX_CLOTH_VERTEX_ATTACHMENT_GLOBAL 1 +#define NX_CLOTH_VERTEX_ATTACHMENT_SHAPE 2 + // PhysxWheelShapeFlag #define NX_WF_WHEEL_AXIS_CONTACT_NORMAL 1<<0 #define NX_WF_INPUT_LAT_SLIPVELOCITY 1<<1 @@ -440,6 +465,27 @@ PUBLISHED: BPT_sap_multi = NX_BP_TYPE_SAP_MULTI }; + enum PhysxClothFlag { + CLF_pressure = NX_CLF_PRESSURE, + CLF_static = NX_CLF_STATIC, + CLF_disable_collision = NX_CLF_DISABLE_COLLISION, + CLF_selfcollision = NX_CLF_SELFCOLLISION, + CLF_visualization = NX_CLF_VISUALIZATION, + CLF_gravity = NX_CLF_GRAVITY, + CLF_bending = NX_CLF_BENDING, + CLF_bending_ortho = NX_CLF_BENDING_ORTHO, + CLF_damping = NX_CLF_DAMPING, + CLF_collision_twoway = NX_CLF_COLLISION_TWOWAY, + CLF_triangle_collision = NX_CLF_TRIANGLE_COLLISION, + CLF_tearable = NX_CLF_TEARABLE, + CLF_hardware = NX_CLF_HARDWARE, + CLF_comdamping = NX_CLF_COMDAMPING, + CLF_validbounds = NX_CLF_VALIDBOUNDS, + CLF_fluid_collision = NX_CLF_FLUID_COLLISION, + CLF_disable_dynamic_ccd = NX_CLF_DISABLE_DYNAMIC_CCD, + CLF_adhere = NX_CLF_ADHERE + }; + enum PhysxContactPairFlag { CPF_ignore_pair = NX_IGNORE_PAIR, CPF_notify_on_start_touch = NX_NOTIFY_ON_START_TOUCH, @@ -609,6 +655,12 @@ PUBLISHED: Z_up = NX_Z }; + enum PhysxVertexAttachmentStatus { + VAS_none = NX_CLOTH_VERTEX_ATTACHMENT_NONE, + VAS_global = NX_CLOTH_VERTEX_ATTACHMENT_GLOBAL, + VAS_shape = NX_CLOTH_VERTEX_ATTACHMENT_SHAPE + }; + enum PhysxWheelFlag { WF_steerable_input = NX_WF_STEERABLE_INPUT, WF_steerable_auto = NX_WF_STEERABLE_AUTO, diff --git a/panda/src/physx/physxKitchen.cxx b/panda/src/physx/physxKitchen.cxx index b58e70d678..379caa184b 100644 --- a/panda/src/physx/physxKitchen.cxx +++ b/panda/src/physx/physxKitchen.cxx @@ -65,8 +65,8 @@ cook_convex_mesh(const PhysxConvexMeshDesc &meshDesc, const Filename &filename) nassertr_always(filename.touch(), false); nassertr_always(meshDesc.is_valid(), false); - PhysxFileStream stream = PhysxFileStream(filename, false); - return _cooking->NxCookConvexMesh(meshDesc.get_desc(), stream); + PhysxFileStream fs = PhysxFileStream(filename, false); + return _cooking->NxCookConvexMesh(meshDesc.get_desc(), fs); } //////////////////////////////////////////////////////////////////// @@ -81,8 +81,8 @@ cook_triangle_mesh(const PhysxTriangleMeshDesc &meshDesc, const Filename &filena nassertr_always(filename.touch(), false); nassertr_always(meshDesc.is_valid(), false); - PhysxFileStream stream = PhysxFileStream(filename, false); - return _cooking->NxCookTriangleMesh(meshDesc.get_desc(), stream); + PhysxFileStream fs = PhysxFileStream(filename, false); + return _cooking->NxCookTriangleMesh(meshDesc.get_desc(), fs); } //////////////////////////////////////////////////////////////////// @@ -93,13 +93,55 @@ cook_triangle_mesh(const PhysxTriangleMeshDesc &meshDesc, const Filename &filena bool PhysxKitchen:: cook_cloth_mesh(const PhysxClothMeshDesc &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->NxCookClothMesh(meshDesc.get_desc(), fs); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxKitchen::cook_texcoords +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +bool PhysxKitchen:: +cook_texcoords(const PhysxClothMeshDesc &meshDesc, const Filename &filename) { nassertr_always(!filename.empty(), false); nassertr_always(filename.touch(), false); nassertr_always(meshDesc.is_valid(), false); - PhysxFileStream stream = PhysxFileStream(filename, false); - return _cooking->NxCookClothMesh(meshDesc.get_desc(), stream); + const plist texcoords = meshDesc.get_texcoords(); + + // Write texcoords to binary file + PhysxFileStream fs = PhysxFileStream(filename.c_str(), false); + + // Header + fs.storeByte('N'); + fs.storeByte('X'); + fs.storeByte('S'); + fs.storeByte(1); + fs.storeByte('T'); + fs.storeByte('E'); + fs.storeByte('X'); + fs.storeByte('C'); + fs.storeByte(1); + + // Size + fs.storeDword(texcoords.size()); + + // Texcoords + plist::const_iterator it; + for(it=texcoords.begin(); it!=texcoords.end(); it++) { + LPoint2f v = *it; + + fs.storeFloat(v.get_x()); + fs.storeFloat(v.get_y()); + } + + return true; } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/physx/physxKitchen.h b/panda/src/physx/physxKitchen.h index bc601f1754..c7afadbb53 100644 --- a/panda/src/physx/physxKitchen.h +++ b/panda/src/physx/physxKitchen.h @@ -42,6 +42,7 @@ 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_texcoords(const PhysxClothMeshDesc &meshDesc, const Filename &filename); PhysxConvexMesh *cook_convex_mesh(const PhysxConvexMeshDesc &meshDesc); PhysxTriangleMesh *cook_triangle_mesh(const PhysxTriangleMeshDesc &meshDesc); diff --git a/panda/src/physx/physxScene.I b/panda/src/physx/physxScene.I index ebf2255730..d645f807fb 100644 --- a/panda/src/physx/physxScene.I +++ b/panda/src/physx/physxScene.I @@ -65,5 +65,7 @@ ls(ostream &out, int indent_level) const { _ffgroups.ls(out, indent_level); _controllers.ls(out, indent_level); _vehicles.ls(out, indent_level); + _cloths.ls(out, indent_level); + //_softbodies.ls(out, indent_level); } diff --git a/panda/src/physx/physxScene.cxx b/panda/src/physx/physxScene.cxx index a56deee202..c2dad441d3 100644 --- a/panda/src/physx/physxScene.cxx +++ b/panda/src/physx/physxScene.cxx @@ -22,6 +22,8 @@ #include "physxConstraintDominance.h" #include "physxVehicle.h" #include "physxVehicleDesc.h" +#include "physxCloth.h" +#include "physxClothDesc.h" TypeHandle PhysxScene::_type_handle; @@ -29,6 +31,8 @@ PStatCollector PhysxScene::_pcollector_fetch_results("App:PhysX:Fetch Results"); PStatCollector PhysxScene::_pcollector_update_transforms("App:PhysX:Update Transforms"); PStatCollector PhysxScene::_pcollector_debug_renderer("App:PhysX:Debug Renderer"); PStatCollector PhysxScene::_pcollector_simulate("App:PhysX:Simulate"); +PStatCollector PhysxScene::_pcollector_cloth("App:PhysX:Cloth"); +//PStatCollector PhysxScene::_pcollector_softbody("App:PhysX:Softbody"); //////////////////////////////////////////////////////////////////// // Function: PhysxScene::link @@ -123,8 +127,25 @@ unlink() { group->unlink(); } - // Unlink cloths TODO - // Unlink softbodies TODO + // Unlink cloths + NxCloth **cloths = _ptr->getCloths(); + NxU32 nCloths = _ptr->getNbCloths(); + + for (NxU32 i=0; i < nCloths; i++) { + PhysxCloth *cloth = (PhysxCloth *)cloths[i]->userData; + cloth->unlink(); + } + + // Unlink softbodies +/* + NxSoftBody **sbs = _ptr->getSoftBodies(); + NxU32 nSbs = _ptr->getNbSoftBodies(); + + for (NxU32 i=0; i < nSbs; i++) { + PhysxSoftBody *sb = (PhysxSoftBody *)sb[i]->userData; + sb->unlink(); + } +*/ // Unlink materials NxMaterial *materials[5]; @@ -253,6 +274,28 @@ fetch_results() { _pcollector_debug_renderer.stop(); nassertv(_ptr->isWritable()); + + // Update cloth nodes + _pcollector_cloth.start(); + + NxCloth **cloths = _ptr->getCloths(); + for (NxU32 i=0; i < _ptr->getNbCloths(); i++) { + PT(PhysxCloth) cloth = (PhysxCloth *)cloths[i]->userData; + cloth->update(); + } + + _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(); +*/ } //////////////////////////////////////////////////////////////////// @@ -856,6 +899,65 @@ get_force_field_shape_group(unsigned int idx) const { return groupPtr ? (PhysxForceFieldShapeGroup *)groupPtr->userData : NULL; } +//////////////////////////////////////////////////////////////////// +// Function: PhysxScene::get_num_cloths +// Access: Published +// Description: Gets the number of cloths in the scene. +//////////////////////////////////////////////////////////////////// +unsigned int PhysxScene:: +get_num_cloths() const { + + nassertr(_error_type == ET_ok, -1); + return _ptr->getNbCloths(); +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxScene::create_cloth +// Access: Published +// Description: Creates a cloth in this scene. +//////////////////////////////////////////////////////////////////// +PhysxCloth *PhysxScene:: +create_cloth(PhysxClothDesc &desc) { + + nassertr(_error_type == ET_ok, NULL); + + PhysxCloth *cloth = new PhysxCloth(); + nassertr(cloth, NULL); + + NxCloth *clothPtr = _ptr->createCloth(desc._desc); + nassertr(clothPtr, NULL); + + cloth->link(clothPtr); + + // TODO: + + // Allocate buffers in the cloth's geom node (PhysxMeshNode) + //NxU32 numVertices = 0; + //NxU32 numTriangles = 0; + //desc.get_mesh_numbers(numVertices, numTriangles); + //cloth->get_cloth_node()->allocate(numVertices, numTriangles, cloth); + + return cloth; +} + +//////////////////////////////////////////////////////////////////// +// Function: PhysxScene::get_cloth +// Access: Published +// Description: Returns the n-th cloth from the array of +// all the cloths in the scene. +//////////////////////////////////////////////////////////////////// +PhysxCloth *PhysxScene:: +get_cloth(unsigned int idx) const { + + nassertr(_error_type == ET_ok, NULL); + nassertr_always(idx < _ptr->getNbCloths(), NULL); + + NxCloth **cloths = _ptr->getCloths(); + NxCloth *clothPtr = cloths[idx]; + + return (PhysxCloth *)(clothPtr->userData); +} + //////////////////////////////////////////////////////////////////// // Function: PhysxScene::get_num_vehicles // Access: Published diff --git a/panda/src/physx/physxScene.h b/panda/src/physx/physxScene.h index 535a6ac0f4..0ebb232f6b 100644 --- a/panda/src/physx/physxScene.h +++ b/panda/src/physx/physxScene.h @@ -50,6 +50,8 @@ class PhysxRaycastReport; class PhysxSceneStats2; class PhysxVehicle; class PhysxVehicleDesc; +class PhysxCloth; +class PhysxClothDesc; //////////////////////////////////////////////////////////////////// // Class : PhysxScene @@ -131,6 +133,12 @@ PUBLISHED: PhysxForceFieldShapeGroup *get_force_field_shape_group(unsigned int idx) const; MAKE_SEQ(get_force_field_shape_groups, get_num_force_field_shape_groups, get_force_field_shape_group); + // Cloths + unsigned int get_num_cloths() const; + PhysxCloth *create_cloth(PhysxClothDesc &desc); + PhysxCloth *get_cloth(unsigned int idx) const; + MAKE_SEQ(get_cloths, get_num_cloths, get_cloth); + // Vehicles unsigned int get_num_vehicles() const; PhysxVehicle *create_vehicle(PhysxVehicleDesc &desc); @@ -221,6 +229,7 @@ public: PhysxObjectCollection _ffgroups; PhysxObjectCollection _controllers; PhysxObjectCollection _vehicles; + PhysxObjectCollection _cloths; PhysxMaterial *get_wheel_shape_material(); @@ -238,6 +247,8 @@ private: static PStatCollector _pcollector_update_transforms; static PStatCollector _pcollector_debug_renderer; static PStatCollector _pcollector_simulate; + static PStatCollector _pcollector_cloth; + //static PStatCollector _pcollector_softbody; //////////////////////////////////////////////////////////////////// public: diff --git a/panda/src/physx/physx_composite.cxx b/panda/src/physx/physx_composite.cxx index 4dd14356ed..e2a4d92803 100644 --- a/panda/src/physx/physx_composite.cxx +++ b/panda/src/physx/physx_composite.cxx @@ -17,6 +17,11 @@ #include "physxCapsuleForceFieldShapeDesc.cxx" #include "physxCapsuleShape.cxx" #include "physxCapsuleShapeDesc.cxx" +#include "physxCloth.cxx" +#include "physxClothDesc.cxx" +#include "physxClothMesh.cxx" +#include "physxClothMeshDesc.cxx" +#include "physxClothNode.cxx" #include "physxContactPair.cxx" #include "physxContactPoint.cxx" #include "physxContactReport.cxx" @@ -112,5 +117,3 @@ #include "physxWheelDesc.cxx" #include "physxWheelShape.cxx" #include "physxWheelShapeDesc.cxx" -#include "physxClothMesh.cxx" -#include "physxClothMeshDesc.cxx"