| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414 | import BoundingSphere from "../Core/BoundingSphere.js";import BoxGeometry from "../Core/BoxGeometry.js";import Cartesian3 from "../Core/Cartesian3.js";import Color from "../Core/Color.js";import CylinderGeometry from "../Core/CylinderGeometry.js";import defined from "../Core/defined.js";import EllipsoidGeometry from "../Core/EllipsoidGeometry.js";import IndexDatatype from "../Core/IndexDatatype.js";import Matrix4 from "../Core/Matrix4.js";import Vector3DTileBatch from "../Scene/Vector3DTileBatch.js";import createTaskProcessorWorker from "./createTaskProcessorWorker.js";const scratchCartesian = new Cartesian3();const packedBoxLength = Matrix4.packedLength + Cartesian3.packedLength;const packedCylinderLength = Matrix4.packedLength + 2;const packedEllipsoidLength = Matrix4.packedLength + Cartesian3.packedLength;const packedSphereLength = Cartesian3.packedLength + 1;const scratchModelMatrixAndBV = {  modelMatrix: new Matrix4(),  boundingVolume: new BoundingSphere(),};function boxModelMatrixAndBoundingVolume(boxes, index) {  let boxIndex = index * packedBoxLength;  const dimensions = Cartesian3.unpack(boxes, boxIndex, scratchCartesian);  boxIndex += Cartesian3.packedLength;  const boxModelMatrix = Matrix4.unpack(    boxes,    boxIndex,    scratchModelMatrixAndBV.modelMatrix  );  Matrix4.multiplyByScale(boxModelMatrix, dimensions, boxModelMatrix);  const boundingVolume = scratchModelMatrixAndBV.boundingVolume;  Cartesian3.clone(Cartesian3.ZERO, boundingVolume.center);  boundingVolume.radius = Math.sqrt(3.0);  return scratchModelMatrixAndBV;}function cylinderModelMatrixAndBoundingVolume(cylinders, index) {  let cylinderIndex = index * packedCylinderLength;  const cylinderRadius = cylinders[cylinderIndex++];  const length = cylinders[cylinderIndex++];  const scale = Cartesian3.fromElements(    cylinderRadius,    cylinderRadius,    length,    scratchCartesian  );  const cylinderModelMatrix = Matrix4.unpack(    cylinders,    cylinderIndex,    scratchModelMatrixAndBV.modelMatrix  );  Matrix4.multiplyByScale(cylinderModelMatrix, scale, cylinderModelMatrix);  const boundingVolume = scratchModelMatrixAndBV.boundingVolume;  Cartesian3.clone(Cartesian3.ZERO, boundingVolume.center);  boundingVolume.radius = Math.sqrt(2.0);  return scratchModelMatrixAndBV;}function ellipsoidModelMatrixAndBoundingVolume(ellipsoids, index) {  let ellipsoidIndex = index * packedEllipsoidLength;  const radii = Cartesian3.unpack(ellipsoids, ellipsoidIndex, scratchCartesian);  ellipsoidIndex += Cartesian3.packedLength;  const ellipsoidModelMatrix = Matrix4.unpack(    ellipsoids,    ellipsoidIndex,    scratchModelMatrixAndBV.modelMatrix  );  Matrix4.multiplyByScale(ellipsoidModelMatrix, radii, ellipsoidModelMatrix);  const boundingVolume = scratchModelMatrixAndBV.boundingVolume;  Cartesian3.clone(Cartesian3.ZERO, boundingVolume.center);  boundingVolume.radius = 1.0;  return scratchModelMatrixAndBV;}function sphereModelMatrixAndBoundingVolume(spheres, index) {  let sphereIndex = index * packedSphereLength;  const sphereRadius = spheres[sphereIndex++];  const sphereTranslation = Cartesian3.unpack(    spheres,    sphereIndex,    scratchCartesian  );  const sphereModelMatrix = Matrix4.fromTranslation(    sphereTranslation,    scratchModelMatrixAndBV.modelMatrix  );  Matrix4.multiplyByUniformScale(    sphereModelMatrix,    sphereRadius,    sphereModelMatrix  );  const boundingVolume = scratchModelMatrixAndBV.boundingVolume;  Cartesian3.clone(Cartesian3.ZERO, boundingVolume.center);  boundingVolume.radius = 1.0;  return scratchModelMatrixAndBV;}const scratchPosition = new Cartesian3();function createPrimitive(  options,  primitive,  primitiveBatchIds,  geometry,  getModelMatrixAndBoundingVolume) {  if (!defined(primitive)) {    return;  }  const numberOfPrimitives = primitiveBatchIds.length;  const geometryPositions = geometry.attributes.position.values;  const geometryIndices = geometry.indices;  const positions = options.positions;  const vertexBatchIds = options.vertexBatchIds;  const indices = options.indices;  const batchIds = options.batchIds;  const batchTableColors = options.batchTableColors;  const batchedIndices = options.batchedIndices;  const indexOffsets = options.indexOffsets;  const indexCounts = options.indexCounts;  const boundingVolumes = options.boundingVolumes;  const modelMatrix = options.modelMatrix;  const center = options.center;  let positionOffset = options.positionOffset;  let batchIdIndex = options.batchIdIndex;  let indexOffset = options.indexOffset;  const batchedIndicesOffset = options.batchedIndicesOffset;  for (let i = 0; i < numberOfPrimitives; ++i) {    const primitiveModelMatrixAndBV = getModelMatrixAndBoundingVolume(      primitive,      i    );    const primitiveModelMatrix = primitiveModelMatrixAndBV.modelMatrix;    Matrix4.multiply(modelMatrix, primitiveModelMatrix, primitiveModelMatrix);    const batchId = primitiveBatchIds[i];    const positionsLength = geometryPositions.length;    for (let j = 0; j < positionsLength; j += 3) {      const position = Cartesian3.unpack(geometryPositions, j, scratchPosition);      Matrix4.multiplyByPoint(primitiveModelMatrix, position, position);      Cartesian3.subtract(position, center, position);      Cartesian3.pack(position, positions, positionOffset * 3 + j);      vertexBatchIds[batchIdIndex++] = batchId;    }    const indicesLength = geometryIndices.length;    for (let k = 0; k < indicesLength; ++k) {      indices[indexOffset + k] = geometryIndices[k] + positionOffset;    }    const offset = i + batchedIndicesOffset;    batchedIndices[offset] = new Vector3DTileBatch({      offset: indexOffset,      count: indicesLength,      color: Color.fromRgba(batchTableColors[batchId]),      batchIds: [batchId],    });    batchIds[offset] = batchId;    indexOffsets[offset] = indexOffset;    indexCounts[offset] = indicesLength;    boundingVolumes[offset] = BoundingSphere.transform(      primitiveModelMatrixAndBV.boundingVolume,      primitiveModelMatrix    );    positionOffset += positionsLength / 3;    indexOffset += indicesLength;  }  options.positionOffset = positionOffset;  options.batchIdIndex = batchIdIndex;  options.indexOffset = indexOffset;  options.batchedIndicesOffset += numberOfPrimitives;}const scratchCenter = new Cartesian3();const scratchMatrix4 = new Matrix4();function unpackBuffer(buffer) {  const packedBuffer = new Float64Array(buffer);  let offset = 0;  Cartesian3.unpack(packedBuffer, offset, scratchCenter);  offset += Cartesian3.packedLength;  Matrix4.unpack(packedBuffer, offset, scratchMatrix4);}function packedBatchedIndicesLength(batchedIndices) {  const length = batchedIndices.length;  let count = 0;  for (let i = 0; i < length; ++i) {    count += Color.packedLength + 3 + batchedIndices[i].batchIds.length;  }  return count;}function packBuffer(indicesBytesPerElement, batchedIndices, boundingVolumes) {  const numBVs = boundingVolumes.length;  const length =    1 +    1 +    numBVs * BoundingSphere.packedLength +    1 +    packedBatchedIndicesLength(batchedIndices);  const packedBuffer = new Float64Array(length);  let offset = 0;  packedBuffer[offset++] = indicesBytesPerElement;  packedBuffer[offset++] = numBVs;  for (let i = 0; i < numBVs; ++i) {    BoundingSphere.pack(boundingVolumes[i], packedBuffer, offset);    offset += BoundingSphere.packedLength;  }  const indicesLength = batchedIndices.length;  packedBuffer[offset++] = indicesLength;  for (let j = 0; j < indicesLength; ++j) {    const batchedIndex = batchedIndices[j];    Color.pack(batchedIndex.color, packedBuffer, offset);    offset += Color.packedLength;    packedBuffer[offset++] = batchedIndex.offset;    packedBuffer[offset++] = batchedIndex.count;    const batchIds = batchedIndex.batchIds;    const batchIdsLength = batchIds.length;    packedBuffer[offset++] = batchIdsLength;    for (let k = 0; k < batchIdsLength; ++k) {      packedBuffer[offset++] = batchIds[k];    }  }  return packedBuffer;}function createVectorTileGeometries(parameters, transferableObjects) {  const boxes = defined(parameters.boxes)    ? new Float32Array(parameters.boxes)    : undefined;  const boxBatchIds = defined(parameters.boxBatchIds)    ? new Uint16Array(parameters.boxBatchIds)    : undefined;  const cylinders = defined(parameters.cylinders)    ? new Float32Array(parameters.cylinders)    : undefined;  const cylinderBatchIds = defined(parameters.cylinderBatchIds)    ? new Uint16Array(parameters.cylinderBatchIds)    : undefined;  const ellipsoids = defined(parameters.ellipsoids)    ? new Float32Array(parameters.ellipsoids)    : undefined;  const ellipsoidBatchIds = defined(parameters.ellipsoidBatchIds)    ? new Uint16Array(parameters.ellipsoidBatchIds)    : undefined;  const spheres = defined(parameters.spheres)    ? new Float32Array(parameters.spheres)    : undefined;  const sphereBatchIds = defined(parameters.sphereBatchIds)    ? new Uint16Array(parameters.sphereBatchIds)    : undefined;  const numberOfBoxes = defined(boxes) ? boxBatchIds.length : 0;  const numberOfCylinders = defined(cylinders) ? cylinderBatchIds.length : 0;  const numberOfEllipsoids = defined(ellipsoids) ? ellipsoidBatchIds.length : 0;  const numberOfSpheres = defined(spheres) ? sphereBatchIds.length : 0;  const boxGeometry = BoxGeometry.getUnitBox();  const cylinderGeometry = CylinderGeometry.getUnitCylinder();  const ellipsoidGeometry = EllipsoidGeometry.getUnitEllipsoid();  const boxPositions = boxGeometry.attributes.position.values;  const cylinderPositions = cylinderGeometry.attributes.position.values;  const ellipsoidPositions = ellipsoidGeometry.attributes.position.values;  let numberOfPositions = boxPositions.length * numberOfBoxes;  numberOfPositions += cylinderPositions.length * numberOfCylinders;  numberOfPositions +=    ellipsoidPositions.length * (numberOfEllipsoids + numberOfSpheres);  const boxIndices = boxGeometry.indices;  const cylinderIndices = cylinderGeometry.indices;  const ellipsoidIndices = ellipsoidGeometry.indices;  let numberOfIndices = boxIndices.length * numberOfBoxes;  numberOfIndices += cylinderIndices.length * numberOfCylinders;  numberOfIndices +=    ellipsoidIndices.length * (numberOfEllipsoids + numberOfSpheres);  const positions = new Float32Array(numberOfPositions);  const vertexBatchIds = new Uint16Array(numberOfPositions / 3);  const indices = IndexDatatype.createTypedArray(    numberOfPositions / 3,    numberOfIndices  );  const numberOfGeometries =    numberOfBoxes + numberOfCylinders + numberOfEllipsoids + numberOfSpheres;  const batchIds = new Uint16Array(numberOfGeometries);  const batchedIndices = new Array(numberOfGeometries);  const indexOffsets = new Uint32Array(numberOfGeometries);  const indexCounts = new Uint32Array(numberOfGeometries);  const boundingVolumes = new Array(numberOfGeometries);  unpackBuffer(parameters.packedBuffer);  const options = {    batchTableColors: new Uint32Array(parameters.batchTableColors),    positions: positions,    vertexBatchIds: vertexBatchIds,    indices: indices,    batchIds: batchIds,    batchedIndices: batchedIndices,    indexOffsets: indexOffsets,    indexCounts: indexCounts,    boundingVolumes: boundingVolumes,    positionOffset: 0,    batchIdIndex: 0,    indexOffset: 0,    batchedIndicesOffset: 0,    modelMatrix: scratchMatrix4,    center: scratchCenter,  };  createPrimitive(    options,    boxes,    boxBatchIds,    boxGeometry,    boxModelMatrixAndBoundingVolume  );  createPrimitive(    options,    cylinders,    cylinderBatchIds,    cylinderGeometry,    cylinderModelMatrixAndBoundingVolume  );  createPrimitive(    options,    ellipsoids,    ellipsoidBatchIds,    ellipsoidGeometry,    ellipsoidModelMatrixAndBoundingVolume  );  createPrimitive(    options,    spheres,    sphereBatchIds,    ellipsoidGeometry,    sphereModelMatrixAndBoundingVolume  );  const packedBuffer = packBuffer(    indices.BYTES_PER_ELEMENT,    batchedIndices,    boundingVolumes  );  transferableObjects.push(    positions.buffer,    vertexBatchIds.buffer,    indices.buffer  );  transferableObjects.push(    batchIds.buffer,    indexOffsets.buffer,    indexCounts.buffer  );  transferableObjects.push(packedBuffer.buffer);  return {    positions: positions.buffer,    vertexBatchIds: vertexBatchIds.buffer,    indices: indices.buffer,    indexOffsets: indexOffsets.buffer,    indexCounts: indexCounts.buffer,    batchIds: batchIds.buffer,    packedBuffer: packedBuffer.buffer,  };}export default createTaskProcessorWorker(createVectorTileGeometries);
 |