Solve() публичный Метод

public Solve ( TimeStep step, System.Vector2 gravity, bool allowSleep ) : void
step TimeStep
gravity System.Vector2
allowSleep bool
Результат void
Пример #1
0
		// 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();
		}
Пример #2
0
        // 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();
        }
Пример #3
0
 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();
 }
Пример #4
0
        // 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();
        }