The Arcore provides a method for emitting a ray from screen coordinates based on screen coordinates, viewport size, and view, Project Matrix, which is used for 3D pickup.
1 classRay {2 3 Public Finalvector3f origin;//Ray Beginnings4 Public Finalvector3f direction;//Ray Direction5 6 PublicRay (vector3f origin, vector3f direction) {7 This. Origin =origin;8 This. Direction =direction;9 }Ten One //calculate Ray--3d pickup based on screen coordinates A Public StaticRay Screenpointtoray (vector2f point, vector2f viewportsize,float[] viewprojmtx) { -Point.y = Viewportsize.y-point.y;//Convert to lower left corner as Origin - floatx = Point.x * 2.0f/viewportsize.x-1.0f;//convert to [ -1,1] the floaty = point.y * 2.0f/viewportsize.y-1.0f;//convert to [ -1,1] - - float[] Farscreenpoint =New float[]{x, Y, 1.0F, 1.0F};//The value after the coordinate perspective division on the far plane - float[] Nearscreenpoint =New float[]{x, Y, -1.0f, 1.0F};//The value after the coordinate perspective Division on the near plane + - float[] Nearplanepoint =New float[4];//used to record points on the near plane in the world coordinate system . + float[] Farplanepoint =New float[4];//used to record points on the far plane under the world coordinate system . A at float[] Invertedprojectionmatrix =New float[16]; -Matrix.setidentitym (Invertedprojectionmatrix, 0); -Matrix.invertm (Invertedprojectionmatrix, 0, viewprojmtx, 0);//Calculating inverse matrices - -MATRIX.MULTIPLYMV (nearplanepoint, 0, Invertedprojectionmatrix, 0, nearscreenpoint, 0);//coordinates that correspond to the near plane in the world coordinate system -MATRIX.MULTIPLYMV (farplanepoint, 0, Invertedprojectionmatrix, 0, farscreenpoint, 0); in -vector3f Direction =NewVECTOR3F (Farplanepoint[0]/farplanepoint[3], farplanepoint[1]/farplanepoint[3], farplanepoint[2]/farPlanePoint[3]); tovector3f origin =NewVECTOR3F (NewVECTOR3F (Nearplanepoint[0]/nearplanepoint[3], nearplanepoint[1]/nearplanepoint[3], nearplanepoint[2]/ Nearplanepoint[3])); + Direction.sub (origin); - direction.normalize (); the return NewRay (origin, direction); * } $}
Principle:
One, the world coordinate system point P1 transforms to the projection space to obtain the point P2 the formula is:P2 = P1 * Viewmatrix * Projectmatrix = P1 * Viewprojmatrix;
In the rendering pipeline, the point of the projected space also needs to undergo perspective division, which translates to X, Y and Z values in the [ -1,1] interval, which is a unit cube. The formula is:point_clip = P2/P2.W;
Then the formula of converting points from the unit cube coordinate system to the world coordinate system is the inverse process with the above situation, the formula:
P2 = Point_clip * Wvalue;
P1 = P2 * Viewprojmatrix_invert;
Where Wvalue represents the given W value, this value is 1 in Arcore, so it is not reflected in the code.
Second, the above code fragment, is the point on the screen x, Y coordinate values are converted to [ -1,1], given near clipping plane point of Z is-1, the point on the far clipping plane Z is 1, its w value is 1, this method obtains the coordinates of the unit cube after the perspective division.
Because the Wvalue is 1, the Farscreenpoint and nearscreenpoint represent the coordinate points in the projection space at this time.
Then, according to the conclusion of (a), the coordinate point corresponding to the world coordinate system can be obtained, and the Ray method is obtained according to two points, and finally the starting point and direction of the ray are obtained.
Algorithm for calculating rays based on screen coordinates in Arcore