D6Joint.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. namespace BansheeEngine
  4. {
  5. /// <summary>
  6. /// Represents the most customizable type of joint. This joint type can be used to create all other built-in joint
  7. /// types, and to design your own custom ones, but is less intuitive to use.Allows a specification of a linear
  8. /// constraint (for example for slider), twist constraint(rotating around X) and swing constraint(rotating around Y and
  9. /// Z). It also allows you to constrain limits to only specific axes or completely lock specific axes.
  10. /// </summary>
  11. public sealed class D6Joint : Joint
  12. {
  13. [SerializeField]
  14. private LimitLinear linearLimit = new LimitLinear();
  15. [SerializeField]
  16. private LimitAngularRange twistLimit = new LimitAngularRange();
  17. [SerializeField]
  18. private LimitConeRange swingLimit = new LimitConeRange();
  19. [SerializeField]
  20. private D6JointMotion[] motion = new D6JointMotion[(int)D6JointAxis.Count];
  21. [SerializeField]
  22. private D6JointDrive[] drives = new D6JointDrive[(int)D6JointDriveType.Count];
  23. [SerializeField]
  24. private Vector3 drivePosition = Vector3.Zero;
  25. [SerializeField]
  26. private Quaternion driveRotation = Quaternion.Identity;
  27. [SerializeField]
  28. private Vector3 driveLinearVelocity = Vector3.Zero;
  29. [SerializeField]
  30. private Vector3 driveAngularVelocity = Vector3.Zero;
  31. /// <summary>
  32. /// Returns the current rotation of the joint around the X axis.
  33. /// </summary>
  34. public Radian Twist
  35. {
  36. get
  37. {
  38. if (Native != null)
  39. return Native.Twist;
  40. return new Radian(0.0f);
  41. }
  42. }
  43. /// <summary>
  44. /// Returns the current rotation of the joint around the Y axis.
  45. /// </summary>
  46. public Radian SwingY
  47. {
  48. get
  49. {
  50. if (Native != null)
  51. return Native.SwingY;
  52. return new Radian(0.0f);
  53. }
  54. }
  55. /// <summary>
  56. /// Returns the current rotation of the joint around the Z axis.
  57. /// </summary>
  58. public Radian SwingZ
  59. {
  60. get
  61. {
  62. if (Native != null)
  63. return Native.SwingZ;
  64. return new Radian(0.0f);
  65. }
  66. }
  67. /// <summary>
  68. /// Linear limit used for constraining translation degrees of freedom.
  69. /// </summary>
  70. public LimitLinear LimitLinear
  71. {
  72. get { return linearLimit; }
  73. set
  74. {
  75. if (linearLimit == value)
  76. return;
  77. linearLimit = value;
  78. if (Native != null)
  79. Native.LimitLinear = value;
  80. }
  81. }
  82. /// <summary>
  83. /// Angular limit used for constraining the twist (rotation around X) degree of freedom.
  84. /// </summary>
  85. public LimitAngularRange LimitTwist
  86. {
  87. get { return twistLimit; }
  88. set
  89. {
  90. if (twistLimit == value)
  91. return;
  92. twistLimit = value;
  93. if (Native != null)
  94. Native.LimitTwist = value;
  95. }
  96. }
  97. /// <summary>
  98. /// Cone limit used for constraining the swing (rotation around Y and Z) degree of freedom.
  99. /// </summary>
  100. public LimitConeRange LimitSwing
  101. {
  102. get { return swingLimit; }
  103. set
  104. {
  105. if (swingLimit == value)
  106. return;
  107. swingLimit = value;
  108. if (Native != null)
  109. Native.LimitSwing = value;
  110. }
  111. }
  112. /// <summary>
  113. /// Determines the drive's target position relative to the joint's first body. This is the position the drive will
  114. /// attempt to reach if enabled.
  115. /// </summary>
  116. public Vector3 DrivePosition
  117. {
  118. get { return drivePosition; }
  119. set
  120. {
  121. if (drivePosition == value)
  122. return;
  123. drivePosition = value;
  124. if (Native != null)
  125. Native.DrivePosition = value;
  126. }
  127. }
  128. /// <summary>
  129. /// Determines the drive's target orientation relative to the joint's first body. This is the orientation the drive
  130. /// will attempt to reach if enabled.
  131. /// </summary>
  132. public Quaternion DriveRotation
  133. {
  134. get { return driveRotation; }
  135. set
  136. {
  137. if (driveRotation == value)
  138. return;
  139. driveRotation = value;
  140. if (Native != null)
  141. Native.DriveRotation = value;
  142. }
  143. }
  144. /// <summary>
  145. /// Determines the drive's target linear velocity. This is the velocity the drive will attempt to reach if enabled.
  146. /// </summary>
  147. public Vector3 DriveLinearVelocity
  148. {
  149. get { return driveLinearVelocity; }
  150. set
  151. {
  152. if (driveLinearVelocity == value)
  153. return;
  154. driveLinearVelocity = value;
  155. if (Native != null)
  156. Native.DriveLinearVelocity = value;
  157. }
  158. }
  159. /// <summary>
  160. /// Determines the drive's target angular velocity. This is the velocity the drive will attempt to reach if enabled.
  161. /// </summary>
  162. public Vector3 DriveAngularVelocity
  163. {
  164. get { return driveAngularVelocity; }
  165. set
  166. {
  167. if (driveAngularVelocity == value)
  168. return;
  169. driveAngularVelocity = value;
  170. if (Native != null)
  171. Native.DriveAngularVelocity = value;
  172. }
  173. }
  174. /// <summary>
  175. /// Returns the type of motion constrain for the specified axis.
  176. /// </summary>
  177. /// <param name="axis">Axis to retrieve the motion constrain for.</param>
  178. /// <returns>Motion constrain type for the axis.</returns>
  179. public D6JointMotion GetMotion(D6JointAxis axis)
  180. {
  181. return motion[(int) axis];
  182. }
  183. /// <summary>
  184. /// Allows you to constrain motion of the specified axis. Be aware that when setting drives for a specific axis
  185. /// you must also take care not to constrain its motion in a conflicting way(for example you cannot add a drive
  186. /// that moves the joint on X axis, and then lock the X axis).
  187. ///
  188. /// Unlocking translations degrees of freedom allows the bodies to move along the subset of the unlocked axes.
  189. /// (for example unlocking just one translational axis is the equivalent of a slider joint.)
  190. ///
  191. /// Angular degrees of freedom are partitioned as twist(around X axis) and swing(around Y and Z axes). Different
  192. /// effects can be achieves by unlocking their various combinations:
  193. /// - If a single degree of angular freedom is unlocked it should be the twist degree as it has extra options for
  194. /// that case (for example for a hinge joint).
  195. /// - If both swing degrees are unlocked but twist is locked the result is a zero-twist joint.
  196. /// - If one swing and one twist degree of freedom are unlocked the result is a zero-swing joint (for example an
  197. /// arm attached at the elbow)
  198. /// - If all angular degrees of freedom are unlocked the result is the same as the spherical joint.
  199. /// </summary>
  200. /// <param name="axis">Axis to change the motion type for.</param>
  201. /// <param name="motion">Type of motion for the axis.</param>
  202. public void SetMotion(D6JointAxis axis, D6JointMotion motion)
  203. {
  204. if (this.motion[(int)axis] == motion)
  205. return;
  206. this.motion[(int)axis] = motion;
  207. if (Native != null)
  208. Native.SetMotion(axis, motion);
  209. }
  210. /// <summary>
  211. /// Returns properties for the specified drive type.
  212. /// </summary>
  213. /// <param name="type">Type of drive to retrieve properties for.</param>
  214. /// <returns>Properties for the requested drive type.</returns>
  215. public D6JointDrive GetDrive(D6JointDriveType type)
  216. {
  217. return drives[(int) type];
  218. }
  219. /// <summary>
  220. /// Sets a drive that will attempt to move the specified degree(s) of freedom to the wanted position and velocity.
  221. /// </summary>
  222. /// <param name="type">Type of the drive.</param>
  223. /// <param name="drive">Drive properties.</param>
  224. public void SetDrive(D6JointDriveType type, D6JointDrive drive)
  225. {
  226. if (this.drives[(int)type] == drive)
  227. return;
  228. this.drives[(int)type] = drive;
  229. if (Native != null)
  230. Native.SetDrive(type, drive);
  231. }
  232. /// <summary>
  233. /// Returns the native joint wrapped by this component.
  234. /// </summary>
  235. private NativeD6Joint Native
  236. {
  237. get { return (NativeD6Joint)native; }
  238. }
  239. /// <inheritdoc/>
  240. internal override NativeJoint CreateNative()
  241. {
  242. NativeD6Joint joint = new NativeD6Joint();
  243. // TODO - Apply this all at once to avoid all the individual interop function calls
  244. joint.LimitLinear = linearLimit;
  245. joint.LimitTwist = twistLimit;
  246. joint.LimitSwing = swingLimit;
  247. for (int i = 0; i < (int) D6JointAxis.Count; i++)
  248. joint.SetMotion((D6JointAxis) i, motion[i]);
  249. for (int i = 0; i < (int)D6JointDriveType.Count; i++)
  250. joint.SetDrive((D6JointDriveType)i, drives[i]);
  251. joint.DrivePosition = drivePosition;
  252. joint.DriveRotation = driveRotation;
  253. joint.DriveLinearVelocity = driveLinearVelocity;
  254. joint.DriveAngularVelocity = driveAngularVelocity;
  255. return joint;
  256. }
  257. }
  258. }