This project has moved and is read-only. For the latest updates, please go here.

Changing the Centroid

Topics: Developer Forum, User Forum
Aug 28, 2013 at 4:17 AM
Edited Sep 5, 2013 at 4:53 AM
-->Added video : .

Hi, I have different objects in my game (for now only pillars and arches) where you can combine them with each other to make a full gate. I delete one shape and add a fixture to the other body.
It works fine as far as the looks go but the centroid of the body doesn't change when the fixture is added. So I can't change the pivot for proper rotation.
Also the position is a little offset now since it's measured from the centroid.
I've read that a possible way is that to delete both objects and have one body created that encompasses both off the start (as opposed to adding a fixture of to the other existing body).
Does any one know of an alternative way to change the centroid after the addition of the fixture? (Just to avoid added complexities as much as I can).


Just to have some code in there, here is the function that's in charge of merging, for now I only merge pillars which have the same shape and density so it's kind of tailor made for now. As you see in the commented lines I've tried many ways to no avail yet.
      public static void MergeBodies(Core.DetailedSprite d1,Core.DetailedSprite d2,Objects.Specializing_Classes.Breakable.Joint[] j1,
            Objects.Specializing_Classes.Breakable.Joint[] j2,Vector2 joinOffset)
            //Matrix rotation = Matrix.CreateRotationZ(d1.Rotation);
            //Objects.Specializing_Classes.Breakable.Joint j = new Objects.Specializing_Classes.Breakable.Joint();
            //foreach (Objects.Specializing_Classes.Breakable.Joint join in j1)
            //    if (join.IsConnected)
            //        j = join;
            PolygonShape s1 = (PolygonShape)d1.body.FixtureList[0].Shape;
            //d1.body.CreateFixture(new PolygonShape(s1.Vertices, d1.Density));

            Vector2 offset = joinOffset;
            if (d2.Shape == Utilities.Constants.Shapes.Rectangle)
                //FixtureFactory.AttachRectangle(d2.DimentionsToFarseer.X, d2.DimentionsToFarseer.Y, d2.Density,
                //   Vector2.Transform(offset, rotation) * Utilities.Constants.PixelsToFarseer, d1.body);
                Vertices n1PartVert = PolygonTools.CreateRectangle(d1.DimentionsToFarseer.X / 2, d1.DimentionsToFarseer.Y);
                Vertices n2PartVert = PolygonTools.CreateRectangle(d2.DimentionsToFarseer.X/2, d2.DimentionsToFarseer.Y, offset * Utilities.Constants.PixelsToFarseer
                    , 0);
                //foreach (Vector2 v in s1.Vertices)
                //    nPartVert.Add(v);
                PolygonShape n1PartShape = new PolygonShape(n1PartVert, d1.Density);
                PolygonShape n2PartShape = new PolygonShape(n2PartVert, d2.Density);
                //List<Vertices> cVerts = FarseerPhysics.Common.Decomposition.BayazitDecomposer.ConvexPartition(nPartVert);
              //  d1.body.CreateFixture(nPartShape);
                //d1.body = BodyFactory.CreateCompoundPolygon(, cVerts, d1.Density + d2.Density);
            //PolygonShape s2 = (PolygonShape)d2.body.FixtureList[1].Shape;


            //d1.body.ApplyForce(new Vector2(.01f));
            d1.extraTextures.Add(new KeyValuePair<Texture2D,Rectangle>(d2.Texture,d2.frames[1]));
And here is where I draw stuff:
  public new void Draw(SpriteBatch spritebatch)
            if (IsAlive)
                Color c = Color.Lerp(base.Color, Color.Red, (isHooked) ? 1 : 0);
                spritebatch.Draw(base.Texture, this.Position, base.Source,c * base.Opacity, Rotation, base.Pivot, new Vector2(1), SpriteEffects.None, 0f);
                if (extraTextures.Count > 0)
                    for (int i = 0; i < extraTextures.Count; i++)
                        spritebatch.Draw(extraTextures[i].Key, this.Position, extraTextures[i].Value, c * base.Opacity,
                            Rotation, base.Pivot - 2*Offsets[i], new Vector2(1), SpriteEffects.FlipVertically, 0f);

                string s = this.Position.ToString();
                spritebatch.DrawString(Game1.objectPositionFont, s, this.Position - Game1.objectPositionFont.MeasureString(s) / 2, Color.Blue);
                //spritebatch.DrawString(Game1.objectPositionFont, HookedCoord.ToString(), this.Position - Game1.objectPositionFont.MeasureString(HookedCoord.ToString()) / 2, Color.Blue);

If these help in any way at all.

Please see the video for visuals.