Box2DX.Dynamics.Island.Clear C# (CSharp) Метод

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

public Clear ( ) : void
Результат void
        public void Clear()
        {
            _bodyCount = 0;
            _contactCount = 0;
            _jointCount = 0;
        }

Usage Example

Пример #1
0
		// Find TOI contacts and solve them.
		private void SolveTOI(TimeStep step)
		{
			// Reserve an island and a queue for TOI island solution.
			Island island = new Island(_bodyCount, Settings.MaxTOIContactsPerIsland, Settings.MaxTOIJointsPerIsland, _contactListener);

			//Simple one pass queue
			//Relies on the fact that we're only making one pass
			//through and each body can only be pushed/popped once.
			//To push: 
			//  queue[queueStart+queueSize++] = newElement;
			//To pop: 
			//	poppedElement = queue[queueStart++];
			//  --queueSize;
			int queueCapacity = _bodyCount;
			Body[] queue = new Body[queueCapacity];
			for (Body b = _bodyList; b != null; b = b._next)
			{
				b._flags &= ~Body.BodyFlags.Island;
				b._sweep.T0 = 0.0f;
			}

			for (Contact c = _contactList; c != null; c = c._next)
			{
				// Invalidate TOI
				c._flags &= ~(Contact.CollisionFlags.Toi | Contact.CollisionFlags.Island);
			}

#if B2_TOI_JOINTS
			for (Joint j = _jointList; j!=null; j = j._next)
			{
					j._islandFlag = false;
			}
#endif

			// Find TOI events and solve them.
			for (; ; )
			{
				// Find the first TOI.
				Contact minContact = null;
				float minTOI = 1.0f;

				for (Contact c = _contactList; c != null; c = c._next)
				{
					if ((c._flags & (Contact.CollisionFlags.Slow | Contact.CollisionFlags.NonSolid)) != 0)
					{
						continue;
					}

					// TODO_ERIN keep a counter on the contact, only respond to M TOIs per contact.

					float toi = 1.0f;
					if ((c._flags & Contact.CollisionFlags.Toi) != 0)
					{
						// This contact has a valid cached TOI.
						toi = c._toi;
					}
					else
					{
						// Compute the TOI for this contact.
						Shape s1_ = c.GetShape1();
						Shape s2_ = c.GetShape2();
						Body b1_ = s1_.GetBody();
						Body b2_ = s2_.GetBody();

						if ((b1_.IsStatic() || b1_.IsSleeping()) && (b2_.IsStatic() || b2_.IsSleeping()))
						{
							continue;
						}

						// Put the sweeps onto the same time interval.
						float t0 = b1_._sweep.T0;

						if (b1_._sweep.T0 < b2_._sweep.T0)
						{
							t0 = b2_._sweep.T0;
							b1_._sweep.Advance(t0);
						}
						else if (b2_._sweep.T0 < b1_._sweep.T0)
						{
							t0 = b1_._sweep.T0;
							b2_._sweep.Advance(t0);
						}

						Box2DXDebug.Assert(t0 < 1.0f);

						// Compute the time of impact.
						toi = Collision.Collision.TimeOfImpact(c._shape1, b1_._sweep, c._shape2, b2_._sweep);
						Box2DXDebug.Assert(0.0f <= toi && toi <= 1.0f);

						if (toi > 0.0f && toi < 1.0f)
						{
							toi = Common.Math.Min((1.0f - toi) * t0 + toi, 1.0f);
						}


						c._toi = toi;
						c._flags |= Contact.CollisionFlags.Toi;
					}

					if (Common.Settings.FLT_EPSILON < toi && toi < minTOI)
					{
						// This is the minimum TOI found so far.
						minContact = c;
						minTOI = toi;
					}
				}

				if (minContact == null || 1.0f - 100.0f * Common.Settings.FLT_EPSILON < minTOI)
				{
					// No more TOI events. Done!
					break;
				}

				// Advance the bodies to the TOI.
				Shape s1 = minContact.GetShape1();
				Shape s2 = minContact.GetShape2();
				Body b1 = s1.GetBody();
				Body b2 = s2.GetBody();
				b1.Advance(minTOI);
				b2.Advance(minTOI);

				// The TOI contact likely has some new contact points.
				minContact.Update(_contactListener);
				minContact._flags &= ~Contact.CollisionFlags.Toi;

				if (minContact.GetManifoldCount() == 0)
				{
					// This shouldn't happen. Numerical error?
					//b2Assert(false);
					continue;
				}

				// Build the TOI island. We need a dynamic seed.
				Body seed = b1;
				if (seed.IsStatic())
				{
					seed = b2;
				}

				// Reset island and queue.
				island.Clear();

				int queueStart = 0; //starting index for queue
				int queueSize = 0;  //elements in queue
				queue[queueStart + queueSize++] = seed;
				seed._flags |= Body.BodyFlags.Island;

				// Perform a breadth first search (BFS) on the contact/joint graph.
				while (queueSize > 0)
				{
					// Grab the next body off the stack and add it to the island.
					Body b = queue[queueStart++];
					--queueSize;
					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)
					{
						// Does the TOI island still have space for contacts?
						if (island._contactCount == island._contactCapacity)
						{
							continue;
						}

						// Has this contact already been added to an island? Skip slow or non-solid contacts.
						if ((cn.Contact._flags & (Contact.CollisionFlags.Island | Contact.CollisionFlags.Slow | Contact.CollisionFlags.NonSolid)) != 0)
						{
							continue;
						}

						// Is this contact touching? For performance we are not updating this contact.
						if (cn.Contact.GetManifoldCount() == 0)
						{
							continue;
						}

						island.Add(cn.Contact);
						cn.Contact._flags |= Contact.CollisionFlags.Island;

						// Update other body.
						Body other = cn.Other;

						// Was the other body already added to this island?
						if ((other._flags & Body.BodyFlags.Island) != 0)
						{
							continue;
						}

						// March forward, this can do no harm since this is the min TOI.
						if (other.IsStatic() == false)
						{
							other.Advance(minTOI);
							other.WakeUp();
						}

						Box2DXDebug.Assert(queueStart + queueSize < queueCapacity);
						queue[queueStart + queueSize++] = other;
						other._flags |= Body.BodyFlags.Island;
					}

#if B2_TOI_JOINTS
					for (JointEdge jn = b._jointList; jn!=null; jn = jn.Next)
					{
						if (island._jointCount == island._jointCapacity)
						{
							continue;
						}
						
						if (jn.Joint._islandFlag == true)
						{
							continue;
						}
						
						island.Add(jn.Joint);
						
						jn.Joint._islandFlag = true;
						
						Body other = jn.Other;
						
						if (other._flags & Body.BodyFlags.Island)
						{
							continue;
						}
						
						if (!other.IsStatic())
						{
							other.Advance(minTOI);
							other.WakeUp();
						}
						
						Box2DXDebug.Assert(queueStart + queueSize < queueCapacity);
						queue[queueStart + queueSize++] = other;
						other._flags |= Body.BodyFlags.Island; 
					}
#endif
				}

				TimeStep subStep = new TimeStep();
				subStep.WarmStarting = false;
				subStep.Dt = (1.0f - minTOI) * step.Dt;
				Box2DXDebug.Assert(subStep.Dt > Common.Settings.FLT_EPSILON);
				subStep.Inv_Dt = 1.0f / subStep.Dt;
				subStep.VelocityIterations = step.VelocityIterations;
				subStep.PositionIterations = step.PositionIterations;

				island.SolveTOI(ref subStep);

				// Post solve cleanup.
				for (int i = 0; i < island._bodyCount; ++i)
				{
					// Allow bodies to participate in future TOI islands.
					Body b = island._bodies[i];
					b._flags &= ~Body.BodyFlags.Island;

					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);
					}

					// Invalidate all contact TOIs associated with this body. Some of these
					// may not be in the island because they were not touching.
					for (ContactEdge cn = b._contactList; cn != null; cn = cn.Next)
					{
						cn.Contact._flags &= ~Contact.CollisionFlags.Toi;
					}
				}

				for (int i = 0; i < island._contactCount; ++i)
				{
					// Allow contacts to participate in future TOI islands.
					Contact c = island._contacts[i];
					c._flags &= ~(Contact.CollisionFlags.Toi | Contact.CollisionFlags.Island);
				}

				for (int i = 0; i < island._jointCount; ++i)
				{
					// Allow joints to participate in future TOI islands.
					Joint j = island._joints[i];
					j._islandFlag = false;
				}

				// Commit shape proxy movements to the broad-phase so that new contacts are created.
				// Also, some contacts can be destroyed.
				_broadPhase.Commit();
			}

			queue = null;
		}
All Usage Examples Of Box2DX.Dynamics.Island::Clear