public static void calculateBounds( ref Rectangle rect, Vector2 parentPosition, Vector2 position, Vector2 origin, Vector2 scale, float rotation, float width, float height )
{
if( rotation == 0f )
{
rect.X = (int)( parentPosition.X + position.X - origin.X * scale.X );
rect.Y = (int)( parentPosition.Y + position.Y - origin.Y * scale.Y );
rect.Width = (int)( width * scale.X );
rect.Height = (int)( height * scale.Y );
}
else
{
// special care for rotated bounds. we need to find our absolute min/max values and create the bounds from that
var worldPosX = parentPosition.X + position.X;
var worldPosY = parentPosition.Y + position.Y;
Matrix2D tempMat;
// set the reference point to world reference taking origin into account
var transformMatrix = Matrix2D.createTranslation( -worldPosX - origin.X, -worldPosY - origin.Y );
Matrix2D.createScale( scale.X, scale.Y, out tempMat ); // scale ->
Matrix2D.multiply( ref transformMatrix, ref tempMat, out transformMatrix );
Matrix2D.createRotation( rotation, out tempMat ); // rotate ->
Matrix2D.multiply( ref transformMatrix, ref tempMat, out transformMatrix );
Matrix2D.createTranslation( worldPosX, worldPosY, out tempMat ); // translate back
Matrix2D.multiply( ref transformMatrix, ref tempMat, out transformMatrix );
// TODO: this is a bit silly. we can just leave the worldPos translation in the Matrix and avoid this
// get all four corners in world space
var topLeft = new Vector2( worldPosX, worldPosY );
var topRight = new Vector2( worldPosX + width, worldPosY );
var bottomLeft = new Vector2( worldPosX, worldPosY + height );
var bottomRight = new Vector2( worldPosX + width, worldPosY + height );
// transform the corners into our work space
Vector2Ext.transform( ref topLeft, ref transformMatrix, out topLeft );
Vector2Ext.transform( ref topRight, ref transformMatrix, out topRight );
Vector2Ext.transform( ref bottomLeft, ref transformMatrix, out bottomLeft );
Vector2Ext.transform( ref bottomRight, ref transformMatrix, out bottomRight );
// find the min and max values so we can concoct our bounding box
var minX = (int)Mathf.minOf( topLeft.X, bottomRight.X, topRight.X, bottomLeft.X );
var maxX = (int)Mathf.maxOf( topLeft.X, bottomRight.X, topRight.X, bottomLeft.X );
var minY = (int)Mathf.minOf( topLeft.Y, bottomRight.Y, topRight.Y, bottomLeft.Y );
var maxY = (int)Mathf.maxOf( topLeft.Y, bottomRight.Y, topRight.Y, bottomLeft.Y );
rect.Location = new Point( minX, minY );
rect.Width = (int)( maxX - minX );
rect.Height = (int)( maxY - minY );
}
}