/PhysicsEngines/Bullet/BulletBody.cs
C# | 405 lines | 325 code | 46 blank | 34 comment | 4 complexity | 04c326574bc257b322bc30efef0e1690 MD5 | raw file
Possible License(s): Apache-2.0
- using System.Collections.Generic;
- using BulletXNA;
- using BulletXNA.BulletCollision;
- using BulletXNA.BulletDynamics;
- using Delta.PhysicsEngines.Enums;
- using Delta.Rendering.Models;
- using Delta.Utilities.Datatypes;
- using Delta.Utilities.Helpers;
- using BulletVector3 = Microsoft.Xna.Framework.Vector3;
- using BulletMatrix = Microsoft.Xna.Framework.Matrix;
-
- namespace Delta.PhysicsEngines.Bullet
- {
- /// <summary>
- /// Bullet implementation of PhysicsBody.
- /// </summary>
- internal class BulletBody : PhysicsBody
- {
- #region Position (Public)
- public override Vector Position
- {
- get
- {
- DefaultMotionState myMotionState =
- (DefaultMotionState)bulletBody.GetMotionState();
-
- BulletMatrix bulletMatrix;
- myMotionState.GetWorldTransform(out bulletMatrix);
-
- return BulletDatatypesMapping.Convert(
- bulletMatrix.Translation);
- }
- set
- {
- // Do we need to multiply here?
- var transMatrix = BulletMatrix.CreateTranslation(
- BulletDatatypesMapping.Convert(value));
-
- DefaultMotionState motionState =
- (DefaultMotionState)bulletBody.GetMotionState();
-
- motionState.m_graphicsWorldTrans = transMatrix;
- }
- }
- #endregion
-
- #region Position2D (Public)
- public override Point Position2D
- {
- get
- {
- return Position.ToPoint();
- }
- set
- {
- // This is 3D physics engine, so do nothing by default.
- }
- }
- #endregion
-
- #region LinearVelocity (Public)
- public override Vector LinearVelocity
- {
- get
- {
- BulletVector3 bulletVec = bulletBody.GetLinearVelocity();
- return BulletDatatypesMapping.Convert(bulletVec);
- }
- set
- {
- bulletBody.SetLinearVelocity(
- BulletDatatypesMapping.Convert(value));
- }
- }
- #endregion
-
- #region AngularVelocity (Public)
- public override Vector AngularVelocity
- {
- get
- {
- BulletVector3 bulletVec = bulletBody.GetAngularVelocity();
- return BulletDatatypesMapping.Convert(bulletVec);
- }
- set
- {
- bulletBody.SetAngularVelocity(
- BulletDatatypesMapping.Convert(value));
- }
- }
- #endregion
-
- #region AngularVelocity2D (Public)
- public override float AngularVelocity2D
- {
- get
- {
- return AngularVelocity.X;
- }
- set
- {
- // This is 3D physics engine, so do nothing by default.
- }
- }
- #endregion
-
- #region Mass (Public)
- public override float Mass
- {
- get
- {
- return base.Mass;
- }
- set
- {
- bulletBody.SetMassProps(value, initialInhertia);
- }
- }
- #endregion
-
- #region Restitution (Public)
- public override float Restitution
- {
- get
- {
- return base.Restitution;
- }
- set
- {
- bulletBody.SetRestitution(value);
- base.Restitution = value;
- }
- }
- #endregion
-
- #region BoundingBox (Public)
- public override BoundingBox BoundingBox
- {
- get
- {
- // Probably this will be removed in future
- BulletVector3 min, max;
- bulletBody.GetAabb(out min, out max);
- return new BoundingBox(
- BulletDatatypesMapping.Convert(min),
- BulletDatatypesMapping.Convert(max));
- }
- }
- #endregion
-
- #region Internal
-
- #region bulletBody (Internal)
- internal RigidBody bulletBody;
- #endregion
-
- #endregion
-
- #region Private
-
- #region bulletPhysics (Private)
- private BulletPhysics bulletPhysics;
- #endregion
-
- #region bulletShape (Private)
- private CollisionShape bulletShape;
- #endregion
-
- #region oldMass (Private)
- private float oldMass;
- #endregion
-
- #region initialInhertia (Private)
- private BulletVector3 initialInhertia;
- #endregion
-
- #endregion
-
- #region Constructors
- /// <summary>
- /// Creates a new instance of <see cref="BulletBody"/>
- /// </summary>
- /// <param name="bulletPhysics">The physics manager.</param>
- /// <param name="shape">The shape.</param>
- public BulletBody(BulletPhysics bulletPhysics,
- PhysicsShape shape, Vector initialPosition)
- : base(false, shape, initialPosition)
- {
- this.bulletPhysics = bulletPhysics;
-
- // First create shape.
- CreateShape();
-
- // Now create Bullet body.
- CreateBody();
-
- // Now add it to world simulation
- bulletPhysics.bulletWorld.AddRigidBody(bulletBody);
- }
-
- /// <summary>
- /// Internal constructor for creating GroundBody.
- /// </summary>
- /// <param name="bulletPhysics">The BulletPhysics implementation.</param>
- /// <param name="bulletBody">The already create Bullet body.</param>
- /// <param name="bulletShape">The already create Bullet CollisionShape.</param>
- internal BulletBody(BulletPhysics bulletPhysics,
- RigidBody bulletBody, CollisionShape bulletShape)
- : base(false, null, Vector.Zero)
- {
- this.bulletPhysics = bulletPhysics;
- this.bulletBody = bulletBody;
- this.bulletShape = bulletShape;
- }
- #endregion
-
- #region ApplyForce (Public)
- public override void ApplyForce(Vector force)
- {
- BulletVector3 bulletVec = BulletDatatypesMapping.Convert(force);
- BulletVector3 relPos = BulletVector3.Zero;
- bulletBody.ApplyForce(ref bulletVec, ref relPos);
- }
-
- public override void ApplyForce(Vector force, Vector position)
- {
- BulletVector3 bulletVec = BulletDatatypesMapping.Convert(force);
- BulletVector3 relPos = BulletDatatypesMapping.Convert(position);
- bulletBody.ApplyForce(ref bulletVec, ref relPos);
- }
- #endregion
-
- #region ApplyTorque (Public)
- public override void ApplyTorque(Vector torque)
- {
- BulletVector3 bulletTorque = BulletDatatypesMapping.Convert(torque);
- bulletBody.ApplyTorque(ref bulletTorque);
- }
- #endregion
-
- #region ApplyLinearImpulse (Public)
- public override void ApplyLinearImpulse(Vector impulse)
- {
- BulletVector3 bulletVec = BulletDatatypesMapping.Convert(impulse);
- BulletVector3 relPos = BulletVector3.Zero;
- bulletBody.ApplyImpulse(ref bulletVec, ref relPos);
- }
-
- public override void ApplyLinearImpulse(Vector impulse, Vector position)
- {
- BulletVector3 bulletVec = BulletDatatypesMapping.Convert(impulse);
- BulletVector3 relPos = BulletDatatypesMapping.Convert(position);
- bulletBody.ApplyImpulse(ref bulletVec, ref relPos);
- }
- #endregion
-
- #region ApplyAngularImpulse (Public)
- public override void ApplyAngularImpulse(Vector impulse)
- {
- BulletVector3 bulletVec = BulletDatatypesMapping.Convert(impulse);
- BulletVector3 relPos = BulletVector3.Zero;
- bulletBody.ApplyImpulse(ref bulletVec, ref relPos);
- }
- #endregion
-
- #region Methods (Private)
-
- #region CreateShape
- /// <summary>
- /// Creates Bullet CollsionShape from properties.
- /// </summary>
- private void CreateShape()
- {
- //http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Collision_Shapes
- Dictionary<PhysicsShape.PropertyType, object> properties =
- base.Shape.Properties;
- switch (Shape.ShapeType)
- {
- case ShapeType.Sphere:
- bulletShape = 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);
- BulletVector3 bulletVector =
- BulletDatatypesMapping.Convert(size / 2.0f);
- bulletShape = new BoxShape(
- ref bulletVector
- );
- break;
- case ShapeType.Capsule:
- bulletShape = new CapsuleShape(
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.Radius),
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.Depth));
- break;
- case ShapeType.Cone:
- bulletShape = new ConeShape(
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.Radius),
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.Height));
- break;
- case ShapeType.Cylinder:
- BulletVector3 bulletVec = new BulletVector3(
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.Height),
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.Radius),
- ArrayHelper.SafeGet<PhysicsShape.PropertyType, float>(
- properties, PhysicsShape.PropertyType.Height));
- bulletShape = new CylinderShape(bulletVec);
- break;
-
- case ShapeType.Triangle:
- bulletShape = 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;
- }
-
- // Store our body to collision user data.
- bulletShape.SetUserPointer(this);
- }
- #endregion
-
- #region CreateBody
- /// <summary>
- /// Creates Bullet body just after we create CollisionShape.
- /// </summary>
- private void CreateBody()
- {
- bool isDynamic = Mass != 0.0f;
-
- initialInhertia = BulletVector3.Zero;
- if (isDynamic)
- {
- bulletShape.CalculateLocalInertia(Mass, out initialInhertia);
- }
-
- BulletMatrix initialTransform =
- BulletMatrix.CreateTranslation(
- base.InitialPosition.X, base.InitialPosition.Y, base.InitialPosition.Z
- );
- // Using motionstate is recommended, it provides interpolation
- // capabilities, and only synchronizes 'active' objects
- DefaultMotionState initialMotionState = new DefaultMotionState(
- initialTransform, BulletMatrix.Identity);
-
- RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(
- Mass, initialMotionState, bulletShape, initialInhertia);
- rbInfo.m_restitution = base.restitution;
-
- bulletBody = new RigidBody(rbInfo);
- // Store our body to collision user data.
- bulletBody.SetUserPointer(this);
-
- // Apply mass and resitution too.
- bulletBody.SetMassProps(base.Mass, initialInhertia);
- }
- #endregion
-
- #region SetIsStatic
- protected override void SetIsStatic(bool value)
- {
- if (value)
- {
- oldMass = base.Mass;
- // By setting mass = 0.0 body is static in bullet
- bulletBody.SetMassProps(0.0f, BulletVector3.Zero);
- }
- else
- {
- bulletBody.SetMassProps(oldMass, ref initialInhertia);
- }
- }
- #endregion
-
- #region SetIsActive
- protected override void SetIsActive(bool value)
- {
- bulletBody.SetActivationState(value
- ? ActivationState.ACTIVE_TAG
- : ActivationState.DISABLE_SIMULATION);
- }
- #endregion
-
- #region SetFriction
- protected override void SetFriction(float value)
- {
- bulletBody.SetFriction(value);
- }
- #endregion
-
- #endregion
- }
- }