UNPKG

potree

Version:

WebGL point cloud viewer - WORK IN PROGRESS

210 lines (183 loc) 6.72 kB
/* global onmessage:true postMessage:false */ /* exported onmessage */ // var pointFormatReaders = { // 0: function(dv) { // return { // "position": [ dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)], // "intensity": dv.getUint16(12, true), // "classification": dv.getUint8(16, true) // }; // }, // 1: function(dv) { // return { // "position": [ dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)], // "intensity": dv.getUint16(12, true), // "classification": dv.getUint8(16, true) // }; // }, // 2: function(dv) { // return { // "position": [ dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)], // "intensity": dv.getUint16(12, true), // "classification": dv.getUint8(16, true), // "color": [dv.getUint16(20, true), dv.getUint16(22, true), dv.getUint16(24, true)] // }; // }, // 3: function(dv) { // return { // "position": [ dv.getInt32(0, true), dv.getInt32(4, true), dv.getInt32(8, true)], // "intensity": dv.getUint16(12, true), // "classification": dv.getUint8(16, true), // "color": [dv.getUint16(28, true), dv.getUint16(30, true), dv.getUint16(32, true)] // }; // } // }; // // // Decodes LAS records into points // // var LASDecoder = function(buffer, pointFormatID, pointSize, pointsCount, scale, offset) { // this.arrayb = buffer; // this.decoder = pointFormatReaders[pointFormatID]; // this.pointsCount = pointsCount; // this.pointSize = pointSize; // this.scale = scale; // this.offset = offset; // }; // // LASDecoder.prototype.getPoint = function(index) { // if (index < 0 || index >= this.pointsCount) // throw new Error("Point index out of range"); // // var dv = new DataView(this.arrayb, index * this.pointSize, this.pointSize); // return this.decoder(dv); // }; onmessage = function (event) { var buffer = event.data.buffer; var numPoints = event.data.numPoints; var pointSize = event.data.pointSize; var pointFormatID = event.data.pointFormatID; var scale = event.data.scale; var offset = event.data.offset; // event.data.mins // event.data.maxs var temp = new ArrayBuffer(4); var tempUint8 = new Uint8Array(temp); var tempUint16 = new Uint16Array(temp); var tempInt32 = new Int32Array(temp); var bufferView = new Uint8Array(buffer); var pBuff = new ArrayBuffer(numPoints * 3 * 4); var cBuff = new ArrayBuffer(numPoints * 3); var iBuff = new ArrayBuffer(numPoints * 4); var clBuff = new ArrayBuffer(numPoints); var rnBuff = new ArrayBuffer(numPoints); var nrBuff = new ArrayBuffer(numPoints); var psBuff = new ArrayBuffer(numPoints * 2); var positions = new Float32Array(pBuff); var colors = new Uint8Array(cBuff); var intensities = new Float32Array(iBuff); var classifications = new Uint8Array(clBuff); var returnNumbers = new Uint8Array(rnBuff); var numberOfReturns = new Uint8Array(nrBuff); var pointSourceIDs = new Uint16Array(psBuff); var 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]; // temp arrays seem to be significantly faster than DataViews // at the moment: http://jsperf.com/dataview-vs-temporary-float64array for (let i = 0; i < numPoints; i++) { // POSITION tempUint8[0] = bufferView[i * pointSize + 0]; tempUint8[1] = bufferView[i * pointSize + 1]; tempUint8[2] = bufferView[i * pointSize + 2]; tempUint8[3] = bufferView[i * pointSize + 3]; var x = tempInt32[0]; tempUint8[0] = bufferView[i * pointSize + 4]; tempUint8[1] = bufferView[i * pointSize + 5]; tempUint8[2] = bufferView[i * pointSize + 6]; tempUint8[3] = bufferView[i * pointSize + 7]; var y = tempInt32[0]; tempUint8[0] = bufferView[i * pointSize + 8]; tempUint8[1] = bufferView[i * pointSize + 9]; tempUint8[2] = bufferView[i * pointSize + 10]; tempUint8[3] = bufferView[i * pointSize + 11]; var z = tempInt32[0]; x = x * scale[0] + offset[0] - event.data.mins[0]; y = y * scale[1] + offset[1] - event.data.mins[1]; z = z * 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], positions[3 * i + 0]); tightBoundingBox.min[1] = Math.min(tightBoundingBox.min[1], positions[3 * i + 1]); tightBoundingBox.min[2] = Math.min(tightBoundingBox.min[2], positions[3 * i + 2]); tightBoundingBox.max[0] = Math.max(tightBoundingBox.max[0], positions[3 * i + 0]); tightBoundingBox.max[1] = Math.max(tightBoundingBox.max[1], positions[3 * i + 1]); tightBoundingBox.max[2] = Math.max(tightBoundingBox.max[2], positions[3 * i + 2]); // INTENSITY tempUint8[0] = bufferView[i * pointSize + 12]; tempUint8[1] = bufferView[i * pointSize + 13]; var intensity = tempUint16[0]; intensities[i] = intensity; // RETURN NUMBER, stored in the first 3 bits - 00000111 var returnNumber = bufferView[i * pointSize + 14] & 7; returnNumbers[i] = returnNumber; // NUMBER OF RETURNS, stored in 00111000 numberOfReturns[i] = (bufferView[i * pointSize + 14] & 56) / 8; // CLASSIFICATION var classification = bufferView[i * pointSize + 15]; classifications[i] = classification; // POINT SOURCE ID tempUint8[0] = bufferView[i * pointSize + 18]; tempUint8[1] = bufferView[i * pointSize + 19]; var pointSourceID = tempUint16[0]; pointSourceIDs[i] = pointSourceID; // COLOR, if available if (pointFormatID === 2) { tempUint8[0] = bufferView[i * pointSize + 20]; tempUint8[1] = bufferView[i * pointSize + 21]; var r = tempUint16[0]; tempUint8[0] = bufferView[i * pointSize + 22]; tempUint8[1] = bufferView[i * pointSize + 23]; var g = tempUint16[0]; tempUint8[0] = bufferView[i * pointSize + 24]; tempUint8[1] = bufferView[i * pointSize + 25]; var b = tempUint16[0]; colors[3 * i + 0] = r / 256; colors[3 * i + 1] = g / 256; colors[3 * i + 2] = b / 256; } } var indices = new ArrayBuffer(numPoints * 4); var iIndices = new Uint32Array(indices); for (let i = 0; i < numPoints; i++) { iIndices[i] = i; } var message = { mean: mean, position: pBuff, color: cBuff, intensity: iBuff, classification: clBuff, returnNumber: rnBuff, numberOfReturns: nrBuff, pointSourceID: psBuff, tightBoundingBox: tightBoundingBox, indices: indices }; var transferables = [ message.position, message.color, message.intensity, message.classification, message.returnNumber, message.numberOfReturns, message.pointSourceID, message.indices]; postMessage(message, transferables); };