@loaders.gl/pcd 4.0.0-alpha.4 → 4.0.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/bundle.d.ts +2 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +2 -2
- package/dist/dist.min.js +476 -0
- package/dist/es5/bundle.js +6 -0
- package/dist/es5/bundle.js.map +1 -0
- package/dist/es5/index.js +45 -0
- package/dist/es5/index.js.map +1 -0
- package/dist/es5/lib/decompress-lzf.js +57 -0
- package/dist/es5/lib/decompress-lzf.js.map +1 -0
- package/dist/es5/lib/get-pcd-schema.js +54 -0
- package/dist/es5/lib/get-pcd-schema.js.map +1 -0
- package/dist/es5/lib/parse-pcd.js +299 -0
- package/dist/es5/lib/parse-pcd.js.map +1 -0
- package/dist/es5/lib/pcd-types.js +2 -0
- package/dist/es5/lib/pcd-types.js.map +1 -0
- package/dist/es5/pcd-loader.js +21 -0
- package/dist/es5/pcd-loader.js.map +1 -0
- package/dist/es5/workers/pcd-worker.js +6 -0
- package/dist/es5/workers/pcd-worker.js.map +1 -0
- package/dist/esm/bundle.js +4 -0
- package/dist/esm/bundle.js.map +1 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lib/decompress-lzf.js +51 -0
- package/dist/esm/lib/decompress-lzf.js.map +1 -0
- package/dist/esm/lib/get-pcd-schema.js +48 -0
- package/dist/esm/lib/get-pcd-schema.js.map +1 -0
- package/dist/esm/lib/parse-pcd.js +289 -0
- package/dist/esm/lib/parse-pcd.js.map +1 -0
- package/dist/esm/lib/pcd-types.js +2 -0
- package/dist/esm/lib/pcd-types.js.map +1 -0
- package/dist/esm/pcd-loader.js +14 -0
- package/dist/esm/pcd-loader.js.map +1 -0
- package/dist/esm/workers/pcd-worker.js +4 -0
- package/dist/esm/workers/pcd-worker.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -8
- package/dist/lib/decompress-lzf.d.ts +8 -0
- package/dist/lib/decompress-lzf.d.ts.map +1 -0
- package/dist/lib/decompress-lzf.js +62 -0
- package/dist/lib/get-pcd-schema.d.ts +10 -0
- package/dist/lib/get-pcd-schema.d.ts.map +1 -0
- package/dist/lib/get-pcd-schema.js +32 -19
- package/dist/lib/parse-pcd.d.ts +8 -0
- package/dist/lib/parse-pcd.d.ts.map +1 -0
- package/dist/lib/parse-pcd.js +317 -223
- package/dist/lib/pcd-types.d.ts +31 -0
- package/dist/lib/pcd-types.d.ts.map +1 -0
- package/dist/lib/pcd-types.js +2 -2
- package/dist/pcd-loader.d.ts +7 -0
- package/dist/pcd-loader.d.ts.map +1 -0
- package/dist/pcd-loader.js +21 -14
- package/dist/pcd-worker.js +200 -439
- package/dist/workers/pcd-worker.d.ts +2 -0
- package/dist/workers/pcd-worker.d.ts.map +1 -0
- package/dist/workers/pcd-worker.js +5 -4
- package/package.json +9 -9
- package/src/index.ts +3 -2
- package/src/lib/decompress-lzf.ts +64 -0
- package/src/lib/get-pcd-schema.ts +15 -10
- package/src/lib/parse-pcd.ts +161 -12
- package/src/lib/pcd-types.ts +9 -9
- package/src/pcd-loader.ts +5 -4
- package/dist/bundle.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/get-pcd-schema.js.map +0 -1
- package/dist/lib/parse-pcd.js.map +0 -1
- package/dist/lib/pcd-types.js.map +0 -1
- package/dist/pcd-loader.js.map +0 -1
- package/dist/workers/pcd-worker.js.map +0 -1
package/dist/lib/parse-pcd.js
CHANGED
|
@@ -1,239 +1,333 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
// PCD Loader, adapted from THREE.js (MIT license)
|
|
3
|
+
// Description: A loader for PCD ascii and binary files.
|
|
4
|
+
// Limitations: Compressed binary files are not supported.
|
|
5
|
+
//
|
|
6
|
+
// Attributions per original THREE.js source file:
|
|
7
|
+
// @author Filipe Caixeta / http://filipecaixeta.com.br
|
|
8
|
+
// @author Mugen87 / https://github.com/Mugen87
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
const schema_1 = require("@loaders.gl/schema");
|
|
11
|
+
const decompress_lzf_1 = require("./decompress-lzf");
|
|
12
|
+
const get_pcd_schema_1 = require("./get-pcd-schema");
|
|
3
13
|
const LITTLE_ENDIAN = true;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param data
|
|
17
|
+
* @returns
|
|
18
|
+
*/
|
|
19
|
+
function parsePCD(data) {
|
|
20
|
+
// parse header (always ascii format)
|
|
21
|
+
const textData = new TextDecoder().decode(data);
|
|
22
|
+
const pcdHeader = parsePCDHeader(textData);
|
|
23
|
+
let attributes = {};
|
|
24
|
+
// parse data
|
|
25
|
+
switch (pcdHeader.data) {
|
|
26
|
+
case 'ascii':
|
|
27
|
+
attributes = parsePCDASCII(pcdHeader, textData);
|
|
28
|
+
break;
|
|
29
|
+
case 'binary':
|
|
30
|
+
attributes = parsePCDBinary(pcdHeader, data);
|
|
31
|
+
break;
|
|
32
|
+
case 'binary_compressed':
|
|
33
|
+
attributes = parsePCDBinaryCompressed(pcdHeader, data);
|
|
34
|
+
break;
|
|
35
|
+
default:
|
|
36
|
+
throw new Error(`PCD: ${pcdHeader.data} files are not supported`);
|
|
37
|
+
}
|
|
38
|
+
attributes = getMeshAttributes(attributes);
|
|
39
|
+
const header = getMeshHeader(pcdHeader, attributes);
|
|
40
|
+
const metadata = Object.fromEntries([
|
|
41
|
+
['mode', '0'],
|
|
42
|
+
['boundingBox', JSON.stringify(header.boundingBox)]
|
|
43
|
+
]);
|
|
44
|
+
const schema = (0, get_pcd_schema_1.getPCDSchema)(pcdHeader, metadata);
|
|
45
|
+
return {
|
|
46
|
+
loader: 'pcd',
|
|
47
|
+
loaderData: pcdHeader,
|
|
48
|
+
header,
|
|
49
|
+
schema,
|
|
50
|
+
mode: 0,
|
|
51
|
+
topology: 'point-list',
|
|
52
|
+
attributes
|
|
53
|
+
};
|
|
37
54
|
}
|
|
38
|
-
|
|
55
|
+
exports.default = parsePCD;
|
|
56
|
+
// Create a header that contains common data for PointCloud category loaders
|
|
39
57
|
function getMeshHeader(pcdHeader, attributes) {
|
|
40
|
-
|
|
41
|
-
|
|
58
|
+
if (typeof pcdHeader.width === 'number' && typeof pcdHeader.height === 'number') {
|
|
59
|
+
const pointCount = pcdHeader.width * pcdHeader.height; // Supports "organized" point sets
|
|
60
|
+
return {
|
|
61
|
+
vertexCount: pointCount,
|
|
62
|
+
boundingBox: (0, schema_1.getMeshBoundingBox)(attributes)
|
|
63
|
+
};
|
|
64
|
+
}
|
|
42
65
|
return {
|
|
43
|
-
|
|
44
|
-
|
|
66
|
+
vertexCount: pcdHeader.vertexCount,
|
|
67
|
+
boundingBox: pcdHeader.boundingBox
|
|
45
68
|
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return pcdHeader;
|
|
49
69
|
}
|
|
50
|
-
|
|
70
|
+
/**
|
|
71
|
+
* @param attributes
|
|
72
|
+
* @returns Normalized attributes
|
|
73
|
+
*/
|
|
51
74
|
function getMeshAttributes(attributes) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
if (attributes.normal && attributes.normal.length > 0) {
|
|
60
|
-
normalizedAttributes.NORMAL = {
|
|
61
|
-
value: new Float32Array(attributes.normal),
|
|
62
|
-
size: 3
|
|
75
|
+
const normalizedAttributes = {
|
|
76
|
+
POSITION: {
|
|
77
|
+
// Binary PCD is only 32 bit
|
|
78
|
+
value: new Float32Array(attributes.position),
|
|
79
|
+
size: 3
|
|
80
|
+
}
|
|
63
81
|
};
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
82
|
+
if (attributes.normal && attributes.normal.length > 0) {
|
|
83
|
+
normalizedAttributes.NORMAL = {
|
|
84
|
+
value: new Float32Array(attributes.normal),
|
|
85
|
+
size: 3
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
if (attributes.color && attributes.color.length > 0) {
|
|
89
|
+
// TODO - RGBA
|
|
90
|
+
normalizedAttributes.COLOR_0 = {
|
|
91
|
+
value: new Uint8Array(attributes.color),
|
|
92
|
+
size: 3
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (attributes.intensity && attributes.intensity.length > 0) {
|
|
96
|
+
// TODO - RGBA
|
|
97
|
+
normalizedAttributes.COLOR_0 = {
|
|
98
|
+
value: new Uint8Array(attributes.color),
|
|
99
|
+
size: 3
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
if (attributes.label && attributes.label.length > 0) {
|
|
103
|
+
// TODO - RGBA
|
|
104
|
+
normalizedAttributes.COLOR_0 = {
|
|
105
|
+
value: new Uint8Array(attributes.label),
|
|
106
|
+
size: 3
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return normalizedAttributes;
|
|
74
110
|
}
|
|
75
|
-
|
|
111
|
+
/**
|
|
112
|
+
* Incoming data parsing
|
|
113
|
+
* @param data
|
|
114
|
+
* @returns Header
|
|
115
|
+
*/
|
|
116
|
+
/* eslint-disable complexity, max-statements */
|
|
76
117
|
function parsePCDHeader(data) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
if (pcdHeader.fields !== null) {
|
|
103
|
-
pcdHeader.fields = pcdHeader.fields[1].split(' ');
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (pcdHeader.type !== null) {
|
|
107
|
-
pcdHeader.type = pcdHeader.type[1].split(' ');
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (pcdHeader.width !== null) {
|
|
111
|
-
pcdHeader.width = parseInt(pcdHeader.width[1], 10);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (pcdHeader.height !== null) {
|
|
115
|
-
pcdHeader.height = parseInt(pcdHeader.height[1], 10);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (pcdHeader.viewpoint !== null) {
|
|
119
|
-
pcdHeader.viewpoint = pcdHeader.viewpoint[1];
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (pcdHeader.points !== null) {
|
|
123
|
-
pcdHeader.points = parseInt(pcdHeader.points[1], 10);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (pcdHeader.points === null && typeof pcdHeader.width === 'number' && typeof pcdHeader.height === 'number') {
|
|
127
|
-
pcdHeader.points = pcdHeader.width * pcdHeader.height;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (pcdHeader.size !== null) {
|
|
131
|
-
pcdHeader.size = pcdHeader.size[1].split(' ').map(x => parseInt(x, 10));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (pcdHeader.count !== null) {
|
|
135
|
-
pcdHeader.count = pcdHeader.count[1].split(' ').map(x => parseInt(x, 10));
|
|
136
|
-
} else {
|
|
137
|
-
pcdHeader.count = [];
|
|
138
|
-
|
|
118
|
+
const result1 = data.search(/[\r\n]DATA\s(\S*)\s/i);
|
|
119
|
+
const result2 = /[\r\n]DATA\s(\S*)\s/i.exec(data.substr(result1 - 1));
|
|
120
|
+
const pcdHeader = {};
|
|
121
|
+
pcdHeader.data = result2 && result2[1];
|
|
122
|
+
if (result2 !== null) {
|
|
123
|
+
pcdHeader.headerLen = (result2 && result2[0].length) + result1;
|
|
124
|
+
}
|
|
125
|
+
pcdHeader.str = data.substr(0, pcdHeader.headerLen);
|
|
126
|
+
// remove comments
|
|
127
|
+
pcdHeader.str = pcdHeader.str.replace(/\#.*/gi, '');
|
|
128
|
+
// parse
|
|
129
|
+
pcdHeader.version = /VERSION (.*)/i.exec(pcdHeader.str);
|
|
130
|
+
pcdHeader.fields = /FIELDS (.*)/i.exec(pcdHeader.str);
|
|
131
|
+
pcdHeader.size = /SIZE (.*)/i.exec(pcdHeader.str);
|
|
132
|
+
pcdHeader.type = /TYPE (.*)/i.exec(pcdHeader.str);
|
|
133
|
+
pcdHeader.count = /COUNT (.*)/i.exec(pcdHeader.str);
|
|
134
|
+
pcdHeader.width = /WIDTH (.*)/i.exec(pcdHeader.str);
|
|
135
|
+
pcdHeader.height = /HEIGHT (.*)/i.exec(pcdHeader.str);
|
|
136
|
+
pcdHeader.viewpoint = /VIEWPOINT (.*)/i.exec(pcdHeader.str);
|
|
137
|
+
pcdHeader.points = /POINTS (.*)/i.exec(pcdHeader.str);
|
|
138
|
+
// evaluate
|
|
139
|
+
if (pcdHeader.version !== null) {
|
|
140
|
+
pcdHeader.version = parseFloat(pcdHeader.version[1]);
|
|
141
|
+
}
|
|
139
142
|
if (pcdHeader.fields !== null) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
pcdHeader.
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
143
|
+
pcdHeader.fields = pcdHeader.fields[1].split(' ');
|
|
144
|
+
}
|
|
145
|
+
if (pcdHeader.type !== null) {
|
|
146
|
+
pcdHeader.type = pcdHeader.type[1].split(' ');
|
|
147
|
+
}
|
|
148
|
+
if (pcdHeader.width !== null) {
|
|
149
|
+
pcdHeader.width = parseInt(pcdHeader.width[1], 10);
|
|
150
|
+
}
|
|
151
|
+
if (pcdHeader.height !== null) {
|
|
152
|
+
pcdHeader.height = parseInt(pcdHeader.height[1], 10);
|
|
153
|
+
}
|
|
154
|
+
if (pcdHeader.viewpoint !== null) {
|
|
155
|
+
pcdHeader.viewpoint = pcdHeader.viewpoint[1];
|
|
156
|
+
}
|
|
157
|
+
if (pcdHeader.points !== null) {
|
|
158
|
+
pcdHeader.points = parseInt(pcdHeader.points[1], 10);
|
|
159
|
+
}
|
|
160
|
+
if (pcdHeader.points === null &&
|
|
161
|
+
typeof pcdHeader.width === 'number' &&
|
|
162
|
+
typeof pcdHeader.height === 'number') {
|
|
163
|
+
pcdHeader.points = pcdHeader.width * pcdHeader.height;
|
|
164
|
+
}
|
|
165
|
+
if (pcdHeader.size !== null) {
|
|
166
|
+
pcdHeader.size = pcdHeader.size[1].split(' ').map((x) => parseInt(x, 10));
|
|
167
|
+
}
|
|
168
|
+
if (pcdHeader.count !== null) {
|
|
169
|
+
pcdHeader.count = pcdHeader.count[1].split(' ').map((x) => parseInt(x, 10));
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
pcdHeader.count = [];
|
|
173
|
+
if (pcdHeader.fields !== null) {
|
|
174
|
+
for (let i = 0; i < pcdHeader.fields.length; i++) {
|
|
175
|
+
pcdHeader.count.push(1);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
pcdHeader.offset = {};
|
|
180
|
+
let sizeSum = 0;
|
|
181
|
+
if (pcdHeader.fields !== null && pcdHeader.size !== null) {
|
|
182
|
+
for (let i = 0; i < pcdHeader.fields.length; i++) {
|
|
183
|
+
if (pcdHeader.data === 'ascii') {
|
|
184
|
+
pcdHeader.offset[pcdHeader.fields[i]] = i;
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
pcdHeader.offset[pcdHeader.fields[i]] = sizeSum;
|
|
188
|
+
sizeSum += pcdHeader.size[i];
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// for binary only
|
|
193
|
+
pcdHeader.rowSize = sizeSum;
|
|
194
|
+
return pcdHeader;
|
|
162
195
|
}
|
|
163
|
-
|
|
196
|
+
/**
|
|
197
|
+
* @param pcdHeader
|
|
198
|
+
* @param textData
|
|
199
|
+
* @returns [attributes]
|
|
200
|
+
*/
|
|
201
|
+
// eslint-enable-next-line complexity, max-statements
|
|
164
202
|
function parsePCDASCII(pcdHeader, textData) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
203
|
+
const position = [];
|
|
204
|
+
const normal = [];
|
|
205
|
+
const color = [];
|
|
206
|
+
const intensity = [];
|
|
207
|
+
const label = [];
|
|
208
|
+
const offset = pcdHeader.offset;
|
|
209
|
+
const pcdData = textData.substr(pcdHeader.headerLen);
|
|
210
|
+
const lines = pcdData.split('\n');
|
|
211
|
+
for (let i = 0; i < lines.length; i++) {
|
|
212
|
+
if (lines[i] !== '') {
|
|
213
|
+
const line = lines[i].split(' ');
|
|
214
|
+
if (offset.x !== undefined) {
|
|
215
|
+
position.push(parseFloat(line[offset.x]));
|
|
216
|
+
position.push(parseFloat(line[offset.y]));
|
|
217
|
+
position.push(parseFloat(line[offset.z]));
|
|
218
|
+
}
|
|
219
|
+
if (offset.rgb !== undefined) {
|
|
220
|
+
const floatValue = parseFloat(line[offset.rgb]);
|
|
221
|
+
const binaryColor = new Float32Array([floatValue]);
|
|
222
|
+
const dataview = new DataView(binaryColor.buffer, 0);
|
|
223
|
+
color.push(dataview.getUint8(0));
|
|
224
|
+
color.push(dataview.getUint8(1));
|
|
225
|
+
color.push(dataview.getUint8(2));
|
|
226
|
+
// TODO - handle alpha channel / RGBA?
|
|
227
|
+
}
|
|
228
|
+
if (offset.normal_x !== undefined) {
|
|
229
|
+
normal.push(parseFloat(line[offset.normal_x]));
|
|
230
|
+
normal.push(parseFloat(line[offset.normal_y]));
|
|
231
|
+
normal.push(parseFloat(line[offset.normal_z]));
|
|
232
|
+
}
|
|
233
|
+
if (offset.intensity !== undefined) {
|
|
234
|
+
intensity.push(parseFloat(line[offset.intensity]));
|
|
235
|
+
}
|
|
236
|
+
if (offset.label !== undefined) {
|
|
237
|
+
label.push(parseInt(line[offset.label]));
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return { position, normal, color };
|
|
204
242
|
}
|
|
205
|
-
|
|
243
|
+
/**
|
|
244
|
+
* @param pcdHeader
|
|
245
|
+
* @param data
|
|
246
|
+
* @returns [attributes]
|
|
247
|
+
*/
|
|
206
248
|
function parsePCDBinary(pcdHeader, data) {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
249
|
+
const position = [];
|
|
250
|
+
const normal = [];
|
|
251
|
+
const color = [];
|
|
252
|
+
const intensity = [];
|
|
253
|
+
const label = [];
|
|
254
|
+
const dataview = new DataView(data, pcdHeader.headerLen);
|
|
255
|
+
const offset = pcdHeader.offset;
|
|
256
|
+
for (let i = 0, row = 0; i < pcdHeader.points; i++, row += pcdHeader.rowSize) {
|
|
257
|
+
if (offset.x !== undefined) {
|
|
258
|
+
position.push(dataview.getFloat32(row + offset.x, LITTLE_ENDIAN));
|
|
259
|
+
position.push(dataview.getFloat32(row + offset.y, LITTLE_ENDIAN));
|
|
260
|
+
position.push(dataview.getFloat32(row + offset.z, LITTLE_ENDIAN));
|
|
261
|
+
}
|
|
262
|
+
if (offset.rgb !== undefined) {
|
|
263
|
+
color.push(dataview.getUint8(row + offset.rgb + 0));
|
|
264
|
+
color.push(dataview.getUint8(row + offset.rgb + 1));
|
|
265
|
+
color.push(dataview.getUint8(row + offset.rgb + 2));
|
|
266
|
+
}
|
|
267
|
+
if (offset.normal_x !== undefined) {
|
|
268
|
+
normal.push(dataview.getFloat32(row + offset.normal_x, LITTLE_ENDIAN));
|
|
269
|
+
normal.push(dataview.getFloat32(row + offset.normal_y, LITTLE_ENDIAN));
|
|
270
|
+
normal.push(dataview.getFloat32(row + offset.normal_z, LITTLE_ENDIAN));
|
|
271
|
+
}
|
|
272
|
+
if (offset.intensity !== undefined) {
|
|
273
|
+
intensity.push(dataview.getFloat32(row + offset.intensity, LITTLE_ENDIAN));
|
|
274
|
+
}
|
|
275
|
+
if (offset.label !== undefined) {
|
|
276
|
+
label.push(dataview.getInt32(row + offset.label, LITTLE_ENDIAN));
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
return { position, normal, color, intensity, label };
|
|
280
|
+
}
|
|
281
|
+
/** Parse compressed PCD data in in binary_compressed form ( https://pointclouds.org/documentation/tutorials/pcd_file_format.html)
|
|
282
|
+
* from https://github.com/mrdoob/three.js/blob/master/examples/jsm/loaders/PCDLoader.js
|
|
283
|
+
* @license MIT (http://opensource.org/licenses/MIT)
|
|
284
|
+
* @param pcdHeader
|
|
285
|
+
* @param data
|
|
286
|
+
* @returns [attributes]
|
|
287
|
+
*/
|
|
288
|
+
// eslint-enable-next-line complexity, max-statements
|
|
289
|
+
function parsePCDBinaryCompressed(pcdHeader, data) {
|
|
290
|
+
const position = [];
|
|
291
|
+
const normal = [];
|
|
292
|
+
const color = [];
|
|
293
|
+
const intensity = [];
|
|
294
|
+
const label = [];
|
|
295
|
+
const sizes = new Uint32Array(data.slice(pcdHeader.headerLen, pcdHeader.headerLen + 8));
|
|
296
|
+
const compressedSize = sizes[0];
|
|
297
|
+
const decompressedSize = sizes[1];
|
|
298
|
+
const decompressed = (0, decompress_lzf_1.decompressLZF)(new Uint8Array(data, pcdHeader.headerLen + 8, compressedSize), decompressedSize);
|
|
299
|
+
const dataview = new DataView(decompressed.buffer);
|
|
300
|
+
const offset = pcdHeader.offset;
|
|
301
|
+
for (let i = 0; i < pcdHeader.points; i++) {
|
|
302
|
+
if (offset.x !== undefined) {
|
|
303
|
+
position.push(dataview.getFloat32(pcdHeader.points * offset.x + pcdHeader.size[0] * i, LITTLE_ENDIAN));
|
|
304
|
+
position.push(dataview.getFloat32(pcdHeader.points * offset.y + pcdHeader.size[1] * i, LITTLE_ENDIAN));
|
|
305
|
+
position.push(dataview.getFloat32(pcdHeader.points * offset.z + pcdHeader.size[2] * i, LITTLE_ENDIAN));
|
|
306
|
+
}
|
|
307
|
+
if (offset.rgb !== undefined) {
|
|
308
|
+
color.push(dataview.getUint8(pcdHeader.points * offset.rgb + pcdHeader.size[3] * i + 0) / 255.0);
|
|
309
|
+
color.push(dataview.getUint8(pcdHeader.points * offset.rgb + pcdHeader.size[3] * i + 1) / 255.0);
|
|
310
|
+
color.push(dataview.getUint8(pcdHeader.points * offset.rgb + pcdHeader.size[3] * i + 2) / 255.0);
|
|
311
|
+
}
|
|
312
|
+
if (offset.normal_x !== undefined) {
|
|
313
|
+
normal.push(dataview.getFloat32(pcdHeader.points * offset.normal_x + pcdHeader.size[4] * i, LITTLE_ENDIAN));
|
|
314
|
+
normal.push(dataview.getFloat32(pcdHeader.points * offset.normal_y + pcdHeader.size[5] * i, LITTLE_ENDIAN));
|
|
315
|
+
normal.push(dataview.getFloat32(pcdHeader.points * offset.normal_z + pcdHeader.size[6] * i, LITTLE_ENDIAN));
|
|
316
|
+
}
|
|
317
|
+
if (offset.intensity !== undefined) {
|
|
318
|
+
const intensityIndex = pcdHeader.fields.indexOf('intensity');
|
|
319
|
+
intensity.push(dataview.getFloat32(pcdHeader.points * offset.intensity + pcdHeader.size[intensityIndex] * i, LITTLE_ENDIAN));
|
|
320
|
+
}
|
|
321
|
+
if (offset.label !== undefined) {
|
|
322
|
+
const labelIndex = pcdHeader.fields.indexOf('label');
|
|
323
|
+
label.push(dataview.getInt32(pcdHeader.points * offset.label + pcdHeader.size[labelIndex] * i, LITTLE_ENDIAN));
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return {
|
|
327
|
+
position,
|
|
328
|
+
normal,
|
|
329
|
+
color,
|
|
330
|
+
intensity,
|
|
331
|
+
label
|
|
332
|
+
};
|
|
238
333
|
}
|
|
239
|
-
//# sourceMappingURL=parse-pcd.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Mesh } from '@loaders.gl/schema';
|
|
2
|
+
type BoundingBox = [[number, number, number], [number, number, number]];
|
|
3
|
+
export type PCDHeader = {
|
|
4
|
+
data: any;
|
|
5
|
+
headerLen: number;
|
|
6
|
+
str: string;
|
|
7
|
+
version: number;
|
|
8
|
+
fields: string[];
|
|
9
|
+
size: number[];
|
|
10
|
+
type: null | string[];
|
|
11
|
+
count: null | number[];
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
viewpoint: null | string;
|
|
15
|
+
points: number;
|
|
16
|
+
offset: {
|
|
17
|
+
[index: string]: number;
|
|
18
|
+
};
|
|
19
|
+
rowSize: number;
|
|
20
|
+
vertexCount: number;
|
|
21
|
+
boundingBox: BoundingBox;
|
|
22
|
+
};
|
|
23
|
+
/** */
|
|
24
|
+
export type PCDMesh = Mesh & {
|
|
25
|
+
loader: 'pcd';
|
|
26
|
+
loaderData: PCDHeader;
|
|
27
|
+
topology: 'point-list';
|
|
28
|
+
mode: 0;
|
|
29
|
+
};
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=pcd-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pcd-types.d.ts","sourceRoot":"","sources":["../../src/lib/pcd-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,oBAAoB,CAAC;AAE7C,KAAK,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAExE,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,GAAG,CAAC;IACV,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,IAAI,GAAG,MAAM,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,GAAG,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE;QAAC,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;KAAC,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,WAAW,CAAC;CAC1B,CAAC;AAEF,OAAO;AACP,MAAM,MAAM,OAAO,GAAG,IAAI,GAAG;IAC3B,MAAM,EAAE,KAAK,CAAC;IACd,UAAU,EAAE,SAAS,CAAC;IACtB,QAAQ,EAAE,YAAY,CAAC;IACvB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC"}
|
package/dist/lib/pcd-types.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Loader, LoaderOptions } from '@loaders.gl/loader-utils';
|
|
2
|
+
import { PCDMesh } from './lib/pcd-types';
|
|
3
|
+
/**
|
|
4
|
+
* Worker loader for PCD - Point Cloud Data
|
|
5
|
+
*/
|
|
6
|
+
export declare const PCDLoader: Loader<PCDMesh, never, LoaderOptions>;
|
|
7
|
+
//# sourceMappingURL=pcd-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pcd-loader.d.ts","sourceRoot":"","sources":["../src/pcd-loader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,MAAM,EAAE,aAAa,EAAC,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAMxC;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,aAAa,CAW3D,CAAC"}
|
package/dist/pcd-loader.js
CHANGED
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
// loaders.gl, MIT license
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.PCDLoader = void 0;
|
|
5
|
+
// __VERSION__ is injected by babel-plugin-version-inline
|
|
6
|
+
// @ts-ignore TS2304: Cannot find name '__VERSION__'.
|
|
7
|
+
const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
|
|
8
|
+
/**
|
|
9
|
+
* Worker loader for PCD - Point Cloud Data
|
|
10
|
+
*/
|
|
11
|
+
exports.PCDLoader = {
|
|
12
|
+
name: 'PCD (Point Cloud Data)',
|
|
13
|
+
id: 'pcd',
|
|
14
|
+
module: 'pcd',
|
|
15
|
+
version: VERSION,
|
|
16
|
+
worker: true,
|
|
17
|
+
extensions: ['pcd'],
|
|
18
|
+
mimeTypes: ['text/plain'],
|
|
19
|
+
options: {
|
|
20
|
+
pcd: {}
|
|
21
|
+
}
|
|
13
22
|
};
|
|
14
|
-
export const _typecheckPCDLoader = PCDLoader;
|
|
15
|
-
//# sourceMappingURL=pcd-loader.js.map
|