Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions src/r3f/components/CameraControls.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 ] );
Expand All @@ -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( () => {
Expand Down
14 changes: 8 additions & 6 deletions src/r3f/components/CompassGizmo.jsx
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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( () => {

Expand All @@ -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();
Expand Down
23 changes: 19 additions & 4 deletions src/r3f/components/TilesRenderer.jsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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 } ) {

Expand Down Expand Up @@ -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 ) {
Expand All @@ -295,9 +308,11 @@ export const TilesRenderer = forwardRef( function TilesRenderer( props, ref ) {
return <>
<primitive object={ tiles.group } { ...group } />
<TilesRendererContext.Provider value={ tiles }>
<TileSetRoot>
{ children }
</TileSetRoot>
<EllipsoidContext.Provider value={ ellipsoidContextValue }>
<TileSetRoot>
{ children }
</TileSetRoot>
</EllipsoidContext.Provider>
</TilesRendererContext.Provider>
</>;

Expand Down
Loading