BsD6Joint.h 8.0 KB

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