Panda3D

physxCloth.cxx

00001 // Filename: physxCloth.cxx
00002 // Created by:  enn0x (30Mar10)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "physxCloth.h"
00016 #include "physxClothDesc.h"
00017 #include "physxScene.h"
00018 #include "physxGroupsMask.h"
00019 #include "physxShape.h"
00020 #include "physxManager.h"
00021 
00022 #include "boundingBox.h"
00023 
00024 TypeHandle PhysxCloth::_type_handle;
00025 
00026 ////////////////////////////////////////////////////////////////////
00027 //     Function: PhysxCloth::link
00028 //       Access: Public
00029 //  Description: 
00030 ////////////////////////////////////////////////////////////////////
00031 void PhysxCloth::
00032 link(NxCloth *clothPtr) {
00033 
00034   // Link self
00035   _ptr = clothPtr;
00036   _error_type = ET_ok;
00037   _ptr->userData = this;
00038 
00039   set_name(clothPtr->getName());
00040 
00041   PhysxScene *scene = (PhysxScene *)_ptr->getScene().userData;
00042   scene->_cloths.add(this);
00043 }
00044 
00045 ////////////////////////////////////////////////////////////////////
00046 //     Function: PhysxCloth::unlink
00047 //       Access: Public
00048 //  Description: 
00049 ////////////////////////////////////////////////////////////////////
00050 void PhysxCloth::
00051 unlink() {
00052 
00053   // Unlink self
00054   _ptr->userData = NULL;
00055   _error_type = ET_released;
00056 
00057   PhysxScene *scene = (PhysxScene *)_ptr->getScene().userData;
00058   scene->_cloths.remove(this);
00059 
00060   _node = NULL;
00061 }
00062 
00063 ////////////////////////////////////////////////////////////////////
00064 //     Function: PhysxCloth::release
00065 //       Access: Published
00066 //  Description: 
00067 ////////////////////////////////////////////////////////////////////
00068 void PhysxCloth::
00069 release() {
00070 
00071   nassertv(_error_type == ET_ok);
00072 
00073   unlink();
00074   _ptr->getScene().releaseCloth(*_ptr);
00075   _ptr = NULL;
00076 }
00077 
00078 ////////////////////////////////////////////////////////////////////
00079 //     Function: PhysxCloth::update
00080 //       Access: Public
00081 //  Description: 
00082 ////////////////////////////////////////////////////////////////////
00083 void PhysxCloth::
00084 update() {
00085 
00086   if (_node) {
00087 
00088     // Update node mesh data
00089     _node->update();
00090 
00091     // Update node bounding volume
00092     NxBounds3 bounds;
00093     _ptr->getWorldBounds(bounds);
00094 
00095     BoundingBox bb(PhysxManager::nxVec3_to_point3(bounds.min),
00096                    PhysxManager::nxVec3_to_point3(bounds.max));
00097     _node->set_bounds(&bb);
00098   }
00099 }
00100 
00101 ////////////////////////////////////////////////////////////////////
00102 //     Function: PhysxCloth::get_scene
00103 //       Access: Published
00104 //  Description: Returns the scene which this cloth belongs to.
00105 ////////////////////////////////////////////////////////////////////
00106 PhysxScene *PhysxCloth::
00107 get_scene() const {
00108 
00109   nassertr(_error_type == ET_ok, NULL);
00110   return (PhysxScene *)_ptr->getScene().userData;
00111 }
00112 
00113 ////////////////////////////////////////////////////////////////////
00114 //     Function: PhysxCloth::get_cloth_node
00115 //       Access: Published
00116 //  Description: 
00117 ////////////////////////////////////////////////////////////////////
00118 PhysxClothNode *PhysxCloth::
00119 get_cloth_node() const {
00120 
00121   nassertr(_error_type == ET_ok, NULL);
00122   return _node;
00123 }
00124 
00125 ////////////////////////////////////////////////////////////////////
00126 //     Function: PhysxCloth::create_cloth_node
00127 //       Access: Published
00128 //  Description: 
00129 ////////////////////////////////////////////////////////////////////
00130 PhysxClothNode *PhysxCloth::
00131 create_cloth_node(const char *name) {
00132 
00133   nassertr(_error_type == ET_ok, NULL);
00134 
00135   _node = new PhysxClothNode(name);
00136   _node->allocate(this);
00137 
00138   return _node;
00139 }
00140 
00141 ////////////////////////////////////////////////////////////////////
00142 //     Function: PhysxCloth::set_name
00143 //       Access: Published
00144 //  Description: Sets a name string for the object that can be
00145 //               retrieved with get_name(). 
00146 //               This is for debugging and is not used by the
00147 //               engine.
00148 ////////////////////////////////////////////////////////////////////
00149 void PhysxCloth::
00150 set_name(const char *name) {
00151 
00152   nassertv(_error_type == ET_ok);
00153 
00154   _name = name ? name : "";
00155   _ptr->setName(_name.c_str());
00156 }
00157 
00158 ////////////////////////////////////////////////////////////////////
00159 //     Function: PhysxCloth::get_name
00160 //       Access: Published
00161 //  Description: Retrieves the name string.
00162 ////////////////////////////////////////////////////////////////////
00163 const char *PhysxCloth::
00164 get_name() const {
00165 
00166   nassertr(_error_type == ET_ok, "");
00167   return _ptr->getName();
00168 }
00169 
00170 ////////////////////////////////////////////////////////////////////
00171 //     Function: PhysxCloth::set_group
00172 //       Access: Published
00173 //  Description: Sets which collision group this cloth is part of.
00174 //               Collision group must be between 0 and 31.
00175 ////////////////////////////////////////////////////////////////////
00176 void PhysxCloth::
00177 set_group(unsigned int group) {
00178 
00179   nassertv(_error_type == ET_ok);
00180   nassertv(group >= 0 && group < 32);
00181   _ptr->setGroup(group);
00182 }
00183 
00184 ////////////////////////////////////////////////////////////////////
00185 //     Function: PhysxCloth::get_group
00186 //       Access: Published
00187 //  Description: Retrieves the collision group this cloth is part
00188 //               of.
00189 ////////////////////////////////////////////////////////////////////
00190 unsigned int PhysxCloth::
00191 get_group() const {
00192 
00193   nassertr(_error_type == ET_ok, 0);
00194   return _ptr->getGroup();
00195 }
00196 
00197 ////////////////////////////////////////////////////////////////////
00198 //     Function: PhysxCloth::set_thickness
00199 //       Access: Published
00200 //  Description: Sets the cloth thickness (must be positive).
00201 ////////////////////////////////////////////////////////////////////
00202 void PhysxCloth::
00203 set_thickness(float thickness) {
00204 
00205   nassertv(_error_type == ET_ok);
00206   _ptr->setThickness(thickness);
00207 }
00208 
00209 ////////////////////////////////////////////////////////////////////
00210 //     Function: PhysxCloth::get_thickness
00211 //       Access: Published
00212 //  Description: Gets the cloth thickness.
00213 ////////////////////////////////////////////////////////////////////
00214 float PhysxCloth::
00215 get_thickness() const {
00216 
00217   nassertr(_error_type == ET_ok, 0.0f);
00218   return _ptr->getThickness();
00219 }
00220 
00221 ////////////////////////////////////////////////////////////////////
00222 //     Function: PhysxCloth::get_density
00223 //       Access: Published
00224 //  Description: Gets the cloth density.
00225 ////////////////////////////////////////////////////////////////////
00226 float PhysxCloth::
00227 get_density() const {
00228 
00229   nassertr(_error_type == ET_ok, 0.0f);
00230   return _ptr->getDensity();
00231 }
00232 
00233 ////////////////////////////////////////////////////////////////////
00234 //     Function: PhysxCloth::get_relative_grid_spacing
00235 //       Access: Published
00236 //  Description: Gets the relative grid spacing for the broad
00237 //               phase. The cloth is represented by a set of
00238 //               world aligned cubical cells in broad phase. The
00239 //               size of these cells is determined by multiplying
00240 //               the length of the diagonal of the AABB of the
00241 //               initial soft body size with this constant.
00242 ////////////////////////////////////////////////////////////////////
00243 float PhysxCloth::
00244 get_relative_grid_spacing() const {
00245 
00246   nassertr(_error_type == ET_ok, 0.0f);
00247   return _ptr->getRelativeGridSpacing();
00248 }
00249 
00250 ////////////////////////////////////////////////////////////////////
00251 //     Function: PhysxCloth::get_num_particles
00252 //       Access: Published
00253 //  Description: Gets the number of cloth particles.
00254 ////////////////////////////////////////////////////////////////////
00255 unsigned int PhysxCloth::
00256 get_num_particles() {
00257 
00258   nassertr(_error_type == ET_ok, 0);
00259   return _ptr->getNumberOfParticles();
00260 }
00261 
00262 ////////////////////////////////////////////////////////////////////
00263 //     Function: PhysxCloth::set_flag
00264 //       Access: Published
00265 //  Description: Sets the value of a single flag.
00266 ////////////////////////////////////////////////////////////////////
00267 void PhysxCloth::
00268 set_flag(PhysxClothFlag flag, bool value) {
00269 
00270   nassertv(_error_type == ET_ok);
00271 
00272   NxU32 flags = _ptr->getFlags();
00273 
00274   if (value == true) {
00275     flags |= flag;
00276   } 
00277   else {
00278     flags &= ~(flag);
00279   }
00280 
00281   _ptr->setFlags(flags);
00282 }
00283 
00284 ////////////////////////////////////////////////////////////////////
00285 //     Function: PhysxCloth::get_flag
00286 //       Access: Published
00287 //  Description: Retrieves the value of a single flag.
00288 ////////////////////////////////////////////////////////////////////
00289 bool PhysxCloth::
00290 get_flag(PhysxClothFlag flag) const {
00291 
00292   nassertr(_error_type == ET_ok, false);
00293 
00294   return (_ptr->getFlags() & flag) ? true : false;
00295 }
00296 
00297 ////////////////////////////////////////////////////////////////////
00298 //     Function: PhysxCloth::set_groups_mask
00299 //       Access: Published
00300 //  Description: Sets 128-bit mask used for collision filtering.
00301 ////////////////////////////////////////////////////////////////////
00302 void PhysxCloth::
00303 set_groups_mask(const PhysxGroupsMask &mask) {
00304 
00305   nassertv(_error_type == ET_ok);
00306 
00307   NxGroupsMask _mask = mask.get_mask();
00308   _ptr->setGroupsMask(_mask);
00309 }
00310 
00311 ////////////////////////////////////////////////////////////////////
00312 //     Function: PhysxCloth::get_groups_mask
00313 //       Access: Published
00314 //  Description: Gets the 128-bit groups mask used for collision
00315 //               filtering.
00316 ////////////////////////////////////////////////////////////////////
00317 PhysxGroupsMask PhysxCloth::
00318 get_groups_mask() const {
00319 
00320   PhysxGroupsMask mask;
00321 
00322   nassertr(_error_type == ET_ok, mask);
00323 
00324   NxGroupsMask _mask = _ptr->getGroupsMask();
00325   mask.set_mask(_mask);
00326 
00327   return mask;
00328 }
00329 
00330 ////////////////////////////////////////////////////////////////////
00331 //     Function: PhysxCloth::is_sleeping
00332 //       Access: Published
00333 //  Description: Returns true if this cloth is sleeping. 
00334 //
00335 //               When a cloth does not move for a period of time,
00336 //               it is no longer simulated in order to save time.
00337 //               This state is called sleeping. However, because the
00338 //               object automatically wakes up when it is either
00339 //               touched by an awake object, or one of its
00340 //               properties is changed by the user, the entire sleep
00341 //               mechanism should be transparent to the user.
00342 ////////////////////////////////////////////////////////////////////
00343 bool PhysxCloth::
00344 is_sleeping() const {
00345 
00346   nassertr(_error_type == ET_ok, false);
00347   return _ptr->isSleeping();
00348 }
00349 
00350 ////////////////////////////////////////////////////////////////////
00351 //     Function: PhysxCloth::wake_up
00352 //       Access: Published
00353 //  Description: Wakes up the cloth if it is sleeping. 
00354 //
00355 //               The wakeCounterValue determines how long until the
00356 //               body is put to sleep, a value of zero means that
00357 //               the body is sleeping. wake_up(0) is equivalent to
00358 //               PhysxCloth::put_to_sleep().
00359 ////////////////////////////////////////////////////////////////////
00360 void PhysxCloth::
00361 wake_up(float wakeCounterValue) {
00362 
00363   nassertv(_error_type == ET_ok);
00364   _ptr->wakeUp(wakeCounterValue);
00365 }
00366 
00367 ////////////////////////////////////////////////////////////////////
00368 //     Function: PhysxCloth::put_to_sleep
00369 //       Access: Published
00370 //  Description: Forces the cloth to sleep. 
00371 //
00372 //               The cloth  will stay asleep until the next
00373 //               call to simulate, and will not wake up until then
00374 //               even when otherwise it would (for example a force
00375 //               is applied to it). It can however wake up during
00376 //               the next do_physics call.
00377 ////////////////////////////////////////////////////////////////////
00378 void PhysxCloth::
00379 put_to_sleep() {
00380 
00381   nassertv(_error_type == ET_ok);
00382   _ptr->putToSleep();
00383 }
00384 
00385 ////////////////////////////////////////////////////////////////////
00386 //     Function: PhysxCloth::set_sleep_linear_velocity
00387 //       Access: Published
00388 //  Description: Sets the linear velocity below which an cloth
00389 //               may go to sleep. Cloths whose linear velocity is
00390 //               above this threshold will not be put to sleep.
00391 //
00392 //               Setting the sleep angular/linear velocity only
00393 //               makes sense when the BF_energy_sleep_test is not
00394 //               set.
00395 ////////////////////////////////////////////////////////////////////
00396 void PhysxCloth::
00397 set_sleep_linear_velocity(float threshold) {
00398 
00399   nassertv(_error_type == ET_ok);
00400   _ptr->setSleepLinearVelocity(threshold);
00401 }
00402 
00403 ////////////////////////////////////////////////////////////////////
00404 //     Function: PhysxCloth::get_sleep_linear_velocity
00405 //       Access: Published
00406 //  Description: Returns the linear velocity below which an soft
00407 //               body may go to sleep. cloths whose linear velocity
00408 //               is above this threshold will not be put to sleep.
00409 ////////////////////////////////////////////////////////////////////
00410 float PhysxCloth::
00411 get_sleep_linear_velocity() const {
00412 
00413   nassertr(_error_type == ET_ok, 0.0f);
00414   return _ptr->getSleepLinearVelocity();
00415 }
00416 
00417 ////////////////////////////////////////////////////////////////////
00418 //     Function: PhysxCloth::attach_vertex_to_global_pos
00419 //       Access: Published
00420 //  Description: Attaches a cloth vertex to a position in world
00421 //               space.
00422 ////////////////////////////////////////////////////////////////////
00423 void PhysxCloth::
00424 attach_vertex_to_global_pos(unsigned int vertexId, LPoint3f const &pos) {
00425 
00426   nassertv(_error_type == ET_ok);
00427   nassertv(!pos.is_nan());
00428 
00429   _ptr->attachVertexToGlobalPosition(vertexId, PhysxManager::point3_to_nxVec3(pos));
00430 }
00431 
00432 ////////////////////////////////////////////////////////////////////
00433 //     Function: PhysxCloth::attach_to_shape
00434 //       Access: Published
00435 //  Description: Attaches the cloth to a shape. All cloth points
00436 //               currently inside the shape are attached.
00437 //
00438 //               This method only works with primitive and convex
00439 //               shapes. Since the inside of a general triangle mesh
00440 //               is not clearly defined.
00441 ////////////////////////////////////////////////////////////////////
00442 void PhysxCloth::
00443 attach_to_shape(PhysxShape *shape) {
00444 
00445   nassertv(_error_type == ET_ok);
00446   nassertv(shape);
00447 
00448   NxU32 attachmentFlags = 0; // --TODO--
00449   _ptr->attachToShape(shape->ptr(), attachmentFlags);
00450 }
00451 
00452 ////////////////////////////////////////////////////////////////////
00453 //     Function: PhysxCloth::attach_to_colliding_shapes
00454 //       Access: Published
00455 //  Description: Attaches the cloth to all shapes, currently
00456 //               colliding. 
00457 //
00458 //               This method only works with primitive and convex
00459 //               shapes. Since the inside of a general triangle mesh
00460 //               is not clearly defined.
00461 ////////////////////////////////////////////////////////////////////
00462 void PhysxCloth::
00463 attach_to_colliding_shapes() {
00464 
00465   nassertv(_error_type == ET_ok);
00466 
00467   NxU32 attachmentFlags = 0; // --TODO--
00468   _ptr->attachToCollidingShapes(attachmentFlags);
00469 }
00470 
00471 ////////////////////////////////////////////////////////////////////
00472 //     Function: PhysxCloth::detach_from_shape
00473 //       Access: Published
00474 //  Description: Detaches the cloth from a shape it has been
00475 //               attached to before. 
00476 //
00477 //               If the cloth has not been attached to the shape
00478 //               before, the call has no effect.
00479 ////////////////////////////////////////////////////////////////////
00480 void PhysxCloth::
00481 detach_from_shape(PhysxShape *shape) {
00482 
00483   nassertv(_error_type == ET_ok);
00484   nassertv(shape);
00485 
00486   _ptr->detachFromShape(shape->ptr());
00487 }
00488 
00489 ////////////////////////////////////////////////////////////////////
00490 //     Function: PhysxCloth::free_vertex
00491 //       Access: Published
00492 //  Description: Frees a previously attached cloth point.
00493 ////////////////////////////////////////////////////////////////////
00494 void PhysxCloth::
00495 free_vertex(unsigned int vertexId) {
00496 
00497   nassertv(_error_type == ET_ok);
00498   _ptr->freeVertex(vertexId);
00499 }
00500 
00501 ////////////////////////////////////////////////////////////////////
00502 //     Function: PhysxCloth::attach_vertex_to_shape
00503 //       Access: Published
00504 //  Description: Attaches a cloth vertex to a local position within
00505 //               a shape.
00506 ////////////////////////////////////////////////////////////////////
00507 void PhysxCloth::
00508 attach_vertex_to_shape(unsigned int vertexId, PhysxShape *shape, LPoint3f const &localPos) {
00509 
00510   nassertv(_error_type == ET_ok);
00511   nassertv(!localPos.is_nan());
00512   nassertv(shape);
00513 
00514   NxU32 attachmentFlags = 0; // --TODO--
00515   _ptr->attachVertexToShape(vertexId, shape->ptr(),
00516                             PhysxManager::point3_to_nxVec3(localPos),
00517                             attachmentFlags);
00518 }
00519 
00520 ////////////////////////////////////////////////////////////////////
00521 //     Function: PhysxCloth::get_vertex_attachment_status
00522 //       Access: Published
00523 //  Description: Return the attachment status of the given vertex.
00524 ////////////////////////////////////////////////////////////////////
00525 PhysxEnums::PhysxVertexAttachmentStatus PhysxCloth::
00526 get_vertex_attachment_status(unsigned int vertexId) const {
00527 
00528   nassertr(_error_type == ET_ok, VAS_none);
00529   // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(), VAS_none);
00530 
00531   return (PhysxVertexAttachmentStatus) _ptr->getVertexAttachmentStatus(vertexId);
00532 }
00533 
00534 ////////////////////////////////////////////////////////////////////
00535 //     Function: PhysxCloth::get_vertex_attachment_shape
00536 //       Access: Published
00537 //  Description: Returns the pointer to an attached shape pointer
00538 //               of the given vertex. If the vertex is not attached
00539 //               or attached to a global position, NULL is returned.
00540 ////////////////////////////////////////////////////////////////////
00541 PhysxShape *PhysxCloth::
00542 get_vertex_attachment_shape(unsigned int vertexId) const {
00543 
00544   nassertr(_error_type == ET_ok, NULL);
00545   // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(), NULL);
00546 
00547   NxShape *shapePtr = _ptr->getVertexAttachmentShape(vertexId);
00548   PhysxShape *shape = shapePtr ? (PhysxShape *)(shapePtr->userData) : NULL;
00549 
00550   return shape;
00551 }
00552 
00553 ////////////////////////////////////////////////////////////////////
00554 //     Function: PhysxCloth::get_vertex_attachment_pos
00555 //       Access: Published
00556 //  Description: Returns the attachment position of the given
00557 //               vertex. If the vertex is attached to shape, the
00558 //               position local to the shape's pose is returned. If
00559 //               the vertex is not attached, the return value is
00560 //               undefined.
00561 ////////////////////////////////////////////////////////////////////
00562 LPoint3f PhysxCloth::
00563 get_vertex_attachment_pos(unsigned int vertexId) const {
00564 
00565   nassertr(_error_type == ET_ok, LPoint3f::zero());
00566   // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(), LPoint3f::zero());
00567 
00568   return PhysxManager::nxVec3_to_point3(_ptr->getVertexAttachmentPosition(vertexId));
00569 }
00570 
00571 ////////////////////////////////////////////////////////////////////
00572 //     Function: PhysxCloth::set_external_acceleration
00573 //       Access: Published
00574 //  Description: Sets an external acceleration which affects all non
00575 //               attached particles of the cloth.
00576 ////////////////////////////////////////////////////////////////////
00577 void PhysxCloth::
00578 set_external_acceleration(LVector3f const &acceleration) {
00579 
00580   nassertv(_error_type == ET_ok);
00581   nassertv_always(!acceleration.is_nan());
00582 
00583   _ptr->setExternalAcceleration(PhysxManager::vec3_to_nxVec3(acceleration));
00584 }
00585 
00586 ////////////////////////////////////////////////////////////////////
00587 //     Function: PhysxCloth::set_wind_acceleration
00588 //       Access: Published
00589 //  Description: Sets an acceleration acting normal to the cloth
00590 //               surface at each vertex.
00591 ////////////////////////////////////////////////////////////////////
00592 void PhysxCloth::
00593 set_wind_acceleration(LVector3f const &acceleration) {
00594 
00595   nassertv(_error_type == ET_ok);
00596   nassertv_always(!acceleration.is_nan());
00597 
00598   _ptr->setWindAcceleration(PhysxManager::vec3_to_nxVec3(acceleration));
00599 }
00600 
00601 ////////////////////////////////////////////////////////////////////
00602 //     Function: PhysxCloth::get_external_acceleration
00603 //       Access: Published
00604 //  Description: Retrieves the external acceleration which affects
00605 //               all non attached particles of the cloth.
00606 ////////////////////////////////////////////////////////////////////
00607 LVector3f PhysxCloth::
00608 get_external_acceleration() const {
00609 
00610   nassertr(_error_type == ET_ok, LVector3f::zero());
00611   return PhysxManager::nxVec3_to_vec3(_ptr->getExternalAcceleration());
00612 }
00613 
00614 ////////////////////////////////////////////////////////////////////
00615 //     Function: PhysxCloth::get_wind_acceleration
00616 //       Access: Published
00617 //  Description: Retrieves the acceleration acting normal to the
00618 //               cloth surface at each vertex
00619 ////////////////////////////////////////////////////////////////////
00620 LVector3f PhysxCloth::
00621 get_wind_acceleration() const {
00622 
00623   nassertr(_error_type == ET_ok, LVector3f::zero());
00624   return PhysxManager::nxVec3_to_vec3(_ptr->getWindAcceleration());
00625 }
00626 
00627 ////////////////////////////////////////////////////////////////////
00628 //     Function: PhysxCloth::add_force_at_vertex
00629 //       Access: Published
00630 //  Description: Applies a force (or impulse) defined in the 
00631 //               global coordinate frame, to a particular vertex
00632 //               of the cloth.
00633 ////////////////////////////////////////////////////////////////////
00634 void PhysxCloth::
00635 add_force_at_vertex(LVector3f const &force, int vertexId, PhysxForceMode mode) {
00636 
00637   nassertv(_error_type == ET_ok);
00638   _ptr->addForceAtVertex(PhysxManager::vec3_to_nxVec3(force),
00639                          vertexId,
00640                          (NxForceMode) mode);
00641 }
00642 
00643 ////////////////////////////////////////////////////////////////////
00644 //     Function: PhysxCloth::add_force_at_pos
00645 //       Access: Published
00646 //  Description: Applies a radial force (or impulse) at a
00647 //               particular position. All vertices within radius
00648 //               will be affected with a quadratic drop-off. 
00649 ////////////////////////////////////////////////////////////////////
00650 void PhysxCloth::
00651 add_force_at_pos(LPoint3f const &pos, float magnitude, float radius, PhysxForceMode mode) {
00652 
00653   nassertv(_error_type == ET_ok);
00654   _ptr->addForceAtPos(PhysxManager::point3_to_nxVec3(pos),
00655                       magnitude,
00656                       radius,
00657                       (NxForceMode) mode);
00658 }
00659 
00660 ////////////////////////////////////////////////////////////////////
00661 //     Function: PhysxCloth::add_directed_force_at_pos
00662 //       Access: Published
00663 //  Description: Applies a directed force (or impulse) at a
00664 //               particular position. All vertices within radius
00665 //               will be affected with a quadratic drop-off.  
00666 ////////////////////////////////////////////////////////////////////
00667 void PhysxCloth::
00668 add_directed_force_at_pos(LPoint3f const &pos, LVector3f const &force, float radius, PhysxForceMode mode) {
00669 
00670   nassertv(_error_type == ET_ok);
00671   _ptr->addDirectedForceAtPos(PhysxManager::point3_to_nxVec3(pos),
00672                               PhysxManager::vec3_to_nxVec3(force),
00673                               radius,
00674                               (NxForceMode) mode);
00675 }
00676 
 All Classes Functions Variables Enumerations