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.
Files changed (166) hide show
  1. package/package.json +12 -0
  2. package/src/common/index.ts +24 -0
  3. package/src/common/useLine2.ts +87 -0
  4. package/src/common/useLoader.ts +184 -0
  5. package/src/common/useLocationCalculator.ts +145 -0
  6. package/src/common/useMark.ts +42 -0
  7. package/src/common/useTween.ts +86 -0
  8. package/src/core/basic/camera.ts +28 -0
  9. package/src/core/basic/clock.ts +11 -0
  10. package/src/core/basic/control.ts +32 -0
  11. package/src/core/basic/index.ts +35 -0
  12. package/src/core/basic/labelRenderer.ts +26 -0
  13. package/src/core/basic/light.ts +63 -0
  14. package/src/core/basic/renderer.ts +37 -0
  15. package/src/core/basic/scene.ts +11 -0
  16. package/src/core/basic/stats.ts +16 -0
  17. package/src/core/event.ts +74 -0
  18. package/src/core/index.ts +11 -0
  19. package/src/core/main.ts +389 -0
  20. package/src/draco/README.md +32 -0
  21. package/src/draco/draco_decoder.js +34 -0
  22. package/src/draco/draco_decoder.wasm +0 -0
  23. package/src/draco/draco_encoder.js +33 -0
  24. package/src/draco/draco_wasm_wrapper.js +117 -0
  25. package/src/draco/gltf/draco_decoder.js +33 -0
  26. package/src/draco/gltf/draco_decoder.wasm +0 -0
  27. package/src/draco/gltf/draco_encoder.js +33 -0
  28. package/src/draco/gltf/draco_wasm_wrapper.js +116 -0
  29. package/src/tileRenderer/base/Tile.d.ts +50 -0
  30. package/src/tileRenderer/base/TileBase.d.ts +76 -0
  31. package/src/tileRenderer/base/TileInternal.d.ts +36 -0
  32. package/src/tileRenderer/base/TilesRendererBase.d.ts +35 -0
  33. package/src/tileRenderer/base/TilesRendererBase.js +847 -0
  34. package/src/tileRenderer/base/Tileset.d.ts +66 -0
  35. package/src/tileRenderer/base/constants.d.ts +6 -0
  36. package/src/tileRenderer/base/constants.js +16 -0
  37. package/src/tileRenderer/base/loaders/B3DMLoaderBase.d.ts +18 -0
  38. package/src/tileRenderer/base/loaders/B3DMLoaderBase.js +85 -0
  39. package/src/tileRenderer/base/loaders/CMPTLoaderBase.d.ts +22 -0
  40. package/src/tileRenderer/base/loaders/CMPTLoaderBase.js +61 -0
  41. package/src/tileRenderer/base/loaders/I3DMLoaderBase.d.ts +21 -0
  42. package/src/tileRenderer/base/loaders/I3DMLoaderBase.js +130 -0
  43. package/src/tileRenderer/base/loaders/LoaderBase.d.ts +10 -0
  44. package/src/tileRenderer/base/loaders/LoaderBase.js +73 -0
  45. package/src/tileRenderer/base/loaders/PNTSLoaderBase.d.ts +17 -0
  46. package/src/tileRenderer/base/loaders/PNTSLoaderBase.js +82 -0
  47. package/src/tileRenderer/base/plugins/ImplicitTilingPlugin.js +12 -0
  48. package/src/tileRenderer/base/traverseFunctions.js +468 -0
  49. package/src/tileRenderer/gltf.js +144 -0
  50. package/src/tileRenderer/index.d.ts +41 -0
  51. package/src/tileRenderer/index.js +44 -0
  52. package/src/tileRenderer/plugins/README.md +578 -0
  53. package/src/tileRenderer/plugins/base/ImplicitTilingPlugin.d.ts +2 -0
  54. package/src/tileRenderer/plugins/base/ImplicitTilingPlugin.js +84 -0
  55. package/src/tileRenderer/plugins/base/SUBTREELoader.js +876 -0
  56. package/src/tileRenderer/plugins/index.d.ts +17 -0
  57. package/src/tileRenderer/plugins/index.js +17 -0
  58. package/src/tileRenderer/plugins/three/CesiumIonAuthPlugin.d.ts +9 -0
  59. package/src/tileRenderer/plugins/three/CesiumIonAuthPlugin.js +175 -0
  60. package/src/tileRenderer/plugins/three/DebugTilesPlugin.d.ts +29 -0
  61. package/src/tileRenderer/plugins/three/DebugTilesPlugin.js +677 -0
  62. package/src/tileRenderer/plugins/three/GLTFExtensionsPlugin.d.ts +18 -0
  63. package/src/tileRenderer/plugins/three/GLTFExtensionsPlugin.js +86 -0
  64. package/src/tileRenderer/plugins/three/GoogleAttributionsManager.js +62 -0
  65. package/src/tileRenderer/plugins/three/GoogleCloudAuthPlugin.d.ts +5 -0
  66. package/src/tileRenderer/plugins/three/GoogleCloudAuthPlugin.js +200 -0
  67. package/src/tileRenderer/plugins/three/ReorientationPlugin.d.ts +12 -0
  68. package/src/tileRenderer/plugins/three/ReorientationPlugin.js +136 -0
  69. package/src/tileRenderer/plugins/three/TileCompressionPlugin.d.ts +18 -0
  70. package/src/tileRenderer/plugins/three/TileCompressionPlugin.js +223 -0
  71. package/src/tileRenderer/plugins/three/UpdateOnChangePlugin.d.ts +5 -0
  72. package/src/tileRenderer/plugins/three/UpdateOnChangePlugin.js +87 -0
  73. package/src/tileRenderer/plugins/three/fade/FadeManager.js +370 -0
  74. package/src/tileRenderer/plugins/three/fade/TilesFadePlugin.d.ts +9 -0
  75. package/src/tileRenderer/plugins/three/fade/TilesFadePlugin.js +318 -0
  76. package/src/tileRenderer/plugins/three/gltf/GLTFCesiumRTCExtension.d.ts +5 -0
  77. package/src/tileRenderer/plugins/three/gltf/GLTFCesiumRTCExtension.js +27 -0
  78. package/src/tileRenderer/plugins/three/gltf/GLTFMeshFeaturesExtension.d.ts +30 -0
  79. package/src/tileRenderer/plugins/three/gltf/GLTFMeshFeaturesExtension.js +76 -0
  80. package/src/tileRenderer/plugins/three/gltf/GLTFStructuralMetadataExtension.d.ts +49 -0
  81. package/src/tileRenderer/plugins/three/gltf/GLTFStructuralMetadataExtension.js +147 -0
  82. package/src/tileRenderer/plugins/three/gltf/metadata/classes/ClassProperty.js +149 -0
  83. package/src/tileRenderer/plugins/three/gltf/metadata/classes/MeshFeatures.js +215 -0
  84. package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertyAttributeAccessor.js +107 -0
  85. package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertySetAccessor.js +45 -0
  86. package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertyTableAccessor.js +209 -0
  87. package/src/tileRenderer/plugins/three/gltf/metadata/classes/PropertyTextureAccessor.js +244 -0
  88. package/src/tileRenderer/plugins/three/gltf/metadata/classes/StructuralMetadata.js +202 -0
  89. package/src/tileRenderer/plugins/three/gltf/metadata/math/Matrix2.js +55 -0
  90. package/src/tileRenderer/plugins/three/gltf/metadata/utilities/ClassPropertyHelpers.js +495 -0
  91. package/src/tileRenderer/plugins/three/gltf/metadata/utilities/TexCoordUtilities.js +72 -0
  92. package/src/tileRenderer/plugins/three/gltf/metadata/utilities/TextureReadUtility.js +154 -0
  93. package/src/tileRenderer/plugins/three/objects/EllipsoidRegionHelper.js +186 -0
  94. package/src/tileRenderer/plugins/three/objects/SphereHelper.js +55 -0
  95. package/src/tileRenderer/r3f/README.md +238 -0
  96. package/src/tileRenderer/r3f/components/CameraControls.jsx +132 -0
  97. package/src/tileRenderer/r3f/components/CameraTransition.jsx +177 -0
  98. package/src/tileRenderer/r3f/components/CanvasDOMOverlay.jsx +54 -0
  99. package/src/tileRenderer/r3f/components/CompassGizmo.jsx +260 -0
  100. package/src/tileRenderer/r3f/components/TilesAttributionOverlay.jsx +110 -0
  101. package/src/tileRenderer/r3f/components/TilesRenderer.jsx +239 -0
  102. package/src/tileRenderer/r3f/index.jsx +6 -0
  103. package/src/tileRenderer/r3f/utilities/useForceUpdate.jsx +8 -0
  104. package/src/tileRenderer/r3f/utilities/useObjectDep.jsx +59 -0
  105. package/src/tileRenderer/r3f/utilities/useOptions.jsx +143 -0
  106. package/src/tileRenderer/three/DebugTilesRenderer.d.ts +28 -0
  107. package/src/tileRenderer/three/DebugTilesRenderer.js +58 -0
  108. package/src/tileRenderer/three/TilesGroup.d.ts +9 -0
  109. package/src/tileRenderer/three/TilesGroup.js +91 -0
  110. package/src/tileRenderer/three/TilesRenderer.d.ts +37 -0
  111. package/src/tileRenderer/three/TilesRenderer.js +1049 -0
  112. package/src/tileRenderer/three/controls/CameraTransitionManager.js +305 -0
  113. package/src/tileRenderer/three/controls/EnvironmentControls.js +1295 -0
  114. package/src/tileRenderer/three/controls/GlobeControls.js +684 -0
  115. package/src/tileRenderer/three/controls/PivotPointMesh.js +104 -0
  116. package/src/tileRenderer/three/controls/PointerTracker.js +257 -0
  117. package/src/tileRenderer/three/controls/utils.js +113 -0
  118. package/src/tileRenderer/three/loaders/B3DMLoader.d.ts +26 -0
  119. package/src/tileRenderer/three/loaders/B3DMLoader.js +85 -0
  120. package/src/tileRenderer/three/loaders/CMPTLoader.d.ts +19 -0
  121. package/src/tileRenderer/three/loaders/CMPTLoader.js +97 -0
  122. package/src/tileRenderer/three/loaders/GLTFExtensionLoader.d.ts +11 -0
  123. package/src/tileRenderer/three/loaders/GLTFExtensionLoader.js +68 -0
  124. package/src/tileRenderer/three/loaders/I3DMLoader.d.ts +26 -0
  125. package/src/tileRenderer/three/loaders/I3DMLoader.js +256 -0
  126. package/src/tileRenderer/three/loaders/PNTSLoader.d.ts +25 -0
  127. package/src/tileRenderer/three/loaders/PNTSLoader.js +202 -0
  128. package/src/tileRenderer/three/loaders/gltf/GLTFCesiumRTCExtension.js +12 -0
  129. package/src/tileRenderer/three/loaders/gltf/GLTFMeshFeaturesExtension.js +12 -0
  130. package/src/tileRenderer/three/loaders/gltf/GLTFStructuralMetadataExtension.js +12 -0
  131. package/src/tileRenderer/three/math/Ellipsoid.d.ts +31 -0
  132. package/src/tileRenderer/three/math/Ellipsoid.js +337 -0
  133. package/src/tileRenderer/three/math/EllipsoidRegion.d.ts +23 -0
  134. package/src/tileRenderer/three/math/EllipsoidRegion.js +178 -0
  135. package/src/tileRenderer/three/math/ExtendedFrustum.js +65 -0
  136. package/src/tileRenderer/three/math/GeoConstants.d.ts +4 -0
  137. package/src/tileRenderer/three/math/GeoConstants.js +5 -0
  138. package/src/tileRenderer/three/math/GeoUtils.d.ts +9 -0
  139. package/src/tileRenderer/three/math/GeoUtils.js +106 -0
  140. package/src/tileRenderer/three/math/OBB.js +179 -0
  141. package/src/tileRenderer/three/math/TileBoundingVolume.js +272 -0
  142. package/src/tileRenderer/three/plugins/CesiumIonAuthPlugin.js +12 -0
  143. package/src/tileRenderer/three/plugins/DebugTilesPlugin.js +26 -0
  144. package/src/tileRenderer/three/plugins/GoogleCloudAuthPlugin.js +12 -0
  145. package/src/tileRenderer/three/raycastTraverse.js +178 -0
  146. package/src/tileRenderer/three/renderers/CesiumIonTilesRenderer.d.ts +14 -0
  147. package/src/tileRenderer/three/renderers/CesiumIonTilesRenderer.js +21 -0
  148. package/src/tileRenderer/three/renderers/GoogleTilesRenderer.d.ts +43 -0
  149. package/src/tileRenderer/three/renderers/GoogleTilesRenderer.js +48 -0
  150. package/src/tileRenderer/three/utilities.js +54 -0
  151. package/src/tileRenderer/utilities/BatchTable.d.ts +24 -0
  152. package/src/tileRenderer/utilities/BatchTable.js +82 -0
  153. package/src/tileRenderer/utilities/BatchTableHierarchyExtension.js +127 -0
  154. package/src/tileRenderer/utilities/FeatureTable.d.ts +30 -0
  155. package/src/tileRenderer/utilities/FeatureTable.js +159 -0
  156. package/src/tileRenderer/utilities/LRUCache.d.ts +8 -0
  157. package/src/tileRenderer/utilities/LRUCache.js +385 -0
  158. package/src/tileRenderer/utilities/PriorityQueue.d.ts +16 -0
  159. package/src/tileRenderer/utilities/PriorityQueue.js +137 -0
  160. package/src/tileRenderer/utilities/arrayToString.js +7 -0
  161. package/src/tileRenderer/utilities/readMagicBytes.js +29 -0
  162. package/src/tileRenderer/utilities/rgb565torgb.js +22 -0
  163. package/src/tileRenderer/utilities/urlExtension.js +34 -0
  164. package/tsconfig.json +42 -0
  165. package/tsconfig.node.json +11 -0
  166. 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,5 @@
1
+ export class UpdateOnChangePlugin {
2
+
3
+ constructor();
4
+
5
+ }
@@ -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
+ }
@@ -0,0 +1,9 @@
1
+ export class TilesFadePlugin {
2
+
3
+ constructor( options: {
4
+ maximumFadeOutTiles: Number,
5
+ fadeRootTiles: Boolean,
6
+ fadeDuration: Number,
7
+ } );
8
+
9
+ }