public CompoundCollisionAlgorithm(
            CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo,
            CollisionObject bodyA,
            CollisionObject bodyB, bool isSwapped)
            : base(collisionAlgorithmConstructionInfo)
        {
            //Begin
            _isSwapped = isSwapped;

            CollisionObject collisionObject = isSwapped ? bodyB : bodyA;
            CollisionObject otherObject     = isSwapped ? bodyA : bodyB;

            BulletDebug.Assert(collisionObject.CollisionShape.IsCompound);

            CompoundShape compoundShape  = collisionObject.CollisionShape as CompoundShape;
            int           childrenNumber = compoundShape.ChildShapeCount;
            int           index          = 0;

            _childCollisionAlgorithms = new List <CollisionAlgorithm>(childrenNumber);

            for (index = 0; index < childrenNumber; index++)
            {
                CollisionShape childShape = compoundShape.GetChildShape(index);
                CollisionShape orgShape   = collisionObject.CollisionShape;

                collisionObject.CollisionShape   = childShape;
                _childCollisionAlgorithms[index] = collisionAlgorithmConstructionInfo.Dispatcher.FindAlgorithm(collisionObject, otherObject);
                collisionObject.CollisionShape   = orgShape;
            }
        }
        public override void ProcessCollision(
            CollisionObject bodyA,
            CollisionObject bodyB,
            DispatcherInfo dispatchInfo, ManifoldResult resultOut)
        {
            //Begin

            CollisionObject collisionObject = _isSwapped ? bodyB : bodyB;
            CollisionObject otherObject     = _isSwapped ? bodyA : bodyB;

            //Debug.Assert(collisionObject.getCollisionShape().isCompound());
            BulletDebug.Assert(collisionObject.CollisionShape.IsCompound);

            CompoundShape compoundShape = (CompoundShape)collisionObject.CollisionShape;

            int childrenNumber = _childCollisionAlgorithms.Count;

            for (int i = 0; i < childrenNumber; i++)
            {
                CompoundShape childShape = compoundShape.GetChildShape(i) as CompoundShape;

                Matrix         orgTransform = collisionObject.WorldTransform;
                CollisionShape orgShape     = collisionObject.CollisionShape;

                Matrix childTransform = compoundShape.GetChildTransform(i);
                Matrix newChildWorld  = orgTransform * childTransform;

                collisionObject.WorldTransform = newChildWorld;
                collisionObject.CollisionShape = childShape;
                _childCollisionAlgorithms[i].ProcessCollision(collisionObject, otherObject, dispatchInfo, resultOut);

                collisionObject.CollisionShape = orgShape;
                collisionObject.WorldTransform = orgTransform;
            }
        }
Esempio n. 3
0
        public AxisSweep3(Vector3 worldAabbMin, Vector3 worldAabbMax, int maxHandles)
            : base()
        {
            BulletDebug.Assert(maxHandles > 1 && maxHandles < 32767);

            // init bounds
            _worldAabbMin = worldAabbMin;
            _worldAabbMax = worldAabbMax;

            Vector3 aabbSize = _worldAabbMax - _worldAabbMin;

            _quantize = new Vector3(65535.0f, 65535.0f, 65535.0f) / aabbSize;

            // allocate handles buffer and put all handles on free list
            _handles = new Handle[maxHandles];
            for (int i = 0; i < maxHandles; i++)
            {
                _handles[i] = new Handle();
            }
            _maxHandles = maxHandles;
            _numHandles = 0;

            // handle 0 is reserved as the null index, and is also used as the sentinel
            _firstFreeHandle = 1;
            {
                for (int i = _firstFreeHandle; i < maxHandles; i++)
                {
                    _handles[i].NextFree = (ushort)(i + 1);
                }
                _handles[maxHandles - 1].NextFree = 0;
            }

            {
                // allocate edge buffers
                for (int i = 0; i < 3; i++)
                {
                    _edges[i] = new Edge[maxHandles * 2];
                    for (int j = 0; j < maxHandles * 2; j++)
                    {
                        _edges[i][j] = new Edge();
                    }
                }
            }
            //removed overlap management

            // make boundary sentinels

            _handles[0].ClientData = 0;

            for (int axis = 0; axis < 3; axis++)
            {
                _handles[0].MinEdges[axis] = 0;
                _handles[0].MaxEdges[axis] = 1;

                _edges[axis][0].Position = 0;
                _edges[axis][0].Handle   = 0;
                _edges[axis][1].Position = 0xffff;
                _edges[axis][1].Handle   = 0;
            }
        }
Esempio n. 4
0
 public void RemoveVertex(int index)
 {
     BulletDebug.Assert(_numVertices > 0);
     _numVertices--;
     _simplexVectorW[index] = _simplexVectorW[_numVertices];
     _simplexPointsP[index] = _simplexPointsP[_numVertices];
     _simplexPointsQ[index] = _simplexPointsQ[_numVertices];
 }
Esempio n. 5
0
        public override void ProcessAllOverlappingPairs(IOverlapCallback callback)
        {
            OverlappingPairs.Sort(new Comparison <BroadphasePair>(BroadphasePair.ComparisonSort));

            if (_invalidPair != 0)
            {
                OverlappingPairs.RemoveRange(OverlappingPairs.Count - _invalidPair, _invalidPair);
            }
            _invalidPair = 0;

            BroadphasePair previousPair = new BroadphasePair();

            previousPair.ProxyA             = null;
            previousPair.ProxyB             = null;
            previousPair.CollisionAlgorithm = null;

            List <BroadphasePair> removal = new List <BroadphasePair>();

            for (int i = 0; i < OverlappingPairs.Count; i++)
            {
                bool isDuplicate = (OverlappingPairs[i] == previousPair);
                previousPair = OverlappingPairs[i];
                bool needsRemoval;
                if (!isDuplicate)
                {
                    bool hasOverlap = TestOverlap(previousPair.ProxyA, previousPair.ProxyB);
                    if (hasOverlap)
                    {
                        needsRemoval = callback.ProcessOverlap(ref previousPair);
                    }
                    else
                    {
                        needsRemoval = true;
                    }
                }
                else
                {
                    needsRemoval = true;
                    BulletDebug.Assert(previousPair.CollisionAlgorithm == null);
                }

                if (needsRemoval)
                {
                    removal.Add(previousPair);
                }
            }

            for (int i = 0; i < removal.Count; i++)
            {
                BroadphasePair pair = removal[i];
                CleanOverlappingPair(ref pair);
                pair.ProxyA = null;
                pair.ProxyB = null;
                _invalidPair++;
                OverlappingPairCount--;
            }
        }
Esempio n. 6
0
        private void FreeHandle(ushort handle)
        {
            BulletDebug.Assert(handle > 0 && handle < _maxHandles);

            GetHandle(handle).NextFree = _firstFreeHandle;
            _firstFreeHandle           = handle;

            _numHandles--;
        }
Esempio n. 7
0
        public override BroadphaseProxy CreateProxy(Vector3 min, Vector3 max, BroadphaseNativeTypes shapeType, object userData, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask)
        {
            if (_proxies.Count >= _maxProxies)
            {
                BulletDebug.Assert(false);
                return(null);                //should never happen, but don't let the game crash ;-)
            }
            BulletDebug.Assert(min.X <= max.X && min.Y <= max.Y && min.Z <= max.Z);

            SimpleBroadphaseProxy proxy = new SimpleBroadphaseProxy(min, max, shapeType, userData, collisionFilterGroup, collisionFilterMask);

            _proxies.Add(proxy);

            return(proxy);
        }
Esempio n. 8
0
        public static void SetRotation(ref Matrix m, Quaternion q)
        {
            float d = q.LengthSquared();

            BulletDebug.Assert(d != 0);
            float s = 2f / d;
            float xs = q.X * s, ys = q.Y * s, zs = q.Z * s;
            float wx = q.W * xs, wy = q.W * ys, wz = q.W * zs;
            float xx = q.X * xs, xy = q.X * ys, xz = q.X * zs;
            float yy = q.Y * ys, yz = q.Y * zs, zz = q.Z * zs;

            m = new Matrix(1 - (yy + zz), xy - wz, xz + wy, 0,
                           xy + wz, 1 - (xx + zz), yz - wx, 0,
                           xz - wy, yz + wx, 1 - (xx + yy), 0,
                           m.M41, m.M42, m.M43, 1);
        }
Esempio n. 9
0
        public void AddOverlappingPair(BroadphaseProxy proxyA, BroadphaseProxy proxyB)
        {
            //don't add overlap with own
            bool test = proxyA != proxyB;

            BulletDebug.Assert(proxyA != proxyB);

            if (!NeedsBroadphaseCollision(proxyA, proxyB))
            {
                return;
            }

            BroadphasePair pair = new BroadphasePair(proxyA, proxyB);

            _overlappingPairs.Add(pair);
            _overlappingPairCount++;
        }
        public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
        {
            CollisionObject collisionObject = _isSwapped ? bodyB : bodyA;
            CollisionObject otherObject     = _isSwapped ? bodyA : bodyB;

            BulletDebug.Assert(collisionObject.CollisionShape.IsCompound);

            CompoundShape compoundShape = (CompoundShape)collisionObject.CollisionShape;

            float hitFraction = 1.0f;

            for (int i = 0; i < _childCollisionAlgorithms.Count; i++)
            {
                CollisionShape childShape = compoundShape.GetChildShape(i);

                Matrix         orgTransform = collisionObject.WorldTransform;
                CollisionShape orgShape     = collisionObject.CollisionShape;

                Matrix childTransform = compoundShape.GetChildTransform(i);
                Matrix newChildWorld  = orgTransform * childTransform;
                collisionObject.WorldTransform = newChildWorld;

                collisionObject.CollisionShape = childShape;
                float frac = _childCollisionAlgorithms[i].CalculateTimeOfImpact(
                    collisionObject, otherObject, dispatchInfo, resultOut
                    );

                if (frac < hitFraction)
                {
                    hitFraction = frac;
                }

                collisionObject.CollisionShape = orgShape;
                collisionObject.WorldTransform = orgTransform;
            }

            return(hitFraction);
        }
Esempio n. 11
0
        public void ReplaceContactPoint(ManifoldPoint newPoint, int insertIndex)
        {
            BulletDebug.Assert(ValidContactDistance(newPoint));

            if (_pointCache[insertIndex] != null)
            {
                int lifeTime = _pointCache[insertIndex].LifeTime;
                BulletDebug.Assert(lifeTime >= 0);
                object cache = _pointCache[insertIndex].UserPersistentData;

                _pointCache[insertIndex] = newPoint;

                _pointCache[insertIndex].UserPersistentData = cache;
                _pointCache[insertIndex].LifeTime           = lifeTime;
            }
            else
            {
                _pointCache[insertIndex] = newPoint;
            }

            //ClearUserCache(_pointCache[insertIndex]);
            //_pointCache[insertIndex] = newPoint;
        }
Esempio n. 12
0
 public override void CalculateLocalInertia(float mass, out Vector3 inertia)
 {
     inertia = new Vector3();
     //moving concave objects not supported
     BulletDebug.Assert(false);
 }
Esempio n. 13
0
 public override void CalculateLocalInertia(float mass, out Vector3 inertia)
 {
     inertia = new Vector3();
     BulletDebug.Assert(false);
 }
Esempio n. 14
0
 public virtual void GetPreferredPenetrationDirection(int index, out Vector3 penetrationVector)
 {
     penetrationVector = new Vector3();
     BulletDebug.Assert(false);
 }
Esempio n. 15
0
        public override void GetClosestPoints(DiscreteCollisionDetectorInterface.ClosestPointInput input, DiscreteCollisionDetectorInterface.Result output, IDebugDraw debugDraw)
        {
            float distance = 0;

            Vector3 normalInB = new Vector3();
            Vector3 pointOnA = new Vector3(), pointOnB = new Vector3();

            Matrix localTransA = input.TransformA;
            Matrix localTransB = input.TransformB;

            Vector3 positionOffset = (localTransA.Translation + localTransB.Translation) * 0.5f;

            localTransA.Translation -= positionOffset;
            localTransB.Translation -= positionOffset;

            float marginA = _minkowskiA.Margin;
            float marginB = _minkowskiB.Margin;

            _numGjkChecks++;

            if (_ignoreMargin)
            {
                marginA = 0;
                marginB = 0;
            }

            _currentIteration = 0;

            int gjkMaxIter = 1000;

            _cachedSeparatingAxis = new Vector3(0, 1, 0);

            bool isValid          = false;
            bool checkSimplex     = false;
            bool checkPenetration = true;

            _degenerateSimplex = 0;

            _lastUsedMethod = -1;

            {
                float squaredDistance = MathHelper.Infinity;
                float delta           = 0;

                float margin = marginA + marginB;

                _simplexSolver.Reset();

                while (true)
                {
                    Matrix transABasis = input.TransformA;
                    transABasis.Translation = Vector3.Zero;

                    Matrix transBBasis = input.TransformB;
                    transBBasis.Translation = Vector3.Zero;

                    Vector3 seperatingAxisInA = Vector3.TransformNormal(-_cachedSeparatingAxis, transABasis);
                    Vector3 seperatingAxisInB = Vector3.TransformNormal(_cachedSeparatingAxis, transBBasis);

                    Vector3 pInA   = _minkowskiA.LocalGetSupportingVertexWithoutMargin(seperatingAxisInA);
                    Vector3 qInB   = _minkowskiB.LocalGetSupportingVertexWithoutMargin(seperatingAxisInB);
                    Vector3 pWorld = MathHelper.MatrixToVector(localTransA, pInA);
                    Vector3 qWorld = MathHelper.MatrixToVector(localTransB, qInB);

                    Vector3 w = pWorld - qWorld;
                    delta = Vector3.Dot(_cachedSeparatingAxis, w);

                    if ((delta > 0.0) && (delta * delta > squaredDistance * input.MaximumDistanceSquared))
                    {
                        checkPenetration = false;
                        break;
                    }

                    if (_simplexSolver.InSimplex(w))
                    {
                        _degenerateSimplex = 1;
                        checkSimplex       = true;
                        break;
                    }

                    float f0 = squaredDistance - delta;
                    float f1 = squaredDistance * RelativeError2;

                    if (f0 <= f1)
                    {
                        if (f0 <= 0.0f)
                        {
                            _degenerateSimplex = 2;
                        }

                        checkSimplex = true;
                        break;
                    }

                    _simplexSolver.AddVertex(w, pWorld, qWorld);

                    if (!_simplexSolver.Closest(out _cachedSeparatingAxis))
                    {
                        _degenerateSimplex = 3;
                        checkSimplex       = true;
                        break;
                    }

                    float previouseSquaredDistance = squaredDistance;
                    squaredDistance = _cachedSeparatingAxis.LengthSquared();

                    if (previouseSquaredDistance - squaredDistance <= MathHelper.Epsilon * previouseSquaredDistance)
                    {
                        _simplexSolver.BackupClosest(out _cachedSeparatingAxis);
                        checkSimplex = true;
                        break;
                    }

                    if (_currentIteration++ > gjkMaxIter)
                    {
#if DEBUG
                        Console.WriteLine("GjkPairDetector maxIter exceeded: {0}", _currentIteration);
                        Console.WriteLine("sepAxis=({0},{1},{2}), squaredDistance = {3}, shapeTypeA={4}, shapeTypeB={5}",
                                          _cachedSeparatingAxis.X,
                                          _cachedSeparatingAxis.Y,
                                          _cachedSeparatingAxis.Z,
                                          squaredDistance,
                                          _minkowskiA.ShapeType,
                                          _minkowskiB.ShapeType
                                          );
#endif
                        break;
                    }

                    bool check = (!_simplexSolver.FullSimplex);

                    if (!check)
                    {
                        _simplexSolver.BackupClosest(out _cachedSeparatingAxis);
                        break;
                    }
                }

                if (checkSimplex)
                {
                    _simplexSolver.ComputePoints(out pointOnA, out pointOnB);
                    normalInB = pointOnA - pointOnB;
                    float lenSqr = _cachedSeparatingAxis.LengthSquared();

                    if (lenSqr < 0.0001f)
                    {
                        _degenerateSimplex = 5;
                    }

                    if (lenSqr > MathHelper.Epsilon * MathHelper.Epsilon)
                    {
                        float rlen = 1.0f / (float)Math.Sqrt((float)lenSqr);
                        normalInB *= rlen;
                        float s = (float)Math.Sqrt((float)squaredDistance);

                        BulletDebug.Assert(s > 0);
                        pointOnA -= _cachedSeparatingAxis * (marginA / s);
                        pointOnB += _cachedSeparatingAxis * (marginB / s);
                        distance  = ((1 / rlen) - margin);

                        isValid = true;

                        _lastUsedMethod = 1;
                    }
                    else
                    {
                        _lastUsedMethod = 2;
                    }
                }

                bool catchDegeneratePenetrationCase =
                    (_catchDegeneracies != 0 && _penetrationDepthSolver != null && _degenerateSimplex != 0 && ((distance + margin) < 0.01f));

                if (checkPenetration && (!isValid || catchDegeneratePenetrationCase))
                {
#warning Check this
                    if (_penetrationDepthSolver != null)
                    {
                        Vector3 tmpPointOnA, tmpPointOnB;

                        _numDeepPenetrationChecks++;

                        bool isValid2 = _penetrationDepthSolver.CalculatePenetrationDepth(
                            _simplexSolver, _minkowskiA, _minkowskiB, localTransA, localTransB,
                            _cachedSeparatingAxis, out tmpPointOnA, out tmpPointOnB,
                            debugDraw
                            );

                        if (isValid2)
                        {
                            Vector3 tmpNormalInB = tmpPointOnB - tmpPointOnA;
                            float   lengSqr      = tmpNormalInB.LengthSquared();

                            if (lengSqr > (MathHelper.Epsilon * MathHelper.Epsilon))
                            {
                                tmpNormalInB /= (float)Math.Sqrt((float)lengSqr);
                                float distance2 = -(tmpPointOnA - tmpPointOnB).Length();

                                if (!isValid || (distance2 < distance))
                                {
                                    distance        = distance2;
                                    pointOnA        = tmpPointOnA;
                                    pointOnB        = tmpPointOnB;
                                    normalInB       = tmpNormalInB;
                                    isValid         = true;
                                    _lastUsedMethod = 3;
                                }
                                else
                                {
                                }
                            }
                            else
                            {
                                _lastUsedMethod = 4;
                            }
                        }
                        else
                        {
                            _lastUsedMethod = 5;
                        }
                    }
                }

                if (isValid)
                {
                    output.AddContactPoint(normalInB, pointOnB + positionOffset, distance);
                }
            }
        }
Esempio n. 16
0
 public override void GetEdge(int i, out Vector3 pa, out Vector3 pb)
 {
     pa = new Vector3();
     pb = new Vector3();
     BulletDebug.Assert(false);
 }
Esempio n. 17
0
 public override bool IsInside(Vector3 pt, float tolerance)
 {
     BulletDebug.Assert(false);
     return(false);
 }
Esempio n. 18
0
 public override void GetPlane(out Vector3 planeNormal, out Vector3 planeSupport, int i)
 {
     planeNormal  = new Vector3();
     planeSupport = new Vector3();
     BulletDebug.Assert(false);
 }
Esempio n. 19
0
 public override void GetVertex(int i, out Vector3 vtx)
 {
     vtx = new Vector3();
     BulletDebug.Assert(false);
 }
Esempio n. 20
0
 public virtual Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
 {
     BulletDebug.Assert(false);
     return(LocalGetSupportingVertex(vec));
 }
        public void BuildAndProcessIslands(IDispatcher dispatcher, List <CollisionObject> collisionObjects, IIslandCallback callback)
        {
            //we are going to sort the unionfind array, and store the element id in the size
            //afterwards, we clean unionfind, to make sure no-one uses it anymore
            UnionFind.SortIslands();
            int numElem = UnionFind.ElementCount;

            int endIslandIndex = 1;
            int startIslandIndex;

            //update the sleeping state for bodies, if all are sleeping
            for (startIslandIndex = 0; startIslandIndex < numElem; startIslandIndex = endIslandIndex)
            {
                int islandId = UnionFind[startIslandIndex].ID;
                for (endIslandIndex = startIslandIndex + 1; (endIslandIndex < numElem) && (UnionFind[endIslandIndex].ID == islandId); endIslandIndex++)
                {
                }

                //int numSleeping = 0;

                bool allSleeping = true;

                int idx;
                for (idx = startIslandIndex; idx < endIslandIndex; idx++)
                {
                    int i = UnionFind[idx].Size;

                    CollisionObject colObjA = collisionObjects[i];
                    if ((colObjA.IslandTag != islandId) && (colObjA.IslandTag != -1))
                    {
                        Console.WriteLine("error in island management");
                    }

                    BulletDebug.Assert((colObjA.IslandTag == islandId) || (colObjA.IslandTag == -1));
                    if (colObjA.IslandTag == islandId)
                    {
                        if (colObjA.ActivationState == ActivationState.Active)
                        {
                            allSleeping = false;
                        }
                        if (colObjA.ActivationState == ActivationState.DisableDeactivation)
                        {
                            allSleeping = false;
                        }
                    }
                }


                if (allSleeping)
                {
                    for (idx = startIslandIndex; idx < endIslandIndex; idx++)
                    {
                        int             i       = UnionFind[idx].Size;
                        CollisionObject colObjA = collisionObjects[i];
                        if ((colObjA.IslandTag != islandId) && (colObjA.IslandTag != -1))
                        {
                            Console.WriteLine("error in island management");
                        }

                        BulletDebug.Assert((colObjA.IslandTag == islandId) || (colObjA.IslandTag == -1));

                        if (colObjA.IslandTag == islandId)
                        {
                            colObjA.ActivationState = ActivationState.IslandSleeping;
                        }
                    }
                }
                else
                {
                    for (idx = startIslandIndex; idx < endIslandIndex; idx++)
                    {
                        int i = UnionFind[idx].Size;

                        CollisionObject colObjA = collisionObjects[i];
                        if ((colObjA.IslandTag != islandId) && (colObjA.IslandTag != -1))
                        {
                            Console.WriteLine("error in island management");
                        }

                        BulletDebug.Assert((colObjA.IslandTag == islandId) || (colObjA.IslandTag == -1));

                        if (colObjA.IslandTag == islandId)
                        {
                            if (colObjA.ActivationState == ActivationState.IslandSleeping)
                            {
                                colObjA.ActivationState = ActivationState.WantsDeactivation;
                            }
                        }
                    }
                }
            }

            //int maxNumManifolds = dispatcher.ManifoldCount;
            List <PersistentManifold> islandmanifold = new List <PersistentManifold>(dispatcher.ManifoldCount);

            for (int i = 0; i < dispatcher.ManifoldCount; i++)
            {
                PersistentManifold manifold = dispatcher.GetManifoldByIndex(i);

                CollisionObject colObjA = manifold.BodyA as CollisionObject;
                CollisionObject colObjB = manifold.BodyB as CollisionObject;

                //todo: check sleeping conditions!
                if (((colObjA != null) && colObjA.ActivationState != ActivationState.IslandSleeping) ||
                    ((colObjB != null) && colObjB.ActivationState != ActivationState.IslandSleeping))
                {
                    //kinematic objects don't merge islands, but wake up all connected objects
                    if (colObjA.IsStaticOrKinematicObject && colObjA.ActivationState != ActivationState.IslandSleeping)
                    {
                        colObjB.Activate();
                    }
                    if (colObjB.IsStaticOrKinematicObject && colObjB.ActivationState != ActivationState.IslandSleeping)
                    {
                        colObjA.Activate();
                    }

                    //filtering for response
                    if (dispatcher.NeedsResponse(colObjA, colObjB))
                    {
                        islandmanifold.Add(manifold);
                    }
                }
            }

            int numManifolds = islandmanifold.Count;

            // Sort manifolds, based on islands
            // Sort the vector using predicate and std::sort
            islandmanifold.Sort(new Comparison <PersistentManifold>(PersistentManifoldSortPredicate));

            //now process all active islands (sets of manifolds for now)
            int startManifoldIndex = 0;
            int endManifoldIndex   = 1;

            List <CollisionObject> islandBodies = new List <CollisionObject>();

            for (startIslandIndex = 0; startIslandIndex < numElem; startIslandIndex = endIslandIndex)
            {
                int  islandId       = UnionFind[startIslandIndex].ID;
                bool islandSleeping = false;
                for (endIslandIndex = startIslandIndex; (endIslandIndex < numElem) && (UnionFind[endIslandIndex].ID == islandId); endIslandIndex++)
                {
                    int             i       = UnionFind[endIslandIndex].Size;
                    CollisionObject colObjA = collisionObjects[i];
                    islandBodies.Add(colObjA);
                    if (!colObjA.IsActive)
                    {
                        islandSleeping = true;
                    }
                }

                //find the accompanying contact manifold for this islandId
                int numIslandManifolds = 0;
                List <PersistentManifold> startManifold = new List <PersistentManifold>(numIslandManifolds);

                if (startManifoldIndex < numManifolds)
                {
                    int curIslandID = GetIslandId(islandmanifold[startManifoldIndex]);
                    if (curIslandID == islandId)
                    {
                        for (int k = startManifoldIndex; k < islandmanifold.Count; k++)
                        {
                            startManifold.Add(islandmanifold[k]);
                        }
                        for (endManifoldIndex = startManifoldIndex + 1; (endManifoldIndex < numManifolds) && (islandId == GetIslandId(islandmanifold[endManifoldIndex])); endManifoldIndex++)
                        {
                        }

                        // Process the actual simulation, only if not sleeping/deactivated
                        numIslandManifolds = endManifoldIndex - startManifoldIndex;
                    }
                }

                if (!islandSleeping)
                {
                    callback.ProcessIsland(islandBodies, startManifold, numIslandManifolds, islandId);
                }

                if (numIslandManifolds != 0)
                {
                    startManifoldIndex = endManifoldIndex;
                }

                islandBodies.Clear();
            }
        }