1//
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions
4// are met:
5// * Redistributions of source code must retain the above copyright
6// notice, this list of conditions and the following disclaimer.
7// * Redistributions in binary form must reproduce the above copyright
8// notice, this list of conditions and the following disclaimer in the
9// documentation and/or other materials provided with the distribution.
10// * Neither the name of NVIDIA CORPORATION nor the names of its
11// contributors may be used to endorse or promote products derived
12// from this software without specific prior written permission.
13//
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
15// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
18// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25//
26// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
27// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
28// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
29
30#ifndef PX_EXTENSIONS_JOINT_LIMIT
31#define PX_EXTENSIONS_JOINT_LIMIT
32/** \addtogroup extensions
33 @{
34*/
35
36#include "foundation/PxMath.h"
37#include "common/PxTolerancesScale.h"
38#include "extensions/PxJoint.h"
39#include "PxPhysXConfig.h"
40
41#if !PX_DOXYGEN
42namespace physx
43{
44#endif
45
46/**
47\brief Describes the parameters for a joint limit.
48
49Limits are enabled or disabled by setting flags or other configuration parameters joints, see the
50documentation for specific joint types for details.
51*/
52class PxJointLimitParameters
53{
54//= ATTENTION! =====================================================================================
55// Changing the data layout of this class breaks the binary serialization format. See comments for
56// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
57// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
58// accordingly.
59//==================================================================================================
60public:
61 /**
62 \brief Controls the amount of bounce when the joint hits a limit.
63
64 A restitution value of 1.0 causes the joint to bounce back with the velocity which it hit the limit.
65 A value of zero causes the joint to stop dead.
66
67 In situations where the joint has many locked DOFs (e.g. 5) the restitution may not be applied
68 correctly. This is due to a limitation in the solver which causes the restitution velocity to become zero
69 as the solver enforces constraints on the other DOFs.
70
71 This limitation applies to both angular and linear limits, however it is generally most apparent with limited
72 angular DOFs. Disabling joint projection and increasing the solver iteration count may improve this behavior
73 to some extent.
74
75 Also, combining soft joint limits with joint drives driving against those limits may affect stability.
76
77 <b>Range:</b> [0,1]<br>
78 <b>Default:</b> 0.0
79 */
80 PxReal restitution;
81
82 /**
83 determines the minimum impact velocity which will cause the joint to bounce
84 */
85 PxReal bounceThreshold;
86
87 /**
88 \brief if greater than zero, the limit is soft, i.e. a spring pulls the joint back to the limit
89
90 <b>Range:</b> [0, PX_MAX_F32)<br>
91 <b>Default:</b> 0.0
92 */
93 PxReal stiffness;
94
95 /**
96 \brief if spring is greater than zero, this is the damping of the limit spring
97
98 <b>Range:</b> [0, PX_MAX_F32)<br>
99 <b>Default:</b> 0.0
100 */
101 PxReal damping;
102
103 /**
104 \brief the distance inside the limit value at which the limit will be considered to be active by the
105 solver. As this value is made larger, the limit becomes active more quickly. It thus becomes less
106 likely to violate the extents of the limit, but more expensive.
107
108 The contact distance should be less than the limit angle or distance, and in the case of a pair limit,
109 less than half the distance between the upper and lower bounds. Exceeding this value will result in
110 the limit being active all the time.
111
112 Making this value too small can result in jitter around the limit.
113
114 <b>Default:</b> depends on the joint
115
116 @see PxPhysics::getTolerancesScale()
117 */
118 PxReal contactDistance;
119
120 PxJointLimitParameters() :
121 restitution (0.0f),
122 bounceThreshold (0.0f),
123 stiffness (0.0f),
124 damping (0.0f),
125 contactDistance (0.0f)
126 {
127 }
128
129 PxJointLimitParameters(const PxJointLimitParameters& p) :
130 restitution (p.restitution),
131 bounceThreshold (p.bounceThreshold),
132 stiffness (p.stiffness),
133 damping (p.damping),
134 contactDistance (p.contactDistance)
135 {
136 }
137
138 /**
139 \brief Returns true if the current settings are valid.
140
141 \return true if the current settings are valid
142 */
143 PX_INLINE bool isValid() const
144 {
145 return PxIsFinite(f: restitution) && restitution >= 0 && restitution <= 1 &&
146 PxIsFinite(f: stiffness) && stiffness >= 0 &&
147 PxIsFinite(f: damping) && damping >= 0 &&
148 PxIsFinite(f: bounceThreshold) && bounceThreshold >= 0 &&
149 PxIsFinite(f: contactDistance) && contactDistance >= 0;
150 }
151
152 PX_INLINE bool isSoft() const
153 {
154 return damping>0 || stiffness>0;
155 }
156
157protected:
158 ~PxJointLimitParameters() {}
159};
160
161
162/**
163\brief Describes a one-sided linear limit.
164*/
165class PxJointLinearLimit : public PxJointLimitParameters
166{
167//= ATTENTION! =====================================================================================
168// Changing the data layout of this class breaks the binary serialization format. See comments for
169// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
170// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
171// accordingly.
172//==================================================================================================
173public:
174 /**
175 \brief the extent of the limit.
176
177 <b>Range:</b> (0, PX_MAX_F32) <br>
178 <b>Default:</b> PX_MAX_F32
179 */
180 PxReal value;
181
182 /**
183 \brief construct a linear hard limit
184
185 \param[in] scale A PxTolerancesScale struct. Should be the same as used when creating the PxPhysics object.
186 \param[in] extent The extent of the limit
187 \param[in] contactDist The distance from the limit at which it becomes active. Default is 0.01f scaled by the tolerance length scale
188
189 @see PxJointLimitParameters PxTolerancesScale
190 */
191 PxJointLinearLimit(const PxTolerancesScale& scale, PxReal extent, PxReal contactDist = -1.0f)
192 : value(extent)
193 {
194 PxJointLimitParameters::contactDistance = contactDist == -1.0f ? 0.01f*scale.length : contactDist;
195 }
196
197 /**
198 \brief construct a linear soft limit
199
200 \param[in] extent the extent of the limit
201 \param[in] spring the stiffness and damping parameters for the limit spring
202
203 @see PxJointLimitParameters PxTolerancesScale
204 */
205 PxJointLinearLimit(PxReal extent, const PxSpring& spring) : value(extent)
206 {
207 stiffness = spring.stiffness;
208 damping = spring.damping;
209 }
210
211 /**
212 \brief Returns true if the limit is valid
213
214 \return true if the current settings are valid
215 */
216 PX_INLINE bool isValid() const
217 {
218 return PxJointLimitParameters::isValid() &&
219 PxIsFinite(f: value) &&
220 value > 0.0f;
221 }
222};
223
224
225/**
226\brief Describes a two-sided limit.
227*/
228class PxJointLinearLimitPair : public PxJointLimitParameters
229{
230//= ATTENTION! =====================================================================================
231// Changing the data layout of this class breaks the binary serialization format. See comments for
232// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
233// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
234// accordingly.
235//==================================================================================================
236public:
237 /**
238 \brief the range of the limit. The upper limit must be no lower than the
239 lower limit, and if they are equal the limited degree of freedom will be treated as locked.
240
241 <b>Range:</b> See the joint on which the limit is used for details<br>
242 <b>Default:</b> lower = -PX_MAX_F32/3, upper = PX_MAX_F32/3
243 */
244 PxReal upper, lower;
245
246 /**
247 \brief Construct a linear hard limit pair. The lower distance value must be less than the upper distance value.
248
249 \param[in] scale A PxTolerancesScale struct. Should be the same as used when creating the PxPhysics object.
250 \param[in] lowerLimit The lower distance of the limit
251 \param[in] upperLimit The upper distance of the limit
252 \param[in] contactDist The distance from the limit at which it becomes active. Default is the lesser of 0.01f scaled by the tolerance length scale, and 0.49 * (upperLimit - lowerLimit)
253
254 @see PxJointLimitParameters PxTolerancesScale
255 */
256 PxJointLinearLimitPair(const PxTolerancesScale& scale, PxReal lowerLimit = -PX_MAX_F32/3.0f, PxReal upperLimit = PX_MAX_F32/3.0f, PxReal contactDist = -1.0f) :
257 upper(upperLimit),
258 lower(lowerLimit)
259 {
260 PxJointLimitParameters::contactDistance = contactDist == -1.0f ? PxMin(a: scale.length * 0.01f, b: (upperLimit*0.49f-lowerLimit*0.49f)) : contactDist;
261 bounceThreshold = 2.0f*scale.length;
262 }
263
264 /**
265 \brief construct a linear soft limit pair
266
267 \param[in] lowerLimit The lower distance of the limit
268 \param[in] upperLimit The upper distance of the limit
269 \param[in] spring The stiffness and damping parameters of the limit spring
270
271 @see PxJointLimitParameters PxTolerancesScale
272 */
273 PxJointLinearLimitPair(PxReal lowerLimit, PxReal upperLimit, const PxSpring& spring) :
274 upper(upperLimit),
275 lower(lowerLimit)
276 {
277 stiffness = spring.stiffness;
278 damping = spring.damping;
279 }
280
281 /**
282 \brief Returns true if the limit is valid.
283
284 \return true if the current settings are valid
285 */
286 PX_INLINE bool isValid() const
287 {
288 return PxJointLimitParameters::isValid() &&
289 PxIsFinite(f: upper) && PxIsFinite(f: lower) && upper >= lower &&
290 PxIsFinite(f: upper - lower);
291 }
292};
293
294
295class PxJointAngularLimitPair : public PxJointLimitParameters
296{
297//= ATTENTION! =====================================================================================
298// Changing the data layout of this class breaks the binary serialization format. See comments for
299// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
300// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
301// accordingly.
302//==================================================================================================
303public:
304 /**
305 \brief the range of the limit. The upper limit must be no lower than the lower limit.
306
307 <b>Unit:</b> Angular: Radians
308 <b>Range:</b> See the joint on which the limit is used for details<br>
309 <b>Default:</b> lower = -PI/2, upper = PI/2
310 */
311 PxReal upper, lower;
312
313 /**
314 \brief construct an angular hard limit pair.
315
316 The lower value must be less than the upper value.
317
318 \param[in] lowerLimit The lower angle of the limit
319 \param[in] upperLimit The upper angle of the limit
320 \param[in] contactDist The distance from the limit at which it becomes active. Default is the lesser of 0.1 radians, and 0.49 * (upperLimit - lowerLimit)
321
322 @see PxJointLimitParameters
323 */
324 PxJointAngularLimitPair(PxReal lowerLimit, PxReal upperLimit, PxReal contactDist = -1.0f) :
325 upper(upperLimit),
326 lower(lowerLimit)
327 {
328 PxJointLimitParameters::contactDistance = contactDist ==-1.0f ? PxMin(a: 0.1f, b: 0.49f*(upperLimit-lowerLimit)) : contactDist;
329 bounceThreshold = 0.5f;
330 }
331
332 /**
333 \brief construct an angular soft limit pair.
334
335 The lower value must be less than the upper value.
336
337 \param[in] lowerLimit The lower angle of the limit
338 \param[in] upperLimit The upper angle of the limit
339 \param[in] spring The stiffness and damping of the limit spring
340
341 @see PxJointLimitParameters
342 */
343 PxJointAngularLimitPair(PxReal lowerLimit, PxReal upperLimit, const PxSpring& spring) :
344 upper(upperLimit),
345 lower(lowerLimit)
346 {
347 stiffness = spring.stiffness;
348 damping = spring.damping;
349 }
350
351 /**
352 \brief Returns true if the limit is valid.
353
354 \return true if the current settings are valid
355 */
356 PX_INLINE bool isValid() const
357 {
358 return PxJointLimitParameters::isValid() &&
359 PxIsFinite(f: upper) && PxIsFinite(f: lower) && upper >= lower;
360 }
361};
362
363/**
364\brief Describes an elliptical conical joint limit. Note that very small or highly elliptical limit cones may
365result in jitter.
366
367@see PxD6Joint PxSphericalJoint
368*/
369class PxJointLimitCone : public PxJointLimitParameters
370{
371//= ATTENTION! =====================================================================================
372// Changing the data layout of this class breaks the binary serialization format. See comments for
373// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
374// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
375// accordingly.
376//==================================================================================================
377public:
378 /**
379 \brief the maximum angle from the Y axis of the constraint frame.
380
381 <b>Unit:</b> Angular: Radians
382 <b>Range:</b> Angular: (0,PI)<br>
383 <b>Default:</b> PI/2
384 */
385 PxReal yAngle;
386
387 /**
388 \brief the maximum angle from the Z-axis of the constraint frame.
389
390 <b>Unit:</b> Angular: Radians
391 <b>Range:</b> Angular: (0,PI)<br>
392 <b>Default:</b> PI/2
393 */
394 PxReal zAngle;
395
396 /**
397 \brief Construct a cone hard limit.
398
399 \param[in] yLimitAngle The limit angle from the Y-axis of the constraint frame
400 \param[in] zLimitAngle The limit angle from the Z-axis of the constraint frame
401 \param[in] contactDist The distance from the limit at which it becomes active. Default is the lesser of 0.1 radians, and 0.49 * the lower of the limit angles
402
403 @see PxJointLimitParameters
404 */
405 PxJointLimitCone(PxReal yLimitAngle, PxReal zLimitAngle, PxReal contactDist = -1.0f) :
406 yAngle(yLimitAngle),
407 zAngle(zLimitAngle)
408 {
409 PxJointLimitParameters::contactDistance = contactDist == -1.0f ? PxMin(a: 0.1f, b: PxMin(a: yLimitAngle, b: zLimitAngle)*0.49f) : contactDist;
410 bounceThreshold = 0.5f;
411 }
412
413 /**
414 \brief Construct a cone soft limit.
415
416 \param[in] yLimitAngle The limit angle from the Y-axis of the constraint frame
417 \param[in] zLimitAngle The limit angle from the Z-axis of the constraint frame
418 \param[in] spring The stiffness and damping of the limit spring
419
420 @see PxJointLimitParameters
421 */
422 PxJointLimitCone(PxReal yLimitAngle, PxReal zLimitAngle, const PxSpring& spring) :
423 yAngle(yLimitAngle),
424 zAngle(zLimitAngle)
425 {
426 stiffness = spring.stiffness;
427 damping = spring.damping;
428 }
429
430 /**
431 \brief Returns true if the limit is valid.
432
433 \return true if the current settings are valid
434 */
435 PX_INLINE bool isValid() const
436 {
437 return PxJointLimitParameters::isValid() &&
438 PxIsFinite(f: yAngle) && yAngle>0 && yAngle<PxPi &&
439 PxIsFinite(f: zAngle) && zAngle>0 && zAngle<PxPi;
440 }
441};
442
443/**
444\brief Describes a pyramidal joint limit.
445
446@see PxD6Joint
447*/
448class PxJointLimitPyramid : public PxJointLimitParameters
449{
450//= ATTENTION! =====================================================================================
451// Changing the data layout of this class breaks the binary serialization format. See comments for
452// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
453// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
454// accordingly.
455//==================================================================================================
456public:
457 /**
458 \brief the minimum angle from the Y axis of the constraint frame.
459
460 <b>Unit:</b> Angular: Radians
461 <b>Range:</b> Angular: (-PI,PI)<br>
462 <b>Default:</b> -PI/2
463 */
464 PxReal yAngleMin;
465
466 /**
467 \brief the maximum angle from the Y axis of the constraint frame.
468
469 <b>Unit:</b> Angular: Radians
470 <b>Range:</b> Angular: (-PI,PI)<br>
471 <b>Default:</b> PI/2
472 */
473 PxReal yAngleMax;
474
475 /**
476 \brief the minimum angle from the Z-axis of the constraint frame.
477
478 <b>Unit:</b> Angular: Radians
479 <b>Range:</b> Angular: (-PI,PI)<br>
480 <b>Default:</b> -PI/2
481 */
482 PxReal zAngleMin;
483
484 /**
485 \brief the maximum angle from the Z-axis of the constraint frame.
486
487 <b>Unit:</b> Angular: Radians
488 <b>Range:</b> Angular: (-PI,PI)<br>
489 <b>Default:</b> PI/2
490 */
491 PxReal zAngleMax;
492
493 /**
494 \brief Construct a pyramid hard limit.
495
496 \param[in] yLimitAngleMin The minimum limit angle from the Y-axis of the constraint frame
497 \param[in] yLimitAngleMax The maximum limit angle from the Y-axis of the constraint frame
498 \param[in] zLimitAngleMin The minimum limit angle from the Z-axis of the constraint frame
499 \param[in] zLimitAngleMax The maximum limit angle from the Z-axis of the constraint frame
500 \param[in] contactDist The distance from the limit at which it becomes active. Default is the lesser of 0.1 radians, and 0.49 * the lower of the limit angles
501
502 @see PxJointLimitParameters
503 */
504 PxJointLimitPyramid(PxReal yLimitAngleMin, PxReal yLimitAngleMax, PxReal zLimitAngleMin, PxReal zLimitAngleMax, PxReal contactDist = -1.0f) :
505 yAngleMin(yLimitAngleMin),
506 yAngleMax(yLimitAngleMax),
507 zAngleMin(zLimitAngleMin),
508 zAngleMax(zLimitAngleMax)
509 {
510 if(contactDist == -1.0f)
511 {
512 const PxReal contactDistY = PxMin(a: 0.1f, b: 0.49f*(yLimitAngleMax - yLimitAngleMin));
513 const PxReal contactDistZ = PxMin(a: 0.1f, b: 0.49f*(zLimitAngleMax - zLimitAngleMin));
514 PxJointLimitParameters::contactDistance = contactDist == PxMin(a: contactDistY, b: contactDistZ);
515 }
516 else
517 {
518 PxJointLimitParameters::contactDistance = contactDist;
519 }
520
521 bounceThreshold = 0.5f;
522 }
523
524 /**
525 \brief Construct a pyramid soft limit.
526
527 \param[in] yLimitAngleMin The minimum limit angle from the Y-axis of the constraint frame
528 \param[in] yLimitAngleMax The maximum limit angle from the Y-axis of the constraint frame
529 \param[in] zLimitAngleMin The minimum limit angle from the Z-axis of the constraint frame
530 \param[in] zLimitAngleMax The maximum limit angle from the Z-axis of the constraint frame
531 \param[in] spring The stiffness and damping of the limit spring
532
533 @see PxJointLimitParameters
534 */
535 PxJointLimitPyramid(PxReal yLimitAngleMin, PxReal yLimitAngleMax, PxReal zLimitAngleMin, PxReal zLimitAngleMax, const PxSpring& spring) :
536 yAngleMin(yLimitAngleMin),
537 yAngleMax(yLimitAngleMax),
538 zAngleMin(zLimitAngleMin),
539 zAngleMax(zLimitAngleMax)
540 {
541 stiffness = spring.stiffness;
542 damping = spring.damping;
543 }
544
545 /**
546 \brief Returns true if the limit is valid.
547
548 \return true if the current settings are valid
549 */
550 PX_INLINE bool isValid() const
551 {
552 return PxJointLimitParameters::isValid() &&
553 PxIsFinite(f: yAngleMin) && yAngleMin>-PxPi && yAngleMin<PxPi &&
554 PxIsFinite(f: yAngleMax) && yAngleMax>-PxPi && yAngleMax<PxPi &&
555 PxIsFinite(f: zAngleMin) && zAngleMin>-PxPi && zAngleMin<PxPi &&
556 PxIsFinite(f: zAngleMax) && zAngleMax>-PxPi && zAngleMax<PxPi &&
557 yAngleMax>=yAngleMin && zAngleMax>=zAngleMin;
558 }
559};
560
561#if !PX_DOXYGEN
562} // namespace physx
563#endif
564
565/** @} */
566#endif
567

source code of qtquick3dphysics/src/3rdparty/PhysX/include/extensions/PxJointLimit.h