add Potree (version 1.8)
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
function readUsingDataView(event) {
|
||||
performance.mark("laslaz-start");
|
||||
|
||||
let buffer = event.data.buffer;
|
||||
let numPoints = event.data.numPoints;
|
||||
let pointSize = event.data.pointSize;
|
||||
let pointFormat = event.data.pointFormatID;
|
||||
|
||||
// gps time byte offsets from LAS specification
|
||||
let gpsOffsets = [null, 20, null, 20, 20, 20, 22, 22, 22, 22, 22]
|
||||
let gpsOffset = gpsOffsets[pointFormat];
|
||||
|
||||
let scale = event.data.scale;
|
||||
let offset = event.data.offset;
|
||||
|
||||
let sourceUint8 = new Uint8Array(buffer);
|
||||
let sourceView = new DataView(buffer);
|
||||
|
||||
let tightBoundingBox = {
|
||||
min: [
|
||||
Number.POSITIVE_INFINITY,
|
||||
Number.POSITIVE_INFINITY,
|
||||
Number.POSITIVE_INFINITY
|
||||
],
|
||||
max: [
|
||||
Number.NEGATIVE_INFINITY,
|
||||
Number.NEGATIVE_INFINITY,
|
||||
Number.NEGATIVE_INFINITY
|
||||
]
|
||||
};
|
||||
|
||||
let mean = [0, 0, 0];
|
||||
|
||||
let pBuff = new ArrayBuffer(numPoints * 3 * 4);
|
||||
let cBuff = new ArrayBuffer(numPoints * 4);
|
||||
let iBuff = new ArrayBuffer(numPoints * 4);
|
||||
let clBuff = new ArrayBuffer(numPoints);
|
||||
let rnBuff = new ArrayBuffer(numPoints);
|
||||
let nrBuff = new ArrayBuffer(numPoints);
|
||||
let psBuff = new ArrayBuffer(numPoints * 2);
|
||||
let gpsBuff64 = new ArrayBuffer(numPoints * 8);
|
||||
let gpsBuff32 = new ArrayBuffer(numPoints * 4);
|
||||
|
||||
let positions = new Float32Array(pBuff);
|
||||
let colors = new Uint8Array(cBuff);
|
||||
let intensities = new Float32Array(iBuff);
|
||||
let classifications = new Uint8Array(clBuff);
|
||||
let returnNumbers = new Uint8Array(rnBuff);
|
||||
let numberOfReturns = new Uint8Array(nrBuff);
|
||||
let pointSourceIDs = new Uint16Array(psBuff);
|
||||
let gpsTime64 = new Float64Array(gpsBuff64)
|
||||
let gpsTime32 = new Float32Array(gpsBuff32)
|
||||
|
||||
// Point format 3 contains an 8-byte GpsTime before RGB values, so make
|
||||
// sure we have the correct color offset.
|
||||
let hasColor = pointFormat == 2 || pointFormat == 3;
|
||||
let co = pointFormat == 2 ? 20 : 28;
|
||||
|
||||
// TODO This should be cached per-resource since this is an expensive check.
|
||||
let twoByteColor = false;
|
||||
if (hasColor) {
|
||||
let r, g, b, pos;
|
||||
for (let i = 0; i < numPoints && !twoByteColor; ++i) {
|
||||
pos = i * pointSize;
|
||||
r = sourceView.getUint16(pos + co, true)
|
||||
g = sourceView.getUint16(pos + co + 2, true)
|
||||
b = sourceView.getUint16(pos + co + 4, true)
|
||||
if (r > 255 || g > 255 || b > 255) twoByteColor = true;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < numPoints; i++) {
|
||||
// POSITION
|
||||
let ux = sourceView.getInt32(i * pointSize + 0, true);
|
||||
let uy = sourceView.getInt32(i * pointSize + 4, true);
|
||||
let uz = sourceView.getInt32(i * pointSize + 8, true);
|
||||
|
||||
x = ux * scale[0] + offset[0] - event.data.mins[0];
|
||||
y = uy * scale[1] + offset[1] - event.data.mins[1];
|
||||
z = uz * scale[2] + offset[2] - event.data.mins[2];
|
||||
|
||||
positions[3 * i + 0] = x;
|
||||
positions[3 * i + 1] = y;
|
||||
positions[3 * i + 2] = z;
|
||||
|
||||
mean[0] += x / numPoints;
|
||||
mean[1] += y / numPoints;
|
||||
mean[2] += z / numPoints;
|
||||
|
||||
tightBoundingBox.min[0] = Math.min(tightBoundingBox.min[0], x);
|
||||
tightBoundingBox.min[1] = Math.min(tightBoundingBox.min[1], y);
|
||||
tightBoundingBox.min[2] = Math.min(tightBoundingBox.min[2], z);
|
||||
|
||||
tightBoundingBox.max[0] = Math.max(tightBoundingBox.max[0], x);
|
||||
tightBoundingBox.max[1] = Math.max(tightBoundingBox.max[1], y);
|
||||
tightBoundingBox.max[2] = Math.max(tightBoundingBox.max[2], z);
|
||||
|
||||
// INTENSITY
|
||||
let intensity = sourceView.getUint16(i * pointSize + 12, true);
|
||||
intensities[i] = intensity;
|
||||
|
||||
// RETURN NUMBER, stored in the first 3 bits - 00000111
|
||||
// number of returns stored in next 3 bits - 00111000
|
||||
let returnNumberAndNumberOfReturns = sourceView.getUint8(i * pointSize + 14, true);
|
||||
let returnNumber = returnNumberAndNumberOfReturns & 0b0111;
|
||||
let numberOfReturn = (returnNumberAndNumberOfReturns & 0b00111000) >> 3;
|
||||
returnNumbers[i] = returnNumber;
|
||||
numberOfReturns[i] = numberOfReturn;
|
||||
|
||||
// CLASSIFICATION
|
||||
let classification = sourceView.getUint8(i * pointSize + 15, true);
|
||||
classifications[i] = classification;
|
||||
|
||||
// POINT SOURCE ID
|
||||
let pointSourceID = sourceView.getUint16(i * pointSize + 18, true);
|
||||
pointSourceIDs[i] = pointSourceID;
|
||||
|
||||
// COLOR, if available
|
||||
if (hasColor) {
|
||||
let r = sourceView.getUint16(i * pointSize + co, true)
|
||||
let g = sourceView.getUint16(i * pointSize + co + 2, true)
|
||||
let b = sourceView.getUint16(i * pointSize + co + 4, true)
|
||||
|
||||
if (twoByteColor) {
|
||||
r /= 256;
|
||||
g /= 256;
|
||||
b /= 256;
|
||||
}
|
||||
|
||||
colors[4 * i + 0] = r;
|
||||
colors[4 * i + 1] = g;
|
||||
colors[4 * i + 2] = b;
|
||||
colors[4 * i + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
let min = Infinity
|
||||
let max = -Infinity
|
||||
|
||||
for (let i = 0; i < numPoints; i++) {
|
||||
min = Math.min(min, gpsTime64[i])
|
||||
max = Math.max(max, gpsTime64[i])
|
||||
}
|
||||
|
||||
for (let i = 0; i < numPoints; i++) {
|
||||
gpsTime32[i] = gpsTime64[i] = min
|
||||
}
|
||||
|
||||
let indices = new ArrayBuffer(numPoints * 4);
|
||||
let iIndices = new Uint32Array(indices);
|
||||
for (let i = 0; i < numPoints; i++) {
|
||||
iIndices[i] = i;
|
||||
}
|
||||
|
||||
performance.mark("laslaz-end");
|
||||
|
||||
//{ // print timings
|
||||
// performance.measure("laslaz", "laslaz-start", "laslaz-end");
|
||||
// let measure = performance.getEntriesByType("measure")[0];
|
||||
// let dpp = 1000 * measure.duration / numPoints;
|
||||
// let debugMessage = `${measure.duration.toFixed(3)} ms, ${numPoints} points, ${dpp.toFixed(3)} µs / point`;
|
||||
// console.log(debugMessage);
|
||||
//}
|
||||
performance.clearMarks();
|
||||
performance.clearMeasures();
|
||||
|
||||
let message = {
|
||||
mean: mean,
|
||||
position: pBuff,
|
||||
color: cBuff,
|
||||
intensity: iBuff,
|
||||
classification: clBuff,
|
||||
returnNumber: rnBuff,
|
||||
numberOfReturns: nrBuff,
|
||||
pointSourceID: psBuff,
|
||||
tightBoundingBox: tightBoundingBox,
|
||||
indices: indices,
|
||||
gpsTime: gpsBuff32,
|
||||
gpsMeta: { offset: min, range: max-min }
|
||||
};
|
||||
|
||||
let transferables = [
|
||||
message.position,
|
||||
message.color,
|
||||
message.intensity,
|
||||
message.classification,
|
||||
message.returnNumber,
|
||||
message.numberOfReturns,
|
||||
message.pointSourceID,
|
||||
message.indices,
|
||||
message.gpsTime
|
||||
];
|
||||
|
||||
postMessage(message, transferables);
|
||||
};
|
||||
|
||||
|
||||
|
||||
onmessage = readUsingDataView;
|
||||
|
||||
Reference in New Issue
Block a user