I am generating many cubes during runtime and applying some photos to them (it's a type of VR photo browser). Anyway, I am trying to encapsulate them all in a larger cube using the smallest possible bounding box of all the little cubes. This is what I have so far.
After generating all the cubes, the first thing I do is center them all on their parent so the user can position and rotate them relative to the center.
Transform[] children = GetComponentsInChildren<Transform>();
Vector3 newPosition = Vector3.zero;
foreach (var child in children)
{
newPosition += child.position;
child.parent = null;
}
newPosition /= children.Length;
gameObject.transform.position = newPosition;
foreach (var child in children)
{
child.parent = gameObject.transform;
}
Then I calculate the bounds of all the cubes which are children of the parent.
Renderer[] meshes = GetComponentsInChildren<Renderer>();
Bounds bounds = new Bounds(transform.position, Vector3.zero);
foreach (Renderer mesh in meshes)
{
bounds.Encapsulate(mesh.bounds);
}
Bounds maximumScrollBounds = bounds;
Then I create the new larger (red/transparent) cube which will encapsulate all the smaller ones and use the bounds I previously calculated for it's scale.
GameObject boundingBox = GameObject.CreatePrimitive(PrimitiveType.Cube);
Destroy(boundingBox.GetComponent<Collider>());
boundingBox.GetComponent<Renderer>().material = Resources.Load("Materials/BasicTransparent") as Material;
boundingBox.GetComponent<Renderer>().material.color = new Color32(255, 0, 0, 130);
boundingBox.name = "BoundingBox";
boundingBox.transform.localScale = new Vector3(maximumScrollBounds.size.x, maximumScrollBounds.size.y, maximumScrollBounds.size.z);
boundingBox.transform.localPosition = maximumScrollBounds.center;
boundingBox.transform.SetParent(transform);
But the problem is the encapsulating cube is always slightly too big and I cannot figure out why.
I need it to basically only reach the very edges of the smaller cubes inside of it.
Things I would try:
1.- I believe Bounds.Encapsulate retrieves the center in world space. So I think that:
boundingBox.transform.localPosition = maximumScrollBounds.center;
Needs to be subtituted by:
boundingBox.transform.position = maximumScrollBounds.center;
2.- Its the same, but just to give ideas to try with local/global space, I would also try:
boundingBox.transform.localPosition = boundingBox.transform.InverseTransformPoint(maximumScrollBounds.center);
On the other hand I would give a look and check all the faces of the bounding box to check if the over extension of the volume is simmetrical. Also draw the center, to try to narrow the problem and check if its more in the extents or just in the center.
As far as I can guess it is a misplaced center of the obtained bounding box, but for that to be, the exceeding volume in one side should be lacking in the other, so if that is not the problem, that could be an interesting update to move on towards the solution.