Esempio n. 1
0
 public override BulletConstraint CreateHingeConstraint(BulletWorld pWorld, BulletBody pBody1, BulletBody pBody2,
                     Vector3 ppivotInA, Vector3 ppivotInB, Vector3 paxisInA, Vector3 paxisInB,
                     bool puseLinearReferenceFrameA, bool pdisableCollisionsBetweenLinkedBodies)
 {
     HingeConstraint constrain = null;
     DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
     RigidBody rb1 = (pBody1 as BulletBodyXNA).rigidBody;
     RigidBody rb2 = (pBody2 as BulletBodyXNA).rigidBody;
     if (rb1 != null && rb2 != null)
     {
         IndexedVector3 pivotInA = new IndexedVector3(ppivotInA.X, ppivotInA.Y, ppivotInA.Z);
         IndexedVector3 pivotInB = new IndexedVector3(ppivotInB.X, ppivotInB.Y, ppivotInB.Z);
         IndexedVector3 axisInA = new IndexedVector3(paxisInA.X, paxisInA.Y, paxisInA.Z);
         IndexedVector3 axisInB = new IndexedVector3(paxisInB.X, paxisInB.Y, paxisInB.Z);
         constrain = new HingeConstraint(rb1, rb2, ref pivotInA, ref pivotInB, ref axisInA, ref axisInB, puseLinearReferenceFrameA);
         world.AddConstraint(constrain, pdisableCollisionsBetweenLinkedBodies);
     }
     return new BulletConstraintXNA(constrain);
 }
        	public RagDoll (RagDollDemo ragDollDemo,DynamicsWorld ownerWorld, ref IndexedVector3 positionOffset,StreamWriter streamWriter)
		
	        {
                m_ownerWorld = ownerWorld;
                m_ragDollDemo = ragDollDemo;
		        // Setup the geometry
                m_shapes[(int)BODYPART.PELVIS] = new CapsuleShape(0.15f, 0.20f);
                m_shapes[(int)BODYPART.SPINE] = new CapsuleShape(0.15f, 0.28f);
                m_shapes[(int)BODYPART.HEAD] = new CapsuleShape(0.10f, 0.05f);
                m_shapes[(int)BODYPART.LEFT_UPPER_LEG] = new CapsuleShape(0.07f, 0.45f);
                m_shapes[(int)BODYPART.LEFT_LOWER_LEG] = new CapsuleShape(0.05f, 0.37f);
                m_shapes[(int)BODYPART.RIGHT_UPPER_LEG] = new CapsuleShape(0.07f, 0.45f);
                m_shapes[(int)BODYPART.RIGHT_LOWER_LEG] = new CapsuleShape(0.05f, 0.37f);
                m_shapes[(int)BODYPART.LEFT_UPPER_ARM] = new CapsuleShape(0.05f, 0.33f);
                m_shapes[(int)BODYPART.LEFT_LOWER_ARM] = new CapsuleShape(0.04f, 0.25f);
                m_shapes[(int)BODYPART.RIGHT_UPPER_ARM] = new CapsuleShape(0.05f, 0.33f);
                m_shapes[(int)BODYPART.RIGHT_LOWER_ARM] = new CapsuleShape(0.04f, 0.25f);

		        // Setup all the rigid bodies
		        IndexedMatrix offset = IndexedMatrix.CreateTranslation(positionOffset);

		        IndexedMatrix transform = IndexedMatrix.CreateTranslation(new IndexedVector3(0,1,0));

				IndexedMatrix adjusted = offset*transform;

                m_bodies[(int)BODYPART.PELVIS] = m_ragDollDemo.LocalCreateRigidBody(1f, adjusted, m_shapes[(int)BODYPART.PELVIS],true);
				m_bodies[(int)BODYPART.PELVIS].SetUserPointer("PELVIS");
                transform = IndexedMatrix.CreateTranslation(new IndexedVector3(0,1.2f,0));
				adjusted = offset * transform;
				m_bodies[(int)BODYPART.SPINE] = m_ragDollDemo.LocalCreateRigidBody(1f, adjusted, m_shapes[(int)BODYPART.SPINE], true);
				m_bodies[(int)BODYPART.SPINE].SetUserPointer("SPINE");

                transform = IndexedMatrix.CreateTranslation(new IndexedVector3(0,1.6f,0));
				adjusted = offset * transform;
				m_bodies[(int)BODYPART.HEAD] = m_ragDollDemo.LocalCreateRigidBody(1f, adjusted, m_shapes[(int)BODYPART.HEAD], true);
				m_bodies[(int)BODYPART.HEAD].SetUserPointer("HEAD");

				transform = IndexedMatrix.CreateTranslation(new IndexedVector3(-0.18f, 0.65f, 0));
				adjusted = offset * transform
                    ;
				m_bodies[(int)BODYPART.LEFT_UPPER_LEG] = m_ragDollDemo.LocalCreateRigidBody(1f, adjusted, m_shapes[(int)BODYPART.LEFT_UPPER_LEG], true);
				m_bodies[(int)BODYPART.LEFT_UPPER_LEG].SetUserPointer("LEFTUPPERLEG");

				transform = IndexedMatrix.CreateTranslation(new IndexedVector3(-0.18f, 0.2f, 0));
				adjusted = offset *transform;
				m_bodies[(int)BODYPART.LEFT_LOWER_LEG] = m_ragDollDemo.LocalCreateRigidBody(1f, adjusted, m_shapes[(int)BODYPART.LEFT_LOWER_LEG], true);
				m_bodies[(int)BODYPART.LEFT_LOWER_LEG].SetUserPointer("LEFTLOWERLEG");

				transform = IndexedMatrix.CreateTranslation(new IndexedVector3(0.18f, 0.65f, 0));
				adjusted = offset * transform;
				m_bodies[(int)BODYPART.RIGHT_UPPER_LEG] = m_ragDollDemo.LocalCreateRigidBody(1f, adjusted, m_shapes[(int)BODYPART.RIGHT_UPPER_LEG], true);
				m_bodies[(int)BODYPART.RIGHT_UPPER_LEG].SetUserPointer("RIGHTUPPERLEG");

				transform = IndexedMatrix.CreateTranslation(new IndexedVector3(0.18f, 0.2f, 0));
				adjusted = offset*transform;
				m_bodies[(int)BODYPART.RIGHT_LOWER_LEG] = m_ragDollDemo.LocalCreateRigidBody(1f, adjusted, m_shapes[(int)BODYPART.RIGHT_LOWER_LEG], true);
				m_bodies[(int)BODYPART.RIGHT_LOWER_LEG].SetUserPointer("RIGHTLOWERLEG");

				transform = MathUtil.SetEulerZYX(0, 0, MathUtil.SIMD_HALF_PI);
				transform._origin = new IndexedVector3(-0.35f, 1.45f, 0);
				adjusted = offset *transform;
				m_bodies[(int)BODYPART.LEFT_UPPER_ARM] = m_ragDollDemo.LocalCreateRigidBody(1f, adjusted, m_shapes[(int)BODYPART.LEFT_UPPER_ARM], true);
				m_bodies[(int)BODYPART.LEFT_UPPER_ARM].SetUserPointer("LEFTUPPERARM");

				transform = MathUtil.SetEulerZYX(0, 0, MathUtil.SIMD_HALF_PI);
				transform._origin = new IndexedVector3(-0.7f, 1.45f, 0);
				adjusted = offset * transform;
				m_bodies[(int)BODYPART.LEFT_LOWER_ARM] = m_ragDollDemo.LocalCreateRigidBody(1f, adjusted, m_shapes[(int)BODYPART.LEFT_LOWER_ARM], true);
				m_bodies[(int)BODYPART.LEFT_LOWER_ARM].SetUserPointer("LEFTLOWERARM");

				transform = MathUtil.SetEulerZYX(0, 0, -MathUtil.SIMD_HALF_PI);
				transform._origin = new IndexedVector3(0.35f, 1.45f, 0);
				adjusted = offset * transform;
				m_bodies[(int)BODYPART.RIGHT_UPPER_ARM] = m_ragDollDemo.LocalCreateRigidBody(1f, adjusted, m_shapes[(int)BODYPART.RIGHT_UPPER_ARM], true);
				m_bodies[(int)BODYPART.RIGHT_UPPER_ARM].SetUserPointer("RIGHTUPPERARM");

				transform = MathUtil.SetEulerZYX(0, 0, -MathUtil.SIMD_HALF_PI);
				transform._origin = new IndexedVector3(0.7f, 1.45f, 0);
				adjusted = offset * transform;
				m_bodies[(int)BODYPART.RIGHT_LOWER_ARM] = m_ragDollDemo.LocalCreateRigidBody(1f, adjusted, m_shapes[(int)BODYPART.RIGHT_LOWER_ARM], true);
				m_bodies[(int)BODYPART.RIGHT_LOWER_ARM].SetUserPointer("RIGHTLOWERARM");

		        // Setup some damping on the m_bodies
		        for (int i = 0; i < (int)BODYPART.COUNT; ++i)
		        {
					if (m_bodies[i] != null)
					{
                        //m_bodies[i].SetDamping(0.05f, 0.85f);
                        m_bodies[i].SetDamping(0.5f, 0.85f);
						m_bodies[i].SetDeactivationTime(0.8f);
						m_bodies[i].SetSleepingThresholds(1.6f, 2.5f);
					}
                }

		        // Now setup the constraints
		        HingeConstraint hingeC;
		        ConeTwistConstraint coneC;

		        IndexedMatrix localA = IndexedMatrix.Identity;
                IndexedMatrix localB = IndexedMatrix.Identity;

                localA = MathUtil.SetEulerZYX(0, MathUtil.SIMD_HALF_PI, 0);
                localA._origin = new IndexedVector3(0.0f, 0.15f, 0.0f);
                localB = MathUtil.SetEulerZYX(0, MathUtil.SIMD_HALF_PI, 0);
                localB._origin = new IndexedVector3(0.0f, -0.15f, 0.0f);
                hingeC = new HingeConstraint(m_bodies[(int)BODYPART.PELVIS], m_bodies[(int)BODYPART.SPINE], ref localA, ref localB);
		        hingeC.SetLimit(-MathUtil.SIMD_QUARTER_PI, MathUtil.SIMD_HALF_PI);
                m_joints[(int)JOINT.PELVIS_SPINE] = hingeC;
                m_joints[(int)JOINT.PELVIS_SPINE].m_debugName = "PELVIS_SPINE";
		        hingeC.SetDbgDrawSize(CONSTRAINT_DEBUG_SIZE);

                m_ownerWorld.AddConstraint(m_joints[(int)JOINT.PELVIS_SPINE], true);


                localA = MathUtil.SetEulerZYX(0, 0, MathUtil.SIMD_HALF_PI);
                localA._origin = new IndexedVector3(0.0f, 0.30f, 0.0f);
                localB = MathUtil.SetEulerZYX(0, 0, MathUtil.SIMD_HALF_PI);
                localB._origin = new IndexedVector3(0.0f, -0.14f, 0.0f);
                coneC = new ConeTwistConstraint(m_bodies[(int)BODYPART.SPINE], m_bodies[(int)BODYPART.HEAD], ref localA, ref localB);
		        coneC.SetLimit(MathUtil.SIMD_QUARTER_PI, MathUtil.SIMD_QUARTER_PI, MathUtil.SIMD_HALF_PI);
                m_joints[(int)JOINT.SPINE_HEAD] = coneC;
                m_joints[(int)JOINT.SPINE_HEAD].m_debugName = "SPINE_HEAD";

		        coneC.SetDbgDrawSize(CONSTRAINT_DEBUG_SIZE);

                m_ownerWorld.AddConstraint(m_joints[(int)JOINT.SPINE_HEAD], true);


				localA = IndexedMatrix.Identity;
				localB = IndexedMatrix.Identity;
				localA = MathUtil.SetEulerZYX(0, 0, -MathUtil.SIMD_QUARTER_PI * 5);
				localA._origin = new IndexedVector3(-0.18f, -0.10f, 0.0f);
				localB = MathUtil.SetEulerZYX(0, 0, -MathUtil.SIMD_QUARTER_PI * 5);
				localB._origin = new IndexedVector3(0.0f, 0.225f, 0.0f);
				coneC = new ConeTwistConstraint(m_bodies[(int)BODYPART.PELVIS], m_bodies[(int)BODYPART.LEFT_UPPER_LEG], ref localA, ref localB);
				coneC.SetLimit(MathUtil.SIMD_QUARTER_PI, MathUtil.SIMD_QUARTER_PI, 0);
				m_joints[(int)JOINT.LEFT_HIP] = coneC;
                m_joints[(int)JOINT.LEFT_HIP].m_debugName = "LEFT_HIP";

				coneC.SetDbgDrawSize(CONSTRAINT_DEBUG_SIZE);

				m_ownerWorld.AddConstraint(m_joints[(int)JOINT.LEFT_HIP], true);

				localA = MathUtil.SetEulerZYX(0f, MathUtil.SIMD_HALF_PI, 0f);
				localA._origin = new IndexedVector3(0.0f, -0.225f, 0.0f);
				localB = MathUtil.SetEulerZYX(0, MathUtil.SIMD_HALF_PI, 0);
				localB._origin = new IndexedVector3(0.0f, 0.185f, 0.0f);
				hingeC = new HingeConstraint(m_bodies[(int)BODYPART.LEFT_UPPER_LEG], m_bodies[(int)BODYPART.LEFT_LOWER_LEG], ref localA, ref localB);
				hingeC.SetLimit(0, MathUtil.SIMD_HALF_PI);
				m_joints[(int)JOINT.LEFT_KNEE] = hingeC;
                m_joints[(int)JOINT.LEFT_KNEE].m_debugName = "LEFT_KNEE";

				hingeC.SetDbgDrawSize(CONSTRAINT_DEBUG_SIZE);

				m_ownerWorld.AddConstraint(m_joints[(int)JOINT.LEFT_KNEE], true);


				localA = MathUtil.SetEulerZYX(0, 0, MathUtil.SIMD_QUARTER_PI);
				localA._origin = new IndexedVector3(0.18f, -0.10f, 0.0f);
				localB = MathUtil.SetEulerZYX(0, 0, MathUtil.SIMD_QUARTER_PI);
				localB._origin = new IndexedVector3(0.0f, 0.225f, 0.0f);
				coneC = new ConeTwistConstraint(m_bodies[(int)BODYPART.PELVIS], m_bodies[(int)BODYPART.RIGHT_UPPER_LEG], ref localA, ref localB);
				coneC.SetLimit(MathUtil.SIMD_QUARTER_PI, MathUtil.SIMD_QUARTER_PI, 0);
				m_joints[(int)JOINT.RIGHT_HIP] = coneC;
                m_joints[(int)JOINT.RIGHT_HIP].m_debugName = "RIGHT_HIP";

				coneC.SetDbgDrawSize(CONSTRAINT_DEBUG_SIZE);

				m_ownerWorld.AddConstraint(m_joints[(int)JOINT.RIGHT_HIP], true);

				localA = MathUtil.SetEulerZYX(0, MathUtil.SIMD_HALF_PI, 0);
				localA._origin = new IndexedVector3(0.0f, -0.225f, 0.0f);
				localB = MathUtil.SetEulerZYX(0, MathUtil.SIMD_HALF_PI, 0);
				localB._origin = new IndexedVector3(0.0f, 0.185f, 0.0f);
				hingeC = new HingeConstraint(m_bodies[(int)BODYPART.RIGHT_UPPER_LEG], m_bodies[(int)BODYPART.RIGHT_LOWER_LEG], ref localA, ref localB);
				hingeC.SetLimit(0, MathUtil.SIMD_HALF_PI);
				m_joints[(int)JOINT.RIGHT_KNEE] = hingeC;
                m_joints[(int)JOINT.RIGHT_KNEE].m_debugName = "RIGHT_KNEE";

				hingeC.SetDbgDrawSize(CONSTRAINT_DEBUG_SIZE);

				m_ownerWorld.AddConstraint(m_joints[(int)JOINT.RIGHT_KNEE], true);


				localA = MathUtil.SetEulerZYX(0, 0, MathUtil.SIMD_PI);
				localA._origin = new IndexedVector3(-0.2f, 0.15f, 0.0f);
				localB = MathUtil.SetEulerZYX(0, 0, MathUtil.SIMD_HALF_PI);
				localB._origin = new IndexedVector3(0.0f, -0.18f, 0.0f);
				coneC = new ConeTwistConstraint(m_bodies[(int)BODYPART.SPINE], m_bodies[(int)BODYPART.LEFT_UPPER_ARM], ref localA, ref localB);
				coneC.SetLimit(MathUtil.SIMD_HALF_PI, MathUtil.SIMD_HALF_PI, 0);
				coneC.SetDbgDrawSize(CONSTRAINT_DEBUG_SIZE);

				m_joints[(int)JOINT.LEFT_SHOULDER] = coneC;
                m_joints[(int)JOINT.LEFT_SHOULDER].m_debugName = "LEFT_SHOULDER";

				m_ownerWorld.AddConstraint(m_joints[(int)JOINT.LEFT_SHOULDER], true);

				localA = MathUtil.SetEulerZYX(0, MathUtil.SIMD_HALF_PI, 0);
				localA._origin = new IndexedVector3(0.0f, 0.18f, 0.0f);
				localB = MathUtil.SetEulerZYX(0, MathUtil.SIMD_HALF_PI, 0);
				localB._origin = new IndexedVector3(0.0f, -0.14f, 0.0f);
				hingeC = new HingeConstraint(m_bodies[(int)BODYPART.LEFT_UPPER_ARM], m_bodies[(int)BODYPART.LEFT_LOWER_ARM], ref localA, ref localB);
				//		hingeC.setLimit(-MathUtil.SIMD_HALF_PI), 0));
				hingeC.SetLimit(0, MathUtil.SIMD_HALF_PI);
				m_joints[(int)JOINT.LEFT_ELBOW] = hingeC;
                m_joints[(int)JOINT.LEFT_ELBOW].m_debugName = "LEFT_ELBOW";

				hingeC.SetDbgDrawSize(CONSTRAINT_DEBUG_SIZE);

				m_ownerWorld.AddConstraint(m_joints[(int)JOINT.LEFT_ELBOW], true);

				localA = MathUtil.SetEulerZYX(0, 0, 0);
				localA._origin = new IndexedVector3(0.2f, 0.15f, 0.0f);
				localB = MathUtil.SetEulerZYX(0, 0, MathUtil.SIMD_HALF_PI);
				localB._origin = new IndexedVector3(0.0f, -0.18f, 0.0f);
				coneC = new ConeTwistConstraint(m_bodies[(int)BODYPART.SPINE], m_bodies[(int)BODYPART.RIGHT_UPPER_ARM], ref localA, ref localB);
				coneC.SetLimit(MathUtil.SIMD_HALF_PI, MathUtil.SIMD_HALF_PI, 0);
				m_joints[(int)JOINT.RIGHT_SHOULDER] = coneC;
                m_joints[(int)JOINT.RIGHT_SHOULDER].m_debugName = "RIGHT_SHOULDER";

				coneC.SetDbgDrawSize(CONSTRAINT_DEBUG_SIZE);

				m_ownerWorld.AddConstraint(m_joints[(int)JOINT.RIGHT_SHOULDER], true);

				localA = MathUtil.SetEulerZYX(0, MathUtil.SIMD_HALF_PI, 0);
				localA._origin = new IndexedVector3(0.0f, 0.18f, 0.0f);
				localB = MathUtil.SetEulerZYX(0, MathUtil.SIMD_HALF_PI, 0);
				localB._origin = new IndexedVector3(0.0f, -0.14f, 0.0f);
				hingeC = new HingeConstraint(m_bodies[(int)BODYPART.RIGHT_UPPER_ARM], m_bodies[(int)BODYPART.RIGHT_LOWER_ARM], ref localA, ref localB);
				//		hingeC.setLimit(-MathUtil.SIMD_HALF_PI), 0));
				hingeC.SetLimit(0, MathUtil.SIMD_HALF_PI);
				m_joints[(int)JOINT.RIGHT_ELBOW] = hingeC;
                m_joints[(int)JOINT.RIGHT_ELBOW].m_debugName = "RIGHT_ELBOW";

				hingeC.SetDbgDrawSize(CONSTRAINT_DEBUG_SIZE);

                m_ownerWorld.AddConstraint(m_joints[(int)JOINT.RIGHT_ELBOW], true); 
				
				
	        }
Esempio n. 3
0
        public override void InitializeDemo()
        {
            //string filename = @"E:\users\man\bullet\xna-constraint-output.txt";
            //FileStream filestream = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.Read);
            //BulletGlobals.g_streamWriter = new StreamWriter(filestream);

            //maxiterations = 100;

	        m_collisionConfiguration = new DefaultCollisionConfiguration();
	        m_dispatcher = new CollisionDispatcher(m_collisionConfiguration);
	        IndexedVector3 worldMin = new IndexedVector3(-1000,-1000,-1000);
	        IndexedVector3 worldMax = new IndexedVector3(1000,1000,1000);
            m_broadphase = new AxisSweep3Internal(ref worldMin, ref worldMax, 0xfffe, 0xffff, 16384, null, false);
	        m_constraintSolver = new SequentialImpulseConstraintSolver();
	        m_dynamicsWorld = new DiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_constraintSolver,m_collisionConfiguration);
            m_dynamicsWorld.SetDebugDrawer(m_debugDraw);

            SetCameraDistance(26f);

            //CollisionShape groundShape = new BoxShape(new IndexedVector3(50f, 40f, 50f));
            CollisionShape groundShape = new StaticPlaneShape(new IndexedVector3(0, 1, 0), 40);

            m_collisionShapes.Add(groundShape);
            IndexedMatrix groundTransform = IndexedMatrix.Identity;
            groundTransform._origin = new IndexedVector3(0, -56, 0);
            RigidBody groundBody = LocalCreateRigidBody(0, ref groundTransform, groundShape);

            CollisionShape shape = new BoxShape(new IndexedVector3(CUBE_HALF_EXTENTS, CUBE_HALF_EXTENTS, CUBE_HALF_EXTENTS));
            m_collisionShapes.Add(shape);
            IndexedMatrix trans = IndexedMatrix.Identity;
            trans._origin = new IndexedVector3(0, 20, 0);

	        float mass = 1f;

#if true
	    //point to point constraint with a breaking threshold
	    {
		    trans = IndexedMatrix.Identity;
		    trans._origin = new IndexedVector3(1,30,-5);
		    LocalCreateRigidBody( mass,trans,shape);
		    trans._origin = new IndexedVector3(0,0,-5);

		    RigidBody body0 = LocalCreateRigidBody( mass,trans,shape);
		    
            trans._origin = new IndexedVector3(2*CUBE_HALF_EXTENTS,20,0);
		    mass = 1.0f;
		    RigidBody body1 = null;//localCreateRigidBody( mass,trans,shape);
		    IndexedVector3 pivotInA = new IndexedVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,0);
		    TypedConstraint p2p = new Point2PointConstraint(body0,ref pivotInA);
		    m_dynamicsWorld.AddConstraint(p2p);
		    p2p.SetBreakingImpulseThreshold(10.2f);
		    p2p.SetDbgDrawSize(5.0f);
	    }
#endif



#if true
        //point to point constraint (ball socket)
			//SEEMS OK
	        {
                //trans = IndexedMatrix.Identity;
		        RigidBody body0 = LocalCreateRigidBody( mass,ref trans,shape);
		        trans._origin = new IndexedVector3(2*CUBE_HALF_EXTENTS,20,0);

		        mass = 1f;
		        RigidBody body1 = null;//localCreateRigidBody( mass,trans,shape);

		        IndexedVector3 pivotInA = new IndexedVector3(CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS);
		        IndexedVector3 axisInA = new IndexedVector3(0,0,1);

                IndexedVector3 pivotInB = body1 != null ? body1.GetCenterOfMassTransform().Inverse() * (body0.GetCenterOfMassTransform() * (pivotInA)) : pivotInA;
                IndexedVector3 axisInB = body1 != null ? (body1.GetCenterOfMassTransform()._basis.Inverse() * (body1.GetCenterOfMassTransform()._basis * axisInA)) :
                body0.GetCenterOfMassTransform()._basis * axisInA;
#if P2P
		TypedConstraint p2p = new Point2PointConstraint(body0,ref pivotInA);
		//btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,*body1,pivotInA,pivotInB);
		//btTypedConstraint* hinge = new btHingeConstraint(*body0,*body1,pivotInA,pivotInB,axisInA,axisInB);
		m_dynamicsWorld.AddConstraint(p2p);
		p2p.SetDbgDrawSize(5.0f);
#else

		        HingeConstraint hinge = new HingeConstraint(body0,ref pivotInA,ref axisInA,false);
        		
		        float	targetVelocity = 1f;
		        float	maxMotorImpulse = 1.0f;
		        hinge.EnableAngularMotor(true,targetVelocity,maxMotorImpulse);

		        m_dynamicsWorld.AddConstraint(hinge);//p2p);
		        hinge.SetDbgDrawSize(5f);
        #endif
	        }
#endif

#if true
            //create a slider, using the generic D6 constraint
			// SEEMS OK
	        {
		        mass = 1f;
		        IndexedVector3 sliderWorldPos = new IndexedVector3(0,10,0);
		        IndexedVector3 sliderAxis = new IndexedVector3(1,0,0);
		        float angle=0f;//SIMD_RADS_PER_DEG * 10.f;
		        IndexedBasisMatrix sliderOrientation = new IndexedBasisMatrix(new IndexedQuaternion(sliderAxis,angle));
		        trans = IndexedMatrix.Identity;
		        trans._origin = sliderWorldPos;
		        //trans.setBasis(sliderOrientation);
		        sliderTransform = trans;

		        d6body0 = LocalCreateRigidBody( mass,ref trans,shape);
		        d6body0.SetActivationState(ActivationState.DISABLE_DEACTIVATION);
		        RigidBody fixedBody1 = LocalCreateRigidBody(0,ref trans,null);
		        m_dynamicsWorld.AddRigidBody(fixedBody1);

		        IndexedMatrix frameInA, frameInB;
		        frameInA = IndexedMatrix.Identity;
		        frameInB = IndexedMatrix.Identity;
                frameInA._origin = new IndexedVector3(0, 5, 0);
                frameInB._origin = new IndexedVector3(0, 5, 0);

        //		bool useLinearReferenceFrameA = false;//use fixed frame B for linear llimits
		        bool useLinearReferenceFrameA = true;//use fixed frame A for linear llimits
		        spSlider6Dof = new Generic6DofConstraint(fixedBody1, d6body0,ref frameInA,ref frameInB,useLinearReferenceFrameA);
                spSlider6Dof.SetLinearLowerLimit(ref lowerSliderLimit);
                spSlider6Dof.SetLinearUpperLimit(ref hiSliderLimit);

		        //range should be small, otherwise singularities will 'explode' the constraint
                IndexedVector3 angularLower = new IndexedVector3(-1.5f,0,0);
                IndexedVector3 angularUpper = -angularLower;
                spSlider6Dof.SetAngularLowerLimit(ref angularLower);
                spSlider6Dof.SetAngularUpperLimit(ref angularUpper);
        //		slider.setAngularLowerLimit(IndexedVector3(0,0,0));
        //		slider.setAngularUpperLimit(IndexedVector3(0,0,0));
                spSlider6Dof.SetAngularLowerLimit(new IndexedVector3(-MathUtil.SIMD_PI, 0, 0));
                spSlider6Dof.SetAngularUpperLimit(new IndexedVector3(1.5f, 0, 0));

                spSlider6Dof.GetTranslationalLimitMotor().m_enableMotor[0] = true;
                spSlider6Dof.GetTranslationalLimitMotor().m_targetVelocity.X = -5.0f;
                spSlider6Dof.GetTranslationalLimitMotor().m_maxMotorForce.X = 0.1f;


                m_dynamicsWorld.AddConstraint(spSlider6Dof);
                spSlider6Dof.SetDbgDrawSize(5f);

	        }
#endif
#if true
	        { // create a door using hinge constraint attached to the world
		        CollisionShape pDoorShape = new BoxShape(new IndexedVector3(2.0f, 5.0f, 0.2f));
		        m_collisionShapes.Add(pDoorShape);
		        IndexedMatrix doorTrans = IndexedMatrix.Identity;
		        doorTrans._origin = new IndexedVector3(-5.0f, -2.0f, 0.0f);
		        RigidBody pDoorBody = LocalCreateRigidBody( 1.0f, ref doorTrans, pDoorShape);
		        pDoorBody.SetActivationState(ActivationState.DISABLE_DEACTIVATION);
		        IndexedVector3 btPivotA = new IndexedVector3( 10f+2.1f, -2.0f, 0.0f ); // right next to the door slightly outside
		        IndexedVector3 btAxisA = new IndexedVector3( 0.0f, 1.0f, 0.0f ); // pointing upwards, aka Y-axis

		        spDoorHinge = new HingeConstraint( pDoorBody, ref btPivotA, ref btAxisA,false );

                spDoorHinge.SetLimit(-MathUtil.SIMD_PI * 0.25f, MathUtil.SIMD_PI * 0.25f);
		        m_dynamicsWorld.AddConstraint(spDoorHinge);
		        spDoorHinge.SetDbgDrawSize(5.0f);

	        }
#endif
#if true
            { // create a generic 6DOF constraint
				// SEEMS OK - But debug draw a bit wrong?
		        IndexedMatrix tr = IndexedMatrix.Identity;
		        tr._origin = new IndexedVector3(10f, 6f, 0f);
                //tr.getBasis().setEulerZYX(0,0,0);
        //		RigidBody pBodyA = localCreateRigidBody( mass, tr, shape);
		        RigidBody pBodyA = LocalCreateRigidBody( 0.0f, ref tr, shape);
        //		RigidBody pBodyA = localCreateRigidBody( 0.0, tr, 0);
		        pBodyA.SetActivationState(ActivationState.DISABLE_DEACTIVATION);

                tr = IndexedMatrix.Identity;
		        tr._origin = new IndexedVector3(0f, 6f, 0f);		        
                //tr.getBasis().setEulerZYX(0,0,0);
		        RigidBody pBodyB = LocalCreateRigidBody(mass, ref tr, shape);
		        pBodyB.SetActivationState(ActivationState.DISABLE_DEACTIVATION);

		        IndexedMatrix frameInA, frameInB;
		        frameInA = IndexedMatrix.CreateTranslation(-5,0,0);
		        frameInB = IndexedMatrix.CreateTranslation(5,0,0);

		        Generic6DofConstraint pGen6DOF = new Generic6DofConstraint(pBodyA, pBodyB, ref frameInA, ref frameInB, true);
        //		btGeneric6DofConstraint* pGen6DOF = new btGeneric6DofConstraint(*pBodyA, *pBodyB, frameInA, frameInB, false);
		        IndexedVector3 linearLower = new IndexedVector3(-10, -2, -1);
                pGen6DOF.SetLinearLowerLimit(ref linearLower);
                IndexedVector3 linearUpper = new IndexedVector3(10,2,1);
		        pGen6DOF.SetLinearUpperLimit(ref linearUpper);
                // ? why again?
                //linearLower = new IndexedVector3(-10,0,0);
                //pGen6DOF.setLinearLowerLimit(ref linearLower);
        //		pGen6DOF.setLinearUpperLimit(IndexedVector3(10., 0., 0.));
        //		pGen6DOF.setLinearLowerLimit(IndexedVector3(0., 0., 0.));
        //		pGen6DOF.setLinearUpperLimit(IndexedVector3(0., 0., 0.));

        //		pGen6DOF.getTranslationalLimitMotor().m_enableMotor[0] = true;
        //		pGen6DOF.getTranslationalLimitMotor().m_targetVelocity[0] = 5.0f;
        //		pGen6DOF.getTranslationalLimitMotor().m_maxMotorForce[0] = 0.1f;


        //		pGen6DOF.setAngularLowerLimit(IndexedVector3(0., SIMD_HALF_PI*0.9, 0.));
        //		pGen6DOF.setAngularUpperLimit(IndexedVector3(0., -SIMD_HALF_PI*0.9, 0.));
        //		pGen6DOF.setAngularLowerLimit(IndexedVector3(0., 0., -SIMD_HALF_PI));
        //		pGen6DOF.setAngularUpperLimit(IndexedVector3(0., 0., SIMD_HALF_PI));

                IndexedVector3 angularLower = new IndexedVector3(-MathUtil.SIMD_HALF_PI * 0.5f, -0.75f, -MathUtil.SIMD_HALF_PI * 0.8f);
                IndexedVector3 angularUpper = -angularLower;
		        pGen6DOF.SetAngularLowerLimit(ref angularLower);
		        pGen6DOF.SetAngularUpperLimit(ref angularUpper);
        //		pGen6DOF.setAngularLowerLimit(IndexedVector3(0.f, -0.75, SIMD_HALF_PI * 0.8f));
        //		pGen6DOF.setAngularUpperLimit(IndexedVector3(0.f, 0.75, -SIMD_HALF_PI * 0.8f));
        //		pGen6DOF.setAngularLowerLimit(IndexedVector3(0.f, -SIMD_HALF_PI * 0.8f, SIMD_HALF_PI * 1.98f));
        //		pGen6DOF.setAngularUpperLimit(IndexedVector3(0.f, SIMD_HALF_PI * 0.8f,  -SIMD_HALF_PI * 1.98f));

        		
        		
        //		pGen6DOF.setAngularLowerLimit(IndexedVector3(-0.75,-0.5, -0.5));
        //		pGen6DOF.setAngularUpperLimit(IndexedVector3(0.75,0.5, 0.5));
        //		pGen6DOF.setAngularLowerLimit(IndexedVector3(-0.75,0., 0.));
        //		pGen6DOF.setAngularUpperLimit(IndexedVector3(0.75,0., 0.));

		        m_dynamicsWorld.AddConstraint(pGen6DOF, true);
		        pGen6DOF.SetDbgDrawSize(5.0f);
	        }
#endif
#if true
            { // create a ConeTwist constraint

		        IndexedMatrix tr = IndexedMatrix.CreateTranslation(-10,5,0);

		        RigidBody pBodyA = LocalCreateRigidBody( 1.0f, ref tr, shape);
		        pBodyA.SetActivationState(ActivationState.DISABLE_DEACTIVATION);

		        tr = IndexedMatrix.CreateTranslation(-10,-5,0);

		        RigidBody pBodyB = LocalCreateRigidBody(0.0f, ref tr, shape);

		        IndexedMatrix frameInA, frameInB;
                frameInA = MathUtil.SetEulerZYX(0, 0, MathUtil.SIMD_HALF_PI);
                frameInA._origin = new IndexedVector3(0, -5, 0);
				frameInB = MathUtil.SetEulerZYX(0, 0, MathUtil.SIMD_HALF_PI);
                frameInB._origin = new IndexedVector3(0, 5, 0);

		        ConeTwistConstraint pCT = new ConeTwistConstraint(pBodyA, pBodyB, ref frameInA, ref frameInB);
		        pCT.SetLimit(MathUtil.SIMD_QUARTER_PI * 0.6f, MathUtil.SIMD_QUARTER_PI, MathUtil.SIMD_PI * 0.8f, 0.5f); // soft limit == hard limit
		        m_dynamicsWorld.AddConstraint(pCT, true);
		        pCT.SetDbgDrawSize(5.0f);
	        }
#endif
#if true
            { // Hinge connected to the world, with motor (to hinge motor with new and old constraint solver)
				// WORKS OK
		        IndexedMatrix tr = IndexedMatrix.Identity;
		        RigidBody pBody = LocalCreateRigidBody( 1.0f, ref tr, shape);
		        pBody.SetActivationState(ActivationState.DISABLE_DEACTIVATION);
		        IndexedVector3 btPivotA = new IndexedVector3( 10.0f, 0.0f, 0.0f );
		        IndexedVector3 btAxisA = new IndexedVector3( 0.0f, 0.0f, 1.0f );

		        HingeConstraint pHinge = new HingeConstraint(pBody, ref btPivotA, ref btAxisA,false);
        //		pHinge.enableAngularMotor(true, -1.0, 0.165); // use for the old solver
		        pHinge.EnableAngularMotor(true, -1.0f, 1.65f); // use for the new SIMD solver
		        m_dynamicsWorld.AddConstraint(pHinge);
		        pHinge.SetDbgDrawSize(5.0f);
	        }
#endif
#if true
            {
		// WORKS OK
		// create a universal joint using generic 6DOF constraint
		// create two rigid bodies
		// static bodyA (parent) on top:
		IndexedMatrix tr = IndexedMatrix.CreateTranslation(20,4,0);
		RigidBody pBodyA = LocalCreateRigidBody( 0.0f, ref tr, shape);
		pBodyA.SetActivationState(ActivationState.DISABLE_DEACTIVATION);
		// dynamic bodyB (child) below it :
		tr = IndexedMatrix.CreateTranslation(20,0,0);
		RigidBody pBodyB = LocalCreateRigidBody(1.0f, ref tr, shape);
		pBodyB.SetActivationState(ActivationState.DISABLE_DEACTIVATION);
		// add some (arbitrary) data to build constraint frames
		IndexedVector3 parentAxis = new IndexedVector3(1.0f, 0.0f, 0.0f); 
		IndexedVector3 childAxis = new IndexedVector3(0.0f, 0.0f, 1.0f);
        IndexedVector3 anchor = new IndexedVector3(20.0f, 2.0f, 0.0f);

		UniversalConstraint pUniv = new UniversalConstraint(pBodyA, pBodyB, ref anchor, ref parentAxis, ref childAxis);
        pUniv.SetLowerLimit(-MathUtil.SIMD_HALF_PI * 0.5f, -MathUtil.SIMD_HALF_PI * 0.5f);
        pUniv.SetUpperLimit(MathUtil.SIMD_HALF_PI * 0.5f, MathUtil.SIMD_HALF_PI * 0.5f);
		// add constraint to world
		m_dynamicsWorld.AddConstraint(pUniv, true);
		// draw constraint frames and limits for debugging
		pUniv.SetDbgDrawSize(5.0f);
	}
#endif

#if true
            // WORKS OK
	{ // create a generic 6DOF constraint with springs 

		IndexedMatrix tr = IndexedMatrix.CreateTranslation(-20f,16f,0f);
        //tr.setIdentity();
        //tr.setOrigin(btVector3(btScalar(-20.), btScalar(16.), btScalar(0.)));
        //tr.getBasis().setEulerZYX(0,0,0);
		RigidBody pBodyA = LocalCreateRigidBody( 0.0f, ref tr, shape);
		pBodyA.SetActivationState(ActivationState.DISABLE_DEACTIVATION);

        //tr.setIdentity();
        //tr.setOrigin(btVector3(btScalar(-10.), btScalar(16.), btScalar(0.)));
        //tr.getBasis().setEulerZYX(0,0,0);
        tr = IndexedMatrix.CreateTranslation(-10,16,0);
		RigidBody pBodyB = LocalCreateRigidBody(1.0f, ref tr, shape);
		pBodyB.SetActivationState(ActivationState.DISABLE_DEACTIVATION);

        IndexedMatrix frameInA = IndexedMatrix.CreateTranslation(10f,0f,0f);
        IndexedMatrix frameInB = IndexedMatrix.CreateTranslation(0f,0f,0f);

		Generic6DofSpringConstraint pGen6DOFSpring = new Generic6DofSpringConstraint(pBodyA, pBodyB, ref frameInA, ref frameInB, true);
		pGen6DOFSpring.SetLinearUpperLimit(new IndexedVector3(5f, 0f, 0f));
		pGen6DOFSpring.SetLinearLowerLimit(new IndexedVector3(-5f, 0f, 0f));

		pGen6DOFSpring.SetAngularLowerLimit(new IndexedVector3(0f, 0f, -1.5f));
		pGen6DOFSpring.SetAngularUpperLimit(new IndexedVector3(0f, 0f, 1.5f));

		m_dynamicsWorld.AddConstraint(pGen6DOFSpring, true);
		pGen6DOFSpring.SetDbgDrawSize(5.0f);
		
		pGen6DOFSpring.EnableSpring(0, true);
		pGen6DOFSpring.SetStiffness(0, 39.478f);
		pGen6DOFSpring.SetDamping(0, 0.5f);
		pGen6DOFSpring.EnableSpring(5, true);
		pGen6DOFSpring.SetStiffness(5, 39.478f);
		pGen6DOFSpring.SetDamping(0, 0.3f);
		pGen6DOFSpring.SetEquilibriumPoint();
	}
#endif
#if true
    {
		// WORKS OK
		// create a Hinge2 joint
		// create two rigid bodies
		// static bodyA (parent) on top:
		IndexedMatrix tr = IndexedMatrix.CreateTranslation(-20f,4f,0f);
        
        RigidBody pBodyA = LocalCreateRigidBody( 0.0f, ref tr, shape);
		pBodyA.SetActivationState(ActivationState.DISABLE_DEACTIVATION);
		// dynamic bodyB (child) below it :
		tr = IndexedMatrix.CreateTranslation(-20f,0f,0f);
        RigidBody pBodyB = LocalCreateRigidBody(1.0f, ref tr, shape);
		pBodyB.SetActivationState(ActivationState.DISABLE_DEACTIVATION);
		// add some data to build constraint frames
		IndexedVector3 parentAxis = new IndexedVector3(0.0f, 1.0f, 0.0f); 
		IndexedVector3 childAxis = new IndexedVector3(1.0f, 0.0f, 0.0f);
        IndexedVector3 anchor = new IndexedVector3(-20.0f, 0.0f, 0.0f);
		Hinge2Constraint pHinge2 = new Hinge2Constraint(pBodyA, pBodyB, ref anchor, ref parentAxis, ref childAxis);
		pHinge2.SetLowerLimit(-MathUtil.SIMD_HALF_PI * 0.5f);
        pHinge2.SetUpperLimit(MathUtil.SIMD_HALF_PI * 0.5f);
		// add constraint to world
		m_dynamicsWorld.AddConstraint(pHinge2, true);
		// draw constraint frames and limits for debugging
		pHinge2.SetDbgDrawSize(5.0f);
	}
#endif
#if true
    { 
			// WORKS OK
		// create a Hinge joint between two dynamic bodies
		// create two rigid bodies
		// static bodyA (parent) on top:
		IndexedMatrix tr = IndexedMatrix.CreateTranslation(-20f,-2f,0f);
		RigidBody pBodyA = LocalCreateRigidBody( 1.0f, ref tr, shape);
		pBodyA.SetActivationState(ActivationState.DISABLE_DEACTIVATION);
		// dynamic bodyB:
		tr = IndexedMatrix.CreateTranslation(-30f,-2f,0f);
		RigidBody pBodyB = LocalCreateRigidBody(10.0f, ref tr, shape);
		pBodyB.SetActivationState(ActivationState.DISABLE_DEACTIVATION);
		// add some data to build constraint frames
		IndexedVector3 axisA = new IndexedVector3(0.0f, 1.0f, 0.0f); 
		IndexedVector3 axisB = new IndexedVector3(0.0f, 1.0f, 0.0f); 
		IndexedVector3 pivotA = new IndexedVector3(-5.0f, 0.0f, 0.0f);
        IndexedVector3 pivotB = new IndexedVector3(5.0f, 0.0f, 0.0f);
		
        spHingeDynAB = new HingeConstraint(pBodyA, pBodyB, ref pivotA, ref pivotB, ref axisA, ref axisB);
        spHingeDynAB.SetLimit(-MathUtil.SIMD_HALF_PI * 0.5f, MathUtil.SIMD_HALF_PI * 0.5f);
		// add constraint to world
		m_dynamicsWorld.AddConstraint(spHingeDynAB, true);
		// draw constraint frames and limits for debugging
		spHingeDynAB.SetDbgDrawSize(5.0f);
	}
#endif

#if true
    { // 6DOF connected to the world, with motor
		IndexedMatrix tr = IndexedMatrix.CreateTranslation(10,-15,0);
		RigidBody pBody = LocalCreateRigidBody( 1.0f, ref tr, shape);
		pBody.SetActivationState(ActivationState.DISABLE_DEACTIVATION);
		IndexedMatrix frameB = IndexedMatrix.Identity;
		Generic6DofConstraint pGen6Dof = new Generic6DofConstraint(pBody, ref frameB, false );
		m_dynamicsWorld.AddConstraint(pGen6Dof);
		pGen6Dof.SetDbgDrawSize(5.0f);

		pGen6Dof.SetAngularLowerLimit(new IndexedVector3(0,0,0));
		pGen6Dof.SetAngularUpperLimit(new IndexedVector3(0,0,0));
		pGen6Dof.SetLinearLowerLimit(new IndexedVector3(-10.0f, 0, 0));
		pGen6Dof.SetLinearUpperLimit(new IndexedVector3(10.0f, 0, 0));

		pGen6Dof.GetTranslationalLimitMotor().m_enableMotor[0] = true;
		pGen6Dof.GetTranslationalLimitMotor().m_targetVelocity[0] = 5.0f;
		pGen6Dof.GetTranslationalLimitMotor().m_maxMotorForce[0] = 0.1f;
	}
#endif
        }
        //----------------------------------------------------------------------------------------------------------------

        public override void InitializeDemo()
        {
            CollisionShape groundShape = new BoxShape(new IndexedVector3(50, 3, 50));
            //CollisionShape groundShape = new StaticPlaneShape(IndexedVector3.Up, 0f);


            m_collisionShapes.Add(groundShape);
            m_collisionConfiguration = new DefaultCollisionConfiguration();
            m_dispatcher = new CollisionDispatcher(m_collisionConfiguration);
            IndexedVector3 worldMin = new IndexedVector3(-1000, -1000, -1000);
            IndexedVector3 worldMax = new IndexedVector3(1000, 1000, 1000);
            //m_broadphase = new AxisSweep3Internal(ref worldMin, ref worldMax, 0xfffe, 0xffff, 16384, null, false);
            m_broadphase = new SimpleBroadphase(100, null);

            m_constraintSolver = new SequentialImpulseConstraintSolver();
            m_dynamicsWorld = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_constraintSolver, m_collisionConfiguration);

            //m_dynamicsWorld.setGravity(new IndexedVector3(0,0,0));
            IndexedMatrix tr = IndexedMatrix.CreateTranslation(0, -10, 0);

            //either use heightfield or triangle mesh

            //create ground object
            LocalCreateRigidBody(0f, ref tr, groundShape);

            CollisionShape chassisShape = new BoxShape(new IndexedVector3(1.0f, 0.5f, 2.0f));
            m_collisionShapes.Add(chassisShape);

            CompoundShape compound = new CompoundShape();
            m_collisionShapes.Add(compound);
            //localTrans effectively shifts the center of mass with respect to the chassis
            IndexedMatrix localTrans = IndexedMatrix.CreateTranslation(0, 1, 0);

            compound.AddChildShape(ref localTrans, chassisShape);

            {
                CollisionShape suppShape = new BoxShape(new IndexedVector3(0.5f, 0.1f, 0.5f));
                //localTrans effectively shifts the center of mass with respect to the chassis
                IndexedMatrix suppLocalTrans = IndexedMatrix.CreateTranslation(0f, 1.0f, 2.5f);
                compound.AddChildShape(ref suppLocalTrans, suppShape);
            }

            tr._origin = IndexedVector3.Zero;

            m_carChassis = LocalCreateRigidBody(800f, ref tr, compound);//chassisShape);
            //m_carChassis = LocalCreateRigidBody(800f, ref tr, chassisShape);//chassisShape);
            //CollisionShape liftShape = new BoxShape(new IndexedVector3(0.5f, 2.0f, 0.05f));
            //m_collisionShapes.Add(liftShape);
            //m_liftStartPos = new IndexedVector3(0.0f, 2.5f, 3.05f);

            //IndexedMatrix liftTrans = IndexedMatrix.CreateTranslation(m_liftStartPos);
            //m_liftBody = LocalCreateRigidBody(10f, ref liftTrans, liftShape);

            //IndexedMatrix localA = MathUtil.SetEulerZYX(0f, MathUtil.SIMD_HALF_PI, 0f);
            //localA._origin = new IndexedVector3(0f, 1.0f, 3.05f);

            //IndexedMatrix localB = MathUtil.SetEulerZYX(0f, MathUtil.SIMD_HALF_PI, 0f);
            //localB._origin = new IndexedVector3(0f, -1.5f, -0.05f);

            //m_liftHinge = new HingeConstraint(m_carChassis, m_liftBody, ref localA, ref localB);
            ////		m_liftHinge.setLimit(-LIFT_EPS, LIFT_EPS);
            //m_liftHinge.SetLimit(0.0f, 0.0f);
            //m_dynamicsWorld.AddConstraint(m_liftHinge, true);


            //CompoundShape forkCompound = new CompoundShape();
            //m_collisionShapes.Add(forkCompound);

            //IndexedMatrix forkLocalTrans = IndexedMatrix.Identity;
            //CollisionShape forkShapeA = new BoxShape(new IndexedVector3(1.0f, 0.1f, 0.1f));
            //m_collisionShapes.Add(forkShapeA);
            //forkCompound.AddChildShape(ref forkLocalTrans, forkShapeA);

            //CollisionShape forkShapeB = new BoxShape(new IndexedVector3(0.1f, 0.02f, 0.6f));
            //m_collisionShapes.Add(forkShapeB);
            //forkLocalTrans = IndexedMatrix.CreateTranslation(-0.9f, -0.08f, 0.7f);
            //forkCompound.AddChildShape(ref forkLocalTrans, forkShapeB);

            //CollisionShape forkShapeC = new BoxShape(new IndexedVector3(0.1f, 0.02f, 0.6f));
            //m_collisionShapes.Add(forkShapeC);
            //forkLocalTrans = IndexedMatrix.CreateTranslation(0.9f, -0.08f, 0.7f);
            //forkCompound.AddChildShape(ref forkLocalTrans, forkShapeC);

            //m_forkStartPos = new IndexedVector3(0.0f, 0.6f, 3.2f);
            //IndexedMatrix forkTrans = IndexedMatrix.CreateTranslation(m_forkStartPos);

            //m_forkBody = LocalCreateRigidBody(5f, ref forkTrans, forkCompound);

            //localA = MathUtil.SetEulerZYX(0f, 0f, MathUtil.SIMD_HALF_PI);
            //localA._origin = new IndexedVector3(0.0f, -1.9f, 0.05f);

            //IndexedVector3 col0 = MathUtil.matrixColumn(ref localA, 0);
            //IndexedVector3 col1 = MathUtil.matrixColumn(ref localA, 1);
            //IndexedVector3 col2 = MathUtil.matrixColumn(ref localA, 2);




            ////localB = MathUtil.setEulerZYX(0f, 0f, MathUtil.SIMD_HALF_PI);
            //localB = MathUtil.SetEulerZYX(0f, 0f, MathUtil.SIMD_HALF_PI);
            //localB._origin = new IndexedVector3(0.0f, 0.0f, -0.1f);

            //m_forkSlider = new SliderConstraint(m_liftBody, m_forkBody, ref localA, ref localB, true);

            //m_forkSlider.SetLowerLinLimit(0.1f);
            //m_forkSlider.SetUpperLinLimit(0.1f);
            ////		m_forkSlider.setLowerAngLimit(-LIFT_EPS);
            ////		m_forkSlider.setUpperAngLimit(LIFT_EPS);
            //m_forkSlider.SetLowerAngLimit(0.0f);
            //m_forkSlider.SetUpperAngLimit(0.0f);

            //IndexedMatrix localAVec = IndexedMatrix.Identity;
            //IndexedMatrix localBVec = IndexedMatrix.Identity;

            //m_forkSlider2 = new HingeConstraint(m_liftBody, m_forkBody, ref localAVec, ref localBVec);
            //m_dynamicsWorld.AddConstraint(m_forkSlider, true);
			//m_dynamicsWorld.addConstraint(m_forkSlider2, true);


            CompoundShape loadCompound = new CompoundShape(true);
            m_collisionShapes.Add(loadCompound);
            CollisionShape loadShapeA = new BoxShape(new IndexedVector3(2.0f, 0.5f, 0.5f));
            m_collisionShapes.Add(loadShapeA);
            IndexedMatrix loadTrans = IndexedMatrix.Identity;
            loadCompound.AddChildShape(ref loadTrans, loadShapeA);
            CollisionShape loadShapeB = new BoxShape(new IndexedVector3(0.1f, 1.0f, 1.0f));
            m_collisionShapes.Add(loadShapeB);
            loadTrans = IndexedMatrix.CreateTranslation(2.1f, 0.0f, 0.0f);
            loadCompound.AddChildShape(ref loadTrans, loadShapeB);
            CollisionShape loadShapeC = new BoxShape(new IndexedVector3(0.1f, 1.0f, 1.0f));
            m_collisionShapes.Add(loadShapeC);
            loadTrans = IndexedMatrix.CreateTranslation(-2.1f, 0.0f, 0.0f);
            loadCompound.AddChildShape(ref loadTrans, loadShapeC);
            m_loadStartPos = new IndexedVector3(0.0f, -3.5f, 7.0f);
            loadTrans = IndexedMatrix.CreateTranslation(m_loadStartPos);

            m_loadBody = LocalCreateRigidBody(4f, ref loadTrans, loadCompound);


#if false

            {
                CollisionShape liftShape = new BoxShape(new IndexedVector3(0.5f, 2.0f, 0.05f));
                m_collisionShapes.Add(liftShape);
                IndexedMatrix liftTrans = IndexedMatrix.CreateTranslation(m_liftStartPos);
                m_liftBody = localCreateRigidBody(10f, ref liftTrans, liftShape);

                IndexedMatrix localA = MathUtil.setEulerZYX(0f, MathUtil.SIMD_HALF_PI, 0f);
                localA._origin = new IndexedVector3(0f, 1.0f, 3.05f);

                IndexedMatrix localB = MathUtil.setEulerZYX(0f, MathUtil.SIMD_HALF_PI, 0f);
                localB._origin = new IndexedVector3(0f, -1.5f, -0.05f);

                m_liftHinge = new HingeConstraint(m_carChassis, m_liftBody, ref localA, ref localB);
                //		m_liftHinge.setLimit(-LIFT_EPS, LIFT_EPS);
                m_liftHinge.setLimit(0.0f, 0.0f);
                m_dynamicsWorld.addConstraint(m_liftHinge, true);

                CollisionShape forkShapeA = new BoxShape(new IndexedVector3(1.0f, 0.1f, 0.1f));
                m_collisionShapes.Add(forkShapeA);
                CompoundShape forkCompound = new CompoundShape();
                m_collisionShapes.Add(forkCompound);
                IndexedMatrix forkLocalTrans = IndexedMatrix.Identity;
                forkCompound.addChildShape(ref forkLocalTrans, forkShapeA);

                CollisionShape forkShapeB = new BoxShape(new IndexedVector3(0.1f, 0.02f, 0.6f));
                m_collisionShapes.Add(forkShapeB);
                forkLocalTrans = IndexedMatrix.CreateTranslation(-0.9f, -0.08f, 0.7f);
                forkCompound.addChildShape(ref forkLocalTrans, forkShapeB);

                CollisionShape forkShapeC = new BoxShape(new IndexedVector3(0.1f, 0.02f, 0.6f));
                m_collisionShapes.Add(forkShapeC);
                forkLocalTrans = IndexedMatrix.CreateTranslation(0.9f, -0.08f, 0.7f);
                forkCompound.addChildShape(ref forkLocalTrans, forkShapeC);

                m_forkStartPos = new IndexedVector3(0.0f, 0.6f, 3.2f);
                IndexedMatrix forkTrans = IndexedMatrix.CreateTranslation(m_forkStartPos);

                m_forkBody = localCreateRigidBody(5f, ref forkTrans, forkCompound);

                localA = MathUtil.setEulerZYX(0f, 0f, MathUtil.SIMD_HALF_PI);
                localA._origin = new IndexedVector3(0.0f, -1.9f, 0.05f);

                localB = MathUtil.setEulerZYX(0f, 0f, MathUtil.SIMD_HALF_PI);
                localB._origin = new IndexedVector3(0.0f, 0.0f, -0.1f);

                m_forkSlider = new SliderConstraint(m_liftBody, m_forkBody, ref localA, ref localB, true);
                m_forkSlider.setLowerLinLimit(0.1f);
                m_forkSlider.setUpperLinLimit(0.1f);
                //		m_forkSlider.setLowerAngLimit(-LIFT_EPS);
                //		m_forkSlider.setUpperAngLimit(LIFT_EPS);
                m_forkSlider.setLowerAngLimit(0.0f);
                m_forkSlider.setUpperAngLimit(0.0f);
                m_dynamicsWorld.addConstraint(m_forkSlider, true);


                CompoundShape loadCompound = new CompoundShape();
                m_collisionShapes.Add(loadCompound);
                CollisionShape loadShapeA = new BoxShape(new IndexedVector3(2.0f, 0.5f, 0.5f));
                m_collisionShapes.Add(loadShapeA);
                IndexedMatrix loadTrans = IndexedMatrix.Identity;
                loadCompound.addChildShape(ref loadTrans, loadShapeA);
                CollisionShape loadShapeB = new BoxShape(new IndexedVector3(0.1f, 1.0f, 1.0f));
                m_collisionShapes.Add(loadShapeB);
                loadTrans = IndexedMatrix.CreateTranslation(2.1f, 0.0f, 0.0f);
                loadCompound.addChildShape(ref loadTrans, loadShapeB);
                CollisionShape loadShapeC = new BoxShape(new IndexedVector3(0.1f, 1.0f, 1.0f));
                m_collisionShapes.Add(loadShapeC);
                loadTrans = IndexedMatrix.CreateTranslation(-2.1f, 0.0f, 0.0f);
                loadCompound.addChildShape(ref loadTrans, loadShapeC);
                m_loadStartPos = new IndexedVector3(0.0f, -3.5f, 7.0f);
                loadTrans = IndexedMatrix.CreateTranslation(m_loadStartPos);

                m_loadBody = localCreateRigidBody(4f, ref loadTrans, loadCompound);
            }
#endif
            //m_carChassis.setDamping(0.2f, 0.2f);

            ClientResetScene();

            /// create vehicle

            SetCameraDistance(26.0f);
            SetTexturing(true);
            SetShadows(true);

        }
		public TestRig (DemoApplication demoApplication,DynamicsWorld ownerWorld, ref IndexedVector3 positionOffset, bool bFixed)
		{
			m_dynamicsWorld = ownerWorld;
            IndexedVector3 vUp = new IndexedVector3(0, 1, 0);

			//
			// Setup geometry
			//
			float fBodySize  = 0.25f;
			float fLegLength = 0.45f;
			float fForeLegLength = 0.75f;
			m_shapes[0] = new CapsuleShape(fBodySize, 0.10f);
			for (int i=0; i<NUM_LEGS; i++)
			{
				m_shapes[1 + 2*i] = new CapsuleShape(0.10f, fLegLength);
				m_shapes[2 + 2*i] = new CapsuleShape(0.08f, fForeLegLength);
			}

			//
			// Setup rigid bodies
			//
			float fHeight = 0.5f;
			IndexedMatrix offset = IndexedMatrix.Identity;
			offset._origin = positionOffset;		

			// root
			IndexedVector3 vRoot = new IndexedVector3(0,fHeight,0);
			IndexedMatrix transform = IndexedMatrix.Identity;
			transform._origin = vRoot;

			if (bFixed)
			{
				m_bodies[0] = demoApplication.LocalCreateRigidBody(0.0f, offset * transform, m_shapes[0]);
			} else
			{
				m_bodies[0] = demoApplication.LocalCreateRigidBody(1.0f, offset * transform, m_shapes[0]);
			}
			// legs
			for (int i=0; i<NUM_LEGS; i++)
			{
				float fAngle = MathUtil.SIMD_2_PI * i / NUM_LEGS;
				float fSin = (float)Math.Sin(fAngle);
				float fCos = (float)Math.Cos(fAngle);

				transform = IndexedMatrix.Identity;
				IndexedVector3 vBoneOrigin = new IndexedVector3(fCos*(fBodySize+0.5f*fLegLength), fHeight, fSin*(fBodySize+0.5f*fLegLength));
				transform._origin = vBoneOrigin;

				// thigh
				IndexedVector3 vToBone = (vBoneOrigin - vRoot);
				vToBone.Normalize();

				IndexedVector3 vAxis = IndexedVector3.Cross(vToBone,vUp);	
				transform._basis = new IndexedBasisMatrix(Quaternion.CreateFromAxisAngle(vAxis.ToVector3(), MathUtil.SIMD_HALF_PI));
				transform._origin = vBoneOrigin;
				m_bodies[1+2*i] = demoApplication.LocalCreateRigidBody(1.0f, offset * transform, m_shapes[1+2*i]);

				// shin
				transform = IndexedMatrix.Identity;
				transform._origin = new IndexedVector3(fCos*(fBodySize+fLegLength), fHeight-0.5f*fForeLegLength, fSin*(fBodySize+fLegLength));
				m_bodies[2+2*i] = demoApplication.LocalCreateRigidBody(1.0f, offset * transform, m_shapes[2+2*i]);
			}

			// Setup some damping on the m_bodies
			for (int i = 0; i < BODYPART_COUNT; ++i)
			{
				m_bodies[i].SetDamping(0.05f, 0.85f);
				m_bodies[i].SetDeactivationTime(0.8f);
				//m_bodies[i].setSleepingThresholds(1.6, 2.5);
				m_bodies[i].SetSleepingThresholds(0.5f, 0.5f);
			}


			//
			// Setup the constraints
			//
			HingeConstraint hingeC;

			IndexedMatrix localA, localB, localC;

			for (int i=0; i<NUM_LEGS; i++)
			{
				float fAngle = MathUtil.SIMD_2_PI * i / NUM_LEGS;
				float fSin = (float)Math.Sin(fAngle);
				float fCos = (float)Math.Cos(fAngle);

				// hip joints
				localA = IndexedMatrix.Identity; 
				localB= IndexedMatrix.Identity;

				localA = MathUtil.SetEulerZYX(0f,-fAngle,0f);	
				localA._origin = new IndexedVector3(fCos*fBodySize, 0.0f, fSin*fBodySize);
                localB = m_bodies[1 + 2 * i].GetWorldTransform().Inverse() * m_bodies[0].GetWorldTransform() * localA;


                if (BulletGlobals.g_streamWriter != null && false)
				{
					MathUtil.PrintMatrix(BulletGlobals.g_streamWriter, "Hip LocalA", localA);
					MathUtil.PrintMatrix(BulletGlobals.g_streamWriter, "Hip LocalB", localB);
				}

				hingeC = new HingeConstraint(m_bodies[0], m_bodies[1+2*i], ref localA, ref localB);
				hingeC.SetLimit(-0.75f * MathUtil.SIMD_QUARTER_PI, MathUtil.SIMD_QUARTER_PI/2f);
				m_joints[2*i] = hingeC;
				m_dynamicsWorld.AddConstraint(m_joints[2*i], true);

				// knee joints
				localA = IndexedMatrix.Identity; 
				localB= IndexedMatrix.Identity;
				localC = IndexedMatrix.Identity;

				localA = MathUtil.SetEulerZYX(0f,-fAngle,0f);	
				localA._origin = new IndexedVector3(fCos*(fBodySize+fLegLength), 0.0f, fSin*(fBodySize+fLegLength));

                localB = m_bodies[1 + 2 * i].GetWorldTransform().Inverse() * m_bodies[0].GetWorldTransform() * localA;
                localC = m_bodies[2 + 2 * i].GetWorldTransform().Inverse() * m_bodies[0].GetWorldTransform() * localA;


				if (BulletGlobals.g_streamWriter != null && false)
				{
					MathUtil.PrintMatrix(BulletGlobals.g_streamWriter, "Knee LocalA", localA);
					MathUtil.PrintMatrix(BulletGlobals.g_streamWriter, "Knee LocalB", localB);
					MathUtil.PrintMatrix(BulletGlobals.g_streamWriter, "Knee LocalC", localC);
				}

				hingeC = new HingeConstraint(m_bodies[1 + 2 * i], m_bodies[2 + 2 * i], ref localB, ref localC);
				//hingeC.setLimit(float(-0.01), float(0.01));
				hingeC.SetLimit(-MathUtil.SIMD_QUARTER_PI/2f, 0.2f);
				m_joints[1+2*i] = hingeC;
				m_dynamicsWorld.AddConstraint(m_joints[1+2*i], true);
			}
		}