Commits

Anonymous committed 66adf3a

Fixed several bugs in the test framework. Recycling contacts now.

Comments (0)

Files changed (10)

Examples/XNATestBed/Test.cs

 		public Test test;
 	}
 
-	public class Test : IDisposable
+	public class Test
 	{
 		public static TestEntry[] g_testEntries = new TestEntry[]
 		{			
 			_world.SetContactListener(_contactListener);
 		}
 
-		public void Dispose()
-		{
-			Dispose(true);
-		}
-
-		protected virtual void Dispose(bool state)
-		{
-			if (state)
-			{
-				// By deleting the world, we delete the bomb, mouse joint, etc.
-				_world.Dispose();
-				_world = null;
-			}
-		}
+        public virtual void Finish()
+        {
+            _world.Dispose();
+            _world = null;
+        }
 
 		public void SetTextLine(int line) { _textLine = line; }
 		public virtual void Keyboard(Keys key) { ; }

Examples/XNATestBed/Tests/BipedTest.cs

 
 namespace TestBed
 {
-	public class BipedTest : Test, IDisposable
+	public class BipedTest : Test
 	{
 		BipedTest()
 		{
 			}
 		}
 
-		protected override void Dispose(bool state) { _biped.Dispose(); _biped = null; }
+		public override void Finish() 
+        {            
+            _biped.Dispose(); 
+            _biped = null;
+            
+            base.Finish();
+        }
 
 		public static Test Create()
 		{

Examples/XNATestBed/Tests/BroadPhaseTest.cs

 			_stepCount = 0;
 		}
 
-		protected override void Dispose(bool state)
+		public override void Finish()
 		{
 			_broadPhase = null;
+            base.Finish();
 		}
 
 		public float GetExtent() { return 1.5f * k_extent; }

Examples/XNATestBed/XnaTestBed.cs

                 _iTestIndex++;
                 if(_iTestIndex >= Test.g_testEntries.Length)
                     _iTestIndex = 0;
+                _currentTest.Finish();
                 _currentTestEntry = Test.g_testEntries[_iTestIndex];
                 _currentTest = _currentTestEntry.CreateFcn();
             }

src/Dynamics/Contacts/CircleContact.cs

 using Box2DX.Common;
 using Microsoft.Xna.Framework;
 using System.Diagnostics;
+using Box2DXNA.Common;
 
 namespace Box2DX.Dynamics
 {
 	public class CircleContact : Contact
 	{
-		public Manifold[] _manifolds = s_singleManifoldPool.Create();
+        private static Pool<CircleContact> s_CircleContactPool = new Pool<CircleContact>();
+
+		private Manifold[] _manifolds = new Manifold[1];
+        private bool _bAlive = true;
 
 		public override Manifold[] GetManifolds()
 		{
 			return _manifolds;
 		}
 
+        public CircleContact() { }
+
 		public CircleContact(Shape s1, Shape s2)
-			: base(s1, s2)
 		{
-			Debug.Assert(_shape1.Type == ShapeType.CircleShape);
+			Initialize(s1, s2);
+		}
+
+        public override void Initialize(Shape s1, Shape s2)
+        {
+            base.Initialize(s1, s2);
+            Debug.Assert(_shape1.Type == ShapeType.CircleShape);
 			Debug.Assert(_shape2.Type == ShapeType.CircleShape);
+            
+            _bAlive = true;
             _manifolds[0].PointCount = 0;
             _manifolds[0].Points[0].NormalImpulse = 0.0f;
             _manifolds[0].Points[0].TangentImpulse = 0.0f;
-		}
+        }
 
 		public override void Evaluate(ContactListener listener)
 		{
+            Debug.Assert(_bAlive);
 			Body b1 = _shape1.Body;
 			Body b2 = _shape2.Body;
             Manifold m0 = new Manifold(_manifolds[0]);
 
         public override void CustomDestroy()
         {
+            Debug.Assert(_bAlive);
+
             _manifolds[0].Done();
-            s_singleManifoldPool.Recycle(_manifolds);
-            _manifolds = null;
+            _bAlive = false;
+
+            s_CircleContactPool.Destroy(this);
         }
 
 		new public static Contact Create(Shape shape1, Shape shape2)
 		{
-			return new CircleContact(shape1, shape2);
+            return s_CircleContactPool.Create(x => x.Initialize(shape1, shape2));
 		}
 	}
 }

src/Dynamics/Contacts/Contact.cs

         private static ContactRegister[,] s_registers =
             new ContactRegister[(int)ShapeType.ShapeTypeCount, (int)ShapeType.ShapeTypeCount];
         protected static ArrayPool<bool> s_persistedPool = new ArrayPool<bool>(2);
-        protected static ArrayPool<Manifold> s_singleManifoldPool = new ArrayPool<Manifold>(1);
 
         protected CollisionFlags _flags;
         protected int _manifoldCount;
             AddType(PolygonContact.Create, ShapeType.PolygonShape, ShapeType.PolygonShape);
         }
 
-        public Contact()
+        protected Contact()
         {
 
         }
 
-		public Contact(Shape s1, Shape s2)
+		protected Contact(Shape s1, Shape s2)
 		{
-			_flags = 0;
+			Initialize(s1, s2);
+		}
+
+        public virtual void Initialize(Shape s1, Shape s2)
+        {
+            _flags = 0;
 
 			if (s1.IsSensor || s2.IsSensor)
 			{
             _node2.Contact = this;
             _node2.Other = s1.Body;
             s2.Body.AddContact(_node2);
-		}
+        }
 
         public void RemoveFromParents()
         {
             _shape1.Body.RemoveContact(_node1);
             _shape2.Body.RemoveContact(_node2);
-        }
-
-		public static void AddType(ContactCreateFcn createFcn, ShapeType type1, ShapeType type2)
-		{
-			Debug.Assert(ShapeType.UnknownShape < type1 && type1 < ShapeType.ShapeTypeCount);
-			Debug.Assert(ShapeType.UnknownShape < type2 && type2 < ShapeType.ShapeTypeCount);
-
-			s_registers[(int)type1,(int)type2].CreateFcn = createFcn;
-			s_registers[(int)type1,(int)type2].Primary = true;
-
-			if (type1 != type2)
-			{
-				s_registers[(int)type2,(int)type1].CreateFcn = createFcn;
-				s_registers[(int)type2,(int)type1].Primary = false;
-			}
-		}
-
-		public static Contact Create(Shape shape1, Shape shape2)
-		{
-			ShapeType type1 = shape1.Type;
-			ShapeType type2 = shape2.Type;
-
-			Debug.Assert(ShapeType.UnknownShape < type1 && type1 < ShapeType.ShapeTypeCount);
-			Debug.Assert(ShapeType.UnknownShape < type2 && type2 < ShapeType.ShapeTypeCount);
-
-			ContactCreateFcn createFcn = s_registers[(int)type1,(int)type2].CreateFcn;
-			if (createFcn != null)
-			{
-				if (s_registers[(int)type1,(int)type2].Primary)
-				{
-					return createFcn(shape1, shape2);
-				}
-				else
-				{
-					Contact c = createFcn(shape2, shape1);
-					for (int i = 0; i < c.ManifoldCount; ++i)
-					{
-						c.GetManifolds()[i].Normal = -c.GetManifolds()[i].Normal;
-					}
-					return c;
-				}
-			}
-			else
-			{
-				return null;
-			}
-		}
-
-		/// <summary>
-		/// Get the manifold array.
-		/// </summary>
-		/// <returns></returns>
-		public abstract Manifold[] GetManifolds();
+        }		
 
 		public void Update(ContactListener listener)
 		{
             CustomDestroy();
         }
 
-		public abstract void Evaluate(ContactListener listener);
+        /// <summary>
+        /// Get the manifold array.
+        /// </summary>
+        /// <returns></returns>
+        public abstract Manifold[] GetManifolds();
+
+        public abstract void Evaluate(ContactListener listener);
         public abstract void CustomDestroy();
+
+        public static void AddType(ContactCreateFcn createFcn, ShapeType type1, ShapeType type2)
+        {
+            Debug.Assert(ShapeType.UnknownShape < type1 && type1 < ShapeType.ShapeTypeCount);
+            Debug.Assert(ShapeType.UnknownShape < type2 && type2 < ShapeType.ShapeTypeCount);
+
+            s_registers[(int)type1, (int)type2].CreateFcn = createFcn;
+            s_registers[(int)type1, (int)type2].Primary = true;
+
+            if (type1 != type2)
+            {
+                s_registers[(int)type2, (int)type1].CreateFcn = createFcn;
+                s_registers[(int)type2, (int)type1].Primary = false;
+            }
+        }
+
+        public static Contact Create(Shape shape1, Shape shape2)
+        {
+            ShapeType type1 = shape1.Type;
+            ShapeType type2 = shape2.Type;
+
+            Debug.Assert(ShapeType.UnknownShape < type1 && type1 < ShapeType.ShapeTypeCount);
+            Debug.Assert(ShapeType.UnknownShape < type2 && type2 < ShapeType.ShapeTypeCount);
+
+            ContactCreateFcn createFcn = s_registers[(int)type1, (int)type2].CreateFcn;
+            if (createFcn != null)
+            {
+                if (s_registers[(int)type1, (int)type2].Primary)
+                {
+                    return createFcn(shape1, shape2);
+                }
+                else
+                {
+                    Contact c = createFcn(shape2, shape1);
+                    for (int i = 0; i < c.ManifoldCount; ++i)
+                    {
+                        c.GetManifolds()[i].Normal = -c.GetManifolds()[i].Normal;
+                    }
+                    return c;
+                }
+            }
+            else
+            {
+                return null;
+            }
+        }
 	}
 }

src/Dynamics/Contacts/ContactSolver.cs

 
         private struct VelocityConstraintAccum
         {
-            public Body body;
             public Vector2 v;
             public float w;
             public float invMass;
 
             public VelocityConstraintAccum(Body body)
             {
-                this.body = body;
                 this.v = body._linearVelocity;
                 this.w = body._angularVelocity;
                 this.invMass = body._invMass;
 
             }
 
-            vca1.body._linearVelocity = vca1.v;
-            vca1.body._angularVelocity = vca1.w;
-            vca2.body._linearVelocity = vca2.v;
-            vca2.body._angularVelocity = vca2.w;
+            aConstraint.Body1._linearVelocity = vca1.v;
+            aConstraint.Body1._angularVelocity = vca1.w;
+            aConstraint.Body2._linearVelocity = vca2.v;
+            aConstraint.Body2._angularVelocity = vca2.w;
         }
 
 		public void SolveVelocityConstraints()

src/Dynamics/Contacts/PolyAndCircleContact.cs

 using Box2DX.Common;
 using Microsoft.Xna.Framework;
 using System.Diagnostics;
+using Box2DXNA.Common;
 
 namespace Box2DX.Dynamics
 {
 	public class PolyAndCircleContact : Contact
 	{
-        public Manifold[] _manifolds = s_singleManifoldPool.Create();
+        private static Pool<PolyAndCircleContact> s_PolyCircleContactPool = new Pool<PolyAndCircleContact>();
+
+        private Manifold[] _manifolds = new Manifold[1];
+        private bool _bAlive = true;
 
         public override Manifold[] GetManifolds()
         {
             return _manifolds;
         }
 
+        public PolyAndCircleContact() { }
+
 		public PolyAndCircleContact(Shape s1, Shape s2)
-			: base(s1, s2)
 		{
-			Debug.Assert(_shape1.Type == ShapeType.PolygonShape);
-			Debug.Assert(_shape2.Type == ShapeType.CircleShape);
+            Initialize(s1, s2);
+		}
+
+        public override void Initialize(Shape s1, Shape s2)
+        {
+            base.Initialize(s1, s2);
+
+            Debug.Assert(_shape1.Type == ShapeType.PolygonShape);
+            Debug.Assert(_shape2.Type == ShapeType.CircleShape);
+            
+            _bAlive = true;
             _manifolds[0].PointCount = 0;
-		}
+        }
 
         public override void Evaluate(ContactListener listener)
         {
+            Debug.Assert(_bAlive);
+
             Body b1 = _shape1.Body;
             Body b2 = _shape2.Body;
 
 
         public override void CustomDestroy()
         {
+            Debug.Assert(_bAlive);
+
             _manifolds[0].Done();
-            s_singleManifoldPool.Recycle(_manifolds);
-            _manifolds = null;
+            _bAlive = false;
+
+            s_PolyCircleContactPool.Destroy(this);
         }
 
 		new public static Contact Create(Shape shape1, Shape shape2)
 		{
-			return new PolyAndCircleContact(shape1, shape2);
+			return s_PolyCircleContactPool.Create(x => x.Initialize(shape1, shape2));
 		}
 	}
 }

src/Dynamics/Contacts/PolyContact.cs

 using Box2DX.Common;
 using Microsoft.Xna.Framework;
 using System.Diagnostics;
+using Box2DXNA.Common;
 
 namespace Box2DX.Dynamics
 {
 	public class PolygonContact : Contact
 	{
-		public Manifold[] _manifolds = s_singleManifoldPool.Create();
+        private static Pool<PolygonContact> s_PolyContactPool = new Pool<PolygonContact>();
+
+        private Manifold[] _manifolds = new Manifold[1];
+        private bool _bAlive = true;
 
 		public override Manifold[] GetManifolds()
 		{
 			return _manifolds;
 		}
 
+        public PolygonContact() { }
+
 		public PolygonContact(Shape s1, Shape s2)
-			: base(s1, s2)
 		{
-			Debug.Assert(_shape1.Type == ShapeType.PolygonShape);
-			Debug.Assert(_shape2.Type == ShapeType.PolygonShape);
-			_manifolds[0].PointCount = 0;
+            Initialize(s1, s2);
 		}
 
+        public override void Initialize(Shape s1, Shape s2)
+        {
+            base.Initialize(s1, s2);
+
+            Debug.Assert(_shape1.Type == ShapeType.PolygonShape);
+            Debug.Assert(_shape2.Type == ShapeType.PolygonShape);
+
+            _bAlive = true;
+            _manifolds[0].PointCount = 0;
+        }
+
         public override void Evaluate(ContactListener listener)
         {
+            Debug.Assert(_bAlive);
+
             Body b1 = _shape1.Body;
             Body b2 = _shape2.Body;
 
 
         public override void CustomDestroy()
         {
+            Debug.Assert(_bAlive);
+
             _manifolds[0].Done();
-            s_singleManifoldPool.Recycle(_manifolds);
-            _manifolds = null;
+
+            s_PolyContactPool.Destroy(this);
         }
 
 		new public static Contact Create(Shape shape1, Shape shape2)
 		{
-			return new PolygonContact(shape1, shape2);
+            return s_PolyContactPool.Create(x => x.Initialize(shape1, shape2));
 		}
 	}
 }

src/Dynamics/World.cs

 			}
 
 			// Delete the attached joints.
-			foreach(Joint jn in b._jointList)
+			while(b._jointList.Count > 0)
 			{
 				if (_destructionListener != null)
 				{
-					_destructionListener.SayGoodbye(jn);
+					_destructionListener.SayGoodbye(b._jointList.First.Value);
 				}
 
-                DestroyJoint(jn);
+                DestroyJoint(b._jointList.First.Value);
 			}
 
 			// Delete the attached shapes. This destroys broad-phase
 				SolveTOI(step);
 			}
 
-            // WHO THE FUCK THOUGHT DRAWING DURRING STEP WAS A GOOD IDEA!?
-			// Draw debug information.
-			//DrawDebugData();
-
 			_inv_dt0 = step.Inv_Dt;
 			_lock = false;
 		}
 
                 // Build and simulate all awake islands.
                 Stack<Body> stack = _bodyStackPool.Create();
-                
+
                 foreach(Body seed in _bodyList)
                 {
                     if ((seed._flags & (Body.BodyFlags.Island | Body.BodyFlags.Sleep | Body.BodyFlags.Frozen)) != 0)
                     stack.Clear();
                     stack.Push(seed);
                     seed._flags |= Body.BodyFlags.Island;
-
+                    
                     // Perform a depth first search (DFS) on the constraint graph.
                     while (stack.Count > 0)
                     {