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_D6JOINT_H
31#define PX_D6JOINT_H
32/** \addtogroup extensions
33 @{
34*/
35
36#include "extensions/PxJoint.h"
37#include "extensions/PxJointLimit.h"
38#include "foundation/PxFlags.h"
39
40#if !PX_DOXYGEN
41namespace physx
42{
43#endif
44
45class PxD6Joint;
46
47/**
48\brief Create a D6 joint.
49
50 \param[in] physics The physics SDK
51 \param[in] actor0 An actor to which the joint is attached. NULL may be used to attach the joint to a specific point in the world frame
52 \param[in] localFrame0 The position and orientation of the joint relative to actor0
53 \param[in] actor1 An actor to which the joint is attached. NULL may be used to attach the joint to a specific point in the world frame
54 \param[in] localFrame1 The position and orientation of the joint relative to actor1
55
56@see PxD6Joint
57*/
58PxD6Joint* PxD6JointCreate(PxPhysics& physics, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1);
59
60/**
61\brief Used to specify one of the degrees of freedom of a D6 joint.
62
63@see PxD6Joint
64*/
65struct PxD6Axis
66{
67 enum Enum
68 {
69 eX = 0, //!< motion along the X axis
70 eY = 1, //!< motion along the Y axis
71 eZ = 2, //!< motion along the Z axis
72 eTWIST = 3, //!< motion around the X axis
73 eSWING1 = 4, //!< motion around the Y axis
74 eSWING2 = 5, //!< motion around the Z axis
75 eCOUNT = 6
76 };
77};
78
79
80/**
81\brief Used to specify the range of motions allowed for a degree of freedom in a D6 joint.
82
83@see PxD6Joint
84*/
85struct PxD6Motion
86{
87 enum Enum
88 {
89 eLOCKED, //!< The DOF is locked, it does not allow relative motion.
90 eLIMITED, //!< The DOF is limited, it only allows motion within a specific range.
91 eFREE //!< The DOF is free and has its full range of motion.
92 };
93};
94
95
96/**
97\brief Used to specify which axes of a D6 joint are driven.
98
99Each drive is an implicit force-limited damped spring:
100
101force = spring * (target position - position) + damping * (targetVelocity - velocity)
102
103Alternatively, the spring may be configured to generate a specified acceleration instead of a force.
104
105A linear axis is affected by drive only if the corresponding drive flag is set. There are two possible models
106for angular drive: swing/twist, which may be used to drive one or more angular degrees of freedom, or slerp,
107which may only be used to drive all three angular degrees simultaneously.
108
109@see PxD6Joint
110*/
111struct PxD6Drive
112{
113 enum Enum
114 {
115 eX = 0, //!< drive along the X-axis
116 eY = 1, //!< drive along the Y-axis
117 eZ = 2, //!< drive along the Z-axis
118 eSWING = 3, //!< drive of displacement from the X-axis
119 eTWIST = 4, //!< drive of the displacement around the X-axis
120 eSLERP = 5, //!< drive of all three angular degrees along a SLERP-path
121 eCOUNT = 6
122 };
123};
124
125/**
126\brief flags for configuring the drive model of a PxD6Joint
127
128@see PxD6JointDrive PxD6Joint
129*/
130struct PxD6JointDriveFlag
131{
132 enum Enum
133 {
134 eACCELERATION = 1 //!< drive spring is for the acceleration at the joint (rather than the force)
135 };
136};
137typedef PxFlags<PxD6JointDriveFlag::Enum, PxU32> PxD6JointDriveFlags;
138PX_FLAGS_OPERATORS(PxD6JointDriveFlag::Enum, PxU32)
139
140/**
141\brief parameters for configuring the drive model of a PxD6Joint
142
143@see PxD6Joint
144*/
145class PxD6JointDrive : public PxSpring
146{
147//= ATTENTION! =====================================================================================
148// Changing the data layout of this class breaks the binary serialization format. See comments for
149// PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData
150// function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION
151// accordingly.
152//==================================================================================================
153
154public:
155 PxReal forceLimit; //!< the force limit of the drive - may be an impulse or a force depending on PxConstraintFlag::eDRIVE_LIMITS_ARE_FORCES
156 PxD6JointDriveFlags flags; //!< the joint drive flags
157
158 /**
159 \brief default constructor for PxD6JointDrive.
160 */
161 PxD6JointDrive(): PxSpring(0,0), forceLimit(PX_MAX_F32), flags(0) {}
162
163 /**
164 \brief constructor a PxD6JointDrive.
165
166 \param[in] driveStiffness The stiffness of the drive spring.
167 \param[in] driveDamping The damping of the drive spring
168 \param[in] driveForceLimit The maximum impulse or force that can be exerted by the drive
169 \param[in] isAcceleration Whether the drive is an acceleration drive or a force drive
170 */
171 PxD6JointDrive(PxReal driveStiffness, PxReal driveDamping, PxReal driveForceLimit, bool isAcceleration = false)
172 : PxSpring(driveStiffness, driveDamping)
173 , forceLimit(driveForceLimit)
174 , flags(isAcceleration?PxU32(PxD6JointDriveFlag::eACCELERATION) : 0)
175 {}
176
177 /**
178 \brief returns true if the drive is valid
179 */
180 bool isValid() const
181 {
182 return PxIsFinite(f: stiffness) && stiffness>=0 &&
183 PxIsFinite(f: damping) && damping >=0 &&
184 PxIsFinite(f: forceLimit) && forceLimit >=0;
185 }
186};
187
188
189/**
190 \brief A D6 joint is a general constraint between two actors.
191
192 It allows the application to individually define the linear and rotational degrees of freedom,
193 and also to configure a variety of limits and driven degrees of freedom.
194
195 By default all degrees of freedom are locked. So to create a prismatic joint with free motion
196 along the x-axis:
197
198 \code
199 ...
200 joint->setMotion(PxD6Axis::eX, PxD6JointMotion::eFREE);
201 ...
202 \endcode
203
204 Or a Revolute joint with motion free allowed around the x-axis:
205
206 \code
207 ...
208 joint->setMotion(PxD6Axis::eTWIST, PxD6JointMotion::eFREE);
209 ...
210 \endcode
211
212 Degrees of freedom may also be set to limited instead of locked.
213
214 There are two different kinds of linear limits available. The first kind is a single limit value
215 for all linear degrees of freedom, which may act as a linear, circular, or spherical limit depending
216 on which degrees of freedom are limited. This is similar to a distance limit. Then, the second kind
217 supports a pair of limit values for each linear axis, which can be used to implement a traditional
218 prismatic joint for example.
219
220 If the twist degree of freedom is limited, is supports upper and lower limits. The two swing degrees
221 of freedom are limited with a cone limit.
222@see PxD6JointCreate() PxJoint
223*/
224class PxD6Joint : public PxJoint
225{
226public:
227
228 /**
229 \brief Set the motion type around the specified axis.
230
231 Each axis may independently specify that the degree of freedom is locked (blocking relative movement
232 along or around this axis), limited by the corresponding limit, or free.
233
234 \param[in] axis the axis around which motion is specified
235 \param[in] type the motion type around the specified axis
236
237 <b>Default:</b> all degrees of freedom are locked
238
239 @see getMotion() PxD6Axis PxD6Motion
240 */
241 virtual void setMotion(PxD6Axis::Enum axis, PxD6Motion::Enum type) = 0;
242
243 /**
244 \brief Get the motion type around the specified axis.
245
246 @see setMotion() PxD6Axis PxD6Motion
247
248 \param[in] axis the degree of freedom around which the motion type is specified
249 \return the motion type around the specified axis
250 */
251 virtual PxD6Motion::Enum getMotion(PxD6Axis::Enum axis) const = 0;
252
253 /**
254 \brief get the twist angle of the joint, in the range (-2*Pi, 2*Pi]
255 */
256 virtual PxReal getTwistAngle() const = 0;
257
258 /**
259 \brief get the twist angle of the joint
260
261 \deprecated Use getTwistAngle instead. Deprecated since PhysX version 4.0
262 */
263 PX_DEPRECATED PX_FORCE_INLINE PxReal getTwist() const { return getTwistAngle(); }
264
265 /**
266 \brief get the swing angle of the joint from the Y axis
267 */
268 virtual PxReal getSwingYAngle() const = 0;
269
270 /**
271 \brief get the swing angle of the joint from the Z axis
272 */
273 virtual PxReal getSwingZAngle() const = 0;
274
275 /**
276 \brief Set the distance limit for the joint.
277
278 A single limit constraints all linear limited degrees of freedom, forming a linear, circular
279 or spherical constraint on motion depending on the number of limited degrees. This is similar
280 to a distance limit.
281
282 \param[in] limit the distance limit structure
283
284 @see getDistanceLimit() PxJointLinearLimit
285 */
286 virtual void setDistanceLimit(const PxJointLinearLimit& limit) = 0;
287
288 /**
289 \brief Get the distance limit for the joint.
290
291 \return the distance limit structure
292
293 @see setDistanceLimit() PxJointLinearLimit
294 */
295 virtual PxJointLinearLimit getDistanceLimit() const = 0;
296
297 /**
298 \deprecated Use setDistanceLimit instead. Deprecated since PhysX version 4.0
299 */
300 PX_DEPRECATED PX_FORCE_INLINE void setLinearLimit(const PxJointLinearLimit& limit) { setDistanceLimit(limit); }
301
302 /**
303 \deprecated Use getDistanceLimit instead. Deprecated since PhysX version 4.0
304 */
305 PX_DEPRECATED PX_FORCE_INLINE PxJointLinearLimit getLinearLimit() const { return getDistanceLimit(); }
306
307 /**
308 \brief Set the linear limit for a given linear axis.
309
310 This function extends the previous setDistanceLimit call with the following features:
311 - there can be a different limit for each linear axis
312 - each limit is defined by two values, i.e. it can now be asymmetric
313
314 This can be used to create prismatic joints similar to PxPrismaticJoint, or point-in-quad joints,
315 or point-in-box joints.
316
317 \param[in] axis The limited linear axis (must be PxD6Axis::eX, PxD6Axis::eY or PxD6Axis::eZ)
318 \param[in] limit The linear limit pair structure
319
320 @see getLinearLimit()
321 */
322 virtual void setLinearLimit(PxD6Axis::Enum axis, const PxJointLinearLimitPair& limit) = 0;
323
324 /**
325 \brief Get the linear limit for a given linear axis.
326
327 \param[in] axis The limited linear axis (must be PxD6Axis::eX, PxD6Axis::eY or PxD6Axis::eZ)
328
329 \return the linear limit pair structure from desired axis
330
331 @see setLinearLimit() PxJointLinearLimit
332 */
333 virtual PxJointLinearLimitPair getLinearLimit(PxD6Axis::Enum axis) const = 0;
334
335 /**
336 \brief Set the twist limit for the joint.
337
338 The twist limit controls the range of motion around the twist axis.
339
340 The limit angle range is (-2*Pi, 2*Pi).
341
342 \param[in] limit the twist limit structure
343
344 @see getTwistLimit() PxJointAngularLimitPair
345 */
346 virtual void setTwistLimit(const PxJointAngularLimitPair& limit) = 0;
347
348 /**
349 \brief Get the twist limit for the joint.
350
351 \return the twist limit structure
352
353 @see setTwistLimit() PxJointAngularLimitPair
354 */
355 virtual PxJointAngularLimitPair getTwistLimit() const = 0;
356
357 /**
358 \brief Set the swing cone limit for the joint.
359
360 The cone limit is used if either or both swing axes are limited. The extents are
361 symmetrical and measured in the frame of the parent. If only one swing degree of freedom
362 is limited, the corresponding value from the cone limit defines the limit range.
363
364 \param[in] limit the cone limit structure
365
366 @see getLimitCone() PxJointLimitCone
367 */
368 virtual void setSwingLimit(const PxJointLimitCone& limit) = 0;
369
370 /**
371 \brief Get the cone limit for the joint.
372
373 \return the swing limit structure
374
375 @see setLimitCone() PxJointLimitCone
376 */
377 virtual PxJointLimitCone getSwingLimit() const = 0;
378
379 /**
380 \brief Set a pyramidal swing limit for the joint.
381
382 The pyramid limits will only be used in the following cases:
383 - both swing Y and Z are limited. The limit shape is then a pyramid.
384 - Y is limited and Z is locked, or vice versa. The limit shape is an asymmetric angular section, similar to
385 what is supported for the twist axis.
386 The remaining cases (Y limited and Z is free, or vice versa) are not supported.
387
388 \param[in] limit the cone limit structure
389
390 @see getLimitCone() PxJointLimitPyramid
391 */
392 virtual void setPyramidSwingLimit(const PxJointLimitPyramid& limit) = 0;
393
394 /**
395 \brief Get the pyramidal swing limit for the joint.
396
397 \return the swing limit structure
398
399 @see setLimitCone() PxJointLimitPyramid
400 */
401 virtual PxJointLimitPyramid getPyramidSwingLimit() const = 0;
402
403 /**
404 \brief Set the drive parameters for the specified drive type.
405
406 \param[in] index the type of drive being specified
407 \param[in] drive the drive parameters
408
409 @see getDrive() PxD6JointDrive
410
411 <b>Default</b> The default drive spring and damping values are zero, the force limit is zero, and no flags are set.
412 */
413 virtual void setDrive(PxD6Drive::Enum index, const PxD6JointDrive& drive) = 0;
414
415 /**
416 \brief Get the drive parameters for the specified drive type.
417
418 \param[in] index the specified drive type
419
420 @see setDrive() PxD6JointDrive
421 */
422 virtual PxD6JointDrive getDrive(PxD6Drive::Enum index) const = 0;
423
424 /**
425 \brief Set the drive goal pose
426
427 The goal is relative to the constraint frame of actor[0]
428
429 <b>Default</b> the identity transform
430
431 \param[in] pose The goal drive pose if positional drive is in use.
432 \param[in] autowake Whether to wake the joint rigids up if it is asleep.
433
434 @see setDrivePosition()
435 */
436 virtual void setDrivePosition(const PxTransform& pose, bool autowake = true) = 0;
437
438 /**
439 \brief Get the drive goal pose.
440
441 @see getDrivePosition()
442 */
443 virtual PxTransform getDrivePosition() const = 0;
444
445 /**
446 \brief Set the target goal velocity for drive.
447
448 The velocity is measured in the constraint frame of actor[0]
449
450 \param[in] linear The goal velocity for linear drive
451 \param[in] angular The goal velocity for angular drive
452 \param[in] autowake Whether to wake the joint rigids up if it is asleep.
453
454 @see getDriveVelocity()
455 */
456 virtual void setDriveVelocity(const PxVec3& linear, const PxVec3& angular, bool autowake = true) = 0;
457
458 /**
459 \brief Get the target goal velocity for joint drive.
460
461 \param[in] linear The goal velocity for linear drive
462 \param[in] angular The goal velocity for angular drive
463
464 @see setDriveVelocity()
465 */
466 virtual void getDriveVelocity(PxVec3& linear, PxVec3& angular) const = 0;
467
468 /**
469 \brief Set the linear tolerance threshold for projection. Projection is enabled if PxConstraintFlag::ePROJECTION
470 is set for the joint.
471
472 If the joint separates by more than this distance along its locked degrees of freedom, the solver
473 will move the bodies to close the distance.
474
475 Setting a very small tolerance may result in simulation jitter or other artifacts.
476
477 Sometimes it is not possible to project (for example when the joints form a cycle).
478
479 <b>Range:</b> [0, PX_MAX_F32)<br>
480 <b>Default:</b> 1e10f
481
482 \param[in] tolerance the linear tolerance threshold
483
484 @see getProjectionLinearTolerance() PxJoint::setConstraintFlags() PxConstraintFlag::ePROJECTION
485 */
486 virtual void setProjectionLinearTolerance(PxReal tolerance) = 0;
487
488 /**
489 \brief Get the linear tolerance threshold for projection.
490
491 \return the linear tolerance threshold
492
493 @see setProjectionLinearTolerance()
494 */
495 virtual PxReal getProjectionLinearTolerance() const = 0;
496
497 /**
498 \brief Set the angular tolerance threshold for projection. Projection is enabled if
499 PxConstraintFlag::ePROJECTION is set for the joint.
500
501 If the joint deviates by more than this angle around its locked angular degrees of freedom,
502 the solver will move the bodies to close the angle.
503
504 Setting a very small tolerance may result in simulation jitter or other artifacts.
505
506 Sometimes it is not possible to project (for example when the joints form a cycle).
507
508 <b>Range:</b> [0,Pi] <br>
509 <b>Default:</b> Pi
510
511 \param[in] tolerance the angular tolerance threshold in radians
512
513 \note
514 Angular projection is implemented only for the case of two or three locked angular degrees of freedom.
515
516 @see getProjectionAngularTolerance() PxJoint::setConstraintFlag() PxConstraintFlag::ePROJECTION
517 */
518 virtual void setProjectionAngularTolerance(PxReal tolerance) = 0;
519
520 /**
521 \brief Get the angular tolerance threshold for projection.
522
523 \return tolerance the angular tolerance threshold in radians
524
525 @see setProjectionAngularTolerance()
526 */
527 virtual PxReal getProjectionAngularTolerance() const = 0;
528
529 /**
530 \brief Returns string name of PxD6Joint, used for serialization
531 */
532 virtual const char* getConcreteTypeName() const { return "PxD6Joint"; }
533
534protected:
535
536 //serialization
537
538 /**
539 \brief Constructor
540 */
541 PX_INLINE PxD6Joint(PxType concreteType, PxBaseFlags baseFlags) : PxJoint(concreteType, baseFlags) {}
542
543 /**
544 \brief Deserialization constructor
545 */
546 PX_INLINE PxD6Joint(PxBaseFlags baseFlags) : PxJoint(baseFlags) {}
547
548 /**
549 \brief Returns whether a given type name matches with the type of this instance
550 */
551 virtual bool isKindOf(const char* name) const { return !::strcmp(s1: "PxD6Joint", s2: name) || PxJoint::isKindOf(name); }
552
553 //~serialization
554};
555
556#if !PX_DOXYGEN
557} // namespace physx
558#endif
559
560/** @} */
561#endif
562

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