00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "physxSoftBody.h"
00016 #include "physxSoftBodyDesc.h"
00017 #include "physxSoftBodyNode.h"
00018 #include "physxScene.h"
00019 #include "physxGroupsMask.h"
00020
00021 #include "boundingBox.h"
00022
00023 TypeHandle PhysxSoftBody::_type_handle;
00024
00025
00026
00027
00028
00029
00030 void PhysxSoftBody::
00031 link(NxSoftBody *softbodyPtr) {
00032
00033
00034 _ptr = softbodyPtr;
00035 _error_type = ET_ok;
00036 _ptr->userData = this;
00037
00038 set_name(softbodyPtr->getName());
00039
00040 PhysxScene *scene = (PhysxScene *)_ptr->getScene().userData;
00041 scene->_softbodies.add(this);
00042 }
00043
00044
00045
00046
00047
00048
00049 void PhysxSoftBody::
00050 unlink() {
00051
00052
00053 _ptr->userData = NULL;
00054 _error_type = ET_released;
00055
00056 PhysxScene *scene = (PhysxScene *)_ptr->getScene().userData;
00057 scene->_softbodies.remove(this);
00058
00059 _node = NULL;
00060 }
00061
00062
00063
00064
00065
00066
00067 void PhysxSoftBody::
00068 release() {
00069
00070 nassertv(_error_type == ET_ok);
00071
00072 unlink();
00073 _ptr->getScene().releaseSoftBody(*_ptr);
00074 _ptr = NULL;
00075 }
00076
00077
00078
00079
00080
00081
00082 void PhysxSoftBody::
00083 update() {
00084
00085 if (_node) {
00086
00087
00088 _node->update();
00089
00090
00091 NxBounds3 bounds;
00092 _ptr->getWorldBounds(bounds);
00093
00094 BoundingBox bb(PhysxManager::nxVec3_to_point3(bounds.min),
00095 PhysxManager::nxVec3_to_point3(bounds.max));
00096 _node->set_bounds(&bb);
00097 }
00098 }
00099
00100
00101
00102
00103
00104
00105 PhysxScene *PhysxSoftBody::
00106 get_scene() const {
00107
00108 nassertr(_error_type == ET_ok, NULL);
00109 return (PhysxScene *)_ptr->getScene().userData;
00110 }
00111
00112
00113
00114
00115
00116
00117 PhysxSoftBodyNode *PhysxSoftBody::
00118 get_soft_body_node() const {
00119
00120 nassertr(_error_type == ET_ok, NULL);
00121 return _node;
00122 }
00123
00124
00125
00126
00127
00128
00129 PhysxSoftBodyNode *PhysxSoftBody::
00130 create_soft_body_node(const char *name) {
00131
00132 nassertr(_error_type == ET_ok, NULL);
00133
00134 _node = new PhysxSoftBodyNode(name);
00135 _node->allocate(this);
00136
00137 return _node;
00138 }
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 void PhysxSoftBody::
00149 set_name(const char *name) {
00150
00151 nassertv(_error_type == ET_ok);
00152
00153 _name = name ? name : "";
00154 _ptr->setName(_name.c_str());
00155 }
00156
00157
00158
00159
00160
00161
00162 const char *PhysxSoftBody::
00163 get_name() const {
00164
00165 nassertr(_error_type == ET_ok, "");
00166 return _ptr->getName();
00167 }
00168
00169
00170
00171
00172
00173
00174
00175 void PhysxSoftBody::
00176 set_group(unsigned int group) {
00177
00178 nassertv(_error_type == ET_ok);
00179 nassertv(group >= 0 && group < 32);
00180 _ptr->setGroup(group);
00181 }
00182
00183
00184
00185
00186
00187
00188
00189 unsigned int PhysxSoftBody::
00190 get_group() const {
00191
00192 nassertr(_error_type == ET_ok, 0);
00193 return _ptr->getGroup();
00194 }
00195
00196
00197
00198
00199
00200
00201 void PhysxSoftBody::
00202 set_groups_mask(const PhysxGroupsMask &mask) {
00203
00204 nassertv(_error_type == ET_ok);
00205
00206 NxGroupsMask _mask = mask.get_mask();
00207 _ptr->setGroupsMask(_mask);
00208 }
00209
00210
00211
00212
00213
00214
00215
00216 PhysxGroupsMask PhysxSoftBody::
00217 get_groups_mask() const {
00218
00219 PhysxGroupsMask mask;
00220
00221 nassertr(_error_type == ET_ok, mask);
00222
00223 NxGroupsMask _mask = _ptr->getGroupsMask();
00224 mask.set_mask(_mask);
00225
00226 return mask;
00227 }
00228
00229
00230
00231
00232
00233
00234 unsigned int PhysxSoftBody::
00235 get_num_particles() {
00236
00237 nassertr(_error_type == ET_ok, 0);
00238 return _ptr->getNumberOfParticles();
00239 }
00240
00241
00242
00243
00244
00245
00246
00247 void PhysxSoftBody::
00248 set_particle_radius(float radius) {
00249
00250 nassertv(_error_type == ET_ok);
00251 _ptr->setParticleRadius(radius);
00252 }
00253
00254
00255
00256
00257
00258
00259 float PhysxSoftBody::
00260 get_particle_radius() const {
00261
00262 nassertr(_error_type == ET_ok, 0.0f);
00263 return _ptr->getParticleRadius();
00264 }
00265
00266
00267
00268
00269
00270
00271 void PhysxSoftBody::
00272 set_flag(PhysxSoftBodyFlag flag, bool value) {
00273
00274 nassertv(_error_type == ET_ok);
00275
00276 NxU32 flags = _ptr->getFlags();
00277
00278 if (value == true) {
00279 flags |= flag;
00280 }
00281 else {
00282 flags &= ~(flag);
00283 }
00284
00285 _ptr->setFlags(flags);
00286 }
00287
00288
00289
00290
00291
00292
00293 bool PhysxSoftBody::
00294 get_flag(PhysxSoftBodyFlag flag) const {
00295
00296 nassertr(_error_type == ET_ok, false);
00297
00298 return (_ptr->getFlags() & flag) ? true : false;
00299 }
00300
00301
00302
00303
00304
00305
00306 float PhysxSoftBody::
00307 get_density() const {
00308
00309 nassertr(_error_type == ET_ok, 0.0f);
00310 return _ptr->getDensity();
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 float PhysxSoftBody::
00324 get_relative_grid_spacing() const {
00325
00326 nassertr(_error_type == ET_ok, 0.0f);
00327 return _ptr->getRelativeGridSpacing();
00328 }
00329
00330
00331
00332
00333
00334
00335
00336 void PhysxSoftBody::
00337 set_volume_stiffness(float stiffness) {
00338
00339 nassertv(_error_type == ET_ok);
00340 ptr()->setVolumeStiffness(stiffness);
00341 }
00342
00343
00344
00345
00346
00347
00348 float PhysxSoftBody::
00349 get_volume_stiffness() const {
00350
00351 nassertr(_error_type == ET_ok, 0.0f);
00352 return ptr()->getVolumeStiffness();
00353 }
00354
00355
00356
00357
00358
00359
00360
00361 void PhysxSoftBody::
00362 set_stretching_stiffness(float stiffness) {
00363
00364 nassertv(_error_type == ET_ok);
00365 ptr()->setStretchingStiffness(stiffness);
00366 }
00367
00368
00369
00370
00371
00372
00373 float PhysxSoftBody::
00374 get_stretching_stiffness() const {
00375
00376 nassertr(_error_type == ET_ok, 0.0f);
00377 return ptr()->getStretchingStiffness();
00378 }
00379
00380
00381
00382
00383
00384
00385
00386 void PhysxSoftBody::
00387 set_damping_coefficient(float coef) {
00388
00389 nassertv(_error_type == ET_ok);
00390 ptr()->setDampingCoefficient(coef);
00391 }
00392
00393
00394
00395
00396
00397
00398 float PhysxSoftBody::
00399 get_damping_coefficient() const {
00400
00401 nassertr(_error_type == ET_ok, 0.0f);
00402 return ptr()->getDampingCoefficient();
00403 }
00404
00405
00406
00407
00408
00409
00410
00411 void PhysxSoftBody::
00412 set_friction(float friction) {
00413
00414 nassertv(_error_type == ET_ok);
00415 ptr()->setFriction(friction);
00416 }
00417
00418
00419
00420
00421
00422
00423 float PhysxSoftBody::
00424 get_friction() const {
00425
00426 nassertr(_error_type == ET_ok, 0.0f);
00427 return ptr()->getFriction();
00428 }
00429
00430
00431
00432
00433
00434
00435
00436 void PhysxSoftBody::
00437 set_tear_factor(float factor) {
00438
00439 nassertv(_error_type == ET_ok);
00440 nassertv(factor > 1.0f);
00441 ptr()->setTearFactor(factor);
00442 }
00443
00444
00445
00446
00447
00448
00449 float PhysxSoftBody::
00450 get_tear_factor() const {
00451
00452 nassertr(_error_type == ET_ok, 0.0f);
00453 return ptr()->getTearFactor();
00454 }
00455
00456
00457
00458
00459
00460
00461
00462 void PhysxSoftBody::
00463 set_attachment_tear_factor(float factor) {
00464
00465 nassertv(_error_type == ET_ok);
00466 nassertv(factor > 1.0f);
00467 ptr()->setAttachmentTearFactor(factor);
00468 }
00469
00470
00471
00472
00473
00474
00475 float PhysxSoftBody::
00476 get_attachment_tear_factor() const {
00477
00478 nassertr(_error_type == ET_ok, 0.0f);
00479 return ptr()->getAttachmentTearFactor();
00480 }
00481
00482
00483
00484
00485
00486
00487 void PhysxSoftBody::
00488 set_solver_iterations(unsigned int iterations) {
00489
00490 nassertv(_error_type == ET_ok);
00491 ptr()->setSolverIterations(iterations);
00492 }
00493
00494
00495
00496
00497
00498
00499 unsigned int PhysxSoftBody::
00500 get_solver_iterations() const {
00501
00502 nassertr(_error_type == ET_ok, 0);
00503 return ptr()->getSolverIterations();
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519 bool PhysxSoftBody::
00520 is_sleeping() const {
00521
00522 nassertr(_error_type == ET_ok, false);
00523 return _ptr->isSleeping();
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536 void PhysxSoftBody::
00537 wake_up(float wakeCounterValue) {
00538
00539 nassertv(_error_type == ET_ok);
00540 _ptr->wakeUp(wakeCounterValue);
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554 void PhysxSoftBody::
00555 put_to_sleep() {
00556
00557 nassertv(_error_type == ET_ok);
00558 _ptr->putToSleep();
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572 void PhysxSoftBody::
00573 set_sleep_linear_velocity(float threshold) {
00574
00575 nassertv(_error_type == ET_ok);
00576 _ptr->setSleepLinearVelocity(threshold);
00577 }
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 float PhysxSoftBody::
00588 get_sleep_linear_velocity() const {
00589
00590 nassertr(_error_type == ET_ok, 0.0f);
00591 return _ptr->getSleepLinearVelocity();
00592 }
00593
00594 #if NX_SDK_VERSION_NUMBER > 281
00595
00596
00597
00598
00599
00600
00601 void PhysxSoftBody::
00602 set_self_collision_thickness(float thickness) {
00603
00604 nassertv(_error_type == ET_ok);
00605 _ptr->setSelfCollisionThickness(thickness);
00606 }
00607
00608
00609
00610
00611
00612
00613 float PhysxSoftBody::
00614 get_self_collision_thickness() const {
00615
00616 nassertr(_error_type == ET_ok, 0.0f);
00617 return _ptr->getSelfCollisionThickness();
00618 }
00619
00620
00621
00622
00623
00624
00625 void PhysxSoftBody::
00626 set_hard_stretch_limitation_factor(float factor) {
00627
00628 nassertv(_error_type == ET_ok);
00629 ptr()->setHardStretchLimitationFactor(factor);
00630 }
00631
00632
00633
00634
00635
00636
00637
00638 float PhysxSoftBody::
00639 get_hard_stretch_limitation_factor() const {
00640
00641 nassertr(_error_type == ET_ok, 0.0f);
00642 return ptr()->getHardStretchLimitationFactor();
00643 }
00644 #endif // NX_SDK_VERSION_NUMBER > 281
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 // Function: PhysxSoftBody::attach_vertex_to_global_pos
00656 // Access: Published
00657 // Description: Attaches a cloth vertex to a position in world
00658 // space.
00659
00660 void PhysxSoftBody::
00661 attach_vertex_to_global_pos(unsigned int vertexId, LPoint3f const &pos) {
00662
00663 nassertv(_error_type == ET_ok);
00664 nassertv(!pos.is_nan());
00665
00666 _ptr->attachVertexToGlobalPosition(vertexId, PhysxManager::point3_to_nxVec3(pos));
00667 }
00668
00669
00670 // Function: PhysxSoftBody::attach_to_shape
00671 // Access: Published
00672 // Description: Attaches the cloth to a shape. All cloth points
00673 // currently inside the shape are attached.
00674 //
00675 // This method only works with primitive and convex
00676 // shapes. Since the inside of a general triangle mesh
00677 // is not clearly defined.
00678
00679 void PhysxSoftBody::
00680 attach_to_shape(PhysxShape *shape) {
00681
00682 nassertv(_error_type == ET_ok);
00683 nassertv(shape);
00684
00685 NxU32 attachmentFlags = 0; // --TODO--
00686 _ptr->attachToShape(shape->ptr(), attachmentFlags);
00687 }
00688
00689
00690 // Function: PhysxSoftBody::attach_to_colliding_shapes
00691 // Access: Published
00692 // Description: Attaches the cloth to all shapes, currently
00693 // colliding.
00694 //
00695 // This method only works with primitive and convex
00696 // shapes. Since the inside of a general triangle mesh
00697 // is not clearly defined.
00698
00699 void PhysxSoftBody::
00700 attach_to_colliding_shapes() {
00701
00702 nassertv(_error_type == ET_ok);
00703
00704 NxU32 attachmentFlags = 0; // --TODO--
00705 _ptr->attachToCollidingShapes(attachmentFlags);
00706 }
00707
00708
00709 // Function: PhysxSoftBody::detach_from_shape
00710 // Access: Published
00711 // Description: Detaches the cloth from a shape it has been
00712 // attached to before.
00713 //
00714 // If the cloth has not been attached to the shape
00715 // before, the call has no effect.
00716
00717 void PhysxSoftBody::
00718 detach_from_shape(PhysxShape *shape) {
00719
00720 nassertv(_error_type == ET_ok);
00721 nassertv(shape);
00722
00723 _ptr->detachFromShape(shape->ptr());
00724 }
00725
00726
00727 // Function: PhysxSoftBody::free_vertex
00728 // Access: Published
00729 // Description: Frees a previously attached cloth point.
00730
00731 void PhysxSoftBody::
00732 free_vertex(unsigned int vertexId) {
00733
00734 nassertv(_error_type == ET_ok);
00735 _ptr->freeVertex(vertexId);
00736 }
00737
00738
00739 // Function: PhysxSoftBody::attach_vertex_to_shape
00740 // Access: Published
00741 // Description: Attaches a cloth vertex to a local position within
00742 // a shape.
00743
00744 void PhysxSoftBody::
00745 attach_vertex_to_shape(unsigned int vertexId, PhysxShape *shape, LPoint3f const &localPos) {
00746
00747 nassertv(_error_type == ET_ok);
00748 nassertv(!localPos.is_nan());
00749 nassertv(shape);
00750
00751 NxU32 attachmentFlags = 0; // --TODO--
00752 _ptr->attachVertexToShape(vertexId, shape->ptr(),
00753 PhysxManager::point3_to_nxVec3(localPos),
00754 attachmentFlags);
00755 }
00756
00757
00758 // Function: PhysxSoftBody::get_vertex_attachment_status
00759 // Access: Published
00760 // Description: Return the attachment status of the given vertex.
00761
00762 PhysxEnums::PhysxVertexAttachmentStatus PhysxSoftBody::
00763 get_vertex_attachment_status(unsigned int vertexId) const {
00764
00765 nassertr(_error_type == ET_ok, VAS_none);
00766 // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(), VAS_none);
00767
00768 return (PhysxVertexAttachmentStatus) _ptr->getVertexAttachmentStatus(vertexId);
00769 }
00770
00771
00772 // Function: PhysxSoftBody::get_vertex_attachment_shape
00773 // Access: Published
00774 // Description: Returns the pointer to an attached shape pointer
00775 // of the given vertex. If the vertex is not attached
00776 // or attached to a global position, NULL is returned.
00777
00778 PhysxShape *PhysxSoftBody::
00779 get_vertex_attachment_shape(unsigned int vertexId) const {
00780
00781 nassertr(_error_type == ET_ok, NULL);
00782 // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(), NULL);
00783
00784 NxShape *shapePtr = _ptr->getVertexAttachmentShape(vertexId);
00785 PhysxShape *shape = shapePtr ? (PhysxShape *)(shapePtr->userData) : NULL;
00786
00787 return shape;
00788 }
00789
00790
00791 // Function: PhysxSoftBody::get_vertex_attachment_pos
00792 // Access: Published
00793 // Description: Returns the attachment position of the given
00794 // vertex. If the vertex is attached to shape, the
00795 // position local to the shape's pose is returned. If
00796 // the vertex is not attached, the return value is
00797 // undefined.
00798
00799 LPoint3f PhysxSoftBody::
00800 get_vertex_attachment_pos(unsigned int vertexId) const {
00801
00802 nassertr(_error_type == ET_ok, LPoint3f::zero());
00803 // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(), LPoint3f::zero());
00804
00805 return PhysxManager::nxVec3_to_point3(_ptr->getVertexAttachmentPosition(vertexId));
00806 }
00807
00808
00809 // Function: PhysxSoftBody::set_external_acceleration
00810 // Access: Published
00811 // Description: Sets an external acceleration which affects all non
00812 // attached particles of the cloth.
00813
00814 void PhysxSoftBody::
00815 set_external_acceleration(LVector3f const &acceleration) {
00816
00817 nassertv(_error_type == ET_ok);
00818 nassertv_always(!acceleration.is_nan());
00819
00820 _ptr->setExternalAcceleration(PhysxManager::vec3_to_nxVec3(acceleration));
00821 }
00822
00823
00824 // Function: PhysxSoftBody::set_wind_acceleration
00825 // Access: Published
00826 // Description: Sets an acceleration acting normal to the cloth
00827 // surface at each vertex.
00828
00829 void PhysxSoftBody::
00830 set_wind_acceleration(LVector3f const &acceleration) {
00831
00832 nassertv(_error_type == ET_ok);
00833 nassertv_always(!acceleration.is_nan());
00834
00835 _ptr->setWindAcceleration(PhysxManager::vec3_to_nxVec3(acceleration));
00836 }
00837
00838
00839 // Function: PhysxSoftBody::get_external_acceleration
00840 // Access: Published
00841 // Description: Retrieves the external acceleration which affects
00842 // all non attached particles of the cloth.
00843
00844 LVector3f PhysxSoftBody::
00845 get_external_acceleration() const {
00846
00847 nassertr(_error_type == ET_ok, LVector3f::zero());
00848 return PhysxManager::nxVec3_to_vec3(_ptr->getExternalAcceleration());
00849 }
00850
00851
00852 // Function: PhysxSoftBody::get_wind_acceleration
00853 // Access: Published
00854 // Description: Retrieves the acceleration acting normal to the
00855 // cloth surface at each vertex
00856
00857 LVector3f PhysxSoftBody::
00858 get_wind_acceleration() const {
00859
00860 nassertr(_error_type == ET_ok, LVector3f::zero());
00861 return PhysxManager::nxVec3_to_vec3(_ptr->getWindAcceleration());
00862 }
00863
00864
00865 // Function: PhysxSoftBody::add_force_at_vertex
00866 // Access: Published
00867 // Description: Applies a force (or impulse) defined in the
00868 // global coordinate frame, to a particular vertex
00869 // of the cloth.
00870
00871 void PhysxSoftBody::
00872 add_force_at_vertex(LVector3f const &force, int vertexId, PhysxForceMode mode) {
00873
00874 nassertv(_error_type == ET_ok);
00875 _ptr->addForceAtVertex(PhysxManager::vec3_to_nxVec3(force),
00876 vertexId,
00877 (NxForceMode) mode);
00878 }
00879
00880
00881 // Function: PhysxSoftBody::add_force_at_pos
00882 // Access: Published
00883 // Description: Applies a radial force (or impulse) at a
00884 // particular position. All vertices within radius
00885 // will be affected with a quadratic drop-off.
00886
00887 void PhysxSoftBody::
00888 add_force_at_pos(LPoint3f const &pos, float magnitude, float radius, PhysxForceMode mode) {
00889
00890 nassertv(_error_type == ET_ok);
00891 _ptr->addForceAtPos(PhysxManager::point3_to_nxVec3(pos),
00892 magnitude,
00893 radius,
00894 (NxForceMode) mode);
00895 }
00896
00897
00898 // Function: PhysxSoftBody::add_directed_force_at_pos
00899 // Access: Published
00900 // Description: Applies a directed force (or impulse) at a
00901 // particular position. All vertices within radius
00902 // will be affected with a quadratic drop-off.
00903
00904 void PhysxSoftBody::
00905 add_directed_force_at_pos(LPoint3f const &pos, LVector3f const &force, float radius, PhysxForceMode mode) {
00906
00907 nassertv(_error_type == ET_ok);
00908 _ptr->addDirectedForceAtPos(PhysxManager::point3_to_nxVec3(pos),
00909 PhysxManager::vec3_to_nxVec3(force),
00910 radius,
00911 (NxForceMode) mode);
00912 }
00913 */
00914