/PhysicsEngines/Jitter/JitterBody.cs
C# | 521 lines | 346 code | 47 blank | 128 comment | 4 complexity | dde6c5eeb4661de6c078fb8741b3a6df MD5 | raw file
Possible License(s): Apache-2.0
- using System.Collections.Generic;
- using Delta.PhysicsEngines.Enums;
- using Delta.Rendering.Models;
- using Delta.Utilities.Datatypes;
- using Delta.Utilities.Helpers;
- using Jitter.Collision.Shapes;
- using Jitter.Dynamics;
- using Jitter.LinearMath;
-
- namespace Delta.PhysicsEngines.Jitter
- {
- /// <summary>
- /// Jitter body implementation.
- /// </summary>
- internal class JitterBody : PhysicsBody
- {
- #region Body (Public)
- /// <summary>
- /// Gets the body.
- /// </summary>
- public RigidBody Body
- {
- get
- {
- return jitterBody;
- }
- }
- #endregion
-
- #region Position (Public)
- /// <summary>
- /// Position given in world space.
- /// </summary>
- public override Vector Position
- {
- get
- {
- JitterDatatypesMapping.Convert(jitterBody.Position, out position);
- return position;
- }
- set
- {
- jitterBody.Position = JitterDatatypesMapping.Convert(ref value);
- }
- }
- #endregion
-
- #region Position2D (Public)
- /// <summary>
- /// Position 2D given in world space (same as Position, just easier to
- /// access for 2D code not having to convert Position to a Point anymore).
- /// </summary>
- public override Point Position2D
- {
- get
- {
- position2D.X = jitterBody.Position.X;
- position2D.Y = jitterBody.Position.Y;
- return position2D;
- }
- set
- {
- // This is 3D physics engine, so do nothing by default.
- }
- }
- #endregion
-
- #region RotationMatrix (Public)
- /// <summary>
- /// Returns the rotation matrix from Jitter back for rendering.
- /// </summary>
- public override Matrix RotationMatrix
- {
- get
- {
- JitterDatatypesMapping.Convert(jitterBody.Orientation,
- ref rotationMatrix);
- return rotationMatrix;
- }
- set
- {
- if (jitterBody != null)
- {
- jitterBody.Orientation = JitterDatatypesMapping.Convert(ref value);
- }
- }
- }
- #endregion
-
- #region LinearVelocity (Public)
- /// <summary>
- /// The linear velocity of the body.
- /// </summary>
- public override Vector LinearVelocity
- {
- get
- {
- JitterDatatypesMapping.Convert(jitterBody.LinearVelocity,
- out linearVelocity);
- return linearVelocity;
- }
- set
- {
- jitterBody.LinearVelocity = JitterDatatypesMapping.Convert(ref value);
- }
- }
- #endregion
-
- #region AngularVelocity (Public)
- /// <summary>
- /// The angular velocity of the body.
- /// <remarks>
- /// For 2D physics simulation only X component is used.
- /// </remarks>
- /// </summary>
- public override Vector AngularVelocity
- {
- get
- {
- JitterDatatypesMapping.Convert(jitterBody.AngularVelocity,
- out angularVelocity);
- return angularVelocity;
- }
- set
- {
- jitterBody.AngularVelocity = JitterDatatypesMapping.Convert(ref value);
- }
- }
- #endregion
-
- #region AngularVelocity2D (Public)
- /// <summary>
- /// Angular velocity 2D as a float, for 2D only the .x component is used!
- /// </summary>
- public override float AngularVelocity2D
- {
- get
- {
- return jitterBody.AngularVelocity.X;
- }
- set
- {
- jitterBody.AngularVelocity = new JVector(value, 0f, 0f);
- }
- }
- #endregion
-
- #region Mass (Public)
- /// <summary>
- /// Gets or sets the mass. Usually in kilograms (kg).
- /// </summary>
- public override float Mass
- {
- get
- {
- return base.Mass;
- }
- set
- {
- jitterBody.Mass = value;
- }
- }
- #endregion
-
- #region Restitution (Public)
- /// <summary>
- /// Gets the restitution of the body.
- /// </summary>
- public override float Restitution
- {
- get
- {
- return base.Restitution;
- }
- set
- {
- jitterBody.Material.Restitution = value;
- base.Restitution = value;
- }
- }
- #endregion
-
- #region BoundingBox (Public)
- /// <summary>
- /// Gets the BoundingBox of the body.
- /// <remarks>
- /// Used during 3D simulation.
- /// </remarks>
- /// </summary>
- public override BoundingBox BoundingBox
- {
- get
- {
- JitterDatatypesMapping.Convert(jitterBody.BoundingBox.Min,
- out bounds.Min);
- JitterDatatypesMapping.Convert(jitterBody.BoundingBox.Max,
- out bounds.Max);
- return bounds;
- }
- }
- #endregion
-
- #region Private
-
- #region physicsManager (Private)
- private JitterPhysics physicsManager;
- #endregion
-
- #region jitterBody (Private)
- private readonly RigidBody jitterBody;
- #endregion
-
- #region jitterShape (Private)
- private Shape jitterShape;
- #endregion
-
- #region position (Private)
- private Vector position;
- #endregion
-
- #region position2D (Private)
- private Point position2D;
- #endregion
-
- #region rotationMatrix (Private)
- /// <summary>
- /// Create rotation matrix to be filled in by the Jitter matrix. It is
- /// very important that M44 is set to 1.0 to be rendered correctly!
- /// </summary>
- private Matrix rotationMatrix = Matrix.Identity;
- #endregion
-
- #region linearVelocity (Private)
- private Vector linearVelocity;
- #endregion
-
- #region angularVelocity (Private)
- private Vector angularVelocity;
- #endregion
-
- #region bounds (Private)
- private BoundingBox bounds;
- #endregion
-
- #endregion
-
- #region Constructors
- /// <summary>
- /// Constructor
- /// </summary>
- /// <param name="physicsManager">The physics manager.</param>
- /// <param name="shape">The shape.</param>
- /// <param name="setInitialPosition">Body initial position.</param>
- public JitterBody(JitterPhysics physicsManager, PhysicsShape shape,
- Vector setInitialPosition)
- : base(false, shape, setInitialPosition)
- {
- this.physicsManager = physicsManager;
-
- // First create shape
- CreateShape();
- // And set the rotation matrix again (needs created shape)
- RotationMatrix = Matrix.Identity;
-
- // Jitter needs the shape on body creation.
- jitterBody = new RigidBody(jitterShape);
- jitterBody.IsStatic = false;
- jitterBody.Mass = base.mass;
- jitterBody.Material.Restitution = base.restitution;
- jitterBody.Position =
- JitterDatatypesMapping.Convert(ref setInitialPosition);
-
- jitterBody.Tag = this;
-
- physicsManager.jitterWorld.AddBody(jitterBody);
- }
-
- /// <summary>
- /// Internal constructor for creating GroundBody.
- /// </summary>
- /// <param name="physicsManager">Jitter physics manager.</param>
- /// <param name="jitterBody">Initial jitter body created manually.</param>
- internal JitterBody(JitterPhysics physicsManager, RigidBody jitterBody)
- : base(false, null, Vector.Zero)
- {
- this.physicsManager = physicsManager;
- this.jitterBody = jitterBody;
- this.jitterBody.Tag = this;
- jitterShape = jitterBody.Shape;
- }
- #endregion
-
- #region ApplyForce (Public)
- /// <summary>
- /// Applies a force at the center of mass.
- /// </summary>
- /// <param name="force">The force.</param>
- public override void ApplyForce(Vector force)
- {
- jitterBody.AddForce(JitterDatatypesMapping.Convert(ref force));
- }
-
- /// <summary>
- /// Apply a force at a world point. If the force is not
- /// applied at the center of mass, it will generate a torque and
- /// affect the angular velocity. This wakes up the body.
- /// </summary>
- /// <param name="force">Force vector data.</param>
- /// <param name="position">Position in 3D where to apply force.</param>
- public override void ApplyForce(Vector force, Vector position)
- {
- jitterBody.AddForce(
- JitterDatatypesMapping.Convert(ref force),
- JitterDatatypesMapping.Convert(ref position)
- );
- }
- #endregion
-
- #region ApplyTorque (Public)
- /// <summary>
- /// Apply a torque. This affects the angular velocity without affecting the
- /// linear velocity of the center of mass.
- /// <remarks>
- /// This wakes up the body.
- /// </remarks>
- /// </summary>
- /// <param name="torque">
- /// Vector containing torque data for both 2D and 3D shapes.
- /// </param>
- public override void ApplyTorque(Vector torque)
- {
- jitterBody.AddTorque(JitterDatatypesMapping.Convert(ref torque));
- }
- #endregion
-
- #region ApplyLinearImpulse (Public)
- /// <summary>
- /// Apply an impulse at a point. This immediately modifies the velocity.
- /// <remarks>
- /// This wakes up the body.
- /// </remarks>
- /// </summary>
- /// <param name="impulse">Impulse vector data.</param>
- public override void ApplyLinearImpulse(Vector impulse)
- {
- jitterBody.ApplyImpulse(JitterDatatypesMapping.Convert(ref impulse));
- }
-
- /// <summary>
- /// Apply an impulse at a point. This immediately modifies the velocity.
- /// It also modifies the angular velocity if the point of application
- /// is not at the center of mass.
- /// <remarks>
- /// This wakes up the body.
- /// </remarks>
- /// </summary>
- /// <param name="impulse">Impulse vector data.</param>
- /// <param name="position">Position in 3D where to apply impulse.</param>
- public override void ApplyLinearImpulse(Vector impulse, Vector position)
- {
- jitterBody.ApplyImpulse(
- JitterDatatypesMapping.Convert(ref impulse),
- JitterDatatypesMapping.Convert(ref position));
- }
- #endregion
-
- #region ApplyAngularImpulse (Public)
- /// <summary>
- /// Apply an angular impulse.
- /// </summary>
- /// <param name="impulse">
- /// Vector containing impulse data for both 2D and 3D shapes.
- /// </param>
- public override void ApplyAngularImpulse(Vector impulse)
- {
- jitterBody.ApplyImpulse(JitterDatatypesMapping.Convert(ref impulse));
- }
- #endregion
-
- #region Methods (Private)
-
- #region CreateShape
- /// <summary>
- /// Creates Jitter shape from properties.
- /// </summary>
- private void CreateShape()
- {
- Dictionary<PhysicsShape.PropertyType, object> properties =
- base.Shape.Properties;
- switch (Shape.ShapeType)
- {
- case ShapeType.Sphere:
- jitterShape = new SphereShape(
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.Radius));
- break;
- case ShapeType.Box:
- Vector size =
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, Vector>(
- properties, PhysicsShape.PropertyType.Size);
- jitterShape = new BoxShape(
- size.Y, size.Z, size.X
- );
- break;
-
- case ShapeType.Capsule:
- jitterShape = new CapsuleShape(
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.Depth),
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.Radius)
- );
- break;
-
- case ShapeType.Cone:
- jitterShape = new ConeShape(
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.Height),
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.Radius)
- );
- break;
-
- case ShapeType.Cylinder:
- jitterShape = new CylinderShape(
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.Height),
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.Radius)
- );
- break;
-
- case ShapeType.Triangle:
- jitterShape = Helpers.CreateFrom(
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, Mesh>(
- properties, PhysicsShape.PropertyType.Mesh),
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, Matrix>(
- properties, PhysicsShape.PropertyType.LocalSpaceMatrix),
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, bool>(
- properties, PhysicsShape.PropertyType.InvertTriangles));
- break;
-
- case ShapeType.Terrain:
- jitterShape = new TerrainShape(
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float[,]>(
- properties, PhysicsShape.PropertyType.Height),
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.ScaleX),
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.ScaleY)
- );
- break;
- }
- }
- #endregion
-
- #region FireCollisionBegin
- /// <summary>
- /// Method for access collision event from JitterPhysicsManager.
- /// </summary>
- /// <param name="other">Other body with which collision begin.</param>
- internal void FireCollisionBegin(PhysicsBody other)
- {
- base.OnCollisionBegin(other);
- }
- #endregion
-
- #region FireCollisionEnd
- /// <summary>
- /// Method for access collision event from JitterPhysicsManager.
- /// </summary>
- /// <param name="other">Other body with which collision end.</param>
- internal void FireCollisionEnd(PhysicsBody other)
- {
- base.OnCollisionEnd(other);
- }
- #endregion
-
- #region SetIsStatic
- /// <summary>
- /// Set if the body should be static or not.
- /// </summary>
- /// <param name="value">True if body should be static, otherwise False.
- /// </param>
- protected override void SetIsStatic(bool value)
- {
- jitterBody.IsStatic = value;
- }
- #endregion
-
- #region SetIsActive
- /// <summary>
- /// Set if the body should be active or not.
- /// </summary>
- /// <param name="value">True if body should be active, otherwise False.
- /// </param>
- protected override void SetIsActive(bool value)
- {
- jitterBody.IsActive = value;
- }
- #endregion
-
- #region SetFriction
- /// <summary>
- /// Set the friction of the body.
- /// </summary>
- /// <param name="value">Friction value to set.</param>
- protected override void SetFriction(float value)
- {
- Body.Material.DynamicFriction = value;
-
- if (IsStatic)
- {
- jitterBody.Material.StaticFriction = value;
- }
- }
- #endregion
-
- #endregion
- }
- }