UNPKG

potree

Version:

WebGL point cloud viewer - WORK IN PROGRESS

312 lines (258 loc) 8.78 kB
var baseLoaded = false; Potree.PointCloudGreyhoundGeometryNode = function ( name, pcoGeometry, boundingBox, scale, offset) { this.id = Potree.PointCloudGreyhoundGeometryNode.IDCount++; this.name = name; this.index = parseInt(name.charAt(name.length - 1)); this.pcoGeometry = pcoGeometry; this.geometry = null; this.boundingBox = boundingBox; this.boundingSphere = boundingBox.getBoundingSphere(); this.scale = scale; this.offset = offset; this.children = {}; this.numPoints = 0; this.level = null; this.loaded = false; this.oneTimeDisposeHandlers = []; let bounds = this.boundingBox.clone(); bounds.min.sub(this.pcoGeometry.boundingBox.getCenter()); bounds.max.sub(this.pcoGeometry.boundingBox.getCenter()); if (this.scale) { bounds.min.multiplyScalar(1 / this.scale); bounds.max.multiplyScalar(1 / this.scale); } // This represents the bounds for this node in the reference frame of the // global bounds from `info`, centered around the origin, and then scaled // by our selected scale. this.greyhoundBounds = bounds; // This represents the offset between the coordinate system described above // and our pcoGeometry bounds. this.greyhoundOffset = this.pcoGeometry.offset.clone().add( this.pcoGeometry.boundingBox.getSize().multiplyScalar(0.5) ); }; Potree.PointCloudGreyhoundGeometryNode.IDCount = 0; Potree.PointCloudGreyhoundGeometryNode.prototype = Object.create(Potree.PointCloudTreeNode.prototype); Potree.PointCloudGreyhoundGeometryNode.prototype.isGeometryNode = function () { return true; }; Potree.PointCloudGreyhoundGeometryNode.prototype.isTreeNode = function () { return false; }; Potree.PointCloudGreyhoundGeometryNode.prototype.isLoaded = function () { return this.loaded; }; Potree.PointCloudGreyhoundGeometryNode.prototype.getBoundingSphere = function () { return this.boundingSphere; }; Potree.PointCloudGreyhoundGeometryNode.prototype.getBoundingBox = function () { return this.boundingBox; }; Potree.PointCloudGreyhoundGeometryNode.prototype.getLevel = function () { return this.level; }; Potree.PointCloudGreyhoundGeometryNode.prototype.getChildren = function () { var children = []; for (var i = 0; i < 8; ++i) { if (this.children[i]) { children.push(this.children[i]); } } return children; }; Potree.PointCloudGreyhoundGeometryNode.prototype.getURL = function () { var schema = this.pcoGeometry.schema; let bounds = this.greyhoundBounds; var boundsString = bounds.min.x + ',' + bounds.min.y + ',' + bounds.min.z + ',' + bounds.max.x + ',' + bounds.max.y + ',' + bounds.max.z; var url = '' + this.pcoGeometry.serverURL + 'read?depthBegin=' + (baseLoaded ? (this.level + this.pcoGeometry.baseDepth) : 0) + '&depthEnd=' + (this.level + this.pcoGeometry.baseDepth + 1) + '&bounds=[' + boundsString + ']' + '&schema=' + JSON.stringify(schema) + '&compress=true'; if (this.scale) { url += '&scale=' + this.scale; } if (this.greyhoundOffset) { let offset = this.greyhoundOffset; url += '&offset=[' + offset.x + ',' + offset.y + ',' + offset.z + ']'; } if (!baseLoaded) baseLoaded = true; return url; }; Potree.PointCloudGreyhoundGeometryNode.prototype.addChild = function (child) { this.children[child.index] = child; child.parent = this; }; Potree.PointCloudGreyhoundGeometryNode.prototype.load = function () { if ( this.loading === true || this.loaded === true || this.pcoGeometry.numNodesLoading > 3) { return; } this.loading = true; this.pcoGeometry.numNodesLoading++; if ( this.level % this.pcoGeometry.hierarchyStepSize === 0 && this.hasChildren) { this.loadHierarchyThenPoints(); } else { this.loadPoints(); } }; Potree.PointCloudGreyhoundGeometryNode.prototype.loadPoints = function () { this.pcoGeometry.loader.load(this); }; Potree.PointCloudGreyhoundGeometryNode.prototype.loadHierarchyThenPoints = function () { // From Greyhound (Cartesian) ordering for the octree to Potree-default var transform = [0, 2, 1, 3, 4, 6, 5, 7]; var makeBitMask = function (node) { var mask = 0; Object.keys(node).forEach(function (key) { if (key === 'swd') mask += 1 << transform[0]; else if (key === 'nwd') mask += 1 << transform[1]; else if (key === 'swu') mask += 1 << transform[2]; else if (key === 'nwu') mask += 1 << transform[3]; else if (key === 'sed') mask += 1 << transform[4]; else if (key === 'ned') mask += 1 << transform[5]; else if (key === 'seu') mask += 1 << transform[6]; else if (key === 'neu') mask += 1 << transform[7]; }); return mask; }; var parseChildrenCounts = function (base, parentName, stack) { var keys = Object.keys(base); var child; var childName; keys.forEach(function (key) { if (key === 'n') return; switch (key) { case 'swd': child = base.swd; childName = parentName + transform[0]; break; case 'nwd': child = base.nwd; childName = parentName + transform[1]; break; case 'swu': child = base.swu; childName = parentName + transform[2]; break; case 'nwu': child = base.nwu; childName = parentName + transform[3]; break; case 'sed': child = base.sed; childName = parentName + transform[4]; break; case 'ned': child = base.ned; childName = parentName + transform[5]; break; case 'seu': child = base.seu; childName = parentName + transform[6]; break; case 'neu': child = base.neu; childName = parentName + transform[7]; break; default: break; } stack.push({ children: makeBitMask(child), numPoints: child.n, name: childName }); parseChildrenCounts(child, childName, stack); }); }; // Load hierarchy. var callback = function (node, greyhoundHierarchy) { var decoded = []; node.numPoints = greyhoundHierarchy.n; parseChildrenCounts(greyhoundHierarchy, node.name, decoded); var nodes = {}; nodes[node.name] = node; var pgg = node.pcoGeometry; for (var i = 0; i < decoded.length; i++) { var name = decoded[i].name; var numPoints = decoded[i].numPoints; var index = parseInt(name.charAt(name.length - 1)); var parentName = name.substring(0, name.length - 1); var parentNode = nodes[parentName]; var level = name.length - 1; var boundingBox = Potree.GreyhoundLoader.createChildAABB( parentNode.boundingBox, index); var currentNode = new Potree.PointCloudGreyhoundGeometryNode( name, pgg, boundingBox, node.scale, node.offset); currentNode.level = level; currentNode.numPoints = numPoints; currentNode.hasChildren = decoded[i].children > 0; currentNode.spacing = pgg.spacing / Math.pow(2, level); parentNode.addChild(currentNode); nodes[name] = currentNode; } node.loadPoints(); }; if (this.level % this.pcoGeometry.hierarchyStepSize === 0) { var depthBegin = this.level + this.pcoGeometry.baseDepth; var depthEnd = depthBegin + this.pcoGeometry.hierarchyStepSize + 2; let bounds = this.greyhoundBounds; var boundsString = bounds.min.x + ',' + bounds.min.y + ',' + bounds.min.z + ',' + bounds.max.x + ',' + bounds.max.y + ',' + bounds.max.z; var hurl = '' + this.pcoGeometry.serverURL + 'hierarchy?bounds=[' + boundsString + ']' + '&depthBegin=' + depthBegin + '&depthEnd=' + depthEnd; if (this.scale) { hurl += '&scale=' + this.scale; } if (this.greyhoundOffset) { let offset = this.greyhoundOffset; hurl += '&offset=[' + offset.x + ',' + offset.y + ',' + offset.z + ']'; } var xhr = new XMLHttpRequest(); xhr.open('GET', hurl, true); var that = this; xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200 || xhr.status === 0) { var greyhoundHierarchy = JSON.parse(xhr.responseText) || { }; callback(that, greyhoundHierarchy); } else { console.log( 'Failed to load file! HTTP status:', xhr.status, 'file:', hurl ); } } }; try { xhr.send(null); } catch (e) { console.log('fehler beim laden der punktwolke: ' + e); } } }; Potree.PointCloudGreyhoundGeometryNode.prototype.getNumPoints = function () { return this.numPoints; }; Potree.PointCloudGreyhoundGeometryNode.prototype.dispose = function () { if (this.geometry && this.parent != null) { this.geometry.dispose(); this.geometry = null; this.loaded = false; // this.dispatchEvent( { type: 'dispose' } ); for (var i = 0; i < this.oneTimeDisposeHandlers.length; i++) { var handler = this.oneTimeDisposeHandlers[i]; handler(); } this.oneTimeDisposeHandlers = []; } }; // THREE.EventDispatcher.prototype.apply( // Potree.PointCloudGreyhoundGeometryNode.prototype); Object.assign(Potree.PointCloudGreyhoundGeometryNode.prototype, THREE.EventDispatcher.prototype);