Skip to content

Nexus

When starting at WMS Gaming, I was given the task of building a 3D tool similar to their existing 2D tool to build casino slot games. I wrote Nexus in C++ and Qt with a custom OpenGL engine. The tool has many plugins such as a shader editor, 3D animation editor, mesh viewer, physics, and plenty more. Unfortunately the company really wasn’t ready to move to a data driven game system. Funny thing is, two years later there’s now an effort to use Unity to build games. If you ask me, I am already halfway there with Nexus. Nexus is approximately 150k lines of code.

Hey look, I wrote some better looking code! Comments, check. Formating, check. Complicated math that I don’t remember what I was doing, check.

/**
 * Build the view matrix for orthographic view.
 */
void CGLCamera::buildOrthoMatrix()
{
    /*
     * Builds the concatenation of the following matrices:
     *
     *  [ [ -Right_X,    Up_X,      At_X,    0 ]       re-orient
     *    [ -Right_Y,    Up_Y,      At_Y,    0 ]
     *    [ -Right_Z,    Up_Z,      At_Z,    0 ]
     *    [ pos Right, -(pos Up), -(pos At), 1 ] ]
     *  [ [   1,      0,    0, 0 ]                     offset eye
     *    [   0,      1,    0, 0 ]
     *    [ off_x,  off_y,  1, 0 ]
     *    [ -off_x, -off_y, 0, 1 ] ]
     *  [ [ 0.5 / width,      0,       0, 0 ]          scale for view window
     *    [      0,      0.5 / height, 0, 0 ]
     *    [      0,           0,       1, 0 ]
     *    [      0,           0,       0, 1 ] ]
     *  [ [ 1, 0,  0, 0 ]                              project & flip y
     *    [ 0, -1, 0, 0 ]
     *    [ 0, 0,  1, 0 ]                              DIFFERS FROM PARALLEL
     *    [ 0, 0,  0, 1 ] ]
     *  [ [  1,   0,  0, 0 ]                           xform XY
     *    [  0,   1,  0, 0 ]                           from [-0.5..0.5]^2
     *    [  0,   0,  1, 0 ]                           to   [0..1]^2
     *    [ 0.5, 0.5, 0, 1 ] ]
     */

    VectorMath::Matrix4 ltw = getLTW();

    float scale;
    VectorMath::Vector3 vector;
    VectorMath::Vector3 right   = ltw.getCol(0).getXYZ();
    VectorMath::Vector3 up      = ltw.getCol(1).getXYZ();
    VectorMath::Vector3 at      = ltw.getCol(2).getXYZ();
    VectorMath::Vector3 pos     = ltw.getTranslation();

    // at
    scale = (1.0f / _viewWindow[0]) * -0.5f;
    vector = right * scale;

    scale = -(scale * _viewOffset[0]);
    vector = vector + at * scale;

    _viewMatrix.setElem(0,0,vector.getX());
    _viewMatrix.setElem(1,0,vector.getY());
    _viewMatrix.setElem(2,0,vector.getZ());
    _viewMatrix.setElem(3,0,0.5f - (scale + VectorMath::dot(pos,vector)));

    // up
    scale = (1.0f / _viewWindow[1]) * -0.5f;
    vector = up * scale;

    scale = scale * _viewOffset[1];
    vector = vector + at * scale;

    _viewMatrix.setElem(0,1,vector.getX());
    _viewMatrix.setElem(1,1,vector.getY());
    _viewMatrix.setElem(2,1,vector.getZ());
    _viewMatrix.setElem(3,1,0.5f - (scale + VectorMath::dot(pos,vector)));

    _viewMatrix.setElem(0,2,at.getX());
    _viewMatrix.setElem(1,2,at.getY());
    _viewMatrix.setElem(2,2,at.getZ());
    _viewMatrix.setElem(3,2,-VectorMath::dot(pos,at));
}