I've been writing Spriter integration into my own engine, and I think I've discovered and solved an error in the reference.
The issue lies in the applying of a parent's transform onto child bones:
SpatialInfo unmapFromParent(SpatialInfo parentInfo)
The current implementation of this function doesn't support non-uniform scaling values, and doesn't support the "flipping" of sprites via a negative scaling. I've found a fix on this forum for the latter, but the former I couldn't find any solution for. I've managed to solve the issue myself, so I would recommend anyone implementing the reference to use this version instead:
SpatialInfo unmapFromParent(SpatialInfo parentInfo)
{
SpatialInfo unmappedObj = this;
if (parentInfo.scaleX * parentInfo.scaleY < 0)
{
unmappedObj.angle = (360 - unmappedObj.angle) + parentInfo.angle;
}
else
{
unmappedObj.angle = unmappedObj.angle + parentInfo.angle;
}
unmappedObj.scaleX *= parentInfo.scaleX;
unmappedObj.scaleY *= parentInfo.scaleY;
unmappedObj.a *= parentInfo.a;
if (x != 0 || y != 0)
{
// Negate angle if the sprite is "flipped"
float angle = parentInfo.scaleX * parentInfo.scaleY < 0 ? -parentInfo.angle : parentInfo.angle;
float s = sin(toRadians(angle));
float c = cos(toRadians(angle));
unmappedObj.x = parentInfo.scaleX * ((x * c) - (y * s));
unmappedObj.y = parentInfo.scaleY * ((x * s) + (y * c));
unmappedObj.x += parentInfo.x;
unmappedObj.y += parentInfo.y;
}
else
{
// Mandatory optimization for future features
unmappedObj.x = parentInfo.x;
unmappedObj.y = parentInfo.y;
}
return unmappedObj;
}
Hope this saves someone a lot of time and frustration.
This solution sadly doesn't preserve the Sprite structure when rotating and using non-uniform scaling at the same time. However, I've tested every other case and it works. I would imagine a perfect solution would scale the root bone around the axis of rotation, and leave the rest of the child rotations untouched, but I haven't gotten it to work yet.