Пример #1
0
 void DispatcherNearCallback(BroadphasePair collisionPair, CollisionDispatcher dispatcher,
     DispatcherInfo dispatchInfo)
 {
     //AddToDisposeQueue(dispatchInfo.DebugDraw);
     TestManifoldPoints();
     //Console.WriteLine("DispatcherNearCallback");
 }
		public void CleanOverlappingPair(BroadphasePair pair, Dispatcher dispatcher)
		{
			btOverlappingPairCache_cleanOverlappingPair(_native, pair._native, dispatcher._native);
		}
		public bool ProcessOverlap(BroadphasePair pair)
		{
			return btOverlapCallback_processOverlap(_native, pair._native);
		}
        protected bool RecoverFromPenetration(CollisionWorld collisionWorld)
        {
            // Here we must refresh the overlapping paircache as the penetrating movement itself or the
            // previous recovery iteration might have used setWorldTransform and pushed us into an object
            // that is not in the previous cache contents from the last timestep, as will happen if we
            // are pushed into a new AABB overlap. Unhandled this means the next convex sweep gets stuck.
            //
            // Do this by calling the broadphase's setAabb with the moved AABB, this will update the broadphase
            // paircache and the ghostobject's internal paircache at the same time.    /BW

            Vector3 minAabb, maxAabb;

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

            bool penetration = false;

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

            m_currentPosition = m_ghostObject.WorldTransform.Origin;

            //  btScalar maxPen = btScalar(0.0);
            for (int i = 0; i < m_ghostObject.OverlappingPairCache.NumOverlappingPairs; i++)
            {
                m_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 (!NeedsCollision(obj0, obj1))
                {
                    continue;
                }

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

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

                        float dist = pt.Distance;

                        if (dist < -m_maxPenetrationDepth)
                        {
                            // to do: cause problems on slopes, not sure if it is needed
                            //if (dist < maxPen)
                            //{
                            //  maxPen = dist;
                            //  m_touchingNormal = pt.m_normalWorldOnB * directionSign;//??

                            //}
                            m_currentPosition += pt.NormalWorldOnB * directionSign * dist * 0.2f;
                            penetration        = true;
                        }
                        else
                        {
                            //System.Console.WriteLine("touching " + dist);
                        }
                    }

                    //manifold.ClearManifold();
                }
            }
            Matrix newTrans = m_ghostObject.WorldTransform;

            newTrans.Origin = m_currentPosition;
            m_ghostObject.WorldTransform = newTrans;
            //System.Console.WriteLine("m_touchingNormal = " + m_touchingNormal);
            return(penetration);
        }
Пример #5
0
 public void CleanOverlappingPair(BroadphasePair pair, Dispatcher dispatcher)
 {
     btOverlappingPairCache_cleanOverlappingPair(_native, pair._native, dispatcher._native);
 }
Пример #6
0
 public bool ProcessOverlap(BroadphasePair pair)
 {
     return(btOverlapCallback_processOverlap(_native, pair._native));
 }
 public static void DefaultNearCallback(BroadphasePair collisionPair, CollisionDispatcher dispatcher,
                                        DispatcherInfo dispatchInfo)
 {
     btCollisionDispatcher_defaultNearCallback(collisionPair.Native, dispatcher.Native,
                                               dispatchInfo.Native);
 }
		public static void DefaultNearCallback(BroadphasePair collisionPair, CollisionDispatcher dispatcher, DispatcherInfo dispatchInfo)
		{
			btCollisionDispatcher_defaultNearCallback(collisionPair._native, dispatcher._native, dispatchInfo._native);
		}
        protected bool RecoverFromPenetration(CollisionWorld collisionWorld)
        {
            Vector3 minAabb, maxAabb;

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

            bool penetration = false;

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

            m_currentPosition = m_ghostObject.WorldTransform.Origin;

            float maxPen = 0f;

            for (int i = 0; i < m_ghostObject.OverlappingPairCache.NumOverlappingPairs; i++)
            {
                m_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(m_manifoldArray);
                }

                for (int j = 0; j < m_manifoldArray.Count; j++)
                {
                    PersistentManifold manifold = m_manifoldArray[j];
                    float directionSign         = manifold.Body0 == m_ghostObject ? -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;
                                m_touchingNormal = pt.NormalWorldOnB * directionSign;//??
                            }
                            m_currentPosition += pt.NormalWorldOnB * directionSign * dist * 0.2f;
                            penetration        = true;
                        }
                        else
                        {
                            //printf("touching %f\n", dist);
                        }
                    }

                    //manifold.ClearManifold();
                }
            }
            Matrix newTrans = m_ghostObject.WorldTransform;

            newTrans.Origin = m_currentPosition;
            m_ghostObject.WorldTransform = newTrans;
            //	printf("m_touchingNormal = %f,%f,%f\n",m_touchingNormal[0],m_touchingNormal[1],m_touchingNormal[2]);
            return(penetration);
        }
Пример #10
0
        protected bool RecoverFromPenetration(CollisionWorld collisionWorld)
        {
            Vector3 minAabb, maxAabb;

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

            bool penetration = false;

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

            m_currentPosition = m_ghostObject.WorldTransform.Origin;

            float maxPen = 0f;

            for (int i = 0; i < m_ghostObject.OverlappingPairCache.NumOverlappingPairs; i++)
            {
                m_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;
                }

                collisionPair.GetAllContactManifolds(m_manifoldArray);

                for (int j = 0; j < m_manifoldArray.Count; j++)
                {
                    var manifoldId  = AlignedManifoldArray.btAlignedManifoldArray_at(m_manifoldArray._native, j);
                    var bodyId      = PersistentManifold.btPersistentManifold_getBody0(manifoldId);
                    var numContacts = PersistentManifold.btPersistentManifold_getNumContacts(manifoldId);

                    float directionSign = bodyId == m_ghostObject._native ? -1f : 1f;
                    for (int p = 0; p < numContacts; p++)
                    {
                        var   manifoldPointId = PersistentManifold.btPersistentManifold_getContactPoint(manifoldId, p);
                        float dist            = ManifoldPoint.btManifoldPoint_getDistance(manifoldPointId);
                        if (dist < 0.0f)
                        {
                            Vector3 normalWorldOnB;
                            ManifoldPoint.btManifoldPoint_getNormalWorldOnB(manifoldPointId, out normalWorldOnB);
                            if (dist < maxPen)
                            {
                                maxPen = dist;
                            }

                            var counterPenDir = normalWorldOnB * directionSign;;
                            m_currentPosition += counterPenDir * dist;
                            penetration        = true;
                            if (counterPenDir.Dot(Vector3.UnitY) > 0)
                            {
                                m_verticalVelocity = 0;
                            }
                        }
                    }
                }
            }
            Matrix newTrans = m_ghostObject.WorldTransform;

            newTrans.Origin = m_currentPosition;
            m_ghostObject.WorldTransform = newTrans;
            return(penetration);
        }
Пример #11
0
        public static void RoomNearCallback(BroadphasePair collisionPair, CollisionDispatcher dispatcher,
            DispatcherInfo dispatchInfo)
        {
            var c0 = (EngineContainer) ((CollisionObject) collisionPair.Proxy0.ClientObject).UserObject;
            var r0 = c0?.Room;
            var c1 = (EngineContainer) ((CollisionObject) collisionPair.Proxy1.ClientObject).UserObject;
            var r1 = c1?.Room;

            if (c1 != null && c1 == c0)
            {
                if (((CollisionObject) collisionPair.Proxy0.ClientObject).IsStaticOrKinematicObject
                    || ((CollisionObject) collisionPair.Proxy1.ClientObject).IsStaticOrKinematicObject)
                {
                    return; // No self interaction
                }
                CollisionDispatcher.DefaultNearCallback(collisionPair, dispatcher, dispatchInfo);
                return;
            }

            if(r0 == null && r1 == null)
            {
                CollisionDispatcher.DefaultNearCallback(collisionPair, dispatcher, dispatchInfo); // Both are out of rooms
                return;
            }

            if(r0 != null && r1 != null)
            {
                if(r0.IsInNearRoomsList(r1))
                {
                    CollisionDispatcher.DefaultNearCallback(collisionPair, dispatcher, dispatchInfo);
                }
            }
        }