如何使用尽可能小的边界将多个立方体封装在一个更大的立方体中?
How to encapsulate several cubes in a larger cube using the smallest possible bounds?
我在运行时生成许多立方体并向它们应用一些照片(这是一种 VR 照片浏览器)。无论如何,我正在尝试使用所有小立方体的最小边界框将它们全部封装在一个更大的立方体中。这是我目前所拥有的。
生成所有立方体后,我做的第一件事就是将它们全部置于父级的中心,以便用户可以相对于中心定位和旋转它们。
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;
}
然后我计算所有作为父级子级的立方体的边界。
Renderer[] meshes = GetComponentsInChildren<Renderer>();
Bounds bounds = new Bounds(transform.position, Vector3.zero);
foreach (Renderer mesh in meshes)
{
bounds.Encapsulate(mesh.bounds);
}
Bounds maximumScrollBounds = bounds;
然后我创建新的更大的 (red/transparent) 立方体,它将封装所有较小的立方体并使用我之前为其比例计算的边界。
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);
但问题是封装立方体总是有点太大,我不知道为什么。
我需要它基本上只到达其中较小立方体的边缘。
我会尝试的事情:
1.- 我相信 Bounds.Encapsulate
找回了世界的中心 space。所以我认为:
boundingBox.transform.localPosition = maximumScrollBounds.center;
需要替换为:
boundingBox.transform.position = maximumScrollBounds.center;
2.- 是一样的,但只是为了提供尝试 local/global space 的想法,我也会尝试:
boundingBox.transform.localPosition = boundingBox.transform.InverseTransformPoint(maximumScrollBounds.center);
另一方面,我会查看并检查边界框的所有面,以检查体积的过度延伸是否对称。同时绘制中心,以尝试缩小问题范围并检查它是在范围内还是在中心。
据我所知,这是获得的边界框的中心位置错位,但为此,一侧的超量应该在另一侧没有,所以如果那不是问题,那可能是一个有趣的更新,可以继续解决问题。
我在运行时生成许多立方体并向它们应用一些照片(这是一种 VR 照片浏览器)。无论如何,我正在尝试使用所有小立方体的最小边界框将它们全部封装在一个更大的立方体中。这是我目前所拥有的。
生成所有立方体后,我做的第一件事就是将它们全部置于父级的中心,以便用户可以相对于中心定位和旋转它们。
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;
}
然后我计算所有作为父级子级的立方体的边界。
Renderer[] meshes = GetComponentsInChildren<Renderer>();
Bounds bounds = new Bounds(transform.position, Vector3.zero);
foreach (Renderer mesh in meshes)
{
bounds.Encapsulate(mesh.bounds);
}
Bounds maximumScrollBounds = bounds;
然后我创建新的更大的 (red/transparent) 立方体,它将封装所有较小的立方体并使用我之前为其比例计算的边界。
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);
但问题是封装立方体总是有点太大,我不知道为什么。
我需要它基本上只到达其中较小立方体的边缘。
我会尝试的事情:
1.- 我相信 Bounds.Encapsulate
找回了世界的中心 space。所以我认为:
boundingBox.transform.localPosition = maximumScrollBounds.center;
需要替换为:
boundingBox.transform.position = maximumScrollBounds.center;
2.- 是一样的,但只是为了提供尝试 local/global space 的想法,我也会尝试:
boundingBox.transform.localPosition = boundingBox.transform.InverseTransformPoint(maximumScrollBounds.center);
另一方面,我会查看并检查边界框的所有面,以检查体积的过度延伸是否对称。同时绘制中心,以尝试缩小问题范围并检查它是在范围内还是在中心。
据我所知,这是获得的边界框的中心位置错位,但为此,一侧的超量应该在另一侧没有,所以如果那不是问题,那可能是一个有趣的更新,可以继续解决问题。