1
votes

I'm currently trying to implement an AR-browser based on indoor maps, but I'm facing several problems, let's take a look at the figure: enter image description here

In this figure, I've already changed the coordinate to OpenGL's right-handed coordinate system.

In our real-world scenario,

given the angle FOV/2 and the camera height h then I can get nearest visible point P(0,0,-n).

Given the angle B and the camera height h then I can get a point Q(0,0,-m) between nearest visible point and longest visible point.

Here comes a problem: when I finished setup my vertices(including P and Q) and use the method Matrix.setLookAtM like

Matrix.setLookAtM(modelMatrix, 0, 0f,h,0f,0f,-2000f,0f,0f,1f,0f);

the aspect ratio is incorrect. If the camera height h is set to 0.92 and FOV is set to 68 degrees, n should be 1.43, But in OpenGL the coordinate of the nearest point is not (0,0,-1.43f). So I'm wondering how to fix this problem, how to map real-world coordinate to OpenGL's coordinate system?

2

2 Answers

1
votes

In a rendering, each mesh of the scene usually is transformed by the model matrix, the view matrix and the projection matrix.

  • Model matrix:
    The model matrix defines the location, oriantation and the relative size of a mesh in the scene. The model matrix transforms the vertex positions of the mesh to the world space.

  • View matrix:
    The view matrix describes the direction and position from which the scene is looked at. The view matrix transforms from the wolrd space to the view (eye) space. In the coordinat system on the viewport, the X-axis points to the left, the Y-axis up and the Z-axis out of the view (Note in a right hand system the Z-Axis is the cross product of the X-Axis and the Y-Axis).

    The view matrix can be set up by Matrix.setLookAtM

  • Projection matrix:
    The projection matrix describes the mapping from 3D points of a scene, to 2D points of the viewport. The projection matrix transforms from view space to the clip space, and the coordinates in the clip space are transformed to the normalized device coordinates (NDC) in the range (-1, -1, -1) to (1, 1, 1) by dividing with the w component of the clip coordinates.
    At Perspective Projection the projection matrix describes the mapping from 3D points in the world as they are seen from of a pinhole camera, to 2D points of the viewport.
    The eye space coordinates in the camera frustum (a truncated pyramid) are mapped to a cube (the normalized device coordinates).

    The perspective projection matrix can be set up by Matrix.perspectiveM

enter image description here



You can set up a separate view matrix and a separate projection matrix and finally multiply them. The aspect ratio and the field of view are parameters to [Matrix.perspectiveM]:

Matrix viewM = new Matrix();
Matrix.setLookAtM(viewM, 0, 0, 0, 0f, 0f,-2000f, 0f, 0f, 1.0f, 0.0f);

Matrix prjM = new Matrix();
Matrix.perspectiveM(prjM, 0, fovy, aspect, zNear, zFar);

Matrix viewPrjM = new Matrix();
Matrix.multiplyMM(viewPrjM, 0, prjM, 0, viewM, 0);
0
votes

Thank to @Rabbid76's support, I finally figure it out myself.

Figure 1: Real-life scenario enter image description here

Figure 2: OpenGL scenario enter image description here

In real-life, if we are facing north, we coordinate system would be like:

  • x point to the east
  • y point to the north
  • z point to the sky

so given a camera held by a user, assuming its height is 1.5 meter and its field of view is 68 degrees, we can reference the nearest visible point is located at P(0,2.223,0). We can set the angle B to 89 degrees, so segment QP will be the visible ground on the smartphone screen.

How can we map the coordinate of real-life to OpenGL coordinate system? I found that we must go through several steps:

  1. Assign the camera position to be the origin (e.g. C in figure2).
  2. Due to OpenGL always draw from (1,1) to (-1,-1), we must assign the distance from C to C' to be 1, so that C' is (0, -1, 0).
  3. Finally, we calculate the aspect ratio with camera height in real-life and segment C, C' in OpenGL, and apply it to other coordinates.

By doing stuff above, we can map real-world coordinate to OpenGL coordinate system magically.