Box2DX.Dynamics.World.Solve C# (CSharp) Method

Solve() private method

private Solve ( TimeStep step ) : void
step TimeStep
return void
        private void Solve(TimeStep step)
        {
            // Step all controlls
            for (Controllers.Controller controller = _controllerList; controller != null; controller = controller._next)
            {
                controller.Step(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();
        }