diff --git a/src/r3f/components/CameraControls.jsx b/src/r3f/components/CameraControls.jsx
index b25cb9ce5..6ff0f1183 100644
--- a/src/r3f/components/CameraControls.jsx
+++ b/src/r3f/components/CameraControls.jsx
@@ -2,13 +2,13 @@ import { forwardRef, useMemo, useEffect, useContext } from 'react';
import { useThree, useFrame } from '@react-three/fiber';
import { EnvironmentControls as EnvironmentControlsImpl, GlobeControls as GlobeControlsImpl } from '3d-tiles-renderer/three';
import { useShallowOptions } from '../utilities/useOptions.js';
-import { TilesRendererContext } from './TilesRenderer.jsx';
+import { EllipsoidContext } from './TilesRenderer.jsx';
import { useApplyRefs } from '../utilities/useApplyRefs.js';
// Add a base component implementation for both EnvironmentControls and GlobeControls
const ControlsBaseComponent = forwardRef( function ControlsBaseComponent( props, ref ) {
- const { controlsConstructor, domElement, scene, camera, ellipsoid, ellipsoidFrame, tilesRenderer, ...rest } = props;
+ const { controlsConstructor, domElement, scene, camera, ellipsoid, ellipsoidFrame, ...rest } = props;
const [ defaultCamera ] = useThree( state => [ state.camera ] );
const [ gl ] = useThree( state => [ state.gl ] );
@@ -17,13 +17,12 @@ const ControlsBaseComponent = forwardRef( function ControlsBaseComponent( props,
const [ get ] = useThree( state => [ state.get ] );
const [ set ] = useThree( state => [ state.set ] );
- const contextTilesRenderer = useContext( TilesRendererContext );
- const appliedTilesRenderer = tilesRenderer || contextTilesRenderer;
+ const ellipsoidContext = useContext( EllipsoidContext );
const appliedCamera = camera || defaultCamera || null;
const appliedScene = scene || defaultScene || null;
const appliedDomElement = domElement || gl.domElement || null;
- const appliedEllipsoid = ellipsoid || appliedTilesRenderer?.ellipsoid || null;
- const appliedEllipsoidFrame = ellipsoidFrame || appliedTilesRenderer?.group || null;
+ const appliedEllipsoid = ellipsoid || ellipsoidContext?.ellipsoid || null;
+ const appliedEllipsoidFrame = ellipsoidFrame || ellipsoidContext?.frame || null;
// create a controls instance
const controls = useMemo( () => {
diff --git a/src/r3f/components/CompassGizmo.jsx b/src/r3f/components/CompassGizmo.jsx
index 828084221..324d76d77 100644
--- a/src/r3f/components/CompassGizmo.jsx
+++ b/src/r3f/components/CompassGizmo.jsx
@@ -1,7 +1,7 @@
import { createPortal, useFrame, useThree } from '@react-three/fiber';
import { useContext, useEffect, useMemo, useRef, useState } from 'react';
import { BackSide, Matrix4, OrthographicCamera, Ray, Scene, Vector3 } from 'three';
-import { TilesRendererContext } from './TilesRenderer.jsx';
+import { EllipsoidContext } from './TilesRenderer.jsx';
// Based in part on @pmndrs/drei's Gizmo component
@@ -152,7 +152,7 @@ function CompassGraphic( { northColor = 0xEF5350, southColor = 0xFFFFFF } ) {
export function CompassGizmo( { children, overrideRenderLoop, mode = '3d', margin = 10, scale = 35, visible = true, ...rest } ) {
const [ defaultCamera, defaultScene, size ] = useThree( state => [ state.camera, state.scene, state.size ] );
- const tiles = useContext( TilesRendererContext );
+ const ellipsoidContext = useContext( EllipsoidContext );
const groupRef = useRef( null );
const scene = useMemo( () => {
@@ -175,22 +175,24 @@ export function CompassGizmo( { children, overrideRenderLoop, mode = '3d', margi
useFrame( () => {
- if ( tiles === null || groupRef.current === null ) {
+ const ellipsoid = ellipsoidContext?.ellipsoid;
+ const frame = ellipsoidContext?.frame;
+
+ if ( ( ! ellipsoid || ! frame ) || groupRef.current === null ) {
return null;
}
- const { ellipsoid } = tiles;
const group = groupRef.current;
// get the ENU frame in world space
- getCameraFocusPoint( defaultCamera, ellipsoid, tiles.group, _pos ).applyMatrix4( tiles.group.matrixWorldInverse );
+ getCameraFocusPoint( defaultCamera, ellipsoid, frame, _pos ).applyMatrix4( frame.matrixWorldInverse );
ellipsoid.getPositionToCartographic( _pos, _cart );
ellipsoid
.getEastNorthUpFrame( _cart.lat, _cart.lon, 0, _enuMatrix )
- .premultiply( tiles.group.matrixWorld );
+ .premultiply( frame.matrixWorld );
// get the camera orientation in the local ENU frame
_enuMatrix.invert();
diff --git a/src/r3f/components/TilesRenderer.jsx b/src/r3f/components/TilesRenderer.jsx
index 2ae7e9c6e..cb08faa32 100644
--- a/src/r3f/components/TilesRenderer.jsx
+++ b/src/r3f/components/TilesRenderer.jsx
@@ -1,4 +1,4 @@
-import { createContext, useContext, useEffect, useRef, forwardRef, useCallback, useState, useLayoutEffect, useReducer } from 'react';
+import { createContext, useMemo, useContext, useEffect, useRef, forwardRef, useCallback, useState, useLayoutEffect, useReducer } from 'react';
import { useThree, useFrame } from '@react-three/fiber';
import { Object3D } from 'three';
import { TilesRenderer as TilesRendererImpl, WGS84_ELLIPSOID } from '3d-tiles-renderer/three';
@@ -10,6 +10,9 @@ import { useApplyRefs } from '../utilities/useApplyRefs.js';
export const TilesRendererContext = createContext( null );
export const TilesPluginContext = createContext( null );
+// context for accessing just ellipsoid and frame data
+export const EllipsoidContext = createContext( null );
+
// group that matches the transform of the tileset root group
function TileSetRoot( { children } ) {
@@ -284,6 +287,16 @@ export const TilesRenderer = forwardRef( function TilesRenderer( props, ref ) {
// assign options recursively
useDeepOptions( tiles, options );
+ const ellipsoidContextValue = useMemo( () => {
+
+ if ( ! tiles ) return null;
+
+ return {
+ ellipsoid: tiles.ellipsoid,
+ frame: tiles.group,
+ };
+
+ }, [ tiles?.ellipsoid, tiles?.group ] );
// only render out the tiles once the instance and context are ready
if ( ! tiles ) {
@@ -295,9 +308,11 @@ export const TilesRenderer = forwardRef( function TilesRenderer( props, ref ) {
return <>
-
- { children }
-
+
+
+ { children }
+
+
>;