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 |
41 | namespace physx |
42 | { |
43 | #endif |
44 | |
45 | class 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 | */ |
58 | PxD6Joint* 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 | */ |
65 | struct 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 | */ |
85 | struct 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 | |
99 | Each drive is an implicit force-limited damped spring: |
100 | |
101 | force = spring * (target position - position) + damping * (targetVelocity - velocity) |
102 | |
103 | Alternatively, the spring may be configured to generate a specified acceleration instead of a force. |
104 | |
105 | A linear axis is affected by drive only if the corresponding drive flag is set. There are two possible models |
106 | for angular drive: swing/twist, which may be used to drive one or more angular degrees of freedom, or slerp, |
107 | which may only be used to drive all three angular degrees simultaneously. |
108 | |
109 | @see PxD6Joint |
110 | */ |
111 | struct 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 | */ |
130 | struct PxD6JointDriveFlag |
131 | { |
132 | enum Enum |
133 | { |
134 | eACCELERATION = 1 //!< drive spring is for the acceleration at the joint (rather than the force) |
135 | }; |
136 | }; |
137 | typedef PxFlags<PxD6JointDriveFlag::Enum, PxU32> PxD6JointDriveFlags; |
138 | PX_FLAGS_OPERATORS(PxD6JointDriveFlag::Enum, PxU32) |
139 | |
140 | /** |
141 | \brief parameters for configuring the drive model of a PxD6Joint |
142 | |
143 | @see PxD6Joint |
144 | */ |
145 | class 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 | |
154 | public: |
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 | */ |
224 | class PxD6Joint : public PxJoint |
225 | { |
226 | public: |
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 | |
534 | protected: |
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 | |