A chain shape is a free form sequence of line segments. The chain has two-sided collision, so you can use inside and outside collision. Therefore, you may use any winding order. Connectivity information is used to create smooth collisions. WARNING: The chain will not collide properly if there are self-intersections.
Наследование: Shape
Пример #1
0
        public CoolRibbonObject(World world, Texture2D tex)
        {
            points = new List<Vector2>();

            points.Add(new Vector2(4, -1));
            points.Add(new Vector2(4, 22));
            points.Add(new Vector2(30, 22));
            points.Add(new Vector2(30, -1));

            stops = new float[4];

            for(int i = 0; i < points.Count-1; i++)
            {
                stops[i] = Vector2.Distance(points[i],points[i+1]);
            }

            body = BodyFactory.CreateBody(world);
            body.BodyType = BodyType.Static;
            body.Position = new Vector2(0,0);
            body.UserData = this;

            hinges = new List<Hinge>();

            AddBox(world, tex);

            ChainShape chain = new ChainShape(new Vertices(points));

            fixture = body.CreateFixture(chain);
        }
Пример #2
0
        public override Shape Clone()
        {
            ChainShape clone = new ChainShape();

            clone._density      = this._density;
            clone._radius       = this._radius;
            clone.PrevVertex    = this.PrevVertex;
            clone.NextVertex    = this.NextVertex;
            clone.HasNextVertex = this.HasNextVertex;
            clone.HasPrevVertex = this.HasPrevVertex;
            clone.Vertices      = this.Vertices;
            clone.MassData      = this.MassData;
            return(clone);
        }
Пример #3
0
        public override Shape Clone()
        {
            var clone = new ChainShape();

            clone.ShapeType      = ShapeType;
            clone._density       = _density;
            clone._radius        = _radius;
            clone.PrevVertex     = _prevVertex;
            clone.NextVertex     = _nextVertex;
            clone._hasNextVertex = _hasNextVertex;
            clone._hasPrevVertex = _hasPrevVertex;
            clone.Vertices       = new Vertices(Vertices);
            clone.MassData       = MassData;
            return(clone);
        }
Пример #4
0
        public override Shape clone()
        {
            var clone = new ChainShape();

            clone.shapeType      = shapeType;
            clone._density       = _density;
            clone._radius        = _radius;
            clone.prevVertex     = _prevVertex;
            clone.nextVertex     = _nextVertex;
            clone._hasNextVertex = _hasNextVertex;
            clone._hasPrevVertex = _hasPrevVertex;
            clone.vertices       = new Vertices(vertices);
            clone.massData       = massData;
            return(clone);
        }
Пример #5
0
		//Contributed by Matthew Bettcher

		/// <summary>
		/// Convert a path into a set of edges and attaches them to the specified body.
		/// Note: use only for static edges.
		/// </summary>
		/// <param name="path">The path.</param>
		/// <param name="body">The body.</param>
		/// <param name="subdivisions">The subdivisions.</param>
		public static void convertPathToEdges( Path path, Body body, int subdivisions )
		{
			var verts = path.getVertices( subdivisions );
			if( path.isClosed )
			{
				var chain = new ChainShape( verts, true );
				body.createFixture( chain );
			}
			else
			{
				for( int i = 1; i < verts.Count; i++ )
				{
					body.createFixture( new EdgeShape( verts[i], verts[i - 1] ) );
				}
			}
		}
Пример #6
0
        /// <summary>
        /// Compare the chain to another chain
        /// </summary>
        /// <param name="shape">The other chain</param>
        /// <returns>True if the two chain shapes are the same</returns>
        public bool CompareTo(ChainShape shape)
        {
            if (Vertices.Count != shape.Vertices.Count)
            {
                return(false);
            }

            for (int i = 0; i < Vertices.Count; i++)
            {
                if (Vertices[i] != shape.Vertices[i])
                {
                    return(false);
                }
            }

            return(PrevVertex == shape.PrevVertex && NextVertex == shape.NextVertex);
        }
Пример #7
0
        /// <summary>
        /// Compare the chain to another chain
        /// </summary>
        /// <param name="shape">The other chain</param>
        /// <returns>True if the two chain shapes are the same</returns>
        public bool CompareTo(ChainShape shape)
        {
            if (vertices.Count != shape.vertices.Count)
            {
                return(false);
            }

            for (int i = 0; i < vertices.Count; i++)
            {
                if (vertices[i] != shape.vertices[i])
                {
                    return(false);
                }
            }

            return(prevVertex == shape.prevVertex && nextVertex == shape.nextVertex);
        }
Пример #8
0
        //Contributed by Matthew Bettcher
        /// <summary>
        /// Convert a path into a set of edges and attaches them to the specified body.
        /// Note: use only for static edges.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <param name="body">The body.</param>
        /// <param name="subdivisions">The subdivisions.</param>
        public static void ConvertPathToEdges(Path path, Body body, int subdivisions)
        {
            Vertices verts = path.GetVertices(subdivisions);

            if (path.Closed)
            {
                ChainShape chain = new ChainShape(verts);
                body.CreateFixture(chain);
            }
            else
            {
                for (int i = 1; i < verts.Count; i++)
                {
                    body.CreateFixture(new EdgeShape(verts[i], verts[i - 1]));
                }
            }
        }
Пример #9
0
 public static Fixture AttachLoopShape(Vertices vertices, Body body, object userData = null)
 {
     ChainShape shape = new ChainShape(vertices, true);
     return body.CreateFixture(shape, userData);
 }
Пример #10
0
 public override Shape Clone()
 {
     ChainShape loop = new ChainShape();
     loop._density = _density;
     loop._radius = _radius;
     loop.Vertices = Vertices;
     loop.MassData = MassData;
     return loop;
 }
Пример #11
0
        private PinballTest()
        {
            // Ground body
            Body ground;
            {
                ground = BodyFactory.CreateBody(World);

                Vertices vertices = new Vertices(5);
                vertices.Add(new Vector2(0.0f, -2.0f));
                vertices.Add(new Vector2(8.0f, 6.0f));
                vertices.Add(new Vector2(8.0f, 20.0f));
                vertices.Add(new Vector2(-8.0f, 20.0f));
                vertices.Add(new Vector2(-8.0f, 6.0f));

                ChainShape chain = new ChainShape(vertices, true);
                ground.CreateFixture(chain);
            }

            // Flippers
            {
                Vector2 p1 = new Vector2(-2.0f, 0f);
                Vector2 p2 = new Vector2(2.0f, 0f);

                Body leftFlipper = BodyFactory.CreateBody(World, p1);
                leftFlipper.BodyType = BodyType.Dynamic;
                Body rightFlipper = BodyFactory.CreateBody(World, p2);
                rightFlipper.BodyType = BodyType.Dynamic;

                PolygonShape box = new PolygonShape(1);
                box.Vertices = PolygonTools.CreateRectangle(1.75f, 0.1f);

                leftFlipper.CreateFixture(box);
                rightFlipper.CreateFixture(box);

                _leftJoint = new RevoluteJoint(ground, leftFlipper, p1, Vector2.Zero);
                _leftJoint.MaxMotorTorque = 1000.0f;
                _leftJoint.LimitEnabled = true;
                _leftJoint.MotorEnabled = true;
                _leftJoint.MotorSpeed = 0.0f;
                _leftJoint.LowerLimit = -30.0f * Settings.Pi / 180.0f;
                _leftJoint.UpperLimit = 5.0f * Settings.Pi / 180.0f;
                World.AddJoint(_leftJoint);

                _rightJoint = new RevoluteJoint(ground, rightFlipper, p2, Vector2.Zero);
                _rightJoint.MaxMotorTorque = 1000.0f;
                _rightJoint.LimitEnabled = true;
                _rightJoint.MotorEnabled = true;
                _rightJoint.MotorSpeed = 0.0f;
                _rightJoint.LowerLimit = -5.0f * Settings.Pi / 180.0f;
                _rightJoint.UpperLimit = 30.0f * Settings.Pi / 180.0f;
                World.AddJoint(_rightJoint);
            }

            // Circle character
            {
                _ball = BodyFactory.CreateBody(World, new Vector2(1.0f, 15.0f));
                _ball.BodyType = BodyType.Dynamic;
                _ball.IsBullet = true;
                _ball.CreateFixture(new CircleShape(0.2f, 1.0f));
            }
        }
Пример #12
0
		/// <summary>
		/// Compare the chain to another chain
		/// </summary>
		/// <param name="shape">The other chain</param>
		/// <returns>True if the two chain shapes are the same</returns>
		public bool CompareTo( ChainShape shape )
		{
			if( vertices.Count != shape.vertices.Count )
				return false;

			for( int i = 0; i < vertices.Count; i++ )
			{
				if( vertices[i] != shape.vertices[i] )
					return false;
			}

			return prevVertex == shape.prevVertex && nextVertex == shape.nextVertex;
		}
Пример #13
0
		Fixture j2b2Fixture(Body body, JObject fixtureValue)
		{
			
			
			if (null == fixtureValue)
				return null;
			
			
			//Fixture fixtureDef = new Fixture();
			var restitution = jsonToFloat("restitution", fixtureValue);
			var friction = jsonToFloat("friction", fixtureValue);
			var density = jsonToFloat("density", fixtureValue);
			var isSensor = fixtureValue["sensor"] == null ? false : (bool)fixtureValue["sensor"];
			
			
			var categoryBits = fixtureValue["filter-categoryBits"] == null ? 0x0001 : (int)fixtureValue["filter-categoryBits"];
			var maskBits = fixtureValue["filter-maskBits"] == null ? 0xffff : (int)fixtureValue["filter-maskBits"];
			var groupIndex = fixtureValue["filter-groupIndex"] == null ? (short)0 : (short)fixtureValue["filter-groupIndex"];
			
			
			Fixture fixture = null;
			
			
			
			if (null != fixtureValue["circle"])
			{
				JObject circleValue = (JObject)fixtureValue["circle"];
				var radius = jsonToFloat("radius", circleValue);
				var position = jsonToVec("center", circleValue);
				fixture = FixtureFactory.AttachCircle(radius, density, body, position);
			}
			else if (null != fixtureValue["edge"])
			{
				JObject edgeValue = (JObject)fixtureValue["edge"];
				var m_vertex1 = (jsonToVec("vertex1", edgeValue));
				var m_vertex2 = (jsonToVec("vertex2", edgeValue));
				fixture = FixtureFactory.AttachEdge(m_vertex1, m_vertex2, body);
				((EdgeShape)fixture.Shape).HasVertex0 = edgeValue["hasVertex0"] == null ? false : (bool)edgeValue["hasVertex0"];
				((EdgeShape)fixture.Shape).HasVertex3 = edgeValue["hasVertex3"] == null ? false : (bool)edgeValue["hasVertex3"];
				
				if (((EdgeShape)fixture.Shape).HasVertex0)
					((EdgeShape)fixture.Shape).Vertex0 = (jsonToVec("vertex0", edgeValue));
				if (((EdgeShape)fixture.Shape).HasVertex3)
					((EdgeShape)fixture.Shape).Vertex3 = (jsonToVec("vertex3", edgeValue));
				
			}
			else if (null != fixtureValue["loop"])
			{// support old
				// format (r197)
				JObject chainValue = (JObject)fixtureValue["loop"];
				int numVertices = ((JArray)chainValue["x"]).Count;
				Vertices vertices = new Vertices();
				for (int i = 0; i < numVertices; i++)
					vertices.Add(jsonToVec("vertices", chainValue, i));
				fixture = FixtureFactory.AttachChainShape(vertices, body);
				
			}
			else if (null != fixtureValue["chain"])
			{
				JObject chainValue = (JObject)fixtureValue["chain"];
				ChainShape chainShape = new ChainShape();
				int numVertices = ((JArray)chainValue["vertices"]["x"]).Count;
				
				Vertices vertices = new Vertices();
				
				
				for (int i = 0; i < numVertices; i++)
					vertices.Add(jsonToVec("vertices", chainValue, i));
				
				// FPE. See http://www.box2d.org/forum/viewtopic.php?f=4&t=7973&p=35363
				if (vertices[0] == vertices[vertices.Count - 1])
				{
					var vertices2 = new Vertices(numVertices - 1);
					vertices2.AddRange(vertices.GetRange(0, numVertices - 1));
					chainShape.CreateLoop(vertices2);
					fixture = body.CreateFixture(chainShape);
				}
				else
					fixture = FixtureFactory.AttachChainShape(vertices, body);
				
				var fixtureChain = fixture.Shape as ChainShape;
				
				var hasPrevVertex = chainValue["hasPrevVertex"] == null ? false : (bool)chainValue["hasPrevVertex"];
				var hasNextVertex = chainValue["hasNextVertex"] == null ? false : (bool)chainValue["hasNextVertex"];
				if (hasPrevVertex)
					fixtureChain.PrevVertex = (jsonToVec("prevVertex", chainValue));
				if (hasNextVertex)
					fixtureChain.NextVertex = (jsonToVec("nextVertex", chainValue));
				
			}
			else if (null != fixtureValue["polygon"])
			{
				JObject polygonValue = (JObject)fixtureValue["polygon"];
				Vertices vertices = new Vertices();
				int numVertices = ((JArray)polygonValue["vertices"]["x"]).Count;
				if (numVertices > Settings.MaxPolygonVertices)
				{
					Console.WriteLine("Ignoring polygon fixture with too many vertices.");
				}
				else if (numVertices < 2)
				{
					Console.WriteLine("Ignoring polygon fixture less than two vertices.");
				}
				else if (numVertices == 2)
				{
					Console.WriteLine("Creating edge shape instead of polygon with two vertices.");
					var m_vertex1 = (jsonToVec("vertices", polygonValue, 0));
					var m_vertex2 = (jsonToVec("vertices", polygonValue, 1));
					fixture = FixtureFactory.AttachEdge(m_vertex1, m_vertex2, body);
					
				}
				else
				{
					for (int i = 0; i < numVertices; i++)
						vertices.Add(jsonToVec("vertices", polygonValue, i));
					fixture = FixtureFactory.AttachPolygon(vertices, density, body);
				}
			}
			
			String fixtureName = fixtureValue["name"] == null ? "" : fixtureValue["name"].ToString();
			if (fixtureName != "")
			{
				SetFixtureName(fixture, fixtureName);
			}
			
			if (fixture != null)
			{
				fixture.Restitution = restitution;
				fixture.Friction = friction;
				fixture.Shape.Density = density;
				fixture.IsSensor = isSensor;
				fixture.CollisionCategories = (Category)categoryBits;
				fixture.CollidesWith = (Category)maskBits;
				fixture.CollisionGroup = groupIndex;
			}
			
			
			return fixture;
		}
Пример #14
0
		public override Shape clone()
		{
			var clone = new ChainShape();
			clone.shapeType = shapeType;
			clone._density = _density;
			clone._radius = _radius;
			clone.prevVertex = _prevVertex;
			clone.nextVertex = _nextVertex;
			clone._hasNextVertex = _hasNextVertex;
			clone._hasPrevVertex = _hasPrevVertex;
			clone.vertices = new Vertices( vertices );
			clone.massData = massData;
			return clone;
		}
Пример #15
0
        /// <summary>
        /// Removes the old terrain physics bodies and replaces them with new ones,
        /// generated from the given terrain.
        /// </summary>
        public void UpdateTerrainBody(Terrain terrain)
        {
            Terrain = terrain;
            foreach (var body in TerrainBodies)
            {
                var fixtures = body.FixtureList.ToArray();
                foreach (var fixture in fixtures)
                {
                    fixture.Dispose();
                }

                body.Dispose();
            }

            TerrainBodies.Clear();

            // Update the terrain explicitly
            terrain.Update();
            var outlines = terrain.GetOutline();
            
            foreach (var outline in outlines)
            {
                var vertices = new Vector2[outline.Count];

                for (int i = 0; i < outline.Count; i++)
                {
                    vertices[i] = outline[i] * terrain.Scale;
                }

                var shape = new ChainShape(new Vertices(vertices));

                var body = new Body(PhysicsWorld);
                body.BodyType = BodyType.Static;
                body.Friction = 1.0f;
                body.CreateFixture(shape);

                TerrainBodies.Add(body);
            }
        }
Пример #16
0
        private void UpdateVertices(ChainShape shape, float scale)
        {
            if (this.vertices == null || this.vertices.Length < 3) return;

            if (shape.Vertices == null)
                shape.Vertices = new Vertices();
            else
                shape.Vertices.Clear();

            for (int i = 0; i < this.vertices.Length; i++)
            {
                shape.Vertices.Add(PhysicsUnit.LengthToPhysical * this.vertices[i] * scale);
            }
            shape.MakeLoop();
        }
Пример #17
0
		public static Fixture AttachChainShape( Vertices vertices, Body body, object userData = null )
		{
			var shape = new ChainShape( vertices );
			return body.createFixture( shape, userData );
		}
        private CharacterCollisionTest()
        {
            //Ground body
            Body ground = BodyFactory.CreateEdge(World, new Vector2(-40.0f, 0.0f), new Vector2(40.0f, 0.0f));

            // Collinear edges
            EdgeShape shape = new EdgeShape(new Vector2(-8.0f, 1.0f), new Vector2(-6.0f, 1.0f));
            ground.CreateFixture(shape);
            shape = new EdgeShape(new Vector2(-6.0f, 1.0f), new Vector2(-4.0f, 1.0f));
            ground.CreateFixture(shape);
            shape = new EdgeShape(new Vector2(-4.0f, 1.0f), new Vector2(-2.0f, 1.0f));
            ground.CreateFixture(shape);

            // Square tiles
            PolygonShape tile = new PolygonShape(1);
            tile.SetAsBox(1.0f, 1.0f, new Vector2(4.0f, 3.0f), 0.0f);
            ground.CreateFixture(tile);
            tile.SetAsBox(1.0f, 1.0f, new Vector2(6.0f, 3.0f), 0.0f);
            ground.CreateFixture(tile);
            tile.SetAsBox(1.0f, 1.0f, new Vector2(8.0f, 3.0f), 0.0f);
            ground.CreateFixture(tile);

            // Square made from an edge chain.
            Vertices vertices = new Vertices(4);
            vertices.Add(new Vector2(-1.0f, 3.0f));
            vertices.Add(new Vector2(1.0f, 3.0f));
            vertices.Add(new Vector2(1.0f, 5.0f));
            vertices.Add(new Vector2(-1.0f, 5.0f));
            ChainShape chainShape = new ChainShape(vertices);
            ground.CreateFixture(chainShape);

            // Edge chain.
            vertices = new Vertices(10);
            vertices.Add(new Vector2(0.0f, 0.0f));
            vertices.Add(new Vector2(6.0f, 0.0f));
            vertices.Add(new Vector2(6.0f, 2.0f));
            vertices.Add(new Vector2(4.0f, 1.0f));
            vertices.Add(new Vector2(2.0f, 2.0f));
            vertices.Add(new Vector2(-2.0f, 2.0f));
            vertices.Add(new Vector2(-4.0f, 3.0f));
            vertices.Add(new Vector2(-6.0f, 2.0f));
            vertices.Add(new Vector2(-6.0f, 0.0f));

            BodyFactory.CreateChainShape(World, vertices, new Vector2(-10, 4));

            // Square character
            Body squareCharacter = BodyFactory.CreateRectangle(World, 1, 1, 20);
            squareCharacter.Position = new Vector2(-3.0f, 5.0f);
            squareCharacter.BodyType = BodyType.Dynamic;
            squareCharacter.FixedRotation = true;
            squareCharacter.SleepingAllowed = false;

            squareCharacter.OnCollision += CharacterOnCollision;
            squareCharacter.OnSeparation += CharacterOnSeparation;

            // Square character 2
            Body squareCharacter2 = BodyFactory.CreateRectangle(World, 0.5f, 0.5f, 20);
            squareCharacter2.Position = new Vector2(-5.0f, 5.0f);
            squareCharacter2.BodyType = BodyType.Dynamic;
            squareCharacter2.FixedRotation = true;
            squareCharacter2.SleepingAllowed = false;

            // Hexagon character
            float angle = 0.0f;
            const float delta = Settings.Pi / 3.0f;
            vertices = new Vertices(6);

            for (int i = 0; i < 6; ++i)
            {
                vertices.Add(new Vector2(0.5f * (float)Math.Cos(angle), 0.5f * (float)Math.Sin(angle)));
                angle += delta;
            }

            Body hexCharacter = BodyFactory.CreatePolygon(World, vertices, 20);
            hexCharacter.Position = new Vector2(-5.0f, 8.0f);
            hexCharacter.BodyType = BodyType.Dynamic;
            hexCharacter.FixedRotation = true;
            hexCharacter.SleepingAllowed = false;

            // Circle character
            Body circleCharacter = BodyFactory.CreateCircle(World, 0.5f, 20);
            circleCharacter.Position = new Vector2(3.0f, 5.0f);
            circleCharacter.BodyType = BodyType.Dynamic;
            circleCharacter.FixedRotation = true;
            circleCharacter.SleepingAllowed = false;
        }
Пример #19
0
        /// <summary>
        /// Compare the chain to another chain
        /// </summary>
        /// <param name="shape">The other chain</param>
        /// <returns>True if the two chain shapes are the same</returns>
        public bool CompareTo(ChainShape shape)
        {
            if (Vertices.Count != shape.Vertices.Count)
                return false;

            for (int i = 0; i < Vertices.Count; i++)
            {
                if (Vertices[i] != shape.Vertices[i])
                    return false;
            }

            return PrevVertex == shape.PrevVertex && NextVertex == shape.NextVertex;
        }
Пример #20
0
 public override Shape Clone()
 {
     ChainShape clone = new ChainShape();
     clone.ShapeType = ShapeType;
     clone._density = _density;
     clone._radius = _radius;
     clone.PrevVertex = _prevVertex;
     clone.NextVertex = _nextVertex;
     clone._hasNextVertex = _hasNextVertex;
     clone._hasPrevVertex = _hasPrevVertex;
     clone.Vertices = new Vertices(Vertices);
     clone.MassData = MassData;
     return clone;
 }
Пример #21
0
        /// <summary>
        /// Makes a set of vertices for the chain shape 
        /// by creating two offset vertices perpendicular 
        /// to the averaged direction from the current vertex
        /// and it's two connected vertices. Returned vertices 
        /// are in counterclockwise order
        /// </summary>
        /// <param name="chain">chain shape to work on</param>
        /// <returns>new Triangularizable Vertices for chain shape</returns>
        private static Vertices CreateChainVertices(ChainShape chain)
        {
            Matrix rotMat = Matrix.CreateRotationZ(MathHelper.PiOver2);
            Vertices chainTextVerts = new Vertices(chain.Vertices.Count * 2);
            List<Vector2> posChainTextVerts = new List<Vector2>(chain.Vertices.Count);
            List<Vector2> negChainTextVerts = new List<Vector2>(chain.Vertices.Count);
            for (int i = 0; i < chain.Vertices.Count; i++)
            {
                var curVertex = chain.Vertices[i];
                Vector2 direction = Vector2.Zero;
                Vector2 distance = Vector2.Zero;
                if (i == 0)
                {
                    distance = chain.Vertices[i + 1] - curVertex;
                }
                else if (i < chain.Vertices.Count - 1)
                {
                    distance = (chain.Vertices[i + 1] - curVertex) + (curVertex - chain.Vertices[i - 1]);
                }
                else
                {
                    distance = curVertex - chain.Vertices[i - 1];
                }

                direction = Vector2.Normalize(Vector2.Transform(distance, rotMat)).ToSimUnits();
                posChainTextVerts.Add(curVertex + (direction * 2f));
                negChainTextVerts.Insert(0, curVertex - (direction * 2f));
            }

            chainTextVerts.AddRange(posChainTextVerts);
            chainTextVerts.AddRange(negChainTextVerts);

            return chainTextVerts;
        }
Пример #22
0
        protected override Fixture CreateFixture(Body body)
        {
            if (!body.IsStatic) return null; // Loop shapes aren't allowed on nonstatic bodies.
            if (this.vertices == null || this.vertices.Length < 3) return null;

            this.Parent.CheckValidTransform();

            ChainShape shape = new ChainShape();
            this.UpdateVertices(shape, 1.0f);
            Fixture f = body.CreateFixture(shape, this);

            this.Parent.CheckValidTransform();
            return f;
        }