예제 #1
0
        public void Update()
        {
            collisionWorld.PerformDiscreteCollisionDetection();
            int numManifolds = collisionWorld.Dispatcher.NumManifolds;

            for (int i = 0; i < numManifolds; i++)
            {
                PersistentManifold contactManifold = collisionWorld.Dispatcher.GetManifoldByIndexInternal(i);
                CollisionObject    obA             = contactManifold.Body0;
                CollisionObject    obB             = contactManifold.Body1;
                int misilId  = obB.UserIndex;
                int objetoId = obA.UserIndex;
                if (objetoId == ID_XWING && EsMisilEnemigo(misilId) &&
                    !Xwing.ESTADO_BARREL.BARRELROLL.Equals(VariablesGlobales.xwing.getEstadoBarrel()) &&
                    !listaIdMisilesQueColisionaronConXwing.Contains(misilId))
                {
                    XwingCollision(contactManifold, misilId);
                }
                if (EsTorreta(objetoId) && EsMisilXWing(misilId) &&
                    !(listaColisionesTorretaMisil.Contains(new Colision(objetoId, misilId))))
                {
                    TorretaCollision(contactManifold, misilId, objetoId);
                }
                if (EsObstaculo(objetoId) && EsMisilXWing(misilId) &&
                    !(listaColisionesObstaculoMisil.Contains(new Colision(objetoId, misilId))))
                {
                    ObstaculoCollision(contactManifold, misilId, objetoId);
                }
                if (objetoId == ID_XWING && (misilId == ID_PARED_OBSTACULO || EsTorreta(misilId)))
                {
                    VariablesGlobales.xwing.ChocarPared();
                }
                collisionWorld.Dispatcher.ClearManifold(contactManifold);
            }
        }
예제 #2
0
        private void OnContactAdded(ManifoldPoint cp, CollisionObjectWrapper colObj0Wrap, int partId0, int index0,
                                    CollisionObjectWrapper colObj1Wrap, int partId1, int index1)
        {
            //Debug.WriteLine("OnContactAdded");
            int numManifolds = BtWorld.Dispatcher.NumManifolds;

            for (int i = 0; i < numManifolds; i++)
            {
                PersistentManifold contactManifold = BtWorld.Dispatcher.GetManifoldByIndexInternal(i);
                int numContacts = contactManifold.NumContacts;
                if (numContacts > 0)
                {
                    cp.UserPersistentData = 1;

                    CollisionObject obA          = (CollisionObject)contactManifold.Body0;
                    CollisionObject obB          = (CollisionObject)contactManifold.Body1;
                    RigidBody       btRigidBodyA = (RigidBody)obA;
                    RigidBody       btRigidBodyB = (RigidBody)obB;
                    RigidBodyImp    rigidBodyA   = new RigidBodyImp();
                    RigidBodyImp    rigidBodyB   = new RigidBodyImp();
                    rigidBodyA._rbi = btRigidBodyA;
                    rigidBodyB._rbi = btRigidBodyB;
                    rigidBodyA.OnCollision(rigidBodyB);
                }
            }
        }
예제 #3
0
        public void OnPhysicsStep(CollisionWorld world)
        {
            Dispatcher dispatcher   = world.Dispatcher;
            int        numManifolds = dispatcher.NumManifolds;

            for (int i = 0; i < numManifolds; i++)
            {
                PersistentManifold contactManifold = dispatcher.GetManifoldByIndexInternal(i);
                CollisionObject    a = contactManifold.Body0;
                CollisionObject    b = contactManifold.Body1;
                if (a is CollisionObject && a.UserObject is BCollisionObject && ((BCollisionObject)a.UserObject).collisionCallbackEventHandlers.Count > 0)
                {
                    foreach (BICollisionCallbackEventHandler collisionCallbackHandler in ((BCollisionObject)a.UserObject).collisionCallbackEventHandlers)
                    {
                        collisionCallbackHandler.OnVisitPersistentManifold(contactManifold);
                    }
                }
                if (b is CollisionObject && b.UserObject is BCollisionObject && ((BCollisionObject)b.UserObject).collisionCallbackEventHandlers.Count > 0)
                {
                    foreach (BICollisionCallbackEventHandler collisionCallbackHandler in ((BCollisionObject)b.UserObject).collisionCallbackEventHandlers)
                    {
                        collisionCallbackHandler.OnVisitPersistentManifold(contactManifold);
                    }
                }
            }
            foreach (BCollisionObject.BICollisionCallbackEventHandler coeh in collisionCallbackListeners)
            {
                if (coeh != null)
                {
                    coeh.OnFinishedVisitingManifolds();
                }
            }
        }
예제 #4
0
        public override bool handleCollision(BroadphasePair collisionPair, CollisionDispatcher dispatcher)
        {
            CollisionObject colObj0 = collisionPair.pProxy0.clientObject;
            CollisionObject colObj1 = collisionPair.pProxy1.clientObject;

            if (colObj0.isStaticOrKinematicObject() && colObj1.isStaticOrKinematicObject())
            {
                collisionPair.manifold.clearManifold();
                return(false);
            }

            PersistentManifold manifold = collisionPair.manifold;
            int oldContacts             = manifold.getContactPointsNum();

            manifold.refreshContactPoints(colObj0.getWorldTransform(), colObj1.getWorldTransform());

            /*if (oldContacts == manifold.getContactPointsNum() && oldContacts > 0)
             *  return true;*/

            manifold.clearManifold();
            CollisionAlgorithm algorithm = dispatcher.findAlgorithm(colObj0, colObj1);

            // discrete collision detection query
            algorithm(colObj0, colObj1, dispatcher.getDispatchInfo(), manifold);
            return(manifold.getContactPointsNum() > 0);
        }
        public void Evaluate(int SpreadMax)
        {
            if (this.FWorld.IsConnected)
            {
                int contcnt = this.FWorld[0].Dispatcher.NumManifolds;
                this.FBody1.SliceCount         = contcnt;
                this.FBody2.SliceCount         = contcnt;
                this.FContactPoints.SliceCount = contcnt;

                for (int i = 0; i < contcnt; i++)
                {
                    PersistentManifold pm = this.FWorld[0].Dispatcher.GetManifoldByIndexInternal(i);
                    RigidBody          b1 = RigidBody.Upcast((CollisionObject)pm.Body0);
                    RigidBody          b2 = RigidBody.Upcast((CollisionObject)pm.Body1);

                    this.FBody1[i] = b1;
                    this.FBody2[i] = b2;

                    this.FContactPoints[i].SliceCount = pm.NumContacts;
                    for (int j = 0; j < pm.NumContacts; j++)
                    {
                        this.FContactPoints[i][j] = pm.GetContactPoint(j);
                    }
                }
            }
            else
            {
                FBody1.SliceCount = 0;
                FBody2.SliceCount = 0;
            }
        }
예제 #6
0
        public static void TickCallback(DynamicsWorld world, float timeStep)
        {
            int numManifolds = colWorld.Dispatcher.NumManifolds;

            for (int i = 0; i < numManifolds; i++)
            {
                PersistentManifold contactManifold = colWorld.Dispatcher.GetManifoldByIndexInternal(i);
                // CollisionObject obA = contactManifold.Body0 as CollisionObject;
                // CollisionObject obB = contactManifold.Body1 as CollisionObject;
                var entity1 = (contactManifold.Body0 as RigidBody).UserObject as Entity;
                var entity2 = (contactManifold.Body1 as RigidBody).UserObject as Entity;

                int numContacts = contactManifold.NumContacts;
                for (int j = 0; j < numContacts; j++)
                {
                    ManifoldPoint pt = contactManifold.GetContactPoint(j);
                    if (pt.Distance < 1.0f)
                    {
                        if (HardCollisionAction != null)
                        {
                            if (entity1.CollisionType == CollisionTypeEnum.Soft &&
                                entity2.CollisionType == CollisionTypeEnum.Soft)
                            {
                                SoftCollisionAction();
                            }
                            else
                            {
                                HardCollisionAction();
                            }
                        }
                        return;
                    }
                }
            }
        }
예제 #7
0
    //Check Collisions
    private void OnPhysicsStep()
    {
        numManifolds = dispatcher.NumManifolds;

        for (int i = 0; i < numManifolds; i++)
        {
            contactManifold = dispatcher.GetManifoldByIndexInternal(i);

            a = contactManifold.Body0;
            b = contactManifold.Body1;

            if (a is CollisionObject && a.UserObject is BCollisionObject && ((BCollisionObject)a.UserObject).collisionCallbackEventHandler != null)
            {
                ((BCollisionObject)a.UserObject).collisionCallbackEventHandler.OnVisitPersistentManifold(contactManifold);
            }

            if (b is CollisionObject && b.UserObject is BCollisionObject && ((BCollisionObject)b.UserObject).collisionCallbackEventHandler != null)
            {
                ((BCollisionObject)b.UserObject).collisionCallbackEventHandler.OnVisitPersistentManifold(contactManifold);
            }
        }

        foreach (BCollisionObject.BICollisionCallbackEventHandler coeh in collisionCallbackListeners)
        {
            if (coeh != null)
            {
                coeh.OnFinishedVisitingManifolds();
            }
        }

        contactManifold = null;
        a = b = null;
    }
예제 #8
0
		public ConvexTriangleCallback(IDispatcher dispatcher, CollisionObject body0, CollisionObject body1, bool isSwapped)
		{
			m_dispatcher = dispatcher;
			m_convexBody = isSwapped ? body1 : body0;
			m_triBody = isSwapped ? body0 : body1;
			m_manifoldPtr = m_dispatcher.GetNewManifold(m_convexBody, m_triBody);
			ClearCache();
		}
예제 #9
0
        public BoxBoxCollisionAlgorithm(PersistentManifold mf,CollisionAlgorithmConstructionInfo ci,CollisionObject body0,CollisionObject body1) : base(ci)
        {
 	        if (m_manifoldPtr == null && m_dispatcher.NeedsCollision(body0,body1))
	        {
		        m_manifoldPtr = m_dispatcher.GetNewManifold(body0,body1);
		        m_ownManifold = true;
	        }
        }
예제 #10
0
        /// <summary>
        /// Called for each manifold iterated over.
        /// </summary>
        /// <param name="pm"></param>
        public override void OnVisitPersistentManifold(PersistentManifold pm)
        {
            for (int i = 0; i < callbacks.Count; i++)
            {
                callbacks[i].OnVisitPersistentManifold(pm);
            }

            base.OnVisitPersistentManifold(pm);
        }
        public bool RecoverFromPenetration(CollisionWorld collisionWorld)
        {
            bool penetration = false;

            collisionWorld.GetDispatcher().DispatchAllCollisionPairs(m_ghostObject.GetOverlappingPairCache(), collisionWorld.GetDispatchInfo(), collisionWorld.GetDispatcher());

            m_currentPosition = m_ghostObject.GetWorldTransform()._origin;

            float maxPen = 0f;

            for (int i = 0; i < m_ghostObject.GetOverlappingPairCache().GetNumOverlappingPairs(); i++)
            {
                m_manifoldArray.Clear();

                BroadphasePair collisionPair = m_ghostObject.GetOverlappingPairCache().GetOverlappingPairArray()[i];

                if (collisionPair.m_algorithm != null)
                {
                    collisionPair.m_algorithm.GetAllContactManifolds(m_manifoldArray);
                }

                for (int j = 0; j < m_manifoldArray.Count; j++)
                {
                    PersistentManifold manifold = m_manifoldArray[j];
                    float directionSign         = manifold.GetBody0() == m_ghostObject ? -1f : 1f;
                    for (int p = 0; p < manifold.GetNumContacts(); p++)
                    {
                        ManifoldPoint pt = manifold.GetContactPoint(p);

                        float dist = pt.GetDistance();

                        if (dist < 0.0)
                        {
                            if (dist < maxPen)
                            {
                                maxPen           = dist;
                                m_touchingNormal = pt.m_normalWorldOnB * directionSign;                                //??
                            }
                            m_currentPosition += pt.m_normalWorldOnB * directionSign * dist * 0.2f;
                            penetration        = true;
                        }
                        else
                        {
                            //printf("touching %f\n", dist);
                        }
                    }

                    //manifold->clearManifold();
                }
            }
            IndexedMatrix newTrans = m_ghostObject.GetWorldTransform();

            newTrans._origin = m_currentPosition;
            m_ghostObject.SetWorldTransform(ref newTrans);
            //	printf("m_touchingNormal = %f,%f,%f\n",m_touchingNormal[0],m_touchingNormal[1],m_touchingNormal[2]);
            return(penetration);
        }
예제 #12
0
	    public Convex2dConvex2dAlgorithm(PersistentManifold mf,CollisionAlgorithmConstructionInfo ci,CollisionObject body0,CollisionObject body1, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold) : base(ci,body0,body1)
        {
            m_simplexSolver = simplexSolver;
            m_pdSolver = pdSolver;
            m_ownManifold = false;
            m_manifoldPtr = mf;
            m_lowLevelOfDetail = false;
            m_numPerturbationIterations = numPerturbationIterations;
            m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
        }
예제 #13
0
 static SphereSphereCollisionAlgorithm AllocFromPool(PersistentManifold mf,CollisionAlgorithmConstructionInfo ci,CollisionObject body0,CollisionObject body1)
 {
     SphereSphereCollisionAlgorithm result;
     if (ObjPool.Count > 0)
         result = ObjPool.Dequeue();
     else
         result = new SphereSphereCollisionAlgorithm();
     result.Constructor(mf, ci, body0, body1);
     return result;
 }
예제 #14
0
            /// Clears all data instanced by this algorithm
            /// if any (like persistent contact manifolds)
            public override void Clear(object o)
            {
                int numManifolds = bt_collision_world.GetDispatcher().GetNumManifolds();

                for (int i = 0; i < numManifolds; i++)
                {
                    PersistentManifold contactManifold = bt_collision_world.GetDispatcher().GetManifoldByIndexInternal(i);
                    contactManifold.ClearManifold();
                }
            }
예제 #15
0
 static ConvexPlaneCollisionAlgorithm AllocFromPool(PersistentManifold mf, CollisionAlgorithmConstructionInfo ci, CollisionObject col0, CollisionObject col1, bool isSwapped, int numPerturbationIterations, int minimumPointsPerturbationThreshold)
 {
     ConvexPlaneCollisionAlgorithm result;
     if (ObjPool.Count > 0)
         result = ObjPool.Dequeue();
     else
         result = new ConvexPlaneCollisionAlgorithm();
     result.Constructor(mf, ci, col0, col1, isSwapped, numPerturbationIterations, minimumPointsPerturbationThreshold);
     return result;
 }
예제 #16
0
		public CompoundLeafCallback (CollisionObject compoundObj,CollisionObject otherObj,IDispatcher dispatcher,DispatcherInfo dispatchInfo,ManifoldResult resultOut,IList<CollisionAlgorithm> childCollisionAlgorithms,PersistentManifold sharedManifold)
		{
			m_compoundColObj = compoundObj;
			m_otherObj = otherObj;
			m_dispatcher = dispatcher;
			m_dispatchInfo = dispatchInfo;
			m_resultOut = resultOut;
			m_childCollisionAlgorithms = childCollisionAlgorithms;
			m_sharedManifold = sharedManifold;
		}
예제 #17
0
 static SphereBoxCollisionAlgorithm AllocFromPool(PersistentManifold mf,CollisionAlgorithmConstructionInfo ci,CollisionObject col0,CollisionObject col1, bool isSwapped)
 {
     SphereBoxCollisionAlgorithm result;
     if (ObjPool.Count > 0)
         result = ObjPool.Dequeue();
     else
         result = new SphereBoxCollisionAlgorithm();
     result.Constructor(mf, ci, col0, col1,isSwapped);
     return result;
 }
예제 #18
0
 static CollisionAlgorithm AllocFromPool(PersistentManifold mf, CollisionAlgorithmConstructionInfo ci, CollisionObject body0, CollisionObject body1, ISimplexSolver simplexSolver, IConvexPenetrationDepthSolver pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold)
 {
     ConvexConvexAlgorithm result;
     if (ObjPool.Count > 0)
         result = ObjPool.Dequeue();
     else
         result = new ConvexConvexAlgorithm();
     result.Constructor(mf, ci, body0, body1, simplexSolver, pdSolver, numPerturbationIterations, minimumPointsPerturbationThreshold);
     return result;
 }
예제 #19
0
 public virtual void releaseManifold(PersistentManifold manifold)
 {
     clearManifold(manifold);
     int findIndex = manifold.m_index1a;
     PersistentManifold temp = m_manifoldsPtr[m_manifoldsPtr.Count - 1];
     m_manifoldsPtr[m_manifoldsPtr.Count - 1] = m_manifoldsPtr[findIndex];
     m_manifoldsPtr[findIndex] = temp;
     m_manifoldsPtr[findIndex].m_index1a = findIndex;
     m_manifoldsPtr.RemoveAt(m_manifoldsPtr.Count - 1);
 }
	    public SphereBoxCollisionAlgorithm(PersistentManifold mf,CollisionAlgorithmConstructionInfo ci,CollisionObject col0,CollisionObject col1, bool isSwapped) : base(ci,col0,col1)
        {
            CollisionObject sphereObj = m_isSwapped ? col1 : col0;
            CollisionObject boxObj = m_isSwapped ? col0 : col1;

            if (m_manifoldPtr == null && m_dispatcher.NeedsCollision(sphereObj, boxObj))
            {
                m_manifoldPtr = m_dispatcher.GetNewManifold(sphereObj, boxObj);
                m_ownManifold = true;
            }
        }
예제 #21
0
 public override void Cleanup()
 {
     if (m_ownManifold)
     {
         if (m_manifoldPtr != null)
         {
             m_dispatcher.ReleaseManifold(m_manifoldPtr);
         }
         m_ownManifold = false;
     }
     m_manifoldPtr = null;
 }
예제 #22
0
        public void Constructor(PersistentManifold mf, CollisionAlgorithmConstructionInfo ci, CollisionObject col0, CollisionObject col1)
        {
            base.Constructor(ci);
            m_ownManifold = false;
            m_manifoldPtr = mf;

            if (m_manifoldPtr == null)
            {
                m_manifoldPtr = m_dispatcher.getNewManifold(col0, col1);
                m_ownManifold = true;
            }
        }
예제 #23
0
 public ManifoldResult(CollisionObject body0, CollisionObject body1)
 {
     m_manifoldPtr = null;
     m_body0 = body0;
     m_body1 = body1;
     m_rootTransA = body0.WorldTransform;
     m_rootTransB = body1.WorldTransform;
     m_partId0 = -1;
     m_partId1 = -1;
     m_index0 = -1;
     m_index1 = -1;
 }
예제 #24
0
        /// <summary>
        /// Finds any robot collisions and adds them to the list of contact points.
        /// </summary>
        /// <param name="pm"></param>
        public void OnVisitPersistentManifold(PersistentManifold pm)
        {
            if (!mainState.Tracking)
            {
                return;
            }

            if (framesPassed == -1)
            {
                framesPassed = physicsWorld.frameCount - lastFrameCount;

                for (int i = 0; i < framesPassed; i++)
                {
                    ContactPoints.Add(new List <ContactDescriptor>());
                }
            }

            BRigidBody obA       = pm.Body0.UserObject as BRigidBody;
            BRigidBody obB       = pm.Body1.UserObject as BRigidBody;
            BRigidBody robotBody = obA != null && obA.gameObject.name.StartsWith("node") ? obA : obB != null && obB.gameObject.name.StartsWith("node") ? obB : null;

            if (robotBody == null)
            {
                return;
            }

            if (pm.NumContacts < 1)
            {
                return;
            }

            int numContacts = pm.NumContacts;

            for (int i = 0; i < Math.Min(framesPassed, numContacts); i++)
            {
                ManifoldPoint mp = pm.GetContactPoint(i);

                ContactDescriptor cd = new ContactDescriptor
                {
                    AppliedImpulse = mp.AppliedImpulse,
                    Position       = (mp.PositionWorldOnA + mp.PositionWorldOnB) * 0.5f,
                    RobotBody      = robotBody
                };

                if (ContactPoints[i] != null)
                {
                    ContactPoints[i].Add(cd);
                }
            }
        }
예제 #25
0
    	public ConvexConvexAlgorithm(PersistentManifold mf,CollisionAlgorithmConstructionInfo ci,CollisionObject body0,CollisionObject body1, ISimplexSolverInterface simplexSolver, IConvexPenetrationDepthSolver pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold) : base(ci,body0,body1)
        {
            m_simplexSolver = simplexSolver;
            m_pdSolver = pdSolver;
            m_ownManifold = false;
            m_manifoldPtr = mf;
            m_lowLevelOfDetail = false;
            #if USE_SEPDISTANCE_UTIL2
            m_sepDistance ((static_cast<btConvexShape*>(body0.getCollisionShape())).getAngularMotionDisc(),
			  (static_cast<btConvexShape*>(body1.getCollisionShape())).getAngularMotionDisc()),
            #endif
            m_numPerturbationIterations = numPerturbationIterations;
            m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
        }
        public override void OnVisitPersistentManifold(PersistentManifold pm)
        {
            if (myCollisionObject == null)
            {
                return;
            }

            CollisionObject other;

            if (pm.NumContacts > 0)
            {
                if (pm.Body0 == myCollisionObject)
                {
                    other = pm.Body1;
                }
                else
                {
                    other = pm.Body0;
                }
                PersistentManifoldList pml;
                if (!otherObjs2ManifoldMap.TryGetValue(other, out pml))
                {
                    //todo get PersistentManifoldList from object pool
                    //this is first contact with this other object
                    //might have multiple new contacts with same object stored in separate persistent manifolds
                    //don't add two different lists to new contacts
                    bool foundExisting = false;
                    for (int i = 0; i < newContacts.Count; i++)
                    {
                        if (newContacts[i].manifolds[0].Body0 == other ||
                            newContacts[i].manifolds[0].Body1 == other)
                        {
                            foundExisting = true;
                            newContacts[i].manifolds.Add(pm);
                        }
                    }
                    if (!foundExisting)
                    {
                        pml = new PersistentManifoldList();
                        newContacts.Add(pml);
                        pml.manifolds.Add(pm);
                        //don't add to otherObjs2ManifoldMap here. It messes up onStay do it after all pm's have been visited.
                    }
                }
                else
                {
                    pml.manifolds.Add(pm);
                }
            }
        }
예제 #27
0
        private void ObstaculoCollision(PersistentManifold contactManifold, int misilId, int objetoId)
        {
            int numContacts = contactManifold.NumContacts;

            for (int j = 0; j < numContacts; j++)
            {
                ManifoldPoint pt     = contactManifold.GetContactPoint(j);
                double        ptdist = pt.Distance;
                if (Math.Abs(ptdist) < epsilonContact)
                {
                    listaColisionesObstaculoMisil.Add(new Colision(objetoId, misilId));
                    listaObstaculos[objetoId].Destruir();
                }
            }
        }
예제 #28
0
        private void TorretaCollision(PersistentManifold contactManifold, int misilId, int objetoId)
        {
            int numContacts = contactManifold.NumContacts;

            for (int j = 0; j < numContacts; j++)
            {
                ManifoldPoint pt     = contactManifold.GetContactPoint(j);
                double        ptdist = pt.Distance;
                Console.WriteLine(ptdist);
                if (Math.Abs(ptdist) < 6)
                {
                    listaColisionesTorretaMisil.Add(new Colision(objetoId, misilId));
                    listaTorretas[objetoId].DisminuirVida();
                }
            }
        }
예제 #29
0
        protected void Constructor(PersistentManifold mf, CollisionAlgorithmConstructionInfo ci, CollisionObject col0, CollisionObject col1, bool isSwapped)
        {
            base.Constructor(ci);
            m_ownManifold = false;
            m_manifoldPtr=mf;
            m_isSwapped=isSwapped;

	        CollisionObject sphereObj = m_isSwapped? col1 : col0;
	        CollisionObject boxObj = m_isSwapped? col0 : col1;
        	
	        if (m_manifoldPtr==null && m_dispatcher.needsCollision(sphereObj,boxObj))
	        {
		        m_manifoldPtr = m_dispatcher.getNewManifold(sphereObj,boxObj);
		        m_ownManifold = true;
	        }
        }
예제 #30
0
        private void XwingCollision(PersistentManifold contactManifold, int misilId)
        {
            int numContacts = contactManifold.NumContacts;

            for (int j = 0; j < numContacts && !listaIdMisilesQueColisionaronConXwing.Contains(misilId); j++)
            {
                ManifoldPoint pt     = contactManifold.GetContactPoint(j);
                double        ptdist = pt.Distance;
                if (Math.Abs(ptdist) < epsilonContact)
                {
                    listaIdMisilesQueColisionaronConXwing.Add(misilId);
                    collisionWorld.RemoveCollisionObject(listaMisilesEnemigo[misilId]);
                    listaMisilesEnemigo.Remove(misilId);
                    VariablesGlobales.RestarVida();
                }
            }
        }
        public ConvexPlaneCollisionAlgorithm(PersistentManifold mf, CollisionAlgorithmConstructionInfo ci, CollisionObject col0,CollisionObject col1,bool isSwapped,int numPerturbationIterations,int minimumPointsPerturbationThreshold) : base(ci)
        {
            m_manifoldPtr = mf;
            m_ownManifold = false;
            m_isSwapped = isSwapped;
            m_numPerturbationIterations = numPerturbationIterations;
            m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
            
            CollisionObject convexObj = m_isSwapped? col1 : col0;
	        CollisionObject planeObj = m_isSwapped? col0 : col1;

	        if (m_manifoldPtr == null && m_dispatcher.NeedsCollision(convexObj,planeObj))
	        {
		        m_manifoldPtr = m_dispatcher.GetNewManifold(convexObj,planeObj);
		        m_ownManifold = true;
	        }

        }
예제 #32
0
        void OnContactDestroyed(object userPersistantData)
        {
            int numManifolds = BtWorld.Dispatcher.NumManifolds;

            for (int i = 0; i < numManifolds; i++)
            {
                PersistentManifold contactManifold = BtWorld.Dispatcher.GetManifoldByIndexInternal(i);
                int numContacts = contactManifold.NumContacts;
                if (numContacts > 0)
                {
                    CollisionObject obA = (CollisionObject)contactManifold.Body0;
                    CollisionObject obB = (CollisionObject)contactManifold.Body1;
                    obA.CollisionFlags = CollisionFlags.CustomMaterialCallback;
                    obB.CollisionFlags = CollisionFlags.CustomMaterialCallback;
                }
            }
            // Debug.WriteLine("OnContactDestroyed");
        }
        public void GhostObjectPairsTest()
        {
            var world = _context.DiscreteDynamicsWorld;

            world.StepSimulation(1.0f / 60.0f);

            AlignedManifoldArray       manifoldArray = new AlignedManifoldArray();
            AlignedBroadphasePairArray pairArray     = _ghostObject.OverlappingPairCache.OverlappingPairArray;

            foreach (BroadphasePair pair in pairArray)
            {
                //unless we manually perform collision detection on this pair, the contacts are in the dynamics world paircache:
                BroadphasePair collisionPair = world.PairCache.FindPair(pair.Proxy0, pair.Proxy1);
                if (collisionPair == null)
                {
                    continue;
                }

                manifoldArray.Clear();

                if (collisionPair.Algorithm != null)
                {
                    collisionPair.Algorithm.GetAllContactManifolds(manifoldArray);
                }

                for (int j = 0; j < manifoldArray.Count; j++)
                {
                    PersistentManifold manifold = manifoldArray[j];
                    float directionSign         = manifold.Body0 == _ghostObject ? -1.0f : 1.0f;
                    for (int p = 0; p < manifold.NumContacts; p++)
                    {
                        ManifoldPoint pt = manifold.GetContactPoint(p);
                        if (pt.Distance < 0.0f)
                        {
                            Vector3 ptA       = pt.PositionWorldOnA;
                            Vector3 ptB       = pt.PositionWorldOnB;
                            Vector3 normalOnB = pt.NormalWorldOnB;
                        }
                    }
                }
            }

            manifoldArray.Dispose();
        }
예제 #34
0
        static void TestGhostObjectPairs(PairCachingGhostObject ghostObject)
        {
            AlignedManifoldArray       manifoldArray = new AlignedManifoldArray();
            AlignedBroadphasePairArray pairArray     = ghostObject.OverlappingPairCache.OverlappingPairArray;
            int numPairs = pairArray.Count;

            for (int i = 0; i < numPairs; i++)
            {
                manifoldArray.Clear();

                BroadphasePair pair = pairArray[i];

                //unless we manually perform collision detection on this pair, the contacts are in the dynamics world paircache:
                BroadphasePair collisionPair = world.PairCache.FindPair(pair.Proxy0, pair.Proxy1);
                if (collisionPair == null)
                {
                    continue;
                }

                if (collisionPair.Algorithm != null)
                {
                    collisionPair.Algorithm.GetAllContactManifolds(manifoldArray);
                }

                for (int j = 0; j < manifoldArray.Count; j++)
                {
                    PersistentManifold manifold = manifoldArray[j];
                    float directionSign         = manifold.Body0 == ghostObject ? -1.0f : 1.0f;
                    for (int p = 0; p < manifold.NumContacts; p++)
                    {
                        ManifoldPoint pt = manifold.GetContactPoint(p);
                        if (pt.Distance < 0.0f)
                        {
                            Vector3 ptA       = pt.PositionWorldOnA;
                            Vector3 ptB       = pt.PositionWorldOnB;
                            Vector3 normalOnB = pt.NormalWorldOnB;
                            /// work here
                        }
                    }
                }
            }
        }
예제 #35
0
        public override void OnVisitPersistentManifold(PersistentManifold pm)
        {
            CollisionObject other;

            if (pm.Body0 == myCollisionObject)
            {
                other = pm.Body1;
            }
            else
            {
                other = pm.Body0;
            }
            PersistentManifoldList pml;

            if (!otherObjs2ManifoldMap.TryGetValue(other, out pml))
            {
                //todo get from object pool
                pml = new PersistentManifoldList();
                newContacts.Add(pml);
            }
            pml.manifolds.Add(pm);
        }
        public override void Update(TimeSpan deltaTime)
        {
            float second = (float)deltaTime.TotalSeconds;

            world.StepSimulation(second);

            // on collision events
            int numManifolds = world.Dispatcher.NumManifolds;

            for (int i = 0; i < numManifolds; i++)
            {
                PersistentManifold manifold = world.Dispatcher.GetManifoldByIndexInternal(i);
                CollisionProxy     colA     = (CollisionProxy)manifold.Body0.UserObject;
                CollisionProxy     colB     = (CollisionProxy)manifold.Body1.UserObject;

                // check if both are not null
                if (colA != null && colB != null)
                {
                    // execute colA -> colB event
                    try
                    {
                        colA.ExecuteCollision(colA, colB);
                    }
                    catch (Exception e)
                    {
                        LogError(string.Format("{0} {1}", e.Message, e.StackTrace));
                    }
                    // execute colB -> colA event
                    try
                    {
                        colB.ExecuteCollision(colB, colA);
                    }
                    catch (Exception e)
                    {
                        LogError(string.Format("{0} {1}", e.Message, e.StackTrace));
                    }
                }
            }
        }
예제 #37
0
        static void TestManifoldPoints()
        {
            int numManifolds = world.Dispatcher.NumManifolds;

            for (int i = 0; i < numManifolds; i++)
            {
                PersistentManifold contactManifold = world.Dispatcher.GetManifoldByIndexInternal(i);
                CollisionObject    obA             = contactManifold.Body0 as CollisionObject;
                CollisionObject    obB             = contactManifold.Body1 as CollisionObject;

                int numContacts = contactManifold.NumContacts;
                for (int j = 0; j < numContacts; j++)
                {
                    ManifoldPoint pt = contactManifold.GetContactPoint(j);
                    if (pt.Distance < 0.0f)
                    {
                        Vector3 ptA       = pt.PositionWorldOnA;
                        Vector3 ptB       = pt.PositionWorldOnB;
                        Vector3 normalOnB = pt.NormalWorldOnB;
                    }
                }
            }
        }
예제 #38
0
        public virtual void Update(float elapsedTime)
        {
            World.StepSimulation(elapsedTime);

            for (int i = 0; i < World.Dispatcher.NumManifolds; ++i)
            {
                PersistentManifold manifold = World.Dispatcher.GetManifoldByIndexInternal(i);
                RigidBody          A        = manifold.Body0 as RigidBody;
                RigidBody          B        = manifold.Body1 as RigidBody;


                if (A.UserObject != null && A.UserObject.Equals("Ground"))
                {
                    World.RemoveRigidBody(B);
                }
                else
                if (B.UserObject != null && B.UserObject.Equals("Ground"))
                {
                    World.RemoveRigidBody(A);
                }
            }

            //  Console.WriteLine(elapsedTime);
        }
예제 #39
0
        // 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;
                    }
                }
            }
        }
예제 #40
0
        public static int GetIslandId(PersistentManifold lhs)
        {
	        int islandId;
	        CollisionObject rcolObj0 = (CollisionObject)(lhs.GetBody0());
            CollisionObject rcolObj1 = (CollisionObject)(lhs.GetBody1());
	        islandId = rcolObj0.GetIslandTag()>=0?rcolObj0.GetIslandTag():rcolObj1.GetIslandTag();
	        return islandId;
        }
예제 #41
0
 private static int PersistentManifoldSortPredicate(PersistentManifold lhs, PersistentManifold rhs)
 {
     int rIslandIdA, lIslandIdB;
     rIslandIdA = GetIslandId(rhs);
     lIslandIdB = GetIslandId(lhs);
     //return lIslandId0 < rIslandId0;
     if (lIslandIdB < rIslandIdA)
         return -1;
     //else if (lIslandIdB > rIslandIdA)
     //    return 1;
     return 1;
 }
예제 #42
0
	    public void	SetPersistentManifold(PersistentManifold manifoldPtr)
	    {
		    m_manifoldPtr = manifoldPtr;
	    }
예제 #43
0
    private void UpdateTrackers()
    {
        int numSteps = physicsWorld.frameCount - lastFrameCount;

        if (tracking && numSteps > 0)
        {
            foreach (Tracker t in Trackers)
            {
                t.AddState(numSteps);
            }

            for (int i = numSteps; i > 0; i--)
            {
                List <ContactDescriptor> frameContacts = null;

                int numManifolds = physicsWorld.world.Dispatcher.NumManifolds;

                for (int j = 0; j < numManifolds; j++)
                {
                    PersistentManifold contactManifold = physicsWorld.world.Dispatcher.GetManifoldByIndexInternal(j);
                    BRigidBody         obA             = (BRigidBody)contactManifold.Body0.UserObject;
                    BRigidBody         obB             = (BRigidBody)contactManifold.Body1.UserObject;

                    if (!obA.gameObject.name.StartsWith("node") && !obB.gameObject.name.StartsWith("node"))
                    {
                        continue;
                    }

                    ManifoldPoint mp = null;

                    int numContacts = contactManifold.NumContacts;

                    for (int k = 0; k < numContacts; k++)
                    {
                        mp = contactManifold.GetContactPoint(k);

                        if (mp.LifeTime == i)
                        {
                            break;
                        }
                    }

                    if (mp == null)
                    {
                        continue;
                    }

                    if (frameContacts == null)
                    {
                        frameContacts = new List <ContactDescriptor>();
                    }

                    frameContacts.Add(new ContactDescriptor
                    {
                        AppliedImpulse = mp.AppliedImpulse,
                        Position       = (mp.PositionWorldOnA + mp.PositionWorldOnB) * 0.5f,
                        RobotBody      = obA.name.StartsWith("node") ? obA : obB
                    });
                }

                contactPoints.Add(frameContacts);
            }
        }

        lastFrameCount += numSteps;
    }
		protected void ConvertContact(PersistentManifold manifold, ContactSolverInfo infoGlobal)
		{
			CollisionObject colObj0 = null, colObj1 = null;


			colObj0 = manifold.GetBody0() as CollisionObject;
			colObj1 = manifold.GetBody1() as CollisionObject;

			RigidBody solverBodyA = RigidBody.Upcast(colObj0);
			RigidBody solverBodyB = RigidBody.Upcast(colObj1);

			///avoid collision response between two static objects
			if ((solverBodyA == null || solverBodyA.GetInvMass() <= 0f) && (solverBodyB == null || solverBodyB.GetInvMass() <= 0f))
			{
				return;
			}

			for (int j = 0; j < manifold.GetNumContacts(); j++)
			{
				ManifoldPoint cp = manifold.GetContactPoint(j);

				if (cp.GetDistance() <= manifold.GetContactProcessingThreshold())
				{
					//                    Vector3 pos1 = cp.getPositionWorldOnA();
					//                    Vector3 pos2 = cp.getPositionWorldOnB();

					Vector3 rel_pos1 = Vector3.Zero;
					Vector3 rel_pos2 = Vector3.Zero;
					//;

					float relaxation = 1f;
					float rel_vel = 0f;
					Vector3 vel = Vector3.Zero;

					int frictionIndex = m_tmpSolverContactConstraintPool.Count;

					SolverConstraint solverConstraint = new SolverConstraint();
					//m_tmpSolverContactConstraintPool.Add(solverConstraint);

					RigidBody rb0 = RigidBody.Upcast(colObj0);
					RigidBody rb1 = RigidBody.Upcast(colObj1);
					if (BulletGlobals.g_streamWriter != null && rb0 != null && debugSolver)
					{
						MathUtil.PrintContactPoint(BulletGlobals.g_streamWriter, cp);
					}
					solverConstraint.m_solverBodyA = rb0 != null ? rb0 : GetFixedBody();
					solverConstraint.m_solverBodyB = rb1 != null ? rb1 : GetFixedBody();

					solverConstraint.m_originalContactPoint = cp;

					SetupContactConstraint(ref solverConstraint, colObj0, colObj1, cp, infoGlobal, ref vel, ref rel_vel, ref relaxation, ref rel_pos1, ref rel_pos2);

					if (BulletGlobals.g_streamWriter != null && debugSolver)
					{
						TypedConstraint.PrintSolverConstraint(BulletGlobals.g_streamWriter, solverConstraint, 99);
					}

					/////setup the friction constraints

					solverConstraint.m_frictionIndex = m_tmpSolverContactFrictionConstraintPool.Count;

					if (!(TestSolverMode(infoGlobal.m_solverMode, SolverMode.SOLVER_ENABLE_FRICTION_DIRECTION_CACHING)) || !cp.GetLateralFrictionInitialized())
					{
						cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel;
						float lat_rel_vel = cp.m_lateralFrictionDir1.LengthSquared();
						if (!TestSolverMode(infoGlobal.m_solverMode, SolverMode.SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > MathUtil.SIMD_EPSILON)
						{
							cp.m_lateralFrictionDir1 /= (float)System.Math.Sqrt(lat_rel_vel);

							if (TestSolverMode(infoGlobal.m_solverMode, SolverMode.SOLVER_USE_2_FRICTION_DIRECTIONS))
							{
								cp.m_lateralFrictionDir2 = Vector3.Cross(cp.m_lateralFrictionDir1, cp.m_normalWorldOnB);
								cp.m_lateralFrictionDir2.Normalize();//??
								ApplyAnisotropicFriction(colObj0, ref cp.m_lateralFrictionDir2);
								ApplyAnisotropicFriction(colObj1, ref cp.m_lateralFrictionDir2);
								AddFrictionConstraint(ref cp.m_lateralFrictionDir2, solverBodyA, solverBodyB, frictionIndex, cp, ref rel_pos1, ref rel_pos2, colObj0, colObj1, relaxation, 0f, 0f);
							}
							ApplyAnisotropicFriction(colObj0, ref cp.m_lateralFrictionDir1);
							ApplyAnisotropicFriction(colObj1, ref cp.m_lateralFrictionDir1);
							AddFrictionConstraint(ref cp.m_lateralFrictionDir1, solverBodyA, solverBodyB, frictionIndex, cp, ref rel_pos1, ref rel_pos2, colObj0, colObj1, relaxation, 0f, 0f);

							cp.m_lateralFrictionInitialized = true;
						}
						else
						{
							//re-calculate friction direction every frame, todo: check if this is really needed
							TransformUtil.PlaneSpace1(ref cp.m_normalWorldOnB, ref cp.m_lateralFrictionDir1, ref cp.m_lateralFrictionDir2);
							if (TestSolverMode(infoGlobal.m_solverMode, SolverMode.SOLVER_USE_2_FRICTION_DIRECTIONS))
							{
								ApplyAnisotropicFriction(colObj0, ref cp.m_lateralFrictionDir2);
								ApplyAnisotropicFriction(colObj1, ref cp.m_lateralFrictionDir2);
								AddFrictionConstraint(ref cp.m_lateralFrictionDir2, solverBodyA, solverBodyB, frictionIndex, cp, ref rel_pos1, ref rel_pos2, colObj0, colObj1, relaxation, 0f, 0f);
							}
							ApplyAnisotropicFriction(colObj0, ref cp.m_lateralFrictionDir1);
							ApplyAnisotropicFriction(colObj1, ref cp.m_lateralFrictionDir1);
							AddFrictionConstraint(ref cp.m_lateralFrictionDir1, solverBodyA, solverBodyB, frictionIndex, cp, ref rel_pos1, ref rel_pos2, colObj0, colObj1, relaxation, 0f, 0f);

							cp.m_lateralFrictionInitialized = true;
						}

					}
					else
					{
						AddFrictionConstraint(ref cp.m_lateralFrictionDir1, solverBodyA, solverBodyB, frictionIndex, cp, ref rel_pos1, ref rel_pos2, colObj0, colObj1, relaxation, cp.m_contactMotion1, cp.m_contactCFM1);

						if (TestSolverMode(infoGlobal.m_solverMode, SolverMode.SOLVER_USE_2_FRICTION_DIRECTIONS))
						{
							AddFrictionConstraint(ref cp.m_lateralFrictionDir2, solverBodyA, solverBodyB, frictionIndex, cp, ref rel_pos1, ref rel_pos2, colObj0, colObj1, relaxation, cp.m_contactMotion2, cp.m_contactCFM2);
						}
					}
					SetFrictionConstraintImpulse(ref solverConstraint, rb0, rb1, cp, infoGlobal);
					m_tmpSolverContactConstraintPool.Add(solverConstraint);
				}
			}
		}
예제 #45
0
 public void OnVisitPersistentManifold(PersistentManifold pm)
 {
     // Not implemented
 }
예제 #46
0
    bool RecoverFromPenetration(CollisionWorld collisionWorld)
    {
        Vector3 minAabb, maxAabb;

        collisionShape.GetAabb(collisionObject.WorldTransform, out minAabb, out maxAabb);
        collisionWorld.Broadphase.SetAabbRef(collisionObject.BroadphaseHandle,
                                             ref minAabb,
                                             ref maxAabb,
                                             collisionWorld.Dispatcher);

        bool penetration = false;

        collisionWorld.Dispatcher.DispatchAllCollisionPairs(collisionObjectCastToPairCache.OverlappingPairCache, collisionWorld.DispatchInfo, collisionWorld.Dispatcher);

        currentPosition = collisionObject.WorldTransform.Origin;

        float maxPen = 0f;

        for (int i = 0; i < collisionObjectCastToPairCache.OverlappingPairCache.NumOverlappingPairs; i++)
        {
            manifoldArray.Clear();

            BroadphasePair collisionPair = collisionObjectCastToPairCache.OverlappingPairCache.OverlappingPairArray[i];

            CollisionObject obj0 = collisionPair.Proxy0.ClientObject as CollisionObject;
            CollisionObject obj1 = collisionPair.Proxy1.ClientObject as CollisionObject;

            if ((obj0 != null && !obj0.HasContactResponse) || (obj1 != null && !obj1.HasContactResponse))
            {
                continue;
            }

            if (collisionPair.Algorithm != null)
            {
                collisionPair.Algorithm.GetAllContactManifolds(manifoldArray);
            }

            for (int j = 0; j < manifoldArray.Count; j++)
            {
                PersistentManifold manifold = manifoldArray[j];
                float directionSign         = manifold.Body0 == collisionObject ? -1f : 1f;
                for (int p = 0; p < manifold.NumContacts; p++)
                {
                    ManifoldPoint pt = manifold.GetContactPoint(p);

                    float dist = pt.Distance;

                    if (dist < 0.0f)
                    {
                        if (dist < maxPen)
                        {
                            maxPen = dist;
                        }
                        currentPosition += pt.NormalWorldOnB * directionSign * dist * 0.2f;
                        penetration      = true;
                    }
                }
            }
        }
        Matrix newTrans = collisionObject.WorldTransform;

        newTrans.Origin = currentPosition;
        collisionObject.WorldTransform = newTrans;

        return(penetration);
    }
 public CollisionAlgorithmConstructionInfo(IDispatcher dispatcher)
 {
     m_dispatcher1 = dispatcher;
     m_manifold = null;
 }
예제 #48
0
 public void SetContactManifold(PersistentManifold contactManifold)
 {
     m_contactManifold = contactManifold;
 }
        void FixedUpdate()
        {
            CollisionWorld collisionWorld = BPhysicsWorld.Get().world;

            collisionWorld.Dispatcher.DispatchAllCollisionPairs(m_ghostObject.OverlappingPairCache, collisionWorld.DispatchInfo, collisionWorld.Dispatcher);

            //m_currentPosition = m_ghostObject.WorldTransform.Origin;

            //float maxPen = 0f;
            objsCurrentlyInContactWith.Clear();
            for (int i = 0; i < m_ghostObject.OverlappingPairCache.NumOverlappingPairs; i++)
            {
                manifoldArray.Clear();

                BroadphasePair collisionPair = m_ghostObject.OverlappingPairCache.OverlappingPairArray[i];

                CollisionObject obj0 = collisionPair.Proxy0.ClientObject as CollisionObject;
                CollisionObject obj1 = collisionPair.Proxy1.ClientObject as CollisionObject;

                if ((obj0 != null && !obj0.HasContactResponse) || (obj1 != null && !obj1.HasContactResponse))
                {
                    continue;
                }

                if (collisionPair.Algorithm != null)
                {
                    collisionPair.Algorithm.GetAllContactManifolds(manifoldArray);
                }

                CollisionObject otherObj = null;
                if (manifoldArray.Count > 0)
                {
                    PersistentManifold pm = manifoldArray[0];
                    if (pm.Body0 == m_collisionObject)
                    {
                        otherObj = pm.Body1;
                    }
                    else
                    {
                        otherObj = pm.Body0;
                    }
                }
                else
                {
                    continue;
                }

                objsCurrentlyInContactWith.Add(otherObj);
                if (!objsIWasInContactWithLastFrame.Contains(otherObj))
                {
                    BOnTriggerEnter(otherObj, manifoldArray);
                }
                else
                {
                    BOnTriggerStay(otherObj, manifoldArray);
                }
            }
            objsIWasInContactWithLastFrame.ExceptWith(objsCurrentlyInContactWith);

            foreach (CollisionObject co in objsIWasInContactWithLastFrame)
            {
                BOnTriggerExit(co);
            }

            //swap the hashsets so objsIWasInContactWithLastFrame now contains the list of objs.
            HashSet <CollisionObject> temp = objsIWasInContactWithLastFrame;

            objsIWasInContactWithLastFrame = objsCurrentlyInContactWith;
            objsCurrentlyInContactWith     = temp;
        }
예제 #50
0
 public ContactConstraint(PersistentManifold contactManifold, RigidBody rbA, RigidBody rbB) : base(TypedConstraintType.CONTACT_CONSTRAINT_TYPE,rbA,rbB)
 {
     m_contactManifold = contactManifold;
 }
예제 #51
0
 public virtual void clearManifold(PersistentManifold manifold)
 {
     manifold.clearManifold();
 }
예제 #52
0
        private static int getIslandId(PersistentManifold lhs)
        {

            int islandId;
            CollisionObject rcolObj0 = (CollisionObject)(lhs.Body0);
            CollisionObject rcolObj1 = (CollisionObject)(lhs.Body1);
            islandId = rcolObj0.IslandTag >= 0 ? rcolObj0.IslandTag : rcolObj1.IslandTag;
            return islandId;


        }
예제 #53
0
        public override void ProcessCollision(CollisionObject body0,CollisionObject body1,DispatcherInfo dispatchInfo,ManifoldResult resultOut)
        {
	        if (m_manifoldPtr == null)
	        {
		        //swapped?
		        m_manifoldPtr = m_dispatcher.GetNewManifold(body0,body1);
		        m_ownManifold = true;
	        }
            //resultOut = new ManifoldResult();
	        resultOut.SetPersistentManifold(m_manifoldPtr);

	        //comment-out next line to test multi-contact generation
	        //resultOut.getPersistentManifold().clearManifold();
        	

	        ConvexShape min0 = (ConvexShape)(body0.GetCollisionShape());
	        ConvexShape min1 = (ConvexShape)(body1.GetCollisionShape());
        	Vector3  normalOnB = Vector3.Up;
            Vector3  pointOnBWorld = Vector3.Zero;
#if !BT_DISABLE_CAPSULE_CAPSULE_COLLIDER
            if ((min0.ShapeType == BroadphaseNativeTypes.CAPSULE_SHAPE_PROXYTYPE) && (min1.ShapeType == BroadphaseNativeTypes.CAPSULE_SHAPE_PROXYTYPE))
	        {
		        CapsuleShape capsuleA = (CapsuleShape) min0;
		        CapsuleShape capsuleB = (CapsuleShape) min1;
		        Vector3 localScalingA = capsuleA.GetLocalScaling();
		        Vector3 localScalingB = capsuleB.GetLocalScaling();
        		
		        float threshold = m_manifoldPtr.GetContactBreakingThreshold();

		        float dist = CapsuleCapsuleDistance(ref normalOnB,ref pointOnBWorld,capsuleA.getHalfHeight(),capsuleA.getRadius(),
			        capsuleB.getHalfHeight(),capsuleB.getRadius(),capsuleA.GetUpAxis(),capsuleB.GetUpAxis(),
			        body0.GetWorldTransform(),body1.GetWorldTransform(),threshold);

		        if (dist<threshold)
		        {
                    Debug.Assert(normalOnB.LengthSquared() >= (MathUtil.SIMD_EPSILON * MathUtil.SIMD_EPSILON));
			        resultOut.AddContactPoint(ref normalOnB,ref pointOnBWorld,dist);	
		        }
		        resultOut.RefreshContactPoints();
		        return;
	        }
#endif //BT_DISABLE_CAPSULE_CAPSULE_COLLIDER



        #if USE_SEPDISTANCE_UTIL2
        	if (dispatchInfo.m_useConvexConservativeDistanceUtil)
            {
                m_sepDistance.updateSeparatingDistance(body0.getWorldTransform(),body1.getWorldTransform());
            }

	        if (!dispatchInfo.m_useConvexConservativeDistanceUtil || m_sepDistance.getConservativeSeparatingDistance()<=0.f)
#endif //USE_SEPDISTANCE_UTIL2

    {

        	
	        ClosestPointInput input = new ClosestPointInput();

	        GjkPairDetector	gjkPairDetector = new GjkPairDetector(min0,min1,m_simplexSolver,m_pdSolver);
	        //TODO: if (dispatchInfo.m_useContinuous)
	        gjkPairDetector.SetMinkowskiA(min0);
	        gjkPairDetector.SetMinkowskiB(min1);

        #if USE_SEPDISTANCE_UTIL2
	        if (dispatchInfo.m_useConvexConservativeDistanceUtil)
	        {
		        input.m_maximumDistanceSquared = float.MaxValue;
	        } 
            else
        #endif //USE_SEPDISTANCE_UTIL2
	        {
		        input.m_maximumDistanceSquared = min0.Margin + min1.Margin + m_manifoldPtr.GetContactBreakingThreshold();
		        input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared;
	        }

            //input.m_stackAlloc = dispatchInfo.m_stackAllocator;
	        input.m_transformA = body0.GetWorldTransform();
	        input.m_transformB = body1.GetWorldTransform();

	        gjkPairDetector.GetClosestPoints(input,resultOut,dispatchInfo.getDebugDraw(),false);
#if USE_SEPDISTANCE_UTIL2
	float sepDist = 0.f;
	if (dispatchInfo.m_useConvexConservativeDistanceUtil)
	{
		sepDist = gjkPairDetector.getCachedSeparatingDistance();
		if (sepDist>MathUtil.SIMD_EPSILON)
		{
			sepDist += dispatchInfo.m_convexConservativeDistanceThreshold;
			//now perturbe directions to get multiple contact points
		}
	}
#endif //USE_SEPDISTANCE_UTIL2

	        //now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects
        	
	        //perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points
	        if (m_numPerturbationIterations > 0 &&  resultOut.GetPersistentManifold().GetNumContacts() < m_minimumPointsPerturbationThreshold)
	        {
                Vector3 v0 = Vector3.Zero, v1 = Vector3.Zero;

                Vector3 sepNormalWorldSpace = gjkPairDetector.GetCachedSeparatingAxis();
                sepNormalWorldSpace.Normalize();
                TransformUtil.PlaneSpace1(ref sepNormalWorldSpace, ref v0, ref v1);

		        bool perturbeA = true;
		        const float angleLimit = 0.125f * MathUtil.SIMD_PI;
		        float perturbeAngle;
		        float radiusA = min0.GetAngularMotionDisc();
		        float radiusB = min1.GetAngularMotionDisc();
		        if (radiusA < radiusB)
		        {
			        perturbeAngle = BulletGlobals.gContactBreakingThreshold /radiusA;
			        perturbeA = true;
		        } 
                else
		        {
                    perturbeAngle = BulletGlobals.gContactBreakingThreshold / radiusB;
			        perturbeA = false;
		        }
                if (perturbeAngle > angleLimit)
                {
                    perturbeAngle = angleLimit;
                }

		        Matrix unPerturbedTransform = Matrix.Identity;
		        if (perturbeA)
		        {
			        unPerturbedTransform = input.m_transformA;
		        } 
                else
		        {
			        unPerturbedTransform = input.m_transformB;
		        }
        		
		        for (int i=0;i<m_numPerturbationIterations;i++)
		        {
                    if (v0.LengthSquared() > MathUtil.SIMD_EPSILON)
                    {

                        Quaternion perturbeRot = Quaternion.CreateFromAxisAngle(v0, perturbeAngle);
                        float iterationAngle = i * (MathUtil.SIMD_2_PI / (float)m_numPerturbationIterations);
                        Quaternion rotq = Quaternion.CreateFromAxisAngle(sepNormalWorldSpace, iterationAngle);

                        if (perturbeA)
                        {
                            //input.m_transformA.setBasis(  btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0.getWorldTransform().getBasis());
                            Quaternion temp = MathUtil.QuaternionMultiply(MathUtil.QuaternionInverse(ref rotq),MathUtil.QuaternionMultiply(perturbeRot,rotq));
                            input.m_transformA = MathUtil.BulletMatrixMultiplyBasis(Matrix.CreateFromQuaternion(temp),body0.GetWorldTransform());
                            input.m_transformB = body1.GetWorldTransform();
#if DEBUG_CONTACTS
				        dispatchInfo.m_debugDraw.DrawTransform(ref input.m_transformA,10.0f);
#endif //DEBUG_CONTACTS
                        }
                        else
                        {
                            input.m_transformA = body0.GetWorldTransform();
                            //input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1.getWorldTransform().getBasis());
                            Quaternion temp = MathUtil.QuaternionMultiply(MathUtil.QuaternionInverse(ref rotq),MathUtil.QuaternionMultiply(perturbeRot,rotq));
                            input.m_transformB = MathUtil.BulletMatrixMultiplyBasis(Matrix.CreateFromQuaternion(temp),body1.GetWorldTransform());
#if DEBUG_CONTACTS
				        dispatchInfo.m_debugDraw.DrawTransform(ref input.m_transformB,10.0f);
#endif
                        }

                        PerturbedContactResult perturbedResultOut = new PerturbedContactResult(resultOut, ref input.m_transformA, ref input.m_transformB, ref unPerturbedTransform, perturbeA, dispatchInfo.getDebugDraw());
                        gjkPairDetector.GetClosestPoints(input, perturbedResultOut, dispatchInfo.getDebugDraw(), false);
                    }
        			
        			
		        }
	        }

        	

        #if USE_SEPDISTANCE_UTIL2
	        if (dispatchInfo.m_useConvexConservativeDistanceUtil && (sepDist > MathUtil.SIMD_EPSILON))
	        {
		        m_sepDistance.initSeparatingDistance(gjkPairDetector.getCachedSeparatingAxis(),sepDist,body0.getWorldTransform(),body1.getWorldTransform());
	        }
        #endif //USE_SEPDISTANCE_UTIL2


	        }

	        if (m_ownManifold)
	        {
		        resultOut.RefreshContactPoints();
	        }
        }
	    public SphereSphereCollisionAlgorithm(PersistentManifold mf,CollisionAlgorithmConstructionInfo ci,CollisionObject body0,CollisionObject body1) : base(ci,body0,body1)
        {

        }
예제 #55
0
        public virtual float SolveGroup(List <CollisionObject> bodies, List <PersistentManifold> manifolds, int numManifolds, List <TypedConstraint> constraints, ContactSolverInfo infoGlobal, IDebugDraw debugDrawer)
        {
            if ((_solverMode & SolverMode.CacheFriendly) != SolverMode.None)
            {
                return(SolveGroupCacheFriendly(bodies, manifolds, numManifolds, constraints, infoGlobal, debugDrawer));
            }

            ContactSolverInfo info = infoGlobal;
            int totalPoints        = 0;

            int numiter = infoGlobal.IterationsCount;

            for (int j = 0; j < manifolds.Count; j++)
            {
                PersistentManifold manifold = manifolds[j];
                PrepareConstraints(manifold, info);

                for (int p = 0; p < manifolds[j].ContactsCount; p++)
                {
                    _order[totalPoints].ManifoldIndex = j;
                    _order[totalPoints].PointIndex    = p;
                    totalPoints++;
                }
            }

            for (int j = 0; j < constraints.Count; j++)
            {
                constraints[j].BuildJacobian();
            }

            //should traverse the contacts random order...
            int iteration;

            for (iteration = 0; iteration < numiter; iteration++)
            {
                int j;
                if ((_solverMode & SolverMode.RandomizeOrder) != SolverMode.None)
                {
                    if ((iteration & 7) == 0)
                    {
                        for (j = 0; j < totalPoints; ++j)
                        {
                            OrderIndex tmp   = _order[j];
                            int        swapi = RandInt2(j + 1);
                            _order[j]     = _order[swapi];
                            _order[swapi] = tmp;
                        }
                    }
                }

                for (j = 0; j < constraints.Count; j++)
                {
                    constraints[j].SolveConstraint(info.TimeStep);
                }

                for (j = 0; j < totalPoints; j++)
                {
                    PersistentManifold manifold = manifolds[_order[j].ManifoldIndex];
                    Solve((RigidBody)manifold.BodyA, (RigidBody)manifold.BodyB,
                          manifold.GetContactPoint(_order[j].PointIndex), info, iteration, debugDrawer);
                }

                for (j = 0; j < totalPoints; j++)
                {
                    PersistentManifold manifold = manifolds[_order[j].ManifoldIndex];
                    SolveFriction((RigidBody)manifold.BodyA,
                                  (RigidBody)manifold.BodyB, manifold.GetContactPoint(_order[j].PointIndex), info, iteration, debugDrawer);
                }
            }

            return(0);
        }
예제 #56
0
        public override void processCollision(CollisionObject body0, CollisionObject body1, DispatcherInfo dispatchInfo, ref ManifoldResult resultOut)
        {
            if (m_manifoldPtr == null)
            {
                //swapped?
                m_manifoldPtr = m_dispatcher.getNewManifold(body0, body1);
                m_ownManifold = true;
            }
            resultOut.PersistentManifold = m_manifoldPtr;

            //comment-out next line to test multi-contact generation
            //resultOut->getPersistentManifold()->clearManifold();


            ConvexShape min0 = (ConvexShape)(body0.CollisionShape);
            ConvexShape min1 = (ConvexShape)(body1.CollisionShape);

            btVector3 normalOnB;
            btVector3 pointOnBWorld;
            if ((min0.ShapeType == BroadphaseNativeTypes.CAPSULE_SHAPE_PROXYTYPE) && (min1.ShapeType == BroadphaseNativeTypes.CAPSULE_SHAPE_PROXYTYPE))
            {
                CapsuleShape capsuleA = (CapsuleShape)min0;
                CapsuleShape capsuleB = (CapsuleShape)min1;
                btVector3 localScalingA = capsuleA.LocalScaling;
                btVector3 localScalingB = capsuleB.LocalScaling;

                float threshold = m_manifoldPtr.ContactBreakingThreshold;

                float dist = capsuleCapsuleDistance(out normalOnB, out	pointOnBWorld, capsuleA.HalfHeight, capsuleA.Radius,
                    capsuleB.HalfHeight, capsuleB.Radius, capsuleA.UpAxis, capsuleB.UpAxis,
                    body0.WorldTransform, body1.WorldTransform, threshold);

                if (dist < threshold)
                {
                    Debug.Assert(normalOnB.Length2 >= (BulletGlobal.SIMD_EPSILON * BulletGlobal.SIMD_EPSILON));
                    resultOut.addContactPoint(ref normalOnB, ref pointOnBWorld, dist);
                }
                resultOut.refreshContactPoints();
                return;
            }


#if USE_SEPDISTANCE_UTIL2
	        if (dispatchInfo.m_useConvexConservativeDistanceUtil)
	        {
		        m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform());
	        }

        	if (!dispatchInfo.m_useConvexConservativeDistanceUtil || m_sepDistance.getConservativeSeparatingDistance()<=0.f)
#endif //USE_SEPDISTANCE_UTIL2
            {


                ClosestPointInput input;

                GjkPairDetector gjkPairDetector = new GjkPairDetector(min0, min1, m_simplexSolver, m_pdSolver);
                //TODO: if (dispatchInfo.m_useContinuous)
                gjkPairDetector.MinkowskiA = min0;
                gjkPairDetector.MinkowskiB = min1;

#if USE_SEPDISTANCE_UTIL2
	            if (dispatchInfo.m_useConvexConservativeDistanceUtil)
	            {
		            input.m_maximumDistanceSquared = BT_LARGE_FLOAT;
	            } else
#endif //USE_SEPDISTANCE_UTIL2
                {
                    input.m_maximumDistanceSquared = min0.Margin + min1.Margin + m_manifoldPtr.ContactBreakingThreshold;
                    input.m_maximumDistanceSquared *= input.m_maximumDistanceSquared;
                }

                //input.m_stackAlloc = dispatchInfo.m_stackAllocator;
                input.m_transformA = body0.WorldTransform;
                input.m_transformB = body1.WorldTransform;

                gjkPairDetector.getClosestPoints(ref input, ref resultOut, dispatchInfo.m_debugDraw);

#if USE_SEPDISTANCE_UTIL2
	            btScalar sepDist = 0.f;
	            if (dispatchInfo.m_useConvexConservativeDistanceUtil)
	            {
		            sepDist = gjkPairDetector.getCachedSeparatingDistance();
		            if (sepDist>SIMD_EPSILON)
		            {
			            sepDist += dispatchInfo.m_convexConservativeDistanceThreshold;
			            //now perturbe directions to get multiple contact points
            			
		            }
	            }
#endif //USE_SEPDISTANCE_UTIL2


                //now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects

                //perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points
                if (m_numPerturbationIterations != 0 && resultOut.PersistentManifold.NumContacts < m_minimumPointsPerturbationThreshold)
                {

                    int i;
                    btVector3 v0, v1;
                    btVector3 sepNormalWorldSpace;

                    //sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis().normalized();
                    gjkPairDetector.getCachedSeparatingAxis().normalized(out sepNormalWorldSpace);
                    btVector3.PlaneSpace1(ref sepNormalWorldSpace, out v0, out v1);


                    bool perturbeA = true;
                    float angleLimit = 0.125f * BulletGlobal.SIMD_PI;
                    float perturbeAngle;
                    float radiusA = min0.getAngularMotionDisc();
                    float radiusB = min1.getAngularMotionDisc();
                    if (radiusA < radiusB)
                    {
                        perturbeAngle = PersistentManifold.gContactBreakingThreshold / radiusA;
                        perturbeA = true;
                    }
                    else
                    {
                        perturbeAngle = PersistentManifold.gContactBreakingThreshold / radiusB;
                        perturbeA = false;
                    }
                    if (perturbeAngle > angleLimit)
                        perturbeAngle = angleLimit;

                    btTransform unPerturbedTransform;
                    if (perturbeA)
                    {
                        unPerturbedTransform = input.m_transformA;
                    }
                    else
                    {
                        unPerturbedTransform = input.m_transformB;
                    }

                    for (i = 0; i < m_numPerturbationIterations; i++)
                    {
                        if (v0.Length2 > BulletGlobal.SIMD_EPSILON)
                        {
                            btQuaternion perturbeRot = new btQuaternion(v0, perturbeAngle);
                            float iterationAngle = i * (BulletGlobal.SIMD_2_PI / m_numPerturbationIterations);
                            btQuaternion rotq = new btQuaternion(sepNormalWorldSpace, iterationAngle);


                            if (perturbeA)
                            {
                                #region input.m_transformA.Basis = new btMatrix3x3(rotq.inverse() * perturbeRot * rotq) * body0.WorldTransform.Basis;
                                {
                                    btMatrix3x3 temp = new btMatrix3x3(rotq.inverse() * perturbeRot * rotq);
                                    btMatrix3x3.Multiply(ref temp, ref body0.WorldTransform.Basis, out input.m_transformA.Basis);
                                }
                                #endregion
                                input.m_transformB = body1.WorldTransform;
#if DEBUG
                                dispatchInfo.m_debugDraw.drawTransform(ref input.m_transformA, 10.0f);
#endif //DEBUG_CONTACTS
                            }
                            else
                            {
                                input.m_transformA = body0.WorldTransform;
                                #region input.m_transformB.Basis = new btMatrix3x3(rotq.inverse() * perturbeRot * rotq) * body1.WorldTransform.Basis;
                                {
                                    btMatrix3x3 temp = new btMatrix3x3(rotq.inverse() * perturbeRot * rotq);
                                    btMatrix3x3.Multiply(ref temp, ref body1.WorldTransform.Basis, out input.m_transformB.Basis);
                                }
                                #endregion
#if DEBUG
                                dispatchInfo.m_debugDraw.drawTransform(ref input.m_transformB, 10.0f);
#endif
                            }
                            PerturbedContactResult perturbedResultOut = new PerturbedContactResult(input.m_transformA, input.m_transformB, unPerturbedTransform, perturbeA, dispatchInfo.m_debugDraw);
                            gjkPairDetector.getClosestPoints(ref input, ref perturbedResultOut, ref resultOut, dispatchInfo.m_debugDraw);

                        }

                    }
                }


#if USE_SEPDISTANCE_UTIL2
	            if (dispatchInfo.m_useConvexConservativeDistanceUtil && (sepDist>SIMD_EPSILON))
	            {
		            m_sepDistance.initSeparatingDistance(gjkPairDetector.getCachedSeparatingAxis(),sepDist,body0->getWorldTransform(),body1->getWorldTransform());
	            }
#endif //USE_SEPDISTANCE_UTIL2



            }

            if (m_ownManifold)
            {
                resultOut.refreshContactPoints();
            }
        }
 public abstract void OnVisitPersistentManifold(PersistentManifold pm);
예제 #58
0
 public void OnVisitPersistentManifold(PersistentManifold pm)
 {
     lastManifolds.Add(pm);
 }
 public SphereTriangleCollisionAlgorithm(PersistentManifold mf,CollisionAlgorithmConstructionInfo ci,CollisionObject body0,CollisionObject body1,bool swapped) : base(ci,body0,body1)
 {
     m_ownManifold = false;
     m_manifoldPtr = mf;
     m_swapped = swapped;
 }
		protected void PrepareConstraints(PersistentManifold manifold, ContactSolverInfo info)
		{
			RigidBody body0 = manifold.BodyA as RigidBody;
			RigidBody body1 = manifold.BodyB as RigidBody;


			//only necessary to refresh the manifold once (first iteration). The integration is done outside the loop
			{
				manifold.RefreshContactPoints(body0.CenterOfMassTransform, body1.CenterOfMassTransform);

				int numpoints = manifold.ContactsCount;

				_totalContactPoints += numpoints;

				Vector3 color = new Vector3(0, 1, 0);
				for (int i = 0; i < numpoints; i++)
				{
					ManifoldPoint cp = manifold.GetContactPoint(i);
					if (cp.Distance <= 0)
					{
						Vector3 pos1 = cp.PositionWorldOnA;
						Vector3 pos2 = cp.PositionWorldOnB;

						Vector3 rel_pos1 = pos1 - body0.CenterOfMassPosition;
						Vector3 rel_pos2 = pos2 - body1.CenterOfMassPosition;


						//this jacobian entry is re-used for all iterations
						JacobianEntry jac = new JacobianEntry(MatrixOperations.Transpose(body0.CenterOfMassTransform),
							MatrixOperations.Transpose(body1.CenterOfMassTransform),
							rel_pos1, rel_pos2, cp.NormalWorldOnB, body0.InvInertiaDiagLocal, body0.InverseMass,
							body1.InvInertiaDiagLocal, body1.InverseMass);

						float jacDiagAB = jac.Diagonal;

						ConstraintPersistentData cpd = cp.UserPersistentData as ConstraintPersistentData;
						if (cpd != null)
						{
							//might be invalid
							cpd.PersistentLifeTime++;
							if (cpd.PersistentLifeTime != cp.LifeTime)
							{
								//printf("Invalid: cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd->m_persistentLifeTime,cp.getLifeTime());
								cpd = new ConstraintPersistentData();
								cpd.PersistentLifeTime = cp.LifeTime;

							}
						}
						else
						{

							cpd = new ConstraintPersistentData();
							_totalCpd++;
							//printf("totalCpd = %i Created Ptr %x\n",totalCpd,cpd);
							cp.UserPersistentData = cpd;
							cpd.PersistentLifeTime = cp.LifeTime;
							//printf("CREATED: %x . cpd->m_persistentLifeTime = %i cp.getLifeTime() = %i\n",cpd,cpd->m_persistentLifeTime,cp.getLifeTime());

						}
						if (cpd == null)
							throw new BulletException();

						cpd.JacDiagABInv = 1f / jacDiagAB;

						//Dependent on Rigidbody A and B types, fetch the contact/friction response func
						//perhaps do a similar thing for friction/restutution combiner funcs...

						cpd.FrictionSolverFunc = _frictionDispatch[(int)body0.FrictionSolverType, (int)body1.FrictionSolverType];
						cpd.ContactSolverFunc = _contactDispatch[(int)body0.ContactSolverType, (int)body1.ContactSolverType];

						Vector3 vel1 = body0.GetVelocityInLocalPoint(rel_pos1);
						Vector3 vel2 = body1.GetVelocityInLocalPoint(rel_pos2);
						Vector3 vel = vel1 - vel2;
						float rel_vel;
						rel_vel = Vector3.Dot(cp.NormalWorldOnB, vel);

						float combinedRestitution = cp.CombinedRestitution;

						cpd.Penetration = cp.Distance;
						cpd.Friction = cp.CombinedFriction;
						cpd.Restitution = RestitutionCurve(rel_vel, combinedRestitution);
						if (cpd.Restitution < 0f)
						{
							cpd.Restitution = 0.0f;

						};

						//restitution and penetration work in same direction so
						//rel_vel 

						float penVel = -cpd.Penetration / info.TimeStep;

						if (cpd.Restitution > penVel)
						{
							cpd.Penetration = 0;
						}


						float relaxation = info.Damping;
						if ((_solverMode & SolverMode.UseWarmstarting) != 0)
						{
							cpd.AppliedImpulse *= relaxation;
						}
						else
						{
							cpd.AppliedImpulse = 0f;
						}

						//for friction
						cpd.PreviousAppliedImpulse = cpd.AppliedImpulse;

						//re-calculate friction direction every frame, todo: check if this is really needed
						Vector3 fwta = cpd.FrictionWorldTangentialA;
						Vector3 fwtb = cpd.FrictionWorldTangentialB;
						MathHelper.PlaneSpace1(cp.NormalWorldOnB, ref fwta, ref fwtb);
						cpd.FrictionWorldTangentialA = fwta;
						cpd.FrictionWorldTangentialB = fwtb;

						cpd.AccumulatedTangentImpulseA = 0;
						cpd.AccumulatedTangentImpulseB = 0;
						float denom0 = body0.ComputeImpulseDenominator(pos1, cpd.FrictionWorldTangentialA);
						float denom1 = body1.ComputeImpulseDenominator(pos2, cpd.FrictionWorldTangentialA);
						float denom = relaxation / (denom0 + denom1);
						cpd.JacDiagABInvTangentA = denom;


						denom0 = body0.ComputeImpulseDenominator(pos1, cpd.FrictionWorldTangentialB);
						denom1 = body1.ComputeImpulseDenominator(pos2, cpd.FrictionWorldTangentialB);
						denom = relaxation / (denom0 + denom1);
						cpd.JacDiagABInvTangentB = denom;

						Vector3 totalImpulse = cp.NormalWorldOnB * cpd.AppliedImpulse;

						{
							Vector3 torqueAxis0 = Vector3.Cross(rel_pos1, cp.NormalWorldOnB);
							cpd.AngularComponentA = Vector3.TransformNormal(torqueAxis0, body0.InvInertiaTensorWorld);
							Vector3 torqueAxis1 = Vector3.Cross(rel_pos2, cp.NormalWorldOnB);
							cpd.AngularComponentB = Vector3.TransformNormal(torqueAxis1, body1.InvInertiaTensorWorld);
						}
						{
							Vector3 ftorqueAxis0 = Vector3.Cross(rel_pos1, cpd.FrictionWorldTangentialA);
							cpd.FrictionAngularComponent0A = Vector3.TransformNormal(ftorqueAxis0, body0.InvInertiaTensorWorld);
						}
						{
							Vector3 ftorqueAxis1 = Vector3.Cross(rel_pos1, cpd.FrictionWorldTangentialB);
							cpd.FrictionAngularComponent1A = Vector3.TransformNormal(ftorqueAxis1, body0.InvInertiaTensorWorld);
						}
						{
							Vector3 ftorqueAxis0 = Vector3.Cross(rel_pos2, cpd.FrictionWorldTangentialA);
							cpd.FrictionAngularComponent0B = Vector3.TransformNormal(ftorqueAxis0, body1.InvInertiaTensorWorld);
						}
						{
							Vector3 ftorqueAxis1 = Vector3.Cross(rel_pos2, cpd.FrictionWorldTangentialB);
							cpd.FrictionAngularComponent1B = Vector3.TransformNormal(ftorqueAxis1, body1.InvInertiaTensorWorld);
						}


						//apply previous frames impulse on both bodies
						body0.ApplyImpulse(totalImpulse, rel_pos1);
						body1.ApplyImpulse(-totalImpulse, rel_pos2);
					}
				}
			}
		}