itowns 2.45.1-next.0 → 2.45.1-next.1
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/455.js +2 -0
- package/dist/455.js.map +1 -0
- package/dist/debug.js +3 -0
- package/dist/debug.js.LICENSE.txt +13 -0
- package/dist/debug.js.map +1 -0
- package/dist/itowns.js +3 -0
- package/dist/itowns.js.LICENSE.txt +5 -0
- package/dist/itowns.js.map +1 -0
- 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 +2 -0
- package/dist/itowns_widgets.js.map +1 -0
- package/lib/Controls/FirstPersonControls.js +308 -0
- package/lib/Controls/FlyControls.js +175 -0
- package/lib/Controls/GlobeControls.js +1178 -0
- package/lib/Controls/PlanarControls.js +1025 -0
- package/lib/Controls/StateControl.js +432 -0
- package/lib/Controls/StreetControls.js +392 -0
- package/lib/Converter/Feature2Mesh.js +612 -0
- package/lib/Converter/Feature2Texture.js +174 -0
- package/lib/Converter/convertToTile.js +70 -0
- package/lib/Converter/textureConverter.js +43 -0
- package/lib/Core/3DTiles/C3DTBatchTable.js +131 -0
- package/lib/Core/3DTiles/C3DTBatchTableHierarchyExtension.js +96 -0
- package/lib/Core/3DTiles/C3DTBoundingVolume.js +156 -0
- package/lib/Core/3DTiles/C3DTExtensions.js +97 -0
- package/lib/Core/3DTiles/C3DTFeature.js +110 -0
- package/lib/Core/3DTiles/C3DTilesEnums.js +20 -0
- package/lib/Core/3DTiles/C3DTileset.js +99 -0
- package/lib/Core/3DTiles/utils/BinaryPropertyAccessor.js +100 -0
- package/lib/Core/AnimationPlayer.js +142 -0
- package/lib/Core/CopcNode.js +174 -0
- package/lib/Core/Deprecated/Undeprecator.js +74 -0
- package/lib/Core/EntwinePointTileNode.js +126 -0
- package/lib/Core/Feature.js +488 -0
- package/lib/Core/Geographic/GeoidGrid.js +108 -0
- package/lib/Core/Label.js +222 -0
- package/lib/Core/MainLoop.js +209 -0
- package/lib/Core/Picking.js +255 -0
- package/lib/Core/PointCloudNode.js +42 -0
- package/lib/Core/Potree2Node.js +206 -0
- package/lib/Core/Potree2PointAttributes.js +139 -0
- package/lib/Core/PotreeNode.js +101 -0
- package/lib/Core/Prefab/Globe/Atmosphere.js +293 -0
- package/lib/Core/Prefab/Globe/GlobeLayer.js +152 -0
- package/lib/Core/Prefab/Globe/GlobeTileBuilder.js +110 -0
- package/lib/Core/Prefab/Globe/SkyShader.js +78 -0
- package/lib/Core/Prefab/GlobeView.js +155 -0
- package/lib/Core/Prefab/Planar/PlanarLayer.js +59 -0
- package/lib/Core/Prefab/Planar/PlanarTileBuilder.js +71 -0
- package/lib/Core/Prefab/PlanarView.js +62 -0
- package/lib/Core/Prefab/TileBuilder.js +82 -0
- package/lib/Core/Prefab/computeBufferTileGeometry.js +248 -0
- package/lib/Core/Scheduler/Cache.js +17 -0
- package/lib/Core/Scheduler/CancelledCommandException.js +15 -0
- package/lib/Core/Scheduler/Scheduler.js +294 -0
- package/lib/Core/Style.js +660 -0
- package/lib/Core/StyleOptions.js +486 -0
- package/lib/Core/System/Capabilities.js +63 -0
- package/lib/Core/Tile/Tile.js +205 -0
- package/lib/Core/Tile/TileGrid.js +49 -0
- package/lib/Core/TileGeometry.js +124 -0
- package/lib/Core/TileMesh.js +108 -0
- package/lib/Core/View.js +1115 -0
- package/lib/Layer/C3DTilesLayer.js +459 -0
- package/lib/Layer/ColorLayer.js +154 -0
- package/lib/Layer/CopcLayer.js +63 -0
- package/lib/Layer/ElevationLayer.js +139 -0
- package/lib/Layer/EntwinePointTileLayer.js +71 -0
- package/lib/Layer/FeatureGeometryLayer.js +77 -0
- package/lib/Layer/GeoidLayer.js +80 -0
- package/lib/Layer/GeometryLayer.js +233 -0
- package/lib/Layer/InfoLayer.js +64 -0
- package/lib/Layer/LabelLayer.js +469 -0
- package/lib/Layer/Layer.js +335 -0
- package/lib/Layer/LayerUpdateState.js +89 -0
- package/lib/Layer/LayerUpdateStrategy.js +80 -0
- package/lib/Layer/OGC3DTilesLayer.js +543 -0
- package/lib/Layer/OrientedImageLayer.js +227 -0
- package/lib/Layer/PointCloudLayer.js +405 -0
- package/lib/Layer/Potree2Layer.js +171 -0
- package/lib/Layer/PotreeLayer.js +72 -0
- package/lib/Layer/RasterLayer.js +37 -0
- package/lib/Layer/ReferencingLayerProperties.js +62 -0
- package/lib/Layer/TiledGeometryLayer.js +459 -0
- package/lib/Loader/LASLoader.js +193 -0
- package/lib/Loader/Potree2BrotliLoader.js +261 -0
- package/lib/Loader/Potree2Loader.js +207 -0
- package/lib/Main.js +113 -0
- package/lib/MainBundle.js +4 -0
- package/lib/Parser/B3dmParser.js +174 -0
- package/lib/Parser/CameraCalibrationParser.js +94 -0
- package/lib/Parser/GDFParser.js +72 -0
- package/lib/Parser/GTXParser.js +75 -0
- package/lib/Parser/GeoJsonParser.js +212 -0
- package/lib/Parser/GpxParser.js +25 -0
- package/lib/Parser/ISGParser.js +71 -0
- package/lib/Parser/KMLParser.js +25 -0
- package/lib/Parser/LASParser.js +137 -0
- package/lib/Parser/MapBoxUrlParser.js +83 -0
- package/lib/Parser/PntsParser.js +131 -0
- package/lib/Parser/Potree2BinParser.js +92 -0
- package/lib/Parser/PotreeBinParser.js +106 -0
- package/lib/Parser/PotreeCinParser.js +29 -0
- package/lib/Parser/ShapefileParser.js +78 -0
- package/lib/Parser/VectorTileParser.js +215 -0
- package/lib/Parser/XbilParser.js +120 -0
- package/lib/Parser/deprecated/LegacyGLTFLoader.js +1386 -0
- package/lib/Parser/iGLTFLoader.js +168 -0
- package/lib/Process/3dTilesProcessing.js +304 -0
- package/lib/Process/FeatureProcessing.js +76 -0
- package/lib/Process/LayeredMaterialNodeProcessing.js +229 -0
- package/lib/Process/ObjectRemovalHelper.js +97 -0
- package/lib/Process/handlerNodeError.js +23 -0
- package/lib/Provider/3dTilesProvider.js +149 -0
- package/lib/Provider/DataSourceProvider.js +24 -0
- package/lib/Provider/Fetcher.js +233 -0
- package/lib/Provider/PointCloudProvider.js +45 -0
- package/lib/Provider/TileProvider.js +16 -0
- package/lib/Provider/URLBuilder.js +116 -0
- package/lib/Renderer/Camera.js +281 -0
- package/lib/Renderer/Color.js +56 -0
- package/lib/Renderer/ColorLayersOrdering.js +115 -0
- package/lib/Renderer/CommonMaterial.js +31 -0
- package/lib/Renderer/Label2DRenderer.js +192 -0
- package/lib/Renderer/LayeredMaterial.js +243 -0
- package/lib/Renderer/OBB.js +150 -0
- package/lib/Renderer/OrientedImageCamera.js +118 -0
- package/lib/Renderer/OrientedImageMaterial.js +167 -0
- package/lib/Renderer/PointsMaterial.js +485 -0
- package/lib/Renderer/RasterTile.js +243 -0
- package/lib/Renderer/RenderMode.js +31 -0
- package/lib/Renderer/Shader/ShaderChunk.js +160 -0
- package/lib/Renderer/Shader/ShaderUtils.js +47 -0
- package/lib/Renderer/SphereHelper.js +17 -0
- package/lib/Renderer/WebXR.js +51 -0
- package/lib/Renderer/c3DEngine.js +214 -0
- package/lib/Source/C3DTilesGoogleSource.js +74 -0
- package/lib/Source/C3DTilesIonSource.js +54 -0
- package/lib/Source/C3DTilesSource.js +30 -0
- package/lib/Source/CopcSource.js +126 -0
- package/lib/Source/EntwinePointTileSource.js +72 -0
- package/lib/Source/FileSource.js +188 -0
- package/lib/Source/OGC3DTilesGoogleSource.js +29 -0
- package/lib/Source/OGC3DTilesIonSource.js +34 -0
- package/lib/Source/OGC3DTilesSource.js +21 -0
- package/lib/Source/OrientedImageSource.js +59 -0
- package/lib/Source/Potree2Source.js +167 -0
- package/lib/Source/PotreeSource.js +82 -0
- package/lib/Source/Source.js +202 -0
- package/lib/Source/TMSSource.js +144 -0
- package/lib/Source/VectorTilesSource.js +182 -0
- package/lib/Source/WFSSource.js +170 -0
- package/lib/Source/WMSSource.js +167 -0
- package/lib/Source/WMTSSource.js +92 -0
- package/lib/ThreeExtended/capabilities/WebGL.js +69 -0
- package/lib/ThreeExtended/libs/ktx-parse.module.js +506 -0
- package/lib/ThreeExtended/libs/zstddec.module.js +29 -0
- package/lib/ThreeExtended/loaders/DDSLoader.js +200 -0
- package/lib/ThreeExtended/loaders/DRACOLoader.js +400 -0
- package/lib/ThreeExtended/loaders/GLTFLoader.js +2879 -0
- package/lib/ThreeExtended/loaders/KTX2Loader.js +709 -0
- package/lib/ThreeExtended/math/ColorSpaces.js +59 -0
- package/lib/ThreeExtended/utils/BufferGeometryUtils.js +846 -0
- package/lib/ThreeExtended/utils/WorkerPool.js +70 -0
- package/lib/Utils/CameraUtils.js +554 -0
- package/lib/Utils/DEMUtils.js +350 -0
- package/lib/Utils/FeaturesUtils.js +156 -0
- package/lib/Utils/Gradients.js +16 -0
- package/lib/Utils/ThreeUtils.js +115 -0
- package/lib/Utils/gui/C3DTilesStyle.js +218 -0
- package/lib/Utils/gui/Main.js +7 -0
- package/lib/Utils/gui/Minimap.js +152 -0
- package/lib/Utils/gui/Navigation.js +245 -0
- package/lib/Utils/gui/Scale.js +104 -0
- package/lib/Utils/gui/Searchbar.js +234 -0
- package/lib/Utils/gui/Widget.js +80 -0
- package/lib/Utils/placeObjectOnGround.js +136 -0
- package/lib/Worker/LASLoaderWorker.js +19 -0
- package/lib/Worker/Potree2Worker.js +21 -0
- package/package.json +2 -2
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import { ELEVATION_MODES } from "./LayeredMaterial.js";
|
|
3
|
+
import { checkNodeElevationTextureValidity, insertSignificantValuesFromParent, computeMinMaxElevation } from "../Parser/XbilParser.js";
|
|
4
|
+
export const EMPTY_TEXTURE_ZOOM = -1;
|
|
5
|
+
const pitch = new THREE.Vector4();
|
|
6
|
+
function getIndiceWithPitch(i, pitch, w) {
|
|
7
|
+
// Return corresponding indice in parent tile using pitch
|
|
8
|
+
// normalized
|
|
9
|
+
const currentY = Math.floor(i / w) / w; // normalized
|
|
10
|
+
const newX = pitch.x + i % w / w * pitch.z;
|
|
11
|
+
const newY = pitch.y + currentY * pitch.w;
|
|
12
|
+
const newIndice = Math.floor(newY * w) * w + Math.floor(newX * w);
|
|
13
|
+
return newIndice;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A `RasterTile` is part of raster {@link Layer} data.
|
|
18
|
+
* This part is a spatial subdivision of the extent of a layer.
|
|
19
|
+
* In the `RasterTile`, The data are converted on three.js textures.
|
|
20
|
+
* This `RasterTile` textures are assigned to a `LayeredMaterial`.
|
|
21
|
+
* This material is applied on terrain (TileMesh).
|
|
22
|
+
* The color textures are mapped to color the terrain.
|
|
23
|
+
* The elevation textures are used to displace vertex terrain.
|
|
24
|
+
*
|
|
25
|
+
* @class RasterTile
|
|
26
|
+
*/
|
|
27
|
+
class RasterTile extends THREE.EventDispatcher {
|
|
28
|
+
constructor(material, layer) {
|
|
29
|
+
super();
|
|
30
|
+
this.layer = layer;
|
|
31
|
+
this.crs = layer.parent.tileMatrixSets.indexOf(layer.crs);
|
|
32
|
+
if (this.crs == -1) {
|
|
33
|
+
console.error('Unknown crs:', layer.crs);
|
|
34
|
+
}
|
|
35
|
+
this.textures = [];
|
|
36
|
+
this.offsetScales = [];
|
|
37
|
+
this.level = EMPTY_TEXTURE_ZOOM;
|
|
38
|
+
this.material = material;
|
|
39
|
+
this._handlerCBEvent = () => {
|
|
40
|
+
this.material.layersNeedUpdate = true;
|
|
41
|
+
};
|
|
42
|
+
layer.addEventListener('visible-property-changed', this._handlerCBEvent);
|
|
43
|
+
layer.addEventListener('opacity-property-changed', this._handlerCBEvent);
|
|
44
|
+
}
|
|
45
|
+
get id() {
|
|
46
|
+
return this.layer.id;
|
|
47
|
+
}
|
|
48
|
+
get opacity() {
|
|
49
|
+
return this.layer.opacity;
|
|
50
|
+
}
|
|
51
|
+
get visible() {
|
|
52
|
+
return this.layer.visible;
|
|
53
|
+
}
|
|
54
|
+
initFromParent(parent, extents) {
|
|
55
|
+
if (parent && parent.level > this.level) {
|
|
56
|
+
let index = 0;
|
|
57
|
+
const sortedParentTextures = this.sortBestParentTextures(parent.textures);
|
|
58
|
+
for (const childExtent of extents) {
|
|
59
|
+
const matchingParentTexture = sortedParentTextures.find(parentTexture => parentTexture && childExtent.isInside(parentTexture.extent));
|
|
60
|
+
if (matchingParentTexture) {
|
|
61
|
+
this.setTexture(index++, matchingParentTexture, childExtent.offsetToParent(matchingParentTexture.extent));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
sortBestParentTextures(textures) {
|
|
67
|
+
const sortByValidity = (a, b) => {
|
|
68
|
+
if (a.isTexture === b.isTexture) {
|
|
69
|
+
return 0;
|
|
70
|
+
} else {
|
|
71
|
+
return a.isTexture ? -1 : 1;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const sortByZoom = (a, b) => b.extent.zoom - a.extent.zoom;
|
|
75
|
+
return textures.toSorted((a, b) => sortByValidity(a, b) || sortByZoom(a, b));
|
|
76
|
+
}
|
|
77
|
+
disposeRedrawnTextures(newTextures) {
|
|
78
|
+
const validTextureIndexes = newTextures.map((texture, index) => this.shouldWriteTextureAtIndex(index, texture) ? index : -1).filter(index => index !== -1);
|
|
79
|
+
if (validTextureIndexes.length === newTextures.length) {
|
|
80
|
+
// Dispose the whole tile when all textures are overwritten
|
|
81
|
+
this.dispose(false);
|
|
82
|
+
} else {
|
|
83
|
+
this.disposeAtIndexes(validTextureIndexes);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
dispose() {
|
|
87
|
+
let removeEvent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
|
88
|
+
if (removeEvent) {
|
|
89
|
+
this.layer.removeEventListener('visible-property-changed', this._handlerCBEvent);
|
|
90
|
+
this.layer.removeEventListener('opacity-property-changed', this._handlerCBEvent);
|
|
91
|
+
// dispose all events
|
|
92
|
+
this._listeners = {};
|
|
93
|
+
}
|
|
94
|
+
// TODO: WARNING verify if textures to dispose aren't attached with ancestor
|
|
95
|
+
// Dispose all textures
|
|
96
|
+
this.disposeAtIndexes(this.textures.keys());
|
|
97
|
+
this.textures = [];
|
|
98
|
+
this.offsetScales = [];
|
|
99
|
+
this.level = EMPTY_TEXTURE_ZOOM;
|
|
100
|
+
}
|
|
101
|
+
disposeAtIndexes(indexes) {
|
|
102
|
+
for (const index of indexes) {
|
|
103
|
+
const texture = this.textures[index];
|
|
104
|
+
if (texture && texture.isTexture) {
|
|
105
|
+
texture.dispose();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
this.material.layersNeedUpdate = true;
|
|
109
|
+
}
|
|
110
|
+
setTexture(index, texture, offsetScale) {
|
|
111
|
+
if (this.shouldWriteTextureAtIndex(index, texture)) {
|
|
112
|
+
this.level = texture && texture.extent ? texture.extent.zoom : this.level;
|
|
113
|
+
this.textures[index] = texture || null;
|
|
114
|
+
this.offsetScales[index] = offsetScale;
|
|
115
|
+
this.material.layersNeedUpdate = true;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
setTextures(textures, pitchs) {
|
|
119
|
+
this.disposeRedrawnTextures(textures);
|
|
120
|
+
for (let i = 0, il = textures.length; i < il; ++i) {
|
|
121
|
+
this.setTexture(i, textures[i], pitchs[i]);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
shouldWriteTextureAtIndex(index, texture) {
|
|
125
|
+
// Do not apply noData texture if current texture is valid
|
|
126
|
+
return !this.textures[index] || texture && texture.isTexture;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
export default RasterTile;
|
|
130
|
+
export class RasterColorTile extends RasterTile {
|
|
131
|
+
get effect_type() {
|
|
132
|
+
return this.layer.effect_type;
|
|
133
|
+
}
|
|
134
|
+
get effect_parameter() {
|
|
135
|
+
return this.layer.effect_parameter;
|
|
136
|
+
}
|
|
137
|
+
get transparent() {
|
|
138
|
+
return this.layer.transparent;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
export class RasterElevationTile extends RasterTile {
|
|
142
|
+
constructor(material, layer) {
|
|
143
|
+
super(material, layer);
|
|
144
|
+
const defaultEle = {
|
|
145
|
+
bias: 0,
|
|
146
|
+
mode: ELEVATION_MODES.DATA,
|
|
147
|
+
zmin: -Infinity,
|
|
148
|
+
zmax: Infinity
|
|
149
|
+
};
|
|
150
|
+
this.scaleFactor = 1.0;
|
|
151
|
+
|
|
152
|
+
// Define elevation properties
|
|
153
|
+
if (layer.useRgbaTextureElevation) {
|
|
154
|
+
defaultEle.mode = ELEVATION_MODES.RGBA;
|
|
155
|
+
defaultEle.zmax = 5000;
|
|
156
|
+
throw new Error('Restore this feature');
|
|
157
|
+
} else if (layer.useColorTextureElevation) {
|
|
158
|
+
this.scaleFactor = layer.colorTextureElevationMaxZ - layer.colorTextureElevationMinZ;
|
|
159
|
+
defaultEle.mode = ELEVATION_MODES.COLOR;
|
|
160
|
+
defaultEle.bias = layer.colorTextureElevationMinZ;
|
|
161
|
+
this.min = this.layer.colorTextureElevationMinZ;
|
|
162
|
+
this.max = this.layer.colorTextureElevationMaxZ;
|
|
163
|
+
} else {
|
|
164
|
+
this.min = 0;
|
|
165
|
+
this.max = 0;
|
|
166
|
+
}
|
|
167
|
+
this.bias = layer.bias ?? defaultEle.bias;
|
|
168
|
+
this.mode = layer.mode ?? defaultEle.mode;
|
|
169
|
+
this.zmin = layer.zmin ?? defaultEle.zmin;
|
|
170
|
+
this.zmax = layer.zmax ?? defaultEle.zmax;
|
|
171
|
+
layer.addEventListener('scale-property-changed', this._handlerCBEvent);
|
|
172
|
+
}
|
|
173
|
+
get scale() {
|
|
174
|
+
return this.layer.scale * this.scaleFactor;
|
|
175
|
+
}
|
|
176
|
+
dispose(removeEvent) {
|
|
177
|
+
super.dispose(removeEvent);
|
|
178
|
+
if (removeEvent) {
|
|
179
|
+
this.layer.removeEventListener('scale-property-changed', this._handlerCBEvent);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
initFromParent(parent, extents) {
|
|
183
|
+
const currentLevel = this.level;
|
|
184
|
+
super.initFromParent(parent, extents);
|
|
185
|
+
this.updateMinMaxElevation();
|
|
186
|
+
if (currentLevel !== this.level) {
|
|
187
|
+
this.dispatchEvent({
|
|
188
|
+
type: 'rasterElevationLevelChanged',
|
|
189
|
+
node: this
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
setTextures(textures, offsetScales) {
|
|
194
|
+
const anyValidTexture = textures.find(texture => texture != null);
|
|
195
|
+
if (!anyValidTexture) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const currentLevel = this.level;
|
|
199
|
+
this.replaceNoDataValueFromTexture(anyValidTexture);
|
|
200
|
+
super.setTextures(textures, offsetScales);
|
|
201
|
+
this.updateMinMaxElevation();
|
|
202
|
+
if (currentLevel !== this.level) {
|
|
203
|
+
this.dispatchEvent({
|
|
204
|
+
type: 'rasterElevationLevelChanged',
|
|
205
|
+
node: this
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
updateMinMaxElevation() {
|
|
210
|
+
const firstValidIndex = this.textures.findIndex(texture => texture.isTexture);
|
|
211
|
+
if (firstValidIndex !== -1 && !this.layer.useColorTextureElevation) {
|
|
212
|
+
const {
|
|
213
|
+
min,
|
|
214
|
+
max
|
|
215
|
+
} = computeMinMaxElevation(this.textures[firstValidIndex], this.offsetScales[firstValidIndex], {
|
|
216
|
+
noDataValue: this.layer.noDataValue,
|
|
217
|
+
zmin: this.layer.zmin,
|
|
218
|
+
zmax: this.layer.zmax
|
|
219
|
+
});
|
|
220
|
+
if (this.min != min || this.max != max) {
|
|
221
|
+
this.min = isNaN(min) ? this.min : min;
|
|
222
|
+
this.max = isNaN(max) ? this.max : max;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
replaceNoDataValueFromTexture(texture) {
|
|
227
|
+
const nodatavalue = this.layer.noDataValue;
|
|
228
|
+
if (nodatavalue == undefined) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
// replace no data value with parent texture value or 0 (if no significant value found).
|
|
232
|
+
const parentTexture = this.textures.find(texture => texture != null);
|
|
233
|
+
const parentDataElevation = parentTexture && parentTexture.image && parentTexture.image.data;
|
|
234
|
+
const dataElevation = texture.image && texture.image.data;
|
|
235
|
+
if (dataElevation && !checkNodeElevationTextureValidity(dataElevation, nodatavalue)) {
|
|
236
|
+
insertSignificantValuesFromParent(dataElevation, parentDataElevation && dataParent(texture, parentTexture, parentDataElevation, pitch), nodatavalue);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function dataParent(texture, parentTexture, parentDataElevation, pitch) {
|
|
241
|
+
texture.extent.offsetToParent(parentTexture.extent, pitch);
|
|
242
|
+
return i => parentDataElevation[getIndiceWithPitch(i, pitch, 256)];
|
|
243
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const MODES = {
|
|
2
|
+
FINAL: 0,
|
|
3
|
+
// final color
|
|
4
|
+
DEPTH: 1,
|
|
5
|
+
// depth buffer
|
|
6
|
+
ID: 2 // id object
|
|
7
|
+
};
|
|
8
|
+
function push(object3d, mode) {
|
|
9
|
+
const _mode = object3d.mode ?? MODES.FINAL;
|
|
10
|
+
if (_mode == mode) {
|
|
11
|
+
return () => {};
|
|
12
|
+
}
|
|
13
|
+
const setMode = m => node => {
|
|
14
|
+
const material = node.material;
|
|
15
|
+
if (material) {
|
|
16
|
+
material.mode = m;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
object3d.traverse(setMode(mode));
|
|
20
|
+
return () => {
|
|
21
|
+
object3d.traverse(setMode(_mode));
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Rendering mode
|
|
26
|
+
// According to the rendering mode, the material's object switches
|
|
27
|
+
// the mode property of the materials
|
|
28
|
+
export default {
|
|
29
|
+
MODES,
|
|
30
|
+
push
|
|
31
|
+
};
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
/* babel-plugin-inline-import './Chunk/color_layers_pars_fragment.glsl' */
|
|
3
|
+
const color_layers_pars_fragment = "struct Layer {\n int textureOffset;\n int crs;\n int effect_type;\n float effect_parameter;\n float opacity;\n bool transparent;\n};\n\n#include <itowns/custom_header_colorLayer>\n\nuniform sampler2D colorTextures[NUM_FS_TEXTURES];\nuniform vec4 colorOffsetScales[NUM_FS_TEXTURES];\nuniform Layer colorLayers[NUM_FS_TEXTURES];\nuniform int colorTextureCount;\n\nvec3 uvs[NUM_CRS];\n\nfloat getBorderDistance(vec2 uv) {\n vec2 p2 = min(uv, 1. -uv);\n return min(p2.x, p2.y);\n}\n\nfloat tolerance = 0.99;\n\nvec4 applyWhiteToInvisibleEffect(vec4 color) {\n float a = dot(color.rgb, vec3(0.333333333));\n if (a >= tolerance) {\n color.a = 0.0;\n }\n return color;\n}\n\nvec4 applyLightColorToInvisibleEffect(vec4 color, float intensity) {\n float a = max(0.05,1. - length(color.xyz - 1.));\n color.a *= 1.0 - pow(abs(a), intensity);\n color.rgb *= color.rgb * color.rgb;\n return color;\n}\n\n#if defined(DEBUG)\nuniform bool showOutline;\nuniform vec3 outlineColors[NUM_CRS];\nuniform float outlineWidth;\n\nvec4 getOutlineColor(vec3 outlineColor, vec2 uv) {\n float alpha = 1. - clamp(getBorderDistance(uv) / outlineWidth, 0., 1.);\n return vec4(outlineColor, alpha);\n}\n#endif\n\nuniform float minBorderDistance;\nvec4 getLayerColor(int textureOffset, sampler2D tex, vec4 offsetScale, Layer layer) {\n if ( textureOffset >= colorTextureCount ) return vec4(0);\n\n vec3 uv;\n // #pragma unroll_loop\n for ( int i = 0; i < NUM_CRS; i ++ ) {\n if ( i == layer.crs ) uv = uvs[ i ];\n }\n\n float borderDistance = getBorderDistance(uv.xy);\n if (textureOffset != layer.textureOffset + int(uv.z) || borderDistance < minBorderDistance ) return vec4(0);\n vec4 color = texture2D(tex, pitUV(uv.xy, offsetScale));\n if (layer.effect_type == 3) {\n #include <itowns/custom_body_colorLayer>\n } else {\n if (layer.transparent && color.a != 0.0) {\n color.rgb /= color.a;\n }\n\n if (layer.effect_type == 1) {\n color = applyLightColorToInvisibleEffect(color, layer.effect_parameter);\n } else if (layer.effect_type == 2) {\n color = applyWhiteToInvisibleEffect(color);\n }\n }\n color.a *= layer.opacity;\n return color;\n}\n";
|
|
4
|
+
/* babel-plugin-inline-import './Chunk/elevation_pars_vertex.glsl' */
|
|
5
|
+
const elevation_pars_vertex = "#if NUM_VS_TEXTURES > 0\n struct Layer {\n float scale;\n float bias;\n int mode;\n float zmin;\n float zmax;\n };\n\n uniform Layer elevationLayers[NUM_VS_TEXTURES];\n uniform sampler2D elevationTextures[NUM_VS_TEXTURES];\n uniform vec4 elevationOffsetScales[NUM_VS_TEXTURES];\n uniform int elevationTextureCount;\n uniform float geoidHeight;\n\n highp float decode32(highp vec4 rgba) {\n highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;\n highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;\n highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);\n highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));\n return Result;\n }\n\n float getElevationMode(vec2 uv, sampler2D tex, int mode) {\n if (mode == ELEVATION_RGBA)\n return decode32(texture2D( tex, uv ).abgr * 255.0);\n if (mode == ELEVATION_DATA || mode == ELEVATION_COLOR)\n return texture2D( tex, uv ).r;\n return 0.;\n }\n\n float getElevation(vec2 uv, sampler2D tex, vec4 offsetScale, Layer layer) {\n // Elevation textures are inverted along the y-axis\n uv = vec2(uv.x, 1.0 - uv.y);\n uv = uv * offsetScale.zw + offsetScale.xy;\n float d = clamp(getElevationMode(uv, tex, layer.mode), layer.zmin, layer.zmax);\n return d * layer.scale + layer.bias;\n }\n#endif\n";
|
|
6
|
+
/* babel-plugin-inline-import './Chunk/elevation_vertex.glsl' */
|
|
7
|
+
const elevation_vertex = "#if NUM_VS_TEXTURES > 0\n if(elevationTextureCount > 0) {\n float elevation = getElevation(uv, elevationTextures[0], elevationOffsetScales[0], elevationLayers[0]);\n transformed += elevation * normal;\n }\n#endif\n";
|
|
8
|
+
/* babel-plugin-inline-import './Chunk/geoid_vertex.glsl' */
|
|
9
|
+
const geoid_vertex = "transformed += geoidHeight * normal;\n";
|
|
10
|
+
/* babel-plugin-inline-import './Chunk/fog_fragment.glsl' */
|
|
11
|
+
const fog_fragment = "#if defined(USE_FOG)\n float fogFactor = 1. - min( exp(-vFogDepth / fogDistance), 1.);\n gl_FragColor.rgb = mix(gl_FragColor.rgb, fogColor, fogFactor);\n#endif\n";
|
|
12
|
+
/* babel-plugin-inline-import './Chunk/fog_pars_fragment.glsl' */
|
|
13
|
+
const fog_pars_fragment = "#if defined(USE_FOG)\nuniform vec3 fogColor;\nuniform float fogDistance;\nvarying float vFogDepth;\n#endif\n";
|
|
14
|
+
/* babel-plugin-inline-import './Chunk/lighting_fragment.glsl' */
|
|
15
|
+
const lighting_fragment = "if (lightingEnabled) {\n float light = min(2. * dot(vNormal, lightPosition), 1.);\n gl_FragColor.rgb *= light;\n}\n";
|
|
16
|
+
/* babel-plugin-inline-import './Chunk/lighting_pars_fragment.glsl' */
|
|
17
|
+
const lighting_pars_fragment = "uniform bool lightingEnabled;\nuniform vec3 lightPosition;\nvarying vec3 vNormal;\n";
|
|
18
|
+
/* babel-plugin-inline-import './Chunk/mode_pars_fragment.glsl' */
|
|
19
|
+
const mode_pars_fragment = "#if MODE == MODE_ID || MODE == MODE_DEPTH\n#include <packing>\n#endif\n\n#if MODE == MODE_ID\nuniform int objectId;\n#endif\n";
|
|
20
|
+
/* babel-plugin-inline-import './Chunk/mode_depth_fragment.glsl' */
|
|
21
|
+
const mode_depth_fragment = "#if defined(USE_LOGDEPTHBUF)\ngl_FragColor = packDepthToRGBA(gl_FragDepthEXT);\n#else\nfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\ngl_FragColor = packDepthToRGBA(fragCoordZ);\n#endif\n";
|
|
22
|
+
/* babel-plugin-inline-import './Chunk/mode_id_fragment.glsl' */
|
|
23
|
+
const mode_id_fragment = "// 16777216.0 == 256.0 * 256.0 * 256.0\ngl_FragColor = packDepthToRGBA(float(objectId) / 16777216.0);\n";
|
|
24
|
+
/* babel-plugin-inline-import './Chunk/overlay_fragment.glsl' */
|
|
25
|
+
const overlay_fragment = "gl_FragColor.rgb = mix(gl_FragColor.rgb, overlayColor, overlayAlpha);\n";
|
|
26
|
+
/* babel-plugin-inline-import './Chunk/overlay_pars_fragment.glsl' */
|
|
27
|
+
const overlay_pars_fragment = "uniform vec3 overlayColor;\nuniform float overlayAlpha;\n";
|
|
28
|
+
/* babel-plugin-inline-import './Chunk/pitUV.glsl' */
|
|
29
|
+
const pitUV = "vec2 pitUV(vec2 uv, vec4 pit)\n{\n return uv * pit.zw + vec2(pit.x, 1.0 - pit.w - pit.y);\n}\n\n";
|
|
30
|
+
/* babel-plugin-inline-import './Chunk/precision_qualifier.glsl' */
|
|
31
|
+
const precision_qualifier = "precision highp float;\nprecision highp int;\n";
|
|
32
|
+
/* babel-plugin-inline-import './Chunk/projective_texturing_vertex.glsl' */
|
|
33
|
+
const projective_texturing_vertex = "for(int i = 0; i < ORIENTED_IMAGES_COUNT; ++i)\n projectiveTextureCoords[i] = projectiveTextureMatrix[i] * mvPosition;\n";
|
|
34
|
+
/* babel-plugin-inline-import './Chunk/projective_texturing_pars_vertex.glsl' */
|
|
35
|
+
const projective_texturing_pars_vertex = "uniform mat4 projectiveTextureMatrix[ORIENTED_IMAGES_COUNT];\nvarying vec4 projectiveTextureCoords[ORIENTED_IMAGES_COUNT];\n";
|
|
36
|
+
/* babel-plugin-inline-import './Chunk/projective_texturing_pars_fragment.glsl' */
|
|
37
|
+
const projective_texturing_pars_fragment = "uniform sampler2D projectiveTexture[ORIENTED_IMAGES_COUNT];\nuniform sampler2D mask[ORIENTED_IMAGES_COUNT];\nvarying vec4 projectiveTextureCoords[ORIENTED_IMAGES_COUNT];\nuniform float projectiveTextureAlphaBorder;\nuniform float opacity;\nuniform bool boostLight;\n\nstruct Distortion {\n vec2 size;\n#if USE_DISTORTION\n vec2 pps;\n vec4 polynom;\n vec3 l1l2;\n#endif\n};\n\nuniform Distortion projectiveTextureDistortion[ORIENTED_IMAGES_COUNT];\n\nfloat getAlphaBorder(vec2 p)\n{\n vec2 d = clamp(projectiveTextureAlphaBorder * min(p, 1. - p), 0., 1.);\n return min(d.x, d.y);\n}\n\n#if USE_DISTORTION\nvoid distort(inout vec2 p, vec4 polynom, vec2 pps)\n{\n vec2 v = p - pps;\n float v2 = dot(v, v);\n if (v2 > polynom.w) {\n p = vec2(-1.);\n }\n else {\n p += (v2 * (polynom.x + v2 * (polynom.y + v2 * polynom.z) ) ) * v;\n }\n}\n\nvoid distort(inout vec2 p, vec4 polynom, vec3 l1l2, vec2 pps)\n{\n if ((l1l2.x == 0.) && (l1l2.y == 0.)) {\n distort(p, polynom, pps);\n } else {\n vec2 AB = (p - pps) / l1l2.z;\n float R = length(AB);\n float lambda = atan(R) / R;\n vec2 ab = lambda * AB;\n float rho2 = dot(ab, ab);\n float r357 = 1. + rho2* (polynom.x + rho2* (polynom.y + rho2 * polynom.z));\n p = pps + l1l2.z * (r357 * ab + vec2(dot(l1l2.xy, ab), l1l2.y * ab.x));\n }\n}\n#endif\n\nvec4 mixBaseColor(vec4 aColor, vec4 baseColor) {\n #ifdef USE_BASE_MATERIAL\n baseColor.rgb = aColor.a == 1.0 ? aColor.rgb : mix(baseColor, aColor, aColor.a).rgb;\n baseColor.a = min(1.0, aColor.a + baseColor.a);\n #else\n baseColor.rgb += aColor.rgb * aColor.a;\n baseColor.a += aColor.a;\n #endif\n return baseColor;\n}\n\nvec4 projectiveTextureColor(vec4 coords, Distortion distortion, sampler2D tex, sampler2D mask, vec4 baseColor) {\n vec3 p = coords.xyz / coords.w;\n if(p.z * p.z < 1.) {\n#if USE_DISTORTION\n p.xy *= distortion.size;\n distort(p.xy, distortion.polynom, distortion.l1l2, distortion.pps);\n p.xy /= distortion.size;\n#endif\n\n float d = getAlphaBorder(p.xy) * texture2D(mask, p.xy).r;\n\n if(d > 0.) {\n\n#if DEBUG_ALPHA_BORDER\n vec3 r = texture2D(tex, p.xy).rgb;\n return mixBaseColor(vec4( r.r * d, r.g, r.b, 1.0), baseColor);\n#else\n vec4 color = texture2D(tex, p.xy);\n color.a *= d;\n if (boostLight) {\n return mixBaseColor(vec4(sqrt(color.rgb), color.a), baseColor);\n } else {\n return mixBaseColor(color, baseColor);\n }\n#endif\n\n }\n }\n return mixBaseColor(vec4(0.), baseColor);\n}\n";
|
|
38
|
+
const custom_header_colorLayer = '// no custom header';
|
|
39
|
+
const custom_body_colorLayer = '// no custom body';
|
|
40
|
+
const itownsShaderChunk = {
|
|
41
|
+
color_layers_pars_fragment,
|
|
42
|
+
custom_body_colorLayer,
|
|
43
|
+
custom_header_colorLayer,
|
|
44
|
+
elevation_pars_vertex,
|
|
45
|
+
elevation_vertex,
|
|
46
|
+
geoid_vertex,
|
|
47
|
+
fog_fragment,
|
|
48
|
+
fog_pars_fragment,
|
|
49
|
+
lighting_fragment,
|
|
50
|
+
lighting_pars_fragment,
|
|
51
|
+
mode_depth_fragment,
|
|
52
|
+
mode_id_fragment,
|
|
53
|
+
mode_pars_fragment,
|
|
54
|
+
overlay_fragment,
|
|
55
|
+
overlay_pars_fragment,
|
|
56
|
+
pitUV,
|
|
57
|
+
precision_qualifier,
|
|
58
|
+
projective_texturing_vertex,
|
|
59
|
+
projective_texturing_pars_vertex,
|
|
60
|
+
projective_texturing_pars_fragment
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The ShaderChunkManager manages the itowns chunks shader.
|
|
65
|
+
* It adds chunks to THREE.ShaderChunk to compile shaders
|
|
66
|
+
*
|
|
67
|
+
* In itowns, if you want access to `ShaderChunkManager` instance :
|
|
68
|
+
*
|
|
69
|
+
* ```js
|
|
70
|
+
* import ShaderChunk from 'Renderer/Shader/ShaderChunk';
|
|
71
|
+
* ```
|
|
72
|
+
* or
|
|
73
|
+
* ```js
|
|
74
|
+
* const ShaderChunk = itowns.ShaderChunk';
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @property {Object} target - The target to install the chunks into.
|
|
78
|
+
* @property {string} [path] - A path to add before a chunk name as a prefix.
|
|
79
|
+
*
|
|
80
|
+
*/
|
|
81
|
+
class ShaderChunkManager {
|
|
82
|
+
/**
|
|
83
|
+
* Constructs a new instance ShaderChunkManager.
|
|
84
|
+
*
|
|
85
|
+
* @constructor
|
|
86
|
+
*
|
|
87
|
+
* @param {Object} target - The target to install the chunks into.
|
|
88
|
+
* @param {string} [path] - A path to add before a chunk name as a prefix.
|
|
89
|
+
*
|
|
90
|
+
*/
|
|
91
|
+
constructor(target, path) {
|
|
92
|
+
this.path = path;
|
|
93
|
+
this.target = target;
|
|
94
|
+
this.install();
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Set the header ColorLayer shader.
|
|
98
|
+
*
|
|
99
|
+
* @param {string} header The glsl header
|
|
100
|
+
*/
|
|
101
|
+
customHeaderColorLayer(header) {
|
|
102
|
+
itownsShaderChunk.custom_header_colorLayer = header;
|
|
103
|
+
this.target[`${this.path}custom_header_colorLayer`] = header;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Set the body ColorLayer shader.
|
|
108
|
+
* You could define you color terrain shader, with a header and a body.
|
|
109
|
+
* the header defines yours fonctions and the body defines the process on ColorLayer.
|
|
110
|
+
* @example <caption>Custom shader chunk</caption>
|
|
111
|
+
* itowns.ShaderChunk.customHeaderColorLayer(`
|
|
112
|
+
* // define yours methods
|
|
113
|
+
* vec4 myColor(vec4 color, float a) {
|
|
114
|
+
* return color * a;
|
|
115
|
+
* }
|
|
116
|
+
* `);
|
|
117
|
+
* itowns.ShaderChunk.customBodyColorLayer(`
|
|
118
|
+
* // the body set final color layer.
|
|
119
|
+
* // layer.amount_effect is variable, it could be change in Layer instance.
|
|
120
|
+
* color = myColor(color, layer.amount_effect)
|
|
121
|
+
* `);
|
|
122
|
+
*
|
|
123
|
+
* var colorLayer = new itowns.ColorLayer('OPENSM', {
|
|
124
|
+
* source,
|
|
125
|
+
* type_effect: itowns.colorLayerEffects.customEffect,
|
|
126
|
+
* amount_effect: 0.5,
|
|
127
|
+
* });
|
|
128
|
+
*
|
|
129
|
+
* @param {string} body The glsl body
|
|
130
|
+
*/
|
|
131
|
+
customBodyColorLayer(body) {
|
|
132
|
+
itownsShaderChunk.custom_body_colorLayer = body;
|
|
133
|
+
this.target[`${this.path}custom_body_colorLayer`] = body;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Install chunks in a target, for example THREE.ShaderChunk, with adding an
|
|
137
|
+
* optional path.
|
|
138
|
+
*
|
|
139
|
+
* @param {Object} target - The target to install the chunks into.
|
|
140
|
+
* @param {Object} chunks - The chunks to install. The key of each chunk will be
|
|
141
|
+
* the name of installation of the chunk in the target (plus an optional path).
|
|
142
|
+
* @param {string} [path] - A path to add before a chunk name as a prefix.
|
|
143
|
+
*
|
|
144
|
+
* @return {Object} The target with installed chunks.
|
|
145
|
+
*/
|
|
146
|
+
install() {
|
|
147
|
+
let target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.target;
|
|
148
|
+
let chunks = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : itownsShaderChunk;
|
|
149
|
+
let path = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.path;
|
|
150
|
+
Object.keys(chunks).forEach(key => {
|
|
151
|
+
Object.defineProperty(this, key, {
|
|
152
|
+
get: () => chunks[key]
|
|
153
|
+
});
|
|
154
|
+
target[path + key] = chunks[key];
|
|
155
|
+
});
|
|
156
|
+
return target;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const ShaderChunk = new ShaderChunkManager(THREE.ShaderChunk, 'itowns/');
|
|
160
|
+
export default ShaderChunk;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const pattern_gl_Position = 'gl_Position.*(?![^]*gl_Position)';
|
|
2
|
+
const pattern_Main = '[^\\w]*main[^\\w]*(void)?[^\\w]*{';
|
|
3
|
+
const rePosition = new RegExp(pattern_gl_Position);
|
|
4
|
+
const reMain = new RegExp(pattern_Main);
|
|
5
|
+
export default {
|
|
6
|
+
patchMaterialForLogDepthSupport(material) {
|
|
7
|
+
// Check if the shader does not already use the log depth buffer
|
|
8
|
+
if (material.vertexShader.includes('USE_LOGDEPTHBUF') || material.vertexShader.includes('logdepthbuf_pars_vertex')) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Add vertex shader log depth buffer header
|
|
13
|
+
material.vertexShader = `#include <logdepthbuf_pars_vertex>\n#define EPSILON 1e-6\n${material.vertexShader}`;
|
|
14
|
+
// Add log depth buffer code snippet after last gl_Position modification
|
|
15
|
+
let re = rePosition.exec(material.vertexShader);
|
|
16
|
+
let idx = re[0].length + re.index;
|
|
17
|
+
material.vertexShader = `${material.vertexShader.slice(0, idx)}\n#include <logdepthbuf_vertex>\n${material.vertexShader.slice(idx)}`;
|
|
18
|
+
|
|
19
|
+
// Add fragment shader log depth buffer header
|
|
20
|
+
material.fragmentShader = `#include <itowns/precision_qualifier\n${material.fragmentShader}`;
|
|
21
|
+
material.fragmentShader = `#include <logdepthbuf_pars_fragment>\n${material.fragmentShader}`;
|
|
22
|
+
// Add log depth buffer code snippet at the first line of the main function
|
|
23
|
+
re = reMain.exec(material.fragmentShader);
|
|
24
|
+
idx = re[0].length + re.index;
|
|
25
|
+
material.fragmentShader = `${material.fragmentShader.slice(0, idx)}\n#include <logdepthbuf_fragment>\n${material.fragmentShader.slice(idx)}`;
|
|
26
|
+
material.defines = {
|
|
27
|
+
USE_LOGDEPTHBUF: 1,
|
|
28
|
+
USE_LOGDEPTHBUF_EXT: 1
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
// adapted from unrollLoops in WebGLProgram
|
|
32
|
+
unrollLoops(string, defines) {
|
|
33
|
+
// look for a for loop with an unroll_loop pragma
|
|
34
|
+
// The detection of the scope of the for loop is hacky as it does not support nested scopes
|
|
35
|
+
|
|
36
|
+
function replace(match, start, end, snippet) {
|
|
37
|
+
let unroll = '';
|
|
38
|
+
start = start in defines ? defines[start] : parseInt(start, 10);
|
|
39
|
+
end = end in defines ? defines[end] : parseInt(end, 10);
|
|
40
|
+
for (let i = start; i < end; i++) {
|
|
41
|
+
unroll += snippet.replace(/\bi\b/g, ` ${i} `);
|
|
42
|
+
}
|
|
43
|
+
return unroll;
|
|
44
|
+
}
|
|
45
|
+
return string.replace(/#pragma unroll_loop\s+for\s*\(\s*int\s+i\s*=\s*([\w\d]+);\s*i\s+<\s+([\w\d]+);\s*i\s*\+\+\s*\)\s*\{\n([^}]*)\}/g, replace);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
function SphereHelper(radius) {
|
|
3
|
+
THREE.Mesh.call(this);
|
|
4
|
+
this.geometry = new THREE.SphereGeometry(radius, 8, 8);
|
|
5
|
+
const color = new THREE.Color(Math.random(), Math.random(), Math.random());
|
|
6
|
+
this.material = new THREE.MeshBasicMaterial({
|
|
7
|
+
color: color.getHex(),
|
|
8
|
+
wireframe: true
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
SphereHelper.prototype = Object.create(THREE.Mesh.prototype);
|
|
12
|
+
SphereHelper.prototype.constructor = SphereHelper;
|
|
13
|
+
SphereHelper.prototype.update = function (radius) {
|
|
14
|
+
this.geometry.dispose();
|
|
15
|
+
this.geometry = new THREE.SphereGeometry(radius, 8, 8);
|
|
16
|
+
};
|
|
17
|
+
export default SphereHelper;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
async function shutdownXR(session) {
|
|
3
|
+
if (session) {
|
|
4
|
+
await session.end();
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
const initializeWebXR = (view, options) => {
|
|
8
|
+
const scale = options.scale || 1.0;
|
|
9
|
+
const xr = view.mainLoop.gfxEngine.renderer.xr;
|
|
10
|
+
xr.addEventListener('sessionstart', () => {
|
|
11
|
+
const camera = view.camera.camera3D;
|
|
12
|
+
const exitXRSession = event => {
|
|
13
|
+
if (event.key === 'Escape') {
|
|
14
|
+
document.removeEventListener('keydown', exitXRSession);
|
|
15
|
+
xr.enabled = false;
|
|
16
|
+
view.camera.camera3D = camera;
|
|
17
|
+
view.scene.scale.multiplyScalar(1 / scale);
|
|
18
|
+
view.scene.updateMatrixWorld();
|
|
19
|
+
shutdownXR(xr.getSession());
|
|
20
|
+
view.notifyChange(view.camera.camera3D, true);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
view.scene.scale.multiplyScalar(scale);
|
|
24
|
+
view.scene.updateMatrixWorld();
|
|
25
|
+
xr.enabled = true;
|
|
26
|
+
xr.getReferenceSpace('local');
|
|
27
|
+
const position = view.camera.position();
|
|
28
|
+
const geodesicNormal = new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0, 0, 1), position.geodesicNormal).invert();
|
|
29
|
+
const quat = new THREE.Quaternion(-1, 0, 0, 1).normalize().multiply(geodesicNormal);
|
|
30
|
+
const trans = camera.position.clone().multiplyScalar(-scale).applyQuaternion(quat);
|
|
31
|
+
const transform = new XRRigidTransform(trans, quat);
|
|
32
|
+
const baseReferenceSpace = xr.getReferenceSpace();
|
|
33
|
+
const teleportSpaceOffset = baseReferenceSpace.getOffsetReferenceSpace(transform);
|
|
34
|
+
xr.setReferenceSpace(teleportSpaceOffset);
|
|
35
|
+
view.camera.camera3D = xr.getCamera();
|
|
36
|
+
view.camera.resize(view.camera.width, view.camera.height);
|
|
37
|
+
document.addEventListener('keydown', exitXRSession, false);
|
|
38
|
+
|
|
39
|
+
// TODO Fix asynchronization between xr and MainLoop render loops.
|
|
40
|
+
// (see MainLoop#scheduleViewUpdate).
|
|
41
|
+
xr.setAnimationLoop(timestamp => {
|
|
42
|
+
if (xr.isPresenting && view.camera.camera3D.cameras[0]) {
|
|
43
|
+
view.camera.camera3D.updateMatrix();
|
|
44
|
+
view.camera.camera3D.updateMatrixWorld(true);
|
|
45
|
+
view.notifyChange(view.camera.camera3D, true);
|
|
46
|
+
}
|
|
47
|
+
view.mainLoop.step(view, timestamp);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
export default initializeWebXR;
|