Ejemplo n.º 1
0
		Breakable()
		{
			// Ground body
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			// Breakable dynamic body
			{
				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(0.0f, 40.0f);
				bd.angle = 0.25f * (float)Math.PI;
				m_body1 = m_world.CreateBody(bd);

				m_shape1.SetAsBox(0.5f, 0.5f, new Vec2(-0.5f, 0.0f), 0.0f);
				m_shape1.Density = 1;
				m_piece1 = m_body1.CreateFixture(m_shape1);

				m_shape2.SetAsBox(0.5f, 0.5f, new Vec2(0.5f, 0.0f), 0.0f);
				m_shape2.Density = 1;
				m_piece2 = m_body1.CreateFixture(m_shape2);
			}

			m_break = false;
			m_broke = false;
		}
Ejemplo n.º 2
0
		public ShapeEditing()
		{
			{
				BodyDef bd1 = new BodyDef();
				Body ground = m_world.CreateBody(bd1);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			BodyDef bd = new BodyDef();
			bd.type = BodyType._dynamicBody;
			bd.Position.Set(0.0f, 10.0f);
			m_body = m_world.CreateBody(bd);

			PolygonShape shape2 = new PolygonShape();
			shape2.SetAsBox(4.0f, 4.0f, new Vec2(0.0f, 0.0f), 0.0f);
			shape2.Density = 10;
			m_fixture1 = m_body.CreateFixture(shape2);

			m_fixture2 = null;

			m_sensor = false;
		}
Ejemplo n.º 3
0
		public SphereStack()
		{
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			{
				CircleShape shape = new CircleShape();
				shape.m_radius = 1.0f;

				for (int i = 0; i < e_count; ++i)
				{
					BodyDef bd = new BodyDef();
					bd.type = BodyType._dynamicBody;
					bd.Position.Set(0.0f, 4.0f + 3.0f * i);

					m_bodies[i] = m_world.CreateBody(bd);

					m_bodies[i].CreateFixture(shape);

					m_bodies[i].SetLinearVelocity(new Vec2(0.0f, -50.0f));
				}
			}
		}
Ejemplo n.º 4
0
		public SensorTest()
		{
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				{
					EdgeShape shape = new EdgeShape();
					shape.Set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
					shape.Density = 0;
					ground.CreateFixture(shape);
				}

	#if ZERO
				{
					FixtureDef sd;
					sd.SetAsBox(10.0f, 2.0f, new Vec2(0.0f, 20.0f), 0.0f);
					sd.IsSensor = true;
					m_sensor = ground.CreateFixture(sd);
				}
	#else
				{
					CircleShape shape = new CircleShape();
					shape.m_radius = 5.0f;
					shape.m_p.Set(0.0f, 10.0f);

					FixtureDef fd = new FixtureDef();
					fd.shape = shape;
					fd.IsSensor = true;
					m_sensor = ground.CreateFixture(fd);
				}
	#endif
			}

			{
				CircleShape shape = new CircleShape();
				shape.m_radius = 1.0f;

				for (int i = 0; i < e_count; ++i)
				{
					BodyDef bd = new BodyDef();
					bd.type = BodyType._dynamicBody;
					bd.Position.Set(-10.0f + 3.0f * i, 20.0f);
					bd.UserData = m_touching[i];

					m_touching[i] = false;
					m_bodies[i] = m_world.CreateBody(bd);

					m_bodies[i].CreateFixture(shape);
				}
			}
		}
Ejemplo n.º 5
0
			//e_columnCount = 1,
			//e_rowCount = 1

		public VerticalStack()
		{
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
				shape.Density = 0;
				ground.CreateFixture(shape);

				shape.Set(new Vec2(20.0f, 0.0f), new Vec2(20.0f, 20.0f));
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			float[] xs = {0.0f, -10.0f, -5.0f, 5.0f, 10.0f};

			for (int j = 0; j < e_columnCount; ++j)
			{
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.5f, 0.5f);

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 1.0f;
				fd.friction = 0.3f;

				for (int i = 0; i < e_rowCount; ++i)
				{
					BodyDef bd = new BodyDef();
					bd.type = BodyType._dynamicBody;

					int n = j * e_rowCount + i;
					Utilities.Assert(n < e_rowCount * e_columnCount);
					m_indices[n] = n;
					bd.UserData = m_indices[n];

					float x = 0.0f;
					//float x = RandomFloat(-0.02f, 0.02f);
					//float x = i % 2 == 0 ? -0.025f : 0.025f;
					bd.Position.Set(xs[j] + x, 0.752f + 1.54f * i);
					Body body = m_world.CreateBody(bd);

					m_bodies[n] = body;

					body.CreateFixture(fd);
				}
			}

			m_bullet = null;
		}
Ejemplo n.º 6
0
		public Confined()
		{
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				EdgeShape shape2 = new EdgeShape();

				// Floor
				shape2.Set(new Vec2(-10.0f, 0.0f), new Vec2(10.0f, 0.0f));
				shape2.Density = 0;
				ground.CreateFixture(shape2);

				// Left wall
				shape2.Set(new Vec2(-10.0f, 0.0f), new Vec2(-10.0f, 20.0f));
				ground.CreateFixture(shape2);

				// Right wall
				shape2.Set(new Vec2(10.0f, 0.0f), new Vec2(10.0f, 20.0f));
				ground.CreateFixture(shape2);

				// Roof
				shape2.Set(new Vec2(-10.0f, 20.0f), new Vec2(10.0f, 20.0f));
				ground.CreateFixture(shape2);
			}

			float radius = 0.5f;
			CircleShape shape = new CircleShape();
			shape.m_p.SetZero();
			shape.m_radius = radius;

			FixtureDef fd = new FixtureDef();
			fd.shape = shape;
			fd.Density = 1.0f;
			fd.friction = 0.1f;

			for (int j = 0; j < e_columnCount; ++j)
			{
				for (int i = 0; i < e_rowCount; ++i)
				{
					BodyDef bd = new BodyDef();
					bd.type = BodyType._dynamicBody;
					bd.Position.Set(-10.0f + (2.1f * j + 1.0f + 0.01f * i) * radius, (2.0f * i + 1.0f) * radius);
					Body body = m_world.CreateBody(bd);

					body.CreateFixture(fd);
				}
			}

			m_world.SetGravity(new Vec2(0.0f, 0.0f));
		}
Ejemplo n.º 7
0
		public OneSidedPlatform()
		{
			// Ground
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-20.0f, 0.0f), new Vec2(20.0f, 0.0f));
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			// Platform
			{
				BodyDef bd = new BodyDef();
				bd.Position.Set(0.0f, 10.0f);
				Body body = m_world.CreateBody(bd);

				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(3.0f, 0.5f);
				shape.Density = 0;
				m_platform = body.CreateFixture(shape);

				m_bottom = 10.0f - 0.5f;
				m_top = 10.0f + 0.5f;
			}

			// Actor
			{
				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(0.0f, 12.0f);
				Body body = m_world.CreateBody(bd);

				m_radius = 0.5f;
				CircleShape shape = new CircleShape();
				shape.m_radius = m_radius;
				shape.Density = 20;
				m_character = body.CreateFixture(shape);

				body.SetLinearVelocity(new Vec2(0.0f, -50.0f));

				m_state = State.e_unknown;
			}
		}
Ejemplo n.º 8
0
		public Prismatic() {
			Body ground = null;
			{
				BodyDef bd = new BodyDef();
				ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			{
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(2.0f, 0.5f);
				shape.Density = 5;

				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(-10.0f, 10.0f);
				bd.angle = 0.5f * (float)Math.PI;
				bd.allowSleep = false;
				Body body = m_world.CreateBody(bd);
				body.CreateFixture(shape);

				PrismaticJointDef pjd = new PrismaticJointDef();

				// Bouncy limit
				Vec2 axis = new Vec2(2.0f, 1.0f);
				axis.Normalize();
				pjd.Initialize(ground, body, new Vec2(0.0f, 0.0f), axis);

				// Non-bouncy limit
				//pjd.Initialize(ground, body, new Vec2(-10.0f, 10.0f), new Vec2(1.0f, 0.0f));

				pjd.motorSpeed = 10.0f;
				pjd.maxMotorForce = 10000.0f;
				pjd.enableMotor = true;
				pjd.lowerTranslation = 0.0f;
				pjd.upperTranslation = 20.0f;
				pjd.enableLimit = true;

				m_joint = (PrismaticJoint)m_world.CreateJoint(pjd);
			}
		}
Ejemplo n.º 9
0
		public BulletTest()
		{
			{
				BodyDef bd = new BodyDef();
				bd.Position.Set(0.0f, 0.0f);
				Body body = m_world.CreateBody(bd);

				EdgeShape edge = new EdgeShape();

				edge.Set(new Vec2(-10.0f, 0.0f), new Vec2(10.0f, 0.0f));
				edge.Density = 0;
				body.CreateFixture(edge);

				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.2f, 1.0f, new Vec2(0.5f, 1.0f), 0.0f);
				shape.Density = 0;
				body.CreateFixture(shape);
			}

			{
				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(0.0f, 4.0f);

				PolygonShape box = new PolygonShape();
				box.SetAsBox(2.0f, 0.1f);
				box.Density = 100;

				m_body = m_world.CreateBody(bd);
				m_body.CreateFixture(box);

				box.SetAsBox(0.25f, 0.25f);

				//m_x = RandomFloat(-1.0f, 1.0f);
				m_x = 0.20352793f;
				bd.Position.Set(m_x, 10.0f);
				bd.bullet = true;

				m_bullet = m_world.CreateBody(bd);
				m_bullet.CreateFixture(box);

				m_bullet.SetLinearVelocity(new Vec2(0.0f, -50.0f));
			}
		}
Ejemplo n.º 10
0
		public Chain()
		{
			Body ground = null;
			{
				BodyDef bd = new BodyDef();
				ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			{
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.6f, 0.125f);

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 20.0f;
				fd.friction = 0.2f;

				RevoluteJointDef jd = new RevoluteJointDef();
				jd.collideConnected = false;

				const float y = 25.0f;
				Body prevBody = ground;
				for (int i = 0; i < 30; ++i)
				{
					BodyDef bd = new BodyDef();
					bd.type = BodyType._dynamicBody;
					bd.Position.Set(0.5f + i, y);
					Body body = m_world.CreateBody(bd);
					body.CreateFixture(fd);

					Vec2 anchor = new Vec2((float)(i), y);
					jd.Initialize(prevBody, body, anchor);
					m_world.CreateJoint(jd);

					prevBody = body;
				}
			}
		}
Ejemplo n.º 11
0
		public Pyramid()
		{
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			{
				float a = 0.5f;
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(a, a);
				shape.Density = 5;

				Vec2 x = new Vec2(-7.0f, 0.75f);
				Vec2 y;
				Vec2 deltaX = new Vec2(0.5625f, 1.25f);
				Vec2 deltaY = new Vec2(1.125f, 0.0f);

				for (int i = 0; i < e_count; ++i)
				{
					y = x;

					for (int j = i; j < e_count; ++j)
					{
						BodyDef bd = new BodyDef();
						bd.type = BodyType._dynamicBody;
						bd.Position = y;
						Body body = m_world.CreateBody(bd);
						body.CreateFixture(shape);

						y += deltaY;
					}

					x += deltaX;
				}
			}
		}
Ejemplo n.º 12
0
		public ConveyorBelt()
		{
			// Ground
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-20.0f, 0.0f), new Vec2(20.0f, 0.0f));
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			// Platform
			{
				BodyDef bd = new BodyDef();
				bd.Position.Set(-5.0f, 5.0f);
				Body body = m_world.CreateBody(bd);

				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(10.0f, 0.5f);

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.friction = 0.8f;
				m_platform = body.CreateFixture(fd);
			}

			// Boxes
			for (int i = 0; i < 5; ++i)
			{
				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(-10.0f + 2.0f * i, 7.0f);
				Body body = m_world.CreateBody(bd);

				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.5f, 0.5f);
				shape.Density = 20;
				body.CreateFixture(shape);
			}
		}
Ejemplo n.º 13
0
		public MotorJointTest()
		{
			Body ground = null;
			{
				BodyDef bd = new BodyDef();
				ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-20.0f, 0.0f), new Vec2(20.0f, 0.0f));

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;

				ground.CreateFixture(fd);
			}

			// Define motorized body
			{
				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(0.0f, 8.0f);
				Body body = m_world.CreateBody(bd);

				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(2.0f, 0.5f);

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.friction = 0.6f;
				fd.Density = 2.0f;
				body.CreateFixture(fd);

				MotorJointDef mjd = new MotorJointDef();
				mjd.Initialize(ground, body);
				mjd.maxForce = 1000.0f;
				mjd.maxTorque = 1000.0f;
				m_joint = (MotorJoint)m_world.CreateJoint(mjd);
			}

			m_go = false;
			m_time = 0.0f;
		}
Ejemplo n.º 14
0
		public VaryingRestitution()
		{
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
				shape.Density = 0;
				ground.CreateFixture(shape);
				
			}

			{
				CircleShape shape = new CircleShape();
				shape.m_radius = 1.0f;

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 1.0f;

				float[] restitution = {0.0f, 0.1f, 0.3f, 0.5f, 0.75f, 0.9f, 1.0f};

				for (int i = 0; i < 7; ++i)
				{
					BodyDef bd = new BodyDef();
					bd.type = BodyType._dynamicBody;
					bd.Position.Set(-10.0f + 3.0f * i, 20.0f);

					Body body = m_world.CreateBody(bd);

					fd.restitution = restitution[i];
					body.CreateFixture(fd);
				}
			}
		}
Ejemplo n.º 15
0
		Bridge()
		{
			Body ground = null;
			{
				BodyDef bd = new BodyDef();
				ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			{
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.5f, 0.125f);

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 20.0f;
				fd.friction = 0.2f;

				RevoluteJointDef jd = new RevoluteJointDef();

				Body prevBody = ground;
				for (int i = 0; i < e_count; ++i)
				{
					BodyDef bd = new BodyDef();
					bd.type = BodyType._dynamicBody;
					bd.Position.Set(-14.5f + 1.0f * i, 5.0f);
					Body body = m_world.CreateBody(bd);
					body.CreateFixture(fd);

					Vec2 anchor = new Vec2(-15.0f + 1.0f * i, 5.0f);
					jd.Initialize(prevBody, body, anchor);
					m_world.CreateJoint(jd);

					if (i == (e_count >> 1))
					{
						m_middle = body;
					}
					prevBody = body;
				}

				Vec2 anchor2 = new Vec2(-15.0f + 1.0f * e_count, 5.0f);
				jd.Initialize(prevBody, ground, anchor2);
				m_world.CreateJoint(jd);
			}

			for (int i = 0; i < 2; ++i)
			{
				Vec2[] vertices = new Vec2[3];
				vertices[0].Set(-0.5f, 0.0f);
				vertices[1].Set(0.5f, 0.0f);
				vertices[2].Set(0.0f, 1.5f);

				PolygonShape shape = new PolygonShape();
				shape.Set(vertices, 3);

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 1.0f;

				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(-8.0f + 8.0f * i, 12.0f);
				Body body = m_world.CreateBody(bd);
				body.CreateFixture(fd);
			}

			for (int i = 0; i < 3; ++i)
			{
				CircleShape shape = new CircleShape();
				shape.m_radius = 0.5f;

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 1.0f;

				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(-6.0f + 6.0f * i, 10.0f);
				Body body = m_world.CreateBody(bd);
				body.CreateFixture(fd);
			}
		}
Ejemplo n.º 16
0
		/// Compute the collision manifold between an edge and a circle.
		public static void CollideEdgeAndPolygon(out Manifold manifold,
									   EdgeShape edgeA, Transform xfA,
									   PolygonShape polygonB, Transform xfB) {
			EPCollider collider = new EPCollider();
			collider.Collide(out manifold, edgeA, xfA, polygonB, xfB);
		}
Ejemplo n.º 17
0
		/// Compute the collision manifold between an edge and a circle.
		public static void CollideEdgeAndCircle(out Manifold manifold,
									   EdgeShape edgeA, Transform xfA,
									   CircleShape circleB, Transform xfB){
			manifold = new Manifold();
	
			// Compute circle in frame of edge
			Vec2 Q = Utilities.MulT(xfA, Utilities.Mul(xfB, circleB.m_p));
	
			Vec2 A = edgeA.m_vertex1, B = edgeA.m_vertex2;
			Vec2 e = B - A;
	
			// Barycentric coordinates
			float u = Utilities.Dot(e, B - Q);
			float v = Utilities.Dot(e, Q - A);
	
			float radius = edgeA.m_radius + circleB.m_radius;
	
			ContactFeature cf;
			cf.indexB = 0;
			cf.typeB = ContactFeature.FeatureType.e_vertex;
	
			// Region A
			if (v <= 0.0f)
			{
				Vec2 P = A;
				Vec2 d = Q - P;
				float dd = Utilities.Dot(d, d);
				if (dd > radius * radius)
				{
					return;
				}
		
				// Is there an edge connected to A?
				if (edgeA.m_hasVertex0)
				{
					Vec2 A1 = edgeA.m_vertex0;
					Vec2 B1 = A;
					Vec2 e1 = B1 - A1;
					float u1 = Utilities.Dot(e1, B1 - Q);
			
					// Is the circle in Region AB of the previous edge?
					if (u1 > 0.0f)
					{
						return;
					}
				}
		
				cf.indexA = 0;
				cf.typeA = ContactFeature.FeatureType.e_vertex;
				manifold.points.Clear();
				manifold.points.Add(new ManifoldPoint());
				manifold.type = Manifold.ManifoldType.e_circles;
				manifold.localNormal.SetZero();
				manifold.localPoint = P;
				manifold.points[0].id.key = 0;
				manifold.points[0].id.cf = cf;
				manifold.points[0].localPoint = circleB.m_p;
				return;
			}
	
			// Region B
			if (u <= 0.0f)
			{
				Vec2 P = B;
				Vec2 d = Q - P;
				float dd = Utilities.Dot(d, d);
				if (dd > radius * radius)
				{
					return;
				}
		
				// Is there an edge connected to B?
				if (edgeA.m_hasVertex3)
				{
					Vec2 B2 = edgeA.m_vertex3;
					Vec2 A2 = B;
					Vec2 e2 = B2 - A2;
					float v2 = Utilities.Dot(e2, Q - A2);
			
					// Is the circle in Region AB of the next edge?
					if (v2 > 0.0f)
					{
						return;
					}
				}
		
				cf.indexA = 1;
				cf.typeA = ContactFeature.FeatureType.e_vertex;
				manifold.points.Clear();
				manifold.points.Add(new ManifoldPoint());
				manifold.type = Manifold.ManifoldType.e_circles;
				manifold.localNormal.SetZero();
				manifold.localPoint = P;
				manifold.points[0].id.key = 0;
				manifold.points[0].id.cf = cf;
				manifold.points[0].localPoint = circleB.m_p;
				return;
			}
	
			// Region AB
			float den = Utilities.Dot(e, e);
			Utilities.Assert(den > 0.0f);
			Vec2 Pb = (1.0f / den) * (u * A + v * B);
			Vec2 db = Q - Pb;
			float ddb = Utilities.Dot(db, db);
			if (ddb > radius * radius)
			{
				return;
			}
	
			Vec2 n = new Vec2(-e.Y, e.X);
			if (Utilities.Dot(n, Q - A) < 0.0f)
			{
				n.Set(-n.X, -n.Y);
			}
			n.Normalize();
	
			cf.indexA = 0;
			cf.typeA = ContactFeature.FeatureType.e_face;
			manifold.points.Clear();
			manifold.points.Add(new ManifoldPoint());
			manifold.type = Manifold.ManifoldType.e_faceA;
			manifold.localNormal = n;
			manifold.localPoint = A;
			manifold.points[0].id.key = 0;
			manifold.points[0].id.cf = cf;
			manifold.points[0].localPoint = circleB.m_p;
		}
Ejemplo n.º 18
0
		public Revolute()
		{
			Body ground = null;
			{
				BodyDef bd = new BodyDef();
				ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				//fd.Filter.CategoryBits = 2;

				ground.CreateFixture(fd);
			}

			{
				CircleShape shape = new CircleShape();
				shape.m_radius = 0.5f;
				shape.Density = 5;

				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;

				RevoluteJointDef rjd = new RevoluteJointDef();

				bd.Position.Set(-10.0f, 20.0f);
				Body body = m_world.CreateBody(bd);
				body.CreateFixture(shape);

				float w = 100.0f;
				body.SetAngularVelocity(w);
				body.SetLinearVelocity(new Vec2(-8.0f * w, 0.0f));

				rjd.Initialize(ground, body, new Vec2(-10.0f, 12.0f));
				rjd.motorSpeed = 1.0f * (float)Math.PI;
				rjd.maxMotorTorque = 10000.0f;
				rjd.enableMotor = false;
				rjd.lowerAngle = -0.25f * (float)Math.PI;
				rjd.upperAngle = 0.5f * (float)Math.PI;
				rjd.enableLimit = true;
				rjd.collideConnected = true;

				m_joint = (RevoluteJoint)m_world.CreateJoint(rjd);
			}

			{
				CircleShape circle_shape = new CircleShape();
				circle_shape.m_radius = 3.0f;

				BodyDef circle_bd = new BodyDef();
				circle_bd.type = BodyType._dynamicBody;
				circle_bd.Position.Set(5.0f, 30.0f);

				FixtureDef fd = new FixtureDef();
				fd.Density = 5.0f;
				fd.Filter.MaskBits = 1;
				fd.shape = circle_shape;

				m_ball = m_world.CreateBody(circle_bd);
				m_ball.CreateFixture(fd);

				PolygonShape polygon_shape = new PolygonShape();
				polygon_shape.SetAsBox(10.0f, 0.2f, new Vec2(-10.0f, 0.0f), 0.0f);
				polygon_shape.Density = 2;

				BodyDef polygon_bd = new BodyDef();
				polygon_bd.Position.Set(20.0f, 10.0f);
				polygon_bd.type = BodyType._dynamicBody;
				polygon_bd.bullet = true;
				Body polygon_body = m_world.CreateBody(polygon_bd);
				
				polygon_body.CreateFixture(polygon_shape);

				RevoluteJointDef rjd = new RevoluteJointDef();
				rjd.Initialize(ground, polygon_body, new Vec2(20.0f, 10.0f));
				rjd.lowerAngle = -0.25f * (float)Math.PI;
				rjd.upperAngle = 0.0f * (float)Math.PI;
				rjd.enableLimit = true;
				m_world.CreateJoint(rjd);
			}

			// Tests mass computation of a small object far from the origin
			{
				BodyDef bodyDef = new BodyDef();
				bodyDef.type = BodyType._dynamicBody;
				Body body = m_world.CreateBody(bodyDef);
		
				PolygonShape polyShape = new PolygonShape();
				Vec2[] verts = new Vec2[3];
				verts[0].Set( 17.63f, 36.31f );
				verts[1].Set( 17.52f, 36.69f );
				verts[2].Set( 17.19f, 36.36f );
				polyShape.Set(verts, 3);
		
				FixtureDef polyFixtureDef = new FixtureDef();
				polyFixtureDef.shape = polyShape;
				polyFixtureDef.Density = 1;

				body.CreateFixture(polyFixtureDef);	//assertion hits inside here
			}

		}
Ejemplo n.º 19
0
		public EdgeShapes()
		{
			// Ground body
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				float x1 = -20.0f;
				float y1 = 2.0f * (float)Math.Cos(x1 / 10.0f * (float)Math.PI);
				for (int i = 0; i < 80; ++i)
				{
					float x2 = x1 + 0.5f;
					float y2 = 2.0f * (float)Math.Cos(x2 / 10.0f * (float)Math.PI);

					EdgeShape shape = new EdgeShape();
					shape.Set(new Vec2(x1, y1), new Vec2(x2, y2));
					shape.Density = 0;
					ground.CreateFixture(shape);

					x1 = x2;
					y1 = y2;
				}
			}

			{
				Vec2[] vertices = new Vec2[3];
				vertices[0].Set(-0.5f, 0.0f);
				vertices[1].Set(0.5f, 0.0f);
				vertices[2].Set(0.0f, 1.5f);
				m_polygons[0].Set(vertices, 3);
			}

			{
				Vec2[] vertices = new Vec2[3];
				vertices[0].Set(-0.1f, 0.0f);
				vertices[1].Set(0.1f, 0.0f);
				vertices[2].Set(0.0f, 1.5f);
				m_polygons[1].Set(vertices, 3);
			}

			{
				float w = 1.0f;
				float b = w / (2.0f + (float)Math.Sqrt(2.0f));
				float s = (float)Math.Sqrt(2.0f) * b;

				Vec2[] vertices = new Vec2[8];
				vertices[0].Set(0.5f * s, 0.0f);
				vertices[1].Set(0.5f * w, b);
				vertices[2].Set(0.5f * w, b + s);
				vertices[3].Set(0.5f * s, w);
				vertices[4].Set(-0.5f * s, w);
				vertices[5].Set(-0.5f * w, b + s);
				vertices[6].Set(-0.5f * w, b);
				vertices[7].Set(-0.5f * s, 0.0f);

				m_polygons[2].Set(vertices, 8);
			}

			{
				m_polygons[3].SetAsBox(0.5f, 0.5f);
			}

			{
				m_circle.m_radius = 0.5f;
			}

			m_bodyIndex = 0;
			Array.Clear(m_bodies, 0, m_bodies.Length);

			m_angle = 0.0f;
		}
Ejemplo n.º 20
0
		public CompoundShapes()
		{
			{
				BodyDef bd = new BodyDef();
				bd.Position.Set(0.0f, 0.0f);
				Body body = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(50.0f, 0.0f), new Vec2(-50.0f, 0.0f));
				shape.Density = 0;
				body.CreateFixture(shape);
			}

			{
				CircleShape circle1 = new CircleShape();
				circle1.m_radius = 0.5f;
				circle1.m_p.Set(-0.5f, 0.5f);
				circle1.Density = 2;

				CircleShape circle2 = new CircleShape();
				circle2.m_radius = 0.5f;
				circle2.m_p.Set(0.5f, 0.5f);
				circle2.Density = 0;

				for (int i = 0; i < 10; ++i)
				{
					float x = RandomFloat(-0.1f, 0.1f);
					BodyDef bd = new BodyDef();
					bd.type = BodyType._dynamicBody;
					bd.Position.Set(x + 5.0f, 1.05f + 2.5f * i);
					bd.angle = RandomFloat(-(float)Math.PI, (float)Math.PI);
					Body body = m_world.CreateBody(bd);
					body.CreateFixture(circle1);
					body.CreateFixture(circle2);
				}
			}

			{
				PolygonShape polygon1 = new PolygonShape();
				polygon1.SetAsBox(0.25f, 0.5f);
				polygon1.Density = 2;

				PolygonShape polygon2 = new PolygonShape();
				polygon2.SetAsBox(0.25f, 0.5f, new Vec2(0.0f, -0.5f), 0.5f * (float)Math.PI);
				polygon2.Density = 2;

				for (int i = 0; i < 10; ++i)
				{
					float x = RandomFloat(-0.1f, 0.1f);
					BodyDef bd = new BodyDef();
					bd.type = BodyType._dynamicBody;
					bd.Position.Set(x - 5.0f, 1.05f + 2.5f * i);
					bd.angle = RandomFloat(-(float)Math.PI, (float)Math.PI);
					Body body = m_world.CreateBody(bd);
					body.CreateFixture(polygon1);
					body.CreateFixture(polygon2);
				}
			}

			{
				Transform xf1 = new Transform();
				xf1.q.Set(0.3524f * (float)Math.PI);
				xf1.p = xf1.q.GetXAxis();

				Vec2[] vertices = new Vec2[3];

				PolygonShape triangle1 = new PolygonShape();
				vertices[0] = Utilities.Mul(xf1, new Vec2(-1.0f, 0.0f));
				vertices[1] = Utilities.Mul(xf1, new Vec2(1.0f, 0.0f));
				vertices[2] = Utilities.Mul(xf1, new Vec2(0.0f, 0.5f));
				triangle1.Set(vertices, 3);

				Transform xf2 = new Transform();
				xf2.q.Set(-0.3524f * (float)Math.PI);
				xf2.p = -xf2.q.GetXAxis();

				PolygonShape triangle2 = new PolygonShape();
				vertices[0] = Utilities.Mul(xf2, new Vec2(-1.0f, 0.0f));
				vertices[1] = Utilities.Mul(xf2, new Vec2(1.0f, 0.0f));
				vertices[2] = Utilities.Mul(xf2, new Vec2(0.0f, 0.5f));
				triangle2.Set(vertices, 3);

				for (int i = 0; i < 10; ++i)
				{
					float x = RandomFloat(-0.1f, 0.1f);
					BodyDef bd = new BodyDef();
					bd.type = BodyType._dynamicBody;
					bd.Position.Set(x, 2.05f + 2.5f * i);
					bd.angle = 0.0f;
					Body body = m_world.CreateBody(bd);
					triangle1.Density = 2;
					triangle2.Density = 2;
					body.CreateFixture(triangle1);
					body.CreateFixture(triangle2);
				}
			}

			{
				PolygonShape bottom = new PolygonShape();
				bottom.SetAsBox( 1.5f, 0.15f );

				PolygonShape left = new PolygonShape();
				left.SetAsBox(0.15f, 2.7f, new Vec2(-1.45f, 2.35f), 0.2f);

				PolygonShape right = new PolygonShape();
				right.SetAsBox(0.15f, 2.7f, new Vec2(1.45f, 2.35f), -0.2f);

				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set( 0.0f, 2.0f );
				Body body = m_world.CreateBody(bd);
				bottom.Density = 4;
				left.Density = 4;
				right.Density = 4;
				body.CreateFixture(bottom);
				body.CreateFixture(left);
				body.CreateFixture(right);
			}
		}
Ejemplo n.º 21
0
		public CharacterCollision()
		{
			// Ground body
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-20.0f, 0.0f), new Vec2(20.0f, 0.0f));
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			// Collinear edges with no adjacency information.
			// This shows the problematic case where a box shape can hit
			// an internal vertex.
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Density = 0;
				shape.Set(new Vec2(-8.0f, 1.0f), new Vec2(-6.0f, 1.0f));
				ground.CreateFixture(shape);
				shape.Set(new Vec2(-6.0f, 1.0f), new Vec2(-4.0f, 1.0f));
				ground.CreateFixture(shape);
				shape.Set(new Vec2(-4.0f, 1.0f), new Vec2(-2.0f, 1.0f));
				ground.CreateFixture(shape);
			}

			// Chain shape
			{
				BodyDef bd = new BodyDef();
				bd.angle = 0.25f * (float)Math.PI;
				Body ground = m_world.CreateBody(bd);

				Vec2[] vs = new Vec2[4];
				vs[0].Set(5.0f, 7.0f);
				vs[1].Set(6.0f, 8.0f);
				vs[2].Set(7.0f, 8.0f);
				vs[3].Set(8.0f, 7.0f);
				ChainShape shape = new ChainShape();
				shape.CreateChain(vs, 4);
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			// Square tiles. This shows that adjacency shapes may
			// have non-smooth collision. There is no solution
			// to this problem.
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				PolygonShape shape = new PolygonShape();
				shape.Density = 0;

				shape.SetAsBox(1.0f, 1.0f, new Vec2(4.0f, 3.0f), 0.0f);
				ground.CreateFixture(shape);
				shape.SetAsBox(1.0f, 1.0f, new Vec2(6.0f, 3.0f), 0.0f);
				ground.CreateFixture(shape);
				shape.SetAsBox(1.0f, 1.0f, new Vec2(8.0f, 3.0f), 0.0f);
				ground.CreateFixture(shape);
			}

			// Square made from an edge loop. Collision should be smooth.
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				Vec2[] vs = new Vec2[4];
				vs[0].Set(-1.0f, 3.0f);
				vs[1].Set(1.0f, 3.0f);
				vs[2].Set(1.0f, 5.0f);
				vs[3].Set(-1.0f, 5.0f);
				ChainShape shape = new ChainShape();
				shape.CreateLoop(vs, 4);
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			// Edge loop. Collision should be smooth.
			{
				BodyDef bd = new BodyDef();
				bd.Position.Set(-10.0f, 4.0f);
				Body ground = m_world.CreateBody(bd);

				Vec2[] vs = new Vec2[10];
				vs[0].Set(0.0f, 0.0f);
				vs[1].Set(6.0f, 0.0f);
				vs[2].Set(6.0f, 2.0f);
				vs[3].Set(4.0f, 1.0f);
				vs[4].Set(2.0f, 2.0f);
				vs[5].Set(0.0f, 2.0f);
				vs[6].Set(-2.0f, 2.0f);
				vs[7].Set(-4.0f, 3.0f);
				vs[8].Set(-6.0f, 2.0f);
				vs[9].Set(-6.0f, 0.0f);
				ChainShape shape = new ChainShape();
				shape.CreateLoop(vs, 10);
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			// Square character 1
			{
				BodyDef bd = new BodyDef();
				bd.Position.Set(-3.0f, 8.0f);
				bd.type = BodyType._dynamicBody;
				bd.fixedRotation = true;
				bd.allowSleep = false;

				Body body = m_world.CreateBody(bd);

				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.5f, 0.5f);

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 20.0f;
				body.CreateFixture(fd);
			}

			// Square character 2
			{
				BodyDef bd = new BodyDef();
				bd.Position.Set(-5.0f, 5.0f);
				bd.type = BodyType._dynamicBody;
				bd.fixedRotation = true;
				bd.allowSleep = false;

				Body body = m_world.CreateBody(bd);

				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.25f, 0.25f);

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 20.0f;
				body.CreateFixture(fd);
			}

			// Hexagon character
			{
				BodyDef bd = new BodyDef();
				bd.Position.Set(-5.0f, 8.0f);
				bd.type = BodyType._dynamicBody;
				bd.fixedRotation = true;
				bd.allowSleep = false;

				Body body = m_world.CreateBody(bd);

				float angle = 0.0f;
				float delta = (float)Math.PI / 3.0f;
				Vec2[] vertices = new Vec2[6];
				for (int i = 0; i < 6; ++i)
				{
					vertices[i].Set(0.5f * (float)Math.Cos(angle), 0.5f * (float)Math.Sin(angle));
					angle += delta;
				}

				PolygonShape shape = new PolygonShape();
				shape.Set(vertices, 6);

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 20.0f;
				body.CreateFixture(fd);
			}

			// Circle character
			{
				BodyDef bd = new BodyDef();
				bd.Position.Set(3.0f, 5.0f);
				bd.type = BodyType._dynamicBody;
				bd.fixedRotation = true;
				bd.allowSleep = false;

				Body body = m_world.CreateBody(bd);

				CircleShape shape = new CircleShape();
				shape.m_radius = 0.5f;

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 20.0f;
				body.CreateFixture(fd);
			}

			// Circle character
			{
				BodyDef bd = new BodyDef();
				bd.Position.Set(-7.0f, 6.0f);
				bd.type = BodyType._dynamicBody;
				bd.allowSleep = false;

				m_character = m_world.CreateBody(bd);

				CircleShape shape = new CircleShape();
				shape.m_radius = 0.25f;

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 20.0f;
				fd.friction = 1.0f;
				m_character.CreateFixture(fd);
			}
		}
Ejemplo n.º 22
0
		public BodyTypes()
		{
			Body ground = null;
			{
				BodyDef bd = new BodyDef();
				ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-20.0f, 0.0f), new Vec2(20.0f, 0.0f));

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;

				ground.CreateFixture(fd);
			}

			// Define attachment
			{
				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(0.0f, 3.0f);
				m_attachment = m_world.CreateBody(bd);

				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.5f, 2.0f);
				shape.Density = 2;
				m_attachment.CreateFixture(shape);
			}

			// Define platform
			{
				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(-4.0f, 5.0f);
				m_platform = m_world.CreateBody(bd);

				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.5f, 4.0f, new Vec2(4.0f, 0.0f), 0.5f * (float)Math.PI);

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.friction = 0.6f;
				fd.Density = 2.0f;
				m_platform.CreateFixture(fd);

				RevoluteJointDef rjd = new RevoluteJointDef();
				rjd.Initialize(m_attachment, m_platform, new Vec2(0.0f, 5.0f));
				rjd.maxMotorTorque = 50.0f;
				rjd.enableMotor = true;
				m_world.CreateJoint(rjd);

				PrismaticJointDef pjd = new PrismaticJointDef();
				pjd.Initialize(ground, m_platform, new Vec2(0.0f, 5.0f), new Vec2(1.0f, 0.0f));

				pjd.maxMotorForce = 1000.0f;
				pjd.enableMotor = true;
				pjd.lowerTranslation = -10.0f;
				pjd.upperTranslation = 10.0f;
				pjd.enableLimit = true;

				m_world.CreateJoint(pjd);

				m_speed = 3.0f;
			}

			// Create a payload
			{
				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(0.0f, 8.0f);
				Body body = m_world.CreateBody(bd);

				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.75f, 0.75f);

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.friction = 0.6f;
				fd.Density = 2.0f;

				body.CreateFixture(fd);
			}
		}
Ejemplo n.º 23
0
		public CollisionFiltering()
		{
			// Ground body
			{
				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));

				FixtureDef sd = new FixtureDef();
				sd.shape = shape;
				sd.friction = 0.3f;

				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);
				ground.CreateFixture(sd);
			}

			// Small triangle
			Vec2[] vertices = new Vec2[3];
			vertices[0].Set(-1.0f, 0.0f);
			vertices[1].Set(1.0f, 0.0f);
			vertices[2].Set(0.0f, 2.0f);
			PolygonShape polygon = new PolygonShape();
			polygon.Set(vertices, 3);

			FixtureDef triangleShapeDef = new FixtureDef();
			triangleShapeDef.shape = polygon;
			triangleShapeDef.Density = 1.0f;

			triangleShapeDef.Filter.GroupIndex = k_smallGroup;
			triangleShapeDef.Filter.CategoryBits = k_triangleCategory;
			triangleShapeDef.Filter.MaskBits = k_triangleMask;

			BodyDef triangleBodyDef = new BodyDef();
			triangleBodyDef.type = BodyType._dynamicBody;
			triangleBodyDef.Position.Set(-5.0f, 2.0f);

			Body body1 = m_world.CreateBody(triangleBodyDef);
			body1.CreateFixture(triangleShapeDef);

			// Large triangle (recycle definitions)
			vertices[0] *= 2.0f;
			vertices[1] *= 2.0f;
			vertices[2] *= 2.0f;
			polygon.Set(vertices, 3);
			triangleShapeDef.Filter.GroupIndex = k_largeGroup;
			triangleBodyDef.Position.Set(-5.0f, 6.0f);
			triangleBodyDef.fixedRotation = true; // look at me!

			Body body2 = m_world.CreateBody(triangleBodyDef);
			body2.CreateFixture(triangleShapeDef);

			{
				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(-5.0f, 10.0f);
				Body body = m_world.CreateBody(bd);

				PolygonShape p = new PolygonShape();
				p.SetAsBox(0.5f, 1.0f);
				body.CreateFixture(p);

				PrismaticJointDef jd = new PrismaticJointDef();
				jd.bodyA = body2;
				jd.bodyB = body;
				jd.enableLimit = true;
				jd.localAnchorA.Set(0.0f, 4.0f);
				jd.localAnchorB.SetZero();
				jd.localAxisA.Set(0.0f, 1.0f);
				jd.lowerTranslation = -1.0f;
				jd.upperTranslation = 1.0f;

				m_world.CreateJoint(jd);
			}

			// Small box
			polygon.SetAsBox(1.0f, 0.5f);
			FixtureDef boxShapeDef = new FixtureDef();
			boxShapeDef.shape = polygon;
			boxShapeDef.Density = 1.0f;
			boxShapeDef.restitution = 0.1f;

			boxShapeDef.Filter.GroupIndex = k_smallGroup;
			boxShapeDef.Filter.CategoryBits = k_boxCategory;
			boxShapeDef.Filter.MaskBits = k_boxMask;

			BodyDef boxBodyDef = new BodyDef();
			boxBodyDef.type = BodyType._dynamicBody;
			boxBodyDef.Position.Set(0.0f, 2.0f);

			Body body3 = m_world.CreateBody(boxBodyDef);
			body3.CreateFixture(boxShapeDef);

			// Large box (recycle definitions)
			polygon.SetAsBox(2.0f, 1.0f);
			boxShapeDef.Filter.GroupIndex = k_largeGroup;
			boxBodyDef.Position.Set(0.0f, 6.0f);

			Body body4 = m_world.CreateBody(boxBodyDef);
			body4.CreateFixture(boxShapeDef);

			// Small circle
			CircleShape circle = new CircleShape();
			circle.m_radius = 1.0f;

			FixtureDef circleShapeDef = new FixtureDef();
			circleShapeDef.shape = circle;
			circleShapeDef.Density = 1.0f;

			circleShapeDef.Filter.GroupIndex = k_smallGroup;
			circleShapeDef.Filter.CategoryBits = k_circleCategory;
			circleShapeDef.Filter.MaskBits = k_circleMask;

			BodyDef circleBodyDef = new BodyDef();
			circleBodyDef.type = BodyType._dynamicBody;
			circleBodyDef.Position.Set(5.0f, 2.0f);
		
			Body body5 = m_world.CreateBody(circleBodyDef);
			body5.CreateFixture(circleShapeDef);

			// Large circle
			circle.m_radius *= 2.0f;
			circleShapeDef.Filter.GroupIndex = k_largeGroup;
			circleBodyDef.Position.Set(5.0f, 6.0f);

			Body body6 = m_world.CreateBody(circleBodyDef);
			body6.CreateFixture(circleShapeDef);
		}
Ejemplo n.º 24
0
        private void DrawShape(Fixture fixture, Transform xf, Color color)
        {
            switch (fixture.GetShapeType())
            {
            case ShapeType.Circle:
            {
                CircleShape circle = (CircleShape)fixture.GetShape();

                Vec2  center = Utilities.Mul(xf, circle.m_p);
                float radius = circle.m_radius;
                Vec2  axis   = Utilities.Mul(xf.q, new Vec2(1.0f, 0.0f));

                m_debugDraw.DrawSolidCircle(center, radius, axis, color);
            }
            break;

            case ShapeType.Edge:
            {
                EdgeShape edge = (EdgeShape)fixture.GetShape();
                Vec2      v1   = Utilities.Mul(xf, edge.m_vertex1);
                Vec2      v2   = Utilities.Mul(xf, edge.m_vertex2);
                m_debugDraw.DrawSegment(v1, v2, color);
            }
            break;

            case ShapeType.Chain:
            {
                ChainShape  chain    = (ChainShape)fixture.GetShape();
                int         count    = chain.m_count;
                List <Vec2> vertices = chain.m_vertices;

                Vec2 v1 = Utilities.Mul(xf, vertices[0]);
                for (int i = 1; i < count; ++i)
                {
                    Vec2 v2 = Utilities.Mul(xf, vertices[i]);
                    m_debugDraw.DrawSegment(v1, v2, color);
                    m_debugDraw.DrawCircle(v1, 0.05f, color);
                    v1 = v2;
                }
            }
            break;

            case ShapeType.Polygon:
            {
                PolygonShape poly        = (PolygonShape)fixture.GetShape();
                int          vertexCount = poly.m_count;
                Utilities.Assert(vertexCount <= Settings._maxPolygonVertices);
                Vec2[] vertices = new Vec2[Settings._maxPolygonVertices];

                for (int i = 0; i < vertexCount; ++i)
                {
                    vertices[i] = Utilities.Mul(xf, poly.m_vertices[i]);
                }

                m_debugDraw.DrawSolidPolygon(vertices, vertexCount, color);
            }
            break;

            default:
                break;
            }
        }
Ejemplo n.º 25
0
		public ApplyForce() {
			m_world.SetGravity(new Vec2(0.0f, 0.0f));

			const float k_restitution = 0.4f;

			Body ground;
			{
				BodyDef bd = new BodyDef();
				bd.Position.Set(0.0f, 20.0f);
				ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();

				FixtureDef sd = new FixtureDef();
				sd.shape = shape;
				sd.Density = 0.0f;
				sd.restitution = k_restitution;

				// Left vertical
				shape.Set(new Vec2(-20.0f, -20.0f), new Vec2(-20.0f, 20.0f));
				ground.CreateFixture(sd);

				// Right vertical
				shape.Set(new Vec2(20.0f, -20.0f), new Vec2(20.0f, 20.0f));
				ground.CreateFixture(sd);

				// Top horizontal
				shape.Set(new Vec2(-20.0f, 20.0f), new Vec2(20.0f, 20.0f));
				ground.CreateFixture(sd);

				// Bottom horizontal
				shape.Set(new Vec2(-20.0f, -20.0f), new Vec2(20.0f, -20.0f));
				ground.CreateFixture(sd);
			}

			{
				Transform xf1 = new Transform();
				xf1.q.Set(0.3524f * (float)Math.PI);
				xf1.p = xf1.q.GetXAxis();

				Vec2[] vertices = new Vec2[3];
				vertices[0] = Utilities.Mul(xf1, new Vec2(-1.0f, 0.0f));
				vertices[1] = Utilities.Mul(xf1, new Vec2(1.0f, 0.0f));
				vertices[2] = Utilities.Mul(xf1, new Vec2(0.0f, 0.5f));

				PolygonShape poly1 = new PolygonShape();
				poly1.Set(vertices, 3);

				FixtureDef sd1 = new FixtureDef();
				sd1.shape = poly1;
				sd1.Density = 4.0f;

				Transform xf2 = new Transform();
				xf2.q.Set(-0.3524f * (float)Math.PI);
				xf2.p = -xf2.q.GetXAxis();

				vertices[0] = Utilities.Mul(xf2, new Vec2(-1.0f, 0.0f));
				vertices[1] = Utilities.Mul(xf2, new Vec2(1.0f, 0.0f));
				vertices[2] = Utilities.Mul(xf2, new Vec2(0.0f, 0.5f));

				PolygonShape poly2 = new PolygonShape();
				poly2.Set(vertices, 3);

				FixtureDef sd2 = new FixtureDef();
				sd2.shape = poly2;
				sd2.Density = 2.0f;

				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.angularDamping = 5.0f;
				bd.linearDamping = 0.1f;

				bd.Position.Set(0.0f, 2.0f);
				bd.angle = (float)Math.PI;
				bd.allowSleep = false;
				m_body = m_world.CreateBody(bd);
				m_body.CreateFixture(sd1);
				m_body.CreateFixture(sd2);
			}

			{
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.5f, 0.5f);

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 1.0f;
				fd.friction = 0.3f;

				for (int i = 0; i < 10; ++i) {
					BodyDef bd = new BodyDef();
					bd.type = BodyType._dynamicBody;

					bd.Position.Set(0.0f, 5.0f + 1.54f * i);
					Body body = m_world.CreateBody(bd);

					body.CreateFixture(fd);

					float gravity = 10.0f;
					float I = body.GetInertia();
					float mass = body.GetMass();

					// For a circle: I = 0.5 * m * r * r ==> r = sqrt(2 * I / m)
					float radius = (float)Math.Sqrt(2.0f * I / mass);

					FrictionJointDef jd = new FrictionJointDef();
					jd.localAnchorA.SetZero();
					jd.localAnchorB.SetZero();
					jd.bodyA = ground;
					jd.bodyB = body;
					jd.collideConnected = true;
					jd.maxForce = mass * gravity;
					jd.maxTorque = mass * radius * gravity;

					m_world.CreateJoint(jd);
				}
			}
		}
Ejemplo n.º 26
0
		public Car()
		{		
			m_hz = 4.0f;
			m_zeta = 0.7f;
			m_speed = 50.0f;

			Body ground = null;
			{
				BodyDef bd = new BodyDef();
				ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 0.0f;
				fd.friction = 0.6f;

				shape.Set(new Vec2(-20.0f, 0.0f), new Vec2(20.0f, 0.0f));
				ground.CreateFixture(fd);

				float[] hs = new float[]{0.25f, 1.0f, 4.0f, 0.0f, 0.0f, -1.0f, -2.0f, -2.0f, -1.25f, 0.0f};

				float x = 20.0f, y1 = 0.0f, dx = 5.0f;

				for (int i = 0; i < 10; ++i)
				{
					float y2 = hs[i];
					shape.Set(new Vec2(x, y1), new Vec2(x + dx, y2));
					ground.CreateFixture(fd);
					y1 = y2;
					x += dx;
				}

				for (int i = 0; i < 10; ++i)
				{
					float y2 = hs[i];
					shape.Set(new Vec2(x, y1), new Vec2(x + dx, y2));
					ground.CreateFixture(fd);
					y1 = y2;
					x += dx;
				}

				shape.Set(new Vec2(x, 0.0f), new Vec2(x + 40.0f, 0.0f));
				ground.CreateFixture(fd);

				x += 80.0f;
				shape.Set(new Vec2(x, 0.0f), new Vec2(x + 40.0f, 0.0f));
				ground.CreateFixture(fd);

				x += 40.0f;
				shape.Set(new Vec2(x, 0.0f), new Vec2(x + 10.0f, 5.0f));
				ground.CreateFixture(fd);

				x += 20.0f;
				shape.Set(new Vec2(x, 0.0f), new Vec2(x + 40.0f, 0.0f));
				ground.CreateFixture(fd);

				x += 40.0f;
				shape.Set(new Vec2(x, 0.0f), new Vec2(x, 20.0f));
				ground.CreateFixture(fd);
			}

			// Teeter
			{
				BodyDef bd = new BodyDef();
				bd.Position.Set(140.0f, 1.0f);
				bd.type = BodyType._dynamicBody;
				Body body = m_world.CreateBody(bd);

				PolygonShape box = new PolygonShape();
				box.SetAsBox(10.0f, 0.25f);
				box.Density = 1;
				body.CreateFixture(box);

				RevoluteJointDef jd = new RevoluteJointDef();
				jd.Initialize(ground, body, body.GetPosition());
				jd.lowerAngle = -8.0f * (float)Math.PI / 180.0f;
				jd.upperAngle = 8.0f * (float)Math.PI / 180.0f;
				jd.enableLimit = true;
				m_world.CreateJoint(jd);

				body.ApplyAngularImpulse(100.0f, true);
			}

			// Bridge
			{
				int N = 20;
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(1.0f, 0.125f);

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 1.0f;
				fd.friction = 0.6f;

				RevoluteJointDef jd = new RevoluteJointDef();

				Body prevBody = ground;
				for (int i = 0; i < N; ++i)
				{
					BodyDef bd = new BodyDef();
					bd.type = BodyType._dynamicBody;
					bd.Position.Set(161.0f + 2.0f * i, -0.125f);
					Body body = m_world.CreateBody(bd);
					body.CreateFixture(fd);

					Vec2 anchor = new Vec2(160.0f + 2.0f * i, -0.125f);
					jd.Initialize(prevBody, body, anchor);
					m_world.CreateJoint(jd);

					prevBody = body;
				}

				Vec2 anchor2 = new Vec2(160.0f + 2.0f * N, -0.125f);
				jd.Initialize(prevBody, ground, anchor2);
				m_world.CreateJoint(jd);
			}

			// Boxes
			{
				PolygonShape box = new PolygonShape();
				box.SetAsBox(0.5f, 0.5f);
				box.Density = 0.5f;

				Body body = null;
				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;

				bd.Position.Set(230.0f, 0.5f);
				body = m_world.CreateBody(bd);
				body.CreateFixture(box);

				bd.Position.Set(230.0f, 1.5f);
				body = m_world.CreateBody(bd);
				body.CreateFixture(box);

				bd.Position.Set(230.0f, 2.5f);
				body = m_world.CreateBody(bd);
				body.CreateFixture(box);

				bd.Position.Set(230.0f, 3.5f);
				body = m_world.CreateBody(bd);
				body.CreateFixture(box);

				bd.Position.Set(230.0f, 4.5f);
				body = m_world.CreateBody(bd);
				body.CreateFixture(box);
			}

			// Car
			{
				PolygonShape chassis = new PolygonShape();
				Vec2[] vertices = new Vec2[8];
				vertices[0].Set(-1.5f, -0.5f);
				vertices[1].Set(1.5f, -0.5f);
				vertices[2].Set(1.5f, 0.0f);
				vertices[3].Set(0.0f, 0.9f);
				vertices[4].Set(-1.15f, 0.9f);
				vertices[5].Set(-1.5f, 0.2f);
				chassis.Set(vertices, 6);

				CircleShape circle = new CircleShape();
				circle.m_radius = 0.4f;

				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(0.0f, 1.0f);
				m_car = m_world.CreateBody(bd);
				m_car.CreateFixture(chassis);

				FixtureDef fd = new FixtureDef();
				fd.shape = circle;
				fd.Density = 1.0f;
				fd.friction = 0.9f;

				bd.Position.Set(-1.0f, 0.35f);
				m_wheel1 = m_world.CreateBody(bd);
				m_wheel1.CreateFixture(fd);

				bd.Position.Set(1.0f, 0.4f);
				m_wheel2 = m_world.CreateBody(bd);
				m_wheel2.CreateFixture(fd);

				WheelJointDef jd = new WheelJointDef();
				Vec2 axis = new Vec2(0.0f, 1.0f);

				jd.Initialize(m_car, m_wheel1, m_wheel1.GetPosition(), axis);
				jd.motorSpeed = 0.0f;
				jd.maxMotorTorque = 20.0f;
				jd.enableMotor = true;
				jd.frequencyHz = m_hz;
				jd.dampingRatio = m_zeta;
				m_spring1 = (WheelJoint)m_world.CreateJoint(jd);

				jd.Initialize(m_car, m_wheel2, m_wheel2.GetPosition(), axis);
				jd.motorSpeed = 0.0f;
				jd.maxMotorTorque = 10.0f;
				jd.enableMotor = false;
				jd.frequencyHz = m_hz;
				jd.dampingRatio = m_zeta;
				m_spring2 = (WheelJoint)m_world.CreateJoint(jd);
			}
		}
Ejemplo n.º 27
0
		// Algorithm:
		// 1. Classify v1 and v2
		// 2. Classify polygon centroid as front or back
		// 3. Flip normal if necessary
		// 4. Initialize normal range to [-pi, pi] about face normal
		// 5. Adjust normal range according to adjacent edges
		// 6. Visit each separating axes, only accept axes within the range
		// 7. Return if _any_ axis indicates separation
		// 8. Clip
		public void Collide(out Manifold manifold, EdgeShape edgeA, Transform xfA, PolygonShape polygonB, Transform xfB){
			manifold = new Manifold();
			m_xf = Utilities.MulT(xfA, xfB);
	
			m_centroidB = Utilities.Mul(m_xf, polygonB.m_centroid);
	
			m_v0 = edgeA.m_vertex0;
			m_v1 = edgeA.m_vertex1;
			m_v2 = edgeA.m_vertex2;
			m_v3 = edgeA.m_vertex3;
	
			bool hasVertex0 = edgeA.m_hasVertex0;
			bool hasVertex3 = edgeA.m_hasVertex3;
	
			Vec2 edge1 = m_v2 - m_v1;
			edge1.Normalize();
			m_normal1.Set(edge1.Y, -edge1.X);
			float offset1 = Utilities.Dot(m_normal1, m_centroidB - m_v1);
			float offset0 = 0.0f, offset2 = 0.0f;
			bool convex1 = false, convex2 = false;
	
			// Is there a preceding edge?
			if (hasVertex0)
			{
				Vec2 edge0 = m_v1 - m_v0;
				edge0.Normalize();
				m_normal0.Set(edge0.Y, -edge0.X);
				convex1 = Utilities.Cross(edge0, edge1) >= 0.0f;
				offset0 = Utilities.Dot(m_normal0, m_centroidB - m_v0);
			}
	
			// Is there a following edge?
			if (hasVertex3)
			{
				Vec2 edge2 = m_v3 - m_v2;
				edge2.Normalize();
				m_normal2.Set(edge2.Y, -edge2.X);
				convex2 = Utilities.Cross(edge1, edge2) > 0.0f;
				offset2 = Utilities.Dot(m_normal2, m_centroidB - m_v2);
			}
	
			// Determine front or back collision. Determine collision normal limits.
			if (hasVertex0 && hasVertex3)
			{
				if (convex1 && convex2)
				{
					m_front = offset0 >= 0.0f || offset1 >= 0.0f || offset2 >= 0.0f;
					if (m_front)
					{
						m_normal = m_normal1;
						m_lowerLimit = m_normal0;
						m_upperLimit = m_normal2;
					}
					else
					{
						m_normal = -m_normal1;
						m_lowerLimit = -m_normal1;
						m_upperLimit = -m_normal1;
					}
				}
				else if (convex1)
				{
					m_front = offset0 >= 0.0f || (offset1 >= 0.0f && offset2 >= 0.0f);
					if (m_front)
					{
						m_normal = m_normal1;
						m_lowerLimit = m_normal0;
						m_upperLimit = m_normal1;
					}
					else
					{
						m_normal = -m_normal1;
						m_lowerLimit = -m_normal2;
						m_upperLimit = -m_normal1;
					}
				}
				else if (convex2)
				{
					m_front = offset2 >= 0.0f || (offset0 >= 0.0f && offset1 >= 0.0f);
					if (m_front)
					{
						m_normal = m_normal1;
						m_lowerLimit = m_normal1;
						m_upperLimit = m_normal2;
					}
					else
					{
						m_normal = -m_normal1;
						m_lowerLimit = -m_normal1;
						m_upperLimit = -m_normal0;
					}
				}
				else
				{
					m_front = offset0 >= 0.0f && offset1 >= 0.0f && offset2 >= 0.0f;
					if (m_front)
					{
						m_normal = m_normal1;
						m_lowerLimit = m_normal1;
						m_upperLimit = m_normal1;
					}
					else
					{
						m_normal = -m_normal1;
						m_lowerLimit = -m_normal2;
						m_upperLimit = -m_normal0;
					}
				}
			}
			else if (hasVertex0)
			{
				if (convex1)
				{
					m_front = offset0 >= 0.0f || offset1 >= 0.0f;
					if (m_front)
					{
						m_normal = m_normal1;
						m_lowerLimit = m_normal0;
						m_upperLimit = -m_normal1;
					}
					else
					{
						m_normal = -m_normal1;
						m_lowerLimit = m_normal1;
						m_upperLimit = -m_normal1;
					}
				}
				else
				{
					m_front = offset0 >= 0.0f && offset1 >= 0.0f;
					if (m_front)
					{
						m_normal = m_normal1;
						m_lowerLimit = m_normal1;
						m_upperLimit = -m_normal1;
					}
					else
					{
						m_normal = -m_normal1;
						m_lowerLimit = m_normal1;
						m_upperLimit = -m_normal0;
					}
				}
			}
			else if (hasVertex3)
			{
				if (convex2)
				{
					m_front = offset1 >= 0.0f || offset2 >= 0.0f;
					if (m_front)
					{
						m_normal = m_normal1;
						m_lowerLimit = -m_normal1;
						m_upperLimit = m_normal2;
					}
					else
					{
						m_normal = -m_normal1;
						m_lowerLimit = -m_normal1;
						m_upperLimit = m_normal1;
					}
				}
				else
				{
					m_front = offset1 >= 0.0f && offset2 >= 0.0f;
					if (m_front)
					{
						m_normal = m_normal1;
						m_lowerLimit = -m_normal1;
						m_upperLimit = m_normal1;
					}
					else
					{
						m_normal = -m_normal1;
						m_lowerLimit = -m_normal2;
						m_upperLimit = m_normal1;
					}
				}		
			}
			else
			{
				m_front = offset1 >= 0.0f;
				if (m_front)
				{
					m_normal = m_normal1;
					m_lowerLimit = -m_normal1;
					m_upperLimit = -m_normal1;
				}
				else
				{
					m_normal = -m_normal1;
					m_lowerLimit = m_normal1;
					m_upperLimit = m_normal1;
				}
			}
	
			// Get polygonB in frameA
			m_polygonB.count = polygonB.m_count;
			for (int i = 0; i < polygonB.m_count; ++i)
			{
				m_polygonB.vertices[i] = Utilities.Mul(m_xf, polygonB.m_vertices[i]);
				m_polygonB.normals[i] = Utilities.Mul(m_xf.q, polygonB.m_normals[i]);
			}
	
			m_radius = 2.0f * Settings._polygonRadius;

			manifold.points.Clear();
	
			EPAxis edgeAxis = ComputeEdgeSeparation();
	
			// If no valid normal can be found than this edge should not collide.
			if (edgeAxis.type == EPAxisType.e_unknown)
			{
				return;
			}
	
			if (edgeAxis.separation > m_radius)
			{
				return;
			}
	
			EPAxis polygonAxis = ComputePolygonSeparation();
			if (polygonAxis.type != EPAxisType.e_unknown && polygonAxis.separation > m_radius)
			{
				return;
			}
	
			// Use hysteresis for jitter reduction.
			const float k_relativeTol = 0.98f;
			const float k_absoluteTol = 0.001f;
	
			EPAxis primaryAxis;
			if (polygonAxis.type == EPAxisType.e_unknown)
			{
				primaryAxis = edgeAxis;
			}
			else if (polygonAxis.separation > k_relativeTol * edgeAxis.separation + k_absoluteTol)
			{
				primaryAxis = polygonAxis;
			}
			else
			{
				primaryAxis = edgeAxis;
			}
	
			ClipVertex[] ie = new ClipVertex[2];
			ReferenceFace rf = new ReferenceFace();
			if (primaryAxis.type == EPAxisType.e_edgeA)
			{
				manifold.type = Manifold.ManifoldType.e_faceA;
		
				// Search for the polygon normal that is most anti-parallel to the edge normal.
				int bestIndex = 0;
				float bestValue = Utilities.Dot(m_normal, m_polygonB.normals[0]);
				for (int i = 1; i < m_polygonB.count; ++i)
				{
					float value = Utilities.Dot(m_normal, m_polygonB.normals[i]);
					if (value < bestValue)
					{
						bestValue = value;
						bestIndex = i;
					}
				}
		
				int i1 = bestIndex;
				int i2 = i1 + 1 < m_polygonB.count ? i1 + 1 : 0;
		
				ie[0].v = m_polygonB.vertices[i1];
				ie[0].id.cf.indexA = 0;
				ie[0].id.cf.indexB = (byte)i1;
				ie[0].id.cf.typeA = ContactFeature.FeatureType.e_face;
				ie[0].id.cf.typeB = ContactFeature.FeatureType.e_vertex;
		
				ie[1].v = m_polygonB.vertices[i2];
				ie[1].id.cf.indexA = 0;
				ie[1].id.cf.indexB = (byte)i2;
				ie[1].id.cf.typeA = ContactFeature.FeatureType.e_face;
				ie[1].id.cf.typeB = ContactFeature.FeatureType.e_vertex;
		
				if (m_front)
				{
					rf.i1 = 0;
					rf.i2 = 1;
					rf.v1 = m_v1;
					rf.v2 = m_v2;
					rf.normal = m_normal1;
				}
				else
				{
					rf.i1 = 1;
					rf.i2 = 0;
					rf.v1 = m_v2;
					rf.v2 = m_v1;
					rf.normal = -m_normal1;
				}		
			}
			else
			{
				manifold.type = Manifold.ManifoldType.e_faceB;
		
				ie[0].v = m_v1;
				ie[0].id.cf.indexA = 0;
				ie[0].id.cf.indexB = (byte)primaryAxis.index;
				ie[0].id.cf.typeA = ContactFeature.FeatureType.e_vertex;
				ie[0].id.cf.typeB = ContactFeature.FeatureType.e_face;
		
				ie[1].v = m_v2;
				ie[1].id.cf.indexA = 0;
				ie[1].id.cf.indexB = (byte)primaryAxis.index;		
				ie[1].id.cf.typeA = ContactFeature.FeatureType.e_vertex;
				ie[1].id.cf.typeB = ContactFeature.FeatureType.e_face;
		
				rf.i1 = primaryAxis.index;
				rf.i2 = rf.i1 + 1 < m_polygonB.count ? rf.i1 + 1 : 0;
				rf.v1 = m_polygonB.vertices[rf.i1];
				rf.v2 = m_polygonB.vertices[rf.i2];
				rf.normal = m_polygonB.normals[rf.i1];
			}
	
			rf.sideNormal1.Set(rf.normal.Y, -rf.normal.X);
			rf.sideNormal2 = -rf.sideNormal1;
			rf.sideOffset1 = Utilities.Dot(rf.sideNormal1, rf.v1);
			rf.sideOffset2 = Utilities.Dot(rf.sideNormal2, rf.v2);
	
			// Clip incident edge against extruded edge1 side edges.
			ClipVertex[] clipPoints1 = new ClipVertex[2];
			ClipVertex[] clipPoints2 = new ClipVertex[2];
			int np;
	
			// Clip to box side 1
			np = Collision.ClipSegmentToLine(clipPoints1, ie, rf.sideNormal1, rf.sideOffset1, rf.i1);
	
			if (np < Settings._maxManifoldPoints)
			{
				return;
			}
	
			// Clip to negative box side 1
			np = Collision.ClipSegmentToLine(clipPoints2, clipPoints1, rf.sideNormal2, rf.sideOffset2, rf.i2);
	
			if (np < Settings._maxManifoldPoints)
			{
				return;
			}
	
			// Now clipPoints2 contains the clipped points.
			if (primaryAxis.type == EPAxisType.e_edgeA)
			{
				manifold.localNormal = rf.normal;
				manifold.localPoint = rf.v1;
			}
			else
			{
				manifold.localNormal = polygonB.m_normals[rf.i1];
				manifold.localPoint = polygonB.m_vertices[rf.i1];
			}

			manifold.points.Clear();
			for (int i = 0; i < Settings._maxManifoldPoints; ++i)
			{
				float separation;
		
				separation = Utilities.Dot(rf.normal, clipPoints2[i].v - rf.v1);
		
				if (separation <= m_radius)
				{
					ManifoldPoint cp = new ManifoldPoint();
			
					if (primaryAxis.type == EPAxisType.e_edgeA)
					{
						cp.localPoint = Utilities.MulT(m_xf, clipPoints2[i].v);
						cp.id = clipPoints2[i].id;
					}
					else
					{
						cp.localPoint = clipPoints2[i].v;
						cp.id.cf.typeA = clipPoints2[i].id.cf.typeB;
						cp.id.cf.typeB = clipPoints2[i].id.cf.typeA;
						cp.id.cf.indexA = clipPoints2[i].id.cf.indexB;
						cp.id.cf.indexB = clipPoints2[i].id.cf.indexA;
					}

					manifold.points.Add(cp);
				}
			}
		}
Ejemplo n.º 28
0
		public EdgeTest()
		{
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				Vec2 v1 = new Vec2(-10.0f, 0.0f), v2 = new Vec2(-7.0f, -2.0f), v3 = new Vec2(-4.0f, 0.0f);
				Vec2 v4 = new Vec2(0.0f, 0.0f), v5 = new Vec2(4.0f, 0.0f), v6 = new Vec2(7.0f, 2.0f), v7 = new Vec2(10.0f, 0.0f);

				EdgeShape shape = new EdgeShape();

				shape.Set(v1, v2);
				shape.m_hasVertex3 = true;
				shape.m_vertex3 = v3;
				shape.Density = 0;
				ground.CreateFixture(shape);

				shape.Set(v2, v3);
				shape.m_hasVertex0 = true;
				shape.m_hasVertex3 = true;
				shape.m_vertex0 = v1;
				shape.m_vertex3 = v4;
				ground.CreateFixture(shape);

				shape.Set(v3, v4);
				shape.m_hasVertex0 = true;
				shape.m_hasVertex3 = true;
				shape.m_vertex0 = v2;
				shape.m_vertex3 = v5;
				ground.CreateFixture(shape);

				shape.Set(v4, v5);
				shape.m_hasVertex0 = true;
				shape.m_hasVertex3 = true;
				shape.m_vertex0 = v3;
				shape.m_vertex3 = v6;
				ground.CreateFixture(shape);

				shape.Set(v5, v6);
				shape.m_hasVertex0 = true;
				shape.m_hasVertex3 = true;
				shape.m_vertex0 = v4;
				shape.m_vertex3 = v7;
				ground.CreateFixture(shape);

				shape.Set(v6, v7);
				shape.m_hasVertex0 = true;
				shape.m_vertex0 = v5;
				ground.CreateFixture(shape);
			}

			{
				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(-0.5f, 0.6f);
				bd.allowSleep = false;
				Body body = m_world.CreateBody(bd);

				CircleShape shape = new CircleShape();
				shape.m_radius = 0.5f;

				body.CreateFixture(shape);
			}

			{
				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(1.0f, 0.6f);
				bd.allowSleep = false;
				Body body = m_world.CreateBody(bd);

				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.5f, 0.5f);

				body.CreateFixture(shape);
			}
		}
Ejemplo n.º 29
0
        /// Compute the collision manifold between an edge and a circle.
        public static void CollideEdgeAndCircle(out Manifold manifold,
                                                EdgeShape edgeA, Transform xfA,
                                                CircleShape circleB, Transform xfB)
        {
            manifold = new Manifold();

            // Compute circle in frame of edge
            Vec2 Q = Utilities.MulT(xfA, Utilities.Mul(xfB, circleB.m_p));

            Vec2 A = edgeA.m_vertex1, B = edgeA.m_vertex2;
            Vec2 e = B - A;

            // Barycentric coordinates
            float u = Utilities.Dot(e, B - Q);
            float v = Utilities.Dot(e, Q - A);

            float radius = edgeA.m_radius + circleB.m_radius;

            ContactFeature cf;

            cf.indexB = 0;
            cf.typeB  = ContactFeature.FeatureType.e_vertex;

            // Region A
            if (v <= 0.0f)
            {
                Vec2  P  = A;
                Vec2  d  = Q - P;
                float dd = Utilities.Dot(d, d);
                if (dd > radius * radius)
                {
                    return;
                }

                // Is there an edge connected to A?
                if (edgeA.m_hasVertex0)
                {
                    Vec2  A1 = edgeA.m_vertex0;
                    Vec2  B1 = A;
                    Vec2  e1 = B1 - A1;
                    float u1 = Utilities.Dot(e1, B1 - Q);

                    // Is the circle in Region AB of the previous edge?
                    if (u1 > 0.0f)
                    {
                        return;
                    }
                }

                cf.indexA = 0;
                cf.typeA  = ContactFeature.FeatureType.e_vertex;
                manifold.points.Clear();
                manifold.points.Add(new ManifoldPoint());
                manifold.type = Manifold.ManifoldType.e_circles;
                manifold.localNormal.SetZero();
                manifold.localPoint           = P;
                manifold.points[0].id.key     = 0;
                manifold.points[0].id.cf      = cf;
                manifold.points[0].localPoint = circleB.m_p;
                return;
            }

            // Region B
            if (u <= 0.0f)
            {
                Vec2  P  = B;
                Vec2  d  = Q - P;
                float dd = Utilities.Dot(d, d);
                if (dd > radius * radius)
                {
                    return;
                }

                // Is there an edge connected to B?
                if (edgeA.m_hasVertex3)
                {
                    Vec2  B2 = edgeA.m_vertex3;
                    Vec2  A2 = B;
                    Vec2  e2 = B2 - A2;
                    float v2 = Utilities.Dot(e2, Q - A2);

                    // Is the circle in Region AB of the next edge?
                    if (v2 > 0.0f)
                    {
                        return;
                    }
                }

                cf.indexA = 1;
                cf.typeA  = ContactFeature.FeatureType.e_vertex;
                manifold.points.Clear();
                manifold.points.Add(new ManifoldPoint());
                manifold.type = Manifold.ManifoldType.e_circles;
                manifold.localNormal.SetZero();
                manifold.localPoint           = P;
                manifold.points[0].id.key     = 0;
                manifold.points[0].id.cf      = cf;
                manifold.points[0].localPoint = circleB.m_p;
                return;
            }

            // Region AB
            float den = Utilities.Dot(e, e);

            Utilities.Assert(den > 0.0f);
            Vec2  Pb  = (1.0f / den) * (u * A + v * B);
            Vec2  db  = Q - Pb;
            float ddb = Utilities.Dot(db, db);

            if (ddb > radius * radius)
            {
                return;
            }

            Vec2 n = new Vec2(-e.Y, e.X);

            if (Utilities.Dot(n, Q - A) < 0.0f)
            {
                n.Set(-n.X, -n.Y);
            }
            n.Normalize();

            cf.indexA = 0;
            cf.typeA  = ContactFeature.FeatureType.e_face;
            manifold.points.Clear();
            manifold.points.Add(new ManifoldPoint());
            manifold.type                 = Manifold.ManifoldType.e_faceA;
            manifold.localNormal          = n;
            manifold.localPoint           = A;
            manifold.points[0].id.key     = 0;
            manifold.points[0].id.cf      = cf;
            manifold.points[0].localPoint = circleB.m_p;
        }
Ejemplo n.º 30
0
		public PolyShapes()
		{
			// Ground body
			{
				BodyDef bd = new BodyDef();
				Body ground = m_world.CreateBody(bd);

				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			{
				Vec2[] vertices = new Vec2[3];
				vertices[0].Set(-0.5f, 0.0f);
				vertices[1].Set(0.5f, 0.0f);
				vertices[2].Set(0.0f, 1.5f);
				m_polygons[0].Set(vertices, 3);
			}
		
			{
				Vec2[] vertices = new Vec2[3];
				vertices[0].Set(-0.1f, 0.0f);
				vertices[1].Set(0.1f, 0.0f);
				vertices[2].Set(0.0f, 1.5f);
				m_polygons[1].Set(vertices, 3);
			}

			{
				float w = 1.0f;
				float b = w / (2.0f + (float)Math.Sqrt(2.0f));
				float s = (float)Math.Sqrt(2.0f) * b;

				Vec2[] vertices = new Vec2[8];
				vertices[0].Set(0.5f * s, 0.0f);
				vertices[1].Set(0.5f * w, b);
				vertices[2].Set(0.5f * w, b + s);
				vertices[3].Set(0.5f * s, w);
				vertices[4].Set(-0.5f * s, w);
				vertices[5].Set(-0.5f * w, b + s);
				vertices[6].Set(-0.5f * w, b);
				vertices[7].Set(-0.5f * s, 0.0f);

				m_polygons[2].Set(vertices, 8);
			}

			{
				m_polygons[3].SetAsBox(0.5f, 0.5f);
			}

			{
				m_circle.m_radius = 0.5f;
			}

			m_bodyIndex = 0;
			Array.Clear(m_bodies, 0, m_bodies.Length);
		}
Ejemplo n.º 31
0
        // Algorithm:
        // 1. Classify v1 and v2
        // 2. Classify polygon centroid as front or back
        // 3. Flip normal if necessary
        // 4. Initialize normal range to [-pi, pi] about face normal
        // 5. Adjust normal range according to adjacent edges
        // 6. Visit each separating axes, only accept axes within the range
        // 7. Return if _any_ axis indicates separation
        // 8. Clip
        public void Collide(out Manifold manifold, EdgeShape edgeA, Transform xfA, PolygonShape polygonB, Transform xfB)
        {
            manifold = new Manifold();
            m_xf     = Utilities.MulT(xfA, xfB);

            m_centroidB = Utilities.Mul(m_xf, polygonB.m_centroid);

            m_v0 = edgeA.m_vertex0;
            m_v1 = edgeA.m_vertex1;
            m_v2 = edgeA.m_vertex2;
            m_v3 = edgeA.m_vertex3;

            bool hasVertex0 = edgeA.m_hasVertex0;
            bool hasVertex3 = edgeA.m_hasVertex3;

            Vec2 edge1 = m_v2 - m_v1;

            edge1.Normalize();
            m_normal1.Set(edge1.Y, -edge1.X);
            float offset1 = Utilities.Dot(m_normal1, m_centroidB - m_v1);
            float offset0 = 0.0f, offset2 = 0.0f;
            bool  convex1 = false, convex2 = false;

            // Is there a preceding edge?
            if (hasVertex0)
            {
                Vec2 edge0 = m_v1 - m_v0;
                edge0.Normalize();
                m_normal0.Set(edge0.Y, -edge0.X);
                convex1 = Utilities.Cross(edge0, edge1) >= 0.0f;
                offset0 = Utilities.Dot(m_normal0, m_centroidB - m_v0);
            }

            // Is there a following edge?
            if (hasVertex3)
            {
                Vec2 edge2 = m_v3 - m_v2;
                edge2.Normalize();
                m_normal2.Set(edge2.Y, -edge2.X);
                convex2 = Utilities.Cross(edge1, edge2) > 0.0f;
                offset2 = Utilities.Dot(m_normal2, m_centroidB - m_v2);
            }

            // Determine front or back collision. Determine collision normal limits.
            if (hasVertex0 && hasVertex3)
            {
                if (convex1 && convex2)
                {
                    m_front = offset0 >= 0.0f || offset1 >= 0.0f || offset2 >= 0.0f;
                    if (m_front)
                    {
                        m_normal     = m_normal1;
                        m_lowerLimit = m_normal0;
                        m_upperLimit = m_normal2;
                    }
                    else
                    {
                        m_normal     = -m_normal1;
                        m_lowerLimit = -m_normal1;
                        m_upperLimit = -m_normal1;
                    }
                }
                else if (convex1)
                {
                    m_front = offset0 >= 0.0f || (offset1 >= 0.0f && offset2 >= 0.0f);
                    if (m_front)
                    {
                        m_normal     = m_normal1;
                        m_lowerLimit = m_normal0;
                        m_upperLimit = m_normal1;
                    }
                    else
                    {
                        m_normal     = -m_normal1;
                        m_lowerLimit = -m_normal2;
                        m_upperLimit = -m_normal1;
                    }
                }
                else if (convex2)
                {
                    m_front = offset2 >= 0.0f || (offset0 >= 0.0f && offset1 >= 0.0f);
                    if (m_front)
                    {
                        m_normal     = m_normal1;
                        m_lowerLimit = m_normal1;
                        m_upperLimit = m_normal2;
                    }
                    else
                    {
                        m_normal     = -m_normal1;
                        m_lowerLimit = -m_normal1;
                        m_upperLimit = -m_normal0;
                    }
                }
                else
                {
                    m_front = offset0 >= 0.0f && offset1 >= 0.0f && offset2 >= 0.0f;
                    if (m_front)
                    {
                        m_normal     = m_normal1;
                        m_lowerLimit = m_normal1;
                        m_upperLimit = m_normal1;
                    }
                    else
                    {
                        m_normal     = -m_normal1;
                        m_lowerLimit = -m_normal2;
                        m_upperLimit = -m_normal0;
                    }
                }
            }
            else if (hasVertex0)
            {
                if (convex1)
                {
                    m_front = offset0 >= 0.0f || offset1 >= 0.0f;
                    if (m_front)
                    {
                        m_normal     = m_normal1;
                        m_lowerLimit = m_normal0;
                        m_upperLimit = -m_normal1;
                    }
                    else
                    {
                        m_normal     = -m_normal1;
                        m_lowerLimit = m_normal1;
                        m_upperLimit = -m_normal1;
                    }
                }
                else
                {
                    m_front = offset0 >= 0.0f && offset1 >= 0.0f;
                    if (m_front)
                    {
                        m_normal     = m_normal1;
                        m_lowerLimit = m_normal1;
                        m_upperLimit = -m_normal1;
                    }
                    else
                    {
                        m_normal     = -m_normal1;
                        m_lowerLimit = m_normal1;
                        m_upperLimit = -m_normal0;
                    }
                }
            }
            else if (hasVertex3)
            {
                if (convex2)
                {
                    m_front = offset1 >= 0.0f || offset2 >= 0.0f;
                    if (m_front)
                    {
                        m_normal     = m_normal1;
                        m_lowerLimit = -m_normal1;
                        m_upperLimit = m_normal2;
                    }
                    else
                    {
                        m_normal     = -m_normal1;
                        m_lowerLimit = -m_normal1;
                        m_upperLimit = m_normal1;
                    }
                }
                else
                {
                    m_front = offset1 >= 0.0f && offset2 >= 0.0f;
                    if (m_front)
                    {
                        m_normal     = m_normal1;
                        m_lowerLimit = -m_normal1;
                        m_upperLimit = m_normal1;
                    }
                    else
                    {
                        m_normal     = -m_normal1;
                        m_lowerLimit = -m_normal2;
                        m_upperLimit = m_normal1;
                    }
                }
            }
            else
            {
                m_front = offset1 >= 0.0f;
                if (m_front)
                {
                    m_normal     = m_normal1;
                    m_lowerLimit = -m_normal1;
                    m_upperLimit = -m_normal1;
                }
                else
                {
                    m_normal     = -m_normal1;
                    m_lowerLimit = m_normal1;
                    m_upperLimit = m_normal1;
                }
            }

            // Get polygonB in frameA
            m_polygonB.count = polygonB.m_count;
            for (int i = 0; i < polygonB.m_count; ++i)
            {
                m_polygonB.vertices[i] = Utilities.Mul(m_xf, polygonB.m_vertices[i]);
                m_polygonB.normals[i]  = Utilities.Mul(m_xf.q, polygonB.m_normals[i]);
            }

            m_radius = 2.0f * Settings._polygonRadius;

            manifold.points.Clear();

            EPAxis edgeAxis = ComputeEdgeSeparation();

            // If no valid normal can be found than this edge should not collide.
            if (edgeAxis.type == EPAxisType.e_unknown)
            {
                return;
            }

            if (edgeAxis.separation > m_radius)
            {
                return;
            }

            EPAxis polygonAxis = ComputePolygonSeparation();

            if (polygonAxis.type != EPAxisType.e_unknown && polygonAxis.separation > m_radius)
            {
                return;
            }

            // Use hysteresis for jitter reduction.
            const float k_relativeTol = 0.98f;
            const float k_absoluteTol = 0.001f;

            EPAxis primaryAxis;

            if (polygonAxis.type == EPAxisType.e_unknown)
            {
                primaryAxis = edgeAxis;
            }
            else if (polygonAxis.separation > k_relativeTol * edgeAxis.separation + k_absoluteTol)
            {
                primaryAxis = polygonAxis;
            }
            else
            {
                primaryAxis = edgeAxis;
            }

            ClipVertex[]  ie = new ClipVertex[2];
            ReferenceFace rf = new ReferenceFace();

            if (primaryAxis.type == EPAxisType.e_edgeA)
            {
                manifold.type = Manifold.ManifoldType.e_faceA;

                // Search for the polygon normal that is most anti-parallel to the edge normal.
                int   bestIndex = 0;
                float bestValue = Utilities.Dot(m_normal, m_polygonB.normals[0]);
                for (int i = 1; i < m_polygonB.count; ++i)
                {
                    float value = Utilities.Dot(m_normal, m_polygonB.normals[i]);
                    if (value < bestValue)
                    {
                        bestValue = value;
                        bestIndex = i;
                    }
                }

                int i1 = bestIndex;
                int i2 = i1 + 1 < m_polygonB.count ? i1 + 1 : 0;

                ie[0].v            = m_polygonB.vertices[i1];
                ie[0].id.cf.indexA = 0;
                ie[0].id.cf.indexB = (byte)i1;
                ie[0].id.cf.typeA  = ContactFeature.FeatureType.e_face;
                ie[0].id.cf.typeB  = ContactFeature.FeatureType.e_vertex;

                ie[1].v            = m_polygonB.vertices[i2];
                ie[1].id.cf.indexA = 0;
                ie[1].id.cf.indexB = (byte)i2;
                ie[1].id.cf.typeA  = ContactFeature.FeatureType.e_face;
                ie[1].id.cf.typeB  = ContactFeature.FeatureType.e_vertex;

                if (m_front)
                {
                    rf.i1     = 0;
                    rf.i2     = 1;
                    rf.v1     = m_v1;
                    rf.v2     = m_v2;
                    rf.normal = m_normal1;
                }
                else
                {
                    rf.i1     = 1;
                    rf.i2     = 0;
                    rf.v1     = m_v2;
                    rf.v2     = m_v1;
                    rf.normal = -m_normal1;
                }
            }
            else
            {
                manifold.type = Manifold.ManifoldType.e_faceB;

                ie[0].v            = m_v1;
                ie[0].id.cf.indexA = 0;
                ie[0].id.cf.indexB = (byte)primaryAxis.index;
                ie[0].id.cf.typeA  = ContactFeature.FeatureType.e_vertex;
                ie[0].id.cf.typeB  = ContactFeature.FeatureType.e_face;

                ie[1].v            = m_v2;
                ie[1].id.cf.indexA = 0;
                ie[1].id.cf.indexB = (byte)primaryAxis.index;
                ie[1].id.cf.typeA  = ContactFeature.FeatureType.e_vertex;
                ie[1].id.cf.typeB  = ContactFeature.FeatureType.e_face;

                rf.i1     = primaryAxis.index;
                rf.i2     = rf.i1 + 1 < m_polygonB.count ? rf.i1 + 1 : 0;
                rf.v1     = m_polygonB.vertices[rf.i1];
                rf.v2     = m_polygonB.vertices[rf.i2];
                rf.normal = m_polygonB.normals[rf.i1];
            }

            rf.sideNormal1.Set(rf.normal.Y, -rf.normal.X);
            rf.sideNormal2 = -rf.sideNormal1;
            rf.sideOffset1 = Utilities.Dot(rf.sideNormal1, rf.v1);
            rf.sideOffset2 = Utilities.Dot(rf.sideNormal2, rf.v2);

            // Clip incident edge against extruded edge1 side edges.
            ClipVertex[] clipPoints1 = new ClipVertex[2];
            ClipVertex[] clipPoints2 = new ClipVertex[2];
            int          np;

            // Clip to box side 1
            np = Collision.ClipSegmentToLine(clipPoints1, ie, rf.sideNormal1, rf.sideOffset1, rf.i1);

            if (np < Settings._maxManifoldPoints)
            {
                return;
            }

            // Clip to negative box side 1
            np = Collision.ClipSegmentToLine(clipPoints2, clipPoints1, rf.sideNormal2, rf.sideOffset2, rf.i2);

            if (np < Settings._maxManifoldPoints)
            {
                return;
            }

            // Now clipPoints2 contains the clipped points.
            if (primaryAxis.type == EPAxisType.e_edgeA)
            {
                manifold.localNormal = rf.normal;
                manifold.localPoint  = rf.v1;
            }
            else
            {
                manifold.localNormal = polygonB.m_normals[rf.i1];
                manifold.localPoint  = polygonB.m_vertices[rf.i1];
            }

            manifold.points.Clear();
            for (int i = 0; i < Settings._maxManifoldPoints; ++i)
            {
                float separation;

                separation = Utilities.Dot(rf.normal, clipPoints2[i].v - rf.v1);

                if (separation <= m_radius)
                {
                    ManifoldPoint cp = new ManifoldPoint();

                    if (primaryAxis.type == EPAxisType.e_edgeA)
                    {
                        cp.localPoint = Utilities.MulT(m_xf, clipPoints2[i].v);
                        cp.id         = clipPoints2[i].id;
                    }
                    else
                    {
                        cp.localPoint   = clipPoints2[i].v;
                        cp.id.cf.typeA  = clipPoints2[i].id.cf.typeB;
                        cp.id.cf.typeB  = clipPoints2[i].id.cf.typeA;
                        cp.id.cf.indexA = clipPoints2[i].id.cf.indexB;
                        cp.id.cf.indexB = clipPoints2[i].id.cf.indexA;
                    }

                    manifold.points.Add(cp);
                }
            }
        }
Ejemplo n.º 32
0
		/// Get a child edge.
		public void GetChildEdge(out EdgeShape edge, int index){
			throw new NotImplementedException();
			//Utilities.Assert(0 <= index && index < m_count - 1);
			//edge.m_type = ShapeType.edge;
			//edge.m_radius = m_radius;

			//edge.m_vertex1 = m_vertices[index + 0];
			//edge.m_vertex2 = m_vertices[index + 1];

			//if (index > 0)
			//{
			//    edge.m_vertex0 = m_vertices[index - 1];
			//    edge.m_hasVertex0 = true;
			//}
			//else
			//{
			//    edge.m_vertex0 = m_prevVertex;
			//    edge.m_hasVertex0 = m_hasPrevVertex;
			//}

			//if (index < m_count - 2)
			//{
			//    edge.m_vertex3 = m_vertices[index + 2];
			//    edge.m_hasVertex3 = true;
			//}
			//else
			//{
			//    edge.m_vertex3 = m_nextVertex;
			//    edge.m_hasVertex3 = m_hasNextVertex;
			//}
		}
Ejemplo n.º 33
0
		public Dominos()
		{
			Body b1;
			{
				EdgeShape shape = new EdgeShape();
				shape.Set(new Vec2(-40.0f, 0.0f), new Vec2(40.0f, 0.0f));
				shape.Density = 0;

				BodyDef bd = new BodyDef();
				b1 = m_world.CreateBody(bd);
				b1.CreateFixture(shape);
			}

			{
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(6.0f, 0.25f);

				BodyDef bd = new BodyDef();
				bd.Position.Set(-1.5f, 10.0f);
				Body ground = m_world.CreateBody(bd);
				shape.Density = 0;
				ground.CreateFixture(shape);
			}

			{
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.1f, 1.0f);

				FixtureDef fd = new FixtureDef();
				fd.shape = shape;
				fd.Density = 20.0f;
				fd.friction = 0.1f;

				for (int i = 0; i < 10; ++i)
				{
					BodyDef bd = new BodyDef();
					bd.type = BodyType._dynamicBody;
					bd.Position.Set(-6.0f + 1.0f * i, 11.25f);
					Body body = m_world.CreateBody(bd);
					body.CreateFixture(fd);
				}
			}

			{
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(7.0f, 0.25f, new Vec2(0, 0), 0.3f);
				shape.Density = 0;

				BodyDef bd = new BodyDef();
				bd.Position.Set(1.0f, 6.0f);
				Body ground = m_world.CreateBody(bd);
				ground.CreateFixture(shape);
			}

			Body b2;
			{
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.25f, 1.5f);
				shape.Density = 0;

				BodyDef bd = new BodyDef();
				bd.Position.Set(-7.0f, 4.0f);
				b2 = m_world.CreateBody(bd);
				b2.CreateFixture(shape);
			}

			Body b3;
			{
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(6.0f, 0.125f);
				shape.Density = 10;

				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(-0.9f, 1.0f);
				bd.angle = -0.15f;

				b3 = m_world.CreateBody(bd);
				b3.CreateFixture(shape);
			}

			RevoluteJointDef jd = new RevoluteJointDef();
			Vec2 anchor = new Vec2();

			anchor.Set(-2.0f, 1.0f);
			jd.Initialize(b1, b3, anchor);
			jd.collideConnected = true;
			m_world.CreateJoint(jd);

			Body b4;
			{
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.25f, 0.25f);

				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(-10.0f, 15.0f);
				b4 = m_world.CreateBody(bd);
				shape.Density = 10;
				shape.Density = 10;
				b4.CreateFixture(shape);
			}

			anchor.Set(-7.0f, 15.0f);
			jd.Initialize(b2, b4, anchor);
			m_world.CreateJoint(jd);

			Body b5;
			{
				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(6.5f, 3.0f);
				b5 = m_world.CreateBody(bd);

				PolygonShape shape = new PolygonShape();
				FixtureDef fd = new FixtureDef();

				fd.shape = shape;
				fd.Density = 10.0f;
				fd.friction = 0.1f;

				shape.SetAsBox(1.0f, 0.1f, new Vec2(0.0f, -0.9f), 0.0f);
				b5.CreateFixture(fd);

				shape.SetAsBox(0.1f, 1.0f, new Vec2(-0.9f, 0.0f), 0.0f);
				b5.CreateFixture(fd);

				shape.SetAsBox(0.1f, 1.0f, new Vec2(0.9f, 0.0f), 0.0f);
				b5.CreateFixture(fd);
			}

			anchor.Set(6.0f, 2.0f);
			jd.Initialize(b1, b5, anchor);
			m_world.CreateJoint(jd);

			Body b6;
			{
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(1.0f, 0.1f);

				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(6.5f, 4.1f);
				b6 = m_world.CreateBody(bd);
				shape.Density = 30;
				b6.CreateFixture(shape);
			}

			anchor.Set(7.5f, 4.0f);
			jd.Initialize(b5, b6, anchor);
			m_world.CreateJoint(jd);

			Body b7;
			{
				PolygonShape shape = new PolygonShape();
				shape.SetAsBox(0.1f, 1.0f);

				BodyDef bd = new BodyDef();
				bd.type = BodyType._dynamicBody;
				bd.Position.Set(7.4f, 1.0f);

				b7 = m_world.CreateBody(bd);
				shape.Density = 10;
				b7.CreateFixture(shape);
			}

			DistanceJointDef djd = new DistanceJointDef();
			djd.bodyA = b3;
			djd.bodyB = b7;
			djd.localAnchorA.Set(6.0f, 0.0f);
			djd.localAnchorB.Set(0.0f, -1.0f);
			Vec2 d = djd.bodyB.GetWorldPoint(djd.localAnchorB) - djd.bodyA.GetWorldPoint(djd.localAnchorA);
			djd.length = d.Length();
			m_world.CreateJoint(djd);

			{
				float radius = 0.2f;

				CircleShape shape = new CircleShape();
				shape.m_radius = radius;

				for (int i = 0; i < 4; ++i)
				{
					BodyDef bd = new BodyDef();
					bd.type = BodyType._dynamicBody;
					bd.Position.Set(5.9f + 2.0f * radius * i, 2.4f);
					Body body = m_world.CreateBody(bd);
					shape.Density = 10;
					body.CreateFixture(shape);
				}
			}
		}