Cloth simulation and rendering. No tearing yet.
This commit is contained in:
parent
36956aed7b
commit
8dd0b6ca96
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
*/
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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<LPoint2f> PhysxClothMeshDesc::
|
||||
get_texcoords() const {
|
||||
|
||||
plist<LPoint2f> texcoords;
|
||||
|
||||
for (unsigned int i=0; i < _desc.numVertices; i++) {
|
||||
LPoint2f uv = _texcoords[i];
|
||||
texcoords.push_back(uv);
|
||||
}
|
||||
|
||||
return texcoords;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<LPoint3f>::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++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<LPoint2f> get_texcoords() const;
|
||||
|
||||
private:
|
||||
NxReal *_points;
|
||||
NxU32 *_triangles;
|
||||
NxClothMeshDesc _desc;
|
||||
NxVec3 *_points;
|
||||
NxU32 *_triangles;
|
||||
|
||||
LPoint2f *_texcoords;
|
||||
};
|
||||
|
||||
#include "physxClothMeshDesc.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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<LPoint2f> 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<LPoint2f>::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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<PhysxForceFieldShapeGroup> _ffgroups;
|
||||
PhysxObjectCollection<PhysxController> _controllers;
|
||||
PhysxObjectCollection<PhysxVehicle> _vehicles;
|
||||
PhysxObjectCollection<PhysxCloth> _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:
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue