2
0

BsD6Joint.h 7.6 KB

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