Skip to content

Coordinate Systems

James Walker edited this page Sep 1, 2019 · 2 revisions

Quesa uses a number of coordinate system and transformations between them.

Local and World Space

There is a single world coordinate system that contains all your geometries, lights, and cameras. The points of a geometry are considered to live in a local coordinate system. Within a rendering loop or other submitting loop, transform objects modify the relationship between local and world coordinates. For example, suppose you submit a transform A, then a transform B, then a geometry G. To convert a point of G from its local coordinates to world coordinates, you would apply B and then A to the point.

Within a submitting loop, you can get the combined local to world transformation using Q3View_GetLocalToWorldMatrixState.

Camera Space, also known as View Space

Each camera defines its own coordinate system. The origin is at the camera location, the -z axis in the camera's viewing direction, and the +y axis along the camera's up direction. The +x axis is determined by the right-hand rule. You can find the world to view transformation matrix for a given camera using the function Q3Camera_GetWorldToView. The world to view transformation is always a rigid motion, i.e., a combination of a rotation and a translation.

Frustum Space

A camera only sees a finite region within world space. This region, called the view frustum, is bounded by 6 planes: near, far, left, right, top, and bottom. In the case of an angle aspect (perspective) camera, the region is a frustum of a pyramid. In the case of an orthographic camera, the region is a rectangular parallelepiped (a box).

The view frustum determines a coordinate system called frustum space. In this coordinate system, the z coordinate ranges from 0 at the near plane to -1 at the far plane, the x coordinate ranges from -1 at the left plane to 1 at the right plane, and the y coordinate ranges from -1 at the bottom plane to 1 at the top plane.

The transformation from view coordinates to frustum coordinates does not preserve distances or angles. You can obtain the matrix of this transformation using the function Q3Camera_GetViewToFrustum. As a convenience, there is also a function to obtain the product of the world to view and view to frustum transformations, Q3Camera_GetWorldToFrustum. Within a submitting loop, you can also obtain the world to frustum transformation using the function Q3View_GetWorldToFrustumMatrixState.

The Camera Viewport

Normally, the camera sees the whole view frustum, as described above. But for certain special purposes, for example rendering a large area in pieces by tiling, you can select a rectangular subset of the frustum xy coordinate area, and stretch and translate it so that it takes up the whole [-1, 1] × [-1, 1] frustum area. The standard view to frustum transformation composed with this viewport transformation is the actual view to frustum transformation returned by Q3Camera_GetViewToFrustum.

The camera viewport is specified in a somewhat peculiar way, not by the minimum and maximum x and y coordinates, but by the top left corner and the width and height. For example, suppose you want to select the area [0.3, 0.5] × [-0.6, 0.4]. Then you would specify a viewport with origin (0.3, 0.4), width 0.2, and height 1.0.

Window Space

A draw context defines a pane area within the xy plane. This area, together with the same z range of 0 to -1 used in frustum space, defines window space.

Beware of the fact that in window space, the minimum y values are at the top, while in frustum space, the minimum y values are at the bottom. As a result, window coordinates are left handed. Within a submitting loop, you can obtain the frustum to window transform matrix using the function Q3View_GetFrustumToWindowMatrixState.

OpenGL Transformations

OpenGL has only 2 spatial transformation matrices, the modelview matrix and the projection matrix. The modelview matrix is what Quesa would call the local to view matrix, i.e., the product of the local to world and world to view transformations. The projection matrix is almost the same as Quesa's view to frustum matrix, except that in OpenGL's normalized device coordinates, z ranges from -1 to 1 instead of 0 to -1. OpenGL's transformation from normalized device coordinates to window coordinates is specified by the glViewport function, not an explicit matrix.