@loaders.gl/potree 4.0.0-alpha.5 → 4.0.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -5
- package/dist/bundle.js +2 -2
- package/dist/es5/bundle.js +6 -0
- package/dist/es5/bundle.js.map +1 -0
- package/dist/es5/index.js +27 -0
- package/dist/es5/index.js.map +1 -0
- package/dist/es5/lib/octree.js +235 -0
- package/dist/es5/lib/octree.js.map +1 -0
- package/dist/es5/parsers/parse-potree-bin.js +10 -0
- package/dist/es5/parsers/parse-potree-bin.js.map +1 -0
- package/dist/es5/parsers/parse-potree-hierarchy-chunk.js +91 -0
- package/dist/es5/parsers/parse-potree-hierarchy-chunk.js.map +1 -0
- package/dist/es5/potree-bin-loader.js +24 -0
- package/dist/es5/potree-bin-loader.js.map +1 -0
- package/dist/es5/potree-hierarchy-chunk-loader.js +43 -0
- package/dist/es5/potree-hierarchy-chunk-loader.js.map +1 -0
- package/dist/es5/potree-loader.js +26 -0
- package/dist/es5/potree-loader.js.map +1 -0
- package/dist/esm/bundle.js +4 -0
- package/dist/esm/bundle.js.map +1 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lib/octree.js +194 -0
- package/dist/esm/lib/octree.js.map +1 -0
- package/dist/esm/parsers/parse-potree-bin.js +4 -0
- package/dist/esm/parsers/parse-potree-bin.js.map +1 -0
- package/dist/esm/parsers/parse-potree-hierarchy-chunk.js +74 -0
- package/dist/esm/parsers/parse-potree-hierarchy-chunk.js.map +1 -0
- package/dist/esm/potree-bin-loader.js +16 -0
- package/dist/esm/potree-bin-loader.js.map +1 -0
- package/dist/esm/potree-hierarchy-chunk-loader.js +14 -0
- package/dist/esm/potree-hierarchy-chunk-loader.js.map +1 -0
- package/dist/esm/potree-loader.js +15 -0
- package/dist/esm/potree-loader.js.map +1 -0
- package/dist/index.js +9 -4
- package/dist/lib/octree.js +191 -222
- package/dist/parsers/parse-potree-bin.js +5 -3
- package/dist/parsers/parse-potree-hierarchy-chunk.js +117 -71
- package/dist/potree-bin-loader.js +24 -14
- package/dist/potree-hierarchy-chunk-loader.js +20 -12
- package/dist/potree-loader.js +20 -14
- package/package.json +5 -5
- package/dist/bundle.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/octree.js.map +0 -1
- package/dist/parsers/parse-potree-bin.js.map +0 -1
- package/dist/parsers/parse-potree-hierarchy-chunk.js.map +0 -1
- package/dist/potree-bin-loader.js.map +0 -1
- package/dist/potree-hierarchy-chunk-loader.js.map +0 -1
- package/dist/potree-loader.js.map +0 -1
package/dist/lib/octree.js
CHANGED
|
@@ -1,228 +1,197 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.PointCloudOctant = exports.PointCloudOctree = void 0;
|
|
5
|
+
// @ts-nocheck
|
|
6
|
+
class PointCloudOctree {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.url = null;
|
|
9
|
+
this.octreeDir = null;
|
|
10
|
+
this.spacing = 0;
|
|
11
|
+
this.boundingBox = null;
|
|
12
|
+
this.root = null;
|
|
13
|
+
this.nodes = null;
|
|
14
|
+
this.pointAttributes = null;
|
|
15
|
+
this.hierarchyStepSize = -1;
|
|
16
|
+
this.loader = null;
|
|
17
|
+
}
|
|
14
18
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
getHierarchyPath() {
|
|
68
|
-
let path = 'r/';
|
|
69
|
-
let hierarchyStepSize = this.octree.hierarchyStepSize;
|
|
70
|
-
let indices = this.name.substr(1);
|
|
71
|
-
let numParts = Math.floor(indices.length / hierarchyStepSize);
|
|
72
|
-
|
|
73
|
-
for (let i = 0; i < numParts; i++) {
|
|
74
|
-
path += indices.substr(i * hierarchyStepSize, hierarchyStepSize) + '/';
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
path = path.slice(0, -1);
|
|
78
|
-
return path;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
addChild(child) {
|
|
82
|
-
this.children[child.index] = child;
|
|
83
|
-
child.parent = this;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
load() {
|
|
87
|
-
if (this.loading === true || this.loaded === true || Potree.numNodesLoading >= Potree.maxNodesLoading) {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
this.loading = true;
|
|
92
|
-
Potree.numNodesLoading++;
|
|
93
|
-
|
|
94
|
-
if (this.octree.loader.version.equalOrHigher('1.5')) {
|
|
95
|
-
if (this.level % this.octree.hierarchyStepSize === 0 && this.hasChildren) {
|
|
96
|
-
this.loadHierachyThenPoints();
|
|
97
|
-
} else {
|
|
98
|
-
this.loadPoints();
|
|
99
|
-
}
|
|
100
|
-
} else {
|
|
101
|
-
this.loadPoints();
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
loadPoints() {
|
|
106
|
-
this.octree.loader.load(this);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
loadHierachyThenPoints() {
|
|
110
|
-
let node = this;
|
|
111
|
-
|
|
112
|
-
let callback = function (node, hbuffer) {
|
|
113
|
-
let view = new DataView(hbuffer);
|
|
114
|
-
let stack = [];
|
|
115
|
-
let children = view.getUint8(0);
|
|
116
|
-
let numPoints = view.getUint32(1, true);
|
|
117
|
-
node.numPoints = numPoints;
|
|
118
|
-
stack.push({
|
|
119
|
-
children: children,
|
|
120
|
-
numPoints: numPoints,
|
|
121
|
-
name: node.name
|
|
122
|
-
});
|
|
123
|
-
let decoded = [];
|
|
124
|
-
let offset = 5;
|
|
125
|
-
|
|
126
|
-
while (stack.length > 0) {
|
|
127
|
-
let snode = stack.shift();
|
|
128
|
-
let mask = 1;
|
|
129
|
-
|
|
130
|
-
for (let i = 0; i < 8; i++) {
|
|
131
|
-
if ((snode.children & mask) !== 0) {
|
|
132
|
-
let childName = snode.name + i;
|
|
133
|
-
let childChildren = view.getUint8(offset);
|
|
134
|
-
let childNumPoints = view.getUint32(offset + 1, true);
|
|
135
|
-
stack.push({
|
|
136
|
-
children: childChildren,
|
|
137
|
-
numPoints: childNumPoints,
|
|
138
|
-
name: childName
|
|
139
|
-
});
|
|
140
|
-
decoded.push({
|
|
141
|
-
children: childChildren,
|
|
142
|
-
numPoints: childNumPoints,
|
|
143
|
-
name: childName
|
|
144
|
-
});
|
|
145
|
-
offset += 5;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
mask = mask * 2;
|
|
19
|
+
exports.PointCloudOctree = PointCloudOctree;
|
|
20
|
+
class PointCloudOctant {
|
|
21
|
+
constructor(name, octree, boundingBox) {
|
|
22
|
+
this.octree = this.id = PointCloudOctreeGeometryNode.IDCount++;
|
|
23
|
+
this.name = name;
|
|
24
|
+
this.index = parseInt(name.charAt(name.length - 1));
|
|
25
|
+
this.octree = octree;
|
|
26
|
+
this.geometry = null;
|
|
27
|
+
this.boundingBox = boundingBox;
|
|
28
|
+
this.boundingSphere = boundingBox.getBoundingSphere(new THREE.Sphere());
|
|
29
|
+
this.children = {};
|
|
30
|
+
this.numPoints = 0;
|
|
31
|
+
this.level = null;
|
|
32
|
+
this.loaded = false;
|
|
33
|
+
this.oneTimeDisposeHandlers = [];
|
|
34
|
+
}
|
|
35
|
+
isGeometryNode() {
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
getLevel() {
|
|
39
|
+
return this.level;
|
|
40
|
+
}
|
|
41
|
+
isTreeNode() {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
isLoaded() {
|
|
45
|
+
return this.loaded;
|
|
46
|
+
}
|
|
47
|
+
getBoundingSphere() {
|
|
48
|
+
return this.boundingSphere;
|
|
49
|
+
}
|
|
50
|
+
getBoundingBox() {
|
|
51
|
+
return this.boundingBox;
|
|
52
|
+
}
|
|
53
|
+
getChildren() {
|
|
54
|
+
// Children is a length 8 array with nulls for "missing" octants
|
|
55
|
+
return this.children.filter(Boolean);
|
|
56
|
+
}
|
|
57
|
+
getURL() {
|
|
58
|
+
const { version } = this.octree;
|
|
59
|
+
const hierarchyPath = version >= 1.5 ? `${this.getHierarchyPath()}/` : '';
|
|
60
|
+
return `${this.octree.octreeDir}/${hierarchyPath}${this.name}`;
|
|
61
|
+
}
|
|
62
|
+
getHierarchyPath() {
|
|
63
|
+
let path = 'r/';
|
|
64
|
+
let hierarchyStepSize = this.octree.hierarchyStepSize;
|
|
65
|
+
let indices = this.name.substr(1);
|
|
66
|
+
let numParts = Math.floor(indices.length / hierarchyStepSize);
|
|
67
|
+
for (let i = 0; i < numParts; i++) {
|
|
68
|
+
path += indices.substr(i * hierarchyStepSize, hierarchyStepSize) + '/';
|
|
149
69
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
70
|
+
path = path.slice(0, -1);
|
|
71
|
+
return path;
|
|
72
|
+
}
|
|
73
|
+
addChild(child) {
|
|
74
|
+
this.children[child.index] = child;
|
|
75
|
+
child.parent = this;
|
|
76
|
+
}
|
|
77
|
+
load() {
|
|
78
|
+
if (this.loading === true ||
|
|
79
|
+
this.loaded === true ||
|
|
80
|
+
Potree.numNodesLoading >= Potree.maxNodesLoading) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
this.loading = true;
|
|
84
|
+
Potree.numNodesLoading++;
|
|
85
|
+
if (this.octree.loader.version.equalOrHigher('1.5')) {
|
|
86
|
+
if (this.level % this.octree.hierarchyStepSize === 0 && this.hasChildren) {
|
|
87
|
+
this.loadHierachyThenPoints();
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
this.loadPoints();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
this.loadPoints();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
loadPoints() {
|
|
98
|
+
this.octree.loader.load(this);
|
|
99
|
+
}
|
|
100
|
+
loadHierachyThenPoints() {
|
|
101
|
+
let node = this;
|
|
102
|
+
// load hierarchy
|
|
103
|
+
let callback = function (node, hbuffer) {
|
|
104
|
+
let view = new DataView(hbuffer);
|
|
105
|
+
let stack = [];
|
|
106
|
+
let children = view.getUint8(0);
|
|
107
|
+
let numPoints = view.getUint32(1, true);
|
|
108
|
+
node.numPoints = numPoints;
|
|
109
|
+
stack.push({ children: children, numPoints: numPoints, name: node.name });
|
|
110
|
+
let decoded = [];
|
|
111
|
+
let offset = 5;
|
|
112
|
+
while (stack.length > 0) {
|
|
113
|
+
let snode = stack.shift();
|
|
114
|
+
let mask = 1;
|
|
115
|
+
for (let i = 0; i < 8; i++) {
|
|
116
|
+
if ((snode.children & mask) !== 0) {
|
|
117
|
+
let childName = snode.name + i;
|
|
118
|
+
let childChildren = view.getUint8(offset);
|
|
119
|
+
let childNumPoints = view.getUint32(offset + 1, true);
|
|
120
|
+
stack.push({ children: childChildren, numPoints: childNumPoints, name: childName });
|
|
121
|
+
decoded.push({ children: childChildren, numPoints: childNumPoints, name: childName });
|
|
122
|
+
offset += 5;
|
|
123
|
+
}
|
|
124
|
+
mask = mask * 2;
|
|
125
|
+
}
|
|
126
|
+
if (offset === hbuffer.byteLength) {
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// console.log(decoded);
|
|
131
|
+
let nodes = {};
|
|
132
|
+
nodes[node.name] = node;
|
|
133
|
+
let pco = node.pcoGeometry;
|
|
134
|
+
for (let i = 0; i < decoded.length; i++) {
|
|
135
|
+
let name = decoded[i].name;
|
|
136
|
+
let decodedNumPoints = decoded[i].numPoints;
|
|
137
|
+
let index = parseInt(name.charAt(name.length - 1));
|
|
138
|
+
let parentName = name.substring(0, name.length - 1);
|
|
139
|
+
let parentNode = nodes[parentName];
|
|
140
|
+
let level = name.length - 1;
|
|
141
|
+
let boundingBox = Utils.createChildAABB(parentNode.boundingBox, index);
|
|
142
|
+
let currentNode = new PointCloudOctreeGeometryNode(name, pco, boundingBox);
|
|
143
|
+
currentNode.level = level;
|
|
144
|
+
currentNode.numPoints = decodedNumPoints;
|
|
145
|
+
currentNode.hasChildren = decoded[i].children > 0;
|
|
146
|
+
currentNode.spacing = pco.spacing / Math.pow(2, level);
|
|
147
|
+
parentNode.addChild(currentNode);
|
|
148
|
+
nodes[name] = currentNode;
|
|
149
|
+
}
|
|
150
|
+
node.loadPoints();
|
|
151
|
+
};
|
|
152
|
+
if (node.level % node.pcoGeometry.hierarchyStepSize === 0) {
|
|
153
|
+
// let hurl = node.pcoGeometry.octreeDir + "/../hierarchy/" + node.name + ".hrc";
|
|
154
|
+
let hurl = node.pcoGeometry.octreeDir + '/' + node.getHierarchyPath() + '/' + node.name + '.hrc';
|
|
155
|
+
let xhr = XHRFactory.createXMLHttpRequest();
|
|
156
|
+
xhr.open('GET', hurl, true);
|
|
157
|
+
xhr.responseType = 'arraybuffer';
|
|
158
|
+
xhr.overrideMimeType('text/plain; charset=x-user-defined');
|
|
159
|
+
xhr.onreadystatechange = () => {
|
|
160
|
+
if (xhr.readyState === 4) {
|
|
161
|
+
if (xhr.status === 200 || xhr.status === 0) {
|
|
162
|
+
let hbuffer = xhr.response;
|
|
163
|
+
callback(node, hbuffer);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
console.log('Failed to load file! HTTP status: ' + xhr.status + ', file: ' + hurl);
|
|
167
|
+
Potree.numNodesLoading--;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
try {
|
|
172
|
+
xhr.send(null);
|
|
173
|
+
}
|
|
174
|
+
catch (e) {
|
|
175
|
+
console.log('fehler beim laden der punktwolke: ' + e);
|
|
176
|
+
}
|
|
153
177
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
currentNode.level = level;
|
|
170
|
-
currentNode.numPoints = decodedNumPoints;
|
|
171
|
-
currentNode.hasChildren = decoded[i].children > 0;
|
|
172
|
-
currentNode.spacing = pco.spacing / Math.pow(2, level);
|
|
173
|
-
parentNode.addChild(currentNode);
|
|
174
|
-
nodes[name] = currentNode;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
node.loadPoints();
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
if (node.level % node.pcoGeometry.hierarchyStepSize === 0) {
|
|
181
|
-
let hurl = node.pcoGeometry.octreeDir + '/' + node.getHierarchyPath() + '/' + node.name + '.hrc';
|
|
182
|
-
let xhr = XHRFactory.createXMLHttpRequest();
|
|
183
|
-
xhr.open('GET', hurl, true);
|
|
184
|
-
xhr.responseType = 'arraybuffer';
|
|
185
|
-
xhr.overrideMimeType('text/plain; charset=x-user-defined');
|
|
186
|
-
|
|
187
|
-
xhr.onreadystatechange = () => {
|
|
188
|
-
if (xhr.readyState === 4) {
|
|
189
|
-
if (xhr.status === 200 || xhr.status === 0) {
|
|
190
|
-
let hbuffer = xhr.response;
|
|
191
|
-
callback(node, hbuffer);
|
|
192
|
-
} else {
|
|
193
|
-
console.log('Failed to load file! HTTP status: ' + xhr.status + ', file: ' + hurl);
|
|
194
|
-
Potree.numNodesLoading--;
|
|
195
|
-
}
|
|
178
|
+
}
|
|
179
|
+
getNumPoints() {
|
|
180
|
+
return this.numPoints;
|
|
181
|
+
}
|
|
182
|
+
dispose() {
|
|
183
|
+
if (this.geometry && this.parent != null) {
|
|
184
|
+
this.geometry.dispose();
|
|
185
|
+
this.geometry = null;
|
|
186
|
+
this.loaded = false;
|
|
187
|
+
// this.dispatchEvent( { type: 'dispose' } );
|
|
188
|
+
for (let i = 0; i < this.oneTimeDisposeHandlers.length; i++) {
|
|
189
|
+
let handler = this.oneTimeDisposeHandlers[i];
|
|
190
|
+
handler();
|
|
191
|
+
}
|
|
192
|
+
this.oneTimeDisposeHandlers = [];
|
|
196
193
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
try {
|
|
200
|
-
xhr.send(null);
|
|
201
|
-
} catch (e) {
|
|
202
|
-
console.log('fehler beim laden der punktwolke: ' + e);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
getNumPoints() {
|
|
208
|
-
return this.numPoints;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
dispose() {
|
|
212
|
-
if (this.geometry && this.parent != null) {
|
|
213
|
-
this.geometry.dispose();
|
|
214
|
-
this.geometry = null;
|
|
215
|
-
this.loaded = false;
|
|
216
|
-
|
|
217
|
-
for (let i = 0; i < this.oneTimeDisposeHandlers.length; i++) {
|
|
218
|
-
let handler = this.oneTimeDisposeHandlers[i];
|
|
219
|
-
handler();
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
this.oneTimeDisposeHandlers = [];
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
194
|
+
}
|
|
226
195
|
}
|
|
196
|
+
exports.PointCloudOctant = PointCloudOctant;
|
|
227
197
|
PointCloudOctreeGeometryNode.IDCount = 0;
|
|
228
|
-
//# sourceMappingURL=octree.js.map
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
function parsePotreeBin(arrayBuffer, byteOffset, options, index) {
|
|
4
|
+
return null;
|
|
3
5
|
}
|
|
4
|
-
|
|
6
|
+
exports.default = parsePotreeBin;
|
|
@@ -1,83 +1,129 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
}
|
|
1
|
+
"use strict";
|
|
2
|
+
// This file is derived from the Cesium code base under BSD 2-clause license
|
|
3
|
+
// See LICENSE.md and https://github.com/potree/potree/blob/develop/LICENSE
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
// Potree Hierarchy Chunk file format
|
|
6
|
+
// https://github.com/potree/potree/blob/develop/docs/potree-file-format.md#index-files
|
|
7
|
+
/*
|
|
8
|
+
### Hierarchy Chunk Files
|
|
5
9
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const stack = [];
|
|
9
|
-
const topTileHeader = {};
|
|
10
|
-
byteOffset = decodeRow(dataView, byteOffset, topTileHeader);
|
|
11
|
-
stack.push(topTileHeader);
|
|
12
|
-
const tileHeaders = [];
|
|
10
|
+
As mentioned in the former section, the `.hrc` files contain the index structure
|
|
11
|
+
meaning a list of all the files stored within the directory tree.
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
An index file contains a list of tuple values with the first being a `uint8`
|
|
14
|
+
"mask" and the second being `uint32` "number of points" of a hierarchy level
|
|
15
|
+
in a [breadth first level order][breadth-first].
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const tileHeader = {};
|
|
21
|
-
byteOffset = decodeRow(dataView, byteOffset, tileHeader);
|
|
22
|
-
tileHeader.name = snode.name + i;
|
|
23
|
-
stack.push(tileHeader);
|
|
24
|
-
tileHeaders.push(tileHeader);
|
|
25
|
-
snode.header.childCount++;
|
|
26
|
-
}
|
|
17
|
+
Per hierarchy level we have 8 possible nodes. To indicate whether a node exists
|
|
18
|
+
a simple binary mask is used:
|
|
27
19
|
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
| Position | Mask | [Binary][bin] |
|
|
21
|
+
|----------|------|---------------|
|
|
22
|
+
| 0 | 1 | 0b00000001 |
|
|
23
|
+
| 1 | 2 | 0b00000010 |
|
|
24
|
+
| 2 | 4 | 0b00000100 |
|
|
25
|
+
| 3 | 8 | 0b00001000 |
|
|
26
|
+
| 4 | 16 | 0b00010000 |
|
|
27
|
+
| 5 | 32 | 0b00100000 |
|
|
28
|
+
| 6 | 64 | 0b01000000 |
|
|
29
|
+
| 7 | 128 | 0b10000000 |
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
}
|
|
31
|
+
So if in a hierarchy the child node 3 and node 7 exist then the hierarchies
|
|
32
|
+
mask has to be `0b00001000 | 0b10000000` → `0b10001000` (=136).
|
|
35
33
|
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
_Example:_ A simple, non-realistic tree:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
|- r1
|
|
38
|
+
| |
|
|
39
|
+
| \- r14 (2 Points)
|
|
40
|
+
|
|
|
41
|
+
\- r3
|
|
42
|
+
|
|
|
43
|
+
\- r36 (1 Point)
|
|
44
|
+
```
|
|
38
45
|
|
|
46
|
+
Would have an index looking like this:
|
|
47
|
+
|
|
48
|
+
| name | mask | points |
|
|
49
|
+
|------|--------------------|--------|
|
|
50
|
+
| r | `0b00001010` (=10) | `3` |
|
|
51
|
+
| r1 | `0b00010000` (=16) | `2` |
|
|
52
|
+
| r3 | `0b01000000` (=64) | `1` |
|
|
53
|
+
| r14 | `0b00000000` (=0) | `2` |
|
|
54
|
+
| r36 | `0b00000000` (=0) | `1` |
|
|
55
|
+
*/
|
|
56
|
+
// @ts-nocheck
|
|
57
|
+
// load hierarchy
|
|
58
|
+
function parsePotreeHierarchyChunk(arrayBuffer) {
|
|
59
|
+
const tileHeaders = parseBinaryChunk(arrayBuffer);
|
|
60
|
+
return buildHierarchy(tileHeaders);
|
|
61
|
+
}
|
|
62
|
+
exports.default = parsePotreeHierarchyChunk;
|
|
63
|
+
// Parses the binary rows
|
|
64
|
+
function parseBinaryChunk(arrayBuffer, byteOffset = 0) {
|
|
65
|
+
const dataView = new DataView(arrayBuffer);
|
|
66
|
+
const stack = [];
|
|
67
|
+
// Get root mask
|
|
68
|
+
const topTileHeader = {};
|
|
69
|
+
byteOffset = decodeRow(dataView, byteOffset, topTileHeader);
|
|
70
|
+
stack.push(topTileHeader);
|
|
71
|
+
const tileHeaders = [];
|
|
72
|
+
while (stack.length > 0) {
|
|
73
|
+
const snode = stack.shift();
|
|
74
|
+
let mask = 1;
|
|
75
|
+
for (let i = 0; i < 8; i++) {
|
|
76
|
+
if (snode && (snode.header.childMask & mask) !== 0) {
|
|
77
|
+
const tileHeader = {};
|
|
78
|
+
byteOffset = decodeRow(dataView, byteOffset, tileHeader);
|
|
79
|
+
tileHeader.name = snode.name + i;
|
|
80
|
+
stack.push(tileHeader);
|
|
81
|
+
tileHeaders.push(tileHeader);
|
|
82
|
+
snode.header.childCount++;
|
|
83
|
+
}
|
|
84
|
+
mask = mask * 2;
|
|
85
|
+
}
|
|
86
|
+
if (byteOffset === dataView.byteLength) {
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return tileHeaders;
|
|
91
|
+
}
|
|
39
92
|
function decodeRow(dataView, byteOffset, tileHeader) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
93
|
+
tileHeader.header = tileHeader.header || {};
|
|
94
|
+
tileHeader.header.childMask = dataView.getUint8(byteOffset);
|
|
95
|
+
tileHeader.header.childCount = 0;
|
|
96
|
+
tileHeader.pointCount = dataView.getUint32(byteOffset + 1, true);
|
|
97
|
+
tileHeader.name = '';
|
|
98
|
+
byteOffset += 5;
|
|
99
|
+
return byteOffset;
|
|
47
100
|
}
|
|
48
|
-
|
|
101
|
+
// Resolves the binary rows into a hierarchy (tree structure)
|
|
49
102
|
function buildHierarchy(tileHeaders, options = {}) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
if (parentNode) {
|
|
74
|
-
parentNode.children.push(tileHeader);
|
|
75
|
-
parentNode.childrenByIndex[index] = tileHeader;
|
|
103
|
+
const DEFAULT_OPTIONS = { spacing: 100 }; // TODO assert instead of default?
|
|
104
|
+
options = { ...DEFAULT_OPTIONS, ...options };
|
|
105
|
+
const topNode = tileHeaders[0];
|
|
106
|
+
const nodes = {};
|
|
107
|
+
for (const tileHeader of tileHeaders) {
|
|
108
|
+
const { name } = tileHeader;
|
|
109
|
+
const index = parseInt(name.charAt(name.length - 1), 10);
|
|
110
|
+
const parentName = name.substring(0, name.length - 1);
|
|
111
|
+
const parentNode = nodes[parentName];
|
|
112
|
+
const level = name.length - 1;
|
|
113
|
+
// assert(parentNode && level >= 0);
|
|
114
|
+
tileHeader.level = level;
|
|
115
|
+
tileHeader.hasChildren = tileHeader.header.childCount;
|
|
116
|
+
tileHeader.children = [];
|
|
117
|
+
tileHeader.childrenByIndex = new Array(8).fill(null);
|
|
118
|
+
tileHeader.spacing = options.spacing / Math.pow(2, level);
|
|
119
|
+
// tileHeader.boundingVolume = Utils.createChildAABB(parentNode.boundingBox, index);
|
|
120
|
+
if (parentNode) {
|
|
121
|
+
parentNode.children.push(tileHeader);
|
|
122
|
+
parentNode.childrenByIndex[index] = tileHeader;
|
|
123
|
+
}
|
|
124
|
+
// Add the node to the map
|
|
125
|
+
nodes[name] = tileHeader;
|
|
76
126
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return topNode;
|
|
127
|
+
// First node is the root
|
|
128
|
+
return topNode;
|
|
82
129
|
}
|
|
83
|
-
//# sourceMappingURL=parse-potree-hierarchy-chunk.js.map
|
|
@@ -1,17 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PotreeBinLoader = void 0;
|
|
7
|
+
const parse_potree_bin_1 = __importDefault(require("./parsers/parse-potree-bin"));
|
|
8
|
+
/**
|
|
9
|
+
* Loader for potree Binary Point Attributes
|
|
10
|
+
* */
|
|
11
|
+
// @ts-ignore
|
|
12
|
+
exports.PotreeBinLoader = {
|
|
13
|
+
name: 'potree Binary Point Attributes',
|
|
14
|
+
id: 'potree',
|
|
15
|
+
extensions: ['bin'],
|
|
16
|
+
mimeTypes: ['application/octet-stream'],
|
|
17
|
+
// Unfortunately binary potree files have no header bytes, no test possible
|
|
18
|
+
// test: ['...'],
|
|
19
|
+
parseSync,
|
|
20
|
+
binary: true
|
|
9
21
|
};
|
|
10
|
-
|
|
11
22
|
function parseSync(arrayBuffer, options) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
23
|
+
const index = {};
|
|
24
|
+
const byteOffset = 0;
|
|
25
|
+
(0, parse_potree_bin_1.default)(arrayBuffer, byteOffset, options, index);
|
|
26
|
+
return index;
|
|
16
27
|
}
|
|
17
|
-
//# sourceMappingURL=potree-bin-loader.js.map
|