简体   繁体   English

计算相机位置以在固定相机旋转的情况下查看所有对象

[英]Calculating a camera position to have all objects in view with a fixed camera rotation

for my 3d board game I am trying to build a "see the whole board" feature which should move the camera to a point where it is able to see the whole board, but without changing the rotation of the camera.对于我的 3d 棋盘游戏,我正在尝试构建一个“查看整个棋盘”功能,该功能应该将相机移动到能够看到整个棋盘的点,但不改变相机的旋转。

For now, I tried to get the minimum and maximum points which include all objects of interest and use these two points to mock a sphere around them (visualized it by actually placing a sphere there programmatically), so I am ending up like this right now: Visualization of the sphere现在,我试图获得包含所有感兴趣对象的最小和最大点,并使用这两个点来模拟它们周围的球体(通过以编程方式实际放置球体来可视化它),所以我现在就这样结束了:球体的可视化

My current problem is, that I am not able to build up a math formula to actually calculate the position of the camera to have the whole sphere in view (remember: rotation has to be unchanged).我目前的问题是,我无法建立一个数学公式来实际计算相机的位置以查看整个球体(请记住:旋转必须保持不变)。

This is my code so far for finding the smalles and biggest point and visualizing it by building the sphere:到目前为止,这是我用于查找最小点和最大点并通过构建球体将其可视化的代码:

        // Find smallest and biggest point of all objects
        var p1 = new Vector3(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
        var p2 = new Vector3(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity);
 
        foreach (var gameObject in gameObjects)
        {
            foreach (var vertice in gameObject.GetComponent<MeshFilter>().sharedMesh.vertices)
            {
                var p = vertice + gameObject.transform.position;
 
                p1.x = Math.Min(p1.x, p.x);
                p1.y = Math.Min(p1.y, p.y);
                p1.z = Math.Min(p1.z, p.z);
 
                p2.x = Math.Max(p2.x, p.x);
                p2.y = Math.Max(p2.y, p.y);
                p2.z = Math.Max(p2.z, p.z);
            }
        }
 
        // Center of all objects
        var average = (p1 + p2) / 2;
 
        // Visualize by creating a sphere
        var diameter = Vector3.Distance(p1, p2);
        var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        sphere.transform.position = average;
        sphere.transform.localScale = new Vector3(diameter, diameter, diameter);

Can you help me with the formula to actually calculate the position of my camera?你能帮我用公式来实际计算我的相机的位置吗?

Regards问候

The easiest thing to do would be to move the camera back, with or without code.最简单的方法是将相机向后移动,无论是否使用代码。 just use the game view to check whether the sphere is in view.只需使用游戏视图来检查球体是否在视野中。 if you got that point then you could leave it there or use code to do this:如果你明白这一点,那么你可以把它留在那里或使用代码来做到这一点:

Vector3 camPos;
//define the camera position in the inspector!
private void Start()
{
    transform.position = camPos;
}

For each side of the view frustrum, find the parallel plane that is as close to the scene as possible.对于视锥体的每一侧,找到尽可能靠近场景的平行平面。 Each of these planes should just touch one of the objects in the scene.这些平面中的每一个都应该只接触场景中的一个对象。

Each pair of opposite planes will intersect along a line.每对相对的平面将沿一条线相交。 Find these two lines.找到这两行。 They will be perpendicular.它们将是垂直的。

The camera should be located on whichever line is furthest away from the scene, situated so that the other line passes through the center of the field of view.相机应位于离场景最远的任何一条线上,以便另一条线穿过视野的中心。

In the resulting view, one pair of opposite sides will just touch some objects in the scene, because the corresponding sides of the view frustrum will just touch those objects.在生成的视图中,一对相对的边将仅接触场景中的某些对象,因为视锥体的对应边将仅接触这些对象。 In the other dimension, the objects will be centered.在另一个维度中,对象将居中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM