Panda3D
physxCloth.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 physxCloth.cxx
10  * @author enn0x
11  * @date 2010-03-30
12  */
13 
14 #include "physxCloth.h"
15 #include "physxClothDesc.h"
16 #include "physxScene.h"
17 #include "physxGroupsMask.h"
18 #include "physxShape.h"
19 #include "physxManager.h"
20 
21 #include "boundingBox.h"
22 
23 TypeHandle PhysxCloth::_type_handle;
24 
25 /**
26  *
27  */
28 void PhysxCloth::
29 link(NxCloth *clothPtr) {
30 
31  // Link self
32  _ptr = clothPtr;
33  _error_type = ET_ok;
34  _ptr->userData = this;
35 
36  set_name(clothPtr->getName());
37 
38  PhysxScene *scene = (PhysxScene *)_ptr->getScene().userData;
39  scene->_cloths.add(this);
40 }
41 
42 /**
43  *
44  */
45 void PhysxCloth::
46 unlink() {
47 
48  // Unlink self
49  _ptr->userData = nullptr;
50  _error_type = ET_released;
51 
52  PhysxScene *scene = (PhysxScene *)_ptr->getScene().userData;
53  scene->_cloths.remove(this);
54 
55  _node = nullptr;
56 }
57 
58 /**
59  *
60  */
61 void PhysxCloth::
62 release() {
63 
64  nassertv(_error_type == ET_ok);
65 
66  unlink();
67  _ptr->getScene().releaseCloth(*_ptr);
68  _ptr = nullptr;
69 }
70 
71 /**
72  *
73  */
74 void PhysxCloth::
75 update() {
76 
77  if (_node) {
78 
79  // Update node mesh data
80  _node->update();
81 
82  // Update node bounding volume
83  NxBounds3 bounds;
84  _ptr->getWorldBounds(bounds);
85 
87  PhysxManager::nxVec3_to_point3(bounds.max));
88  _node->set_bounds(&bb);
89  }
90 }
91 
92 /**
93  * Returns the scene which this cloth belongs to.
94  */
96 get_scene() const {
97 
98  nassertr(_error_type == ET_ok, nullptr);
99  return (PhysxScene *)_ptr->getScene().userData;
100 }
101 
102 /**
103  *
104  */
105 PhysxClothNode *PhysxCloth::
106 get_cloth_node() const {
107 
108  nassertr(_error_type == ET_ok, nullptr);
109  return _node;
110 }
111 
112 /**
113  *
114  */
115 PhysxClothNode *PhysxCloth::
116 create_cloth_node(const char *name) {
117 
118  nassertr(_error_type == ET_ok, nullptr);
119 
120  _node = new PhysxClothNode(name);
121  _node->allocate(this);
122 
123  return _node;
124 }
125 
126 /**
127  * Sets a name string for the object that can be retrieved with get_name().
128  * This is for debugging and is not used by the engine.
129  */
131 set_name(const char *name) {
132 
133  nassertv(_error_type == ET_ok);
134 
135  _name = name ? name : "";
136  _ptr->setName(_name.c_str());
137 }
138 
139 /**
140  * Retrieves the name string.
141  */
142 const char *PhysxCloth::
143 get_name() const {
144 
145  nassertr(_error_type == ET_ok, "");
146  return _ptr->getName();
147 }
148 
149 /**
150  * Sets which collision group this cloth is part of. Collision group must be
151  * between 0 and 31.
152  */
154 set_group(unsigned int group) {
155 
156  nassertv(_error_type == ET_ok);
157  nassertv(group >= 0 && group < 32);
158  _ptr->setGroup(group);
159 }
160 
161 /**
162  * Retrieves the collision group this cloth is part of.
163  */
164 unsigned int PhysxCloth::
165 get_group() const {
166 
167  nassertr(_error_type == ET_ok, 0);
168  return _ptr->getGroup();
169 }
170 
171 /**
172  * Sets the cloth thickness (must be positive).
173  */
175 set_thickness(float thickness) {
176 
177  nassertv(_error_type == ET_ok);
178  _ptr->setThickness(thickness);
179 }
180 
181 /**
182  * Gets the cloth thickness.
183  */
185 get_thickness() const {
186 
187  nassertr(_error_type == ET_ok, 0.0f);
188  return _ptr->getThickness();
189 }
190 
191 /**
192  * Gets the cloth density.
193  */
195 get_density() const {
196 
197  nassertr(_error_type == ET_ok, 0.0f);
198  return _ptr->getDensity();
199 }
200 
201 /**
202  * Gets the relative grid spacing for the broad phase. The cloth is
203  * represented by a set of world aligned cubical cells in broad phase. The
204  * size of these cells is determined by multiplying the length of the diagonal
205  * of the AABB of the initial soft body size with this constant.
206  */
209 
210  nassertr(_error_type == ET_ok, 0.0f);
211  return _ptr->getRelativeGridSpacing();
212 }
213 
214 /**
215  * Gets the number of cloth particles.
216  */
217 unsigned int PhysxCloth::
219 
220  nassertr(_error_type == ET_ok, 0);
221  return _ptr->getNumberOfParticles();
222 }
223 
224 /**
225  * Sets the value of a single flag.
226  */
228 set_flag(PhysxClothFlag flag, bool value) {
229 
230  nassertv(_error_type == ET_ok);
231 
232  NxU32 flags = _ptr->getFlags();
233 
234  if (value == true) {
235  flags |= flag;
236  }
237  else {
238  flags &= ~(flag);
239  }
240 
241  _ptr->setFlags(flags);
242 }
243 
244 /**
245  * Retrieves the value of a single flag.
246  */
248 get_flag(PhysxClothFlag flag) const {
249 
250  nassertr(_error_type == ET_ok, false);
251 
252  return (_ptr->getFlags() & flag) ? true : false;
253 }
254 
255 /**
256  * Sets 128-bit mask used for collision filtering.
257  */
259 set_groups_mask(const PhysxGroupsMask &mask) {
260 
261  nassertv(_error_type == ET_ok);
262 
263  NxGroupsMask _mask = mask.get_mask();
264  _ptr->setGroupsMask(_mask);
265 }
266 
267 /**
268  * Gets the 128-bit groups mask used for collision filtering.
269  */
271 get_groups_mask() const {
272 
273  PhysxGroupsMask mask;
274 
275  nassertr(_error_type == ET_ok, mask);
276 
277  NxGroupsMask _mask = _ptr->getGroupsMask();
278  mask.set_mask(_mask);
279 
280  return mask;
281 }
282 
283 /**
284  * Returns true if this cloth is sleeping.
285  *
286  * When a cloth does not move for a period of time, it is no longer simulated
287  * in order to save time. This state is called sleeping. However, because
288  * the object automatically wakes up when it is either touched by an awake
289  * object, or one of its properties is changed by the user, the entire sleep
290  * mechanism should be transparent to the user.
291  */
293 is_sleeping() const {
294 
295  nassertr(_error_type == ET_ok, false);
296  return _ptr->isSleeping();
297 }
298 
299 /**
300  * Wakes up the cloth if it is sleeping.
301  *
302  * The wakeCounterValue determines how long until the body is put to sleep, a
303  * value of zero means that the body is sleeping. wake_up(0) is equivalent to
304  * PhysxCloth::put_to_sleep().
305  */
307 wake_up(float wakeCounterValue) {
308 
309  nassertv(_error_type == ET_ok);
310  _ptr->wakeUp(wakeCounterValue);
311 }
312 
313 /**
314  * Forces the cloth to sleep.
315  *
316  * The cloth will stay asleep until the next call to simulate, and will not
317  * wake up until then even when otherwise it would (for example a force is
318  * applied to it). It can however wake up during the next do_physics call.
319  */
321 put_to_sleep() {
322 
323  nassertv(_error_type == ET_ok);
324  _ptr->putToSleep();
325 }
326 
327 /**
328  * Sets the linear velocity below which an cloth may go to sleep. Cloths
329  * whose linear velocity is above this threshold will not be put to sleep.
330  *
331  * Setting the sleep angular/linear velocity only makes sense when the
332  * BF_energy_sleep_test is not set.
333  */
335 set_sleep_linear_velocity(float threshold) {
336 
337  nassertv(_error_type == ET_ok);
338  _ptr->setSleepLinearVelocity(threshold);
339 }
340 
341 /**
342  * Returns the linear velocity below which an soft body may go to sleep.
343  * cloths whose linear velocity is above this threshold will not be put to
344  * sleep.
345  */
348 
349  nassertr(_error_type == ET_ok, 0.0f);
350  return _ptr->getSleepLinearVelocity();
351 }
352 
353 /**
354  * Attaches a cloth vertex to a position in world space.
355  */
357 attach_vertex_to_global_pos(unsigned int vertexId, LPoint3f const &pos) {
358 
359  nassertv(_error_type == ET_ok);
360  nassertv(!pos.is_nan());
361 
362  _ptr->attachVertexToGlobalPosition(vertexId, PhysxManager::point3_to_nxVec3(pos));
363 }
364 
365 /**
366  * Attaches the cloth to a shape. All cloth points currently inside the shape
367  * are attached.
368  *
369  * This method only works with primitive and convex shapes. Since the inside
370  * of a general triangle mesh is not clearly defined.
371  */
373 attach_to_shape(PhysxShape *shape) {
374 
375  nassertv(_error_type == ET_ok);
376  nassertv(shape);
377 
378  NxU32 attachmentFlags = 0; // --TODO--
379  _ptr->attachToShape(shape->ptr(), attachmentFlags);
380 }
381 
382 /**
383  * Attaches the cloth to all shapes, currently colliding.
384  *
385  * This method only works with primitive and convex shapes. Since the inside
386  * of a general triangle mesh is not clearly defined.
387  */
390 
391  nassertv(_error_type == ET_ok);
392 
393  NxU32 attachmentFlags = 0; // --TODO--
394  _ptr->attachToCollidingShapes(attachmentFlags);
395 }
396 
397 /**
398  * Detaches the cloth from a shape it has been attached to before.
399  *
400  * If the cloth has not been attached to the shape before, the call has no
401  * effect.
402  */
405 
406  nassertv(_error_type == ET_ok);
407  nassertv(shape);
408 
409  _ptr->detachFromShape(shape->ptr());
410 }
411 
412 /**
413  * Frees a previously attached cloth point.
414  */
416 free_vertex(unsigned int vertexId) {
417 
418  nassertv(_error_type == ET_ok);
419  _ptr->freeVertex(vertexId);
420 }
421 
422 /**
423  * Attaches a cloth vertex to a local position within a shape.
424  */
426 attach_vertex_to_shape(unsigned int vertexId, PhysxShape *shape, LPoint3f const &localPos) {
427 
428  nassertv(_error_type == ET_ok);
429  nassertv(!localPos.is_nan());
430  nassertv(shape);
431 
432  NxU32 attachmentFlags = 0; // --TODO--
433  _ptr->attachVertexToShape(vertexId, shape->ptr(),
435  attachmentFlags);
436 }
437 
438 /**
439  * Return the attachment status of the given vertex.
440  */
441 PhysxEnums::PhysxVertexAttachmentStatus PhysxCloth::
442 get_vertex_attachment_status(unsigned int vertexId) const {
443 
444  nassertr(_error_type == ET_ok, VAS_none);
445  // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(), VAS_none);
446 
447  return (PhysxVertexAttachmentStatus) _ptr->getVertexAttachmentStatus(vertexId);
448 }
449 
450 /**
451  * Returns the pointer to an attached shape pointer of the given vertex. If
452  * the vertex is not attached or attached to a global position, NULL is
453  * returned.
454  */
456 get_vertex_attachment_shape(unsigned int vertexId) const {
457 
458  nassertr(_error_type == ET_ok, nullptr);
459  // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(), NULL);
460 
461  NxShape *shapePtr = _ptr->getVertexAttachmentShape(vertexId);
462  PhysxShape *shape = shapePtr ? (PhysxShape *)(shapePtr->userData) : nullptr;
463 
464  return shape;
465 }
466 
467 /**
468  * Returns the attachment position of the given vertex. If the vertex is
469  * attached to shape, the position local to the shape's pose is returned. If
470  * the vertex is not attached, the return value is undefined.
471  */
472 LPoint3f PhysxCloth::
473 get_vertex_attachment_pos(unsigned int vertexId) const {
474 
475  nassertr(_error_type == ET_ok, LPoint3f::zero());
476  // --TODO-- nassertr(vertexId < _ptr->getNumberOfParticles(),
477  // LPoint3f::zero());
478 
479  return PhysxManager::nxVec3_to_point3(_ptr->getVertexAttachmentPosition(vertexId));
480 }
481 
482 /**
483  * Sets an external acceleration which affects all non attached particles of
484  * the cloth.
485  */
487 set_external_acceleration(LVector3f const &acceleration) {
488 
489  nassertv(_error_type == ET_ok);
490  nassertv_always(!acceleration.is_nan());
491 
492  _ptr->setExternalAcceleration(PhysxManager::vec3_to_nxVec3(acceleration));
493 }
494 
495 /**
496  * Sets an acceleration acting normal to the cloth surface at each vertex.
497  */
499 set_wind_acceleration(LVector3f const &acceleration) {
500 
501  nassertv(_error_type == ET_ok);
502  nassertv_always(!acceleration.is_nan());
503 
504  _ptr->setWindAcceleration(PhysxManager::vec3_to_nxVec3(acceleration));
505 }
506 
507 /**
508  * Retrieves the external acceleration which affects all non attached
509  * particles of the cloth.
510  */
511 LVector3f PhysxCloth::
513 
514  nassertr(_error_type == ET_ok, LVector3f::zero());
515  return PhysxManager::nxVec3_to_vec3(_ptr->getExternalAcceleration());
516 }
517 
518 /**
519  * Retrieves the acceleration acting normal to the cloth surface at each
520  * vertex
521  */
522 LVector3f PhysxCloth::
523 get_wind_acceleration() const {
524 
525  nassertr(_error_type == ET_ok, LVector3f::zero());
526  return PhysxManager::nxVec3_to_vec3(_ptr->getWindAcceleration());
527 }
528 
529 /**
530  * Applies a force (or impulse) defined in the global coordinate frame, to a
531  * particular vertex of the cloth.
532  */
534 add_force_at_vertex(LVector3f const &force, int vertexId, PhysxForceMode mode) {
535 
536  nassertv(_error_type == ET_ok);
537  _ptr->addForceAtVertex(PhysxManager::vec3_to_nxVec3(force),
538  vertexId,
539  (NxForceMode) mode);
540 }
541 
542 /**
543  * Applies a radial force (or impulse) at a particular position. All vertices
544  * within radius will be affected with a quadratic drop-off.
545  */
547 add_force_at_pos(LPoint3f const &pos, float magnitude, float radius, PhysxForceMode mode) {
548 
549  nassertv(_error_type == ET_ok);
550  _ptr->addForceAtPos(PhysxManager::point3_to_nxVec3(pos),
551  magnitude,
552  radius,
553  (NxForceMode) mode);
554 }
555 
556 /**
557  * Applies a directed force (or impulse) at a particular position. All
558  * vertices within radius will be affected with a quadratic drop-off.
559  */
561 add_directed_force_at_pos(LPoint3f const &pos, LVector3f const &force, float radius, PhysxForceMode mode) {
562 
563  nassertv(_error_type == ET_ok);
564  _ptr->addDirectedForceAtPos(PhysxManager::point3_to_nxVec3(pos),
566  radius,
567  (NxForceMode) mode);
568 }
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
Renderable geometry which represents a cloth mesh.
void set_wind_acceleration(LVector3f const &acceleration)
Sets an acceleration acting normal to the cloth surface at each vertex.
Definition: physxCloth.cxx:499
void put_to_sleep()
Forces the cloth to sleep.
Definition: physxCloth.cxx:321
float get_thickness() const
Gets the cloth thickness.
Definition: physxCloth.cxx:185
float get_relative_grid_spacing() const
Gets the relative grid spacing for the broad phase.
Definition: physxCloth.cxx:208
LVector3f get_external_acceleration() const
Retrieves the external acceleration which affects all non attached particles of the cloth.
Definition: physxCloth.cxx:512
void attach_vertex_to_global_pos(unsigned int vertexId, LPoint3f const &pos)
Attaches a cloth vertex to a position in world space.
Definition: physxCloth.cxx:357
LVector3f get_wind_acceleration() const
Retrieves the acceleration acting normal to the cloth surface at each vertex.
Definition: physxCloth.cxx:523
void detach_from_shape(PhysxShape *shape)
Detaches the cloth from a shape it has been attached to before.
Definition: physxCloth.cxx:404
void add_force_at_vertex(LVector3f const &force, int vertexId, PhysxForceMode mode=FM_force)
Applies a force (or impulse) defined in the global coordinate frame, to a particular vertex of the cl...
Definition: physxCloth.cxx:534
void set_group(unsigned int group)
Sets which collision group this cloth is part of.
Definition: physxCloth.cxx:154
void attach_vertex_to_shape(unsigned int vertexId, PhysxShape *shape, LPoint3f const &localPos)
Attaches a cloth vertex to a local position within a shape.
Definition: physxCloth.cxx:426
void add_force_at_pos(LPoint3f const &pos, float magnitude, float radius, PhysxForceMode mode=FM_force)
Applies a radial force (or impulse) at a particular position.
Definition: physxCloth.cxx:547
void add_directed_force_at_pos(LPoint3f const &pos, LVector3f const &force, float radius, PhysxForceMode mode=FM_force)
Applies a directed force (or impulse) at a particular position.
Definition: physxCloth.cxx:561
void set_external_acceleration(LVector3f const &acceleration)
Sets an external acceleration which affects all non attached particles of the cloth.
Definition: physxCloth.cxx:487
void set_sleep_linear_velocity(float threshold)
Sets the linear velocity below which an cloth may go to sleep.
Definition: physxCloth.cxx:335
const char * get_name() const
Retrieves the name string.
Definition: physxCloth.cxx:143
void set_groups_mask(const PhysxGroupsMask &mask)
Sets 128-bit mask used for collision filtering.
Definition: physxCloth.cxx:259
void set_flag(PhysxClothFlag flag, bool value)
Sets the value of a single flag.
Definition: physxCloth.cxx:228
float get_sleep_linear_velocity() const
Returns the linear velocity below which an soft body may go to sleep.
Definition: physxCloth.cxx:347
PhysxVertexAttachmentStatus get_vertex_attachment_status(unsigned int vertexId) const
Return the attachment status of the given vertex.
Definition: physxCloth.cxx:442
unsigned int get_num_particles()
Gets the number of cloth particles.
Definition: physxCloth.cxx:218
void wake_up(float wakeCounterValue=NX_SLEEP_INTERVAL)
Wakes up the cloth if it is sleeping.
Definition: physxCloth.cxx:307
void attach_to_shape(PhysxShape *shape)
Attaches the cloth to a shape.
Definition: physxCloth.cxx:373
LPoint3f get_vertex_attachment_pos(unsigned int vertexId) const
Returns the attachment position of the given vertex.
Definition: physxCloth.cxx:473
float get_density() const
Gets the cloth density.
Definition: physxCloth.cxx:195
void attach_to_colliding_shapes()
Attaches the cloth to all shapes, currently colliding.
Definition: physxCloth.cxx:389
PhysxGroupsMask get_groups_mask() const
Gets the 128-bit groups mask used for collision filtering.
Definition: physxCloth.cxx:271
void set_thickness(float thickness)
Sets the cloth thickness (must be positive).
Definition: physxCloth.cxx:175
bool get_flag(PhysxClothFlag flag) const
Retrieves the value of a single flag.
Definition: physxCloth.cxx:248
PhysxShape * get_vertex_attachment_shape(unsigned int vertexId) const
Returns the pointer to an attached shape pointer of the given vertex.
Definition: physxCloth.cxx:456
unsigned int get_group() const
Retrieves the collision group this cloth is part of.
Definition: physxCloth.cxx:165
void set_name(const char *name)
Sets a name string for the object that can be retrieved with get_name().
Definition: physxCloth.cxx:131
bool is_sleeping() const
Returns true if this cloth is sleeping.
Definition: physxCloth.cxx:293
PhysxScene * get_scene() const
Returns the scene which this cloth belongs to.
Definition: physxCloth.cxx:96
void free_vertex(unsigned int vertexId)
Frees a previously attached cloth point.
Definition: physxCloth.cxx:416
128-bit bitmask class.
static NxVec3 vec3_to_nxVec3(const LVector3f &v)
Converts from LVector3f to NxVec3.
Definition: physxManager.I:27
static NxVec3 point3_to_nxVec3(const LPoint3f &p)
Converts from LPoint3f to NxVec3.
Definition: physxManager.I:63
static LPoint3f nxVec3_to_point3(const NxVec3 &p)
Converts from NxVec3 to LPoint3f.
Definition: physxManager.I:72
static LVector3f nxVec3_to_vec3(const NxVec3 &v)
Converts from NxVec3 to LVector3f.
Definition: physxManager.I:36
A scene is a collection of bodies, constraints, and effectors which can interact.
Definition: physxScene.h:69
Abstract base class for shapes.
Definition: physxShape.h:39
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.