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);
|