public Solve ( |
||
step | ||
gravity | System.Vector2 | |
allowSleep | bool | |
리턴 | void |
// Find islands, integrate and solve constraints, solve position constraints private void Solve(TimeStep step) { // Size the island for the worst case. Island island = new Island(_bodyCount, _contactCount, _jointCount, _contactListener); // Clear all the island flags. for (Body b = _bodyList; b != null; b = b._next) { b._flags &= ~Body.BodyFlags.Island; } for (Contact c = _contactList; c != null; c = c._next) { c._flags &= ~Contact.CollisionFlags.Island; } for (Joint j = _jointList; j != null; j = j._next) { j._islandFlag = false; } // Build and simulate all awake islands. int stackSize = _bodyCount; { Body[] stack = new Body[stackSize]; for (Body seed = _bodyList; seed != null; seed = seed._next) { if ((seed._flags & (Body.BodyFlags.Island | Body.BodyFlags.Sleep | Body.BodyFlags.Frozen)) != 0) { continue; } if (seed.IsStatic()) { continue; } // Reset island and stack. island.Clear(); int stackCount = 0; stack[stackCount++] = seed; seed._flags |= Body.BodyFlags.Island; // Perform a depth first search (DFS) on the constraint graph. while (stackCount > 0) { // Grab the next body off the stack and add it to the island. Body b = stack[--stackCount]; island.Add(b); // Make sure the body is awake. b._flags &= ~Body.BodyFlags.Sleep; // To keep islands as small as possible, we don't // propagate islands across static bodies. if (b.IsStatic()) { continue; } // Search all contacts connected to this body. for (ContactEdge cn = b._contactList; cn != null; cn = cn.Next) { // Has this contact already been added to an island? if ((cn.Contact._flags & (Contact.CollisionFlags.Island | Contact.CollisionFlags.NonSolid)) != 0) { continue; } // Is this contact touching? if (cn.Contact.GetManifoldCount() == 0) { continue; } island.Add(cn.Contact); cn.Contact._flags |= Contact.CollisionFlags.Island; Body other = cn.Other; // Was the other body already added to this island? if ((other._flags & Body.BodyFlags.Island) != 0) { continue; } Box2DXDebug.Assert(stackCount < stackSize); stack[stackCount++] = other; other._flags |= Body.BodyFlags.Island; } // Search all joints connect to this body. for (JointEdge jn = b._jointList; jn != null; jn = jn.Next) { if (jn.Joint._islandFlag == true) { continue; } island.Add(jn.Joint); jn.Joint._islandFlag = true; Body other = jn.Other; if ((other._flags & Body.BodyFlags.Island) != 0) { continue; } Box2DXDebug.Assert(stackCount < stackSize); stack[stackCount++] = other; other._flags |= Body.BodyFlags.Island; } } island.Solve(step, _gravity, _allowSleep); // Post solve cleanup. for (int i = 0; i < island._bodyCount; ++i) { // Allow static bodies to participate in other islands. Body b = island._bodies[i]; if (b.IsStatic()) { b._flags &= ~Body.BodyFlags.Island; } } } stack = null; } // Synchronize shapes, check for out of range bodies. for (Body b = _bodyList; b != null; b = b.GetNext()) { if ((b._flags & (Body.BodyFlags.Sleep | Body.BodyFlags.Frozen)) != 0) { continue; } if (b.IsStatic()) { continue; } // Update shapes (for broad-phase). If the shapes go out of // the world AABB then shapes and contacts may be destroyed, // including contacts that are bool inRange = b.SynchronizeShapes(); // Did the body's shapes leave the world? if (inRange == false && _boundaryListener != null) { _boundaryListener.Violation(b); } } // Commit shape proxy movements to the broad-phase so that new contacts are created. // Also, some contacts can be destroyed. _broadPhase.Commit(); }
// Find islands, integrate and solve constraints, solve position constraints private void Solve(TimeStep step) { // Size the island for the worst case. Island island = new Island(_bodyCount, _contactManager._contactCount, _jointCount, _contactManager._contactListener); // Clear all the island flags. for (Body b = _bodyList; b != null; b = b._next) { b._flags &= ~Body.BodyFlags.Island; } for (Contact c = _contactManager._contactList; c != null; c = c.Next) { c.Flags &= ~ContactFlag.IslandFlag; } for (Joint j = _jointList; j != null; j = j._next) { j._islandFlag = false; } // Build and simulate all awake islands. int stackSize = _bodyCount; Body[] stack = new Body[stackSize]; for (Body seed = _bodyList; seed != null; seed = seed._next) { if ((seed._flags & (Body.BodyFlags.Island | Body.BodyFlags.Sleep)) != 0) { continue; } if (seed.IsStatic()) { continue; } // Reset island and stack. island.Clear(); int stackCount = 0; stack[stackCount++] = seed; seed._flags |= Body.BodyFlags.Island; // Perform a depth first search (DFS) on the constraint graph. while (stackCount > 0) { // Grab the next body off the stack and add it to the island. Body b = stack[--stackCount]; island.Add(ref b); // Make sure the body is awake. b._flags &= ~Body.BodyFlags.Sleep; // To keep islands as small as possible, we don't // propagate islands across static bodies. if (b.IsStatic()) { continue; } // Search all contacts connected to this body. for (ContactEdge ce = b._contactList; ce != null; ce = ce.Next) { // Has this contact already been added to an island? if ((ce.Contact.Flags & ContactFlag.IslandFlag) != 0) { continue; } // Is this contact touching? if (ce.Contact.IsSolid() == false || ce.Contact.IsTouching() == false) { continue; } island.Add(ref ce.Contact); ce.Contact.Flags |= ContactFlag.IslandFlag; Body other = ce.Other; // Was the other body already added to this island? if ((other._flags & Body.BodyFlags.Island) != 0) { continue; } Box2DXDebug.Assert(stackCount < stackSize); stack[stackCount++] = other; other._flags |= Body.BodyFlags.Island; } // Search all joints connect to this body. for (JointEdge je = b._jointList; je != null; je = je.Next) { if (je.Joint._islandFlag == true) { continue; } island.Add(je.Joint); je.Joint._islandFlag = true; Body other = je.Other; if ((other._flags & Body.BodyFlags.Island) != 0) { continue; } Box2DXDebug.Assert(stackCount < stackSize); stack[stackCount++] = other; other._flags |= Body.BodyFlags.Island; } } island.Solve(step, _gravity, _allowSleep); // Post solve cleanup. for (int i = 0; i < island.BodyCount; ++i) { // Allow static bodies to participate in other islands. Body b = island.Bodies[i]; if (b.IsStatic()) { b._flags &= ~Body.BodyFlags.Island; } } } stack = null; // Synchronize shapes, check for out of range bodies. for (Body b = _bodyList; b != null; b = b.GetNext()) { if ((b._flags & Body.BodyFlags.Sleep) != 0) { continue; } if (b.IsStatic()) { continue; } // Update fixtures (for broad-phase). b.SynchronizeFixtures(); } // Look for new contacts. _contactManager.FindNewContacts(); }
private void Solve(TimeStep step) { Island island = new Island(this._bodyCount, this._contactCount, this._jointCount, this._contactListener); for (Body body = this._bodyList; body != null; body = body._next) { body._flags &= ~Body.BodyFlags.Island; } for (Contact contact = this._contactList; contact != null; contact = contact._next) { contact._flags &= ~Contact.CollisionFlags.Island; } for (Joint joint = this._jointList; joint != null; joint = joint._next) { joint._islandFlag = false; } int bodyCount = this._bodyCount; Body[] array = new Body[bodyCount]; for (Body body2 = this._bodyList; body2 != null; body2 = body2._next) { if ((body2._flags & (Body.BodyFlags.Frozen | Body.BodyFlags.Island | Body.BodyFlags.Sleep)) == (Body.BodyFlags)0) { if (!body2.IsStatic()) { island.Clear(); int i = 0; array[i++] = body2; body2._flags |= Body.BodyFlags.Island; while (i > 0) { Body body = array[--i]; island.Add(body); body._flags &= ~Body.BodyFlags.Sleep; if (!body.IsStatic()) { for (ContactEdge contactEdge = body._contactList; contactEdge != null; contactEdge = contactEdge.Next) { if ((contactEdge.Contact._flags & (Contact.CollisionFlags.NonSolid | Contact.CollisionFlags.Island)) == (Contact.CollisionFlags)0) { if (contactEdge.Contact.GetManifoldCount() != 0) { island.Add(contactEdge.Contact); contactEdge.Contact._flags |= Contact.CollisionFlags.Island; Body other = contactEdge.Other; if ((other._flags & Body.BodyFlags.Island) == (Body.BodyFlags)0) { Box2DXDebug.Assert(i < bodyCount); array[i++] = other; other._flags |= Body.BodyFlags.Island; } } } } for (JointEdge jointEdge = body._jointList; jointEdge != null; jointEdge = jointEdge.Next) { if (!jointEdge.Joint._islandFlag) { island.Add(jointEdge.Joint); jointEdge.Joint._islandFlag = true; Body other = jointEdge.Other; if ((other._flags & Body.BodyFlags.Island) == (Body.BodyFlags)0) { Box2DXDebug.Assert(i < bodyCount); array[i++] = other; other._flags |= Body.BodyFlags.Island; } } } } } island.Solve(step, this._gravity, this._allowSleep); for (int j = 0; j < island._bodyCount; j++) { Body body = island._bodies[j]; if (body.IsStatic()) { body._flags &= ~Body.BodyFlags.Island; } } } } } for (Body body = this._bodyList; body != null; body = body.GetNext()) { if ((body._flags & (Body.BodyFlags.Frozen | Body.BodyFlags.Sleep)) == (Body.BodyFlags)0) { if (!body.IsStatic()) { if (!body.SynchronizeShapes() && this._boundaryListener != null) { this._boundaryListener.Violation(body); } } } } this._broadPhase.Commit(); }
// Find islands, integrate and solve constraints, solve position constraints private void Solve(TimeStep step) { // Size the island for the worst case. Island island = new Island(_bodyCount, _contactManager._contactCount, _jointCount, _contactManager._contactListener); // Clear all the island flags. for (Body b = _bodyList; b != null; b = b._next) { b._flags &= ~Body.BodyFlags.Island; } for (Contact c = _contactManager._contactList; c != null; c = c.Next) { c.Flags &= ~ContactFlag.IslandFlag; } for (Joint j = _jointList; j != null; j = j._next) { j._islandFlag = false; } // Build and simulate all awake islands. int stackSize = _bodyCount; Body[] stack = new Body[stackSize]; for (Body seed = _bodyList; seed != null; seed = seed._next) { if ((seed._flags & (Body.BodyFlags.Island | Body.BodyFlags.Sleep)) != 0) { continue; } if (seed.IsStatic()) { continue; } // Reset island and stack. island.Clear(); int stackCount = 0; stack[stackCount++] = seed; seed._flags |= Body.BodyFlags.Island; // Perform a depth first search (DFS) on the constraint graph. while (stackCount > 0) { // Grab the next body off the stack and add it to the island. Body b = stack[--stackCount]; island.Add(ref b); // Make sure the body is awake. b._flags &= ~Body.BodyFlags.Sleep; // To keep islands as small as possible, we don't // propagate islands across static bodies. if (b.IsStatic()) { continue; } // Search all contacts connected to this body. for (ContactEdge ce = b._contactList; ce != null; ce = ce.Next) { // Has this contact already been added to an island? if ((ce.Contact.Flags & ContactFlag.IslandFlag) != 0) { continue; } // Is this contact touching? if (ce.Contact.IsSolid() == false || ce.Contact.IsTouching() == false) { continue; } island.Add(ref ce.Contact); ce.Contact.Flags |= ContactFlag.IslandFlag; Body other = ce.Other; // Was the other body already added to this island? if ((other._flags & Body.BodyFlags.Island) != 0) { continue; } Box2DXDebug.Assert(stackCount < stackSize); stack[stackCount++] = other; other._flags |= Body.BodyFlags.Island; } // Search all joints connect to this body. for (JointEdge je = b._jointList; je != null; je = je.Next) { if (je.Joint._islandFlag == true) { continue; } island.Add(je.Joint); je.Joint._islandFlag = true; Body other = je.Other; if ((other._flags & Body.BodyFlags.Island) != 0) { continue; } Box2DXDebug.Assert(stackCount < stackSize); stack[stackCount++] = other; other._flags |= Body.BodyFlags.Island; } } island.Solve(step, _gravity, _allowSleep); // Post solve cleanup. for (int i = 0; i < island.BodyCount; ++i) { // Allow static bodies to participate in other islands. Body b = island.Bodies[i]; if (b.IsStatic()) { b._flags &= ~Body.BodyFlags.Island; } } } stack = null; // Synchronize shapes, check for out of range bodies. for (Body b = _bodyList; b != null; b = b.GetNext()) { if ((b._flags & Body.BodyFlags.Sleep) != 0) { continue; } if (b.IsStatic()) { continue; } // Update fixtures (for broad-phase). b.SynchronizeFixtures(); } // Look for new contacts. _contactManager.FindNewContacts(); }