Exemple #1
0
        public virtual void SetUpBulletPhysicsBody()
        {
            if (!IsGhost)
            {
                RigidBodyConstructionInfo rbInfo =
                    new RigidBodyConstructionInfo(Mass, MotionState, CollisionShape, Inertia);
                RigidBody       = new RigidBody(rbInfo);
                CollisionObject = RigidBody;
            }
            else
            {
                GhostObject = new BulletXNA.BulletCollision.PairCachingGhostObject();
                GhostObject.SetCollisionShape(CollisionShape);
                CollisionObject = GhostObject;

                GhostObject.SetCollisionFlags(BulletXNA.BulletCollision.CollisionFlags.CF_NO_CONTACT_RESPONSE);         // We can choose to make it "solid" if we want...
                GhostObject.SetWorldTransform(BulletXNA.LinearMath.IndexedMatrix.CreateTranslation(Position));
            }

            bulletPhysics.AddCollisionObject(CollisionObject, CollisionGroups, CollisionMask);
            CollisionObject.SetUserPointer(this);
        }
Exemple #2
0
    public void RecordGhostCollisions(PairCachingGhostObject obj)
    {
        IOverlappingPairCache cache = obj.GetOverlappingPairCache();
        ObjectArray<BroadphasePair> pairs = cache.GetOverlappingPairArray();

        DiscreteDynamicsWorld world = (PhysicsScene.World as BulletWorldXNA).world;
        PersistentManifoldArray manifoldArray = new PersistentManifoldArray();
        BroadphasePair collisionPair;
        PersistentManifold contactManifold;

        CollisionObject objA;
        CollisionObject objB;

        ManifoldPoint pt;

        int numPairs = pairs.Count;

        for (int i = 0; i < numPairs; i++)
        {
            manifoldArray.Clear();
            if (LastCollisionDesc < UpdatedCollisions.Length)
                break;
            collisionPair = world.GetPairCache().FindPair(pairs[i].m_pProxy0, pairs[i].m_pProxy1);
            if (collisionPair == null)
                continue;

            collisionPair.m_algorithm.GetAllContactManifolds(manifoldArray);
            for (int j = 0; j < manifoldArray.Count; j++)
            {
                contactManifold = manifoldArray[j];
                int numContacts = contactManifold.GetNumContacts();
                objA = contactManifold.GetBody0() as CollisionObject;
                objB = contactManifold.GetBody1() as CollisionObject;
                for (int p = 0; p < numContacts; p++)
                {
                    pt = contactManifold.GetContactPoint(p);
                    if (pt.GetDistance() < 0.0f)
                    {
                        RecordCollision(this, objA, objB, pt.GetPositionWorldOnA(), -pt.m_normalWorldOnB,pt.GetDistance());
                        break;
                    }
                }
            }
        }

    }
Exemple #3
0
    //sim.ptr, shape.ptr,prim.LocalID, prim.RawPosition, prim.RawOrientation
    public override BulletBody CreateGhostFromShape(BulletWorld pWorld, BulletShape pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation)
    {
        DiscreteDynamicsWorld world = (pWorld as BulletWorldXNA).world;
        IndexedMatrix bodyTransform = new IndexedMatrix();
        bodyTransform._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z);
        bodyTransform.SetRotation(new IndexedQuaternion(pRawOrientation.X,pRawOrientation.Y,pRawOrientation.Z,pRawOrientation.W));
        GhostObject gObj = new PairCachingGhostObject();
        gObj.SetWorldTransform(bodyTransform);
        CollisionShape shape = (pShape as BulletShapeXNA).shape;
        gObj.SetCollisionShape(shape);
        gObj.SetUserPointer(pLocalID);

        if (specialCollisionObjects.ContainsKey(pLocalID))
            specialCollisionObjects[pLocalID] = gObj;
        else
            specialCollisionObjects.Add(pLocalID, gObj);

        // TODO: Add to Special CollisionObjects!
        return new BulletBodyXNA(pLocalID, gObj);
    }
		public KinematicCharacterController(PairCachingGhostObject ghostObject, ConvexShape convexShape, float stepHeight, int upAxis)
		{
			m_upAxis = upAxis;
			m_addedMargin = 0.02f;
			m_walkDirection = IndexedVector3.Zero;
			m_useGhostObjectSweepTest = true;
			m_ghostObject = ghostObject;
			m_stepHeight = stepHeight;
			m_turnAngle = 0f;
			m_convexShape = convexShape;
			m_useWalkDirection = true;	// use walk direction by default, legacy behavior
			m_velocityTimeInterval = 0.0f;
			m_verticalVelocity = 0.0f;
			m_verticalOffset = 0.0f;
			m_gravity = 9.8f * 3; // 3G acceleration.
			m_fallSpeed = 55.0f; // Terminal velocity of a sky diver in m/s.
			m_jumpSpeed = 10.0f; // ?
			m_wasOnGround = false;
			m_wasJumping = false;
			SetMaxSlope(MathUtil.DegToRadians(45.0f));
		}
 //sim.ptr, shape.ptr,prim.LocalID, prim.RawPosition, prim.RawOrientation
 internal static object CreateGhostFromShape2(object pWorld, object pShape, uint pLocalID, Vector3 pRawPosition, Quaternion pRawOrientation)
 {
     IndexedMatrix bodyTransform = new IndexedMatrix();
     bodyTransform._origin = new IndexedVector3(pRawPosition.X, pRawPosition.Y, pRawPosition.Z);
     bodyTransform.SetRotation(new IndexedQuaternion(pRawOrientation.X,pRawOrientation.Y,pRawOrientation.Z,pRawOrientation.W));
     GhostObject gObj = new PairCachingGhostObject();
     gObj.SetWorldTransform(bodyTransform);
     CollisionShape shape = pShape as CollisionShape;
     gObj.SetCollisionShape(shape);
     gObj.SetUserPointer(pLocalID);
     // TODO: Add to Special CollisionObjects!
     return gObj;
 }
Exemple #6
0
        public override void InitializeDemo()
        {
            base.InitializeDemo();
            SetCameraDistance(50f);

            //string filename = @"E:\users\man\bullet\xna-basic-output-1.txt";
            //FileStream filestream = File.Open(filename, FileMode.Create, FileAccess.Write, FileShare.Read);
            //BulletGlobals.g_streamWriter = new StreamWriter(filestream);

            ///collision configuration contains default setup for memory, collision setup
            m_collisionConfiguration = new DefaultCollisionConfiguration();

            ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
            m_dispatcher = new CollisionDispatcher(m_collisionConfiguration);

            IndexedVector3 worldMin = new IndexedVector3 (-1000,-1000,-1000);
	        IndexedVector3 worldMax = -worldMin;
            m_broadphase = new AxisSweep3Internal(ref worldMin, ref worldMax, 0xfffe, 0xffff, 16384, null, false);
            //pairCache = new SortedOverlappingPairCache();

            //m_broadphase = new SimpleBroadphase(1000, pairCache);

            ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
            SequentialImpulseConstraintSolver sol = new SequentialImpulseConstraintSolver();
            m_constraintSolver = sol;

            m_dynamicsWorld = new DiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_constraintSolver, m_collisionConfiguration);
            m_dynamicsWorld.GetDispatchInfo().SetAllowedCcdPenetration(0.0001f);

            IndexedVector3 gravity = new IndexedVector3(0, -10, 0);
            m_dynamicsWorld.SetGravity(ref gravity);

            ///create a few basic rigid bodies
            IndexedVector3 halfExtents = new IndexedVector3(50, 50, 50);
            //IndexedVector3 halfExtents = new IndexedVector3(10, 10, 10);
            CollisionShape groundShape = new BoxShape(ref halfExtents);
            //CollisionShape groundShape = new StaticPlaneShape(new IndexedVector3(0,1,0), 50);

            m_collisionShapes.Add(groundShape);

            IndexedMatrix groundTransform = IndexedMatrix.CreateTranslation(new IndexedVector3(0, -50, 0));
            //IndexedMatrix groundTransform = IndexedMatrix.CreateTranslation(new IndexedVector3(0,-10,0));
            float mass = 0f;
            LocalCreateRigidBody(mass, ref groundTransform, groundShape);



            #region CharacterController
	        IndexedMatrix startTransform = IndexedMatrix.Identity;
	        //startTransform.setOrigin (btVector3(0.0, 4.0, 0.0));
	        startTransform._origin = new IndexedVector3(10.210098f,-1.6433364f,16.453260f);
	        
            m_ghostObject = new PairCachingGhostObject();
	        m_ghostObject.SetWorldTransform(startTransform);
	        m_broadphase.GetOverlappingPairCache().SetInternalGhostPairCallback(new GhostPairCallback());
	        float characterHeight=1.75f;
	        float characterWidth =1.75f;
	        ConvexShape capsule = new CapsuleShape(characterWidth,characterHeight);
	        m_ghostObject.SetCollisionShape (capsule);
	        m_ghostObject.SetCollisionFlags (CollisionFlags.CF_CHARACTER_OBJECT);

	        float stepHeight = 0.35f;
            int upAxis = 1;
	        m_character = new KinematicCharacterController (m_ghostObject,capsule,stepHeight,upAxis);

            m_dynamicsWorld.AddCollisionObject(m_ghostObject, CollisionFilterGroups.CharacterFilter, CollisionFilterGroups.StaticFilter | CollisionFilterGroups.DefaultFilter);
	        m_dynamicsWorld.AddAction(m_character);

            #endregion














        }
Exemple #7
0
        public virtual void LoadPlayerController(Entity playerEntity, SceneNode characterNode, object userData, Vector3 mobNodePositionUpdate)
        {
            //if (!initialized)
            //{
            //    characterToLoad = characterNode;
            //    characterEntityToLoad = playerEntity;
            //    JumpHandlerToLoad = jumpHandler;
            //    MobNodePositionUpdateToLoad = mobNodePositionUpdate;
            //    userDataToLoad = userData;
            //    return;
            //}
            if (playerController != null)
                return;
            float modelHeight = 2f;// (playerEntity.BoundingBox.Max.Y) / scaleFactor; // AJ: used to subtract minimum from maximum- playerEntity.BoundingBox.Minimum.y
            System.Console.WriteLine("Player capsule info: modelheight '{0}', boundingbox max '{1}', bounding box min '{2}' and playerPosition '{3}'",
                modelHeight, playerEntity.BoundingBox.Max.Y, playerEntity.BoundingBox.Min.Y, characterNode.Position);
            float radius = 1.75f;
            float height = 1.75f;



            ConvexShape capsule = new CapsuleShape(radius, height);
            //ConvexShape capsule = new SphereShape(radius);
            ghostObject = new PairCachingGhostObject();
            Vector3 position = new Vector3(0, 0, 0);//new Vector3(characterNode.Position.X / scaleFactor, (characterNode.Position.Y + 1500) / scaleFactor, characterNode.Position.Z / scaleFactor);
            //IndexedMatrix worldTransform = IndexedMatrix.CreateTranslation(characterNode.Position.X / scaleFactor,
            //    (characterNode.Position.Y + 1500) / scaleFactor, characterNode.Position.Z / scaleFactor);

            IndexedMatrix worldTransform = IndexedMatrix.CreateTranslation(position);

            ghostObject.SetWorldTransform(worldTransform);
            //broadphase.OverlappingPairCache.SetInternalGhostPairCallback(new GhostPairCallback());


            ghostObject.SetCollisionShape(capsule);
            ghostObject.SetCollisionFlags(CollisionFlags.CF_CHARACTER_OBJECT);
            float stepHeight = 0.35f;
            playerController = new KinematicCharacterController(ghostObject, capsule, stepHeight, 1);
            //characterToLoad = null;
            BulletMobState mobMovementState = new BulletMobState(playerController, mobNodePositionUpdate);
            //mobMovementState.JumpEvent += jumpHandler;
            mobControllers.Add(characterNode, mobMovementState);
            //m_dynamicsWorld.AddCollisionObject(ghostObject, CollisionFilterGroups.CharacterFilter, CollisionFilterGroups.StaticFilter | CollisionFilterGroups.DefaultFilter);
            m_dynamicsWorld.AddCollisionObject(ghostObject, CollisionFilterGroups.CharacterFilter, CollisionFilterGroups.StaticFilter | CollisionFilterGroups.DefaultFilter);
            //m_dynamicsWorld.AddCollisionObject(ghostObject, CollisionFilterGroups.DefaultFilter, CollisionFilterGroups.AllFilter);
            m_dynamicsWorld.AddAction(playerController);
            //collisionShapes.Add(capsule);
            //frozenTime = 0;
        }
        protected override void Initialize()
        {
            base.Initialize();
            SetCameraDistance(50.0f);

            ///collision configuration contains default setup for memory, collision setup
            m_collisionConfiguration = new DefaultCollisionConfiguration();
            //m_collisionConfiguration.setConvexConvexMultipointIterations();

            ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
            m_dispatcher = new CollisionDispatcher(m_collisionConfiguration);

            m_broadphase = new DbvtBroadphase();

            ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
            m_constraintSolver = new SequentialImpulseConstraintSolver();

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

            IndexedVector3 gravity = new IndexedVector3(0, -10, 0);
            m_dynamicsWorld.SetGravity(ref gravity);


            // NEW => btGhostPairCallback =================================
            m_ghostPairCallback = new GhostPairCallback();
            m_dynamicsWorld.GetBroadphase().GetOverlappingPairCache().SetInternalGhostPairCallback(m_ghostPairCallback);	// Needed once to enable ghost objects inside Bullet

            // NEW => btGhostObject =======================================
            m_ghostObject = new GhostObject();
            CollisionShape shape = new BoxShape(new IndexedVector3(5f));	// As far as I know only the world aabb of the shape will be used (i.e. a box always parallel to the x,y,z axis of variable size)
            m_collisionShapes.Add(shape);
            m_ghostObject.SetCollisionShape(shape);
            m_ghostObject.SetCollisionFlags(CollisionFlags.CF_NO_CONTACT_RESPONSE);		// We can choose to make it "solid" if we want...
            m_dynamicsWorld.AddCollisionObject(m_ghostObject, CollisionFilterGroups.SensorTrigger, CollisionFilterGroups.AllFilter & ~CollisionFilterGroups.SensorTrigger);
            //m_ghostObject.setWorldTransform(btTransform(btQuaternion::getIdentity(),btVector3(0,5,-15)));
            IndexedMatrix im = IndexedMatrix.CreateFromQuaternion(quatDeg45Y);
            im._origin = new IndexedVector3(0, 5, -15);
            m_ghostObject.SetWorldTransform(im);

            // NEW => btPairCachingGhostObject ============================
            m_pairCachingGhostObject = new PairCachingGhostObject();
            shape = new ConeShape(7.0f, 14.0f);
            m_collisionShapes.Add(shape);
            m_pairCachingGhostObject.SetCollisionShape(shape);
            m_pairCachingGhostObject.SetCollisionFlags(CollisionFlags.CF_NO_CONTACT_RESPONSE);	// We can choose to make it "solid" if we want...
            m_dynamicsWorld.AddCollisionObject(m_pairCachingGhostObject, CollisionFilterGroups.SensorTrigger, CollisionFilterGroups.AllFilter & ~CollisionFilterGroups.SensorTrigger);
            //m_pairCachingGhostObject.setWorldTransform(btTransform(btQuaternion::getIdentity(),btVector3(0,5,15)));
            im._origin = new IndexedVector3(0, 7, 15);
            m_pairCachingGhostObject.SetWorldTransform(im);
            //=============================================================

            ///create a few basic rigid bodies
            CollisionShape groundShape = new BoxShape(new IndexedVector3(50));

            m_collisionShapes.Add(groundShape);

            IndexedMatrix groundTransform = IndexedMatrix.Identity;
            groundTransform._origin = new IndexedVector3(0, -50, 0);

            float mass = 0.0f;
            LocalCreateRigidBody(mass, groundTransform, groundShape);

            // spawn some cubes (code pasted from appBasicDemo...)
            if(true)
            {
                //create a few dynamic rigidbodies
                CollisionShape colShape = new BoxShape(new IndexedVector3(SCALING, SCALING, SCALING));
                //btCollisionShape* colShape = new btSphereShape(btScalar(1.));
                //CollisionShape colShape = new CylinderShape(new IndexedVector3(1f, 1, 1f));
                m_collisionShapes.Add(colShape);

                /// Create Dynamic Objects
                IndexedMatrix startTransform = IndexedMatrix.Identity;

                mass = 1f;

                //rigidbody is dynamic if and only if mass is non zero, otherwise static
                bool isDynamic = mass != 0f;

                IndexedVector3 localInertia = IndexedVector3.Zero;
                if (isDynamic)
                {
                    colShape.CalculateLocalInertia(mass, out localInertia);
                }
                float start_x = START_POS_X - ARRAY_SIZE_X / 2;
                float start_y = START_POS_Y;
                float start_z = START_POS_Z - ARRAY_SIZE_Z / 2;

                for (int k = 0; k < ARRAY_SIZE_Y; k++)
                {
                    for (int i = 0; i < ARRAY_SIZE_X; i++)
                    {
                        for (int j = 0; j < ARRAY_SIZE_Z; j++)
                        {
                            startTransform._origin = (new IndexedVector3(2.0f * i + start_x, 20 + 2.0f * k + start_y, 2.0f * j + start_z) * SCALING);

                            //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
                            DefaultMotionState myMotionState = new DefaultMotionState(startTransform, IndexedMatrix.Identity);
                            RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(mass, myMotionState, colShape, localInertia);
                            RigidBody body = new RigidBody(rbInfo);
                            //body.setContactProcessingThreshold(colShape.getContactBreakingThreshold());
                            body.SetActivationState(ActivationState.ISLAND_SLEEPING);

                            m_dynamicsWorld.AddRigidBody(body);
                            body.SetActivationState(ActivationState.ISLAND_SLEEPING);
                            body.SetUserPointer(String.Format("Box X{0} Y{1} Z{2}", k, i, j));
                        }
                    }
                }
            }

            ClientResetScene();

        }
        // Portable static method: prerequisite call: m_dynamicsWorld.getBroadphase().getOverlappingPairCache().setInternalGhostPairCallback(new btGhostPairCallback()); 
        public static void GetCollidingObjectsInsidePairCachingGhostObject(DiscreteDynamicsWorld m_dynamicsWorld, PairCachingGhostObject m_pairCachingGhostObject, ObjectArray<CollisionObject> collisionArrayOut)
        {
            bool addOnlyObjectsWithNegativeDistance = true;	// With "false" things don't change much, and the code is a bit faster and cleaner...


            collisionArrayOut.Resize(0);
            if (m_pairCachingGhostObject == null || m_dynamicsWorld == null) return;

            //#define USE_PLAIN_COLLISION_WORLD // We dispatch all collision pairs of the ghost object every step (slow)
#if USE_PLAIN_COLLISION_WORLD
	//======================================================================================================
	// I thought this line was no longer needed, but it seems to be necessary (and I believe it's an expensive call):
	m_dynamicsWorld.getDispatcher().dispatchAllCollisionPairs(m_pairCachingGhostObject.getOverlappingPairCache(), m_dynamicsWorld.getDispatchInfo(), m_dynamicsWorld.getDispatcher());
	// Maybe the call can be automatically triggered by some other Bullet call (I'm almost sure I could comment it out in another demo I made long ago...)
	// So by now the general rule is: in real projects, simply comment it out and see if it works!
	//======================================================================================================
	// UPDATE: in dynamic worlds, the line above can be commented out and the broadphase pair can be retrieved through the call to findPair(...) below.
	// In collision worlds probably the above line is needed only if collision detection for all the bodies hasn't been made... This is something
	// I'm still not sure of... the general rule is to try to comment out the line above and try to use findPair(...) and see if it works whenever possible....
	//======================================================================================================
#endif //USE_PLAIN_COLLISION_WORLD

            ObjectArray<BroadphasePair> collisionPairs = m_pairCachingGhostObject.GetOverlappingPairCache().GetOverlappingPairArray();
            int numObjects = collisionPairs.Count;
            PersistentManifoldArray m_manifoldArray = new PersistentManifoldArray();
            bool added;
            for (int i = 0; i < numObjects; i++)
            {
                m_manifoldArray.Resize(0);

#if USE_PLAIN_COLLISION_WORLD
		const btBroadphasePair& collisionPair = collisionPairs[i];
		if (collisionPair.m_algorithm) collisionPair.m_algorithm.getAllContactManifolds(m_manifoldArray);
		else {	// THIS SHOULD NEVER HAPPEN, AND IF IT DOES, PLEASE RE-ENABLE the "call" a few lines above...
			printf("No collisionPair.m_algorithm - probably m_dynamicsWorld.getDispatcher().dispatchAllCollisionPairs(...) must be missing.\n");	
		}	
#else // USE_PLAIN_COLLISION_WORLD
                BroadphasePair cPair = collisionPairs[i];
                //unless we manually perform collision detection on this pair, the contacts are in the dynamics world paircache:
                BroadphasePair collisionPair = m_dynamicsWorld.GetPairCache().FindPair(cPair.m_pProxy0, cPair.m_pProxy1);
                if (collisionPair == null)
                {
                    continue;

                }
                if (collisionPair.m_algorithm != null)
                {
                    collisionPair.m_algorithm.GetAllContactManifolds(m_manifoldArray);
                }
                else
                {	// THIS SHOULD NEVER HAPPEN, AND IF IT DOES, PLEASE RE-ENABLE the "call" a few lines above...
                    //printf("No collisionPair.m_algorithm - probably m_dynamicsWorld.getDispatcher().dispatchAllCollisionPairs(...) must be missing.\n");	
                }
#endif //USE_PLAIN_COLLISION_WORLD

                added = false;
                for (int j = 0; j < m_manifoldArray.Count; j++)
                {
                    PersistentManifold manifold = m_manifoldArray[j];
                    // Here we are in the narrowphase, but can happen that manifold.getNumContacts()==0:
                    if (addOnlyObjectsWithNegativeDistance)
                    {
                        for (int p = 0, numContacts = manifold.GetNumContacts(); p < numContacts; p++)
                        {
                            ManifoldPoint pt = manifold.GetContactPoint(p);
                            if (pt.GetDistance() < 0.0)
                            {
                                // How can I be sure that the colObjs are all distinct ? I use the "added" flag.
                                collisionArrayOut.Add((CollisionObject)(manifold.GetBody0() == m_pairCachingGhostObject ? manifold.GetBody1() : manifold.GetBody0()));
                                added = true;
                                break;
                            }
                        }
                        if (added)
                        {
                            break;
                        }
                    }
                    else if (manifold.GetNumContacts() > 0)
                    {
                        collisionArrayOut.Add((CollisionObject)(manifold.GetBody0() == m_pairCachingGhostObject ? manifold.GetBody1() : manifold.GetBody0()));
                        break;
                    }
                }
            }
        }