| 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 | |