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,177 @@
|
|
|
1
|
+
import { forwardRef, useEffect, useMemo } from 'react';
|
|
2
|
+
import { useFrame, useThree } from '@react-three/fiber';
|
|
3
|
+
import { CameraTransitionManager } from '3d-tiles-renderer';
|
|
4
|
+
|
|
5
|
+
export const CameraTransition = forwardRef( function CameraTransition( props, ref ) {
|
|
6
|
+
|
|
7
|
+
const { mode = 'perspective', onTransitionStart, onTransitionEnd, perspectiveCamera, orthographicCamera } = props;
|
|
8
|
+
const [ set, invalidate, controls, camera, size ] = useThree( state => [ state.set, state.invalidate, state.controls, state.camera, state.size ] );
|
|
9
|
+
|
|
10
|
+
// create the manager
|
|
11
|
+
const manager = useMemo( () => {
|
|
12
|
+
|
|
13
|
+
const manager = new CameraTransitionManager();
|
|
14
|
+
manager.autoSync = false;
|
|
15
|
+
|
|
16
|
+
if ( camera.isOrthographicCamera ) {
|
|
17
|
+
|
|
18
|
+
manager.orthographicCamera.copy( camera );
|
|
19
|
+
manager.mode = 'orthographic';
|
|
20
|
+
|
|
21
|
+
} else {
|
|
22
|
+
|
|
23
|
+
manager.perspectiveCamera.copy( camera );
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
manager.syncCameras();
|
|
28
|
+
manager.mode = mode;
|
|
29
|
+
|
|
30
|
+
return manager;
|
|
31
|
+
|
|
32
|
+
// only respect the camera initially so the default camera settings are automatically used
|
|
33
|
+
|
|
34
|
+
}, [] );
|
|
35
|
+
|
|
36
|
+
useEffect( () => {
|
|
37
|
+
|
|
38
|
+
const { perspectiveCamera, orthographicCamera } = manager;
|
|
39
|
+
const aspect = size.width / size.height;
|
|
40
|
+
perspectiveCamera.aspect = aspect;
|
|
41
|
+
perspectiveCamera.updateProjectionMatrix();
|
|
42
|
+
|
|
43
|
+
orthographicCamera.left = - orthographicCamera.top * aspect;
|
|
44
|
+
orthographicCamera.right = - orthographicCamera.left;
|
|
45
|
+
perspectiveCamera.updateProjectionMatrix();
|
|
46
|
+
|
|
47
|
+
}, [ manager, size ] );
|
|
48
|
+
|
|
49
|
+
// assign ref
|
|
50
|
+
useEffect( () => {
|
|
51
|
+
|
|
52
|
+
if ( ref ) {
|
|
53
|
+
|
|
54
|
+
if ( ref instanceof Function ) {
|
|
55
|
+
|
|
56
|
+
ref( manager );
|
|
57
|
+
|
|
58
|
+
} else {
|
|
59
|
+
|
|
60
|
+
ref.current = manager;
|
|
61
|
+
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
}, [ manager, ref ] );
|
|
67
|
+
|
|
68
|
+
// set the camera
|
|
69
|
+
useEffect( () => {
|
|
70
|
+
|
|
71
|
+
const cameraCallback = ( { camera } ) => {
|
|
72
|
+
|
|
73
|
+
set( () => ( { camera } ) );
|
|
74
|
+
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
set( () => ( { camera: manager.camera } ) );
|
|
78
|
+
manager.addEventListener( 'camera-change', cameraCallback );
|
|
79
|
+
return () => {
|
|
80
|
+
|
|
81
|
+
manager.removeEventListener( 'camera-change', cameraCallback );
|
|
82
|
+
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
}, [ manager, set ] );
|
|
86
|
+
|
|
87
|
+
// register for events
|
|
88
|
+
useEffect( () => {
|
|
89
|
+
|
|
90
|
+
if ( onTransitionEnd ) {
|
|
91
|
+
|
|
92
|
+
manager.addEventListener( 'transition-end', onTransitionEnd );
|
|
93
|
+
return () => manager.removeEventListener( 'transition-end', onTransitionEnd );
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
}, [ onTransitionEnd, manager ] );
|
|
98
|
+
|
|
99
|
+
useEffect( () => {
|
|
100
|
+
|
|
101
|
+
if ( onTransitionStart ) {
|
|
102
|
+
|
|
103
|
+
manager.addEventListener( 'transition-start', onTransitionStart );
|
|
104
|
+
return () => manager.removeEventListener( 'transition-start', onTransitionStart );
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
}, [ onTransitionStart, manager ] );
|
|
109
|
+
|
|
110
|
+
// assign cameras
|
|
111
|
+
useEffect( () => {
|
|
112
|
+
|
|
113
|
+
const oldPerspectiveCamera = manager.perspectiveCamera;
|
|
114
|
+
const oldOrthographicCamera = manager.orthographicCamera;
|
|
115
|
+
manager.perspectiveCamera = perspectiveCamera || oldPerspectiveCamera;
|
|
116
|
+
manager.orthographicCamera = orthographicCamera || oldOrthographicCamera;
|
|
117
|
+
|
|
118
|
+
set( () => ( { camera: manager.camera } ) );
|
|
119
|
+
|
|
120
|
+
return () => {
|
|
121
|
+
|
|
122
|
+
manager.perspectiveCamera = oldPerspectiveCamera;
|
|
123
|
+
manager.orthographicCamera = oldOrthographicCamera;
|
|
124
|
+
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
}, [ perspectiveCamera, orthographicCamera, manager, set ] );
|
|
128
|
+
|
|
129
|
+
// toggle
|
|
130
|
+
useEffect( () => {
|
|
131
|
+
|
|
132
|
+
if ( mode !== manager.mode ) {
|
|
133
|
+
|
|
134
|
+
if ( controls && controls.isEnvironmentControls ) {
|
|
135
|
+
|
|
136
|
+
controls.getPivotPoint( manager.fixedPoint );
|
|
137
|
+
manager.syncCameras();
|
|
138
|
+
controls.adjustCamera( manager.perspectiveCamera );
|
|
139
|
+
controls.adjustCamera( manager.orthographicCamera );
|
|
140
|
+
|
|
141
|
+
} else {
|
|
142
|
+
|
|
143
|
+
manager.fixedPoint
|
|
144
|
+
.set( 0, 0, - 1 )
|
|
145
|
+
.transformDirection( manager.camera.matrixWorld )
|
|
146
|
+
.multiplyScalar( 50 )
|
|
147
|
+
.add( manager.camera.position );
|
|
148
|
+
manager.syncCameras();
|
|
149
|
+
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
manager.toggle();
|
|
153
|
+
invalidate();
|
|
154
|
+
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
}, [ mode, manager, invalidate, controls ] );
|
|
158
|
+
|
|
159
|
+
// update animation
|
|
160
|
+
useFrame( () => {
|
|
161
|
+
|
|
162
|
+
manager.update();
|
|
163
|
+
if ( controls ) {
|
|
164
|
+
|
|
165
|
+
controls.enabled = ! manager.animating;
|
|
166
|
+
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if ( manager.animating ) {
|
|
170
|
+
|
|
171
|
+
invalidate();
|
|
172
|
+
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
}, - 1 );
|
|
176
|
+
|
|
177
|
+
} );
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useMemo, useEffect, StrictMode } from 'react';
|
|
2
|
+
import { createRoot } from 'react-dom/client';
|
|
3
|
+
import { useThree } from '@react-three/fiber';
|
|
4
|
+
|
|
5
|
+
// Utility class for overlaying dom elements on top of the canvas
|
|
6
|
+
export function CanvasDOMOverlay( { children, ...rest } ) {
|
|
7
|
+
|
|
8
|
+
// create the dom element and react root
|
|
9
|
+
const [ gl ] = useThree( state => [ state.gl ] );
|
|
10
|
+
const container = useMemo( () => document.createElement( 'div' ), [] );
|
|
11
|
+
const root = useMemo( () => createRoot( container ), [ container ] );
|
|
12
|
+
|
|
13
|
+
// watch for canvas resize
|
|
14
|
+
const observer = useMemo( () => {
|
|
15
|
+
|
|
16
|
+
const observer = new ResizeObserver( ( [ { contentRect } ] ) => {
|
|
17
|
+
|
|
18
|
+
container.style.top = `${ contentRect.top }px`;
|
|
19
|
+
container.style.left = `${ contentRect.left }px`;
|
|
20
|
+
container.style.width = `${ contentRect.width }px`;
|
|
21
|
+
container.style.height = `${ contentRect.height }px`;
|
|
22
|
+
|
|
23
|
+
} );
|
|
24
|
+
observer.observe( gl.domElement );
|
|
25
|
+
return observer;
|
|
26
|
+
|
|
27
|
+
}, [ gl, container ] );
|
|
28
|
+
|
|
29
|
+
// position the container
|
|
30
|
+
useEffect( () => {
|
|
31
|
+
|
|
32
|
+
container.style.pointerEvents = 'none';
|
|
33
|
+
container.style.position = 'absolute';
|
|
34
|
+
document.body.appendChild( container );
|
|
35
|
+
|
|
36
|
+
return () => {
|
|
37
|
+
|
|
38
|
+
container.remove();
|
|
39
|
+
observer.disconnect();
|
|
40
|
+
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
}, [ observer, container ] );
|
|
44
|
+
|
|
45
|
+
// render the children into the container
|
|
46
|
+
root.render(
|
|
47
|
+
<StrictMode>
|
|
48
|
+
<div { ...rest }>
|
|
49
|
+
{ children }
|
|
50
|
+
</div>
|
|
51
|
+
</StrictMode>
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import { createPortal, useFrame, useThree } from '@react-three/fiber';
|
|
2
|
+
import { useContext, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
+
import { BackSide, Matrix4, OrthographicCamera, Ray, Scene, Vector3 } from 'three';
|
|
4
|
+
import { TilesRendererContext } from './TilesRenderer';
|
|
5
|
+
import { closestRayEllipsoidSurfacePointEstimate } from '../../three/controls/utils';
|
|
6
|
+
|
|
7
|
+
// Based in part on @pmndrs/drei's Gizmo component
|
|
8
|
+
|
|
9
|
+
const _vec = /*@__PURE__*/ new Vector3();
|
|
10
|
+
const _axis = /*@__PURE__*/ new Vector3();
|
|
11
|
+
const _pos = /*@__PURE__*/ new Vector3();
|
|
12
|
+
const _matrix = /*@__PURE__*/ new Matrix4();
|
|
13
|
+
const _invMatrix = /*@__PURE__*/ new Matrix4();
|
|
14
|
+
const _enuMatrix = /*@__PURE__*/ new Matrix4();
|
|
15
|
+
const _ray = /*@__PURE__*/ new Ray();
|
|
16
|
+
const _cart = {};
|
|
17
|
+
|
|
18
|
+
// Returns the "focus" point that the camera is facing based on the closest point to the ellipsoid.
|
|
19
|
+
// Used for determining the compass orientation.
|
|
20
|
+
function getCameraFocusPoint( camera, ellipsoid, tilesGroup, target ) {
|
|
21
|
+
|
|
22
|
+
_invMatrix.copy( tilesGroup.matrixWorld ).invert();
|
|
23
|
+
|
|
24
|
+
// get ray in globe coordinate frame
|
|
25
|
+
_ray.origin.copy( camera.position );
|
|
26
|
+
_ray.direction.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
|
|
27
|
+
_ray.applyMatrix4( _invMatrix );
|
|
28
|
+
|
|
29
|
+
// get the closest point to the ray on the globe in the global coordinate frame
|
|
30
|
+
closestRayEllipsoidSurfacePointEstimate( _ray, ellipsoid, _pos );
|
|
31
|
+
_pos.applyMatrix4( tilesGroup.matrixWorld );
|
|
32
|
+
|
|
33
|
+
// get ortho camera info
|
|
34
|
+
_axis.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld );
|
|
35
|
+
|
|
36
|
+
// ensure we move the camera exactly along the forward vector to avoid shifting
|
|
37
|
+
// the camera in other directions due to floating point error
|
|
38
|
+
const dist = _pos.sub( camera.position ).dot( _axis );
|
|
39
|
+
target.copy( camera.position ).addScaledVector( _axis, dist );
|
|
40
|
+
return target;
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Renders the portal with an orthographic camera
|
|
45
|
+
function RenderPortal( props ) {
|
|
46
|
+
|
|
47
|
+
const { defaultScene, defaultCamera, overrideRenderLoop = true, renderPriority = 1 } = props;
|
|
48
|
+
const camera = useMemo( () => new OrthographicCamera(), [] );
|
|
49
|
+
const [ set, size, gl, scene ] = useThree( state => [ state.set, state.size, state.gl, state.scene ] );
|
|
50
|
+
useEffect( () => {
|
|
51
|
+
|
|
52
|
+
set( { camera } );
|
|
53
|
+
|
|
54
|
+
}, [ set, camera ] );
|
|
55
|
+
|
|
56
|
+
useEffect( () => {
|
|
57
|
+
|
|
58
|
+
camera.left = - size.width / 2;
|
|
59
|
+
camera.right = size.width / 2;
|
|
60
|
+
camera.top = size.height / 2;
|
|
61
|
+
camera.bottom = - size.height / 2;
|
|
62
|
+
camera.near = 0;
|
|
63
|
+
camera.far = 2000;
|
|
64
|
+
camera.position.z = camera.far / 2;
|
|
65
|
+
camera.updateProjectionMatrix();
|
|
66
|
+
|
|
67
|
+
}, [ camera, size ] );
|
|
68
|
+
|
|
69
|
+
useFrame( () => {
|
|
70
|
+
|
|
71
|
+
if ( overrideRenderLoop ) {
|
|
72
|
+
|
|
73
|
+
gl.render( defaultScene, defaultCamera );
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const currentAutoClear = gl.autoClear;
|
|
78
|
+
gl.autoClear = false;
|
|
79
|
+
|
|
80
|
+
gl.clearDepth();
|
|
81
|
+
gl.render( scene, camera );
|
|
82
|
+
|
|
83
|
+
gl.autoClear = currentAutoClear;
|
|
84
|
+
|
|
85
|
+
}, renderPriority );
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// generates an extruded box geometry
|
|
90
|
+
function TriangleGeometry() {
|
|
91
|
+
|
|
92
|
+
const ref = useRef();
|
|
93
|
+
useEffect( () => {
|
|
94
|
+
|
|
95
|
+
const geometry = ref.current;
|
|
96
|
+
const position = geometry.attributes.position;
|
|
97
|
+
for ( let i = 0, l = position.count; i < l; i ++ ) {
|
|
98
|
+
|
|
99
|
+
_vec.fromBufferAttribute( position, i );
|
|
100
|
+
if ( _vec.y > 0 ) {
|
|
101
|
+
|
|
102
|
+
_vec.x = 0;
|
|
103
|
+
position.setXYZ( i, ..._vec );
|
|
104
|
+
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
} );
|
|
110
|
+
|
|
111
|
+
return <boxGeometry ref={ ref } />;
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// renders a typical compass graphic with red north triangle, white south, and a tinted circular background
|
|
116
|
+
function CompassGraphic( { northColor = 0xEF5350, southColor = 0xFFFFFF } ) {
|
|
117
|
+
|
|
118
|
+
const [ lightTarget, setLightTarget ] = useState();
|
|
119
|
+
const groupRef = useRef();
|
|
120
|
+
useEffect( () => {
|
|
121
|
+
|
|
122
|
+
setLightTarget( groupRef.current );
|
|
123
|
+
|
|
124
|
+
}, [] );
|
|
125
|
+
|
|
126
|
+
return (
|
|
127
|
+
<group scale={ 0.5 } ref={ groupRef }>
|
|
128
|
+
|
|
129
|
+
{/* Lights */}
|
|
130
|
+
<ambientLight intensity={ 1 } />
|
|
131
|
+
<directionalLight position={ [ 0, 2, 3 ] } intensity={ 3 } target={ lightTarget } />
|
|
132
|
+
<directionalLight position={ [ 0, - 2, - 3 ] } intensity={ 3 } target={ lightTarget } />
|
|
133
|
+
|
|
134
|
+
{/* Background */}
|
|
135
|
+
<mesh>
|
|
136
|
+
<sphereGeometry />
|
|
137
|
+
<meshBasicMaterial color={ 0 } opacity={ 0.3 } transparent={ true } side={ BackSide } />
|
|
138
|
+
</mesh>
|
|
139
|
+
|
|
140
|
+
{/* Compass shape */}
|
|
141
|
+
<group scale={ [ 0.5, 1, 0.15 ] }>
|
|
142
|
+
<mesh position-y={ 0.5 }>
|
|
143
|
+
<TriangleGeometry />
|
|
144
|
+
<meshStandardMaterial color={ northColor } />
|
|
145
|
+
</mesh>
|
|
146
|
+
<mesh position-y={ - 0.5 } rotation-x={ Math.PI }>
|
|
147
|
+
<TriangleGeometry />
|
|
148
|
+
<meshStandardMaterial color={ southColor } />
|
|
149
|
+
</mesh>
|
|
150
|
+
</group>
|
|
151
|
+
</group>
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function CompassGizmo( { children, overrideRenderLoop, mode = '3d', margin = 10, scale = 35, visible = true, ...rest } ) {
|
|
157
|
+
|
|
158
|
+
const [ defaultCamera, defaultScene, size ] = useThree( state => [ state.camera, state.scene, state.size ] );
|
|
159
|
+
const tiles = useContext( TilesRendererContext );
|
|
160
|
+
const groupRef = useRef( null );
|
|
161
|
+
const scene = useMemo( () => {
|
|
162
|
+
|
|
163
|
+
return new Scene();
|
|
164
|
+
|
|
165
|
+
}, [] );
|
|
166
|
+
|
|
167
|
+
useFrame( () => {
|
|
168
|
+
|
|
169
|
+
if ( tiles === null || groupRef.current === null ) {
|
|
170
|
+
|
|
171
|
+
return null;
|
|
172
|
+
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const { ellipsoid } = tiles;
|
|
176
|
+
const group = groupRef.current;
|
|
177
|
+
|
|
178
|
+
// get the ENU frame in world space
|
|
179
|
+
_matrix.copy( tiles.group.matrixWorld ).invert();
|
|
180
|
+
getCameraFocusPoint( defaultCamera, ellipsoid, tiles.group, _pos ).applyMatrix4( _matrix );
|
|
181
|
+
ellipsoid.getPositionToCartographic( _pos, _cart );
|
|
182
|
+
|
|
183
|
+
ellipsoid
|
|
184
|
+
.getRotationMatrixFromAzElRoll( _cart.lat, _cart.lon, 0, 0, 0, _enuMatrix )
|
|
185
|
+
.premultiply( tiles.group.matrixWorld );
|
|
186
|
+
|
|
187
|
+
// get the camera orientation in the local ENU frame
|
|
188
|
+
_enuMatrix.invert();
|
|
189
|
+
_matrix.copy( defaultCamera.matrixWorld ).premultiply( _enuMatrix );
|
|
190
|
+
|
|
191
|
+
if ( mode.toLowerCase() === '3d' ) {
|
|
192
|
+
|
|
193
|
+
group.quaternion.setFromRotationMatrix( _matrix ).invert();
|
|
194
|
+
|
|
195
|
+
} else {
|
|
196
|
+
|
|
197
|
+
// get the projected facing direction of the camera
|
|
198
|
+
_vec.set( 0, 1, 0 ).transformDirection( _matrix ).normalize();
|
|
199
|
+
_vec.z = 0;
|
|
200
|
+
_vec.normalize();
|
|
201
|
+
|
|
202
|
+
if ( _vec.length() === 0 ) {
|
|
203
|
+
|
|
204
|
+
// if we're looking exactly top-down
|
|
205
|
+
group.quaternion.identity();
|
|
206
|
+
|
|
207
|
+
} else {
|
|
208
|
+
|
|
209
|
+
// compute the 2d looking direction
|
|
210
|
+
const angle = _axis.set( 0, 1, 0 ).angleTo( _vec );
|
|
211
|
+
_axis.cross( _vec ).normalize();
|
|
212
|
+
group.quaternion.setFromAxisAngle( _axis, - angle );
|
|
213
|
+
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
} );
|
|
219
|
+
|
|
220
|
+
// default to the compass graphic
|
|
221
|
+
if ( ! children ) {
|
|
222
|
+
|
|
223
|
+
children = <CompassGraphic />;
|
|
224
|
+
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// remove the portal rendering if not present
|
|
228
|
+
if ( ! visible ) {
|
|
229
|
+
|
|
230
|
+
return null;
|
|
231
|
+
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return (
|
|
235
|
+
createPortal(
|
|
236
|
+
<>
|
|
237
|
+
<group
|
|
238
|
+
ref={ groupRef }
|
|
239
|
+
scale={ scale }
|
|
240
|
+
position={ [
|
|
241
|
+
size.width / 2 - margin - scale / 2,
|
|
242
|
+
- size.height / 2 + margin + scale / 2,
|
|
243
|
+
0,
|
|
244
|
+
] }
|
|
245
|
+
|
|
246
|
+
{ ...rest }
|
|
247
|
+
>{ children }</group>
|
|
248
|
+
<RenderPortal
|
|
249
|
+
defaultCamera={ defaultCamera }
|
|
250
|
+
defaultScene={ defaultScene }
|
|
251
|
+
overrideRenderLoop={ overrideRenderLoop }
|
|
252
|
+
renderPriority={ 10 }
|
|
253
|
+
/>
|
|
254
|
+
</>,
|
|
255
|
+
scene,
|
|
256
|
+
{ events: { priority: 10 } },
|
|
257
|
+
)
|
|
258
|
+
);
|
|
259
|
+
|
|
260
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { useContext, useState, useEffect, useMemo } from 'react';
|
|
2
|
+
import { TilesRendererContext } from './TilesRenderer.jsx';
|
|
3
|
+
import { CanvasDOMOverlay } from './CanvasDOMOverlay.jsx';
|
|
4
|
+
|
|
5
|
+
// Overlay for displaying tile data set attributions
|
|
6
|
+
export function TilesAttributionOverlay( { children, style, ...rest } ) {
|
|
7
|
+
|
|
8
|
+
const tiles = useContext( TilesRendererContext );
|
|
9
|
+
const [ attributions, setAttributions ] = useState( [] );
|
|
10
|
+
|
|
11
|
+
// Add events for checking when attributions may be updated
|
|
12
|
+
useEffect( () => {
|
|
13
|
+
|
|
14
|
+
if ( ! tiles ) {
|
|
15
|
+
|
|
16
|
+
return;
|
|
17
|
+
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let queued = false;
|
|
21
|
+
const callback = () => {
|
|
22
|
+
|
|
23
|
+
if ( ! queued ) {
|
|
24
|
+
|
|
25
|
+
queued = true;
|
|
26
|
+
queueMicrotask( () => {
|
|
27
|
+
|
|
28
|
+
setAttributions( tiles.getAttributions() );
|
|
29
|
+
queued = false;
|
|
30
|
+
|
|
31
|
+
} );
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
tiles.addEventListener( 'tile-visibility-change', callback );
|
|
38
|
+
tiles.addEventListener( 'load-tile-set', callback );
|
|
39
|
+
|
|
40
|
+
return () => {
|
|
41
|
+
|
|
42
|
+
tiles.removeEventListener( 'tile-visibility-change', callback );
|
|
43
|
+
tiles.removeEventListener( 'load-tile-set', callback );
|
|
44
|
+
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
}, [ tiles ] );
|
|
48
|
+
|
|
49
|
+
// generate elements for each type of attribution
|
|
50
|
+
const output = [];
|
|
51
|
+
attributions.forEach( ( att, i ) => {
|
|
52
|
+
|
|
53
|
+
let element = null;
|
|
54
|
+
if ( att.type === 'string' ) {
|
|
55
|
+
|
|
56
|
+
element = <div key={ i }>{ att.value }</div>;
|
|
57
|
+
|
|
58
|
+
} else if ( att.type === 'html' ) {
|
|
59
|
+
|
|
60
|
+
element = <div key={ i } dangerouslySetInnerHTML={ { __html: att.value } } style={ { pointerEvents: 'all' } }/>;
|
|
61
|
+
|
|
62
|
+
} else if ( att.type === 'image' ) {
|
|
63
|
+
|
|
64
|
+
element = <div key={ i }><img src={ att.value } /></div>;
|
|
65
|
+
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if ( element ) {
|
|
69
|
+
|
|
70
|
+
output.push( element );
|
|
71
|
+
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
} );
|
|
75
|
+
|
|
76
|
+
// Generate CSS for modifying child elements implicit to the html attributions
|
|
77
|
+
const classId = useMemo( () => 'class_' + window.crypto.randomUUID(), [] );
|
|
78
|
+
const styles = useMemo( () => `
|
|
79
|
+
#${ classId } a {
|
|
80
|
+
color: white;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
#${ classId } img {
|
|
84
|
+
max-width: 125px;
|
|
85
|
+
display: block;
|
|
86
|
+
margin: 5px 0;
|
|
87
|
+
}
|
|
88
|
+
`, [ classId ] );
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<CanvasDOMOverlay
|
|
92
|
+
id={ classId }
|
|
93
|
+
style={ {
|
|
94
|
+
position: 'absolute',
|
|
95
|
+
bottom: 0,
|
|
96
|
+
left: 0,
|
|
97
|
+
padding: '10px',
|
|
98
|
+
color: 'rgba( 255, 255, 255, 0.75 )',
|
|
99
|
+
fontSize: '10px',
|
|
100
|
+
...style,
|
|
101
|
+
} }
|
|
102
|
+
{ ...rest }
|
|
103
|
+
>
|
|
104
|
+
<style>{ styles }</style>
|
|
105
|
+
{ children }
|
|
106
|
+
{ output }
|
|
107
|
+
</CanvasDOMOverlay>
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
}
|