Skip to content

Commit 4cc3128

Browse files
committed
update new format loader
1 parent 8f24dae commit 4cc3128

File tree

7 files changed

+224
-105
lines changed

7 files changed

+224
-105
lines changed

.github/PULL_REQUEST_TEMPLATE.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
Please follow these instructions when creating a new pull request:
33

4+
* Validating PRs can take a lot of time. The simpler the PR, the higher the chance that it will get accepted.
45
* Set the potree develop branch as the PR target.
56
* Builds should not be part of the PR. Don't commit them.
67
* Do not use a formatter. They make a mess out of diffs.

src/PointCloudOctree.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,21 @@ export class PointCloudOctree extends PointCloudTree {
372372
data[parentOffset * 4 + 2] = (offsetsToChild[parentOffset] % 256);
373373
}
374374

375-
data[i * 4 + 3] = node.name.length - 1;
375+
// data[i * 4 + 3] = node.geometryNode.nodeType === 1 ? 1 : 0;
376+
// data[i * 4 + 3] = node.name.length - 1;
377+
378+
let density = node.geometryNode.density;
379+
380+
if(typeof density === "number"){
381+
let lodOffset = Math.log2(density) / 2 - 1.5;
382+
383+
let offsetUint8 = (lodOffset + 10) * 10;
384+
385+
data[i * 4 + 3] = offsetUint8;
386+
}else{
387+
data[i * 4 + 3] = 100;
388+
}
389+
376390
}
377391

378392
var a = 10;

src/Potree.js

+86-38
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export * from "./materials/NormalizationMaterial.js";
3232
export * from "./materials/PointCloudMaterial.js";
3333

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

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

128130

129131
export function loadPointCloud(path, name, callback){
130-
let loaded = function(pointcloud){
131-
pointcloud.name = name;
132-
callback({type: 'pointcloud_loaded', pointcloud: pointcloud});
132+
let loaded = function(e){
133+
e.pointcloud.name = name;
134+
callback(e);
133135
};
134136

135-
// load pointcloud
136-
if (!path){
137-
// TODO: callback? comment? Hello? Bueller? Anyone?
138-
} else if (path.indexOf('ept.json') > 0) {
139-
EptLoader.load(path, function(geometry) {
140-
if (!geometry) {
141-
console.error(new Error(`failed to load point cloud from URL: ${path}`));
142-
}
143-
else {
144-
let pointcloud = new PointCloudOctree(geometry);
145-
loaded(pointcloud);
146-
}
147-
});
148-
} else if (path.indexOf('cloud.js') > 0) {
149-
POCLoader.load(path, function (geometry) {
150-
if (!geometry) {
151-
//callback({type: 'loading_failed'});
152-
console.error(new Error(`failed to load point cloud from URL: ${path}`));
153-
} else {
154-
let pointcloud = new PointCloudOctree(geometry);
155-
loaded(pointcloud);
156-
}
157-
});
158-
} else if (path.indexOf('.vpc') > 0) {
159-
PointCloudArena4DGeometry.load(path, function (geometry) {
160-
if (!geometry) {
161-
//callback({type: 'loading_failed'});
162-
console.error(new Error(`failed to load point cloud from URL: ${path}`));
163-
} else {
164-
let pointcloud = new PointCloudArena4D(geometry);
165-
loaded(pointcloud);
166-
}
137+
let promise = new Promise( resolve => {
138+
139+
// load pointcloud
140+
if (!path){
141+
// TODO: callback? comment? Hello? Bueller? Anyone?
142+
} else if (path.indexOf('ept.json') > 0) {
143+
EptLoader.load(path, function(geometry) {
144+
if (!geometry) {
145+
console.error(new Error(`failed to load point cloud from URL: ${path}`));
146+
}
147+
else {
148+
let pointcloud = new PointCloudOctree(geometry);
149+
//loaded(pointcloud);
150+
resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
151+
}
152+
});
153+
} else if (path.indexOf('cloud.js') > 0) {
154+
POCLoader.load(path, function (geometry) {
155+
if (!geometry) {
156+
//callback({type: 'loading_failed'});
157+
console.error(new Error(`failed to load point cloud from URL: ${path}`));
158+
} else {
159+
let pointcloud = new PointCloudOctree(geometry);
160+
// loaded(pointcloud);
161+
resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
162+
}
163+
});
164+
} else if (path.indexOf('metadata.json') > 0) {
165+
Potree.OctreeLoader_1_8.load(path).then(e => {
166+
let geometry = e.geometry;
167+
168+
if(!geometry){
169+
console.error(new Error(`failed to load point cloud from URL: ${path}`));
170+
}else{
171+
let pointcloud = new PointCloudOctree(geometry);
172+
173+
let aPosition = pointcloud.getAttribute("position");
174+
175+
let material = pointcloud.material;
176+
material.elevationRange = [
177+
aPosition.range[0][2],
178+
aPosition.range[1][2],
179+
];
180+
181+
// loaded(pointcloud);
182+
resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
183+
}
184+
});
185+
186+
OctreeLoader_1_8.load(path, function (geometry) {
187+
if (!geometry) {
188+
//callback({type: 'loading_failed'});
189+
console.error(new Error(`failed to load point cloud from URL: ${path}`));
190+
} else {
191+
let pointcloud = new PointCloudOctree(geometry);
192+
// loaded(pointcloud);
193+
resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
194+
}
195+
});
196+
} else if (path.indexOf('.vpc') > 0) {
197+
PointCloudArena4DGeometry.load(path, function (geometry) {
198+
if (!geometry) {
199+
//callback({type: 'loading_failed'});
200+
console.error(new Error(`failed to load point cloud from URL: ${path}`));
201+
} else {
202+
let pointcloud = new PointCloudArena4D(geometry);
203+
// loaded(pointcloud);
204+
resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
205+
}
206+
});
207+
} else {
208+
//callback({'type': 'loading_failed'});
209+
console.error(new Error(`failed to load point cloud from URL: ${path}`));
210+
}
211+
});
212+
213+
if(callback){
214+
promise.then(pointcloud => {
215+
loaded(pointcloud);
167216
});
168-
} else {
169-
//callback({'type': 'loading_failed'});
170-
console.error(new Error(`failed to load point cloud from URL: ${path}`));
217+
}else{
218+
return promise;
171219
}
172220
};
173221

src/materials/shaders/pointcloud.vs

+40-7
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,35 @@ float getLOD(){
240240
depth++;
241241
}else{
242242
// no more visible child nodes at this position
243-
return value.a * 255.0;
244-
//return depth;
243+
//return value.a * 255.0;
244+
245+
float lodOffset = (255.0 * value.a) / 10.0 - 10.0;
246+
247+
return depth + lodOffset;
248+
249+
// if(255.0 * value.a < 4.0){
250+
// return depth - 0.5;
251+
// }if(255.0 * value.a < 12.0){
252+
// return depth;
253+
// }else if(255.0 * value.a < 24.0){
254+
// return depth + 1.0;
255+
// }else if(255.0 * value.a < 48.0){
256+
// return depth + 1.5;
257+
// }else{
258+
// return depth + 2.0;
259+
// }
260+
261+
// return depth;
262+
263+
// test
264+
// bool isLeaf = value.a > 0.0;
265+
266+
// if(isLeaf){
267+
// return 1000.0;
268+
// }else{
269+
// //return value.a * 255.0;
270+
// return depth;
271+
// }
245272
}
246273

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

686-
if(uIsLeafNode && false){
687-
pointSize = size * spacing * projFactor;
688-
}else{
713+
// float leafSpacing = 0.122069092 * 8.0;
714+
715+
// bool isLeafNode = getLOD() == 1000.0;
716+
// if(isLeafNode){
717+
// // pointSize = size * spacing * projFactor;
718+
719+
// float worldSpaceSize = size * leafSpacing;
720+
// pointSize = worldSpaceSize * projFactor;
721+
// }else{
689722
float worldSpaceSize = 1.0 * size * r / getPointSizeAttenuation();
690723

691724
// minimum world space size
692-
// worldSpaceSize = max(worldSpaceSize, 0.02);
725+
// worldSpaceSize = max(worldSpaceSize, leafSpacing);
693726

694727
pointSize = worldSpaceSize * projFactor;
695-
}
728+
// }
696729
}
697730
#endif
698731

src/modules/Loader_1.8/OctreeDecoderWorker.js

+35-34
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Potree = {};
2020

2121
onmessage = function (event) {
2222

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

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

36+
let gridSize = 32;
37+
let grid = new Uint32Array(gridSize ** 3);
38+
let toIndex = (x, y, z) => {
39+
// let dx = gridSize * (x - min.x) / size.x;
40+
// let dy = gridSize * (y - min.y) / size.y;
41+
// let dz = gridSize * (z - min.z) / size.z;
42+
43+
// min is already subtracted
44+
let dx = gridSize * x / size.x;
45+
let dy = gridSize * y / size.y;
46+
let dz = gridSize * z / size.z;
47+
48+
let ix = Math.min(parseInt(dx), gridSize - 1);
49+
let iy = Math.min(parseInt(dy), gridSize - 1);
50+
let iz = Math.min(parseInt(dz), gridSize - 1);
51+
52+
let index = ix + iy * gridSize + iz * gridSize * gridSize;
53+
54+
return index;
55+
};
56+
57+
let numOccupiedCells = 0;
3658
for (let pointAttribute of pointAttributes.attributes) {
3759

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

72+
let index = toIndex(x, y, z);
73+
let count = grid[index]++;
74+
if(count === 0){
75+
numOccupiedCells++;
76+
}
77+
5078
positions[3 * j + 0] = x;
5179
positions[3 * j + 1] = y;
5280
positions[3 * j + 2] = z;
@@ -74,71 +102,40 @@ onmessage = function (event) {
74102
let buff = new ArrayBuffer(numPoints * 4);
75103
let f32 = new Float32Array(buff);
76104

77-
// console.log(pointAttribute.name, pointAttribute.type.name);
78-
79105
let TypedArray = typedArrayMapping[pointAttribute.type.name];
80106
preciseBuffer = new TypedArray(numPoints);
81107

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

85110
const getterMap = {
86111
"int8": view.getInt8,
87112
"int16": view.getInt16,
88113
"int32": view.getInt32,
89-
"int64": view.getInt64,
114+
// "int64": view.getInt64,
90115
"uint8": view.getUint8,
91116
"uint16": view.getUint16,
92117
"uint32": view.getUint32,
93-
"uint64": view.getUint64,
118+
// "uint64": view.getUint64,
94119
"float": view.getFloat32,
95120
"double": view.getFloat64,
96121
};
97122
const getter = getterMap[pointAttribute.type.name].bind(view);
98123

99124
// compute offset and scale to pack larger types into 32 bit floats
100125
if(pointAttribute.type.size > 4){
101-
102126
let [amin, amax] = pointAttribute.range;
103127
offset = amin;
104128
scale = 1 / (amax - amin);
105-
106-
// for(let j = 0; j < numPoints; j++){
107-
// let pointOffset = j * bytesPerPoint;
108-
// let value = getter(pointOffset + attributeOffset, true);
109-
110-
// if(!Number.isNaN(value)){
111-
// min = Math.min(min, value);
112-
// max = Math.max(max, value);
113-
// }
114-
// }
115-
116-
// if(pointAttribute.initialRange != null){
117-
// offset = pointAttribute.initialRange[0];
118-
// scale = 1 / (pointAttribute.initialRange[1] - pointAttribute.initialRange[0]);
119-
// }else{
120-
// offset = min;
121-
// scale = 1 / (max - min);
122-
// }
123129
}
124130

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

129-
if(!Number.isNaN(value)){
130-
min = Math.min(min, value);
131-
max = Math.max(max, value);
132-
}
133-
134135
f32[j] = (value - offset) * scale;
135136
preciseBuffer[j] = value;
136137
}
137138

138-
// pointAttribute.range = [min, max];
139-
140-
//console.log(pointAttribute.range);
141-
//attributeBuffers[pointAttribute.name] = { buffer: buff, attribute: pointAttribute };
142139
attributeBuffers[pointAttribute.name] = {
143140
buffer: buff,
144141
preciseBuffer: preciseBuffer,
@@ -153,6 +150,9 @@ onmessage = function (event) {
153150

154151
}
155152

153+
let occupancy = parseInt(numPoints / numOccupiedCells);
154+
// console.log(`${name}: #points: ${numPoints}: #occupiedCells: ${numOccupiedCells}, occupancy: ${occupancy} points/cell`);
155+
156156
{ // add indices
157157
let buff = new ArrayBuffer(numPoints * 4);
158158
let indices = new Uint32Array(buff);
@@ -208,6 +208,7 @@ onmessage = function (event) {
208208
let message = {
209209
buffer: buffer,
210210
attributeBuffers: attributeBuffers,
211+
density: occupancy,
211212
};
212213

213214
let transferables = [];

0 commit comments

Comments
 (0)