PageRenderTime 26ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 0ms

/PhysicsEngines/Jitter/JitterJoint.cs

#
C# | 355 lines | 264 code | 50 blank | 41 comment | 19 complexity | 3757ba4ab528c43f6c14f1eb9bb3856a MD5 | raw file
Possible License(s): Apache-2.0
  1. using Delta.PhysicsEngines.Enums;
  2. using Delta.Utilities;
  3. using Delta.Utilities.Datatypes;
  4. using Delta.Utilities.Helpers;
  5. using Jitter.Dynamics;
  6. using Jitter.Dynamics.Constraints;
  7. using Jitter.Dynamics.Joints;
  8. using Jitter.LinearMath;
  9. using SingleBodyConstraints = Jitter.Dynamics.Constraints.SingleBody;
  10. namespace Delta.PhysicsEngines.Jitter
  11. {
  12. /// <summary>
  13. /// JItter joint implementation
  14. /// </summary>
  15. internal class JitterJoint : PhysicsJoint
  16. {
  17. #region Constraint (Public)
  18. /// <summary>
  19. /// Gets jitter Constraint
  20. /// </summary>
  21. public Constraint Constraint
  22. {
  23. get;
  24. private set;
  25. }
  26. #endregion
  27. #region Joint (Public)
  28. /// <summary>
  29. /// Gets jitter Joint.
  30. /// </summary>
  31. public Joint Joint
  32. {
  33. get;
  34. private set;
  35. }
  36. #endregion
  37. #region Softness (Public)
  38. /// <summary>
  39. /// Defines how big the applied impulses can get.
  40. /// </summary>
  41. /// <value>
  42. /// The softness.
  43. /// </value>
  44. public override float Softness
  45. {
  46. get
  47. {
  48. return base.Softness;
  49. }
  50. set
  51. {
  52. if (Constraint is FixedAngle)
  53. {
  54. (Constraint as FixedAngle).Softness = value;
  55. }
  56. if (Constraint is PointOnLine)
  57. {
  58. (Constraint as PointOnLine).Softness = value;
  59. }
  60. if (Constraint is PointOnPoint)
  61. {
  62. (Constraint as PointOnPoint).Softness = value;
  63. }
  64. if (
  65. Constraint is global::Jitter.Dynamics.Constraints.SingleBody.PointOnPoint)
  66. {
  67. (Constraint as global::Jitter.Dynamics.Constraints.SingleBody.PointOnPoint)
  68. .Softness = value;
  69. }
  70. base.Softness = value;
  71. }
  72. }
  73. #endregion
  74. #region Anchor1 (Public)
  75. /// <summary>
  76. /// The anchor 1 point in the world.
  77. /// </summary>
  78. /// <value>
  79. /// The anchor1.
  80. /// </value>
  81. public override Vector Anchor1
  82. {
  83. get
  84. {
  85. return base.Anchor1;
  86. }
  87. set
  88. {
  89. if (Constraint is PointPointDistance)
  90. {
  91. (Constraint as PointPointDistance).LocalAnchor1 =
  92. JitterDatatypesMapping.Convert(ref value);
  93. }
  94. if (
  95. Constraint is global::Jitter.Dynamics.Constraints.SingleBody.PointOnPoint)
  96. {
  97. (Constraint as global::Jitter.Dynamics.Constraints.SingleBody.PointOnPoint)
  98. .Anchor =
  99. JitterDatatypesMapping.Convert(ref value);
  100. }
  101. base.Anchor1 = value;
  102. }
  103. }
  104. #endregion
  105. #region Anchor2 (Public)
  106. /// <summary>
  107. /// The anchor 2 point in the world.
  108. /// </summary>
  109. /// <value>
  110. /// The anchor2.
  111. /// </value>
  112. public override Vector Anchor2
  113. {
  114. get
  115. {
  116. return base.Anchor2;
  117. }
  118. set
  119. {
  120. if (Constraint is PointPointDistance)
  121. {
  122. (Constraint as PointPointDistance).LocalAnchor2 =
  123. JitterDatatypesMapping.Convert(ref value);
  124. }
  125. base.Anchor2 = value;
  126. }
  127. }
  128. #endregion
  129. #region Private
  130. #region physicsManager (Private)
  131. private readonly JitterPhysics physicsManager;
  132. #endregion
  133. #endregion
  134. #region Constructors
  135. /// <summary>
  136. /// Initializes a new instance of the <see cref="JitterJoint"/> class.
  137. /// </summary>
  138. /// <param name="physicsManager">The physics manager.</param>
  139. /// <param name="jointType">Type of the joint.</param>
  140. /// <param name="bodyA">The body A.</param>
  141. /// <param name="bodyB">The body B.</param>
  142. /// <param name="args">The args.</param>
  143. public JitterJoint(
  144. JitterPhysics physicsManager,
  145. JointType jointType,
  146. PhysicsBody bodyA,
  147. PhysicsBody bodyB, object[] args)
  148. : base(jointType, bodyA, bodyB, args)
  149. {
  150. this.physicsManager = physicsManager;
  151. CreateJoint();
  152. }
  153. #endregion
  154. #region Methods (Private)
  155. #region CreateJoint
  156. /// <summary>
  157. /// Creates jitter joint.
  158. /// </summary>
  159. private void CreateJoint()
  160. {
  161. RigidBody rigidBodyA = (BodyA as JitterBody).Body;
  162. RigidBody rigidBodyB = BodyB != null
  163. ? (BodyB as JitterBody).Body
  164. : null;
  165. Vector tempVector;
  166. switch (JointType)
  167. {
  168. case JointType.FixedAngle:
  169. #region FixedAngle
  170. // Do we create single body joint?
  171. if (rigidBodyB != null)
  172. {
  173. Constraint = new FixedAngle(rigidBodyA, rigidBodyB);
  174. }
  175. else
  176. {
  177. Constraint =
  178. new global::Jitter.Dynamics.Constraints.SingleBody.FixedAngle(rigidBodyA);
  179. }
  180. #endregion
  181. break;
  182. case JointType.PointOnLine:
  183. #region PointOnLine
  184. JVector lineStartPointBody1;
  185. tempVector = ArrayHelper.SafeGet<PropertyType, Vector>(
  186. Properties, PropertyType.LineStartPointBody);
  187. JitterDatatypesMapping.Convert(ref tempVector,
  188. out lineStartPointBody1);
  189. JVector pointBody2;
  190. tempVector = ArrayHelper.SafeGet<PropertyType, Vector>(
  191. Properties, PropertyType.PointBody);
  192. JitterDatatypesMapping.Convert(ref tempVector,
  193. out pointBody2);
  194. // Do we create single body joint?
  195. if (rigidBodyB != null)
  196. {
  197. Constraint = new PointOnLine(rigidBodyA, rigidBodyB,
  198. lineStartPointBody1, pointBody2);
  199. }
  200. {
  201. Log.Warning("You're trying to create PointOnLine with second " +
  202. "body at null.Maybe you should create SingleBodyPointOnLine.");
  203. }
  204. #endregion
  205. break;
  206. case JointType.PointOnPoint:
  207. #region PointOnPoint
  208. JVector localAnchor;
  209. tempVector = ArrayHelper.SafeGet<PropertyType, Vector>(
  210. Properties, PropertyType.Anchor1);
  211. JitterDatatypesMapping.Convert(ref tempVector, out localAnchor);
  212. // Do we create single body point on point ?
  213. if (rigidBodyB != null)
  214. {
  215. Constraint = new PointOnPoint(rigidBodyA, rigidBodyB, localAnchor);
  216. }
  217. else
  218. {
  219. Constraint =
  220. new global::Jitter.Dynamics.Constraints.SingleBody.PointOnPoint(
  221. rigidBodyA,
  222. localAnchor);
  223. }
  224. #endregion
  225. break;
  226. case JointType.PointPointDistance:
  227. #region PointPointDistance
  228. JVector anchor1;
  229. tempVector = ArrayHelper.SafeGet<PropertyType, Vector>(
  230. Properties, PropertyType.Anchor1);
  231. JitterDatatypesMapping.Convert(ref tempVector, out anchor1);
  232. JVector anchor2;
  233. tempVector = ArrayHelper.SafeGet<PropertyType, Vector>(
  234. Properties, PropertyType.Anchor2);
  235. JitterDatatypesMapping.Convert(ref tempVector, out anchor2);
  236. Constraint = new PointPointDistance(rigidBodyA, rigidBodyB,
  237. anchor1, anchor2);
  238. #endregion
  239. break;
  240. case JointType.Hinge:
  241. #region Hinge
  242. JVector position;
  243. tempVector = ArrayHelper.SafeGet<PropertyType, Vector>(
  244. Properties, PropertyType.Position);
  245. JitterDatatypesMapping.Convert(ref tempVector, out position);
  246. JVector hingeAxis;
  247. tempVector = ArrayHelper.SafeGet<PropertyType, Vector>(
  248. Properties, PropertyType.HingeAxis);
  249. JitterDatatypesMapping.Convert(ref tempVector, out hingeAxis);
  250. Joint = new HingeJoint(physicsManager.jitterWorld, rigidBodyA,
  251. rigidBodyB, position, hingeAxis);
  252. #endregion
  253. break;
  254. case JointType.Prismatic:
  255. #region Prismatic
  256. Joint = new PrismaticJoint(
  257. physicsManager.jitterWorld,
  258. rigidBodyA,
  259. rigidBodyB,
  260. ArrayHelper.SafeGet<PropertyType, float>(
  261. Properties, PropertyType.MinimumDistance),
  262. ArrayHelper.SafeGet<PropertyType, float>(
  263. Properties, PropertyType.MaximumDistance)
  264. );
  265. float minimumSoftness =
  266. ArrayHelper.SafeGet<PropertyType, float>(
  267. Properties, PropertyType.MinimumSoftness);
  268. float maximumSoftness =
  269. ArrayHelper.SafeGet<PropertyType, float>(
  270. Properties, PropertyType.MaximumSoftness);
  271. (Joint as PrismaticJoint).MaximumDistanceConstraint.Softness =
  272. maximumSoftness;
  273. (Joint as PrismaticJoint).MinimumDistanceConstraint.Softness =
  274. minimumSoftness;
  275. #endregion
  276. break;
  277. case JointType.SingleBodyPointOnLine:
  278. #region SingleBodyPointOnLine
  279. JVector anchor;
  280. tempVector = ArrayHelper.SafeGet<PropertyType, Vector>(
  281. Properties, PropertyType.Anchor1);
  282. JitterDatatypesMapping.Convert(ref tempVector, out anchor);
  283. JVector lineDirection;
  284. tempVector = ArrayHelper.SafeGet<PropertyType, Vector>(
  285. Properties, PropertyType.LineDirection);
  286. JitterDatatypesMapping.Convert(ref tempVector, out lineDirection);
  287. Constraint =
  288. new global::Jitter.Dynamics.Constraints.SingleBody.PointOnLine(rigidBodyA,
  289. anchor, lineDirection);
  290. #endregion
  291. break;
  292. }
  293. if (Constraint != null)
  294. {
  295. physicsManager.jitterWorld.AddConstraint(Constraint);
  296. }
  297. if (Joint != null)
  298. {
  299. Joint.Activate();
  300. }
  301. }
  302. #endregion
  303. #endregion
  304. }
  305. }