buildTiledTexture()

in packages/miew/src/chem/Volume.js [232:304]


  buildTiledTexture() {
    let tilesX = Math.ceil(Math.sqrt(this._dimZ * this._dimY / this._dimX));

    let width = tilesX * (this._dimX + 2) - 1;
    width = pow2ceil(width);
    tilesX = Math.floor(width / (this._dimX + 2));

    const tilesY = Math.ceil(this._dimZ / tilesX);
    let height = tilesY * (this._dimY + 2) - 1;
    height = pow2ceil(height);

    const data = new Uint8Array(width * height);

    let src;
    let dst;
    for (let tileRow = 0; tileRow < tilesY; ++tileRow) {
      // process each pixel row of this tile row
      for (let row = 0; row < this._dimY; ++row) {
        src = tileRow * tilesX * this._planeElements + row * this._rowElements;
        dst = width * (tileRow * (this._dimY + 2) + row);
        // copy a series of rows through several XY planes
        for (let t = 0; t < tilesX; ++t) {
          // copy one row of one XY plane
          for (let x = 0; x < this._dimX; ++x) {
            data[dst++] = 255.0 * this._data[src++];
          }

          // repeat last pixel of previous tile
          data[dst++] = 255.0 * this._data[src - 1];

          if (t < tilesX - 1) {
            // skip to the same row of next XY plane
            src += this._planeElements - this._rowElements;
            // repeat first pixel of next tile
            data[dst++] = 255.0 * this._data[src];
          }
        }
      }
    }

    // fill pixels between tile rows with copy of edge pixels
    for (let tileRow = 0; tileRow < tilesY; ++tileRow) {
      // copy last pixel row of this tile row to the following pixel row of the texture
      src = width * (tileRow * (this._dimY + 2) + this._dimY - 1);
      dst = src + width;
      for (let x = 0; x < width; ++x) {
        data[dst++] = data[src++];
      }
      if (tileRow < tilesY - 1) {
        // copy first pixel row of next tile row to the preceding pixel row of the texture
        src = width * (tileRow + 1) * (this._dimY + 2);
        dst = src - width;
        for (let x = 0; x < width; ++x) {
          data[dst++] = data[src++];
        }
      }
    }

    const texture = new THREE.DataTexture(
      data,
      width,
      height,
      THREE.LuminanceFormat,
      THREE.UnsignedByteType,
      THREE.UVMapping,
      THREE.ClampToEdgeWrapping,
      THREE.ClampToEdgeWrapping,
      THREE.LinearFilter,
      THREE.LinearFilter,
    );
    texture.needsUpdate = true;
    return texture;
  }