PageRenderTime 205ms CodeModel.GetById 81ms app.highlight 13ms RepoModel.GetById 107ms app.codeStats 1ms

/PhysicsEngines/Jitter/JitterJoint.cs

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