Skip to content
Permalink
Browse files
update new format loader
  • Loading branch information
potree committed Jul 28, 2020
1 parent 8f24dae commit 4cc31281d77e9d456a8075026228f3e271479a8f
Showing 7 changed files with 224 additions and 105 deletions.
@@ -1,6 +1,7 @@

Please follow these instructions when creating a new pull request:

* Validating PRs can take a lot of time. The simpler the PR, the higher the chance that it will get accepted.
* Set the potree develop branch as the PR target.
* Builds should not be part of the PR. Don't commit them.
* Do not use a formatter. They make a mess out of diffs.
@@ -372,7 +372,21 @@ export class PointCloudOctree extends PointCloudTree {
data[parentOffset * 4 + 2] = (offsetsToChild[parentOffset] % 256);
}

data[i * 4 + 3] = node.name.length - 1;
// data[i * 4 + 3] = node.geometryNode.nodeType === 1 ? 1 : 0;
// data[i * 4 + 3] = node.name.length - 1;

let density = node.geometryNode.density;

if(typeof density === "number"){
let lodOffset = Math.log2(density) / 2 - 1.5;

let offsetUint8 = (lodOffset + 10) * 10;

data[i * 4 + 3] = offsetUint8;
}else{
data[i * 4 + 3] = 100;
}

}

var a = 10;
@@ -32,6 +32,7 @@ export * from "./materials/NormalizationMaterial.js";
export * from "./materials/PointCloudMaterial.js";

export * from "./loader/POCLoader.js";
export * from "./modules/Loader_1.8/OctreeLoader_1_8.js";
export * from "./loader/EptLoader.js";
export * from "./loader/ept/BinaryLoader.js";
export * from "./loader/ept/LaszipLoader.js";
@@ -79,6 +80,7 @@ import "./extensions/PerspectiveCamera.js";
import "./extensions/Ray.js";

import {LRU} from "./LRU.js";
import {OctreeLoader_1_8} from "./modules/Loader_1.8/OctreeLoader_1_8.js";
import {POCLoader} from "./loader/POCLoader.js";
import {EptLoader} from "./loader/EptLoader.js";
import {PointCloudOctree} from "./PointCloudOctree.js";
@@ -127,47 +129,93 @@ export {scriptPath, resourcePath};


export function loadPointCloud(path, name, callback){
let loaded = function(pointcloud){
pointcloud.name = name;
callback({type: 'pointcloud_loaded', pointcloud: pointcloud});
let loaded = function(e){
e.pointcloud.name = name;
callback(e);
};

// load pointcloud
if (!path){
// TODO: callback? comment? Hello? Bueller? Anyone?
} else if (path.indexOf('ept.json') > 0) {
EptLoader.load(path, function(geometry) {
if (!geometry) {
console.error(new Error(`failed to load point cloud from URL: ${path}`));
}
else {
let pointcloud = new PointCloudOctree(geometry);
loaded(pointcloud);
}
});
} else if (path.indexOf('cloud.js') > 0) {
POCLoader.load(path, function (geometry) {
if (!geometry) {
//callback({type: 'loading_failed'});
console.error(new Error(`failed to load point cloud from URL: ${path}`));
} else {
let pointcloud = new PointCloudOctree(geometry);
loaded(pointcloud);
}
});
} else if (path.indexOf('.vpc') > 0) {
PointCloudArena4DGeometry.load(path, function (geometry) {
if (!geometry) {
//callback({type: 'loading_failed'});
console.error(new Error(`failed to load point cloud from URL: ${path}`));
} else {
let pointcloud = new PointCloudArena4D(geometry);
loaded(pointcloud);
}
let promise = new Promise( resolve => {

// load pointcloud
if (!path){
// TODO: callback? comment? Hello? Bueller? Anyone?
} else if (path.indexOf('ept.json') > 0) {
EptLoader.load(path, function(geometry) {
if (!geometry) {
console.error(new Error(`failed to load point cloud from URL: ${path}`));
}
else {
let pointcloud = new PointCloudOctree(geometry);
//loaded(pointcloud);
resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
}
});
} else if (path.indexOf('cloud.js') > 0) {
POCLoader.load(path, function (geometry) {
if (!geometry) {
//callback({type: 'loading_failed'});
console.error(new Error(`failed to load point cloud from URL: ${path}`));
} else {
let pointcloud = new PointCloudOctree(geometry);
// loaded(pointcloud);
resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
}
});
} else if (path.indexOf('metadata.json') > 0) {
Potree.OctreeLoader_1_8.load(path).then(e => {
let geometry = e.geometry;

if(!geometry){
console.error(new Error(`failed to load point cloud from URL: ${path}`));
}else{
let pointcloud = new PointCloudOctree(geometry);

let aPosition = pointcloud.getAttribute("position");

let material = pointcloud.material;
material.elevationRange = [
aPosition.range[0][2],
aPosition.range[1][2],
];

// loaded(pointcloud);
resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
}
});

OctreeLoader_1_8.load(path, function (geometry) {
if (!geometry) {
//callback({type: 'loading_failed'});
console.error(new Error(`failed to load point cloud from URL: ${path}`));
} else {
let pointcloud = new PointCloudOctree(geometry);
// loaded(pointcloud);
resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
}
});
} else if (path.indexOf('.vpc') > 0) {
PointCloudArena4DGeometry.load(path, function (geometry) {
if (!geometry) {
//callback({type: 'loading_failed'});
console.error(new Error(`failed to load point cloud from URL: ${path}`));
} else {
let pointcloud = new PointCloudArena4D(geometry);
// loaded(pointcloud);
resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
}
});
} else {
//callback({'type': 'loading_failed'});
console.error(new Error(`failed to load point cloud from URL: ${path}`));
}
});

if(callback){
promise.then(pointcloud => {
loaded(pointcloud);
});
} else {
//callback({'type': 'loading_failed'});
console.error(new Error(`failed to load point cloud from URL: ${path}`));
}else{
return promise;
}
};

@@ -240,8 +240,35 @@ float getLOD(){
depth++;
}else{
// no more visible child nodes at this position
return value.a * 255.0;
//return depth;
//return value.a * 255.0;

float lodOffset = (255.0 * value.a) / 10.0 - 10.0;

return depth + lodOffset;

// if(255.0 * value.a < 4.0){
// return depth - 0.5;
// }if(255.0 * value.a < 12.0){
// return depth;
// }else if(255.0 * value.a < 24.0){
// return depth + 1.0;
// }else if(255.0 * value.a < 48.0){
// return depth + 1.5;
// }else{
// return depth + 2.0;
// }

// return depth;

// test
// bool isLeaf = value.a > 0.0;

// if(isLeaf){
// return 1000.0;
// }else{
// //return value.a * 255.0;
// return depth;
// }
}

offset = offset + (vec3(1.0, 1.0, 1.0) * nodeSizeAtLevel * 0.5) * index3d;
@@ -683,16 +710,22 @@ float getPointSize(){
pointSize = (worldSpaceSize / uOrthoWidth) * uScreenWidth;
} else {

if(uIsLeafNode && false){
pointSize = size * spacing * projFactor;
}else{
// float leafSpacing = 0.122069092 * 8.0;

// bool isLeafNode = getLOD() == 1000.0;
// if(isLeafNode){
// // pointSize = size * spacing * projFactor;

// float worldSpaceSize = size * leafSpacing;
// pointSize = worldSpaceSize * projFactor;
// }else{
float worldSpaceSize = 1.0 * size * r / getPointSizeAttenuation();

// minimum world space size
// worldSpaceSize = max(worldSpaceSize, 0.02);
// worldSpaceSize = max(worldSpaceSize, leafSpacing);

pointSize = worldSpaceSize * projFactor;
}
// }
}
#endif

@@ -20,7 +20,7 @@ Potree = {};

onmessage = function (event) {

let {buffer, pointAttributes, scale, min, offset} = event.data;
let {buffer, pointAttributes, scale, name, min, max, size, offset} = event.data;

let numPoints = buffer.byteLength / pointAttributes.byteSize;
let view = new DataView(buffer);
@@ -33,6 +33,28 @@ onmessage = function (event) {
bytesPerPoint += pointAttribute.byteSize;
}

let gridSize = 32;
let grid = new Uint32Array(gridSize ** 3);
let toIndex = (x, y, z) => {
// let dx = gridSize * (x - min.x) / size.x;
// let dy = gridSize * (y - min.y) / size.y;
// let dz = gridSize * (z - min.z) / size.z;

// min is already subtracted
let dx = gridSize * x / size.x;
let dy = gridSize * y / size.y;
let dz = gridSize * z / size.z;

let ix = Math.min(parseInt(dx), gridSize - 1);
let iy = Math.min(parseInt(dy), gridSize - 1);
let iz = Math.min(parseInt(dz), gridSize - 1);

let index = ix + iy * gridSize + iz * gridSize * gridSize;

return index;
};

let numOccupiedCells = 0;
for (let pointAttribute of pointAttributes.attributes) {

if(["POSITION_CARTESIAN", "position"].includes(pointAttribute.name)){
@@ -47,6 +69,12 @@ onmessage = function (event) {
let y = (view.getUint32(pointOffset + attributeOffset + 4, true) * scale[1]) + offset[1] - min.y;
let z = (view.getUint32(pointOffset + attributeOffset + 8, true) * scale[2]) + offset[2] - min.z;

let index = toIndex(x, y, z);
let count = grid[index]++;
if(count === 0){
numOccupiedCells++;
}

positions[3 * j + 0] = x;
positions[3 * j + 1] = y;
positions[3 * j + 2] = z;
@@ -74,71 +102,40 @@ onmessage = function (event) {
let buff = new ArrayBuffer(numPoints * 4);
let f32 = new Float32Array(buff);

// console.log(pointAttribute.name, pointAttribute.type.name);

let TypedArray = typedArrayMapping[pointAttribute.type.name];
preciseBuffer = new TypedArray(numPoints);

let [min, max] = [Infinity, -Infinity];
let [offset, scale] = [0, 1];

const getterMap = {
"int8": view.getInt8,
"int16": view.getInt16,
"int32": view.getInt32,
"int64": view.getInt64,
// "int64": view.getInt64,
"uint8": view.getUint8,
"uint16": view.getUint16,
"uint32": view.getUint32,
"uint64": view.getUint64,
// "uint64": view.getUint64,
"float": view.getFloat32,
"double": view.getFloat64,
};
const getter = getterMap[pointAttribute.type.name].bind(view);

// compute offset and scale to pack larger types into 32 bit floats
if(pointAttribute.type.size > 4){

let [amin, amax] = pointAttribute.range;
offset = amin;
scale = 1 / (amax - amin);

// for(let j = 0; j < numPoints; j++){
// let pointOffset = j * bytesPerPoint;
// let value = getter(pointOffset + attributeOffset, true);

// if(!Number.isNaN(value)){
// min = Math.min(min, value);
// max = Math.max(max, value);
// }
// }

// if(pointAttribute.initialRange != null){
// offset = pointAttribute.initialRange[0];
// scale = 1 / (pointAttribute.initialRange[1] - pointAttribute.initialRange[0]);
// }else{
// offset = min;
// scale = 1 / (max - min);
// }
}

for(let j = 0; j < numPoints; j++){
let pointOffset = j * bytesPerPoint;
let value = getter(pointOffset + attributeOffset, true);

if(!Number.isNaN(value)){
min = Math.min(min, value);
max = Math.max(max, value);
}

f32[j] = (value - offset) * scale;
preciseBuffer[j] = value;
}

// pointAttribute.range = [min, max];

//console.log(pointAttribute.range);
//attributeBuffers[pointAttribute.name] = { buffer: buff, attribute: pointAttribute };
attributeBuffers[pointAttribute.name] = {
buffer: buff,
preciseBuffer: preciseBuffer,
@@ -153,6 +150,9 @@ onmessage = function (event) {

}

let occupancy = parseInt(numPoints / numOccupiedCells);
// console.log(`${name}: #points: ${numPoints}: #occupiedCells: ${numOccupiedCells}, occupancy: ${occupancy} points/cell`);

{ // add indices
let buff = new ArrayBuffer(numPoints * 4);
let indices = new Uint32Array(buff);
@@ -208,6 +208,7 @@ onmessage = function (event) {
let message = {
buffer: buffer,
attributeBuffers: attributeBuffers,
density: occupancy,
};

let transferables = [];

0 comments on commit 4cc3128

Please sign in to comment.