_getModels()

in examples/website/plot/plot-layer/axes-layer.js [182:334]


  _getModels(gl) {
    /* grids:
     * for each x tick, draw rectangle on yz plane around the bounding box.
     * for each y tick, draw rectangle on zx plane around the bounding box.
     * for each z tick, draw rectangle on xy plane around the bounding box.
     * show/hide is toggled by the vertex shader
     */
    /*
     * rectangles are defined in 2d and rotated in the vertex shader
     *
     * (-1,1)      (1,1)
     *   +-----------+
     *   |           |
     *   |           |
     *   |           |
     *   |           |
     *   +-----------+
     * (-1,-1)     (1,-1)
     */

    // offset of each corner
    const gridPositions = [
      // left edge
      -1,
      -1,
      0,
      -1,
      1,
      0,
      // top edge
      -1,
      1,
      0,
      1,
      1,
      0,
      // right edge
      1,
      1,
      0,
      1,
      -1,
      0,
      // bottom edge
      1,
      -1,
      0,
      -1,
      -1,
      0
    ];
    // normal of each edge
    const gridNormals = [
      // left edge
      -1,
      0,
      0,
      -1,
      0,
      0,
      // top edge
      0,
      1,
      0,
      0,
      1,
      0,
      // right edge
      1,
      0,
      0,
      1,
      0,
      0,
      // bottom edge
      0,
      -1,
      0,
      0,
      -1,
      0
    ];

    const grids = new Model(gl, {
      id: `${this.props.id}-grids`,
      vs: gridVertex,
      fs: fragmentShader,
      geometry: new Geometry({
        drawMode: GL.LINES,
        attributes: {
          positions: new Float32Array(gridPositions),
          normals: new Float32Array(gridNormals)
        },
        vertexCount: gridPositions.length / 3
      }),
      isInstanced: true
    });

    /* labels
     * one label is placed at each end of every grid line
     * show/hide is toggled by the vertex shader
     */
    let labelTexCoords = [];
    let labelPositions = [];
    let labelNormals = [];
    let labelIndices = [];
    for (let i = 0; i < 8; i++) {
      /*
       * each label is rendered as a rectangle
       *   0     2
       *    +--.+
       *    | / |
       *    +'--+
       *   1     3
       */
      labelTexCoords = labelTexCoords.concat([0, 0, 0, 1, 1, 0, 1, 1]);
      labelIndices = labelIndices.concat([
        i * 4 + 0,
        i * 4 + 1,
        i * 4 + 2,
        i * 4 + 2,
        i * 4 + 1,
        i * 4 + 3
      ]);

      // all four vertices of this label's rectangle is anchored at the same grid endpoint
      for (let j = 0; j < 4; j++) {
        labelPositions = labelPositions.concat(gridPositions.slice(i * 3, i * 3 + 3));
        labelNormals = labelNormals.concat(gridNormals.slice(i * 3, i * 3 + 3));
      }
    }

    const labels = new Model(gl, {
      id: `${this.props.id}-labels`,
      vs: labelVertex,
      fs: labelFragment,
      geometry: new Geometry({
        drawMode: GL.TRIANGLES,
        attributes: {
          indices: new Uint16Array(labelIndices),
          positions: new Float32Array(labelPositions),
          texCoords: {size: 2, value: new Float32Array(labelTexCoords)},
          normals: new Float32Array(labelNormals)
        }
      }),
      isInstanced: true
    });

    return {
      models: [grids, labels].filter(Boolean),
      modelsByName: {grids, labels}
    };
  }