BsD6Joint.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsCorePrerequisites.h"
  5. #include "BsJoint.h"
  6. namespace BansheeEngine
  7. {
  8. /** @addtogroup Physics
  9. * @{
  10. */
  11. /**
  12. * Represents the most customizable type of joint. This joint type can be used to create all other built-in joint
  13. * types, and to design your own custom ones, but is less intuitive to use. Allows a specification of a linear
  14. * constraint (for example for slider), twist constraint (rotating around X) and swing constraint (rotating around Y and
  15. * Z). It also allows you to constrain limits to only specific axes or completely lock specific axes.
  16. */
  17. class BS_CORE_EXPORT D6Joint : public Joint
  18. {
  19. public:
  20. /** Specifies axes that the D6 joint can constrain motion on. */
  21. enum class Axis
  22. {
  23. X, /**< Movement on the X axis. */
  24. Y, /**< Movement on the Y axis. */
  25. Z, /**< Movement on the Z axis. */
  26. Twist, /**< Rotation around the X axis. */
  27. SwingY, /**< Rotation around the Y axis. */
  28. SwingZ, /**< Rotation around the Z axis. */
  29. Count
  30. };
  31. /** Specifies type of constraint placed on a specific axis. */
  32. enum class Motion
  33. {
  34. Locked, /**< Axis is immovable. */
  35. Limited, /**< Axis will be constrained by the specified limits. */
  36. Free, /**< Axis will not be constrained. */
  37. Count
  38. };
  39. /** Type of drives that can be used for moving or rotating bodies attached to the joint. */
  40. enum class DriveType
  41. {
  42. X, /**< Linear movement on the X axis using the linear drive model. */
  43. Y, /**< Linear movement on the Y axis using the linear drive model. */
  44. Z, /**< Linear movement on the Z axis using the linear drive model. */
  45. /**
  46. * Rotation around the Y axis using the twist/swing angular drive model. Should not be used together with
  47. * SLERP mode.
  48. */
  49. Swing,
  50. /**
  51. * Rotation around the Z axis using the twist/swing angular drive model. Should not be used together with
  52. * SLERP mode.
  53. */
  54. Twist,
  55. /**
  56. * Rotation using spherical linear interpolation. Uses the SLERP angular drive mode which performs rotation
  57. * by interpolating the quaternion values directly over the shortest path (applies to all three axes, which
  58. * they all must be unlocked).
  59. */
  60. SLERP,
  61. Count
  62. };
  63. /**
  64. * Specifies parameters for a drive that will attempt to move the joint bodies to the specified drive position and
  65. * velocity.
  66. */
  67. struct Drive
  68. {
  69. bool operator==(const Drive& other) const
  70. {
  71. return stiffness == other.stiffness && damping == other.damping && forceLimit == other.forceLimit &&
  72. acceleration == other.acceleration;
  73. }
  74. /** Spring strength. Force proportional to the position error. */
  75. float stiffness = 0.0f;
  76. /** Damping strength. Force propertional to the velocity error. */
  77. float damping = 0.0f;
  78. /** Maximum force the drive can apply. */
  79. float forceLimit = FLT_MAX;
  80. /**
  81. * If true the drive will generate acceleration instead of forces. Acceleration drives are easier to tune as
  82. * they account for the masses of the actors to which the joint is attached.
  83. */
  84. bool acceleration = false;
  85. };
  86. public:
  87. virtual ~D6Joint() { }
  88. /**
  89. * Returns motion constraint for the specified axis.
  90. *
  91. * @see setMotion
  92. */
  93. virtual Motion getMotion(Axis axis) const = 0;
  94. /**
  95. * Allows you to constrain motion of the specified axis. Be aware that when setting drives for a specific axis
  96. * you must also take care not to constrain its motion in a conflicting way (for example you cannot add a drive that
  97. * moves the joint on X axis, and then lock the X axis).
  98. *
  99. * Unlocking translations degrees of freedom allows the bodies to move along the subset of the unlocked axes.
  100. * (for example unlocking just one translational axis is the equivalent of a slider joint.)
  101. *
  102. * Angular degrees of freedom are partitioned as twist (around X axis) and swing (around Y and Z axes). Different
  103. * effects can be achieves by unlocking their various combinations:
  104. * - If a single degree of angular freedom is unlocked it should be the twist degree as it has extra options for
  105. * that case (for example for a hinge joint).
  106. * - If both swing degrees are unlocked but twist is locked the result is a zero-twist joint.
  107. * - If one swing and one twist degree of freedom are unlocked the result is a zero-swing joint (for example an arm
  108. * attached at the elbow)
  109. * - If all angular degrees of freedom are unlocked the result is the same as the spherical joint.
  110. */
  111. virtual void setMotion(Axis axis, Motion motion) = 0;
  112. /** Returns the current rotation of the joint around the X axis. */
  113. virtual Radian getTwist() const = 0;
  114. /** Returns the current rotation of the joint around the Y axis. */
  115. virtual Radian getSwingY() const = 0;
  116. /** Returns the current rotation of the joint around the Z axis. */
  117. virtual Radian getSwingZ() const = 0;
  118. /** Returns the linear limit used for constraining translation degrees of freedom. */
  119. virtual LimitLinear getLimitLinear() const = 0;
  120. /** Sets the linear limit used for constraining translation degrees of freedom. */
  121. virtual void setLimitLinear(const LimitLinear& limit) = 0;
  122. /** Returns the angular limit used for constraining the twist (rotation around X) degree of freedom. */
  123. virtual LimitAngularRange getLimitTwist() const = 0;
  124. /** Sets the angular limit used for constraining the twist (rotation around X) degree of freedom. */
  125. virtual void setLimitTwist(const LimitAngularRange& limit) = 0;
  126. /** Returns the cone limit used for constraining the swing (rotation around Y and Z) degree of freedom. */
  127. virtual LimitConeRange getLimitSwing() const = 0;
  128. /** Sets the cone limit used for constraining the swing (rotation around Y and Z) degree of freedom. */
  129. virtual void setLimitSwing(const LimitConeRange& limit) = 0;
  130. /**
  131. * Returns a drive that will attempt to move the specified degree(s) of freedom to the wanted position and velocity.
  132. */
  133. virtual Drive getDrive(DriveType type) const = 0;
  134. /**
  135. * Sets a drive that will attempt to move the specified degree(s) of freedom to the wanted position and velocity.
  136. */
  137. virtual void setDrive(DriveType type, const Drive& drive) = 0;
  138. /** Returns the drive's target position relative to the joint's first body. */
  139. virtual Vector3 getDrivePosition() const = 0;
  140. /** Returns the drive's target rotation relative to the joint's first body. */
  141. virtual Quaternion getDriveRotation() const = 0;
  142. /** Sets the drive's target position and rotation relative to the joint's first body. */
  143. virtual void setDriveTransform(const Vector3& position, const Quaternion& rotation) = 0;
  144. /** Returns the drive's target linear velocity. */
  145. virtual Vector3 getDriveLinearVelocity() const = 0;
  146. /** Returns the drive's target angular velocity. */
  147. virtual Vector3 getDriveAngularVelocity() const = 0;
  148. /** Sets the drive's target linear and angular velocities. */
  149. virtual void setDriveVelocity(const Vector3& linear, const Vector3& angular) = 0;
  150. /** Creates a new D6 joint. */
  151. static SPtr<D6Joint> create();
  152. };
  153. /** @} */
  154. }