First, pay attention to the question about the height of the camera: be sure to keep the position of the camera and pointing in the ModelView matrix, and not in the Projection matrix. The Projection matrix should only be used to compensate your human eye for your real screen (truncated). βScalingβ is a more complex issue.
The previous answer links show how to get the line of sight of a vector from the camera by looking into the model space (center of the screen or crosshair).
Name this line of sight vector l. It should be a single column vector expressed in the same coordinate system as your blocks. In terms of yaw (h for heading) and pitch (p), if + y is up and 0 yaw has -z forward and x to the right, then the components (x, y, z) l: l = (cp * sh, sp , -cp * ch), where cp is cos (pitch), sh is sin (yaw = heading), etc.
We want the nearest cube in front of the camera to have any faces pierced by the beam from the camera in the l direction.
At each step, you want to exclude cubes for consideration in order to conserve bandwidth. OpenGL has the ability to determine whether a primitive (for example, a triangle) writes a depth buffer (apparently). If you want, you can do it twice, and pay attention to the cubes that write to the depth buffer under the * -or-equal rule in the second pass and consider only these cubes. If not, you can skip this and just look at all the cubes.
If you do not have a limited number of 16x16x64 blocks selected by you, you can consider large cubic cubic pieces (e.g. 16 ^ 3) to fail first as a whole, using the rough method below for individual blocks, with a valid threshold increased for example 16.
Suppose a cube has 2x2x2 units (angles in the center +/- 1 at x, y, z). The eye camera is in position e. For each cube centered at point c, derive the displacement from the eye: d = c - e. Calculate the distance in the l direction: u = d dot l. (i.e. u = dx * lx + dy * ly + dz * lz.) Drop this cube if u <-1.5 (the cube is completely behind the camera). Calculate the perpendicular vector of the cube center from the ray: p = d - u * l.
Rough check: Drop the cube if the sum of the absolute values ββof the components of p is> 3. This is a quick check that eliminates everything except the cubes that are very close to the line of sight.
Sort all remaining cubes from smallest to largest u.
The first one will go through the following detailed checks.
Detailed check: First you need to do some preparation based on your l-vector before processing any cubes: Designate 8 angular vertex numbers and position vectors that are universal for all cubes, as follows:
no xyz 1 1 1 1 2 1 -1 1 3 1 -1 -1 4 1 1 -1 5 -1 1 1 6 -1 -1 1 7 -1 -1 -1 8 -1 1 -1
Then select 4 or 6 vertices that form the two-dimensional convex hull of the exact collision, as can be seen on the eye, based on the signs x, y, z of the component l:
xyz Vertices (cyclic) +++ 234856 --- 658432 (reverse order of +++) ++- 123785 (6->1, 4->7) of +++ --+ 587321 reverse order of ++- +-+ 156734 -+- 437651 reverse of +-+ -++ 148762 +-- 267841 reverse of -++
Degenerate cases when any 2 of the lx, y or z components are equal to zero:
+00 1234 -00 4321 0+0 1485 0-0 5841 00+ 1562 00- 2651
Select one of the above 14 cases, once, based on your l-vector line of sight. Then perform the following detailed test for each of the remaining cubes sorted by range. Now that the ray is inside this enclosure, the value of at least one cube surface breaks through (or at least grazes), the ray should be on the left of each segment defined by subsequent pairs of vertices of the enclosure (6 or 4) when we we go around the case counterclockwise. This is the same as requiring that the cross-product of the housing segment with movement from either end of this segment onto the beam have a negative or zero projection into the line of the vector of sight l: Taking the vertices of the housing in pairs from left to right and wrapping them from the last to the first, leftmost the vertex is designated as βaβ, and to the right, βbβ, ((b - a) cross (p - a)) dot l <= 0. (the same βpβ as above, p = d - u * l. p can be stored on top or recounted here.) The first cube, taken in order from the closest to the farthest, to go through all 4 or 6 linear segments of the case, is test is a cube in front of the player. Four or six (b - a) vectors can be precomputed (once). You can also find sets of four vertices for degenerate cases when only one of the components of l is zero, but this is not necessary, unlike cases where two components of l are zero, where you should use only 4 vertices.
It is all on paper, not encoded or tested.