Panda3D
Loading...
Searching...
No Matches
physxSoftBody.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file physxSoftBody.cxx
10 * @author enn0x
11 * @date 2010-09-13
12 */
13
14#include "physxSoftBody.h"
15#include "physxSoftBodyDesc.h"
16#include "physxSoftBodyNode.h"
17#include "physxScene.h"
18#include "physxGroupsMask.h"
19
20#include "boundingBox.h"
21
22TypeHandle PhysxSoftBody::_type_handle;
23
24/**
25 *
26 */
27void PhysxSoftBody::
28link(NxSoftBody *softbodyPtr) {
29
30 // Link self
31 _ptr = softbodyPtr;
32 _error_type = ET_ok;
33 _ptr->userData = this;
34
35 set_name(softbodyPtr->getName());
36
37 PhysxScene *scene = (PhysxScene *)_ptr->getScene().userData;
38 scene->_softbodies.add(this);
39}
40
41/**
42 *
43 */
44void PhysxSoftBody::
45unlink() {
46
47 // Unlink self
48 _ptr->userData = nullptr;
49 _error_type = ET_released;
50
51 PhysxScene *scene = (PhysxScene *)_ptr->getScene().userData;
52 scene->_softbodies.remove(this);
53
54 _node = nullptr;
55}
56
57/**
58 *
59 */
60void PhysxSoftBody::
61release() {
62
63 nassertv(_error_type == ET_ok);
64
65 unlink();
66 _ptr->getScene().releaseSoftBody(*_ptr);
67 _ptr = nullptr;
68}
69
70/**
71 *
72 */
73void PhysxSoftBody::
74update() {
75
76 if (_node) {
77
78 // Update node mesh data
79 _node->update();
80
81 // Update node bounding volume
82 NxBounds3 bounds;
83 _ptr->getWorldBounds(bounds);
84
87 _node->set_bounds(&bb);
88 }
89}
90
91/**
92 * Returns the scene which this soft body belongs to.
93 */
95get_scene() const {
96
97 nassertr(_error_type == ET_ok, nullptr);
98 return (PhysxScene *)_ptr->getScene().userData;
99}
100
101/**
102 *
103 */
104PhysxSoftBodyNode *PhysxSoftBody::
105get_soft_body_node() const {
106
107 nassertr(_error_type == ET_ok, nullptr);
108 return _node;
109}
110
111/**
112 *
113 */
114PhysxSoftBodyNode *PhysxSoftBody::
115create_soft_body_node(const char *name) {
116
117 nassertr(_error_type == ET_ok, nullptr);
118
119 _node = new PhysxSoftBodyNode(name);
120 _node->allocate(this);
121
122 return _node;
123}
124
125/**
126 * Sets a name string for the object that can be retrieved with get_name().
127 * This is for debugging and is not used by the engine.
128 */
130set_name(const char *name) {
131
132 nassertv(_error_type == ET_ok);
133
134 _name = name ? name : "";
135 _ptr->setName(_name.c_str());
136}
137
138/**
139 * Retrieves the name string.
140 */
142get_name() const {
143
144 nassertr(_error_type == ET_ok, "");
145 return _ptr->getName();
146}
147
148/**
149 * Sets which collision group this soft body is part of. Collision group must
150 * be between 0 and 31.
151 */
153set_group(unsigned int group) {
154
155 nassertv(_error_type == ET_ok);
156 nassertv(group >= 0 && group < 32);
157 _ptr->setGroup(group);
158}
159
160/**
161 * Retrieves the collision group this soft body is part of.
162 */
163unsigned int PhysxSoftBody::
164get_group() const {
165
166 nassertr(_error_type == ET_ok, 0);
167 return _ptr->getGroup();
168}
169
170/**
171 * Sets 128-bit mask used for collision filtering.
172 */
174set_groups_mask(const PhysxGroupsMask &mask) {
175
176 nassertv(_error_type == ET_ok);
177
178 NxGroupsMask _mask = mask.get_mask();
179 _ptr->setGroupsMask(_mask);
180}
181
182/**
183 * Gets the 128-bit groups mask used for collision filtering.
184 */
186get_groups_mask() const {
187
188 PhysxGroupsMask mask;
189
190 nassertr(_error_type == ET_ok, mask);
191
192 NxGroupsMask _mask = _ptr->getGroupsMask();
193 mask.set_mask(_mask);
194
195 return mask;
196}
197
198/**
199 * Gets the number of cloth particles.
200 */
201unsigned int PhysxSoftBody::
203
204 nassertr(_error_type == ET_ok, 0);
205 return _ptr->getNumberOfParticles();
206}
207
208/**
209 * Sets the soft body particle radius (must be positive).
210 */
212set_particle_radius(float radius) {
213
214 nassertv(_error_type == ET_ok);
215 _ptr->setParticleRadius(radius);
216}
217
218/**
219 * Gets the soft body particle radius.
220 */
222get_particle_radius() const {
223
224 nassertr(_error_type == ET_ok, 0.0f);
225 return _ptr->getParticleRadius();
226}
227
228/**
229 * Sets the value of a single flag.
230 */
232set_flag(PhysxSoftBodyFlag flag, bool value) {
233
234 nassertv(_error_type == ET_ok);
235
236 NxU32 flags = _ptr->getFlags();
237
238 if (value == true) {
239 flags |= flag;
240 }
241 else {
242 flags &= ~(flag);
243 }
244
245 _ptr->setFlags(flags);
246}
247
248/**
249 * Retrieves the value of a single flag.
250 */
252get_flag(PhysxSoftBodyFlag flag) const {
253
254 nassertr(_error_type == ET_ok, false);
255
256 return (_ptr->getFlags() & flag) ? true : false;
257}
258
259/**
260 * Gets the soft body density.
261 */
263get_density() const {
264
265 nassertr(_error_type == ET_ok, 0.0f);
266 return _ptr->getDensity();
267}
268
269/**
270 * Gets the relative grid spacing for the broad phase. The cloth is
271 * represented by a set of world aligned cubical cells in broad phase. The
272 * size of these cells is determined by multiplying the length of the diagonal
273 * of the AABB of the initial soft body size with this constant.
274 */
277
278 nassertr(_error_type == ET_ok, 0.0f);
279 return _ptr->getRelativeGridSpacing();
280}
281
282/**
283 * Sets the soft body volume stiffness in the range from 0 to 1.
284 */
286set_volume_stiffness(float stiffness) {
287
288 nassertv(_error_type == ET_ok);
289 ptr()->setVolumeStiffness(stiffness);
290}
291
292/**
293 * Retrieves the soft body volume stiffness.
294 */
296get_volume_stiffness() const {
297
298 nassertr(_error_type == ET_ok, 0.0f);
299 return ptr()->getVolumeStiffness();
300}
301
302/**
303 * Sets the soft body stretching stiffness in the range from 0 to 1.
304 */
306set_stretching_stiffness(float stiffness) {
307
308 nassertv(_error_type == ET_ok);
309 ptr()->setStretchingStiffness(stiffness);
310}
311
312/**
313 * Retrieves the soft body stretching stiffness.
314 */
317
318 nassertr(_error_type == ET_ok, 0.0f);
319 return ptr()->getStretchingStiffness();
320}
321
322/**
323 * Sets the damping coefficient in the range from 0 to 1.
324 */
326set_damping_coefficient(float coef) {
327
328 nassertv(_error_type == ET_ok);
329 ptr()->setDampingCoefficient(coef);
330}
331
332/**
333 * Retrieves the damping coefficient.
334 */
337
338 nassertr(_error_type == ET_ok, 0.0f);
339 return ptr()->getDampingCoefficient();
340}
341
342/**
343 * Sets the soft body friction coefficient in the range from 0 to 1.
344 */
346set_friction(float friction) {
347
348 nassertv(_error_type == ET_ok);
349 ptr()->setFriction(friction);
350}
351
352/**
353 * Retrieves the soft body friction coefficient.
354 */
356get_friction() const {
357
358 nassertr(_error_type == ET_ok, 0.0f);
359 return ptr()->getFriction();
360}
361
362/**
363 * Sets the soft body tear factor (must be larger than one).
364 */
366set_tear_factor(float factor) {
367
368 nassertv(_error_type == ET_ok);
369 nassertv(factor > 1.0f);
370 ptr()->setTearFactor(factor);
371}
372
373/**
374 * Retrieves the soft body tear factor.
375 */
377get_tear_factor() const {
378
379 nassertr(_error_type == ET_ok, 0.0f);
380 return ptr()->getTearFactor();
381}
382
383/**
384 * Sets the soft body attachment tear factor (must be larger than one).
385 */
387set_attachment_tear_factor(float factor) {
388
389 nassertv(_error_type == ET_ok);
390 nassertv(factor > 1.0f);
391 ptr()->setAttachmentTearFactor(factor);
392}
393
394/**
395 * Retrieves the attachment soft body tear factor.
396 */
399
400 nassertr(_error_type == ET_ok, 0.0f);
401 return ptr()->getAttachmentTearFactor();
402}
403
404/**
405 * Sets the soft body solver iterations.
406 */
408set_solver_iterations(unsigned int iterations) {
409
410 nassertv(_error_type == ET_ok);
411 ptr()->setSolverIterations(iterations);
412}
413
414/**
415 * Retrieves the soft body solver iterations.
416 */
417unsigned int PhysxSoftBody::
418get_solver_iterations() const {
419
420 nassertr(_error_type == ET_ok, 0);
421 return ptr()->getSolverIterations();
422}
423
424/**
425 * Returns true if this soft body is sleeping.
426 *
427 * When a soft body does not move for a period of time, it is no longer
428 * simulated in order to save time. This state is called sleeping. However,
429 * because the object automatically wakes up when it is either touched by an
430 * awake object, or one of its properties is changed by the user, the entire
431 * sleep mechanism should be transparent to the user.
432 */
434is_sleeping() const {
435
436 nassertr(_error_type == ET_ok, false);
437 return _ptr->isSleeping();
438}
439
440/**
441 * Wakes up the soft body if it is sleeping.
442 *
443 * The wakeCounterValue determines how long until the body is put to sleep, a
444 * value of zero means that the body is sleeping. wake_up(0) is equivalent to
445 * PhysxSoftBody::put_to_sleep().
446 */
448wake_up(float wakeCounterValue) {
449
450 nassertv(_error_type == ET_ok);
451 _ptr->wakeUp(wakeCounterValue);
452}
453
454/**
455 * Forces the soft body to sleep.
456 *
457 * The soft body will stay asleep until the next call to simulate, and will
458 * not wake up until then even when otherwise it would (for example a force is
459 * applied to it). It can however wake up during the next do_physics call.
460 */
462put_to_sleep() {
463
464 nassertv(_error_type == ET_ok);
465 _ptr->putToSleep();
466}
467
468/**
469 * Sets the linear velocity below which an soft body may go to sleep.
470 * SoftBodys whose linear velocity is above this threshold will not be put to
471 * sleep.
472 *
473 * Setting the sleep angular/linear velocity only makes sense when the
474 * BF_energy_sleep_test is not set.
475 */
477set_sleep_linear_velocity(float threshold) {
478
479 nassertv(_error_type == ET_ok);
480 _ptr->setSleepLinearVelocity(threshold);
481}
482
483/**
484 * Returns the linear velocity below which an soft body may go to sleep. Soft
485 * bodies whose linear velocity is above this threshold will not be put to
486 * sleep.
487 */
490
491 nassertr(_error_type == ET_ok, 0.0f);
492 return _ptr->getSleepLinearVelocity();
493}
494
495#if NX_SDK_VERSION_NUMBER > 281
496/**
497 * Sets the soft body self collision thickness (must be positive).
498 */
499void PhysxSoftBody::
500set_self_collision_thickness(float thickness) {
501
502 nassertv(_error_type == ET_ok);
503 _ptr->setSelfCollisionThickness(thickness);
504}
505
506/**
507 * Gets the soft body self collision thickness.
508 */
509float PhysxSoftBody::
510get_self_collision_thickness() const {
511
512 nassertr(_error_type == ET_ok, 0.0f);
513 return _ptr->getSelfCollisionThickness();
514}
515
516/**
517 * Sets the soft body hard stretch elongation limit.
518 */
519void PhysxSoftBody::
520set_hard_stretch_limitation_factor(float factor) {
521
522 nassertv(_error_type == ET_ok);
523 ptr()->setHardStretchLimitationFactor(factor);
524}
525
526/**
527 * Retrieves the soft body hard stretch elongation limit.
528 */
529float PhysxSoftBody::
530get_hard_stretch_limitation_factor() const {
531
532 nassertr(_error_type == ET_ok, 0.0f);
533 return ptr()->getHardStretchLimitationFactor();
534}
535#endif // NX_SDK_VERSION_NUMBER > 281
536
537
538/**
539 * Attaches a cloth vertex to a position in world space.
540 */
541/*
542void PhysxSoftBody::
543attach_vertex_to_global_pos(unsigned int vertexId, LPoint3f const &pos) {
544
545 nassertv(_error_type == ET_ok);
546 nassertv(!pos.is_nan());
547
548 _ptr->attachVertexToGlobalPosition(vertexId, PhysxManager::point3_to_nxVec3(pos));
549}
550*/
551
552/**
553 * Attaches the cloth to a shape. All cloth points currently inside the shape
554 * are attached.
555 *
556 * This method only works with primitive and convex shapes. Since the inside
557 * of a general triangle mesh is not clearly defined.
558 */
559/*
560void PhysxSoftBody::
561attach_to_shape(PhysxShape *shape) {
562
563 nassertv(_error_type == ET_ok);
564 nassertv(shape);
565
566 NxU32 attachmentFlags = 0; // --TODO--
567 _ptr->attachToShape(shape->ptr(), attachmentFlags);
568}
569*/
570
571/**
572 * Attaches the cloth to all shapes, currently colliding.
573 *
574 * This method only works with primitive and convex shapes. Since the inside
575 * of a general triangle mesh is not clearly defined.
576 */
577/*
578void PhysxSoftBody::
579attach_to_colliding_shapes() {
580
581 nassertv(_error_type == ET_ok);
582
583 NxU32 attachmentFlags = 0; // --TODO--
584 _ptr->attachToCollidingShapes(attachmentFlags);
585}
586*/
587
588/**
589 * Detaches the cloth from a shape it has been attached to before.
590 *
591 * If the cloth has not been attached to the shape before, the call has no
592 * effect.
593 */
594/*
595void PhysxSoftBody::
596detach_from_shape(PhysxShape *shape) {
597
598 nassertv(_error_type == ET_ok);
599 nassertv(shape);
600
601 _ptr->detachFromShape(shape->ptr());
602}
603*/
604
605/**
606 * Frees a previously attached cloth point.
607 */
608/*
609void PhysxSoftBody::
610free_vertex(unsigned int vertexId) {
611
612 nassertv(_error_type == ET_ok);
613 _ptr->freeVertex(vertexId);
614}
615*/
616
617/**
618 * Attaches a cloth vertex to a local position within a shape.
619 */
620/*
621void PhysxSoftBody::
622attach_vertex_to_shape(unsigned int vertexId, PhysxShape *shape, LPoint3f const &localPos) {
623
624 nassertv(_error_type == ET_ok);
625 nassertv(!localPos.is_nan());
626 nassertv(shape);
627
628 NxU32 attachmentFlags = 0; // --TODO--
629 _ptr->attachVertexToShape(vertexId, shape->ptr(),
630 PhysxManager::point3_to_nxVec3(localPos),
631 attachmentFlags);
632}
633*/
634
635/**
636 * Return the attachment status of the given vertex.
637 */
638/*
639PhysxEnums::PhysxVertexAttachmentStatus PhysxSoftBody::
640get_vertex_attachment_status(unsigned int vertexId) const {
641
642 nassertr(_error_type == ET_ok, VAS_none);
643 // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(), VAS_none);
644
645 return (PhysxVertexAttachmentStatus) _ptr->getVertexAttachmentStatus(vertexId);
646}
647*/
648
649/**
650 * Returns the pointer to an attached shape pointer of the given vertex. If
651 * the vertex is not attached or attached to a global position, NULL is
652 * returned.
653 */
654/*
655PhysxShape *PhysxSoftBody::
656get_vertex_attachment_shape(unsigned int vertexId) const {
657
658 nassertr(_error_type == ET_ok, NULL);
659 // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(), NULL);
660
661 NxShape *shapePtr = _ptr->getVertexAttachmentShape(vertexId);
662 PhysxShape *shape = shapePtr ? (PhysxShape *)(shapePtr->userData) : NULL;
663
664 return shape;
665}
666*/
667
668/**
669 * Returns the attachment position of the given vertex. If the vertex is
670 * attached to shape, the position local to the shape's pose is returned. If
671 * the vertex is not attached, the return value is undefined.
672 */
673/*
674LPoint3f PhysxSoftBody::
675get_vertex_attachment_pos(unsigned int vertexId) const {
676
677 nassertr(_error_type == ET_ok, LPoint3f::zero());
678 // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(),
679 // LPoint3f::zero());
680
681 return PhysxManager::nxVec3_to_point3(_ptr->getVertexAttachmentPosition(vertexId));
682}
683*/
684
685/**
686 * Sets an external acceleration which affects all non attached particles of
687 * the cloth.
688 */
689/*
690void PhysxSoftBody::
691set_external_acceleration(LVector3f const &acceleration) {
692
693 nassertv(_error_type == ET_ok);
694 nassertv_always(!acceleration.is_nan());
695
696 _ptr->setExternalAcceleration(PhysxManager::vec3_to_nxVec3(acceleration));
697}
698*/
699
700/**
701 * Sets an acceleration acting normal to the cloth surface at each vertex.
702 */
703/*
704void PhysxSoftBody::
705set_wind_acceleration(LVector3f const &acceleration) {
706
707 nassertv(_error_type == ET_ok);
708 nassertv_always(!acceleration.is_nan());
709
710 _ptr->setWindAcceleration(PhysxManager::vec3_to_nxVec3(acceleration));
711}
712*/
713
714/**
715 * Retrieves the external acceleration which affects all non attached
716 * particles of the cloth.
717 */
718/*
719LVector3f PhysxSoftBody::
720get_external_acceleration() const {
721
722 nassertr(_error_type == ET_ok, LVector3f::zero());
723 return PhysxManager::nxVec3_to_vec3(_ptr->getExternalAcceleration());
724}
725*/
726
727/**
728 * Retrieves the acceleration acting normal to the cloth surface at each
729 * vertex
730 */
731/*
732LVector3f PhysxSoftBody::
733get_wind_acceleration() const {
734
735 nassertr(_error_type == ET_ok, LVector3f::zero());
736 return PhysxManager::nxVec3_to_vec3(_ptr->getWindAcceleration());
737}
738*/
739
740/**
741 * Applies a force (or impulse) defined in the global coordinate frame, to a
742 * particular vertex of the cloth.
743 */
744/*
745void PhysxSoftBody::
746add_force_at_vertex(LVector3f const &force, int vertexId, PhysxForceMode mode) {
747
748 nassertv(_error_type == ET_ok);
749 _ptr->addForceAtVertex(PhysxManager::vec3_to_nxVec3(force),
750 vertexId,
751 (NxForceMode) mode);
752}
753*/
754
755/**
756 * Applies a radial force (or impulse) at a particular position. All vertices
757 * within radius will be affected with a quadratic drop-off.
758 */
759/*
760void PhysxSoftBody::
761add_force_at_pos(LPoint3f const &pos, float magnitude, float radius, PhysxForceMode mode) {
762
763 nassertv(_error_type == ET_ok);
764 _ptr->addForceAtPos(PhysxManager::point3_to_nxVec3(pos),
765 magnitude,
766 radius,
767 (NxForceMode) mode);
768}
769*/
770
771/**
772 * Applies a directed force (or impulse) at a particular position. All
773 * vertices within radius will be affected with a quadratic drop-off.
774 */
775/*
776void PhysxSoftBody::
777add_directed_force_at_pos(LPoint3f const &pos, LVector3f const &force, float radius, PhysxForceMode mode) {
778
779 nassertv(_error_type == ET_ok);
780 _ptr->addDirectedForceAtPos(PhysxManager::point3_to_nxVec3(pos),
781 PhysxManager::vec3_to_nxVec3(force),
782 radius,
783 (NxForceMode) mode);
784}
785*/
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An axis-aligned bounding box; that is, a minimum and maximum coordinate triple.
Definition boundingBox.h:29
128-bit bitmask class.
static LPoint3f nxVec3_to_point3(const NxVec3 &p)
Converts from NxVec3 to LPoint3f.
A scene is a collection of bodies, constraints, and effectors which can interact.
Definition physxScene.h:69
Renderable geometry which represents a soft body mesh.
unsigned int get_group() const
Retrieves the collision group this soft body is part of.
float get_particle_radius() const
Gets the soft body particle radius.
float get_attachment_tear_factor() const
Retrieves the attachment soft body tear factor.
float get_stretching_stiffness() const
Retrieves the soft body stretching stiffness.
const char * get_name() const
Retrieves the name string.
void set_particle_radius(float radius)
Sets the soft body particle radius (must be positive).
bool is_sleeping() const
Returns true if this soft body is sleeping.
unsigned int get_solver_iterations() const
Retrieves the soft body solver iterations.
void set_attachment_tear_factor(float factor)
Sets the soft body attachment tear factor (must be larger than one).
float get_friction() const
Retrieves the soft body friction coefficient.
void wake_up(float wakeCounterValue=NX_SLEEP_INTERVAL)
Wakes up the soft body if it is sleeping.
unsigned int get_num_particles()
Gets the number of cloth particles.
void set_tear_factor(float factor)
Sets the soft body tear factor (must be larger than one).
float get_volume_stiffness() const
Retrieves the soft body volume stiffness.
float get_relative_grid_spacing() const
Gets the relative grid spacing for the broad phase.
float get_tear_factor() const
Retrieves the soft body tear factor.
void set_flag(PhysxSoftBodyFlag flag, bool value)
Sets the value of a single flag.
void set_groups_mask(const PhysxGroupsMask &mask)
Sets 128-bit mask used for collision filtering.
void set_friction(float friction)
Sets the soft body friction coefficient in the range from 0 to 1.
PhysxGroupsMask get_groups_mask() const
Gets the 128-bit groups mask used for collision filtering.
void put_to_sleep()
Forces the soft body to sleep.
void set_sleep_linear_velocity(float threshold)
Sets the linear velocity below which an soft body may go to sleep.
PhysxScene * get_scene() const
Returns the scene which this soft body belongs to.
void set_group(unsigned int group)
Sets which collision group this soft body is part of.
float get_density() const
Gets the soft body density.
bool get_flag(PhysxSoftBodyFlag flag) const
Retrieves the value of a single flag.
float get_sleep_linear_velocity() const
Returns the linear velocity below which an soft body may go to sleep.
void set_volume_stiffness(float stiffness)
Sets the soft body volume stiffness in the range from 0 to 1.
void set_damping_coefficient(float coef)
Sets the damping coefficient in the range from 0 to 1.
float get_damping_coefficient() const
Retrieves the damping coefficient.
void set_stretching_stiffness(float stiffness)
Sets the soft body stretching stiffness in the range from 0 to 1.
void set_solver_iterations(unsigned int iterations)
Sets the soft body solver iterations.
void set_name(const char *name)
Sets a name string for the object that can be retrieved with get_name().
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.