public static Rectangle GetBounds(GameObject obj, VxlFile vxl, HvaFile hva, DrawProperties props)
{
vxl.Initialize();
hva.Initialize();
float direction = (obj is OwnableObject) ? (obj as OwnableObject).Direction : 0;
float objectRotation = 45f - direction / 256f * 360f; // convert game rotation to world degrees
var world = Matrix4.CreateRotationX(MathHelper.DegreesToRadians(60));
world = Matrix4.CreateRotationZ(MathHelper.DegreesToRadians(objectRotation)) * world; // object facing
world = Matrix4.Scale(0.25f, 0.25f, 0.25f) * world;
// art.ini TurretOffset value positions some voxel parts over our x-axis
world = Matrix4.CreateTranslation(0.18f * props.TurretVoxelOffset, 0, 0) * world;
var camera = Matrix4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(30), 1f, 1, 100);
world = world * camera;
Rectangle ret = Rectangle.Empty;
foreach (var section in vxl.Sections) {
var frameRot = hva.LoadGLMatrix(section.Index);
frameRot.M41 *= section.HVAMultiplier * section.ScaleX;
frameRot.M42 *= section.HVAMultiplier * section.ScaleY;
frameRot.M43 *= section.HVAMultiplier * section.ScaleZ;
var minbounds = new Vector3(section.MinBounds);
if (props.HasShadow)
minbounds.Z = -100;
var frameTransl = Matrix4.CreateTranslation(minbounds);
var frame = frameTransl * frameRot * world;
// floor rect of the bounding box
Vector3 floorTopLeft = new Vector3(0, 0, 0);
Vector3 floorTopRight = new Vector3(section.SpanX, 0, 0);
Vector3 floorBottomRight = new Vector3(section.SpanX, section.SpanY, 0);
Vector3 floorBottomLeft = new Vector3(0, section.SpanY, 0);
// ceil rect of the bounding box
Vector3 ceilTopLeft = new Vector3(0, 0, section.SpanZ);
Vector3 ceilTopRight = new Vector3(section.SpanX, 0, section.SpanZ);
Vector3 ceilBottomRight = new Vector3(section.SpanX, section.SpanY, section.SpanZ);
Vector3 ceilBottomLeft = new Vector3(0, section.SpanY, section.SpanZ);
// apply transformations
floorTopLeft = Vector3.Transform(floorTopLeft, frame);
floorTopRight = Vector3.Transform(floorTopRight, frame);
floorBottomRight = Vector3.Transform(floorBottomRight, frame);
floorBottomLeft = Vector3.Transform(floorBottomLeft, frame);
ceilTopLeft = Vector3.Transform(ceilTopLeft, frame);
ceilTopRight = Vector3.Transform(ceilTopRight, frame);
ceilBottomRight = Vector3.Transform(ceilBottomRight, frame);
ceilBottomLeft = Vector3.Transform(ceilBottomLeft, frame);
int FminX = (int)Math.Floor(Math.Min(Math.Min(Math.Min(floorTopLeft.X, floorTopRight.X), floorBottomRight.X), floorBottomLeft.X));
int FmaxX = (int)Math.Ceiling(Math.Max(Math.Max(Math.Max(floorTopLeft.X, floorTopRight.X), floorBottomRight.X), floorBottomLeft.X));
int FminY = (int)Math.Floor(Math.Min(Math.Min(Math.Min(floorTopLeft.Y, floorTopRight.Y), floorBottomRight.Y), floorBottomLeft.Y));
int FmaxY = (int)Math.Ceiling(Math.Max(Math.Max(Math.Max(floorTopLeft.Y, floorTopRight.Y), floorBottomRight.Y), floorBottomLeft.Y));
int TminX = (int)Math.Floor(Math.Min(Math.Min(Math.Min(ceilTopLeft.X, ceilTopRight.X), ceilBottomRight.X), ceilBottomLeft.X));
int TmaxX = (int)Math.Ceiling(Math.Max(Math.Max(Math.Max(ceilTopLeft.X, ceilTopRight.X), ceilBottomRight.X), ceilBottomLeft.X));
int TminY = (int)Math.Floor(Math.Min(Math.Min(Math.Min(ceilTopLeft.Y, ceilTopRight.Y), ceilBottomRight.Y), ceilBottomLeft.Y));
int TmaxY = (int)Math.Ceiling(Math.Max(Math.Max(Math.Max(ceilTopLeft.Y, ceilTopRight.Y), ceilBottomRight.Y), ceilBottomLeft.Y));
int minX = Math.Min(FminX, TminX);
int maxX = Math.Max(FmaxX, TmaxX);
int minY = Math.Min(FminY, TminY);
int maxY = Math.Max(FmaxY, TmaxY);
ret = Rectangle.Union(ret, Rectangle.FromLTRB(minX, minY, maxX, maxY));
}
// return new Rectangle(-ret.Width / 2, -ret.Height / 2, ret.Width, ret.Height);
return ret;
}