Hi,
I've been toying around with the XNA runtime and due to the way my rendering code is set up I'm not able to easily integrate the existing SkeletonRenderer. All my drawing is done between a single Begin and End using the camera position / zoom as the transform.
Here's the SpriteBatch extension method I have so far. It's based on the "XNA/MonoGame with content pipeline" third-party runtime. Does anyone notice anything wrong with it?
public static void Draw(this SpriteBatch spriteBatch, Skeleton skeleton, Vector2 position, float rotation, Vector2 scale,
Color tintColor, bool flipHorizontal, bool flipVertical)
{
SpriteEffects spriteEffects = SpriteEffects.None;
if(flipHorizontal) { spriteEffects |= SpriteEffects.FlipHorizontally; }
if(flipVertical) { spriteEffects |= SpriteEffects.FlipVertically; }
// Draw individual components
for (int i = 0, n = skeleton.DrawOrder.Count; i < n; i++)
{
Slot slot = skeleton.DrawOrder[i];
RegionAttachment regionAttachment = slot.Attachment as RegionAttachment;
if (regionAttachment != null)
{
AtlasRegion region = regionAttachment.RendererObject as AtlasRegion;
byte r = (byte)(skeleton.R * slot.R * 255);
byte g = (byte)(skeleton.G * slot.G * 255);
byte b = (byte)(skeleton.B * slot.B * 255);
byte a = (byte)(skeleton.A * slot.A * 255);
float offsetX = (regionAttachment.Offset[X1] + regionAttachment.Offset[X3]) / 2;
float offsetY = (regionAttachment.Offset[Y1] + regionAttachment.Offset[Y3]) / 2;
spriteBatch.Draw(region.page.rendererObject as Texture2D,
new Vector2(
(offsetX * slot.Bone.M00) + (offsetY * slot.Bone.M01) + (slot.Bone.WorldX + skeleton.X),
(offsetX * slot.Bone.M10) + (offsetY * slot.Bone.M11) + (slot.Bone.WorldY + skeleton.Y)
),
new Rectangle(region.x, region.y, region.width, region.height),
new Color(r * tintColor.R, g * tintColor.G, b * tintColor.B, a * tintColor.A),
-(slot.Bone.WorldRotation + regionAttachment.Rotation + rotation) * 3.14159f / 180.0f,
new Vector2(region.width * 0.5f, region.height * 0.5f),
new Vector2(slot.Bone.WorldScaleX * scale.X * regionAttachment.ScaleX,
slot.Bone.WorldScaleY * scale.Y * regionAttachment.ScaleY),
spriteEffects, 0.0f);
}
}
And the result... As you can see in the second image, some of the images (parts of the arms and legs) have the incorrect rotation compared to how they are displayed in Spine (first image).
I'm also unsure if the following is the proper way to flip the animation or not. This is done in an Update method.
m_Skeleton.FlipX = (m_FacingDirection == HorizontalDirection.Left);
m_Skeleton.FlipY = false;
m_AnimationState.Update(gameTime.ElapsedGameTime.Milliseconds * 0.001f * gameSpeed);
m_AnimationState.Apply(m_Skeleton);
m_Skeleton.UpdateWorldTransform();
Thank you.