Introduction
In the previous section, I described how to implement a ray-to-triangle cross-detection algorithm. However, we should know that in game development, a model has a lot of triangles, if you want to all objects, all the triangles to do this detection, even if the current computer computing ability, is not efficient to complete. Therefore, we need to use other means to remove some of the objects that are not likely to cross, this early thinking, a lot of use in 3D game technology. In this article, I'll show you how to achieve cross-detection of ray and axial bounding box aabb. If the reader does not understand what an axial bounding box is, see this article.
Ray-aabb Cross Detection algorithm
Nowadays, there are a lot of ray-aabb cross-detection algorithms, which mainly describe a cross-detection algorithm called "slabs Method".
In 3D space, we first determine the three faces of the ray, that is, we can somehow omit the aabb from the back of Ray Ray to determine the three candidate faces. These three candidate faces are the closest faces possible to intersect with Ray Ray. At the same time, we need to know the fact that, when the rays intersect with one of the three candidate faces, Ray Ray's origin is longer than the distance from the other faces.
If the facts above are not very clear, let us look at:
In, our rays are emitted in the lower right corner, to the top left. Therefore, the candidate surface is the Y1 face, and the X2 face (here because of the convenience of storytelling, using 2D graphics to represent). Ty is the distance from the ray to the Y1 surface, and TX is the distance from the ray to the X2. The tx > Ty can be seen, and the ray crosses the X2 plane.
Through, we should understand, the above the meaning of the fact. This algorithm is based on these facts.
We know that the Ray's formula is R (t) = O + T * d, the distance of the ray to a plane, in fact, the distance from the Ray origin to the intersection of the plane, and this distance is exactly what we have to bring the plane equation into R (t) = O + T * d, the computed T value. So what we're going to do now is to identify the candidates for the interview and bring the equation of the candidate face into R (t) = O + T * d, find the value of T, and also make sure that the intersection is found on the Aabb box to be counted as crossing, if only the maximum T value is calculated, It is not guaranteed that the intersection is on the Aabb box, and the algorithm is invalid.
In the above, the approximate flow of the algorithm is described, but there are several issues that need to be addressed.
First of all:
1. How to identify candidate faces
2. How to determine the equation of candidate faces
3. How to judge whether the intersection is on the AABB box
Let's take a few steps to solve these problems in turn.
For question 1, very simple, such as in the Y1 plane and Y2 plane, as long as the plane equation into Ray Ray's equation, to find the T-value of the two planes, and then the lower T-value of the natural first cross with the ray, then it is a candidate surface. It can be seen that the solution to this problem is to determine the plane equation. This question is exactly the question 2.
We can use the following equation to represent the equation of a candidate surface:
X * n = d; where x represents the point on the candidate face, N is the normal of that face, notice that there are two normals on a face, the normals we use are not defined as a vertex normal in 3D graphics, where we uniformly use a normal with a component of 1, that is, If the above equation represents the left side of the Aabb box, then n in the formula means (1,0,0), but the above formula represents the right side of the Aabb box, the value of n is still (1,0,0). Readers see here, may be dozens, for Mao, why do you want to make the same normal, why not defined as the definition of vertex normals in DirectX? Well, that means it's actually a programming trick, and when you look at the code later, you can understand the benefits of doing it. After understanding how n is expressed, there is still d. The d here represents the component of the Aabb box on the axis perpendicular to the plane. In other words, if the above represents the left side of the Aabb box, D represents the x-coordinate of all points on the face (because it is an axial bounding box aabb, the x-coordinate of the left side is the same). Note that this represents the coordinate value, which is the representation of the direction. In this way, the reader may not understand the point and the plane of the normal dot product can be negative. Well, indeed, if you are using the normal definition of vertices in DirectX, the dot product of the points from the origin to the plane and the DirectX normals is definitely a positive number, but dear readers, I'm not using that normal definition way, so please forgive me, The D value here is likely to be negative.
Well, it took a lot of effort to explain the origin of the formula, hoping that the reader can understand the meaning of the above words. With the formula above, we can bring this formula into the ray equation to get the following result:
t = (D-O * N)/(d * N). For the Aabb box, the normal of its face is always two components is 0, and the other component because of the technique I described above, so that the component is always 1, so you can get the following uniform T-value formula:
When the candidate faces are perpendicular to the two faces of the x-axis, t = (d-ox)/Dx
When the candidate faces are perpendicular to the two faces of the y-axis, t = (D-oy)/Dy
When the candidate faces are perpendicular to the two faces of the z axis, t = (d-oz)/Dz
With the equation, we can find the T value.
Now that's the last question, how do you make sure that the intersection point represented by the T value is on the Aabb box??
In order to find out this problem, we need to keep the other three not the candidate face T value in the process of seeking T value. These T-values are then determined to determine if they are on the Aabb box. This process will be shown in the code because it is just a simple comparison operation, so don't repeat it.
Implementation of RAY-AABB crossover algorithm
Here is a version of the code that I implemented:
<span style= "Font-family:microsoft Yahei;" >bool Ray::intersectwithaabb (aabb* A, vector3* vchit) {float tmin = 0.0f; float Tmax = Flt_max;//the plane Perpendicula R to X-axieif (ABS (dir.x) < 0.000001f)//if the ray parallel to the plane{//if the ray was not within AABB box and then not Intersectingif (origin.x < a->min.x | | origin.x > a->max.x) return false;} Else{//compute the distance of Ray to the near plane and far planefloat ood = 1.0f/dir.x; float T1 = (a->min.x-orig in.x) * OOD; float t2 = (a->max.x-origin.x) * OOD;//make t1 be intersecting with the near plane, T2 with the far PLA Neif (T1 > T2) {Float temp = t1; t1 = t2; t2 = temp;} Compute the intersection of Slab intersection intervalsif (T1 > tmin) tmin = t1; if (T2 < Tmax) Tmax = T2;//exit wi Th no collision as soon as slab intersection becomes emptyif (tmin > Tmax) return false;} End for perpendicular to x-axie//the plane perpendicular to Y-axieif (ABS (DIR.Y) < 0.000001f)//if the ray PArallel to the plane{//if the ray was not within AABB box and then not Intersectingif (ORIGIN.Y < A->MIN.Y | | ORIGIN.Y &G T A->MAX.Y) return false;} Else{//compute the distance of Ray to the near plane and far planefloat ood = 1.0f/dir.y; float T1 = (a->min.y-orig IN.Y) * OOD; float t2 = (a->max.y-origin.y) * OOD;//make t1 be intersecting with the near plane, T2 with the far PLA Neif (T1 > T2) {Float temp = t1; t1 = t2; t2 = temp;} Compute the intersection of Slab intersection intervalsif (T1 > tmin) tmin = t1; if (T2 < Tmax) Tmax = T2;//exit wi Th no collision as soon as slab intersection becomes emptyif (tmin > Tmax) return false;} End for perpendicular-y-axie//the plane perpendicular to Z-axieif (ABS (DIR.Z) < 0.000001f)//if the ray parallel t o The plane{//if the ray is not within AABB box and then not Intersectingif (Origin.z < A->MIN.Z | | origin.z > a-> MAX.Z) return false;} Else{//compute the distance of Ray to the near plane and far Planefloat ood = 1.0f/dir.z; float T1 = (a->min.z-origin.z) * OOD; float t2 = (a->max.z-origin.z) * OOD;//make t1 be I Ntersecting with the near plane, T2 with the far planeif (T1 > T2) {Float temp = t1; t1 = t2; t2 = temp;} Compute the intersection of Slab intersection intervalsif (T1 > tmin) tmin = t1; if (T2 < Tmax) Tmax = T2;//exit wi Th no collision as soon as slab intersection becomes emptyif (tmin > Tmax) return false;} End for perpendicular to z-axievchit->x = origin.x + tmin * dir.x; vchit->y = origin.y + tmin * dir.y;vchit-> z = origin.z + tmin * DIR.Z; return true;} End for Intersectwithaabb</span>
This code I probably explained, in order to ensure that the intersection of the time does not occur in addition to the 0 exception, the algorithm first to determine the direction of the vector D of a component is 0, if so, only need to simple judgment to know whether to cross with the AABB, because at this time the ray is parallel with an axis.
In the above code, in addition to always seek three candidate plane of the maximum T value, the algorithm has been calculated the other three non-candidate plane of the minimum t value, and since each calculation, the judgment of the intersection at this point T value, that is, tmin, whether greater than Tmax, if so, it is, The T value found on this axis is not on the Aabb box (as long as it is simple to draw a picture on the draft paper, you should understand this), and once there is a separation on the axis, then we do not need to carry out the following steps, a separation on one axis, it means that the ray and AABB box can not cross.
Program examples
Not before the intersection:
After crossing the diagram:
http://m.blog.csdn.net/article/details?id=38342739
Cross-detection algorithm of X-ray and axial bounding box AABB in 3D space "turn"