I have an object, that is facing a particular direction with (for instance) a 45 degree field of view, and a limit view range. I have done all the initial checks (Quadtree node, and distance), but now I need to check if a particular object is within that view cone, (In this case to decide only to follow that object if we can see it).
我有一个物体,面向特定方向(例如)45度视野和极限视野范围。我已经完成了所有初始检查(四叉树节点和距离),但现在我需要检查特定对象是否在该视锥内(在这种情况下,如果我们可以看到它,则决定只跟随该对象)。
Apart from casting a ray for each degree from Direction - (FieldOfView / 2)
to Direction + (FieldOfView / 2)
(I am doing that at the moment and it is horrible), what is the best way to do this visibility check?
除了从Direction - (FieldOfView / 2)到Direction +(FieldOfView / 2)每个度数投射一条光线(我现在这样做并且它很可怕),进行这种可见性检查的最佳方法是什么?
5 个解决方案
#1
9
Compute the angle between your view direction (understood as a vector) and the vector that starts at you and ends at the object. If it falls under FieldOfView/2, you can view the object.
计算视图方向(理解为矢量)与从您开始并在对象处结束的矢量之间的角度。如果它属于FieldOfView / 2,则可以查看该对象。
That angle is:
那个角度是:
arccos(scalarProduct(viewDirection, (object - you)) / (norm(viewDirection)*norm(object - you))).
#2
10
I've worked in the video game industry, and I can say that doing trig functions like arccos every frame is less than ideal. Instead, you precompute the cosine of the angle for the cone:
我曾经在视频游戏行业工作,我可以说每帧都像arccos这样的触发功能并不理想。相反,您预先计算锥体角度的余弦:
float cos_angle = cos(PI/4); // 45 degrees, for example
Then, each frame you can quickly check if a point falls inside that cone by comparing that with the dot product of the cone and the .
然后,通过将点与锥体的点积进行比较,您可以快速检查每个帧是否落入锥体内部。
vector test_point_vector = normalize(test_point_loc - cone_origin);
float dot_product = dot(normalized_cone_vector, text_point_vector);
bool inside_code = dot_product > cos_angle;
There are no trig functions, just some multiplication, division, and addition. Most game engines have an optimized normalize() function for vectors.
没有触发功能,只有一些乘法,除法和加法。大多数游戏引擎都具有针对向量的优化的normalize()函数。
This works because of this equation:
这是因为这个等式:
A · B = |A| * |B| * cos(Θ)
If you normalize the vectors (A -> An), the equation is simplified:
如果对矢量进行归一化(A - > An),则简化等式:
An · Bn = cos(Θ)
#3
3
Get the angle between the viewer's heading vector and the vector from viewer to target. If that angle is less than (FieldOfView/2), then the target is in the viewer's field of view.
获取查看者的标题向量与从查看者到目标的向量之间的角度。如果该角度小于(FieldOfView / 2),则目标位于查看器的视野中。
If your vectors are 2d or 3d this will work the same way. (In 3D, if you have a view frustum instead of cone, then you'll need to separate the angles into two components.) You just need to find the angle between the two vectors.
如果你的向量是2d或3d,这将以相同的方式工作。 (在3D中,如果你有视锥体而不是锥体,那么你需要将角度分成两个部分。)你只需要找到两个矢量之间的角度。
If you want to test targets which are larger than a single point, you'll need multiple points for each target, such as the corners of a bounding box. If the vector from viewer to any of these points gives an angle inside the field of view, then that corner of the box is visible.
如果要测试大于单个点的目标,则每个目标需要多个点,例如边界框的角。如果从观察者到任何这些点的矢量在视野内给出一个角度,那么该框的那个角是可见的。
#4
2
If you're doing 3D and can define the viewing range as a frustrum, then you can use something similar to this Frustrum Culling technique.
如果你正在做3D并且可以将观看范围定义为截头体,那么你可以使用类似于这种Frustrum Culling技术的东西。
#5
1
Good answers already but I just wanted to give you a link to the Wolfire blog, they recently started a algebra series that take the "field of view" equation as one example. Go read it, its well written and easy.
已经很好的答案,但我只想给你一个Wolfire博客的链接,他们最近开始了一个以“视野”方程为例的代数系列。去读它,写得好而且容易。
#1
9
Compute the angle between your view direction (understood as a vector) and the vector that starts at you and ends at the object. If it falls under FieldOfView/2, you can view the object.
计算视图方向(理解为矢量)与从您开始并在对象处结束的矢量之间的角度。如果它属于FieldOfView / 2,则可以查看该对象。
That angle is:
那个角度是:
arccos(scalarProduct(viewDirection, (object - you)) / (norm(viewDirection)*norm(object - you))).
#2
10
I've worked in the video game industry, and I can say that doing trig functions like arccos every frame is less than ideal. Instead, you precompute the cosine of the angle for the cone:
我曾经在视频游戏行业工作,我可以说每帧都像arccos这样的触发功能并不理想。相反,您预先计算锥体角度的余弦:
float cos_angle = cos(PI/4); // 45 degrees, for example
Then, each frame you can quickly check if a point falls inside that cone by comparing that with the dot product of the cone and the .
然后,通过将点与锥体的点积进行比较,您可以快速检查每个帧是否落入锥体内部。
vector test_point_vector = normalize(test_point_loc - cone_origin);
float dot_product = dot(normalized_cone_vector, text_point_vector);
bool inside_code = dot_product > cos_angle;
There are no trig functions, just some multiplication, division, and addition. Most game engines have an optimized normalize() function for vectors.
没有触发功能,只有一些乘法,除法和加法。大多数游戏引擎都具有针对向量的优化的normalize()函数。
This works because of this equation:
这是因为这个等式:
A · B = |A| * |B| * cos(Θ)
If you normalize the vectors (A -> An), the equation is simplified:
如果对矢量进行归一化(A - > An),则简化等式:
An · Bn = cos(Θ)
#3
3
Get the angle between the viewer's heading vector and the vector from viewer to target. If that angle is less than (FieldOfView/2), then the target is in the viewer's field of view.
获取查看者的标题向量与从查看者到目标的向量之间的角度。如果该角度小于(FieldOfView / 2),则目标位于查看器的视野中。
If your vectors are 2d or 3d this will work the same way. (In 3D, if you have a view frustum instead of cone, then you'll need to separate the angles into two components.) You just need to find the angle between the two vectors.
如果你的向量是2d或3d,这将以相同的方式工作。 (在3D中,如果你有视锥体而不是锥体,那么你需要将角度分成两个部分。)你只需要找到两个矢量之间的角度。
If you want to test targets which are larger than a single point, you'll need multiple points for each target, such as the corners of a bounding box. If the vector from viewer to any of these points gives an angle inside the field of view, then that corner of the box is visible.
如果要测试大于单个点的目标,则每个目标需要多个点,例如边界框的角。如果从观察者到任何这些点的矢量在视野内给出一个角度,那么该框的那个角是可见的。
#4
2
If you're doing 3D and can define the viewing range as a frustrum, then you can use something similar to this Frustrum Culling technique.
如果你正在做3D并且可以将观看范围定义为截头体,那么你可以使用类似于这种Frustrum Culling技术的东西。
#5
1
Good answers already but I just wanted to give you a link to the Wolfire blog, they recently started a algebra series that take the "field of view" equation as one example. Go read it, its well written and easy.
已经很好的答案,但我只想给你一个Wolfire博客的链接,他们最近开始了一个以“视野”方程为例的代数系列。去读它,写得好而且容易。