itowns 2.43.2-next.2 → 2.43.2-next.20
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/558.js +2 -0
- package/dist/558.js.map +1 -0
- package/dist/debug.js +1 -1
- package/dist/debug.js.map +1 -1
- package/dist/itowns.js +1 -1
- package/dist/itowns.js.map +1 -1
- package/dist/itowns_lasparser.js +2 -0
- package/dist/itowns_lasparser.js.map +1 -0
- package/dist/itowns_lasworker.js +2 -0
- package/dist/itowns_lasworker.js.map +1 -0
- package/dist/itowns_potree2worker.js +2 -0
- package/dist/itowns_potree2worker.js.map +1 -0
- package/dist/itowns_widgets.js +1 -1
- package/dist/itowns_widgets.js.map +1 -1
- package/examples/3dtiles_25d.html +1 -1
- package/examples/3dtiles_basic.html +2 -2
- package/examples/3dtiles_batch_table.html +1 -3
- package/examples/3dtiles_pointcloud.html +9 -15
- package/examples/config.json +1 -0
- package/examples/copc_simple_loader.html +1 -1
- package/examples/entwine_3d_loader.html +1 -1
- package/examples/entwine_simple_loader.html +1 -1
- package/examples/js/plugins/COGParser.js +84 -50
- package/examples/js/plugins/COGSource.js +7 -4
- package/examples/layers/JSONLayers/OPENSM.json +1 -1
- package/examples/potree2_25d_map.html +127 -0
- package/examples/potree_25d_map.html +1 -1
- package/examples/potree_3d_map.html +1 -1
- package/examples/source_file_cog.html +22 -5
- package/lib/Controls/FirstPersonControls.js +0 -1
- package/lib/Controls/FlyControls.js +0 -1
- package/lib/Converter/Feature2Mesh.js +2 -4
- package/lib/Converter/textureConverter.js +1 -1
- package/lib/Core/3DTiles/C3DTBatchTable.js +1 -1
- package/lib/Core/3DTiles/C3DTFeature.js +6 -7
- package/lib/Core/Feature.js +1 -2
- package/lib/Core/Geographic/CoordStars.js +0 -1
- package/lib/Core/Label.js +0 -1
- package/lib/Core/MainLoop.js +0 -1
- package/lib/Core/Potree2Node.js +206 -0
- package/lib/Core/Potree2PointAttributes.js +139 -0
- package/lib/Core/Prefab/Globe/Atmosphere.js +0 -4
- package/lib/Core/Prefab/Globe/GlobeLayer.js +3 -3
- package/lib/Core/Scheduler/Scheduler.js +1 -1
- package/lib/Core/Style.js +54 -53
- package/lib/Core/View.js +2 -4
- package/lib/Layer/C3DTilesLayer.js +8 -6
- package/lib/Layer/ElevationLayer.js +2 -3
- package/lib/Layer/GeoidLayer.js +1 -2
- package/lib/Layer/LabelLayer.js +8 -17
- package/lib/Layer/Layer.js +4 -2
- package/lib/Layer/PointCloudLayer.js +5 -8
- package/lib/Layer/Potree2Layer.js +165 -0
- package/lib/Layer/ReferencingLayerProperties.js +8 -3
- package/lib/Layer/TiledGeometryLayer.js +6 -4
- package/lib/Loader/Potree2BrotliLoader.js +261 -0
- package/lib/Loader/Potree2Loader.js +207 -0
- package/lib/Main.js +2 -0
- package/lib/Parser/GeoJsonParser.js +2 -3
- package/lib/Parser/LASParser.js +49 -18
- package/lib/Parser/Potree2BinParser.js +92 -0
- package/lib/Parser/deprecated/LegacyGLTFLoader.js +1 -2
- package/lib/Process/3dTilesProcessing.js +2 -1
- package/lib/Process/FeatureProcessing.js +1 -2
- package/lib/Process/LayeredMaterialNodeProcessing.js +3 -9
- package/lib/Process/ObjectRemovalHelper.js +1 -2
- package/lib/Provider/3dTilesProvider.js +3 -2
- package/lib/Renderer/ColorLayersOrdering.js +1 -2
- package/lib/Renderer/Label2DRenderer.js +1 -4
- package/lib/Renderer/PointsMaterial.js +135 -100
- package/lib/Renderer/RenderMode.js +0 -1
- package/lib/Source/FileSource.js +1 -1
- package/lib/Source/Potree2Source.js +172 -0
- package/lib/ThreeExtended/loaders/DDSLoader.js +11 -1
- package/lib/ThreeExtended/loaders/DRACOLoader.js +0 -1
- package/lib/ThreeExtended/loaders/GLTFLoader.js +1 -0
- package/lib/Utils/DEMUtils.js +2 -2
- package/lib/Utils/OrientationUtils.js +0 -1
- package/lib/Utils/gui/Searchbar.js +1 -2
- package/lib/Worker/LASLoaderWorker.js +19 -0
- package/lib/Worker/Potree2Worker.js +21 -0
- package/package.json +11 -8
- /package/lib/{Parser → Loader}/LASLoader.js +0 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/*
|
|
2
|
+
============
|
|
3
|
+
== POTREE ==
|
|
4
|
+
============
|
|
5
|
+
|
|
6
|
+
http://potree.org
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2011-2020, Markus Schütz
|
|
9
|
+
All rights reserved.
|
|
10
|
+
|
|
11
|
+
Redistribution and use in source and binary forms, with or without
|
|
12
|
+
modification, are permitted provided that the following conditions are met:
|
|
13
|
+
|
|
14
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
15
|
+
list of conditions and the following disclaimer.
|
|
16
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
17
|
+
this list of conditions and the following disclaimer in the documentation
|
|
18
|
+
and/or other materials provided with the distribution.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
21
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
22
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
24
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
25
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
26
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
27
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
28
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
29
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
30
|
+
|
|
31
|
+
The views and conclusions contained in the software and documentation are those
|
|
32
|
+
of the authors and should not be interpreted as representing official policies,
|
|
33
|
+
either expressed or implied, of the FreeBSD Project.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
import * as THREE from 'three';
|
|
37
|
+
import PointCloudNode from "./PointCloudNode.js";
|
|
38
|
+
|
|
39
|
+
// Create an A(xis)A(ligned)B(ounding)B(ox) for the child `childIndex` of one aabb.
|
|
40
|
+
// (PotreeConverter protocol builds implicit octree hierarchy by applying the same
|
|
41
|
+
// subdivision algo recursively)
|
|
42
|
+
const dHalfLength = new THREE.Vector3();
|
|
43
|
+
const NODE_TYPE = {
|
|
44
|
+
NORMAL: 0,
|
|
45
|
+
LEAF: 1,
|
|
46
|
+
PROXY: 2
|
|
47
|
+
};
|
|
48
|
+
class Potree2Node extends PointCloudNode {
|
|
49
|
+
constructor() {
|
|
50
|
+
let numPoints = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
|
51
|
+
let childrenBitField = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
52
|
+
let layer = arguments.length > 2 ? arguments[2] : undefined;
|
|
53
|
+
super(numPoints, layer);
|
|
54
|
+
this.childrenBitField = childrenBitField;
|
|
55
|
+
this.id = '';
|
|
56
|
+
this.depth = 0;
|
|
57
|
+
this.baseurl = layer.source.baseurl;
|
|
58
|
+
}
|
|
59
|
+
add(node, indexChild) {
|
|
60
|
+
super.add(node, indexChild);
|
|
61
|
+
node.id = this.id + indexChild;
|
|
62
|
+
node.depth = this.depth + 1;
|
|
63
|
+
}
|
|
64
|
+
createChildAABB(node, childIndex) {
|
|
65
|
+
// Code inspired from potree
|
|
66
|
+
node.bbox.copy(this.bbox);
|
|
67
|
+
this.bbox.getCenter(node.bbox.max);
|
|
68
|
+
dHalfLength.copy(node.bbox.max).sub(this.bbox.min);
|
|
69
|
+
if (childIndex === 1) {
|
|
70
|
+
node.bbox.min.z += dHalfLength.z;
|
|
71
|
+
node.bbox.max.z += dHalfLength.z;
|
|
72
|
+
} else if (childIndex === 3) {
|
|
73
|
+
node.bbox.min.z += dHalfLength.z;
|
|
74
|
+
node.bbox.max.z += dHalfLength.z;
|
|
75
|
+
node.bbox.min.y += dHalfLength.y;
|
|
76
|
+
node.bbox.max.y += dHalfLength.y;
|
|
77
|
+
} else if (childIndex === 0) {
|
|
78
|
+
//
|
|
79
|
+
} else if (childIndex === 2) {
|
|
80
|
+
node.bbox.min.y += dHalfLength.y;
|
|
81
|
+
node.bbox.max.y += dHalfLength.y;
|
|
82
|
+
} else if (childIndex === 5) {
|
|
83
|
+
node.bbox.min.z += dHalfLength.z;
|
|
84
|
+
node.bbox.max.z += dHalfLength.z;
|
|
85
|
+
node.bbox.min.x += dHalfLength.x;
|
|
86
|
+
node.bbox.max.x += dHalfLength.x;
|
|
87
|
+
} else if (childIndex === 7) {
|
|
88
|
+
node.bbox.min.add(dHalfLength);
|
|
89
|
+
node.bbox.max.add(dHalfLength);
|
|
90
|
+
} else if (childIndex === 4) {
|
|
91
|
+
node.bbox.min.x += dHalfLength.x;
|
|
92
|
+
node.bbox.max.x += dHalfLength.x;
|
|
93
|
+
} else if (childIndex === 6) {
|
|
94
|
+
node.bbox.min.y += dHalfLength.y;
|
|
95
|
+
node.bbox.max.y += dHalfLength.y;
|
|
96
|
+
node.bbox.min.x += dHalfLength.x;
|
|
97
|
+
node.bbox.max.x += dHalfLength.x;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
get octreeIsLoaded() {
|
|
101
|
+
return !(this.childrenBitField && this.children.length === 0);
|
|
102
|
+
}
|
|
103
|
+
get url() {
|
|
104
|
+
return `${this.baseurl}/octree.bin`;
|
|
105
|
+
}
|
|
106
|
+
networkOptions(byteOffset, byteSize) {
|
|
107
|
+
const first = byteOffset;
|
|
108
|
+
// When we specify 'multipart/byteranges' on headers request it trigger a preflight request
|
|
109
|
+
// Actually github doesn't support it https://github.com/orgs/community/discussions/24659
|
|
110
|
+
// But if we omit header parameter, github seems to know it's a 'multipart/byteranges' request (thanks to 'Range' parameter)
|
|
111
|
+
const networkOptions = {
|
|
112
|
+
...this.layer.source.networkOptions,
|
|
113
|
+
headers: {
|
|
114
|
+
...this.layer.source.networkOptions.headers,
|
|
115
|
+
...(this.url.startsWith('https://raw.githubusercontent.com') ? {} : {
|
|
116
|
+
'content-type': 'multipart/byteranges'
|
|
117
|
+
}),
|
|
118
|
+
Range: `bytes=${first}-${first + byteSize - 1n}`
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
return networkOptions;
|
|
122
|
+
}
|
|
123
|
+
async load() {
|
|
124
|
+
// Query octree if we don't have children potreeNode yet.
|
|
125
|
+
if (!this.octreeIsLoaded) {
|
|
126
|
+
await this.loadOctree();
|
|
127
|
+
}
|
|
128
|
+
return this.layer.source.fetcher(this.url, this.networkOptions(this.byteOffset, this.byteSize)).then(file => this.layer.source.parser(file, {
|
|
129
|
+
in: {
|
|
130
|
+
source: this.layer.source,
|
|
131
|
+
bbox: this.bbox,
|
|
132
|
+
numPoints: this.numPoints
|
|
133
|
+
},
|
|
134
|
+
out: this.layer
|
|
135
|
+
})).then(data => {
|
|
136
|
+
this.loaded = true;
|
|
137
|
+
this.loading = false;
|
|
138
|
+
return data.geometry;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
async loadOctree() {
|
|
142
|
+
if (this.loaded || this.loading) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
this.loading = true;
|
|
146
|
+
return this.nodeType === NODE_TYPE.PROXY ? this.loadHierarchy() : Promise.resolve();
|
|
147
|
+
}
|
|
148
|
+
async loadHierarchy() {
|
|
149
|
+
const hierarchyPath = `${this.baseurl}/hierarchy.bin`;
|
|
150
|
+
const buffer = await this.layer.source.fetcher(hierarchyPath, this.networkOptions(this.hierarchyByteOffset, this.hierarchyByteSize));
|
|
151
|
+
this.parseHierarchy(buffer);
|
|
152
|
+
}
|
|
153
|
+
parseHierarchy(buffer) {
|
|
154
|
+
const view = new DataView(buffer);
|
|
155
|
+
const bytesPerNode = 22;
|
|
156
|
+
const numNodes = buffer.byteLength / bytesPerNode;
|
|
157
|
+
const stack = [];
|
|
158
|
+
stack.push(this);
|
|
159
|
+
for (let indexNode = 0; indexNode < numNodes; indexNode++) {
|
|
160
|
+
const current = stack.shift();
|
|
161
|
+
const offset = indexNode * bytesPerNode;
|
|
162
|
+
const type = view.getUint8(offset + 0);
|
|
163
|
+
const childMask = view.getUint8(offset + 1);
|
|
164
|
+
const numPoints = view.getUint32(offset + 2, true);
|
|
165
|
+
const byteOffset = view.getBigInt64(offset + 6, true);
|
|
166
|
+
const byteSize = view.getBigInt64(offset + 14, true);
|
|
167
|
+
if (current.nodeType === NODE_TYPE.PROXY) {
|
|
168
|
+
// replace proxy with real node
|
|
169
|
+
current.byteOffset = byteOffset;
|
|
170
|
+
current.byteSize = byteSize;
|
|
171
|
+
current.numPoints = numPoints;
|
|
172
|
+
} else if (type === NODE_TYPE.PROXY) {
|
|
173
|
+
// load proxy
|
|
174
|
+
current.hierarchyByteOffset = byteOffset;
|
|
175
|
+
current.hierarchyByteSize = byteSize;
|
|
176
|
+
current.numPoints = numPoints;
|
|
177
|
+
} else {
|
|
178
|
+
// load real node
|
|
179
|
+
current.byteOffset = byteOffset;
|
|
180
|
+
current.byteSize = byteSize;
|
|
181
|
+
current.numPoints = numPoints;
|
|
182
|
+
}
|
|
183
|
+
if (current.byteSize === 0n) {
|
|
184
|
+
// workaround for issue potree/potree#1125
|
|
185
|
+
// some inner nodes erroneously report >0 points even though have 0 points
|
|
186
|
+
// however, they still report a byteSize of 0, so based on that we now set node.numPoints to 0
|
|
187
|
+
current.numPoints = 0;
|
|
188
|
+
}
|
|
189
|
+
current.nodeType = type;
|
|
190
|
+
if (current.nodeType === NODE_TYPE.PROXY) {
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
for (let childIndex = 0; childIndex < 8; childIndex++) {
|
|
194
|
+
const childExists = (1 << childIndex & childMask) !== 0;
|
|
195
|
+
if (!childExists) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const child = new Potree2Node(numPoints, childMask, this.layer);
|
|
199
|
+
child.spacing = current.spacing / 2;
|
|
200
|
+
current.add(child, childIndex);
|
|
201
|
+
stack.push(child);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
export default Potree2Node;
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/*
|
|
2
|
+
============
|
|
3
|
+
== POTREE ==
|
|
4
|
+
============
|
|
5
|
+
|
|
6
|
+
http://potree.org
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2011-2020, Markus Schütz
|
|
9
|
+
All rights reserved.
|
|
10
|
+
|
|
11
|
+
Redistribution and use in source and binary forms, with or without
|
|
12
|
+
modification, are permitted provided that the following conditions are met:
|
|
13
|
+
|
|
14
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
15
|
+
list of conditions and the following disclaimer.
|
|
16
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
17
|
+
this list of conditions and the following disclaimer in the documentation
|
|
18
|
+
and/or other materials provided with the distribution.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
21
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
22
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
24
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
25
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
26
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
27
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
28
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
29
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
30
|
+
|
|
31
|
+
The views and conclusions contained in the software and documentation are those
|
|
32
|
+
of the authors and should not be interpreted as representing official policies,
|
|
33
|
+
either expressed or implied, of the FreeBSD Project.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Some types of possible point attribute data formats
|
|
38
|
+
*
|
|
39
|
+
* @class
|
|
40
|
+
*/
|
|
41
|
+
const PointAttributeTypes = {
|
|
42
|
+
DATA_TYPE_DOUBLE: {
|
|
43
|
+
name: 'double',
|
|
44
|
+
size: 8
|
|
45
|
+
},
|
|
46
|
+
DATA_TYPE_FLOAT: {
|
|
47
|
+
name: 'float',
|
|
48
|
+
size: 4
|
|
49
|
+
},
|
|
50
|
+
DATA_TYPE_INT8: {
|
|
51
|
+
name: 'int8',
|
|
52
|
+
size: 1
|
|
53
|
+
},
|
|
54
|
+
DATA_TYPE_UINT8: {
|
|
55
|
+
name: 'uint8',
|
|
56
|
+
size: 1
|
|
57
|
+
},
|
|
58
|
+
DATA_TYPE_INT16: {
|
|
59
|
+
name: 'int16',
|
|
60
|
+
size: 2
|
|
61
|
+
},
|
|
62
|
+
DATA_TYPE_UINT16: {
|
|
63
|
+
name: 'uint16',
|
|
64
|
+
size: 2
|
|
65
|
+
},
|
|
66
|
+
DATA_TYPE_INT32: {
|
|
67
|
+
name: 'int32',
|
|
68
|
+
size: 4
|
|
69
|
+
},
|
|
70
|
+
DATA_TYPE_UINT32: {
|
|
71
|
+
name: 'uint32',
|
|
72
|
+
size: 4
|
|
73
|
+
},
|
|
74
|
+
DATA_TYPE_INT64: {
|
|
75
|
+
name: 'int64',
|
|
76
|
+
size: 8
|
|
77
|
+
},
|
|
78
|
+
DATA_TYPE_UINT64: {
|
|
79
|
+
name: 'uint64',
|
|
80
|
+
size: 8
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
Object.keys(PointAttributeTypes).forEach((type, index) => {
|
|
84
|
+
PointAttributeTypes[index] = PointAttributeTypes[type];
|
|
85
|
+
});
|
|
86
|
+
export { PointAttributeTypes };
|
|
87
|
+
class PointAttribute {
|
|
88
|
+
constructor(name, type, numElements) {
|
|
89
|
+
this.name = name;
|
|
90
|
+
this.type = type;
|
|
91
|
+
this.numElements = numElements;
|
|
92
|
+
this.byteSize = this.numElements * this.type.size;
|
|
93
|
+
this.description = '';
|
|
94
|
+
this.range = [Infinity, -Infinity];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
PointAttribute.POSITION_CARTESIAN = new PointAttribute('POSITION_CARTESIAN', PointAttributeTypes.DATA_TYPE_FLOAT, 3);
|
|
98
|
+
PointAttribute.RGBA_PACKED = new PointAttribute('COLOR_PACKED', PointAttributeTypes.DATA_TYPE_INT8, 4);
|
|
99
|
+
PointAttribute.COLOR_PACKED = PointAttribute.RGBA_PACKED;
|
|
100
|
+
PointAttribute.RGB_PACKED = new PointAttribute('COLOR_PACKED', PointAttributeTypes.DATA_TYPE_INT8, 3);
|
|
101
|
+
PointAttribute.NORMAL_FLOATS = new PointAttribute('NORMAL_FLOATS', PointAttributeTypes.DATA_TYPE_FLOAT, 3);
|
|
102
|
+
PointAttribute.INTENSITY = new PointAttribute('INTENSITY', PointAttributeTypes.DATA_TYPE_UINT16, 1);
|
|
103
|
+
PointAttribute.CLASSIFICATION = new PointAttribute('CLASSIFICATION', PointAttributeTypes.DATA_TYPE_UINT8, 1);
|
|
104
|
+
PointAttribute.NORMAL_SPHEREMAPPED = new PointAttribute('NORMAL_SPHEREMAPPED', PointAttributeTypes.DATA_TYPE_UINT8, 2);
|
|
105
|
+
PointAttribute.NORMAL_OCT16 = new PointAttribute('NORMAL_OCT16', PointAttributeTypes.DATA_TYPE_UINT8, 2);
|
|
106
|
+
PointAttribute.NORMAL = new PointAttribute('NORMAL', PointAttributeTypes.DATA_TYPE_FLOAT, 3);
|
|
107
|
+
PointAttribute.RETURN_NUMBER = new PointAttribute('RETURN_NUMBER', PointAttributeTypes.DATA_TYPE_UINT8, 1);
|
|
108
|
+
PointAttribute.NUMBER_OF_RETURNS = new PointAttribute('NUMBER_OF_RETURNS', PointAttributeTypes.DATA_TYPE_UINT8, 1);
|
|
109
|
+
PointAttribute.SOURCE_ID = new PointAttribute('SOURCE_ID', PointAttributeTypes.DATA_TYPE_UINT16, 1);
|
|
110
|
+
PointAttribute.INDICES = new PointAttribute('INDICES', PointAttributeTypes.DATA_TYPE_UINT32, 1);
|
|
111
|
+
PointAttribute.SPACING = new PointAttribute('SPACING', PointAttributeTypes.DATA_TYPE_FLOAT, 1);
|
|
112
|
+
PointAttribute.GPS_TIME = new PointAttribute('GPS_TIME', PointAttributeTypes.DATA_TYPE_DOUBLE, 1);
|
|
113
|
+
export { PointAttribute };
|
|
114
|
+
export class Potree2PointAttributes {
|
|
115
|
+
constructor() {
|
|
116
|
+
this.attributes = [];
|
|
117
|
+
this.byteSize = 0;
|
|
118
|
+
this.size = 0;
|
|
119
|
+
this.vectors = [];
|
|
120
|
+
}
|
|
121
|
+
add(pointAttribute) {
|
|
122
|
+
this.attributes.push(pointAttribute);
|
|
123
|
+
this.byteSize += pointAttribute.byteSize;
|
|
124
|
+
this.size++;
|
|
125
|
+
}
|
|
126
|
+
addVector(vector) {
|
|
127
|
+
this.vectors.push(vector);
|
|
128
|
+
}
|
|
129
|
+
hasNormals() {
|
|
130
|
+
for (let index = 0; index < this.attributes.length; index++) {
|
|
131
|
+
const name = this.attributes[index];
|
|
132
|
+
const pointAttribute = this.attributes[name];
|
|
133
|
+
if (pointAttribute === PointAttribute.NORMAL_SPHEREMAPPED || pointAttribute === PointAttribute.NORMAL_FLOATS || pointAttribute === PointAttribute.NORMAL || pointAttribute === PointAttribute.NORMAL_OCT16) {
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -72,7 +72,6 @@ class Atmosphere extends GeometryLayer {
|
|
|
72
72
|
value: new THREE.Vector2(window.innerWidth, window.innerHeight)
|
|
73
73
|
} // Should be updated on screen resize...
|
|
74
74
|
},
|
|
75
|
-
|
|
76
75
|
vertexShader: GlowVS,
|
|
77
76
|
fragmentShader: GlowFS,
|
|
78
77
|
side: THREE.BackSide,
|
|
@@ -100,7 +99,6 @@ class Atmosphere extends GeometryLayer {
|
|
|
100
99
|
value: new THREE.Vector2(window.innerWidth, window.innerHeight)
|
|
101
100
|
} // Should be updated on screen resize...
|
|
102
101
|
},
|
|
103
|
-
|
|
104
102
|
vertexShader: GlowVS,
|
|
105
103
|
fragmentShader: GlowFS,
|
|
106
104
|
side: THREE.FrontSide,
|
|
@@ -135,7 +133,6 @@ class Atmosphere extends GeometryLayer {
|
|
|
135
133
|
scaleDepth: 0.25
|
|
136
134
|
// mieScaleDepth: 0.1,
|
|
137
135
|
};
|
|
138
|
-
|
|
139
136
|
this.object3d.updateMatrixWorld();
|
|
140
137
|
}
|
|
141
138
|
update(context, layer, node) {
|
|
@@ -288,7 +285,6 @@ class Atmosphere extends GeometryLayer {
|
|
|
288
285
|
skyDome.material.uniforms.mieDirectionalG.value = effectController.mieDirectionalG;
|
|
289
286
|
skyDome.material.uniforms.up.value = new THREE.Vector3(); // no more necessary, estimate normal from cam..
|
|
290
287
|
}
|
|
291
|
-
|
|
292
288
|
setRealisticOn(bool) {
|
|
293
289
|
if (bool) {
|
|
294
290
|
if (!this.realisticAtmosphere.children.length) {
|
|
@@ -3,7 +3,6 @@ import TiledGeometryLayer from "../../../Layer/TiledGeometryLayer.js";
|
|
|
3
3
|
import { ellipsoidSizes } from "../../Math/Ellipsoid.js";
|
|
4
4
|
import { globalExtentTMS, schemeTiles } from "../../Geographic/Extent.js";
|
|
5
5
|
import BuilderEllipsoidTile from "./BuilderEllipsoidTile.js";
|
|
6
|
-
import { SIZE_DIAGONAL_TEXTURE } from "../../../Process/LayeredMaterialNodeProcessing.js";
|
|
7
6
|
import CRS from "../../Geographic/Crs.js";
|
|
8
7
|
|
|
9
8
|
// matrix to convert sphere to ellipsoid
|
|
@@ -129,7 +128,7 @@ class GlobeLayer extends TiledGeometryLayer {
|
|
|
129
128
|
return isOccluded;
|
|
130
129
|
}
|
|
131
130
|
computeTileZoomFromDistanceCamera(distance, camera) {
|
|
132
|
-
const preSinus =
|
|
131
|
+
const preSinus = this.sizeDiagonalTexture * (this.sseSubdivisionThreshold * 0.5) / camera._preSSE / ellipsoidSizes.x;
|
|
133
132
|
let sinus = distance * preSinus;
|
|
134
133
|
let zoom = Math.log(Math.PI / (2.0 * Math.asin(sinus))) / Math.log(2);
|
|
135
134
|
const delta = Math.PI / 2 ** zoom;
|
|
@@ -143,7 +142,8 @@ class GlobeLayer extends TiledGeometryLayer {
|
|
|
143
142
|
const delta = Math.PI / 2 ** zoom;
|
|
144
143
|
const circleChord = 2.0 * ellipsoidSizes.x * Math.sin(delta * 0.5);
|
|
145
144
|
const radius = circleChord * 0.5;
|
|
146
|
-
|
|
145
|
+
const error = radius / this.sizeDiagonalTexture;
|
|
146
|
+
return camera._preSSE * error / (this.sseSubdivisionThreshold * 0.5) + radius;
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
export default GlobeLayer;
|
|
@@ -140,7 +140,7 @@ Scheduler.prototype.execute = function (command) {
|
|
|
140
140
|
|
|
141
141
|
// parse host
|
|
142
142
|
const layer = command.layer;
|
|
143
|
-
const host = layer.source && layer.source.url ? new URL(URLBuilder.subDomains(layer.source.url), document.location).host : undefined;
|
|
143
|
+
const host = layer.source && layer.source.url && layer.source.url !== 'none' ? new URL(URLBuilder.subDomains(layer.source.url), document.location).host : undefined;
|
|
144
144
|
command.promise = new Promise((resolve, reject) => {
|
|
145
145
|
command.resolve = resolve;
|
|
146
146
|
command.reject = reject;
|
package/lib/Core/Style.js
CHANGED
|
@@ -12,33 +12,33 @@ const matrix = document.createElementNS('http://www.w3.org/2000/svg', 'svg').cre
|
|
|
12
12
|
const canvas = document.createElement('canvas');
|
|
13
13
|
const inv255 = 1 / 255;
|
|
14
14
|
function baseAltitudeDefault(properties, ctx) {
|
|
15
|
-
|
|
16
|
-
return (ctx === null || ctx === void 0 ? void 0 : (_ctx$coordinates = ctx.coordinates) === null || _ctx$coordinates === void 0 ? void 0 : _ctx$coordinates.z) || 0;
|
|
15
|
+
return ctx?.coordinates?.z || 0;
|
|
17
16
|
}
|
|
18
17
|
export function readExpression(property, ctx) {
|
|
19
|
-
if (property
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
if (property.expression) {
|
|
19
|
+
return property.expression.evaluate(ctx);
|
|
20
|
+
}
|
|
21
|
+
if (property.stops) {
|
|
22
|
+
const stops = property.stops;
|
|
23
|
+
property = property.stops[0][1];
|
|
24
|
+
for (let i = stops.length - 1; i >= 0; i--) {
|
|
25
|
+
const stop = stops[i];
|
|
26
|
+
if (ctx.zoom >= stop[0]) {
|
|
27
|
+
property = stop[1];
|
|
28
|
+
break;
|
|
28
29
|
}
|
|
29
|
-
return property.stops[0][1];
|
|
30
|
-
}
|
|
31
|
-
if (typeof property === 'string' || property instanceof String) {
|
|
32
|
-
property = property.replace(/\{(.+?)\}/g, (a, b) => ctx.properties[b] || '').trim();
|
|
33
30
|
}
|
|
34
|
-
if (property instanceof Function) {
|
|
35
|
-
// TOBREAK: Pass the current `context` as a unique parameter.
|
|
36
|
-
// In this proposal, metadata will be accessed in the callee by the
|
|
37
|
-
// `context.properties` property.
|
|
38
|
-
return property(ctx.properties, ctx);
|
|
39
|
-
}
|
|
40
|
-
return property;
|
|
41
31
|
}
|
|
32
|
+
if (typeof property === 'string' || property instanceof String) {
|
|
33
|
+
return property.replace(/\{(.+?)\}/g, (a, b) => ctx.properties[b] || '').trim();
|
|
34
|
+
}
|
|
35
|
+
if (property instanceof Function) {
|
|
36
|
+
// TOBREAK: Pass the current `context` as a unique parameter.
|
|
37
|
+
// In this proposal, metadata will be accessed in the callee by the
|
|
38
|
+
// `context.properties` property.
|
|
39
|
+
return property(ctx.properties, ctx);
|
|
40
|
+
}
|
|
41
|
+
return property;
|
|
42
42
|
}
|
|
43
43
|
function rgba2rgb(orig) {
|
|
44
44
|
if (!orig) {
|
|
@@ -49,7 +49,7 @@ function rgba2rgb(orig) {
|
|
|
49
49
|
};
|
|
50
50
|
} else if (typeof orig == 'string') {
|
|
51
51
|
const result = orig.match(/(?:((hsl|rgb)a? *\(([\d.%]+(?:deg|g?rad|turn)?)[ ,]*([\d.%]+)[ ,]*([\d.%]+)[ ,/]*([\d.%]*)\))|(#((?:[\d\w]{3}){1,2})([\d\w]{1,2})?))/i);
|
|
52
|
-
if (
|
|
52
|
+
if (result === null) {
|
|
53
53
|
return {
|
|
54
54
|
color: orig,
|
|
55
55
|
opacity: 1.0
|
|
@@ -63,10 +63,10 @@ function rgba2rgb(orig) {
|
|
|
63
63
|
color: `#${result[8]}`,
|
|
64
64
|
opacity
|
|
65
65
|
};
|
|
66
|
-
} else if (result[
|
|
66
|
+
} else if (result[1]) {
|
|
67
67
|
return {
|
|
68
68
|
color: `${result[2]}(${result[3]},${result[4]},${result[5]})`,
|
|
69
|
-
opacity: Number(result[6])
|
|
69
|
+
opacity: result[6] ? Number(result[6]) : 1.0
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
}
|
|
@@ -154,7 +154,6 @@ function defineStyleProperty(style, category, parameter, userValue, defaultValue
|
|
|
154
154
|
Object.defineProperty(style[category], parameter, {
|
|
155
155
|
enumerable: true,
|
|
156
156
|
get: () => {
|
|
157
|
-
var _style$context$featur, _style$context$featur2;
|
|
158
157
|
// != to check for 'undefined' and 'null' value)
|
|
159
158
|
if (property != undefined) {
|
|
160
159
|
return property;
|
|
@@ -162,7 +161,7 @@ function defineStyleProperty(style, category, parameter, userValue, defaultValue
|
|
|
162
161
|
if (userValue != undefined) {
|
|
163
162
|
return readExpression(userValue, style.context);
|
|
164
163
|
}
|
|
165
|
-
const dataValue =
|
|
164
|
+
const dataValue = style.context.featureStyle?.[category]?.[parameter];
|
|
166
165
|
if (dataValue != undefined) {
|
|
167
166
|
return readExpression(dataValue, style.context);
|
|
168
167
|
}
|
|
@@ -694,31 +693,6 @@ class Style {
|
|
|
694
693
|
defineStyleProperty(this, 'icon', 'color', params.icon.color);
|
|
695
694
|
defineStyleProperty(this, 'icon', 'opacity', params.icon.opacity, 1.0);
|
|
696
695
|
}
|
|
697
|
-
|
|
698
|
-
/**
|
|
699
|
-
* Copies the content of the target style into this style.
|
|
700
|
-
* @param {Style} style - The style to copy.
|
|
701
|
-
*
|
|
702
|
-
* @return {Style} This style.
|
|
703
|
-
*/
|
|
704
|
-
copy(style) {
|
|
705
|
-
Object.assign(this.fill, style.fill);
|
|
706
|
-
Object.assign(this.stroke, style.stroke);
|
|
707
|
-
Object.assign(this.point, style.point);
|
|
708
|
-
Object.assign(this.text, style.text);
|
|
709
|
-
Object.assign(this.icon, style.icon);
|
|
710
|
-
return this;
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
/**
|
|
714
|
-
* Clones this style.
|
|
715
|
-
*
|
|
716
|
-
* @return {Style} The new style, cloned from this one.
|
|
717
|
-
*/
|
|
718
|
-
clone() {
|
|
719
|
-
const clone = new Style();
|
|
720
|
-
return clone.copy(this);
|
|
721
|
-
}
|
|
722
696
|
setContext(ctx) {
|
|
723
697
|
this.context = ctx;
|
|
724
698
|
}
|
|
@@ -942,8 +916,35 @@ class Style {
|
|
|
942
916
|
if (iconImg) {
|
|
943
917
|
try {
|
|
944
918
|
style.icon.id = iconImg;
|
|
919
|
+
if (iconImg.stops) {
|
|
920
|
+
const iconCropValue = {
|
|
921
|
+
...(iconImg.base !== undefined && {
|
|
922
|
+
base: iconImg.base
|
|
923
|
+
}),
|
|
924
|
+
stops: iconImg.stops.map(stop => {
|
|
925
|
+
let cropValues = sprites[stop[1]];
|
|
926
|
+
if (stop[1].includes('{')) {
|
|
927
|
+
cropValues = function (p) {
|
|
928
|
+
const id = stop[1].replace(/\{(.+?)\}/g, (a, b) => p[b] || '').trim();
|
|
929
|
+
cropValues = sprites[id];
|
|
930
|
+
return sprites[id];
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
return [stop[0], cropValues];
|
|
934
|
+
})
|
|
935
|
+
};
|
|
936
|
+
style.icon.cropValues = iconCropValue;
|
|
937
|
+
} else {
|
|
938
|
+
style.icon.cropValues = sprites[iconImg];
|
|
939
|
+
if (iconImg[0].includes('{')) {
|
|
940
|
+
style.icon.cropValues = function (p) {
|
|
941
|
+
const id = iconImg.replace(/\{(.+?)\}/g, (a, b) => p[b] || '').trim();
|
|
942
|
+
style.icon.cropValues = sprites[id];
|
|
943
|
+
return sprites[id];
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
}
|
|
945
947
|
style.icon.source = sprites.source;
|
|
946
|
-
style.icon.cropValues = sprites[iconImg];
|
|
947
948
|
style.icon.size = readVectorProperty(layer.layout['icon-size']) || 1;
|
|
948
949
|
const {
|
|
949
950
|
color,
|
package/lib/Core/View.js
CHANGED
|
@@ -232,8 +232,7 @@ class View extends THREE.EventDispatcher {
|
|
|
232
232
|
* @returns {THREE.WebGLRenderer} the WebGLRenderer used to render this view.
|
|
233
233
|
*/
|
|
234
234
|
get renderer() {
|
|
235
|
-
|
|
236
|
-
return (_this$mainLoop = this.mainLoop) === null || _this$mainLoop === void 0 ? void 0 : (_this$mainLoop$gfxEng = _this$mainLoop.gfxEngine) === null || _this$mainLoop$gfxEng === void 0 ? void 0 : _this$mainLoop$gfxEng.getRenderer();
|
|
235
|
+
return this.mainLoop?.gfxEngine?.getRenderer();
|
|
237
236
|
}
|
|
238
237
|
|
|
239
238
|
/**
|
|
@@ -241,8 +240,7 @@ class View extends THREE.EventDispatcher {
|
|
|
241
240
|
* @returns {THREE.Camera} the threejs camera of this view
|
|
242
241
|
*/
|
|
243
242
|
get camera3D() {
|
|
244
|
-
|
|
245
|
-
return (_this$camera = this.camera) === null || _this$camera === void 0 ? void 0 : _this$camera.camera3D;
|
|
243
|
+
return this.camera?.camera3D;
|
|
246
244
|
}
|
|
247
245
|
|
|
248
246
|
/**
|
|
@@ -92,7 +92,9 @@ class C3DTilesLayer extends GeometryLayer {
|
|
|
92
92
|
* @param {Number} [config.cleanupDelay=1000] The time (in ms) after which a tile content (and its children) are
|
|
93
93
|
* removed from the scene.
|
|
94
94
|
* @param {C3DTExtensions} [config.registeredExtensions] 3D Tiles extensions managers registered for this tileset.
|
|
95
|
-
* @param {String} [config.pntsMode= PNTS_MODE.COLOR] {@link PointsMaterials} Point cloud coloring mode.
|
|
95
|
+
* @param {String} [config.pntsMode= PNTS_MODE.COLOR] {@link PointsMaterials} Point cloud coloring mode.
|
|
96
|
+
* Only 'COLOR' or 'CLASSIFICATION' are possible. COLOR uses RGB colors of the points,
|
|
97
|
+
* CLASSIFICATION uses a classification property of the batch table to color points.
|
|
96
98
|
* @param {String} [config.pntsShape= PNTS_SHAPE.CIRCLE] Point cloud point shape. Only 'CIRCLE' or 'SQUARE' are possible.
|
|
97
99
|
* @param {String} [config.pntsSizeMode= PNTS_SIZE_MODE.VALUE] {@link PointsMaterials} Point cloud size mode. Only 'VALUE' or 'ATTENUATED' are possible. VALUE use constant size, ATTENUATED compute size depending on distance from point to camera.
|
|
98
100
|
* @param {Number} [config.pntsMinAttenuatedSize=3] Minimum scale used by 'ATTENUATED' size mode
|
|
@@ -114,8 +116,8 @@ class C3DTilesLayer extends GeometryLayer {
|
|
|
114
116
|
this.pntsShape = PNTS_SHAPE.CIRCLE;
|
|
115
117
|
this.classification = config.classification;
|
|
116
118
|
this.pntsSizeMode = PNTS_SIZE_MODE.VALUE;
|
|
117
|
-
this.pntsMinAttenuatedSize = config.pntsMinAttenuatedSize ||
|
|
118
|
-
this.pntsMaxAttenuatedSize = config.pntsMaxAttenuatedSize ||
|
|
119
|
+
this.pntsMinAttenuatedSize = config.pntsMinAttenuatedSize || 1;
|
|
120
|
+
this.pntsMaxAttenuatedSize = config.pntsMaxAttenuatedSize || 7;
|
|
119
121
|
if (config.pntsMode) {
|
|
120
122
|
const exists = Object.values(PNTS_MODE).includes(config.pntsMode);
|
|
121
123
|
if (!exists) {
|
|
@@ -184,8 +186,8 @@ class C3DTilesLayer extends GeometryLayer {
|
|
|
184
186
|
init3dTilesLayer(view, view.mainLoop.scheduler, this, tileset.root).then(resolve);
|
|
185
187
|
});
|
|
186
188
|
}
|
|
187
|
-
preUpdate() {
|
|
188
|
-
return pre3dTilesUpdate.bind(this)();
|
|
189
|
+
preUpdate(context) {
|
|
190
|
+
return pre3dTilesUpdate.bind(this)(context);
|
|
189
191
|
}
|
|
190
192
|
update(context, layer, node) {
|
|
191
193
|
return update(context, layer, node);
|
|
@@ -241,7 +243,7 @@ class C3DTilesLayer extends GeometryLayer {
|
|
|
241
243
|
// face is a Face3 object of THREE which is a
|
|
242
244
|
// triangular face. face.a is its first vertex
|
|
243
245
|
const vertex = closestIntersect.face.a;
|
|
244
|
-
const batchID = closestIntersect.object.geometry.attributes._BATCHID.
|
|
246
|
+
const batchID = closestIntersect.object.geometry.attributes._BATCHID.getX(vertex);
|
|
245
247
|
return this.tilesC3DTileFeatures.get(tileId).get(batchID);
|
|
246
248
|
}
|
|
247
249
|
|
|
@@ -60,14 +60,13 @@ class ElevationLayer extends RasterLayer {
|
|
|
60
60
|
* view.addLayer(elevation);
|
|
61
61
|
*/
|
|
62
62
|
constructor(id) {
|
|
63
|
-
var _config$clampValues, _config$clampValues2;
|
|
64
63
|
let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
65
64
|
super(id, config);
|
|
66
65
|
if (config.zmin || config.zmax) {
|
|
67
66
|
console.warn('Config using zmin and zmax are deprecated, use {clampValues: {min, max}} structure.');
|
|
68
67
|
}
|
|
69
|
-
this.zmin =
|
|
70
|
-
this.zmax =
|
|
68
|
+
this.zmin = config.clampValues?.min ?? config.zmin;
|
|
69
|
+
this.zmax = config.clampValues?.max ?? config.zmax;
|
|
71
70
|
this.isElevationLayer = true;
|
|
72
71
|
this.defineLayerProperty('scale', this.scale || 1.0);
|
|
73
72
|
}
|
package/lib/Layer/GeoidLayer.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import Layer from "./Layer.js";
|
|
2
2
|
import LayerUpdateState from "./LayerUpdateState.js";
|
|
3
3
|
export function geoidLayerIsVisible(tilelayer) {
|
|
4
|
-
|
|
5
|
-
return tilelayer === null || tilelayer === void 0 ? void 0 : (_tilelayer$attachedLa = tilelayer.attachedLayers.filter(l => l.isGeoidLayer)[0]) === null || _tilelayer$attachedLa === void 0 ? void 0 : _tilelayer$attachedLa.visible;
|
|
4
|
+
return tilelayer?.attachedLayers.filter(l => l.isGeoidLayer)[0]?.visible;
|
|
6
5
|
}
|
|
7
6
|
|
|
8
7
|
/**
|