public CollisionSkin()
        {
            this.ID = idCounter++;
            this.owner = null;

            collSystem = null;
        }
        public CollisionSkin(Body owner)
        {
            this.ID = idCounter++;
            this.owner = owner;

            collSystem = null;
        }
        public void Initialise(Body body, Vector3 pointOnBody, Vector3 worldPosition)
        {
            this.body = body;
            this.pointOnBody = pointOnBody;
            this.worldPosition = worldPosition;

            if (body!=null) body.AddConstraint(this);
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="body"></param>
 /// <param name="pointOnBody">pointOnBody is in body coords</param>
 /// <param name="worldPosition"></param>
 public ConstraintWorldPoint(Body body, Vector3 pointOnBody, Vector3 worldPosition)
 {
     Initialise(body, pointOnBody, worldPosition);
 }
        /// <summary>
        /// Finds recursivly all bodies which are touching each other and
        /// adds them to a list.
        /// </summary>
        /// <param name="body">The body with which to start</param>
        /// <param name="island">The island contains the bodies which are in contact with
        /// each other</param>
        private void FindConnected(Body body, CollisionIsland island)
        {
            if (body.foundIsland || body.Immovable) return;

            body.foundIsland = true;

            island.Add(body);

            foreach (CollisionInfo collision in body.CollisionSkin.Collisions)
            {
                if (collision.SkinInfo.Skin1.Owner != null)
                {
                    if (collision.SkinInfo.Skin1.Owner == body)
                        FindConnected(collision.SkinInfo.Skin0.Owner, island);
                    else
                        FindConnected(collision.SkinInfo.Skin1.Owner, island);
                }
            }
        }
        public override void Destroy()
        {
            // this is moved here from ConstraintWorldPoint destructor..
            if (body != null) body.RemoveConstraint(this);

            body = null;
            DisableConstraint();
        }
 /// <summary>
 /// Detects all collisions between the body and all the registered
 /// collision skins (which should have already had their
 /// positions/bounding volumes etc updated).  For each potential
 /// pair of skins then the predicate (if it exists) will be called
 /// to see whether or not to continue. If the skins are closer
 /// than collTolerance (+ve value means report objects that aren't
 /// quite colliding) then the functor will get called.
 /// You can't just loop over all your bodies calling this, because 
 /// that will double-detect collisions. Use DetectAllCollisions for 
 /// that.
 /// </summary>
 public abstract void DetectCollisions(Body body, CollisionFunctor collisionFunctor,
     CollisionSkinPredicate2 collisionPredicate, float collTolerance);
 public LinearSpringJoint(Body body0, Vector3 attachPoint0, Body body1, Vector3 attachPoint1, float springConstant, float dampingConstant, float breakPoint)
     : base(springConstant, dampingConstant, breakPoint)
 {
     Initialize(body0, attachPoint0, body1, attachPoint1);
 }
 public void Dispose()
 {
     _primitive = null;
     _body = null;
     _skin = null;
 }
        public void Initialise(Body body0, Vector3 body0Pos, Body body1, Vector3 body1Pos, float maxDistance)
        {
            this.body0Pos = body0Pos;
            this.body1Pos = body1Pos;
            this.body0 = body0;
            this.body1 = body1;
            this.mMaxDistance = maxDistance;

            if (body0 != null) this.body0.AddConstraint(this);
            if (body1 != null) this.body1.AddConstraint(this);
        }
        public void Initialise(Body body0, Body body1, Vector3 hingeAxis, Vector3 hingePosRel0,
            float hingeHalfWidth, float hingeFwdAngle, float hingeBckAngle, float sidewaysSlack, float damping)
        {
            this.body0 = body0;
            this.body1 = body1;
            this.hingeAxis = hingeAxis;
            this.hingePosRel0 = hingePosRel0;
            this.usingLimit = false;
            this.damping = damping;

            //  tScalar allowedDistance = 0.005f;
            this.hingeAxis.Normalize();

            Vector3 hingePosRel1 = body0.Position + hingePosRel0 - body1.Position;

            // generate the two positions relative to each body
            Vector3 relPos0a = hingePosRel0 + hingeHalfWidth * hingeAxis;
            Vector3 relPos0b = hingePosRel0 - hingeHalfWidth * hingeAxis;

            Vector3 relPos1a = hingePosRel1 + hingeHalfWidth * hingeAxis;
            Vector3 relPos1b = hingePosRel1 - hingeHalfWidth * hingeAxis;

            float timescale = 1.0f / 20.0f;
            float allowedDistanceMid = 0.005f;
            float allowedDistanceSide = sidewaysSlack * hingeHalfWidth;

            mSidePointConstraints = new ConstraintMaxDistance[2];

            mSidePointConstraints[0] = new ConstraintMaxDistance();
            mSidePointConstraints[1] = new ConstraintMaxDistance();

            mSidePointConstraints[0].Initialise(body0, relPos0a, body1, relPos1a, allowedDistanceSide);
            mSidePointConstraints[1].Initialise(body0, relPos0b, body1, relPos1b, allowedDistanceSide);

            mMidPointConstraint = new ConstraintPoint();
            mMidPointConstraint.Initialise(body0, hingePosRel0, body1, hingePosRel1, allowedDistanceMid, timescale);

            if (hingeFwdAngle <= 150) // MAX_HINGE_ANGLE_LIMIT
            {
                // choose a direction that is perpendicular to the hinge
                Vector3 perpDir = Vector3Helper.Up;

                if (Vector3.Dot(perpDir, hingeAxis) > 0.1f)
                    perpDir = Vector3Helper.Right;

                // now make it perpendicular to the hinge
                Vector3 sideAxis = Vector3.Cross(hingeAxis, perpDir);
                perpDir = Vector3.Cross(sideAxis, hingeAxis);
                perpDir.Normalize();

                // the length of the "arm" TODO take this as a parameter? what's
                // the effect of changing it?
                float len = 10.0f * hingeHalfWidth;

                // Choose a position using that dir. this will be the anchor point
                // for body 0. relative to hinge
                Vector3 hingeRelAnchorPos0 = perpDir * len;

                // anchor point for body 2 is chosen to be in the middle of the
                // angle range.  relative to hinge
                float angleToMiddle = 0.5f * (hingeFwdAngle - hingeBckAngle);
                Vector3 hingeRelAnchorPos1 = Vector3.TransformCoordinate(hingeRelAnchorPos0, Matrix.RotationAxis(hingeAxis,MathHelper.ToRadians(-angleToMiddle)));

                // work out the "string" length
                float hingeHalfAngle = 0.5f * (hingeFwdAngle + hingeBckAngle);
                float allowedDistance = len * 2.0f * (float)System.Math.Sin(MathHelper.ToRadians(hingeHalfAngle * 0.5f));

                Vector3 hingePos = body1.Position + hingePosRel0;
                Vector3 relPos0c = hingePos + hingeRelAnchorPos0 - body0.Position;
                Vector3 relPos1c = hingePos + hingeRelAnchorPos1 - body1.Position;

                mMaxDistanceConstraint = new ConstraintMaxDistance();

                mMaxDistanceConstraint.Initialise(body0, relPos0c, body1, relPos1c, allowedDistance);

                usingLimit = true;
            }
            if (damping <= 0.0f)
                damping = -1.0f; // just make sure that a value of 0.0 doesn't mess up...
            else
                damping = MathHelper.Clamp(damping, 0, 1);
        }
        public override void DetectCollisions(Body body, CollisionFunctor collisionFunctor, CollisionSkinPredicate2 collisionPredicate, float collTolerance)
        {
            if (!body.IsActive)
                return;

            CollDetectInfo info = new CollDetectInfo();
            info.Skin0 = body.CollisionSkin; //?!
            if (info.Skin0 == null) return;

            int bodyPrimitves = info.Skin0.NumPrimitives;
            int numSkins = skins.Count;

            for (int skin = 0; skin < numSkins; ++skin)
            {
                info.Skin1 = skins[skin];
                if ((info.Skin0 != info.Skin1) && CheckCollidables(info.Skin0, info.Skin1))
                {
                    int primitives = info.Skin1.NumPrimitives;

                    for (info.IndexPrim0 = 0; info.IndexPrim0 < bodyPrimitves; ++info.IndexPrim0)
                    {
                        for (info.IndexPrim1 = 0; info.IndexPrim1 < primitives; ++info.IndexPrim1)
                        {
                            DetectFunctor f = GetCollDetectFunctor(info.Skin0.GetPrimitiveNewWorld(info.IndexPrim0).Type,
                                info.Skin1.GetPrimitiveNewWorld(info.IndexPrim1).Type);

                            if (f != null) f.CollDetect(info, collTolerance, collisionFunctor);
                        }
                    }
                }
            }
        }
 private int LessBodyZ(Body body0, Body body1)
 {
     return (body1.Position.Z > body0.Position.Z) ? -1 : 1;
 }
 private int LessBodyY(Body body0, Body body1)
 {
     return (body1.Position.Y > body0.Position.Y) ? -1 : 1;
 }
 private int LessBodyX(Body body0, Body body1)
 {
     return (body1.Position.X > body0.Position.X) ? -1 : 1;
 }
 public BasicController(Body body)
 {
     _body = body;
 }
        private void Initialize(Primitive primitive, MaterialProperties materialProperties, PrimitiveProperties primitiveProperties, bool enableBody)
        {
            float mass;
            Vector3 centerOfMass;
            Matrix inertiaTensor;
            Matrix inertiaTensorCoM;

            // Set variables ...
            _primitive = primitive;
            _primitiveProperties = primitiveProperties;
            _materialProperties = materialProperties;

            // Create and link Body and CollisionSkin.
            _body = new Body();
            _skin = new CollisionSkin(_body);
            _body.CollisionSkin = _skin;

            // Add primitive to CollisionSkin.
            _skin.AddPrimitive(primitive, materialProperties);

            // Set body properties.
            _skin.GetMassProperties(primitiveProperties, out mass, out centerOfMass, out inertiaTensor, out inertiaTensorCoM);

            _body.BodyInertia = inertiaTensorCoM;
            _body.Mass = mass;

            // Sync CollisionSkin and Body.
            _body.MoveTo(Vector3.Zero, Matrix.Identity);
            _skin.ApplyLocalTransform(new Transform(-centerOfMass, Matrix.Identity));

            // Enable Body.
            if (enableBody)
            {
                _body.EnableBody();
            }
            else
            {
                _body.DisableBody();
            }
        }
        /// <summary>
        /// adds the other body to the list of bodies to be activated if
        /// this body moves more than a certain distance from either a
        /// previously stored position, or the position passed in.
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="otherBody"></param>
        public void AddMovementActivation(Vector3 pos, Body otherBody)
        {
            if (bodiesToBeActivatedOnMovement.Contains(otherBody)) return;

            if (bodiesToBeActivatedOnMovement.Count == 0)
                storedPositionForActivation = pos;

            bodiesToBeActivatedOnMovement.Add(otherBody);
        }
        /// <summary>
        /// Loads a physics world object.
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="skin"></param>
        /// <param name="body"></param>
        /// <param name="massProperties"></param>
        /// <returns></returns>
        public static bool Load(string filePath, out CollisionSkin skin, out Body body, out PrimitiveProperties primitiveProperties, out MassProperties massProperties)
        {
            skin = null;
            body = null;
            primitiveProperties = new PrimitiveProperties(PrimitiveProperties.MassDistributionEnum.Solid, PrimitiveProperties.MassTypeEnum.Mass, 0.001f);
            massProperties = MassProperties.Zero;

            if (File.Exists(filePath))
            {
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(PhysicsObjectData));
                TextReader textReader = new StreamReader(filePath);

                PhysicsObjectData data = (PhysicsObjectData)xmlSerializer.Deserialize(textReader);
                textReader.Close();

                if (data != null && data.MaterialPrimitivePairs != null && data.MaterialPrimitivePairs.Count > 0)
                {
                    body = new JigLibSDX.Physics.Body();
                    skin = new JigLibSDX.Collision.CollisionSkin(body);
                    body.CollisionSkin = skin;

                    primitiveProperties = data.PrimitiveProperties;

                    for (int i = 0; i < data.MaterialPrimitivePairs.Count; i++)
                    {
                        if (data.MaterialPrimitivePairs[i].MaterialID == (int)MaterialTable.MaterialID.UserDefined)
                        {
                            skin.AddPrimitive(data.MaterialPrimitivePairs[i].Primitive, data.MaterialPrimitivePairs[i].MaterialID);
                        }
                        else
                        {
                            skin.AddPrimitive(data.MaterialPrimitivePairs[i].Primitive, data.MaterialPrimitivePairs[i].MaterialProperties);
                        }
                    }

                    massProperties = data.MassProperties;

                    body.BodyInertia = massProperties.InertiaTensorCoM;
                    body.Mass = massProperties.Mass;

                    body.MoveTo(Vector3.Zero, Matrix.Identity);
                    skin.ApplyLocalTransform(new Transform(-massProperties.CenterOfMass, Matrix.Identity));

                    body.EnableBody();
                }

                return true;
            }
            else
            {
                MessageBox.Show("File \"" + filePath + "\" not found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }
        }
 public ConstraintMaxDistance(Body body0, Vector3 body0Pos, Body body1, Vector3 body1Pos, float maxDistance)
 {
     Initialise(body0, body0Pos, body1, body1Pos, maxDistance);
 }
        public void Initialise(Body body0, Vector3 body0Pos, Body body1, Vector3 body1Pos, float allowedDistance, float timescale)
        {
            this.body0Pos = body0Pos;
            this.body1Pos = body1Pos;
            this.body0 = body0;
            this.body1 = body1;

            this.allowedDistance = allowedDistance;
            this.timescale = timescale;

            if (timescale < JiggleMath.Epsilon)
                timescale = JiggleMath.Epsilon;

            if (body0 != null) body0.AddConstraint(this);
            if (body1 != null) body1.AddConstraint(this);
        }
        private void Initialize(Body body0, Vector3 attachPoint0, Body body1, Vector3 attachPoint1)
        {
            _body0 = body0;
            _body1 = body1;
            _attachPoint0 = attachPoint0;
            _attachPoint1 = attachPoint1;

            _difference = body1.GetWorldPosition(attachPoint1) - body0.GetWorldPosition(attachPoint0);
            _restLength = _difference.Length();
        }
        /// <summary>
        /// Adds the body to the Physic- and the CollisionSystem
        /// </summary>
        /// <param name="body">Body which should be added to the simulation.</param>
        public void AddBody(Body body)
        {
            if (!bodies.Contains(body))
                bodies.Add(body);
            else
                System.Diagnostics.Debug.WriteLine("Warning: tried to add body to physics but it's already registered");

            if ((collisionSystem != null) && (body.CollisionSkin != null))
                collisionSystem.AddCollisionSkin(body.CollisionSkin);
        }
        public override void Destroy()
        {
            body0 = null;
            body1 = null;

            DisableConstraint();
        }
        /// <summary>
        /// Removes the body from the Physic- and the CollisionSystem
        /// </summary>
        /// <param name="body">Body which should be removed form the simulation</param>
        /// <returns>True if the Body was successfully removed.</returns>
        public bool RemoveBody(Body body)
        {
            if ((collisionSystem != null) && (body.CollisionSkin != null))
                collisionSystem.RemoveCollisionSkin(body.CollisionSkin);

            if (!bodies.Contains(body))
                return false;

            bodies.Remove(body);
            return true;
        }
 public ConstraintPoint(Body body0, Vector3 body0Pos, Body body1, Vector3 body1Pos, float allowedDistance, float timescale)
 {
     Initialise(body0, body0Pos, body1, body1Pos, allowedDistance, timescale);
 }
                public BodyPair(Body bodyA, Body bodyB)
                {
                    // if (bodyA > bodyB) {mBodyA = bodyA; mBodyB = bodyB; mRA = rA;}
                    // else {mBodyA = bodyB; mBodyB = bodyA; mRA = rB;}
                    int skinId = -1;
                    if (bodyB != null) skinId = bodyB.ID;

                    if (bodyA.ID > skinId)
                    {
                        this.BodyA = bodyA; this.BodyB = bodyB;
                    }
                    else
                    {
                        this.BodyA = bodyB; this.BodyB = bodyA;
                    }

                    this.RA = Vector3.Zero;
                }