1/*
2 * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
3 *
4 * NVIDIA CORPORATION and its licensors retain all intellectual property
5 * and proprietary rights in and to this software, related documentation
6 * and any modifications thereto. Any use, reproduction, disclosure or
7 * distribution of this software and related documentation without an express
8 * license agreement from NVIDIA CORPORATION is strictly prohibited.
9 */
10// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
11// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
12
13
14#ifndef PX_EXTENSIONS_JOINT_LIMIT
15#define PX_EXTENSIONS_JOINT_LIMIT
16/** \addtogroup extensions
17 @{
18*/
19
20#include "foundation/PxMath.h"
21#include "PxPhysXConfig.h"
22#include "common/PxTolerancesScale.h"
23#include "PxJoint.h"
24
25#ifndef PX_DOXYGEN
26namespace physx
27{
28#endif
29
30/**
31\brief Describes the parameters for a joint limit.
32
33Limits are enabled or disabled by setting flags or other configuration parameters joints, see the
34documentation for specific joint types for details.
35
36@see
37*/
38
39class PxJointLimitParameters
40{
41//= ATTENTION! =====================================================================================
42// Changing the data layout of this class breaks the binary serialization format. See comments for
43// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
44// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
45// accordingly.
46//==================================================================================================
47public:
48 /**
49 \brief Controls the amount of bounce when the joint hits a limit.
50
51 A restitution value of 1.0 causes the joint to bounce back with the velocity which it hit the limit.
52 A value of zero causes the joint to stop dead.
53
54 In situations where the joint has many locked DOFs (e.g. 5) the restitution may not be applied
55 correctly. This is due to a limitation in the solver which causes the restitution velocity to become zero
56 as the solver enforces constraints on the other DOFs.
57
58 This limitation applies to both angular and linear limits, however it is generally most apparent with limited
59 angular DOFs. Disabling joint projection and increasing the solver iteration count may improve this behavior
60 to some extent.
61
62 Also, combining soft joint limits with joint drives driving against those limits may affect stability.
63
64 <b>Range:</b> [0,1]<br>
65 <b>Default:</b> 0.0
66 */
67 PxReal restitution;
68
69
70 /**
71 determines the minimum impact velocity which will cause the joint to bounce
72 */
73
74 PxReal bounceThreshold;
75 /**
76 \brief if greater than zero, the limit is soft, i.e. a spring pulls the joint back to the limit
77
78 <b>Range:</b> [0, PX_MAX_F32)<br>
79 <b>Default:</b> 0.0
80 */
81 PxReal stiffness;
82
83 /**
84 \brief if spring is greater than zero, this is the damping of the limit spring
85
86 <b>Range:</b> [0, PX_MAX_F32)<br>
87 <b>Default:</b> 0.0
88 */
89 PxReal damping;
90
91 /**
92 \brief the distance inside the limit value at which the limit will be considered to be active by the
93 solver. As this value is made larger, the limit becomes active more quickly. It thus becomes less
94 likely to violate the extents of the limit, but more expensive.
95
96 The contact distance should be less than the limit angle or distance, and in the case of a pair limit,
97 less than half the distance between the upper and lower bounds. Exceeding this value will result in
98 the limit being active all the time.
99
100 Making this value too small can result in jitter around the limit.
101
102 <b>Default:</b> depends on the joint
103
104 @see PxPhysics::getTolerancesScale()
105 */
106
107 PxReal contactDistance;
108
109
110
111 PxJointLimitParameters()
112 : restitution(0)
113 , bounceThreshold(0)
114 , stiffness(0)
115 , damping(0)
116 , contactDistance(0)
117 {
118 }
119
120 /**
121 \brief Returns true if the current settings are valid.
122
123 \return true if the current settings are valid
124 */
125 PX_INLINE bool isValid() const
126 {
127 return PxIsFinite(restitution) && restitution >= 0 && restitution <= 1 &&
128 PxIsFinite(stiffness) && stiffness >= 0 &&
129 PxIsFinite(damping) && damping >= 0 &&
130 PxIsFinite(bounceThreshold) && bounceThreshold >= 0 &&
131 PxIsFinite(contactDistance) && contactDistance >= 0;
132 }
133
134 PX_INLINE bool isSoft() const
135 {
136 return damping>0 || stiffness>0;
137 }
138
139protected:
140 ~PxJointLimitParameters() {}
141};
142
143
144/**
145\brief Describes a one-sided linear limit.
146*/
147class PxJointLinearLimit : public PxJointLimitParameters
148{
149//= ATTENTION! =====================================================================================
150// Changing the data layout of this class breaks the binary serialization format. See comments for
151// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
152// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
153// accordingly.
154//==================================================================================================
155public:
156 /**
157 \brief the extent of the limit.
158
159 <b>Range:</b> (0, PX_MAX_F32) <br>
160 <b>Default:</b> PX_MAX_F32
161 */
162 PxReal value;
163
164 /**
165 \brief construct a linear hard limit
166
167 \param[in] scale a PxTolerancesScale struct. Should be the same as used when creating the PxPhysics object.
168 \param[in] extent the extent of the limit
169 \param[in] contactDist the distance from the limit at which it becomes active. Default is 0.01f scaled by the tolerance length scale
170
171 @see PxJointLimitParameters PxTolerancesScale
172 */
173
174 PxJointLinearLimit(const PxTolerancesScale& scale, PxReal extent, PxReal contactDist = -1)
175 : value(extent)
176 {
177 PxJointLimitParameters::contactDistance = contactDist == -1 ? 0.01f*scale.length : contactDist;
178 }
179
180
181 /**
182 \brief construct a linear soft limit
183
184 \param[in] extent the extent of the limit
185 \param[in] spring the stiffness and damping parameters for the limit spring
186
187 @see PxJointLimitParameters PxTolerancesScale
188 */
189
190 PxJointLinearLimit(PxReal extent, const PxSpring& spring)
191 : value(extent)
192 {
193 stiffness = spring.stiffness;
194 damping = spring.damping;
195 }
196
197
198
199 /**
200 \brief Returns true if the limit is valid
201
202 \return true if the current settings are valid
203 */
204 PX_INLINE bool isValid() const
205 {
206 return PxJointLimitParameters::isValid() &&
207 PxIsFinite(value) &&
208 value > 0;
209 }
210};
211
212
213/**
214\brief Describes a two-sided limit.
215*/
216
217class PxJointLinearLimitPair : public PxJointLimitParameters
218{
219//= ATTENTION! =====================================================================================
220// Changing the data layout of this class breaks the binary serialization format. See comments for
221// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
222// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
223// accordingly.
224//==================================================================================================
225public:
226 /**
227 \brief the range of the limit. The upper limit must be no lower than the
228 lower limit, and if they are equal the limited degree of freedom will be treated as locked.
229
230 <b>Unit:</b> Angular: Radians
231 <b>Range:</b> See the joint on which the limit is used for details<br>
232 <b>Default:</b> 0.0
233 */
234 PxReal upper, lower;
235
236
237 /**
238 \brief Construct a linear hard limit pair. The lower distance value must be less than the upper distance value.
239
240 \param[in] scale a PxTolerancesScale struct. Should be the same as used when creating the PxPhysics object.
241 \param[in] lowerLimit the lower distance of the limit
242 \param[in] upperLimit the upper distance of the limit
243 \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)
244
245 @see PxJointLimitParameters PxTolerancesScale
246 */
247
248 PxJointLinearLimitPair(const PxTolerancesScale& scale, PxReal lowerLimit, PxReal upperLimit, PxReal contactDist = -1)
249 : upper(upperLimit)
250 , lower(lowerLimit)
251 {
252 PxJointLimitParameters::contactDistance = contactDist == -1 ? PxMin(scale.length * 0.01f, (upperLimit*0.49f-lowerLimit*0.49f)) : contactDist;
253 bounceThreshold = 2*scale.length;
254 }
255
256
257 /**
258 \brief construct a linear soft limit pair
259
260 \param[in] lowerLimit the lower distance of the limit
261 \param[in] upperLimit the upper distance of the limit
262 \param[in] spring the stiffness and damping parameters of the limit spring
263
264 @see PxJointLimitParameters PxTolerancesScale
265 */
266
267 PxJointLinearLimitPair(PxReal lowerLimit, PxReal upperLimit, const PxSpring& spring)
268 : upper(upperLimit)
269 , lower(lowerLimit)
270 {
271 stiffness = spring.stiffness;
272 damping = spring.damping;
273 }
274
275
276 /**
277 \brief Returns true if the limit is valid.
278
279 \return true if the current settings are valid
280 */
281 PX_INLINE bool isValid() const
282 {
283 return PxJointLimitParameters::isValid() &&
284 PxIsFinite(upper) && PxIsFinite(lower) && upper >= lower &&
285 PxIsFinite(upper - lower) &&
286 PxIsFinite(contactDistance) && contactDistance <= upper - lower;
287 }
288};
289
290
291class PxJointAngularLimitPair : public PxJointLimitParameters
292{
293//= ATTENTION! =====================================================================================
294// Changing the data layout of this class breaks the binary serialization format. See comments for
295// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
296// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
297// accordingly.
298//==================================================================================================
299public:
300 /**
301 \brief the range of the limit. The upper limit must be no lower than the lower limit.
302
303 <b>Unit:</b> Angular: Radians
304 <b>Range:</b> See the joint on which the limit is used for details<br>
305 <b>Default:</b> 0.0
306 */
307 PxReal upper, lower;
308
309
310 /**
311 \brief construct an angular hard limit pair.
312
313 The lower value must be less than the upper value.
314
315 \param[in] lowerLimit the lower angle of the limit
316 \param[in] upperLimit the upper angle of the limit
317 \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)
318
319 @see PxJointLimitParameters
320 */
321
322 PxJointAngularLimitPair(PxReal lowerLimit, PxReal upperLimit, PxReal contactDist = -1)
323 : upper(upperLimit)
324 , lower(lowerLimit)
325 {
326 PxJointLimitParameters::contactDistance = contactDist ==-1 ? PxMin(0.1f, 0.49f*(upperLimit-lowerLimit)) : contactDist;
327 bounceThreshold = 0.5f;
328 }
329
330
331 /**
332 \brief construct an angular soft limit pair.
333
334 The lower value must be less than the upper value.
335
336 \param[in] lowerLimit the lower angle of the limit
337 \param[in] upperLimit the upper angle of the limit
338 \param[in] spring the stiffness and damping of the limit spring
339
340 @see PxJointLimitParameters
341 */
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 /**
353 \brief Returns true if the limit is valid.
354
355 \return true if the current settings are valid
356 */
357 PX_INLINE bool isValid() const
358 {
359 return PxJointLimitParameters::isValid() &&
360 PxIsFinite(upper) && PxIsFinite(lower) && upper >= lower &&
361 PxIsFinite(contactDistance) && contactDistance <= upper - lower;
362 }
363};
364
365
366
367/**
368\brief Describes an elliptical conical joint limit. Note that very small or highly elliptical limit cones may
369result in jitter.
370
371@see PxD6Joint PxSphericalJoint
372*/
373
374class PxJointLimitCone : public PxJointLimitParameters
375{
376//= ATTENTION! =====================================================================================
377// Changing the data layout of this class breaks the binary serialization format. See comments for
378// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
379// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
380// accordingly.
381//==================================================================================================
382public:
383 /**
384 \brief the maximum angle from the Y axis of the constraint frame.
385
386 <b>Unit:</b> Angular: Radians
387 <b>Range:</b> Angular: (0,PI)<br>
388 <b>Default:</b> PI/2
389 */
390 PxReal yAngle;
391
392
393 /**
394 \brief the maximum angle from the Z-axis of the constraint frame.
395
396 <b>Unit:</b> Angular: Radians
397 <b>Range:</b> Angular: (0,PI)<br>
398 <b>Default:</b> PI/2
399 */
400 PxReal zAngle;
401
402 /**
403 \brief Construct a cone hard limit.
404
405 \param[in] yLimitAngle the limit angle from the Y-axis of the constraint frame
406 \param[in] zLimitAngle the limit angle from the Z-axis of the constraint frame
407 \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
408
409 @see PxJointLimitParameters
410 */
411
412 PxJointLimitCone(PxReal yLimitAngle, PxReal zLimitAngle, PxReal contactDist = -1):
413 yAngle(yLimitAngle),
414 zAngle(zLimitAngle)
415 {
416 PxJointLimitParameters::contactDistance = contactDist == -1 ? PxMin(0.1f, PxMin(yLimitAngle, zLimitAngle)*0.49f) : contactDist;
417 bounceThreshold = 0.5f;
418 }
419
420
421
422 /**
423 \brief Construct a cone soft limit.
424
425 \param[in] yLimitAngle the limit angle from the Y-axis of the constraint frame
426 \param[in] zLimitAngle the limit angle from the Z-axis of the constraint frame
427 \param[in] spring the stiffness and damping of the limit spring
428
429 @see PxJointLimitParameters
430 */
431
432 PxJointLimitCone(PxReal yLimitAngle, PxReal zLimitAngle, const PxSpring& spring):
433 yAngle(yLimitAngle),
434 zAngle(zLimitAngle)
435 {
436 stiffness = spring.stiffness;
437 damping = spring.damping;
438 }
439
440
441 /**
442 \brief Returns true if the limit is valid.
443
444 \return true if the current settings are valid
445 */
446 PX_INLINE bool isValid() const
447 {
448 return PxJointLimitParameters::isValid() &&
449 PxIsFinite(yAngle) && yAngle>0 && yAngle<PxPi &&
450 PxIsFinite(zAngle) && zAngle>0 && zAngle<PxPi;
451 }
452};
453
454#ifndef PX_DOXYGEN
455} // namespace physx
456#endif
457
458/** @} */
459#endif
460