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
25namespace physx
26{
27#endif
28
29class 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
43PxD6Joint* 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
56struct 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*/
76struct 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
90Each drive is an implicit force-limited damped spring:
91
92force = spring * (target position - position) + damping * (targetVelocity - velocity)
93
94Alternatively, the spring may be configured to generate a specified acceleration instead of a force.
95
96A linear axis is affected by drive only if the corresponding drive flag is set. There are two possible models
97for angular drive: swing/twist, which may be used to drive one or more angular degrees of freedom, or slerp,
98which may only be used to drive all three angular degrees simultaneously.
99
100@see PxD6Joint
101*/
102
103struct 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
123struct PxD6JointDriveFlag
124{
125 enum Enum
126 {
127 eACCELERATION = 1 //!< drive spring is for the acceleration at the joint (rather than the force)
128 };
129};
130typedef PxFlags<PxD6JointDriveFlag::Enum, PxU32> PxD6JointDriveFlags;
131PX_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
140class 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
149public:
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
221class PxD6Joint : public PxJoint
222{
223public:
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
483protected:
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