@loaders.gl/potree 4.3.0-alpha.5 → 4.3.0-alpha.6
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/dist/dist.dev.js +19531 -16
- package/dist/dist.min.js +21 -1
- package/dist/index.cjs +172 -16
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/lib/potree-node-source.d.ts +4 -4
- package/dist/lib/potree-node-source.d.ts.map +1 -1
- package/dist/lib/potree-node-source.js +10 -7
- package/dist/parsers/parse-potree-hierarchy-chunk.d.ts +21 -2
- package/dist/parsers/parse-potree-hierarchy-chunk.d.ts.map +1 -1
- package/dist/parsers/parse-potree-hierarchy-chunk.js +32 -18
- package/dist/potree-hierarchy-chunk-loader.js +1 -1
- package/dist/potree-loader.js +1 -1
- package/package.json +5 -5
- package/src/index.ts +1 -0
- package/src/lib/potree-node-source.ts +14 -11
- package/src/parsers/parse-potree-hierarchy-chunk.ts +52 -26
|
@@ -54,32 +54,53 @@ Would have an index looking like this:
|
|
|
54
54
|
| r36 | `0b00000000` (=0) | `1` |
|
|
55
55
|
*/
|
|
56
56
|
|
|
57
|
-
/**
|
|
57
|
+
/** Node metadata from index file */
|
|
58
58
|
export type POTreeTileHeader = {
|
|
59
|
+
/** Number of child nodes */
|
|
59
60
|
childCount: number;
|
|
61
|
+
/** Human readable name */
|
|
60
62
|
name: string;
|
|
63
|
+
/** Child availability mask */
|
|
61
64
|
childMask: number;
|
|
62
65
|
};
|
|
63
66
|
|
|
64
|
-
/**
|
|
67
|
+
/** Hierarchical potree node structure */
|
|
65
68
|
export type POTreeNode = {
|
|
69
|
+
/** Index data */
|
|
66
70
|
header: POTreeTileHeader;
|
|
71
|
+
/** Human readable name */
|
|
67
72
|
name: string;
|
|
73
|
+
/** Number of points */
|
|
68
74
|
pointCount: number;
|
|
75
|
+
/** Node's level in the tree */
|
|
76
|
+
level: number;
|
|
77
|
+
/** Has children */
|
|
78
|
+
hasChildren: boolean;
|
|
79
|
+
/** Space between points */
|
|
80
|
+
spacing: number;
|
|
81
|
+
/** Available children */
|
|
69
82
|
children: POTreeNode[];
|
|
83
|
+
/** All children including unavailable */
|
|
70
84
|
childrenByIndex: POTreeNode[];
|
|
71
85
|
};
|
|
72
86
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
87
|
+
/**
|
|
88
|
+
* load hierarchy
|
|
89
|
+
* @param arrayBuffer - binary index data
|
|
90
|
+
* @returns root node
|
|
91
|
+
**/
|
|
92
|
+
export function parsePotreeHierarchyChunk(arrayBuffer: ArrayBuffer): POTreeNode {
|
|
77
93
|
const tileHeaders = parseBinaryChunk(arrayBuffer);
|
|
78
94
|
return buildHierarchy(tileHeaders);
|
|
79
95
|
}
|
|
80
96
|
|
|
81
|
-
|
|
82
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Parses the binary rows
|
|
99
|
+
* @param arrayBuffer - binary index data to parse
|
|
100
|
+
* @param byteOffset - byte offset to start from
|
|
101
|
+
* @returns flat nodes array
|
|
102
|
+
* */
|
|
103
|
+
function parseBinaryChunk(arrayBuffer: ArrayBuffer, byteOffset = 0): POTreeNode[] {
|
|
83
104
|
const dataView = new DataView(arrayBuffer);
|
|
84
105
|
|
|
85
106
|
const stack: POTreeNode[] = [];
|
|
@@ -90,8 +111,7 @@ function parseBinaryChunk(arrayBuffer: ArrayBuffer, byteOffset = 0) {
|
|
|
90
111
|
byteOffset = decodeRow(dataView, byteOffset, topTileHeader);
|
|
91
112
|
|
|
92
113
|
stack.push(topTileHeader);
|
|
93
|
-
|
|
94
|
-
const tileHeaders: POTreeTileHeader[] = [];
|
|
114
|
+
const tileHeaders: POTreeNode[] = [topTileHeader];
|
|
95
115
|
|
|
96
116
|
while (stack.length > 0) {
|
|
97
117
|
const snode = stack.shift();
|
|
@@ -100,11 +120,10 @@ function parseBinaryChunk(arrayBuffer: ArrayBuffer, byteOffset = 0) {
|
|
|
100
120
|
for (let i = 0; i < 8; i++) {
|
|
101
121
|
if (snode && (snode.header.childMask & mask) !== 0) {
|
|
102
122
|
// @ts-expect-error
|
|
103
|
-
const tileHeader:
|
|
123
|
+
const tileHeader: POTreeNode = {};
|
|
104
124
|
byteOffset = decodeRow(dataView, byteOffset, tileHeader);
|
|
105
125
|
tileHeader.name = snode.name + i;
|
|
106
126
|
|
|
107
|
-
// @ts-expect-error
|
|
108
127
|
stack.push(tileHeader);
|
|
109
128
|
tileHeaders.push(tileHeader);
|
|
110
129
|
snode.header.childCount++;
|
|
@@ -120,7 +139,14 @@ function parseBinaryChunk(arrayBuffer: ArrayBuffer, byteOffset = 0) {
|
|
|
120
139
|
return tileHeaders;
|
|
121
140
|
}
|
|
122
141
|
|
|
123
|
-
|
|
142
|
+
/**
|
|
143
|
+
* Reads next row from binary index file
|
|
144
|
+
* @param dataView - index data
|
|
145
|
+
* @param byteOffset - current offset in the index data
|
|
146
|
+
* @param tileHeader - container to read to
|
|
147
|
+
* @returns new offset
|
|
148
|
+
*/
|
|
149
|
+
function decodeRow(dataView: DataView, byteOffset: number, tileHeader: POTreeNode): number {
|
|
124
150
|
tileHeader.header = tileHeader.header || {};
|
|
125
151
|
tileHeader.header.childMask = dataView.getUint8(byteOffset);
|
|
126
152
|
tileHeader.header.childCount = 0;
|
|
@@ -130,16 +156,16 @@ function decodeRow(dataView, byteOffset, tileHeader) {
|
|
|
130
156
|
return byteOffset;
|
|
131
157
|
}
|
|
132
158
|
|
|
133
|
-
|
|
134
|
-
function buildHierarchy(
|
|
159
|
+
/** Resolves the binary rows into a hierarchy (tree structure) */
|
|
160
|
+
function buildHierarchy(flatNodes: POTreeNode[], options: {spacing?: number} = {}): POTreeNode {
|
|
135
161
|
const DEFAULT_OPTIONS = {spacing: 100}; // TODO assert instead of default?
|
|
136
162
|
options = {...DEFAULT_OPTIONS, ...options};
|
|
137
163
|
|
|
138
|
-
const topNode =
|
|
164
|
+
const topNode: POTreeNode = flatNodes[0];
|
|
139
165
|
const nodes = {};
|
|
140
166
|
|
|
141
|
-
for (const
|
|
142
|
-
const {name} =
|
|
167
|
+
for (const node of flatNodes) {
|
|
168
|
+
const {name} = node;
|
|
143
169
|
|
|
144
170
|
const index = parseInt(name.charAt(name.length - 1), 10);
|
|
145
171
|
const parentName = name.substring(0, name.length - 1);
|
|
@@ -147,20 +173,20 @@ function buildHierarchy(tileHeaders, options: {spacing?: number} = {}): POTreeNo
|
|
|
147
173
|
const level = name.length - 1;
|
|
148
174
|
// assert(parentNode && level >= 0);
|
|
149
175
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
176
|
+
node.level = level;
|
|
177
|
+
node.hasChildren = Boolean(node.header.childCount);
|
|
178
|
+
node.children = [];
|
|
179
|
+
node.childrenByIndex = new Array(8).fill(null);
|
|
180
|
+
node.spacing = (options?.spacing || 0) / Math.pow(2, level);
|
|
155
181
|
// tileHeader.boundingVolume = Utils.createChildAABB(parentNode.boundingBox, index);
|
|
156
182
|
|
|
157
183
|
if (parentNode) {
|
|
158
|
-
parentNode.children.push(
|
|
159
|
-
parentNode.childrenByIndex[index] =
|
|
184
|
+
parentNode.children.push(node);
|
|
185
|
+
parentNode.childrenByIndex[index] = node;
|
|
160
186
|
}
|
|
161
187
|
|
|
162
188
|
// Add the node to the map
|
|
163
|
-
nodes[name] =
|
|
189
|
+
nodes[name] = node;
|
|
164
190
|
}
|
|
165
191
|
|
|
166
192
|
// First node is the root
|