示例#1
0
 private void DisableCollisions(Body rb0, Body rb1)
 {
     if ((rb0.CollisionSkin == null) || (rb1.CollisionSkin == null))
         return;
     rb0.CollisionSkin.NonCollidables.Add(rb1.CollisionSkin);
     rb1.CollisionSkin.NonCollidables.Add(rb0.CollisionSkin);
 }
示例#2
0
        /// <summary>
        /// Constructor
        /// </summary>
        public CollisionSkin()
        {
            this.ID = idCounter++;
            this.owner = null;

            collSystem = null;
        }
示例#3
0
        public HeightMapModel2(Game game, HeightMap info, Boolean t, Vector3 pos, float scale)
            : base(game , null, t, pos, scale)
        {
            // Game game, Model m, Boolean t, Vector3 pos, float scale, Boolean solid
            //Game game, HeightMap m, Boolean t, Vector3 pos, float scale

            this.Visible = false;
            Body = new Body();
            Skin = new CollisionSkin(null);
            //Skin.CollisionType = (int)CollisionTypes.Terrain;

            Array2D field = new Array2D(info.heights.GetUpperBound(0), info.heights.GetUpperBound(1));

            for (int x = 0; x < info.heights.GetUpperBound(0); x++)
            {
                for (int z = 0; z < info.heights.GetUpperBound(1); z++)
                {
                    field.SetAt(x, z, info.heights[x, z]);
                }
            }

            Body.MoveTo(new Vector3(info.heightmapPosition.X, info.heightmapPosition.Y, info.heightmapPosition.Y), Matrix.Identity);

            Skin.AddPrimitive(new Heightmap(field, info.heightmapPosition.X, info.heightmapPosition.Y, scale, scale), (int)MaterialTable.MaterialID.NotBouncyRough);

            Body.Immovable = true;

            PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(Skin);
        }
示例#4
0
 public BoostController(Body body, Vector3 force, Vector3 forcePos, Vector3 torque)
 {
     Body = body;
     Force = force;
     ForcePosition = forcePos;
     Torque = torque;
 }
示例#5
0
 public override void SetSkinAndBody()
 {
     Body = new Body();
     Skin = new CollisionSkin(null);
     Skin.AddPrimitive(new JigLibX.Geometry.Plane(Vector3.Up, 0f), new MaterialProperties(0.2f, 0.7f, 0.6f));
     PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(Skin);
 }
示例#6
0
        public HeightmapObject(Game game, Model model,Vector2 shift)
            : base(game, model)
        {
            body = new Body(); // just a dummy. The PhysicObject uses its position to get the draw pos
            collision = new CollisionSkin(null);

            HeightMapInfo heightMapInfo = model.Tag as HeightMapInfo;
            Array2D field = new Array2D(heightMapInfo.heights.GetUpperBound(0), heightMapInfo.heights.GetUpperBound(1));

            for (int x = 0; x < heightMapInfo.heights.GetUpperBound(0); x++)
            {
                for (int z = 0; z < heightMapInfo.heights.GetUpperBound(1); z++)
                {
                    field.SetAt(x,z,heightMapInfo.heights[x,z]);
                }
            }

            // move the body. The body (because its not connected to the collision
            // skin) is just a dummy. But the base class shoudl know where to
            // draw the model.
            body.MoveTo(new Vector3(shift.X,0,shift.Y), Matrix.Identity);

            collision.AddPrimitive(new Heightmap(field, shift.X, shift.Y, 1, 1), new MaterialProperties(0.7f,0.7f,0.6f));

            PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(collision);
        }
示例#7
0
        // TODO: Need to add png parameter
        public HeightMapModel(Game game, Model m, Boolean t, Vector3 pos, float scale)
            : base(game, m, t, pos, scale, true)
        {
            Body = new Body(); // just a dummy. The PhysicObject uses its position to get the draw pos
            Skin = new CollisionSkin(null);

            HeightMapInfo heightMapInfo = this.model.Tag as HeightMapInfo;
            Array2D field = new Array2D(heightMapInfo.heights.GetUpperBound(0), heightMapInfo.heights.GetUpperBound(1));

            for (int x = 0; x < heightMapInfo.heights.GetUpperBound(0); x++)
            {
                for (int z = 0; z < heightMapInfo.heights.GetUpperBound(1); z++)
                {
                    field.SetAt(x, z, heightMapInfo.heights[x, z]);
                }
            }

            // move the body. The body (because its not connected to the collision
            // skin) is just a dummy. But the base class shoudl know where to
            // draw the model.
            Body.MoveTo(this.Position, Matrix.Identity);

            Skin.AddPrimitive(new Heightmap(field, 0f, 0f, 1, 1), new MaterialProperties(0.7f, 0.7f, 0.6f));

            PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(this.Skin);
        }
示例#8
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="owner"></param>
        public CollisionSkin(Body owner)
        {
            this.ID = idCounter++;
            this.owner = owner;

            collSystem = null;
        }
 public static Matrix ToXNA(Body body, Transform transform)
 {
     Vector3 rot = transform.GetRotation();
     Matrix mat = body.Orientation * Matrix.CreateRotationY(rot.Y);
     mat.Translation = body.Position;
     return mat;
 }
示例#10
0
        public BowlingPin(Game game, Model model, Matrix orientation, Vector3 position)
            : base(game, model)
        {
            body = new Body();
            collision = new CollisionSkin(body);

            // add a capsule for the main corpus
            Primitive capsule = new Capsule(Vector3.Zero, Matrix.Identity, 0.1f, 1.3f);
            // add a small box at the buttom
            Primitive box = new Box(new Vector3(-0.1f,-0.1f,-0.1f), Matrix.Identity, Vector3.One * 0.2f);
            // add a sphere in the middle
            Primitive sphere = new Sphere(new Vector3(0.0f, 0.0f, 0.3f), 0.3f);

            collision.AddPrimitive(capsule, new MaterialProperties(0.1f, 0.5f, 0.5f));
            collision.AddPrimitive(box, new MaterialProperties(0.1f, 0.5f, 0.5f));
            collision.AddPrimitive(sphere, new MaterialProperties(0.1f, 0.5f, 0.5f));

            body.CollisionSkin = this.collision;
            Vector3 com = SetMass(0.5f);

            body.MoveTo(position, orientation);
            collision.ApplyLocalTransform(new Transform(-com, Matrix.Identity));

            body.EnableBody();
            this.scale = Vector3.One * 10.0f;
        }
        public override void Initialise()
        {
            base.Initialise();

            // Create new bodey and collision skin
            m_Body = new Body();
            m_Skin = new CollisionSkin(m_Body);

            if (m_Body != null)
            {
                // Set skin to the body
                m_Body.CollisionSkin = m_Skin;

                // Check the skin was successfully created and add this 
                // custom dice as a primitive to the collision skin
                if (m_Skin != null)
                {
                    Box box = new Box(Vector3.Zero, Matrix.Identity, transform.Scale);
                    m_Skin.AddPrimitive(box, (int)MaterialTable.MaterialID.BouncyNormal);

                    // Set mass
                    m_Mass = SetMass(1.0f);

                    // Move the body to correct position initially
                    m_Body.MoveTo(transform.Position, Matrix.Identity);

                    // Apply transform to skin
                    m_Skin.ApplyLocalTransform(new JigLibX.Math.Transform(-m_Mass, Matrix.Identity));

                    // Enable body
                    EnableBody();
                }
            }
        }
示例#12
0
        void Setup(HeightMapInfo heightMapInfo, Vector2 shift)
        {
            // A dummy. The physics object uses its position to get draw pos
            Body = new Body();

            CollisionSkin = new CollisionSkin(null);

            info = heightMapInfo;
            Array2D field = new Array2D(heightMapInfo.Heights.GetUpperBound(0), heightMapInfo.Heights.GetUpperBound(1));

            for (int x = 0; x < heightMapInfo.Heights.GetUpperBound(0); ++x)
            {
                for (int z = 0; z < heightMapInfo.Heights.GetUpperBound(1); ++z)
                {
                    field.SetAt(x, z, heightMapInfo.Heights[x, z]);
                }
            }

            // Move dummy body. The body isn't connected to the collision skin.
            // But the base class should know where to draw the model.
            Body.MoveTo(new Vector3(shift.X, 0, shift.Y), Matrix.Identity);

            CollisionSkin.AddPrimitive(new Heightmap(field, shift.X, shift.Y, 1, 1), new MaterialProperties(0.7f, 0.7f, 0.6f));

            PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(CollisionSkin);
        }
示例#13
0
 /// <summary>
 /// Default Constructor
 /// Initalizes the Body and a CollisionSkin
 /// No Primatives are added to the Body
 /// </summary>
 /// <param name="position">Initial Body Position</param>
 /// <param name="scale">Scale</param>
 public Gobject()
 {
     Body = new Body();
     Skin = new CollisionSkin(Body);
     Body.CollisionSkin = Skin;
     Body.ExternalData = this;
 }
示例#14
0
        public HeightmapObject(Model model,Vector2 shift, Vector3 position)
            : base()
        {
            Body = new Body(); // just a dummy. The PhysicObject uses its position to get the draw pos
            Skin = new CollisionSkin(null);

            HeightMapInfo heightMapInfo = model.Tag as HeightMapInfo;
            Array2D field = new Array2D(heightMapInfo.heights.GetLength(0), heightMapInfo.heights.GetLength(1));

            for (int x = 0; x < heightMapInfo.heights.GetLength(0); x++)
            {
                for (int z = 0; z < heightMapInfo.heights.GetLength(1); z++)
                {
                    field.SetAt(x,z,heightMapInfo.heights[x,z]);
                }
            }

            // move the body. The body (because its not connected to the collision
            // skin) is just a dummy. But the base class shoudl know where to
            // draw the model.
            Body.MoveTo(new Vector3(shift.X,0,shift.Y), Matrix.Identity);

            Skin.AddPrimitive(new Heightmap(field, shift.X, shift.Y, heightMapInfo.terrainScale, heightMapInfo.terrainScale), new MaterialProperties(0.7f, 0.7f, 0.6f));

            PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(Skin);
            CommonInit(position, new Vector3(1,1,1), model, false, 0);
        }
示例#15
0
 // I'd like to create a controller and tell it how to control from then on.
 // maybe it should be a more abstract body controller, made up of physics controllers
 //
 public BoostController(Body body, Vector3 force, Vector3 torque)
 {
     Body = body;
     Force = force;
     Torque = torque;
     ForcePosition = new Vector3(0, 0, 0);
 }
示例#16
0
        public Missile(ParentGame game, Model modelObj, Texture2D[] modelTextures, DrawingClass drawClass, GameplayScreen Screen)
            : base(game, modelObj, modelTextures)
        {
            this.drawClass = drawClass;
            this.Screen = Screen;

            _body = new Body();
            _skin = new CollisionSkin(_body);
            _body.CollisionSkin = _skin;

            Box box = new Box(Vector3.Zero, Matrix.Identity, new Vector3(1f,1f,4f));
            _skin.AddPrimitive(box, new MaterialProperties(0.8f, 0.8f, 0.7f));

            Vector3 com = SetMass(2.0f);

            _body.MoveTo(position, Matrix.Identity);
            _skin.ApplyLocalTransform(new Transform(-com, Matrix.Identity));
            _body.EnableBody();

            Body.ExternalData = this;

            Vector3 pos = position;
            Vector3 forwardVec = Body.Orientation.Forward;
            forwardVec.Normalize();

            pos -= forwardVec * 10;
            // Use the particle emitter helper to output our trail particles.
            trailEmitter = new ParticleEmitter(drawClass.projectileTrailParticles,
                                               trailParticlesPerSecond, position);

            rgob = new RagdollObject(parentGame, null, null, null, RagdollObject.RagdollType.Simple, 1.0f, 3);
            rgob.Position = position;
            //rgob.PutToSleep();

            //rgob.limbs[0].PhysicsBody.AngularVelocity = (new Vector3(1, 1, 0) * 2000);

            RagdollTransforms = new List<Matrix>();

            RagdollTransforms = rgob.GetWorldMatrix();

            foreach (JigLibX.Objects.PhysicObject lim in rgob.limbs)
                DisableCollisions(lim.PhysicsBody, Body);

            foreach (JigLibX.Objects.PhysicObject lim in rgob.limbs)
                foreach (BuildingPiece pic in Screen.PieceList)
                    DisableCollisions(lim.PhysicsBody, pic.Body);

            foreach (JigLibX.Objects.PhysicObject lim in rgob.limbs)
                foreach (Building bld in Screen.Buildings)
                    DisableCollisions(lim.PhysicsBody, bld.Body);

            foreach (JigLibX.Objects.PhysicObject lim in rgob.limbs)
                DisableCollisions(lim.PhysicsBody, Screen.terrainActor.Body);

            foreach (JigLibX.Objects.PhysicObject limb0 in rgob.limbs)
                foreach (Missile mis in Screen.BulletList)
                    foreach (JigLibX.Objects.PhysicObject limb1 in mis.rgob.limbs)
                        DisableCollisions(limb1.PhysicsBody, limb0.PhysicsBody);
        }
示例#17
0
        private bool CollidedRecently = true; // we want the object to update immediately once created

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Default Constructor
        /// Initalizes the Body and a CollisionSkin
        /// No Primatives are added to the Body
        /// </summary>
        /// <param name="position">Initial Body Position</param>
        /// <param name="scale">Scale</param>
        public Gobject()
        {
            Body = new Body();
            Skin = new CollisionSkin(Body);
            Body.CollisionSkin = Skin;
            Body.ExternalData = this;
            Body.CollisionSkin.callbackFn += new CollisionCallbackFn(CollisionSkin_callbackFn);
        }
示例#18
0
 public PlaneObject(Game game, Model model, float d)
     : base(game, model)
 {
     body = new Body();
     collision = new CollisionSkin(null);
     collision.AddPrimitive(new JigLibX.Geometry.Plane(Vector3.Up, d), new MaterialProperties(0.2f, 0.7f, 0.6f));
     PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(collision);
 }
示例#19
0
 public PlaneObject(Model model,float d, Vector3 position, int asset)
     : base()
 {
     Body = new Body();
     Skin = new CollisionSkin(null);
     Skin.AddPrimitive(new JigLibX.Geometry.Plane(Vector3.Up, d), new MaterialProperties(0.2f, 0.7f, 0.6f));
     PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(Skin);
     CommonInit(position, new Vector3(1,1,1), model, false, asset);
 }
示例#20
0
 public Weapon(string modelName, Body body, Transform transform, Scene scene)
 {
     this.ignorePred = new IgnoreSkinPredicate(body);
     this.scene = scene;
     this.fpsModel = new ViewModel(modelName);
     fpsModel.SetTransform(transform);
     Matrix weaponTransform = Matrix.CreateScale(0.1f) * Matrix.CreateRotationX(-MathHelper.PiOver2) * Matrix.CreateRotationY(MathHelper.PiOver2);
     fpsModel.SetCustomMatrix(weaponTransform);
     fpsModel.GetAnimationLayer().SetActiveAnimation("Pistol_Idle", true);//.SetAnimationLayer("Pistol_Idle", 1);
 }
示例#21
0
 // Setup everything
 void Setup()
 {
     // We can't use InitializeBody() here because we want to add a
     // plane and not have it fall
     Body = new Body();
     CollisionSkin = new CollisionSkin(null);
     CollisionSkin.AddPrimitive(
         new JigLibX.Geometry.Plane(Vector3.Up, 0.0f),
         new MaterialProperties(0.2f, 0.7f, 0.6f));
     PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(CollisionSkin);
 }
 public ZoneObject(string id, ObjectType objectType,
     Transform3D transform, Effect effect, Color color, float alpha, bool isImpenetrable)
     : base(id, objectType, transform, effect, color, alpha)
 {
     //set body and skin for this zone
     this.body = new Body();
     this.body.ExternalData = this;
     this.collision = new CollisionSkin(this.body);
     this.body.CollisionSkin = this.collision;
     this.isImpenetrable = isImpenetrable; //we cant move through it
 }
示例#23
0
        public override void Initialise()
        {
            base.Initialise();

            // Create new bodey and collision skin
            m_Body = new Body();
            m_Skin = new CollisionSkin(m_Body);

            // Set physics controller
            m_PhysicsController.Initialize(m_Body);
        }
        public virtual void Initialize(Body body)
        {
            EnableController();
            m_Body = body;

            if (m_Body != null)
            {
                // Update downwards force ( mass based )
                //m_ConstantForces = (Vector3.Down * m_Body.Mass * 100);
            }
        }
示例#25
0
 public SphereObject(Game game, Model model,float radius, Matrix orientation, Vector3 position)
     : base(game, model)
 {
     body = new Body();
     collision = new CollisionSkin(body);
     collision.AddPrimitive(new Sphere(Vector3.Zero * 5.0f,radius), new MaterialProperties(0.5f,0.7f,0.6f));
     body.CollisionSkin = this.collision;
     Vector3 com = SetMass(10.0f);
     body.MoveTo(position + com, orientation);
        // collision.ApplyLocalTransform(new Transform(-com, Matrix.Identity));
     body.EnableBody();
     this.scale = Vector3.One * radius;
 }
示例#26
0
 public Weapon(string datablockName, Body body, Transform transform, Scene scene)
 {
     this.ignorePred = new IgnoreSkinPredicate(body);
     this.scene = scene;
     this.datablock = ResourceManager.Inst.GetWeaponDatablock(datablockName);
     this.fpsModel = new ViewModel(datablock.MeshName);
     this.fpsModel.SetRenderAlways(true, scene);
     this.ammo = datablock.AmmoPerClip;
     this.ReserveAmmo = datablock.DefaultAmmo;
     fpsModel.SetTransform(transform);
     fpsModel.SetCustomMatrix(datablock.CustomMatrix);
     fpsModel.GetAnimationLayer().SetActiveAnimation(datablock.GetAnimation(WeaponAnimations.Idle), true);
 }
        public CollidableObject(string id, ObjectType objectType, Transform3D transform, Effect effect,
            Texture2D texture, Model model, Color color, float alpha)
            : base(id, objectType, transform, effect, texture, model, color, alpha)
        {
            this.body = new Body();
            this.body.ExternalData = this;
            this.collision = new CollisionSkin(this.body);
            this.body.CollisionSkin = this.collision;

            //register for callback collision to see who just walked into the zone
            //we will only normally register for this event in a class that sub-classes CollidableObject e.g. PickupCollidableObject or PlayerCollidableObject
            this.Body.CollisionSkin.callbackFn += CollisionSkin_callbackFn;
        }
示例#28
0
        public BoxObject(Game game,Model model,Vector3 sideLengths, Matrix orientation, Vector3 position)
            : base(game,model)
        {
            body = new Body();
            collision = new CollisionSkin(body);

            collision.AddPrimitive(new Box(- 0.5f * sideLengths, orientation, sideLengths), new MaterialProperties(0.8f, 0.8f, 0.7f));
            body.CollisionSkin = this.collision;
            Vector3 com = SetMass(1.0f);
            body.MoveTo(position, Matrix.Identity);
            collision.ApplyLocalTransform(new Transform(-com, Matrix.Identity));
            body.EnableBody();
            this.scale = sideLengths;
        }
示例#29
0
        public CapsuleObject(Game game, Model model,float radius,float length, Matrix orientation, Vector3 position)
            : base(game, model)
        {
            body = new Body();
            collision = new CollisionSkin(body);
            collision.AddPrimitive(new Capsule(Vector3.Transform(new Vector3(-0.5f,0,0), orientation),orientation,radius,length),(int)MaterialTable.MaterialID.BouncyNormal);
            body.CollisionSkin = this.collision;
            Vector3 com = SetMass(10.0f);
            body.MoveTo(position + com, Matrix.Identity);

            collision.ApplyLocalTransform(new Transform(-com,Matrix.Identity));

            body.EnableBody();
            this.scale = new Vector3(radius, radius, length / 2);
        }
示例#30
0
        public CylinderObject(Game game, float radius, float length, Vector3 position, Model model)
            : base(game, model)
        {
            body = new Body();
            collision = new CollisionSkin(body);

            if (length - 2.0f * radius < 0.0f)
                throw new ArgumentException("Radius must be at least half length");

            Capsule middle = new Capsule(Vector3.Zero, Matrix.Identity, radius, length - 2.0f * radius);

            float sideLength = 2.0f * radius / (float) Math.Sqrt(2.0d);

            Vector3 sides = new Vector3(-0.5f * sideLength, -0.5f * sideLength, -radius);

            Box supply0 = new Box(sides, Matrix.Identity,
                new Vector3(sideLength, sideLength, length));

            Box supply1 = new Box(Vector3.Transform(sides,Matrix.CreateRotationZ(MathHelper.PiOver4)),
                Matrix.CreateRotationZ(MathHelper.PiOver4), new Vector3(sideLength, sideLength, length));

            collision.AddPrimitive(middle, new MaterialProperties(0.8f, 0.8f, 0.7f));
            collision.AddPrimitive(supply0, new MaterialProperties(0.8f, 0.8f, 0.7f));
            collision.AddPrimitive(supply1, new MaterialProperties(0.8f, 0.8f, 0.7f));

            body.CollisionSkin = this.collision;

            Vector3 com = SetMass(1.0f);
            collision.ApplyLocalTransform(new Transform(-com, Matrix.Identity));

            #region Manually set body inertia
            float cylinderMass = body.Mass;

            float comOffs = (length - 2.0f * radius) * 0.5f; ;

            float Ixx = 0.5f * cylinderMass * radius * radius + cylinderMass * comOffs * comOffs;
            float Iyy = 0.25f * cylinderMass * radius * radius + (1.0f / 12.0f) * cylinderMass * length * length + cylinderMass * comOffs * comOffs;
            float Izz = Iyy;

            body.SetBodyInertia(Ixx, Iyy, Izz);
            #endregion

            body.MoveTo(position, Matrix.CreateRotationX(MathHelper.PiOver2));

            body.EnableBody();

            this.scale = new Vector3(radius, radius, length * 0.5f);
        }
示例#31
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="body"></param>
 /// <param name="frame"></param>
 /// <param name="vel"></param>
 /// <param name="angVel"></param>
 public ConstraintVelocity(Body body, ReferenceFrame frame, Vector3?vel, Vector3?angVel)
 {
     Initialise(body, frame, vel, angVel);
 }
示例#32
0
        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 = Vector3.Up;

                if (Vector3.Dot(perpDir, hingeAxis) > 0.1f)
                {
                    perpDir = Vector3.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.Transform(hingeRelAnchorPos0, Matrix.CreateFromAxisAngle(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);
            }
        }