public void buildIslands(IDispatcher dispatcher, CollisionWorld collisionWorld) { BulletGlobal.StartProfile("0-3-1-0 buildIslands"); List<CollisionObject> collisionObjects = collisionWorld.CollisionObjects; m_islandmanifold.Clear(); //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.NumElements; 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.getElement(startIslandIndex).m_id; for (endIslandIndex = startIslandIndex + 1; (endIslandIndex < numElem) && (UnionFind.getElement(endIslandIndex).m_id == islandId); endIslandIndex++) { } //int numSleeping = 0; bool allSleeping = true; for (int idx = startIslandIndex; idx < endIslandIndex; idx++) { int i = UnionFind.getElement(idx).m_sz; CollisionObject colObj0 = collisionObjects[i]; if ((colObj0.IslandTag != islandId) && (colObj0.IslandTag != -1)) { // printf("error in island management\n"); } Debug.Assert((colObj0.IslandTag == islandId) || (colObj0.IslandTag == -1)); if (colObj0.IslandTag == islandId) { if (colObj0.ActivationState == ActivationStateFlags.ACTIVE_TAG) { allSleeping = false; } if (colObj0.ActivationState == ActivationStateFlags.DISABLE_DEACTIVATION) { allSleeping = false; } } } if (allSleeping) { for (int idx = startIslandIndex; idx < endIslandIndex; idx++) { int i = UnionFind.getElement(idx).m_sz; CollisionObject colObj0 = collisionObjects[i]; if ((colObj0.IslandTag != islandId) && (colObj0.IslandTag != -1)) { // printf("error in island management\n"); } Debug.Assert((colObj0.IslandTag == islandId) || (colObj0.IslandTag == -1)); if (colObj0.IslandTag == islandId) { colObj0.ActivationState = ActivationStateFlags.ISLAND_SLEEPING; } } } else { int idx; for (idx = startIslandIndex; idx < endIslandIndex; idx++) { int i = UnionFind.getElement(idx).m_sz; CollisionObject colObj0 = collisionObjects[i]; if ((colObj0.IslandTag != islandId) && (colObj0.IslandTag != -1)) { // printf("error in island management\n"); } Debug.Assert((colObj0.IslandTag == islandId) || (colObj0.IslandTag == -1)); if (colObj0.IslandTag == islandId) { if (colObj0.ActivationState == ActivationStateFlags.ISLAND_SLEEPING) { colObj0.ActivationState = ActivationStateFlags.WANTS_DEACTIVATION; colObj0.DeactivationTime = 0f; } } } } } int maxNumManifolds = dispatcher.NumManifolds; //#define SPLIT_ISLANDS 1 //#ifdef SPLIT_ISLANDS //#endif //SPLIT_ISLANDS for (int i = 0; i < maxNumManifolds; i++) { PersistentManifold manifold = dispatcher.getManifoldByIndexInternal(i); CollisionObject colObj0 = manifold.Body0; CollisionObject colObj1 = manifold.Body1; ///@todo: check sleeping conditions! if (((colObj0 != null) && colObj0.ActivationState != ActivationStateFlags.ISLAND_SLEEPING) || ((colObj1 != null) && colObj1.ActivationState != ActivationStateFlags.ISLAND_SLEEPING)) { //kinematic objects don't merge islands, but wake up all connected objects if (colObj0.isKinematicObject && colObj0.ActivationState != ActivationStateFlags.ISLAND_SLEEPING) { colObj1.activate(false); } if (colObj1.isKinematicObject && colObj1.ActivationState != ActivationStateFlags.ISLAND_SLEEPING) { colObj0.activate(false); } if (m_splitIslands) { //filtering for response if (dispatcher.needsResponse(colObj0, colObj1)) m_islandmanifold.Add(manifold); } } } BulletGlobal.EndProfile("0-3-1-0 buildIslands"); }