178 lines
5.5 KiB
JavaScript
178 lines
5.5 KiB
JavaScript
/**
|
|
* A worker that does cpu-heavy tasks related to webgl rendering.
|
|
* @module ol/worker/webgl
|
|
*/
|
|
import {WebGLWorkerMessageType} from '../render/webgl/constants.js';
|
|
import {
|
|
create as createTransform,
|
|
makeInverse as makeInverseTransform,
|
|
} from '../transform.js';
|
|
import {
|
|
writeLineSegmentToBuffers,
|
|
writePointFeatureToBuffers,
|
|
writePolygonTrianglesToBuffers,
|
|
} from '../render/webgl/utils.js';
|
|
|
|
/** @type {any} */
|
|
const worker = self;
|
|
|
|
worker.onmessage = (event) => {
|
|
const received = event.data;
|
|
switch (received.type) {
|
|
case WebGLWorkerMessageType.GENERATE_POINT_BUFFERS: {
|
|
// This is specific to point features (x, y, index)
|
|
const baseVertexAttrsCount = 3;
|
|
const baseInstructionsCount = 2;
|
|
|
|
const customAttrsCount = received.customAttributesCount;
|
|
const instructionsCount = baseInstructionsCount + customAttrsCount;
|
|
const renderInstructions = new Float32Array(received.renderInstructions);
|
|
|
|
const elementsCount = renderInstructions.length / instructionsCount;
|
|
const indicesCount = elementsCount * 6;
|
|
const verticesCount =
|
|
elementsCount * 4 * (customAttrsCount + baseVertexAttrsCount);
|
|
const indexBuffer = new Uint32Array(indicesCount);
|
|
const vertexBuffer = new Float32Array(verticesCount);
|
|
|
|
let bufferPositions;
|
|
for (let i = 0; i < renderInstructions.length; i += instructionsCount) {
|
|
bufferPositions = writePointFeatureToBuffers(
|
|
renderInstructions,
|
|
i,
|
|
vertexBuffer,
|
|
indexBuffer,
|
|
customAttrsCount,
|
|
bufferPositions
|
|
);
|
|
}
|
|
|
|
/** @type {import('../render/webgl/constants.js').WebGLWorkerGenerateBuffersMessage} */
|
|
const message = Object.assign(
|
|
{
|
|
vertexBuffer: vertexBuffer.buffer,
|
|
indexBuffer: indexBuffer.buffer,
|
|
renderInstructions: renderInstructions.buffer,
|
|
},
|
|
received
|
|
);
|
|
|
|
worker.postMessage(message, [
|
|
vertexBuffer.buffer,
|
|
indexBuffer.buffer,
|
|
renderInstructions.buffer,
|
|
]);
|
|
break;
|
|
}
|
|
case WebGLWorkerMessageType.GENERATE_LINE_STRING_BUFFERS: {
|
|
const vertices = [];
|
|
const indices = [];
|
|
|
|
const customAttrsCount = received.customAttributesCount;
|
|
const instructionsPerVertex = 2;
|
|
|
|
const renderInstructions = new Float32Array(received.renderInstructions);
|
|
let currentInstructionsIndex = 0;
|
|
|
|
const transform = received.renderInstructionsTransform;
|
|
const invertTransform = createTransform();
|
|
makeInverseTransform(invertTransform, transform);
|
|
|
|
let verticesCount, customAttributes;
|
|
while (currentInstructionsIndex < renderInstructions.length) {
|
|
customAttributes = Array.from(
|
|
renderInstructions.slice(
|
|
currentInstructionsIndex,
|
|
currentInstructionsIndex + customAttrsCount
|
|
)
|
|
);
|
|
currentInstructionsIndex += customAttrsCount;
|
|
verticesCount = renderInstructions[currentInstructionsIndex++];
|
|
|
|
// last point is only a segment end, do not loop over it
|
|
for (let i = 0; i < verticesCount - 1; i++) {
|
|
writeLineSegmentToBuffers(
|
|
renderInstructions,
|
|
currentInstructionsIndex + i * instructionsPerVertex,
|
|
currentInstructionsIndex + (i + 1) * instructionsPerVertex,
|
|
i > 0
|
|
? currentInstructionsIndex + (i - 1) * instructionsPerVertex
|
|
: null,
|
|
i < verticesCount - 2
|
|
? currentInstructionsIndex + (i + 2) * instructionsPerVertex
|
|
: null,
|
|
vertices,
|
|
indices,
|
|
customAttributes,
|
|
transform,
|
|
invertTransform
|
|
);
|
|
}
|
|
currentInstructionsIndex += verticesCount * instructionsPerVertex;
|
|
}
|
|
|
|
const indexBuffer = Uint32Array.from(indices);
|
|
const vertexBuffer = Float32Array.from(vertices);
|
|
|
|
/** @type {import('../render/webgl/constants.js').WebGLWorkerGenerateBuffersMessage} */
|
|
const message = Object.assign(
|
|
{
|
|
vertexBuffer: vertexBuffer.buffer,
|
|
indexBuffer: indexBuffer.buffer,
|
|
renderInstructions: renderInstructions.buffer,
|
|
},
|
|
received
|
|
);
|
|
|
|
worker.postMessage(message, [
|
|
vertexBuffer.buffer,
|
|
indexBuffer.buffer,
|
|
renderInstructions.buffer,
|
|
]);
|
|
break;
|
|
}
|
|
case WebGLWorkerMessageType.GENERATE_POLYGON_BUFFERS: {
|
|
const vertices = [];
|
|
const indices = [];
|
|
|
|
const customAttrsCount = received.customAttributesCount;
|
|
const renderInstructions = new Float32Array(received.renderInstructions);
|
|
|
|
let currentInstructionsIndex = 0;
|
|
while (currentInstructionsIndex < renderInstructions.length) {
|
|
currentInstructionsIndex = writePolygonTrianglesToBuffers(
|
|
renderInstructions,
|
|
currentInstructionsIndex,
|
|
vertices,
|
|
indices,
|
|
customAttrsCount
|
|
);
|
|
}
|
|
|
|
const indexBuffer = Uint32Array.from(indices);
|
|
const vertexBuffer = Float32Array.from(vertices);
|
|
|
|
/** @type {import('../render/webgl/constants.js').WebGLWorkerGenerateBuffersMessage} */
|
|
const message = Object.assign(
|
|
{
|
|
vertexBuffer: vertexBuffer.buffer,
|
|
indexBuffer: indexBuffer.buffer,
|
|
renderInstructions: renderInstructions.buffer,
|
|
},
|
|
received
|
|
);
|
|
|
|
worker.postMessage(message, [
|
|
vertexBuffer.buffer,
|
|
indexBuffer.buffer,
|
|
renderInstructions.buffer,
|
|
]);
|
|
break;
|
|
}
|
|
default:
|
|
// pass
|
|
}
|
|
};
|
|
|
|
export let create;
|