All files / src/views/threejs/cad instancedMeshes.ts

100% Statements 30/30
100% Branches 0/0
100% Functions 1/1
100% Lines 29/29

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46        2x     2x         4x   4x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x   1x 1x 4x 4x   1x 1x 1x 1x 1x 1x     4x    
/*!
 * Copyright 2020 Cognite AS
 */
 
import * as THREE from 'three';
import { InstancedMeshFile } from '../../../models/cad/types';
 
export function createInstancedMeshes(
  meshes: InstancedMeshFile[],
  bounds: THREE.Box3,
  material: THREE.ShaderMaterial
): THREE.Mesh[] {
  const result: THREE.Mesh[] = [];
 
  for (const meshFile of meshes) {
    const indices = new THREE.Uint32BufferAttribute(meshFile.indices.buffer, 1);
    const vertices = new THREE.Float32BufferAttribute(meshFile.vertices.buffer, 3);
    for (const instancedMesh of meshFile.instances) {
      const triangleCount = instancedMesh.triangleCount;
      const triangleOffset = instancedMesh.triangleOffset;
      const geometry = new THREE.InstancedBufferGeometry();
      geometry.setDrawRange(triangleOffset * 3, triangleCount * 3);
      geometry.boundingBox = bounds.clone(); // TODO 2019-12-03 larsmoa: Share instance with all geometries?
      geometry.boundingSphere = new THREE.Sphere();
      bounds.getBoundingSphere(geometry.boundingSphere);
      geometry.setIndex(indices);
      geometry.setAttribute('position', vertices);
      geometry.setAttribute('a_treeIndex', new THREE.InstancedBufferAttribute(instancedMesh.treeIndices, 1));
      geometry.setAttribute(`a_color`, new THREE.InstancedBufferAttribute(instancedMesh.colors, 4, true));
      // TODO de-duplicate this, which is the same as in setAttributes
      const buffer = new THREE.InstancedInterleavedBuffer(instancedMesh.instanceMatrices, 16);
      for (let column = 0; column < 4; column++) {
        const attribute = new THREE.InterleavedBufferAttribute(buffer, 4, column * 4);
        geometry.setAttribute(`a_instanceMatrix_column_${column}`, attribute);
      }
      geometry.boundingBox = bounds.clone();
      geometry.boundingSphere = new THREE.Sphere();
      bounds.getBoundingSphere(geometry.boundingSphere);
      const obj = new THREE.Mesh(geometry, material);
      obj.name = `Instanced mesh ${meshFile.fileId}`;
      result.push(obj);
    }
  }
  return result;
}