I'm having a problem in Monogame/XNA where I am storing the position/rotation/scale in a matrix for easier manipulation of these values with parenting. It all seems to be going well, except for when I rotate the matrix, which is when the object seems to jitter around and shake. Here is the relevant code:
// Executes every frame
internal void Draw()
{
float RadRot = MathHelper.ToRadians(Rotation);
// Sets world matrix for things that draw
if (Parent != null) {
WorldMatrix = Matrix.CreateScale(Size.X, Size.Y, 1) * -Matrix.CreateTranslation(Pivot.X, Pivot.Y, 0) * Matrix.CreateRotationZ(RadRot);
WorldMatrix.Translation = Vector3.Zero; // Rotating seems to create a strange positioning issue, this fixes it
WorldMatrix *= Matrix.CreateTranslation(RelativePosition.X, RelativePosition.Y, 0) * Matrix.CreateRotationZ(MathHelper.ToRadians(Parent.Rotation)) * <FIX JITTER> * Matrix.CreateTranslation(Parent.DecomposedPosition.X, Parent.DecomposedPosition.Y, 0);
} else
{
// For objects without parents
WorldMatrix = Matrix.CreateScale(RelativeSize.X, RelativeSize.Y, 1) * -Matrix.CreateTranslation(Pivot.X, Pivot.Y, 0) * Matrix.CreateRotationZ(RadRot);
WorldMatrix.Translation = Vector3.Zero; // This fixes the jitter issue, but in the code above (in the if statement), I can't do this when translating the child around the parent
WorldMatrix *= Matrix.CreateTranslation(RelativePosition.X, RelativePosition.Y, 0);
}
Vector3 TempPos = Vector3.Zero;
Quaternion TempRot = Quaternion.Identity;
Vector3 TempSize = Vector3.Zero;
WorldMatrix.Decompose(out TempSize, out TempRot, out TempPos);
DecomposedPosition = new Vector2(-TempPos.X, -TempPos.Y);
DecomposedRotation = MathHelper.ToRadians(Rotation); // Can't convert quaternions, but this works
DecomposedSize = new Vector2(MathF.Round(TempSize.X), MathF.Round(TempSize.Y));
foreach (Component2D comp in Components)
{
comp.Draw();
}
}
This is what comp.Draw calls:
MyGame.SpriteDrawing.Draw(Image, new Rectangle(LinkedObject.DecomposedPosition.ToPoint(), LinkedObject.DecomposedSize.ToPoint()), RenderRegion, Color, LinkedObject.DecomposedRotation, LinkedObject.Pivot, SpriteEffects.None, LinkedObject.Layer + (SubLayer / 10000));
Here is what it looks like in action:
EXTRA NOTE: This jittering does occur no matter the scale of the objects
It seems that I was simply using the wrong SpriteBatch.Draw()
. I was using the Rectangle version, whereas all I needed was to use the Vector2 version to prevent rounding errors.
MyGame.SpriteDrawing.Draw(Image, LinkedObject.DecomposedPosition, RenderRegion, Color, LinkedObject.DecomposedRotation, LinkedObject.Pivot * RenderRegion.Size.ToVector2(), LinkedObject.DecomposedSize / RenderRegion.Size.ToVector2(), SpriteEffects.None, LinkedObject.Layer + (SubLayer / 10000));