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