CNCMaps.Engine.Rendering.VxlRenderer.GetBounds C# (CSharp) Method

GetBounds() public static method

public static GetBounds ( GameObject obj, CNCMaps.FileFormats.VxlFile vxl, CNCMaps.FileFormats.HvaFile hva, CNCMaps.Engine.Rendering.DrawProperties props ) : Rectangle
obj CNCMaps.Engine.Map.GameObject
vxl CNCMaps.FileFormats.VxlFile
hva CNCMaps.FileFormats.HvaFile
props CNCMaps.Engine.Rendering.DrawProperties
return Rectangle
        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;
        }