I've got this implemented on my world editor. I can group sprites together and rotate them or scale them as a group around an arbitrary origin (which in my case is also the center of the group). I use something like this:
// Origin should be supplied in World-Space
void RotateGroup(IEnumerable<Sprite> sprites, Vector2 origin, float angle)
{
Matrix transform = Matrix.CreateTranslation(-origin.X, -origin.Y, 0f) *
Matrix.CreateRotationZ(angle) *
Matrix.CreateTranslation(origin.X, origin.Y, 0f);
foreach(Sprite sprite in sprites)
{
sprite.Position = Vector2.Transform(sprite.Position, transform);
sprite.Rotation += angle;
}
}
// Origin should be supplied in World-Space
void RotateGroup(IEnumerable<Sprite> sprites, Vector2 origin, float angle)
{
Matrix transform = Matrix.CreateTranslation(-origin.X, -origin.Y, 0f) *
Matrix.CreateRotationZ(angle) *
Matrix.CreateTranslation(origin.X, origin.Y, 0f);
foreach(Sprite sprite in sprites)
{
sprite.Position = Vector2.Transform(sprite.Position, transform);
sprite.Rotation += angle;
}
}
I simply call this method when I want to rotate my group as a whole, and the method calculates a new position and rotation for each sprite in order to give the illusion that they are changing as a group.
Most importantly, I don't pass any special matrix to my drawing function. Each sprite still has its own individual position, rotation and origin which are independent from them being in a group or not.
This means that the group's origin is conceptual, and simply changing that value won't mess up with your sprites. The value is only used when rotating the group in order to specify where the pivot should be, but not when drawing. So
In sum, the only matrix you should be passing to SpriteBatch.Begin is your viewView matrix, nothing else, and each. Each sprite should be drawn according to its usualindividual properties, and if you'd like to rotate them as a group, play around those properties, not around the drawing code.