easy-three-utils 0.0.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/package.json +12 -0
- package/src/common/index.ts +24 -0
- package/src/common/useLine2.ts +87 -0
- package/src/common/useLoader.ts +184 -0
- package/src/common/useLocationCalculator.ts +145 -0
- package/src/common/useMark.ts +42 -0
- package/src/common/useTween.ts +86 -0
- package/src/core/basic/camera.ts +28 -0
- package/src/core/basic/clock.ts +11 -0
- package/src/core/basic/control.ts +32 -0
- package/src/core/basic/index.ts +35 -0
- package/src/core/basic/labelRenderer.ts +26 -0
- package/src/core/basic/light.ts +63 -0
- package/src/core/basic/renderer.ts +37 -0
- package/src/core/basic/scene.ts +11 -0
- package/src/core/basic/stats.ts +16 -0
- package/src/core/event.ts +74 -0
- package/src/core/index.ts +11 -0
- package/src/core/main.ts +389 -0
- package/src/draco/README.md +32 -0
- package/src/draco/draco_decoder.js +34 -0
- package/src/draco/draco_decoder.wasm +0 -0
- package/src/draco/draco_encoder.js +33 -0
- package/src/draco/draco_wasm_wrapper.js +117 -0
- package/src/draco/gltf/draco_decoder.js +33 -0
- package/src/draco/gltf/draco_decoder.wasm +0 -0
- package/src/draco/gltf/draco_encoder.js +33 -0
- package/src/draco/gltf/draco_wasm_wrapper.js +116 -0
- package/src/tileRenderer/base/Tile.d.ts +50 -0
- package/src/tileRenderer/base/TileBase.d.ts +76 -0
- package/src/tileRenderer/base/TileInternal.d.ts +36 -0
- package/src/tileRenderer/base/TilesRendererBase.d.ts +35 -0
- package/src/tileRenderer/base/TilesRendererBase.js +847 -0
- package/src/tileRenderer/base/Tileset.d.ts +66 -0
- package/src/tileRenderer/base/constants.d.ts +6 -0
- package/src/tileRenderer/base/constants.js +16 -0
- package/src/tileRenderer/base/loaders/B3DMLoaderBase.d.ts +18 -0
- package/src/tileRenderer/base/loaders/B3DMLoaderBase.js +85 -0
- package/src/tileRenderer/base/loaders/CMPTLoaderBase.d.ts +22 -0
- package/src/tileRenderer/base/loaders/CMPTLoaderBase.js +61 -0
- package/src/tileRenderer/base/loaders/I3DMLoaderBase.d.ts +21 -0
- package/src/tileRenderer/base/loaders/I3DMLoaderBase.js +130 -0
- package/src/tileRenderer/base/loaders/LoaderBase.d.ts +10 -0
- package/src/tileRenderer/base/loaders/LoaderBase.js +73 -0
- package/src/tileRenderer/base/loaders/PNTSLoaderBase.d.ts +17 -0
- package/src/tileRenderer/base/loaders/PNTSLoaderBase.js +82 -0
- package/src/tileRenderer/base/plugins/ImplicitTilingPlugin.js +12 -0
- package/src/tileRenderer/base/traverseFunctions.js +468 -0
- package/src/tileRenderer/gltf.js +144 -0
- package/src/tileRenderer/index.d.ts +41 -0
- package/src/tileRenderer/index.js +44 -0
- package/src/tileRenderer/plugins/README.md +578 -0
- package/src/tileRenderer/plugins/base/ImplicitTilingPlugin.d.ts +2 -0
- package/src/tileRenderer/plugins/base/ImplicitTilingPlugin.js +84 -0
- package/src/tileRenderer/plugins/base/SUBTREELoader.js +876 -0
- package/src/tileRenderer/plugins/index.d.ts +17 -0
- package/src/tileRenderer/plugins/index.js +17 -0
- package/src/tileRenderer/plugins/three/CesiumIonAuthPlugin.d.ts +9 -0
- package/src/tileRenderer/plugins/three/CesiumIonAuthPlugin.js +175 -0
- package/src/tileRenderer/plugins/three/DebugTilesPlugin.d.ts +29 -0
- package/src/tileRenderer/plugins/three/DebugTilesPlugin.js +677 -0
- package/src/tileRenderer/plugins/three/GLTFExtensionsPlugin.d.ts +18 -0
- package/src/tileRenderer/plugins/three/GLTFExtensionsPlugin.js +86 -0
- package/src/tileRenderer/plugins/three/GoogleAttributionsManager.js +62 -0
- package/src/tileRenderer/plugins/three/GoogleCloudAuthPlugin.d.ts +5 -0
- package/src/tileRenderer/plugins/three/GoogleCloudAuthPlugin.js +200 -0
- package/src/tileRenderer/plugins/three/ReorientationPlugin.d.ts +12 -0
- package/src/tileRenderer/plugins/three/ReorientationPlugin.js +136 -0
- package/src/tileRenderer/plugins/three/TileCompressionPlugin.d.ts +18 -0
- package/src/tileRenderer/plugins/three/TileCompressionPlugin.js +223 -0
- package/src/tileRenderer/plugins/three/UpdateOnChangePlugin.d.ts +5 -0
- package/src/tileRenderer/plugins/three/UpdateOnChangePlugin.js +87 -0
- package/src/tileRenderer/plugins/three/fade/FadeManager.js +370 -0
- package/src/tileRenderer/plugins/three/fade/TilesFadePlugin.d.ts +9 -0
- package/src/tileRenderer/plugins/three/fade/TilesFadePlugin.js +318 -0
- package/src/tileRenderer/plugins/three/gltf/GLTFCesiumRTCExtension.d.ts +5 -0
- package/src/tileRenderer/plugins/three/gltf/GLTFCesiumRTCExtension.js +27 -0
- package/src/tileRenderer/plugins/three/gltf/GLTFMeshFeaturesExtension.d.ts +30 -0
- package/src/tileRenderer/plugins/three/gltf/GLTFMeshFeaturesExtension.js +76 -0
- package/src/tileRenderer/plugins/three/gltf/GLTFStructuralMetadataExtension.d.ts +49 -0
- package/src/tileRenderer/plugins/three/gltf/GLTFStructuralMetadataExtension.js +147 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/classes/ClassProperty.js +149 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/classes/MeshFeatures.js +215 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertyAttributeAccessor.js +107 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertySetAccessor.js +45 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertyTableAccessor.js +209 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertyTextureAccessor.js +244 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/classes/StructuralMetadata.js +202 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/math/Matrix2.js +55 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/utilities/ClassPropertyHelpers.js +495 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/utilities/TexCoordUtilities.js +72 -0
- package/src/tileRenderer/plugins/three/gltf/metadata/utilities/TextureReadUtility.js +154 -0
- package/src/tileRenderer/plugins/three/objects/EllipsoidRegionHelper.js +186 -0
- package/src/tileRenderer/plugins/three/objects/SphereHelper.js +55 -0
- package/src/tileRenderer/r3f/README.md +238 -0
- package/src/tileRenderer/r3f/components/CameraControls.jsx +132 -0
- package/src/tileRenderer/r3f/components/CameraTransition.jsx +177 -0
- package/src/tileRenderer/r3f/components/CanvasDOMOverlay.jsx +54 -0
- package/src/tileRenderer/r3f/components/CompassGizmo.jsx +260 -0
- package/src/tileRenderer/r3f/components/TilesAttributionOverlay.jsx +110 -0
- package/src/tileRenderer/r3f/components/TilesRenderer.jsx +239 -0
- package/src/tileRenderer/r3f/index.jsx +6 -0
- package/src/tileRenderer/r3f/utilities/useForceUpdate.jsx +8 -0
- package/src/tileRenderer/r3f/utilities/useObjectDep.jsx +59 -0
- package/src/tileRenderer/r3f/utilities/useOptions.jsx +143 -0
- package/src/tileRenderer/three/DebugTilesRenderer.d.ts +28 -0
- package/src/tileRenderer/three/DebugTilesRenderer.js +58 -0
- package/src/tileRenderer/three/TilesGroup.d.ts +9 -0
- package/src/tileRenderer/three/TilesGroup.js +91 -0
- package/src/tileRenderer/three/TilesRenderer.d.ts +37 -0
- package/src/tileRenderer/three/TilesRenderer.js +1049 -0
- package/src/tileRenderer/three/controls/CameraTransitionManager.js +305 -0
- package/src/tileRenderer/three/controls/EnvironmentControls.js +1295 -0
- package/src/tileRenderer/three/controls/GlobeControls.js +684 -0
- package/src/tileRenderer/three/controls/PivotPointMesh.js +104 -0
- package/src/tileRenderer/three/controls/PointerTracker.js +257 -0
- package/src/tileRenderer/three/controls/utils.js +113 -0
- package/src/tileRenderer/three/loaders/B3DMLoader.d.ts +26 -0
- package/src/tileRenderer/three/loaders/B3DMLoader.js +85 -0
- package/src/tileRenderer/three/loaders/CMPTLoader.d.ts +19 -0
- package/src/tileRenderer/three/loaders/CMPTLoader.js +97 -0
- package/src/tileRenderer/three/loaders/GLTFExtensionLoader.d.ts +11 -0
- package/src/tileRenderer/three/loaders/GLTFExtensionLoader.js +68 -0
- package/src/tileRenderer/three/loaders/I3DMLoader.d.ts +26 -0
- package/src/tileRenderer/three/loaders/I3DMLoader.js +256 -0
- package/src/tileRenderer/three/loaders/PNTSLoader.d.ts +25 -0
- package/src/tileRenderer/three/loaders/PNTSLoader.js +202 -0
- package/src/tileRenderer/three/loaders/gltf/GLTFCesiumRTCExtension.js +12 -0
- package/src/tileRenderer/three/loaders/gltf/GLTFMeshFeaturesExtension.js +12 -0
- package/src/tileRenderer/three/loaders/gltf/GLTFStructuralMetadataExtension.js +12 -0
- package/src/tileRenderer/three/math/Ellipsoid.d.ts +31 -0
- package/src/tileRenderer/three/math/Ellipsoid.js +337 -0
- package/src/tileRenderer/three/math/EllipsoidRegion.d.ts +23 -0
- package/src/tileRenderer/three/math/EllipsoidRegion.js +178 -0
- package/src/tileRenderer/three/math/ExtendedFrustum.js +65 -0
- package/src/tileRenderer/three/math/GeoConstants.d.ts +4 -0
- package/src/tileRenderer/three/math/GeoConstants.js +5 -0
- package/src/tileRenderer/three/math/GeoUtils.d.ts +9 -0
- package/src/tileRenderer/three/math/GeoUtils.js +106 -0
- package/src/tileRenderer/three/math/OBB.js +179 -0
- package/src/tileRenderer/three/math/TileBoundingVolume.js +272 -0
- package/src/tileRenderer/three/plugins/CesiumIonAuthPlugin.js +12 -0
- package/src/tileRenderer/three/plugins/DebugTilesPlugin.js +26 -0
- package/src/tileRenderer/three/plugins/GoogleCloudAuthPlugin.js +12 -0
- package/src/tileRenderer/three/raycastTraverse.js +178 -0
- package/src/tileRenderer/three/renderers/CesiumIonTilesRenderer.d.ts +14 -0
- package/src/tileRenderer/three/renderers/CesiumIonTilesRenderer.js +21 -0
- package/src/tileRenderer/three/renderers/GoogleTilesRenderer.d.ts +43 -0
- package/src/tileRenderer/three/renderers/GoogleTilesRenderer.js +48 -0
- package/src/tileRenderer/three/utilities.js +54 -0
- package/src/tileRenderer/utilities/BatchTable.d.ts +24 -0
- package/src/tileRenderer/utilities/BatchTable.js +82 -0
- package/src/tileRenderer/utilities/BatchTableHierarchyExtension.js +127 -0
- package/src/tileRenderer/utilities/FeatureTable.d.ts +30 -0
- package/src/tileRenderer/utilities/FeatureTable.js +159 -0
- package/src/tileRenderer/utilities/LRUCache.d.ts +8 -0
- package/src/tileRenderer/utilities/LRUCache.js +385 -0
- package/src/tileRenderer/utilities/PriorityQueue.d.ts +16 -0
- package/src/tileRenderer/utilities/PriorityQueue.js +137 -0
- package/src/tileRenderer/utilities/arrayToString.js +7 -0
- package/src/tileRenderer/utilities/readMagicBytes.js +29 -0
- package/src/tileRenderer/utilities/rgb565torgb.js +22 -0
- package/src/tileRenderer/utilities/urlExtension.js +34 -0
- package/tsconfig.json +42 -0
- package/tsconfig.node.json +11 -0
- package/typings/three.d.ts +27 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { Vector3, LinearFilter, BufferAttribute, MathUtils } from 'three';
|
|
2
|
+
|
|
3
|
+
const _vec = new Vector3();
|
|
4
|
+
function compressAttribute( attribute, arrayType ) {
|
|
5
|
+
|
|
6
|
+
if ( attribute.isInterleavedBufferAttribute || attribute.array instanceof arrayType ) {
|
|
7
|
+
|
|
8
|
+
return attribute;
|
|
9
|
+
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const signed = arrayType === Int8Array || arrayType === Int16Array || arrayType === Int32Array;
|
|
13
|
+
const minValue = signed ? - 1 : 0;
|
|
14
|
+
|
|
15
|
+
const array = new arrayType( attribute.count * attribute.itemSize );
|
|
16
|
+
const newAttribute = new BufferAttribute( array, attribute.itemSize, true );
|
|
17
|
+
const itemSize = attribute.itemSize;
|
|
18
|
+
const count = attribute.count;
|
|
19
|
+
for ( let i = 0; i < count; i ++ ) {
|
|
20
|
+
|
|
21
|
+
for ( let j = 0; j < itemSize; j ++ ) {
|
|
22
|
+
|
|
23
|
+
const v = MathUtils.clamp( attribute.getComponent( i, j ), minValue, 1 );
|
|
24
|
+
newAttribute.setComponent( i, j, v );
|
|
25
|
+
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return newAttribute;
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function compressPositionAttribute( mesh, arrayType = Int16Array ) {
|
|
35
|
+
|
|
36
|
+
const geometry = mesh.geometry;
|
|
37
|
+
const attributes = geometry.attributes;
|
|
38
|
+
const attribute = attributes.position;
|
|
39
|
+
|
|
40
|
+
// skip if it's already compressed to the provided level
|
|
41
|
+
if ( attribute.isInterleavedBufferAttribute || attribute.array instanceof arrayType ) {
|
|
42
|
+
|
|
43
|
+
return attribute;
|
|
44
|
+
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// new attribute data
|
|
48
|
+
const array = new arrayType( attribute.count * attribute.itemSize );
|
|
49
|
+
const newAttribute = new BufferAttribute( array, attribute.itemSize, false );
|
|
50
|
+
const itemSize = attribute.itemSize;
|
|
51
|
+
const count = attribute.count;
|
|
52
|
+
|
|
53
|
+
// bounding box stride
|
|
54
|
+
// TODO: the bounding box is computed every time even if it already exists because
|
|
55
|
+
// it's possible that the encoded value is incorrect causing artifacts
|
|
56
|
+
geometry.computeBoundingBox();
|
|
57
|
+
|
|
58
|
+
const boundingBox = geometry.boundingBox;
|
|
59
|
+
const { min, max } = boundingBox;
|
|
60
|
+
|
|
61
|
+
// array range
|
|
62
|
+
const maxValue = 2 ** ( 8 * arrayType.BYTES_PER_ELEMENT - 1 ) - 1;
|
|
63
|
+
const minValue = - maxValue;
|
|
64
|
+
|
|
65
|
+
for ( let i = 0; i < count; i ++ ) {
|
|
66
|
+
|
|
67
|
+
for ( let j = 0; j < itemSize; j ++ ) {
|
|
68
|
+
|
|
69
|
+
const key = j === 0 ? 'x' : j === 1 ? 'y' : 'z';
|
|
70
|
+
const bbMinValue = min[ key ];
|
|
71
|
+
const bbMaxValue = max[ key ];
|
|
72
|
+
|
|
73
|
+
// scale the geometry values to the integer range
|
|
74
|
+
const v = MathUtils.mapLinear(
|
|
75
|
+
attribute.getComponent( i, j ),
|
|
76
|
+
bbMinValue, bbMaxValue,
|
|
77
|
+
minValue, maxValue,
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
newAttribute.setComponent( i, j, v );
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// shift the mesh to the center of the bounds
|
|
87
|
+
boundingBox.getCenter( _vec );
|
|
88
|
+
mesh.position.add( _vec );
|
|
89
|
+
|
|
90
|
+
// adjust the scale to accommodate the new geometry data range
|
|
91
|
+
mesh.scale.x *= 0.5 * ( max.x - min.x ) / maxValue;
|
|
92
|
+
mesh.scale.y *= 0.5 * ( max.y - min.y ) / maxValue;
|
|
93
|
+
mesh.scale.z *= 0.5 * ( max.z - min.z ) / maxValue;
|
|
94
|
+
|
|
95
|
+
attributes.position = newAttribute;
|
|
96
|
+
mesh.geometry.boundingBox = null;
|
|
97
|
+
mesh.geometry.boundingSphere = null;
|
|
98
|
+
|
|
99
|
+
mesh.updateMatrixWorld();
|
|
100
|
+
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export class TileCompressionPlugin {
|
|
104
|
+
|
|
105
|
+
constructor( options ) {
|
|
106
|
+
|
|
107
|
+
this._options = {
|
|
108
|
+
// whether to generate normals if they don't already exist.
|
|
109
|
+
generateNormals: false,
|
|
110
|
+
|
|
111
|
+
// whether to disable use of mipmaps since they are typically not necessary
|
|
112
|
+
// with something like 3d tiles.
|
|
113
|
+
disableMipmaps: true,
|
|
114
|
+
|
|
115
|
+
// whether to compress certain attributes
|
|
116
|
+
compressIndex: true,
|
|
117
|
+
compressNormals: true,
|
|
118
|
+
compressUvs: true,
|
|
119
|
+
compressPosition: false,
|
|
120
|
+
|
|
121
|
+
// the TypedArray type to use when compressing the attributes
|
|
122
|
+
uvType: Int8Array,
|
|
123
|
+
normalType: Int8Array,
|
|
124
|
+
positionType: Int16Array,
|
|
125
|
+
|
|
126
|
+
...options,
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
processTileModel( scene, tile ) {
|
|
132
|
+
|
|
133
|
+
const {
|
|
134
|
+
generateNormals,
|
|
135
|
+
|
|
136
|
+
disableMipmaps,
|
|
137
|
+
compressIndex,
|
|
138
|
+
compressUvs,
|
|
139
|
+
compressNormals,
|
|
140
|
+
compressPosition,
|
|
141
|
+
|
|
142
|
+
uvType,
|
|
143
|
+
normalType,
|
|
144
|
+
positionType,
|
|
145
|
+
} = this._options;
|
|
146
|
+
|
|
147
|
+
scene.traverse( c => {
|
|
148
|
+
|
|
149
|
+
// handle materials
|
|
150
|
+
if ( c.material && disableMipmaps ) {
|
|
151
|
+
|
|
152
|
+
const material = c.material;
|
|
153
|
+
for ( const key in material ) {
|
|
154
|
+
|
|
155
|
+
const value = material[ key ];
|
|
156
|
+
if ( value && value.isTexture && value.generateMipmaps ) {
|
|
157
|
+
|
|
158
|
+
value.generateMipmaps = false;
|
|
159
|
+
value.minFilter = LinearFilter;
|
|
160
|
+
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// handle geometry attribute compression
|
|
168
|
+
if ( c.geometry ) {
|
|
169
|
+
|
|
170
|
+
const geometry = c.geometry;
|
|
171
|
+
const attributes = geometry.attributes;
|
|
172
|
+
if ( compressUvs ) {
|
|
173
|
+
|
|
174
|
+
const { uv, uv1, uv2, uv3 } = attributes;
|
|
175
|
+
if ( uv ) attributes.uv = compressAttribute( uv, uvType );
|
|
176
|
+
if ( uv1 ) attributes.uv1 = compressAttribute( uv1, uvType );
|
|
177
|
+
if ( uv2 ) attributes.uv2 = compressAttribute( uv2, uvType );
|
|
178
|
+
if ( uv3 ) attributes.uv3 = compressAttribute( uv3, uvType );
|
|
179
|
+
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if ( generateNormals && ! attributes.normals ) {
|
|
183
|
+
|
|
184
|
+
geometry.computeVertexNormals();
|
|
185
|
+
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if ( compressNormals && attributes.normals ) {
|
|
189
|
+
|
|
190
|
+
attributes.normals = compressAttribute( attributes.normals, normalType );
|
|
191
|
+
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if ( compressPosition ) {
|
|
195
|
+
|
|
196
|
+
compressPositionAttribute( c, positionType );
|
|
197
|
+
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if ( compressIndex && geometry.index ) {
|
|
201
|
+
|
|
202
|
+
const vertCount = attributes.position.count;
|
|
203
|
+
const index = geometry.index;
|
|
204
|
+
const type = vertCount > 65535 ? Uint32Array : vertCount > 255 ? Uint16Array : Uint8Array;
|
|
205
|
+
if ( ! ( index.array instanceof type ) ) {
|
|
206
|
+
|
|
207
|
+
const array = new type( geometry.index.count );
|
|
208
|
+
array.set( index.array );
|
|
209
|
+
|
|
210
|
+
const attribute = new BufferAttribute( array, 1 );
|
|
211
|
+
geometry.setIndex( attribute );
|
|
212
|
+
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
} );
|
|
220
|
+
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Matrix4 } from 'three';
|
|
2
|
+
|
|
3
|
+
const _matrix = new Matrix4();
|
|
4
|
+
export class UpdateOnChangePlugin {
|
|
5
|
+
|
|
6
|
+
constructor() {
|
|
7
|
+
|
|
8
|
+
this.name = 'UPDATE_ON_CHANGE_PLUGIN';
|
|
9
|
+
this.tiles = null;
|
|
10
|
+
this.needsUpdate = false;
|
|
11
|
+
this.cameraMatrices = new Map();
|
|
12
|
+
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
init( tiles ) {
|
|
16
|
+
|
|
17
|
+
this.tiles = tiles;
|
|
18
|
+
|
|
19
|
+
// register callbacks to add cameras and force a new update
|
|
20
|
+
this._needsUpdateCallback = () => {
|
|
21
|
+
|
|
22
|
+
this.needsUpdate = true;
|
|
23
|
+
|
|
24
|
+
};
|
|
25
|
+
this._onCameraAdd = ( { camera } ) => {
|
|
26
|
+
|
|
27
|
+
this.needsUpdate = true;
|
|
28
|
+
this.cameraMatrices.set( camera, new Matrix4() );
|
|
29
|
+
|
|
30
|
+
};
|
|
31
|
+
this._onCameraDelete = ( { camera } ) => {
|
|
32
|
+
|
|
33
|
+
this.needsUpdate = true;
|
|
34
|
+
this.cameraMatrices.delete( camera );
|
|
35
|
+
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
tiles.addEventListener( 'camera-resolution-change', this._needsUpdateCallback );
|
|
39
|
+
tiles.addEventListener( 'load-content', this._needsUpdateCallback );
|
|
40
|
+
tiles.addEventListener( 'add-camera', this._onCameraAdd );
|
|
41
|
+
tiles.addEventListener( 'delete-camera', this._onCameraDelete );
|
|
42
|
+
|
|
43
|
+
// register any already-present cameras
|
|
44
|
+
tiles.cameras.forEach( camera => {
|
|
45
|
+
|
|
46
|
+
this._onCameraAdd( { camera } );
|
|
47
|
+
|
|
48
|
+
} );
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
doTilesNeedUpdate() {
|
|
53
|
+
|
|
54
|
+
const tiles = this.tiles;
|
|
55
|
+
let didCamerasChange = false;
|
|
56
|
+
this.cameraMatrices.forEach( ( matrix, camera ) => {
|
|
57
|
+
|
|
58
|
+
// check if the camera position or frustum changed by comparing the MVP
|
|
59
|
+
// matrix between frames
|
|
60
|
+
_matrix
|
|
61
|
+
.copy( tiles.group.matrixWorld )
|
|
62
|
+
.premultiply( camera.matrixWorldInverse )
|
|
63
|
+
.premultiply( camera.projectionMatrixInverse );
|
|
64
|
+
|
|
65
|
+
didCamerasChange = didCamerasChange || ! _matrix.equals( matrix );
|
|
66
|
+
matrix.copy( _matrix );
|
|
67
|
+
|
|
68
|
+
} );
|
|
69
|
+
|
|
70
|
+
const needsUpdate = this.needsUpdate;
|
|
71
|
+
this.needsUpdate = false;
|
|
72
|
+
|
|
73
|
+
return needsUpdate || didCamerasChange;
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
dispose() {
|
|
78
|
+
|
|
79
|
+
const tiles = this.tiles;
|
|
80
|
+
tiles.removeEventListener( 'camera-resolution-change', this._needsUpdateCallback );
|
|
81
|
+
tiles.removeEventListener( 'content-load', this._needsUpdateCallback );
|
|
82
|
+
tiles.removeEventListener( 'camera-add', this._onCameraAdd );
|
|
83
|
+
tiles.removeEventListener( 'camera-delete', this._onCameraDelete );
|
|
84
|
+
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
}
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import { MathUtils } from 'three';
|
|
2
|
+
|
|
3
|
+
const { clamp } = MathUtils;
|
|
4
|
+
export class FadeManager {
|
|
5
|
+
|
|
6
|
+
constructor() {
|
|
7
|
+
|
|
8
|
+
this.duration = 250;
|
|
9
|
+
this.fadeCount = 0;
|
|
10
|
+
this._lastTick = - 1;
|
|
11
|
+
this._fadeState = new Map();
|
|
12
|
+
this._fadeParams = new WeakMap();
|
|
13
|
+
this.onFadeComplete = null;
|
|
14
|
+
this.onFadeStart = null;
|
|
15
|
+
this.onFadeSetComplete = null;
|
|
16
|
+
this.onFadeSetStart = null;
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// initialize materials in the object
|
|
21
|
+
prepareObject( object ) {
|
|
22
|
+
|
|
23
|
+
object.traverse( child => {
|
|
24
|
+
|
|
25
|
+
if ( child.material ) {
|
|
26
|
+
|
|
27
|
+
this.prepareMaterial( child.material );
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
} );
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// delete the object from the fade, reset the material data
|
|
36
|
+
deleteObject( object ) {
|
|
37
|
+
|
|
38
|
+
if ( ! object ) {
|
|
39
|
+
|
|
40
|
+
return;
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
this.completeFade( object );
|
|
45
|
+
|
|
46
|
+
const fadeParams = this._fadeParams;
|
|
47
|
+
object.traverse( child => {
|
|
48
|
+
|
|
49
|
+
const material = child.material;
|
|
50
|
+
if ( material ) {
|
|
51
|
+
|
|
52
|
+
fadeParams.delete( material );
|
|
53
|
+
material.onBeforeCompile = () => {};
|
|
54
|
+
material.needsUpdate = true;
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
} );
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// initialize the material
|
|
63
|
+
prepareMaterial( material ) {
|
|
64
|
+
|
|
65
|
+
const fadeParams = this._fadeParams;
|
|
66
|
+
if ( fadeParams.has( material ) ) {
|
|
67
|
+
|
|
68
|
+
return;
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const params = {
|
|
73
|
+
fadeIn: { value: 0 },
|
|
74
|
+
fadeOut: { value: 0 },
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
material.defines = {
|
|
78
|
+
FEATURE_FADE: 0,
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
material.onBeforeCompile = shader => {
|
|
82
|
+
|
|
83
|
+
shader.uniforms = {
|
|
84
|
+
...shader.uniforms,
|
|
85
|
+
...params,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
shader.fragmentShader = shader.fragmentShader
|
|
89
|
+
.replace( /void main\(/, value => /* glsl */`
|
|
90
|
+
#if FEATURE_FADE
|
|
91
|
+
|
|
92
|
+
// adapted from https://www.shadertoy.com/view/Mlt3z8
|
|
93
|
+
float bayerDither2x2( vec2 v ) {
|
|
94
|
+
|
|
95
|
+
return mod( 3.0 * v.y + 2.0 * v.x, 4.0 );
|
|
96
|
+
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
float bayerDither4x4( vec2 v ) {
|
|
100
|
+
|
|
101
|
+
vec2 P1 = mod( v, 2.0 );
|
|
102
|
+
vec2 P2 = floor( 0.5 * mod( v, 4.0 ) );
|
|
103
|
+
return 4.0 * bayerDither2x2( P1 ) + bayerDither2x2( P2 );
|
|
104
|
+
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
uniform float fadeIn;
|
|
108
|
+
uniform float fadeOut;
|
|
109
|
+
#endif
|
|
110
|
+
|
|
111
|
+
${ value }
|
|
112
|
+
` )
|
|
113
|
+
.replace( /#include <dithering_fragment>/, value => /* glsl */`
|
|
114
|
+
|
|
115
|
+
${ value }
|
|
116
|
+
|
|
117
|
+
#if FEATURE_FADE
|
|
118
|
+
|
|
119
|
+
float bayerValue = bayerDither4x4( floor( mod( gl_FragCoord.xy, 4.0 ) ) );
|
|
120
|
+
float bayerBins = 16.0;
|
|
121
|
+
float dither = ( 0.5 + bayerValue ) / bayerBins;
|
|
122
|
+
if ( dither >= fadeIn ) {
|
|
123
|
+
|
|
124
|
+
discard;
|
|
125
|
+
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if ( dither < fadeOut ) {
|
|
129
|
+
|
|
130
|
+
discard;
|
|
131
|
+
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
#endif
|
|
135
|
+
|
|
136
|
+
` );
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
fadeParams.set( material, params );
|
|
142
|
+
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Ensure we're storing a fade timer for the provided object
|
|
146
|
+
// Returns whether a new state had to be added
|
|
147
|
+
guaranteeState( object ) {
|
|
148
|
+
|
|
149
|
+
const fadeState = this._fadeState;
|
|
150
|
+
if ( fadeState.has( object ) ) {
|
|
151
|
+
|
|
152
|
+
return false;
|
|
153
|
+
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const state = {
|
|
157
|
+
fadeInTarget: 0,
|
|
158
|
+
fadeOutTarget: 0,
|
|
159
|
+
fadeIn: 0,
|
|
160
|
+
fadeOut: 0,
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
fadeState.set( object, state );
|
|
164
|
+
|
|
165
|
+
const fadeParams = this._fadeParams;
|
|
166
|
+
object.traverse( child => {
|
|
167
|
+
|
|
168
|
+
const material = child.material;
|
|
169
|
+
if ( material && fadeParams.has( material ) ) {
|
|
170
|
+
|
|
171
|
+
const params = fadeParams.get( material );
|
|
172
|
+
params.fadeIn.value = 0;
|
|
173
|
+
params.fadeOut.value = 0;
|
|
174
|
+
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
} );
|
|
178
|
+
|
|
179
|
+
return true;
|
|
180
|
+
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Force the fade to complete in the direction it is already trending
|
|
184
|
+
completeFade( object ) {
|
|
185
|
+
|
|
186
|
+
const fadeState = this._fadeState;
|
|
187
|
+
if ( ! fadeState.has( object ) ) return;
|
|
188
|
+
|
|
189
|
+
fadeState.delete( object );
|
|
190
|
+
object.traverse( child => {
|
|
191
|
+
|
|
192
|
+
const material = child.material;
|
|
193
|
+
if ( material && material.defines.FEATURE_FADE !== 0 ) {
|
|
194
|
+
|
|
195
|
+
material.defines.FEATURE_FADE = 0;
|
|
196
|
+
material.needsUpdate = true;
|
|
197
|
+
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
} );
|
|
201
|
+
|
|
202
|
+
// fire events
|
|
203
|
+
this.fadeCount --;
|
|
204
|
+
|
|
205
|
+
if ( this.onFadeComplete ) {
|
|
206
|
+
|
|
207
|
+
this.onFadeComplete( object );
|
|
208
|
+
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if ( this.fadeCount === 0 && this.onFadeSetComplete ) {
|
|
212
|
+
|
|
213
|
+
this.onFadeSetComplete();
|
|
214
|
+
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
completeAllFades() {
|
|
220
|
+
|
|
221
|
+
this._fadeState.forEach( ( value, key ) => {
|
|
222
|
+
|
|
223
|
+
this.completeFade( key );
|
|
224
|
+
|
|
225
|
+
} );
|
|
226
|
+
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
forEachObject( cb ) {
|
|
230
|
+
|
|
231
|
+
this._fadeState.forEach( ( info, scene ) => cb( scene ) );
|
|
232
|
+
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Fade the object in
|
|
236
|
+
fadeIn( object ) {
|
|
237
|
+
|
|
238
|
+
const noState = this.guaranteeState( object );
|
|
239
|
+
const state = this._fadeState.get( object );
|
|
240
|
+
state.fadeInTarget = 1;
|
|
241
|
+
state.fadeOutTarget = 0;
|
|
242
|
+
state.fadeOut = 0;
|
|
243
|
+
|
|
244
|
+
// Fire events
|
|
245
|
+
if ( noState ) {
|
|
246
|
+
|
|
247
|
+
this.fadeCount ++;
|
|
248
|
+
if ( this.fadeCount === 1 && this.onFadeSetStart ) {
|
|
249
|
+
|
|
250
|
+
this.onFadeSetStart();
|
|
251
|
+
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if ( this.onFadeStart ) {
|
|
255
|
+
|
|
256
|
+
this.onFadeStart( object );
|
|
257
|
+
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Fade the object out
|
|
265
|
+
fadeOut( object ) {
|
|
266
|
+
|
|
267
|
+
const noState = this.guaranteeState( object );
|
|
268
|
+
const state = this._fadeState.get( object );
|
|
269
|
+
state.fadeOutTarget = 1;
|
|
270
|
+
|
|
271
|
+
// Fire events and initialize state
|
|
272
|
+
if ( noState ) {
|
|
273
|
+
|
|
274
|
+
state.fadeInTarget = 1;
|
|
275
|
+
state.fadeIn = 1;
|
|
276
|
+
|
|
277
|
+
this.fadeCount ++;
|
|
278
|
+
if ( this.fadeCount === 1 && this.onFadeSetStart ) {
|
|
279
|
+
|
|
280
|
+
this.onFadeSetStart();
|
|
281
|
+
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if ( this.onFadeStart ) {
|
|
285
|
+
|
|
286
|
+
this.onFadeStart( object );
|
|
287
|
+
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Tick the fade timer for each actively fading object
|
|
295
|
+
update() {
|
|
296
|
+
|
|
297
|
+
// clamp delta in case duration is really small or 0
|
|
298
|
+
const time = window.performance.now();
|
|
299
|
+
if ( this._lastTick === - 1 ) {
|
|
300
|
+
|
|
301
|
+
this._lastTick = time;
|
|
302
|
+
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const delta = clamp( ( time - this._lastTick ) / this.duration, 0, 1 );
|
|
306
|
+
this._lastTick = time;
|
|
307
|
+
|
|
308
|
+
const fadeState = this._fadeState;
|
|
309
|
+
const fadeParams = this._fadeParams;
|
|
310
|
+
fadeState.forEach( ( state, object ) => {
|
|
311
|
+
|
|
312
|
+
// tick the fade values
|
|
313
|
+
const {
|
|
314
|
+
fadeOutTarget,
|
|
315
|
+
fadeInTarget,
|
|
316
|
+
} = state;
|
|
317
|
+
|
|
318
|
+
let {
|
|
319
|
+
fadeOut,
|
|
320
|
+
fadeIn,
|
|
321
|
+
} = state;
|
|
322
|
+
|
|
323
|
+
const fadeInSign = Math.sign( fadeInTarget - fadeIn );
|
|
324
|
+
fadeIn = clamp( fadeIn + fadeInSign * delta, 0, 1 );
|
|
325
|
+
|
|
326
|
+
const fadeOutSign = Math.sign( fadeOutTarget - fadeOut );
|
|
327
|
+
fadeOut = clamp( fadeOut + fadeOutSign * delta, 0, 1 );
|
|
328
|
+
|
|
329
|
+
state.fadeIn = fadeIn;
|
|
330
|
+
state.fadeOut = fadeOut;
|
|
331
|
+
|
|
332
|
+
// update the material fields
|
|
333
|
+
const defineValue = Number( fadeOut !== fadeOutTarget || fadeIn !== fadeInTarget );
|
|
334
|
+
object.traverse( child => {
|
|
335
|
+
|
|
336
|
+
const material = child.material;
|
|
337
|
+
if ( material && fadeParams.has( material ) ) {
|
|
338
|
+
|
|
339
|
+
const uniforms = fadeParams.get( material );
|
|
340
|
+
uniforms.fadeIn.value = fadeIn;
|
|
341
|
+
uniforms.fadeOut.value = fadeOut;
|
|
342
|
+
|
|
343
|
+
if ( defineValue !== material.defines.FEATURE_FADE ) {
|
|
344
|
+
|
|
345
|
+
material.defines.FEATURE_FADE = defineValue;
|
|
346
|
+
material.needsUpdate = true;
|
|
347
|
+
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
} );
|
|
353
|
+
|
|
354
|
+
// Check if the fade in and fade out animations are complete
|
|
355
|
+
const fadeOutComplete = fadeOut === 1 || fadeOut === 0;
|
|
356
|
+
const fadeInComplete = fadeIn === 1 || fadeIn === 0;
|
|
357
|
+
|
|
358
|
+
// If they are or the fade out animation is further along than the
|
|
359
|
+
// fade in animation then mark the fade as completed for this tile
|
|
360
|
+
if ( ( fadeOutComplete && fadeInComplete ) || fadeOut >= fadeIn ) {
|
|
361
|
+
|
|
362
|
+
this.completeFade( object );
|
|
363
|
+
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
} );
|
|
367
|
+
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
}
|