From 2167c747b49f2f515447bc48fe693621c2d8853f Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 20 May 2026 09:29:46 +0900 Subject: [PATCH 01/12] EnvironmentControls: Add flight support --- example/three/index.js | 55 ++-- .../three/src/controls/FlyOrbitControls.js | 279 ------------------ .../controls/EnvironmentControls.d.ts | 5 + .../renderer/controls/EnvironmentControls.js | 116 +++++++- 4 files changed, 145 insertions(+), 310 deletions(-) delete mode 100644 example/three/src/controls/FlyOrbitControls.js diff --git a/example/three/index.js b/example/three/index.js index 55f6f6cb8..c61d7deff 100644 --- a/example/three/index.js +++ b/example/three/index.js @@ -1,5 +1,6 @@ import { TilesRenderer, + EnvironmentControls, } from '3d-tiles-renderer'; import { DebugTilesPlugin, @@ -24,7 +25,6 @@ import { OrthographicCamera, Sphere, } from 'three'; -import { FlyOrbitControls } from './src/controls/FlyOrbitControls.js'; import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'; import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js'; import { KTX2Loader } from 'three/addons/loaders/KTX2Loader.js'; @@ -144,6 +144,7 @@ function init() { camera = new PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 ); camera.position.set( 400, 400, 400 ); + camera.lookAt( 0, 0, 0 ); cameraHelper = new CameraHelper( camera ); scene.add( cameraHelper ); @@ -168,10 +169,12 @@ function init() { secondRenderer.domElement.style.outline = '#0f1416 solid 2px'; secondRenderer.domElement.tabIndex = 1; - secondControls = new FlyOrbitControls( secondCamera, secondRenderer.domElement ); - secondControls.screenSpacePanning = false; + secondControls = new EnvironmentControls( null, secondCamera, secondRenderer.domElement ); + secondControls.enableFlight = true; + secondControls.flightSpeed = 200; secondControls.minDistance = 1; secondControls.maxDistance = 5000; + secondControls.useFallbackPlane = false; secondCameraHelper = new CameraHelper( secondCamera ); scene.add( secondCameraHelper ); @@ -192,16 +195,20 @@ function init() { thirdPersonRenderer.domElement.style.bottom = '5px'; thirdPersonRenderer.domElement.tabIndex = 1; - thirdPersonControls = new FlyOrbitControls( thirdPersonCamera, thirdPersonRenderer.domElement ); - thirdPersonControls.screenSpacePanning = false; + thirdPersonControls = new EnvironmentControls( null, thirdPersonCamera, thirdPersonRenderer.domElement ); + thirdPersonControls.enableFlight = true; + thirdPersonControls.flightSpeed = 200; thirdPersonControls.minDistance = 1; thirdPersonControls.maxDistance = 5000; + thirdPersonControls.useFallbackPlane = false; // controls - controls = new FlyOrbitControls( camera, renderer.domElement ); - controls.screenSpacePanning = false; + controls = new EnvironmentControls( null, camera, renderer.domElement ); + controls.enableFlight = true; + controls.flightSpeed = 200; controls.minDistance = 1; controls.maxDistance = 5000; + controls.useFallbackPlane = false; // lights const dirLight = new DirectionalLight( 0xffffff, 4 ); @@ -217,6 +224,10 @@ function init() { offsetParent = new Group(); scene.add( offsetParent ); + controls.setScene( offsetParent ); + secondControls.setScene( offsetParent ); + thirdPersonControls.setScene( offsetParent ); + geospatialRotationParent = new Group(); offsetParent.add( geospatialRotationParent ); @@ -405,28 +416,12 @@ function onPointerUp( e ) { if ( results.length ) { const object = results[ 0 ].object; - const info = tiles.getPluginByName( 'DEBUG_TILES_PLUGIN' ).getTileInformationFromActiveObject( object ); + const tile = tiles.getPluginByName( 'DEBUG_TILES_PLUGIN' ).getTileFromObject3D( object ); let str = ''; - for ( const key in info ) { - - let val = info[ key ]; - if ( typeof val === 'number' ) { - - val = Math.floor( val * 1e5 ) / 1e5; - - } - - let name = key; - while ( name.length < 20 ) { - - name += ' '; - - } - - str += `${ name } : ${ val }\n`; - - } + str += `geometricError : ${ tile.geometricError.toFixed( 3 ) }\n`; + str += `error : ${ tile.traversal.error.toFixed( 3 ) }\n`; + str += `refine : ${ tile.refine }\n`; console.log( str ); @@ -439,7 +434,7 @@ function updateOrthoCamera() { orthoCamera.position.copy( camera.position ); orthoCamera.rotation.copy( camera.rotation ); - const scale = camera.position.distanceTo( controls.target ) / 2.0; + const scale = camera.position.distanceTo( controls.pivotPoint ) / 2.0; let aspect = window.innerWidth / window.innerHeight; if ( params.showSecondView ) { @@ -590,6 +585,10 @@ function animate() { window.tiles = tiles; if ( params.enableUpdate ) { + controls.update(); + secondControls.update(); + thirdPersonControls.update(); + secondCamera.updateMatrixWorld(); camera.updateMatrixWorld(); orthoCamera.updateMatrixWorld(); diff --git a/example/three/src/controls/FlyOrbitControls.js b/example/three/src/controls/FlyOrbitControls.js deleted file mode 100644 index ccd844c88..000000000 --- a/example/three/src/controls/FlyOrbitControls.js +++ /dev/null @@ -1,279 +0,0 @@ -import { Clock, Vector3, Vector4 } from 'three'; -import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; - -const changeEvent = { type: 'fly-change' }; -const startEvent = { type: 'fly-start' }; -const endEvent = { type: 'fly-end' }; -const tempVector = new Vector4( 0, 0, 0, 0 ); -export class FlyOrbitControls extends OrbitControls { - - constructor( camera, domElement ) { - - // Disable use of shift key so we can use it for acceleration - const disableShiftKeyCallback = e => { - - if ( this.enabled ) { - - Object.defineProperty( e, 'shiftKey', { get() { - - return false; - - } } ); - - } - - }; - - domElement.addEventListener( 'pointerdown', disableShiftKeyCallback ); - - super( camera, domElement ); - - this.enableKeys = false; - this.enableFlight = true; - this.baseSpeed = 1; - this.fastSpeed = 4; - this.forwardKey = 'w'; - this.backKey = 's'; - this.leftKey = 'a'; - this.rightKey = 'd'; - this.upKey = 'q'; - this.downKey = 'e'; - this.fastKey = 'shift'; - - let fastHeld = false; - let forwardHeld = false; - let backHeld = false; - let leftHeld = false; - let rightHeld = false; - let upHeld = false; - let downHeld = false; - - let originalDistance = 0; - let originalMinDistance = 0; - let originalMaxDistance = 0; - let rafHandle = - 1; - const originalTarget = new Vector3(); - const clock = new Clock(); - - const endFlight = () => { - - if ( rafHandle !== - 1 ) { - - // cancel the animation playing - cancelAnimationFrame( rafHandle ); - rafHandle = - 1; - - // store the original distances for the controls - this.minDistance = originalMinDistance; - this.maxDistance = originalMaxDistance; - - const targetDistance = Math.min( originalDistance, camera.position.distanceTo( originalTarget ) ); - tempVector - .set( 0, 0, - 1, 0 ) - .applyMatrix4( camera.matrixWorld ); - this - .target - .copy( camera.position ) - .addScaledVector( tempVector, targetDistance ); - - this.dispatchEvent( endEvent ); - - } - - }; - - const updateFlight = () => { - - if ( ! this.enabled || ! this.enableFlight ) { - - return; - - } - - rafHandle = requestAnimationFrame( updateFlight ); - - // get the direction - tempVector.set( 0, 0, 0, 0 ); - if ( forwardHeld ) tempVector.z -= 1; - if ( backHeld ) tempVector.z += 1; - if ( leftHeld ) tempVector.x -= 1; - if ( rightHeld ) tempVector.x += 1; - if ( upHeld ) tempVector.y += 1; - if ( downHeld ) tempVector.y -= 1; - tempVector.applyMatrix4( camera.matrixWorld ); - - // apply the movement - const delta = 60 * clock.getDelta(); - const speed = fastHeld ? this.fastSpeed : this.baseSpeed; - camera - .position - .addScaledVector( tempVector, speed * delta ); - this - .target - .addScaledVector( tempVector, speed * delta ); - - this.dispatchEvent( changeEvent ); - - }; - - const keyDownCallback = e => { - - const key = e.key.toLowerCase(); - - if ( rafHandle === - 1 ) { - - originalMaxDistance = this.maxDistance; - originalMinDistance = this.minDistance; - originalDistance = camera.position.distanceTo( this.target ); - originalTarget.copy( this.target ); - - } - - switch ( key ) { - - case this.forwardKey: - forwardHeld = true; - break; - case this.backKey: - backHeld = true; - break; - case this.leftKey: - leftHeld = true; - break; - case this.rightKey: - rightHeld = true; - break; - case this.upKey: - upHeld = true; - break; - case this.downKey: - downHeld = true; - break; - case this.fastKey: - fastHeld = true; - break; - - } - - switch ( key ) { - - case this.fastKey: - case this.forwardKey: - case this.backKey: - case this.leftKey: - case this.rightKey: - case this.upKey: - case this.downKey: - e.stopPropagation(); - e.preventDefault(); - - } - - if ( forwardHeld || backHeld || leftHeld || rightHeld || upHeld || downHeld || fastHeld ) { - - this.minDistance = 0.01; - this.maxDistance = 0.01; - - // Move the orbit target out to just in front of the camera - tempVector - .set( 0, 0, - 1, 0 ) - .applyMatrix4( camera.matrixWorld ); - this - .target - .copy( camera.position ) - .addScaledVector( tempVector, 0.01 ); - - if ( rafHandle === - 1 ) { - - // start the flight and reset the clock - this.dispatchEvent( startEvent ); - clock.getDelta(); - updateFlight(); - - } - - } - - }; - - const keyUpCallback = e => { - - const key = e.key.toLowerCase(); - - switch ( key ) { - - case this.fastKey: - case this.forwardKey: - case this.backKey: - case this.leftKey: - case this.rightKey: - case this.upKey: - case this.downKey: - e.stopPropagation(); - e.preventDefault(); - - } - - switch ( key ) { - - case this.forwardKey: - forwardHeld = false; - break; - case this.backKey: - backHeld = false; - break; - case this.leftKey: - leftHeld = false; - break; - case this.rightKey: - rightHeld = false; - break; - case this.upKey: - upHeld = false; - break; - case this.downKey: - downHeld = false; - break; - case this.fastKey: - fastHeld = false; - break; - - } - - if ( ! ( forwardHeld || backHeld || leftHeld || rightHeld || upHeld || downHeld || fastHeld ) ) { - - endFlight(); - - } - - }; - - const blurCallback = () => { - - endFlight(); - - }; - - this.blurCallback = blurCallback; - this.keyDownCallback = keyDownCallback; - this.keyUpCallback = keyUpCallback; - this.disableShiftKeyCallback = disableShiftKeyCallback; - - this.domElement.addEventListener( 'blur', blurCallback ); - this.domElement.addEventListener( 'keydown', keyDownCallback ); - this.domElement.addEventListener( 'keyup', keyUpCallback ); - - } - - dispose() { - - super.dispose(); - - this.domElement.removeEventListener( 'blur', this.blurCallback ); - this.domElement.removeEventListener( 'keydown', this.keyDownCallback ); - this.domElement.removeEventListener( 'keyup', this.keyUpCallback ); - this.domElement.removeEventListener( 'pointerdown', this.disableShiftKeyCallback ); - - } - -} diff --git a/src/three/renderer/controls/EnvironmentControls.d.ts b/src/three/renderer/controls/EnvironmentControls.d.ts index a7155f823..491a9aa3e 100644 --- a/src/three/renderer/controls/EnvironmentControls.d.ts +++ b/src/three/renderer/controls/EnvironmentControls.d.ts @@ -35,6 +35,11 @@ export class EnvironmentControls extends EventDispatcher { + + this._keysDown.add( e.key.toLowerCase() ); + + }; + + const keyupCallback = e => { + + this._keysDown.delete( e.key.toLowerCase() ); + + }; + + const blurCallback = () => { + + this._keysDown.clear(); + + }; + + window.addEventListener( 'keydown', keydownCallback ); + window.addEventListener( 'keyup', keyupCallback ); + window.addEventListener( 'blur', blurCallback ); + this._detachCallback = () => { domElement.removeEventListener( 'contextmenu', contextMenuCallback ); @@ -631,6 +675,10 @@ export class EnvironmentControls extends EventDispatcher { document.removeEventListener( 'pointerup', pointerupCallback ); document.removeEventListener( 'pointerleave', pointerleaveCallback ); + window.removeEventListener( 'keydown', keydownCallback ); + window.removeEventListener( 'keyup', keyupCallback ); + window.removeEventListener( 'blur', blurCallback ); + }; } @@ -850,10 +898,19 @@ export class EnvironmentControls extends EventDispatcher { } + const didFly = this._updateFlight( deltaTime ); + if ( didFly ) { + + this.dragInertia.set( 0, 0, 0 ); + this.rotationInertia.set( 0, 0, 0 ); + this.dispatchEvent( _changeEvent ); + + } + // update the up direction based on where the camera moved to // if using an orthographic camera then rotate around drag pivot // reuse the "hit" information since it can be slow to perform multiple hits - const hit = camera.isOrthographicCamera ? null : adjustHeight && this._getPointBelowCamera() || null; + const hit = camera.isOrthographicCamera ? null : ( adjustHeight && ! didFly && this._getPointBelowCamera() ) || null; this.getCameraUpDirection( _localUp ); this._setFrame( _localUp ); @@ -893,7 +950,7 @@ export class EnvironmentControls extends EventDispatcher { this.pointerTracker.updateFrame(); - if ( adjustCameraRotation && autoAdjustCameraRotation ) { + if ( ( adjustCameraRotation && autoAdjustCameraRotation ) || didFly ) { this.getCameraUpDirection( _localUp ); this._alignCameraUp( _localUp, 1 ); @@ -901,7 +958,6 @@ export class EnvironmentControls extends EventDispatcher { this.getCameraUpDirection( _localUp ); this._clampRotation( _localUp ); - } } @@ -1057,6 +1113,60 @@ export class EnvironmentControls extends EventDispatcher { } + _updateFlight( deltaTime ) { + + const { + camera, + enableFlight, + flightSpeed, + flightSpeedMultiplier, + _keysDown, + } = this; + + if ( ! enableFlight ) { + + return false; + + } + + // get key state + const forward = _keysDown.has( 'w' ) || _keysDown.has( 'arrowup' ); + const back = _keysDown.has( 's' ) || _keysDown.has( 'arrowdown' ); + const left = _keysDown.has( 'a' ) || _keysDown.has( 'arrowleft' ); + const right = _keysDown.has( 'd' ) || _keysDown.has( 'arrowright' ); + const up = _keysDown.has( 'q' ); + const down = _keysDown.has( 'e' ); + + // calculate speed + const mult = _keysDown.has( 'shift' ) ? flightSpeedMultiplier : 1; + const speed = mult * flightSpeed * deltaTime; + + // calculate direction + _flightDir.set( + ( right ? 1 : 0 ) - ( left ? 1 : 0 ), + ( up ? 1 : 0 ) - ( down ? 1 : 0 ), + ( back ? 1 : 0 ) - ( forward ? 1 : 0 ), + ); + + // early out if there's no flight direction + if ( _flightDir.lengthSq() === 0 ) { + + return false; + + } + + // fly relative to the camera direction + _flightDir + .normalize() + .transformDirection( camera.matrixWorld ); + + camera.position.addScaledVector( _flightDir, speed ); + camera.updateMatrixWorld(); + + return true; + + } + _updateZoom() { const { From 4c685d70aad201a57dce64fb259fb948c4608d46 Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 20 May 2026 09:53:44 +0900 Subject: [PATCH 02/12] Add free rotation --- .../renderer/controls/EnvironmentControls.js | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/three/renderer/controls/EnvironmentControls.js b/src/three/renderer/controls/EnvironmentControls.js index 69ab76d9e..e1551f0a9 100644 --- a/src/three/renderer/controls/EnvironmentControls.js +++ b/src/three/renderer/controls/EnvironmentControls.js @@ -19,6 +19,7 @@ export const DRAG = 1; export const ROTATE = 2; export const ZOOM = 3; export const WAITING = 4; +export const FREE_ROTATE = 5; const DRAG_PLANE_THRESHOLD = 0.05; const DRAG_UP_THRESHOLD = 0.025; @@ -410,6 +411,21 @@ export class EnvironmentControls extends EventDispatcher { } + // flight mode with shift held: free-look around the camera origin, skip raycasting + if ( + this.enableFlight && + ! pointerTracker.isPointerTouch() && ( + pointerTracker.isRightClicked() || + pointerTracker.isLeftClicked() && e.shiftKey + ) + ) { + + pivotPoint.copy( camera.position ); + this.setState( FREE_ROTATE ); + return; + + } + // find the hit point const hit = this._raycast( raycaster ); if ( hit ) { @@ -877,7 +893,7 @@ export class EnvironmentControls extends EventDispatcher { this._updatePosition( deltaTime ); this._updateRotation( deltaTime ); - if ( state === DRAG || state === ROTATE ) { + if ( state === DRAG || state === ROTATE || state === FREE_ROTATE ) { _forward.set( 0, 0, - 1 ).transformDirection( camera.matrixWorld ); this.inertiaTargetDistance = _vec.copy( pivotPoint ).sub( camera.position ).dot( _forward ); @@ -917,7 +933,7 @@ export class EnvironmentControls extends EventDispatcher { // when dragging the camera and drag point may be moved // to accommodate terrain so we try to move it back down // to the original point. - if ( ( this.state === DRAG || this.state === ROTATE ) && this.actionHeightOffset !== 0 ) { + if ( ( this.state === DRAG || this.state === ROTATE || this.state === FREE_ROTATE ) && this.actionHeightOffset !== 0 ) { const { actionHeightOffset } = this; camera.position.addScaledVector( up, - actionHeightOffset ); @@ -1483,7 +1499,14 @@ export class EnvironmentControls extends EventDispatcher { rotationInertia, } = this; - if ( state === ROTATE ) { + if ( state === ROTATE || state === FREE_ROTATE ) { + + // keep the pivot glued to the camera for first-person look-around + if ( state === FREE_ROTATE ) { + + pivotPoint.copy( this.camera.position ); + + } // get the rotation motion and divide out the container height to normalize for element size pointerTracker.getCenterPoint( _pointer ); @@ -1689,7 +1712,7 @@ export class EnvironmentControls extends EventDispatcher { // calculate the active point let fixedPoint = null; - if ( state === DRAG || state === ROTATE ) { + if ( state === DRAG || state === ROTATE || state === FREE_ROTATE ) { fixedPoint = _pos.copy( pivotPoint ); @@ -1770,7 +1793,7 @@ export class EnvironmentControls extends EventDispatcher { // calculate the active point let fixedPoint = null; - if ( state === DRAG || state === ROTATE ) { + if ( state === DRAG || state === ROTATE || state === FREE_ROTATE ) { fixedPoint = _pos.copy( pivotPoint ); From 7be9f2e8343ea805775befd3fd0f096aec6c9100 Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 20 May 2026 10:46:01 +0900 Subject: [PATCH 03/12] Updates --- example/three/googleMapsExample.js | 3 + src/three/renderer/API.md | 30 ++++++++ .../renderer/controls/EnvironmentControls.js | 70 +++++++++++++++---- src/three/renderer/controls/GlobeControls.js | 61 +++++++++++++++- 4 files changed, 149 insertions(+), 15 deletions(-) diff --git a/example/three/googleMapsExample.js b/example/three/googleMapsExample.js index 533a52248..dfea2d00a 100644 --- a/example/three/googleMapsExample.js +++ b/example/three/googleMapsExample.js @@ -135,6 +135,9 @@ function init() { // controls controls = new GlobeControls( scene, transition.camera, renderer.domElement, null ); controls.enableDamping = true; + controls.enableFlight = true; + controls.flightSpeed = 0.5; + controls.maxAltitude = Math.PI / 2; // initialize tiles reinstantiateTiles(); diff --git a/src/three/renderer/API.md b/src/three/renderer/API.md index 17074c301..8045c311d 100644 --- a/src/three/renderer/API.md +++ b/src/three/renderer/API.md @@ -600,6 +600,36 @@ useFallbackPlane: boolean When true, the fallback plane is used when raycasting misses scene geometry. Default is true. +### .enableFlight + +```js +enableFlight: boolean +``` + +When true, enables keyboard flight: W/A/S/D and arrow keys move forward/back/strafe, Q/E move +up/down, and Shift multiplies speed by `flightSpeedMultiplier`. Right-click or Shift+left-click +enters free-look mode, rotating the camera in place without requiring a surface hit. Only +supported for perspective cameras. Default is false. + + +### .flightSpeed + +```js +flightSpeed: number +``` + +Base camera speed in world units per second during keyboard flight. Default is 10. + + +### .flightSpeedMultiplier + +```js +flightSpeedMultiplier: number +``` + +Speed multiplier applied when the fast key is held during flight. Default is 4. + + ### .constructor ```js diff --git a/src/three/renderer/controls/EnvironmentControls.js b/src/three/renderer/controls/EnvironmentControls.js index e1551f0a9..c04f0f6d3 100644 --- a/src/three/renderer/controls/EnvironmentControls.js +++ b/src/three/renderer/controls/EnvironmentControls.js @@ -192,13 +192,12 @@ export class EnvironmentControls extends EventDispatcher { */ this.useFallbackPlane = true; - // settings for GlobeControls - this.scaleZoomOrientationAtEdges = false; - this.autoAdjustCameraRotation = true; - // flight /** - * When true, WASD/QE keys move the camera freely through space. Default is false. + * When true, enables keyboard flight: W/A/S/D and arrow keys move forward/back/strafe, Q/E move + * up/down, and Shift multiplies speed by `flightSpeedMultiplier`. Right-click or Shift+left-click + * enters free-look mode, rotating the camera in place without requiring a surface hit. Only + * supported for perspective cameras. Default is false. * @type {boolean} */ this.enableFlight = false; @@ -215,7 +214,10 @@ export class EnvironmentControls extends EventDispatcher { */ this.flightSpeedMultiplier = 4; - this._keysDown = new Set(); + + // settings for GlobeControls + this.scaleZoomOrientationAtEdges = false; + this.autoAdjustCameraRotation = true; // internal state this.state = NONE; @@ -252,6 +254,8 @@ export class EnvironmentControls extends EventDispatcher { this.up = new Vector3( 0, 1, 0 ); this._lastTime = performance.now(); + this._keysDown = new Set(); + this._detachCallback = null; this._upInitialized = false; this._lastUsedState = NONE; @@ -370,6 +374,8 @@ export class EnvironmentControls extends EventDispatcher { scene, pivotPoint, enabled, + enableFlight, + _keysDown, } = this; // init the pointer @@ -411,12 +417,25 @@ export class EnvironmentControls extends EventDispatcher { } - // flight mode with shift held: free-look around the camera origin, skip raycasting + // free-look around the camera origin when flight is active with any flight key held, or shift/right-click + const anyFlightKey = + _keysDown.has( 'w' ) || + _keysDown.has( 's' ) || + _keysDown.has( 'a' ) || + _keysDown.has( 'd' ) || + _keysDown.has( 'q' ) || + _keysDown.has( 'e' ) || + _keysDown.has( 'arrowup' ) || + _keysDown.has( 'arrowdown' ) || + _keysDown.has( 'arrowleft' ) || + _keysDown.has( 'arrowright' ) || + _keysDown.has( 'shift' ); + if ( - this.enableFlight && + enableFlight && anyFlightKey && ! pointerTracker.isPointerTouch() && ( pointerTracker.isRightClicked() || - pointerTracker.isLeftClicked() && e.shiftKey + pointerTracker.isLeftClicked() ) ) { @@ -661,7 +680,28 @@ export class EnvironmentControls extends EventDispatcher { const keydownCallback = e => { - this._keysDown.add( e.key.toLowerCase() ); + const { _keysDown, state } = this; + + _keysDown.add( e.key.toLowerCase() ); + + const anyFlightKey = + _keysDown.has( 'w' ) || + _keysDown.has( 's' ) || + _keysDown.has( 'a' ) || + _keysDown.has( 'd' ) || + _keysDown.has( 'q' ) || + _keysDown.has( 'e' ) || + _keysDown.has( 'arrowup' ) || + _keysDown.has( 'arrowdown' ) || + _keysDown.has( 'arrowleft' ) || + _keysDown.has( 'arrowright' ); + + if ( anyFlightKey && state !== FREE_ROTATE ) { + + this.resetState(); + + } + }; @@ -1129,6 +1169,12 @@ export class EnvironmentControls extends EventDispatcher { } + _getFlightSpeedScale() { + + return 1; + + } + _updateFlight( deltaTime ) { const { @@ -1139,7 +1185,7 @@ export class EnvironmentControls extends EventDispatcher { _keysDown, } = this; - if ( ! enableFlight ) { + if ( ! enableFlight || camera.isOrthographicCamera ) { return false; @@ -1155,7 +1201,7 @@ export class EnvironmentControls extends EventDispatcher { // calculate speed const mult = _keysDown.has( 'shift' ) ? flightSpeedMultiplier : 1; - const speed = mult * flightSpeed * deltaTime; + const speed = mult * flightSpeed * this._getFlightSpeedScale() * deltaTime; // calculate direction _flightDir.set( diff --git a/src/three/renderer/controls/GlobeControls.js b/src/three/renderer/controls/GlobeControls.js index 48810a2dd..99a562463 100644 --- a/src/three/renderer/controls/GlobeControls.js +++ b/src/three/renderer/controls/GlobeControls.js @@ -8,7 +8,7 @@ import { Ray, Group, } from 'three'; -import { DRAG, ZOOM, EnvironmentControls, NONE } from './EnvironmentControls.js'; +import { DRAG, ZOOM, FREE_ROTATE, EnvironmentControls, NONE } from './EnvironmentControls.js'; import { makeRotateAroundPoint, adjustedPointerToCoords, setRaycasterFromCamera } from './utils.js'; import { Ellipsoid } from '../math/Ellipsoid.js'; import { WGS84_ELLIPSOID } from '../math/GeoConstants.js'; @@ -279,7 +279,7 @@ export class GlobeControls extends EnvironmentControls { this.adjustCamera( camera ); // align the camera up vector if the camera as updated - if ( adjustCameraRotation && this._isNearControls() ) { + if ( adjustCameraRotation && ( this._isNearControls() || this.state === FREE_ROTATE ) ) { this.getCameraUpDirection( _globalUp ); this._alignCameraUp( _globalUp, 1 ); @@ -459,6 +459,54 @@ export class GlobeControls extends EnvironmentControls { } + _getFlightSpeedScale() { + + // Scale speed proportionally to altitude so movement feels consistent at any distance. + // The 1000 m floor prevents movement becoming imperceptibly slow near the surface. + const altitude = this.getDistanceToCenter() - this._getMaxWorldRadius(); + return 2 * Math.max( altitude, 1000 ); + + } + + _updateFlight( deltaTime ) { + + const { camera } = this; + + const didFly = super._updateFlight( deltaTime ); + if ( didFly ) { + + // prevent flying past the point where the globe would be too small, just like mouse zoom. + const maxDistance = this._getMaxPerspectiveDistance(); + const distToCenter = this.getDistanceToCenter(); + if ( distToCenter > maxDistance ) { + + this.getVectorToCenter( _vec ).normalize(); + camera.position.addScaledVector( _vec, distToCenter - maxDistance ); + camera.updateMatrixWorld(); + + } + + // Outside the near-controls zone (high altitude / space view), gently nudge the + // camera to keep the globe centered and the horizon level — matching the behavior + // of scroll-zoom at the same distance. Alpha scales from 0 at the transition + // threshold to full strength at maxDistance. + if ( ! this._isNearControls() ) { + + const distanceAlpha = MathUtils.clamp( + MathUtils.mapLinear( this.getDistanceToCenter(), this._getPerspectiveTransitionDistance(), maxDistance, 0, 1 ), + 0, 1, + ); + this._tiltTowardsCenter( 0.02 * distanceAlpha ); + this._alignCameraUpToNorth( 0.01 * distanceAlpha ); + + } + + } + + return didFly; + + } + _updatePosition( deltaTime ) { if ( this.state === DRAG ) { @@ -540,6 +588,14 @@ export class GlobeControls extends EnvironmentControls { // disable rotation once we're outside the control transition _updateRotation( ...args ) { + // FREE_ROTATE is always allowed regardless of globe proximity + if ( this.state === FREE_ROTATE ) { + + super._updateRotation( ...args ); + return; + + } + if ( this._rotationMode === 1 || this._isNearControls() ) { this._rotationMode = 1; @@ -552,7 +608,6 @@ export class GlobeControls extends EnvironmentControls { } - } _updateZoom() { From bf36de521daab812cd4e7e82198ae4be8264f8a4 Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 20 May 2026 11:38:57 +0900 Subject: [PATCH 04/12] fix focus --- .../renderer/controls/EnvironmentControls.js | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/three/renderer/controls/EnvironmentControls.js b/src/three/renderer/controls/EnvironmentControls.js index c04f0f6d3..4f829dc80 100644 --- a/src/three/renderer/controls/EnvironmentControls.js +++ b/src/three/renderer/controls/EnvironmentControls.js @@ -340,6 +340,15 @@ export class EnvironmentControls extends EventDispatcher { this.pointerTracker.domElement = domElement; domElement.style.touchAction = 'none'; + // Ensure the element can receive keyboard focus. If no tabindex attribute is + // present, set it to -1 so the element is programmatically focusable without + // being inserted into the tab order. + if ( ! domElement.hasAttribute( 'tabindex' ) ) { + + domElement.tabIndex = - 1; + + } + const contextMenuCallback = e => { // exit early if the controls are disabled @@ -355,15 +364,6 @@ export class EnvironmentControls extends EventDispatcher { const pointerdownCallback = e => { - // exit early if the controls are disabled - if ( ! this.enabled ) { - - return; - - } - - e.preventDefault(); - const { camera, raycaster, @@ -378,6 +378,17 @@ export class EnvironmentControls extends EventDispatcher { _keysDown, } = this; + + // exit early if the controls are disabled + if ( ! this.enabled ) { + + return; + + } + + e.preventDefault(); + domElement.focus(); + // init the pointer pointerTracker.addPointer( e ); this.needsUpdate = true; @@ -717,7 +728,7 @@ export class EnvironmentControls extends EventDispatcher { }; - window.addEventListener( 'keydown', keydownCallback ); + domElement.addEventListener( 'keydown', keydownCallback ); window.addEventListener( 'keyup', keyupCallback ); window.addEventListener( 'blur', blurCallback ); @@ -731,7 +742,7 @@ export class EnvironmentControls extends EventDispatcher { document.removeEventListener( 'pointerup', pointerupCallback ); document.removeEventListener( 'pointerleave', pointerleaveCallback ); - window.removeEventListener( 'keydown', keydownCallback ); + domElement.removeEventListener( 'keydown', keydownCallback ); window.removeEventListener( 'keyup', keyupCallback ); window.removeEventListener( 'blur', blurCallback ); From 558f48b4756da689244f000a47083e58acad0e0b Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 20 May 2026 11:44:59 +0900 Subject: [PATCH 05/12] Remove lines --- src/three/renderer/controls/EnvironmentControls.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/three/renderer/controls/EnvironmentControls.js b/src/three/renderer/controls/EnvironmentControls.js index 4f829dc80..01c42e5fe 100644 --- a/src/three/renderer/controls/EnvironmentControls.js +++ b/src/three/renderer/controls/EnvironmentControls.js @@ -192,7 +192,6 @@ export class EnvironmentControls extends EventDispatcher { */ this.useFallbackPlane = true; - // flight /** * When true, enables keyboard flight: W/A/S/D and arrow keys move forward/back/strafe, Q/E move * up/down, and Shift multiplies speed by `flightSpeedMultiplier`. Right-click or Shift+left-click @@ -214,7 +213,6 @@ export class EnvironmentControls extends EventDispatcher { */ this.flightSpeedMultiplier = 4; - // settings for GlobeControls this.scaleZoomOrientationAtEdges = false; this.autoAdjustCameraRotation = true; From 9adc50025e2adca45bcdd2bf7c771e3bb60b5f70 Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 20 May 2026 11:46:23 +0900 Subject: [PATCH 06/12] Stylistic --- src/three/renderer/controls/EnvironmentControls.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/three/renderer/controls/EnvironmentControls.js b/src/three/renderer/controls/EnvironmentControls.js index 01c42e5fe..38d2f5953 100644 --- a/src/three/renderer/controls/EnvironmentControls.js +++ b/src/three/renderer/controls/EnvironmentControls.js @@ -376,7 +376,6 @@ export class EnvironmentControls extends EventDispatcher { _keysDown, } = this; - // exit early if the controls are disabled if ( ! this.enabled ) { @@ -693,6 +692,7 @@ export class EnvironmentControls extends EventDispatcher { _keysDown.add( e.key.toLowerCase() ); + // reset any activities if a key is pressed unless FREE_ROTATE is being used const anyFlightKey = _keysDown.has( 'w' ) || _keysDown.has( 's' ) || @@ -711,7 +711,6 @@ export class EnvironmentControls extends EventDispatcher { } - }; const keyupCallback = e => { From 7250d794742d1b580faa260f6a5d9458089062e8 Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 20 May 2026 12:00:32 +0900 Subject: [PATCH 07/12] Add "@default" annotations --- src/core/renderer/API.md | 7 +-- src/core/renderer/tiles/TilesRendererBase.js | 4 +- src/core/renderer/utilities/LRUCache.js | 3 +- src/core/renderer/utilities/PriorityQueue.js | 9 +-- src/three/plugins/DebugTilesPlugin.js | 1 + src/three/renderer/API.md | 55 +++++++++---------- .../controls/CameraTransitionManager.js | 15 +++-- .../renderer/controls/EnvironmentControls.js | 51 +++++++++++------ src/three/renderer/controls/GlobeControls.js | 9 ++- src/three/renderer/tiles/TilesRenderer.js | 6 +- 10 files changed, 91 insertions(+), 69 deletions(-) diff --git a/src/core/renderer/API.md b/src/core/renderer/API.md index d68cbce61..73b36bc90 100644 --- a/src/core/renderer/API.md +++ b/src/core/renderer/API.md @@ -352,7 +352,7 @@ unloadPriorityCallback: ( a: any, b: any ) => number | null ``` Comparator used to determine eviction order. Items that sort last are evicted first. -Defaults to `null` (eviction order is by last-used time). +When `null`, eviction order is by last-used time. ### .minSize @@ -573,7 +573,7 @@ priorityCallback: ( a: any, b: any ) => number | null ``` Comparator used to sort queued items. Higher-priority items should sort last -(i.e. return positive when `itemA` should run before `itemB`). Defaults to `null`. +(i.e. return positive when `itemA` should run before `itemB`). ### .sort @@ -907,9 +907,6 @@ tiles to load first. Prevents visual gaps and flashing during camera movement. Based in part on [Cesium Native tile selection](https://cesium.com/learn/cesium-native/ref-doc/selection-algorithm-details.html). -Default is `false`, which uses the previous approach of loading all parent and sibling -tiles for guaranteed smooth transitions. - > [!WARNING] > Setting is currently incompatible with plugins that split tiles and on-the-fly generate and > dispose of child tiles including the `ImageOverlayPlugin` `enableTileSplitting` setting, diff --git a/src/core/renderer/tiles/TilesRendererBase.js b/src/core/renderer/tiles/TilesRendererBase.js index b83701be2..7928fe3f4 100644 --- a/src/core/renderer/tiles/TilesRendererBase.js +++ b/src/core/renderer/tiles/TilesRendererBase.js @@ -571,14 +571,12 @@ export class TilesRendererBase { * tiles to load first. Prevents visual gaps and flashing during camera movement. * * Based in part on {@link https://cesium.com/learn/cesium-native/ref-doc/selection-algorithm-details.html Cesium Native tile selection}. - * - * Default is `false`, which uses the previous approach of loading all parent and sibling - * tiles for guaranteed smooth transitions. * @warn Setting is currently incompatible with plugins that split tiles and on-the-fly generate and * dispose of child tiles including the `ImageOverlayPlugin` `enableTileSplitting` setting, * `QuantizedMeshPlugin`, & `ImageFormatPlugin` subclasses (XYZ, TMS, etc). Any tile sets * that share caches or queues must also use the same setting. * @type {boolean} + * @default false */ this.optimizedLoadStrategy = false; diff --git a/src/core/renderer/utilities/LRUCache.js b/src/core/renderer/utilities/LRUCache.js index 47e252c83..35c263116 100644 --- a/src/core/renderer/utilities/LRUCache.js +++ b/src/core/renderer/utilities/LRUCache.js @@ -22,8 +22,9 @@ class LRUCache { /** * Comparator used to determine eviction order. Items that sort last are evicted first. - * Defaults to `null` (eviction order is by last-used time). + * When `null`, eviction order is by last-used time. * @type {UnloadPriorityCallback|null} + * @default null */ get unloadPriorityCallback() { diff --git a/src/core/renderer/utilities/PriorityQueue.js b/src/core/renderer/utilities/PriorityQueue.js index 8648f4801..2c822c031 100644 --- a/src/core/renderer/utilities/PriorityQueue.js +++ b/src/core/renderer/utilities/PriorityQueue.js @@ -60,10 +60,10 @@ export class PriorityQueue { /** * Callback used to schedule when to run jobs next, so more work doesn't happen in a - * single frame than there is time for. Defaults to `requestAnimationFrame`. Should be - * overridden in scenarios where `requestAnimationFrame` is not reliable, such as when - * running in WebXR. + * single frame than there is time for. Should be overridden in scenarios where + * `requestAnimationFrame` is not reliable, such as when running in WebXR. * @type {SchedulingCallback} + * @default requestAnimationFrame * @deprecated */ get schedulingCallback() { @@ -100,8 +100,9 @@ export class PriorityQueue { /** * Comparator used to sort queued items. Higher-priority items should sort last - * (i.e. return positive when `itemA` should run before `itemB`). Defaults to `null`. + * (i.e. return positive when `itemA` should run before `itemB`). * @type {PriorityCallback|null} + * @default null */ this.priorityCallback = null; diff --git a/src/three/plugins/DebugTilesPlugin.js b/src/three/plugins/DebugTilesPlugin.js index 36b251ece..31012de8f 100644 --- a/src/three/plugins/DebugTilesPlugin.js +++ b/src/three/plugins/DebugTilesPlugin.js @@ -262,6 +262,7 @@ export class DebugTilesPlugin { * a black-to-white gradient. Replace with a custom function to use a different color * ramp. * @type {GetDebugColorCallback} + * @default ( value, target ) => target.setRGB( value, value, value ) */ this.getDebugColor = ( value, target ) => { diff --git a/src/three/renderer/API.md b/src/three/renderer/API.md index 8045c311d..f8c636756 100644 --- a/src/three/renderer/API.md +++ b/src/three/renderer/API.md @@ -110,7 +110,7 @@ animation. Use `toggle()` to animate the transition. orthographicPositionalZoom: boolean ``` -When true, the orthographic camera position is offset backwards along the view direction so it does not clip into terrain. Default is true. +When true, the orthographic camera position is offset backwards along the view direction so it does not clip into terrain. ### .orthographicOffset @@ -119,7 +119,7 @@ When true, the orthographic camera position is offset backwards along the view d orthographicOffset: number ``` -Distance the orthographic camera is pushed back when `orthographicPositionalZoom` is true. Default is 50. +Distance the orthographic camera is pushed back when `orthographicPositionalZoom` is true. ### .fixedPoint @@ -137,7 +137,7 @@ World-space point that remains visually fixed during the transition. duration: number ``` -Duration of the animated transition in milliseconds. Default is 200. +Duration of the animated transition in milliseconds. ### .autoSync @@ -146,7 +146,7 @@ Duration of the animated transition in milliseconds. Default is 200. autoSync: boolean ``` -When true, cameras are synced automatically before each `update` call. Default is true. +When true, cameras are synced automatically before each `update` call. ### .easeFunction @@ -155,7 +155,7 @@ When true, cameras are synced automatically before each `update` call. Default i easeFunction: function ``` -Easing function applied to the raw transition alpha. Receives and returns a value in [0, 1]. Default is the identity function. +Easing function applied to the raw transition alpha. Receives and returns a value in [0, 1]. ### .constructor @@ -480,7 +480,7 @@ and inertia is cleared. cameraRadius: number ``` -Minimum camera distance above the surface in world units. Prevents clipping into terrain. Default is 5. +Minimum camera distance above the surface in world units. Prevents clipping into terrain. ### .rotationSpeed @@ -489,7 +489,7 @@ Minimum camera distance above the surface in world units. Prevents clipping into rotationSpeed: number ``` -Rotation sensitivity multiplier. Default is 1. +Rotation sensitivity multiplier. ### .minAltitude @@ -498,7 +498,7 @@ Rotation sensitivity multiplier. Default is 1. minAltitude: number ``` -Minimum camera angle above the horizon in radians. Default is 0. +Minimum camera angle above the horizon in radians. ### .maxAltitude @@ -507,7 +507,7 @@ Minimum camera angle above the horizon in radians. Default is 0. maxAltitude: number ``` -Maximum camera angle above the horizon in radians. Default is 0.45π. +Maximum camera angle above the horizon in radians. ### .minDistance @@ -516,7 +516,7 @@ Maximum camera angle above the horizon in radians. Default is 0.45π. minDistance: number ``` -Minimum zoom distance in world units. Default is 10. +Minimum zoom distance in world units. ### .maxDistance @@ -525,7 +525,7 @@ Minimum zoom distance in world units. Default is 10. maxDistance: number ``` -Maximum zoom distance in world units. Default is Infinity. +Maximum zoom distance in world units. ### .minZoom @@ -534,7 +534,7 @@ Maximum zoom distance in world units. Default is Infinity. minZoom: number ``` -Minimum orthographic zoom level. Default is 0. +Minimum orthographic zoom level. ### .maxZoom @@ -543,7 +543,7 @@ Minimum orthographic zoom level. Default is 0. maxZoom: number ``` -Maximum orthographic zoom level. Default is Infinity. +Maximum orthographic zoom level. ### .zoomSpeed @@ -552,7 +552,7 @@ Maximum orthographic zoom level. Default is Infinity. zoomSpeed: number ``` -Zoom sensitivity multiplier. Default is 1. +Zoom sensitivity multiplier. ### .adjustHeight @@ -561,7 +561,7 @@ Zoom sensitivity multiplier. Default is 1. adjustHeight: boolean ``` -When true, the camera height is automatically adjusted to avoid clipping into the terrain. Default is true. +When true, the camera height is automatically adjusted to avoid clipping into the terrain. ### .enableDamping @@ -570,7 +570,7 @@ When true, the camera height is automatically adjusted to avoid clipping into th enableDamping: boolean ``` -When true, camera movements decelerate gradually after input ends. Default is false. +When true, camera movements decelerate gradually after input ends. ### .dampingFactor @@ -579,7 +579,7 @@ When true, camera movements decelerate gradually after input ends. Default is fa dampingFactor: number ``` -Rate of inertia decay per frame when damping is enabled. Lower values produce longer coasting. Default is 0.15. +Rate of inertia decay per frame when damping is enabled. Lower values produce longer coasting. ### .fallbackPlane @@ -588,7 +588,7 @@ Rate of inertia decay per frame when damping is enabled. Lower values produce lo fallbackPlane: Plane ``` -Fallback plane used for drag/zoom when no scene geometry is hit. Default is the XZ plane (y=0). +Fallback plane used for drag/zoom when no scene geometry is hit. ### .useFallbackPlane @@ -597,7 +597,7 @@ Fallback plane used for drag/zoom when no scene geometry is hit. Default is the useFallbackPlane: boolean ``` -When true, the fallback plane is used when raycasting misses scene geometry. Default is true. +When true, the fallback plane is used when raycasting misses scene geometry. ### .enableFlight @@ -609,7 +609,7 @@ enableFlight: boolean When true, enables keyboard flight: W/A/S/D and arrow keys move forward/back/strafe, Q/E move up/down, and Shift multiplies speed by `flightSpeedMultiplier`. Right-click or Shift+left-click enters free-look mode, rotating the camera in place without requiring a surface hit. Only -supported for perspective cameras. Default is false. +supported for perspective cameras. ### .flightSpeed @@ -618,7 +618,7 @@ supported for perspective cameras. Default is false. flightSpeed: number ``` -Base camera speed in world units per second during keyboard flight. Default is 10. +Base camera speed in world units per second during keyboard flight. ### .flightSpeedMultiplier @@ -627,7 +627,7 @@ Base camera speed in world units per second during keyboard flight. Default is 1 flightSpeedMultiplier: number ``` -Speed multiplier applied when the fast key is held during flight. Default is 4. +Speed multiplier applied when the fast key is held during flight. ### .constructor @@ -778,7 +778,7 @@ The inverse of `ellipsoidFrame`. nearMargin: number ``` -Fraction of the near plane distance added as a buffer. Default is 0.25. +Fraction of the near plane distance added as a buffer. ### .farMargin @@ -787,7 +787,7 @@ Fraction of the near plane distance added as a buffer. Default is 0.25. farMargin: number ``` -Fraction of the far plane distance added as a buffer. Default is 0. +Fraction of the far plane distance added as a buffer. ### .globeInertia @@ -814,7 +814,7 @@ Magnitude of the current globe rotation inertia. Decays to zero over time. ellipsoid: Ellipsoid ``` -The ellipsoid model used for surface interaction and up-direction calculation. Defaults to WGS84. +The ellipsoid model used for surface interaction and up-direction calculation. ### .ellipsoidGroup @@ -951,9 +951,8 @@ tileset frame. ellipsoid: Ellipsoid ``` -The ellipsoid definition used for the tileset. Defaults to WGS84 and may be -overridden by the `3DTILES_ellipsoid` extension. Specified in the local frame of -`TilesRenderer.group`. +The ellipsoid definition used for the tileset. May be overridden by the +`3DTILES_ellipsoid` extension. Specified in the local frame of `TilesRenderer.group`. ### .cameras diff --git a/src/three/renderer/controls/CameraTransitionManager.js b/src/three/renderer/controls/CameraTransitionManager.js index 7e37d147c..933da54b3 100644 --- a/src/three/renderer/controls/CameraTransitionManager.js +++ b/src/three/renderer/controls/CameraTransitionManager.js @@ -104,14 +104,16 @@ export class CameraTransitionManager extends EventDispatcher { // settings /** - * When true, the orthographic camera position is offset backwards along the view direction so it does not clip into terrain. Default is true. + * When true, the orthographic camera position is offset backwards along the view direction so it does not clip into terrain. * @type {boolean} + * @default true */ this.orthographicPositionalZoom = true; /** - * Distance the orthographic camera is pushed back when `orthographicPositionalZoom` is true. Default is 50. + * Distance the orthographic camera is pushed back when `orthographicPositionalZoom` is true. * @type {number} + * @default 50 */ this.orthographicOffset = 50; @@ -122,20 +124,23 @@ export class CameraTransitionManager extends EventDispatcher { this.fixedPoint = new Vector3(); /** - * Duration of the animated transition in milliseconds. Default is 200. + * Duration of the animated transition in milliseconds. * @type {number} + * @default 200 */ this.duration = 200; /** - * When true, cameras are synced automatically before each `update` call. Default is true. + * When true, cameras are synced automatically before each `update` call. * @type {boolean} + * @default true */ this.autoSync = true; /** - * Easing function applied to the raw transition alpha. Receives and returns a value in [0, 1]. Default is the identity function. + * Easing function applied to the raw transition alpha. Receives and returns a value in [0, 1]. * @type {Function} + * @default x => x */ this.easeFunction = x => x; diff --git a/src/three/renderer/controls/EnvironmentControls.js b/src/three/renderer/controls/EnvironmentControls.js index 38d2f5953..b8bc76d4b 100644 --- a/src/three/renderer/controls/EnvironmentControls.js +++ b/src/three/renderer/controls/EnvironmentControls.js @@ -109,86 +109,100 @@ export class EnvironmentControls extends EventDispatcher { this._enabled = true; /** - * Minimum camera distance above the surface in world units. Prevents clipping into terrain. Default is 5. + * Minimum camera distance above the surface in world units. Prevents clipping into terrain. * @type {number} + * @default 5 */ this.cameraRadius = 5; /** - * Rotation sensitivity multiplier. Default is 1. + * Rotation sensitivity multiplier. * @type {number} + * @default 1 */ this.rotationSpeed = 1; /** - * Minimum camera angle above the horizon in radians. Default is 0. + * Minimum camera angle above the horizon in radians. * @type {number} + * @default 0 */ this.minAltitude = 0; /** - * Maximum camera angle above the horizon in radians. Default is 0.45π. + * Maximum camera angle above the horizon in radians. * @type {number} + * @default 0.45 * Math.PI */ this.maxAltitude = 0.45 * Math.PI; /** - * Minimum zoom distance in world units. Default is 10. + * Minimum zoom distance in world units. * @type {number} + * @default 10 */ this.minDistance = 10; /** - * Maximum zoom distance in world units. Default is Infinity. + * Maximum zoom distance in world units. * @type {number} + * @default Infinity */ this.maxDistance = Infinity; /** - * Minimum orthographic zoom level. Default is 0. + * Minimum orthographic zoom level. * @type {number} + * @default 0 */ this.minZoom = 0; /** - * Maximum orthographic zoom level. Default is Infinity. + * Maximum orthographic zoom level. * @type {number} + * @default Infinity */ this.maxZoom = Infinity; /** - * Zoom sensitivity multiplier. Default is 1. + * Zoom sensitivity multiplier. * @type {number} + * @default 1 */ this.zoomSpeed = 1; /** - * When true, the camera height is automatically adjusted to avoid clipping into the terrain. Default is true. + * When true, the camera height is automatically adjusted to avoid clipping into the terrain. * @type {boolean} + * @default true */ this.adjustHeight = true; /** - * When true, camera movements decelerate gradually after input ends. Default is false. + * When true, camera movements decelerate gradually after input ends. * @type {boolean} + * @default false */ this.enableDamping = false; /** - * Rate of inertia decay per frame when damping is enabled. Lower values produce longer coasting. Default is 0.15. + * Rate of inertia decay per frame when damping is enabled. Lower values produce longer coasting. * @type {number} + * @default 0.15 */ this.dampingFactor = 0.15; /** - * Fallback plane used for drag/zoom when no scene geometry is hit. Default is the XZ plane (y=0). + * Fallback plane used for drag/zoom when no scene geometry is hit. * @type {Plane} + * @default new Plane( UP, 0 ) */ this.fallbackPlane = new Plane( new Vector3( 0, 1, 0 ), 0 ); /** - * When true, the fallback plane is used when raycasting misses scene geometry. Default is true. + * When true, the fallback plane is used when raycasting misses scene geometry. * @type {boolean} + * @default true */ this.useFallbackPlane = true; @@ -196,20 +210,23 @@ export class EnvironmentControls extends EventDispatcher { * When true, enables keyboard flight: W/A/S/D and arrow keys move forward/back/strafe, Q/E move * up/down, and Shift multiplies speed by `flightSpeedMultiplier`. Right-click or Shift+left-click * enters free-look mode, rotating the camera in place without requiring a surface hit. Only - * supported for perspective cameras. Default is false. + * supported for perspective cameras. * @type {boolean} + * @default false */ this.enableFlight = false; /** - * Base camera speed in world units per second during keyboard flight. Default is 10. + * Base camera speed in world units per second during keyboard flight. * @type {number} + * @default 10 */ this.flightSpeed = 10; /** - * Speed multiplier applied when the fast key is held during flight. Default is 4. + * Speed multiplier applied when the fast key is held during flight. * @type {number} + * @default 4 */ this.flightSpeedMultiplier = 4; diff --git a/src/three/renderer/controls/GlobeControls.js b/src/three/renderer/controls/GlobeControls.js index 99a562463..ce7a58a88 100644 --- a/src/three/renderer/controls/GlobeControls.js +++ b/src/three/renderer/controls/GlobeControls.js @@ -85,14 +85,16 @@ export class GlobeControls extends EnvironmentControls { this.maxZoom = 0.01; /** - * Fraction of the near plane distance added as a buffer. Default is 0.25. + * Fraction of the near plane distance added as a buffer. * @type {number} + * @default 0.25 */ this.nearMargin = 0.25; /** - * Fraction of the far plane distance added as a buffer. Default is 0. + * Fraction of the far plane distance added as a buffer. * @type {number} + * @default 0 */ this.farMargin = 0; this.useFallbackPlane = false; @@ -111,8 +113,9 @@ export class GlobeControls extends EnvironmentControls { this.globeInertiaFactor = 0; /** - * The ellipsoid model used for surface interaction and up-direction calculation. Defaults to WGS84. + * The ellipsoid model used for surface interaction and up-direction calculation. * @type {Ellipsoid} + * @default WGS84_ELLIPSOID */ this.ellipsoid = WGS84_ELLIPSOID.clone(); diff --git a/src/three/renderer/tiles/TilesRenderer.js b/src/three/renderer/tiles/TilesRenderer.js index 738578c12..fbced130c 100644 --- a/src/three/renderer/tiles/TilesRenderer.js +++ b/src/three/renderer/tiles/TilesRenderer.js @@ -105,10 +105,10 @@ export class TilesRenderer extends TilesRendererBase { this.group = new TilesGroup( this ); /** - * The ellipsoid definition used for the tileset. Defaults to WGS84 and may be - * overridden by the `3DTILES_ellipsoid` extension. Specified in the local frame of - * `TilesRenderer.group`. + * The ellipsoid definition used for the tileset. May be overridden by the + * `3DTILES_ellipsoid` extension. Specified in the local frame of `TilesRenderer.group`. * @type {Ellipsoid} + * @default WGS84_ELLIPSOID */ this.ellipsoid = WGS84_ELLIPSOID.clone(); From fd7415c683f15309b39a3f10f8f9a51ba447f7a7 Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 20 May 2026 12:04:35 +0900 Subject: [PATCH 08/12] Update docs build functions --- src/core/renderer/API.md | 6 ++-- src/three/plugins/API.md | 2 +- src/three/renderer/API.md | 52 +++++++++++++++++------------------ utils/docs/RenderDocsUtils.js | 3 +- 4 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/core/renderer/API.md b/src/core/renderer/API.md index 73b36bc90..71e499f12 100644 --- a/src/core/renderer/API.md +++ b/src/core/renderer/API.md @@ -348,7 +348,7 @@ are in use each frame and evicts unused items when the cache exceeds its size li ### .unloadPriorityCallback ```js -unloadPriorityCallback: ( a: any, b: any ) => number | null +unloadPriorityCallback: ( a: any, b: any ) => number | null = null ``` Comparator used to determine eviction order. Items that sort last are evicted first. @@ -569,7 +569,7 @@ If true, job runs are automatically scheduled after `add` and after each job com ### .priorityCallback ```js -priorityCallback: ( a: any, b: any ) => number | null +priorityCallback: ( a: any, b: any ) => number | null = null ``` Comparator used to sort queued items. Higher-priority items should sort last @@ -897,7 +897,7 @@ Maximum depth in the tile hierarchy to traverse. Tiles deeper than this are skip ### .optimizedLoadStrategy ```js -optimizedLoadStrategy: boolean +optimizedLoadStrategy: boolean = false ``` **Experimental.** Enables an optimized tile loading strategy that loads only the tiles diff --git a/src/three/plugins/API.md b/src/three/plugins/API.md index ad44bc574..26a5f7b56 100644 --- a/src/three/plugins/API.md +++ b/src/three/plugins/API.md @@ -709,7 +709,7 @@ order, and an unlit rendering mode. Color modes are available via the static ### .getDebugColor ```js -getDebugColor: ( val: number, target: Color ) => void +getDebugColor: ( val: number, target: Color ) => void = ( value, target ) => target.setRGB( value, value, value ) ``` Maps a normalized [0, 1] value to a `Color` for debug visualizations. Defaults to diff --git a/src/three/renderer/API.md b/src/three/renderer/API.md index f8c636756..0da16f1e1 100644 --- a/src/three/renderer/API.md +++ b/src/three/renderer/API.md @@ -107,7 +107,7 @@ animation. Use `toggle()` to animate the transition. ### .orthographicPositionalZoom ```js -orthographicPositionalZoom: boolean +orthographicPositionalZoom: boolean = true ``` When true, the orthographic camera position is offset backwards along the view direction so it does not clip into terrain. @@ -116,7 +116,7 @@ When true, the orthographic camera position is offset backwards along the view d ### .orthographicOffset ```js -orthographicOffset: number +orthographicOffset: number = 50 ``` Distance the orthographic camera is pushed back when `orthographicPositionalZoom` is true. @@ -134,7 +134,7 @@ World-space point that remains visually fixed during the transition. ### .duration ```js -duration: number +duration: number = 200 ``` Duration of the animated transition in milliseconds. @@ -143,7 +143,7 @@ Duration of the animated transition in milliseconds. ### .autoSync ```js -autoSync: boolean +autoSync: boolean = true ``` When true, cameras are synced automatically before each `update` call. @@ -152,7 +152,7 @@ When true, cameras are synced automatically before each `update` call. ### .easeFunction ```js -easeFunction: function +easeFunction: function = x => x ``` Easing function applied to the raw transition alpha. Receives and returns a value in [0, 1]. @@ -477,7 +477,7 @@ and inertia is cleared. ### .cameraRadius ```js -cameraRadius: number +cameraRadius: number = 5 ``` Minimum camera distance above the surface in world units. Prevents clipping into terrain. @@ -486,7 +486,7 @@ Minimum camera distance above the surface in world units. Prevents clipping into ### .rotationSpeed ```js -rotationSpeed: number +rotationSpeed: number = 1 ``` Rotation sensitivity multiplier. @@ -495,7 +495,7 @@ Rotation sensitivity multiplier. ### .minAltitude ```js -minAltitude: number +minAltitude: number = 0 ``` Minimum camera angle above the horizon in radians. @@ -504,7 +504,7 @@ Minimum camera angle above the horizon in radians. ### .maxAltitude ```js -maxAltitude: number +maxAltitude: number = 0.45 * Math.PI ``` Maximum camera angle above the horizon in radians. @@ -513,7 +513,7 @@ Maximum camera angle above the horizon in radians. ### .minDistance ```js -minDistance: number +minDistance: number = 10 ``` Minimum zoom distance in world units. @@ -522,7 +522,7 @@ Minimum zoom distance in world units. ### .maxDistance ```js -maxDistance: number +maxDistance: number = Infinity ``` Maximum zoom distance in world units. @@ -531,7 +531,7 @@ Maximum zoom distance in world units. ### .minZoom ```js -minZoom: number +minZoom: number = 0 ``` Minimum orthographic zoom level. @@ -540,7 +540,7 @@ Minimum orthographic zoom level. ### .maxZoom ```js -maxZoom: number +maxZoom: number = Infinity ``` Maximum orthographic zoom level. @@ -549,7 +549,7 @@ Maximum orthographic zoom level. ### .zoomSpeed ```js -zoomSpeed: number +zoomSpeed: number = 1 ``` Zoom sensitivity multiplier. @@ -558,7 +558,7 @@ Zoom sensitivity multiplier. ### .adjustHeight ```js -adjustHeight: boolean +adjustHeight: boolean = true ``` When true, the camera height is automatically adjusted to avoid clipping into the terrain. @@ -567,7 +567,7 @@ When true, the camera height is automatically adjusted to avoid clipping into th ### .enableDamping ```js -enableDamping: boolean +enableDamping: boolean = false ``` When true, camera movements decelerate gradually after input ends. @@ -576,7 +576,7 @@ When true, camera movements decelerate gradually after input ends. ### .dampingFactor ```js -dampingFactor: number +dampingFactor: number = 0.15 ``` Rate of inertia decay per frame when damping is enabled. Lower values produce longer coasting. @@ -585,7 +585,7 @@ Rate of inertia decay per frame when damping is enabled. Lower values produce lo ### .fallbackPlane ```js -fallbackPlane: Plane +fallbackPlane: Plane = new Plane( UP, 0 ) ``` Fallback plane used for drag/zoom when no scene geometry is hit. @@ -594,7 +594,7 @@ Fallback plane used for drag/zoom when no scene geometry is hit. ### .useFallbackPlane ```js -useFallbackPlane: boolean +useFallbackPlane: boolean = true ``` When true, the fallback plane is used when raycasting misses scene geometry. @@ -603,7 +603,7 @@ When true, the fallback plane is used when raycasting misses scene geometry. ### .enableFlight ```js -enableFlight: boolean +enableFlight: boolean = false ``` When true, enables keyboard flight: W/A/S/D and arrow keys move forward/back/strafe, Q/E move @@ -615,7 +615,7 @@ supported for perspective cameras. ### .flightSpeed ```js -flightSpeed: number +flightSpeed: number = 10 ``` Base camera speed in world units per second during keyboard flight. @@ -624,7 +624,7 @@ Base camera speed in world units per second during keyboard flight. ### .flightSpeedMultiplier ```js -flightSpeedMultiplier: number +flightSpeedMultiplier: number = 4 ``` Speed multiplier applied when the fast key is held during flight. @@ -775,7 +775,7 @@ The inverse of `ellipsoidFrame`. ### .nearMargin ```js -nearMargin: number +nearMargin: number = 0.25 ``` Fraction of the near plane distance added as a buffer. @@ -784,7 +784,7 @@ Fraction of the near plane distance added as a buffer. ### .farMargin ```js -farMargin: number +farMargin: number = 0 ``` Fraction of the far plane distance added as a buffer. @@ -811,7 +811,7 @@ Magnitude of the current globe rotation inertia. Decays to zero over time. ### .ellipsoid ```js -ellipsoid: Ellipsoid +ellipsoid: Ellipsoid = WGS84_ELLIPSOID ``` The ellipsoid model used for surface interaction and up-direction calculation. @@ -948,7 +948,7 @@ tileset frame. ### .ellipsoid ```js -ellipsoid: Ellipsoid +ellipsoid: Ellipsoid = WGS84_ELLIPSOID ``` The ellipsoid definition used for the tileset. May be overridden by the diff --git a/utils/docs/RenderDocsUtils.js b/utils/docs/RenderDocsUtils.js index 9c8b43b27..b123de73b 100644 --- a/utils/docs/RenderDocsUtils.js +++ b/utils/docs/RenderDocsUtils.js @@ -265,7 +265,8 @@ export function renderMember( doc, callbackMap = {} ) { const type = formatType( doc.type, callbackMap ); const readonly = doc.readonly ? 'readonly ' : ''; - lines.push( `${ readonly }${ doc.name }: ${ type }` ); + const defaultStr = doc.defaultvalue !== undefined ? ` = ${ doc.defaultvalue }` : ''; + lines.push( `${ readonly }${ doc.name }: ${ type }${ defaultStr }` ); lines.push( '```' ); lines.push( '' ); From d808ed318e6dbe5a1875266b1ed84b333e8ae63f Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 20 May 2026 12:09:15 +0900 Subject: [PATCH 09/12] Update more defaults --- src/core/renderer/API.md | 12 ++++++------ src/core/renderer/utilities/LRUCache.js | 4 ++++ src/core/renderer/utilities/PriorityQueue.js | 2 ++ src/three/renderer/API.md | 2 +- src/three/renderer/controls/GlobeControls.js | 1 + 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/core/renderer/API.md b/src/core/renderer/API.md index 71e499f12..f3350f698 100644 --- a/src/core/renderer/API.md +++ b/src/core/renderer/API.md @@ -358,7 +358,7 @@ When `null`, eviction order is by last-used time. ### .minSize ```js -minSize: number +minSize: number = 6000 ``` Minimum number of items to keep in the cache after eviction. @@ -367,7 +367,7 @@ Minimum number of items to keep in the cache after eviction. ### .maxSize ```js -maxSize: number +maxSize: number = 8000 ``` Maximum number of items before eviction is triggered. @@ -398,7 +398,7 @@ Maximum total bytes before eviction is triggered. ### .unloadPercent ```js -unloadPercent: number +unloadPercent: number = 0.05 ``` Fraction of excess items/bytes to unload per eviction pass. @@ -407,7 +407,7 @@ Fraction of excess items/bytes to unload per eviction pass. ### .autoMarkUnused ```js -autoMarkUnused: boolean +autoMarkUnused: boolean = true ``` If true, items are automatically marked as unused at the start of each eviction pass. @@ -551,7 +551,7 @@ returns whether tasks are queued or actively running ### .maxJobs ```js -maxJobs: number +maxJobs: number = 6 ``` Maximum number of jobs that can run concurrently. @@ -560,7 +560,7 @@ Maximum number of jobs that can run concurrently. ### .autoUpdate ```js -autoUpdate: boolean +autoUpdate: boolean = true ``` If true, job runs are automatically scheduled after `add` and after each job completes. diff --git a/src/core/renderer/utilities/LRUCache.js b/src/core/renderer/utilities/LRUCache.js index 35c263116..5dd127c76 100644 --- a/src/core/renderer/utilities/LRUCache.js +++ b/src/core/renderer/utilities/LRUCache.js @@ -61,12 +61,14 @@ class LRUCache { /** * Minimum number of items to keep in the cache after eviction. * @type {number} + * @default 6000 */ this.minSize = 6000; /** * Maximum number of items before eviction is triggered. * @type {number} + * @default 8000 */ this.maxSize = 8000; @@ -87,12 +89,14 @@ class LRUCache { /** * Fraction of excess items/bytes to unload per eviction pass. * @type {number} + * @default 0.05 */ this.unloadPercent = 0.05; /** * If true, items are automatically marked as unused at the start of each eviction pass. * @type {boolean} + * @default true */ this.autoMarkUnused = true; diff --git a/src/core/renderer/utilities/PriorityQueue.js b/src/core/renderer/utilities/PriorityQueue.js index 2c822c031..c802364e7 100644 --- a/src/core/renderer/utilities/PriorityQueue.js +++ b/src/core/renderer/utilities/PriorityQueue.js @@ -84,6 +84,7 @@ export class PriorityQueue { /** * Maximum number of jobs that can run concurrently. * @type {number} + * @default 6 */ this.maxJobs = 6; @@ -95,6 +96,7 @@ export class PriorityQueue { /** * If true, job runs are automatically scheduled after `add` and after each job completes. * @type {boolean} + * @default true */ this.autoUpdate = true; diff --git a/src/three/renderer/API.md b/src/three/renderer/API.md index 0da16f1e1..82b8ea293 100644 --- a/src/three/renderer/API.md +++ b/src/three/renderer/API.md @@ -802,7 +802,7 @@ Accumulated globe rotation inertia quaternion. Applied each frame when globe ine ### .globeInertiaFactor ```js -globeInertiaFactor: number +globeInertiaFactor: number = 0 ``` Magnitude of the current globe rotation inertia. Decays to zero over time. diff --git a/src/three/renderer/controls/GlobeControls.js b/src/three/renderer/controls/GlobeControls.js index ce7a58a88..50b6688d5 100644 --- a/src/three/renderer/controls/GlobeControls.js +++ b/src/three/renderer/controls/GlobeControls.js @@ -109,6 +109,7 @@ export class GlobeControls extends EnvironmentControls { /** * Magnitude of the current globe rotation inertia. Decays to zero over time. * @type {number} + * @default 0 */ this.globeInertiaFactor = 0; From 77c3d6233f3141772948c7e1764d447e2be51fda Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 20 May 2026 13:08:40 +0900 Subject: [PATCH 10/12] Update new defaults --- src/core/renderer/API.md | 14 +++++++------- src/core/renderer/tiles/TilesRendererBase.js | 7 +++++++ src/three/renderer/API.md | 2 +- src/three/renderer/controls/EnvironmentControls.js | 1 + 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/core/renderer/API.md b/src/core/renderer/API.md index f3350f698..a8848f942 100644 --- a/src/core/renderer/API.md +++ b/src/core/renderer/API.md @@ -773,7 +773,7 @@ The loaded root tileset object, or null if not yet loaded. ### .fetchOptions ```js -fetchOptions: RequestInit +fetchOptions: RequestInit = {} ``` Options passed to `fetch` when loading tile and tileset resources. @@ -863,7 +863,7 @@ Loading and rendering statistics updated each frame. Fields: ### .errorTarget ```js -errorTarget: number +errorTarget: number = 16 ``` Target screen-space error in pixels to aim for when updating the geometry. Tiles will @@ -875,7 +875,7 @@ of the 3D Tiles specification for more information. ### .displayActiveTiles ```js -displayActiveTiles: boolean +displayActiveTiles: boolean = false ``` "Active tiles" are those that are loaded and available but not necessarily visible. @@ -888,7 +888,7 @@ camera view not accounted for by the tiles renderer. ### .maxDepth ```js -maxDepth: number +maxDepth: number = Infinity ``` Maximum depth in the tile hierarchy to traverse. Tiles deeper than this are skipped. @@ -916,7 +916,7 @@ Based in part on [Cesium Native tile selection](https://cesium.com/learn/cesium- ### .loadSiblings ```js -loadSiblings: boolean +loadSiblings: boolean = true ``` **Experimental.** When `true`, sibling tiles are loaded together to prevent gaps during @@ -930,7 +930,7 @@ Only applies when `optimizedLoadStrategy` is enabled. ### .loadAncestors ```js -loadAncestors: boolean +loadAncestors: boolean = false ``` **Experimental.** When `true`, ancestor tiles are queued for download and displayed as a @@ -944,7 +944,7 @@ Only applies when `optimizedLoadStrategy` is enabled. ### .maxTilesProcessed ```js -maxTilesProcessed: number +maxTilesProcessed: number = 250 ``` The number of tiles to process immediately when traversing the tile set to determine diff --git a/src/core/renderer/tiles/TilesRendererBase.js b/src/core/renderer/tiles/TilesRendererBase.js index 7928fe3f4..a8e552df6 100644 --- a/src/core/renderer/tiles/TilesRendererBase.js +++ b/src/core/renderer/tiles/TilesRendererBase.js @@ -403,6 +403,7 @@ export class TilesRendererBase { /** * Options passed to `fetch` when loading tile and tileset resources. * @type {RequestInit} + * @default {} */ this.fetchOptions = {}; this.plugins = []; @@ -544,6 +545,7 @@ export class TilesRendererBase { * {@link https://github.com/CesiumGS/3d-tiles/tree/master/specification#geometric-error geometric error section} * of the 3D Tiles specification for more information. * @type {number} + * @default 16 */ this.errorTarget = 16.0; this._errorThreshold = Infinity; @@ -555,12 +557,14 @@ export class TilesRendererBase { * Setting this to `true` keeps them in the scene so they can be rendered from an outside * camera view not accounted for by the tiles renderer. * @type {boolean} + * @default false */ this.displayActiveTiles = false; /** * Maximum depth in the tile hierarchy to traverse. Tiles deeper than this are skipped. * @type {number} + * @default Infinity */ this.maxDepth = Infinity; @@ -588,6 +592,7 @@ export class TilesRendererBase { * * Only applies when `optimizedLoadStrategy` is enabled. * @type {boolean} + * @default true */ this.loadSiblings = true; @@ -599,6 +604,7 @@ export class TilesRendererBase { * * Only applies when `optimizedLoadStrategy` is enabled. * @type {boolean} + * @default false */ this.loadAncestors = false; @@ -608,6 +614,7 @@ export class TilesRendererBase { * at once when a new tile set is available, while higher values process more tiles * immediately so data can be downloaded and displayed sooner. * @type {number} + * @default 250 */ this.maxTilesProcessed = 250; diff --git a/src/three/renderer/API.md b/src/three/renderer/API.md index 82b8ea293..6341ddaa4 100644 --- a/src/three/renderer/API.md +++ b/src/three/renderer/API.md @@ -467,7 +467,7 @@ right-click-to-rotate, and optional damping/inertia. Works with any Three.js sce ### .enabled ```js -enabled: boolean +enabled: boolean = true ``` Whether the controls are active. When set to false, all input is ignored diff --git a/src/three/renderer/controls/EnvironmentControls.js b/src/three/renderer/controls/EnvironmentControls.js index b8bc76d4b..11ff11844 100644 --- a/src/three/renderer/controls/EnvironmentControls.js +++ b/src/three/renderer/controls/EnvironmentControls.js @@ -68,6 +68,7 @@ export class EnvironmentControls extends EventDispatcher { * Whether the controls are active. When set to false, all input is ignored * and inertia is cleared. * @type {boolean} + * @default true */ get enabled() { From 0579d5d74f43195cb33bac33b5af474c48113656 Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 20 May 2026 13:14:09 +0900 Subject: [PATCH 11/12] Update docs --- src/core/renderer/API.md | 4 ++-- src/core/renderer/utilities/LRUCache.js | 2 ++ src/three/renderer/API.md | 10 +++++----- src/three/renderer/controls/CameraTransitionManager.js | 1 + src/three/renderer/controls/GlobeControls.js | 2 ++ src/three/renderer/tiles/TilesRenderer.js | 2 ++ 6 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/core/renderer/API.md b/src/core/renderer/API.md index a8848f942..5d28c9502 100644 --- a/src/core/renderer/API.md +++ b/src/core/renderer/API.md @@ -376,7 +376,7 @@ Maximum number of items before eviction is triggered. ### .minBytesSize ```js -minBytesSize: number +minBytesSize: number = ~322MB ``` Minimum total bytes to retain after eviction. @@ -387,7 +387,7 @@ Minimum total bytes to retain after eviction. ### .maxBytesSize ```js -maxBytesSize: number +maxBytesSize: number = ~430MB ``` Maximum total bytes before eviction is triggered. diff --git a/src/core/renderer/utilities/LRUCache.js b/src/core/renderer/utilities/LRUCache.js index 5dd127c76..d90501e11 100644 --- a/src/core/renderer/utilities/LRUCache.js +++ b/src/core/renderer/utilities/LRUCache.js @@ -76,6 +76,7 @@ class LRUCache { * Minimum total bytes to retain after eviction. * @note Only works with three.js r166 or higher. * @type {number} + * @default ~322MB */ this.minBytesSize = 0.3 * GIGABYTE_BYTES; @@ -83,6 +84,7 @@ class LRUCache { * Maximum total bytes before eviction is triggered. * @note Only works with three.js r166 or higher. * @type {number} + * @default ~430MB */ this.maxBytesSize = 0.4 * GIGABYTE_BYTES; diff --git a/src/three/renderer/API.md b/src/three/renderer/API.md index 6341ddaa4..f14388094 100644 --- a/src/three/renderer/API.md +++ b/src/three/renderer/API.md @@ -125,7 +125,7 @@ Distance the orthographic camera is pushed back when `orthographicPositionalZoom ### .fixedPoint ```js -fixedPoint: Vector3 +fixedPoint: Vector3 = new Vector3() ``` World-space point that remains visually fixed during the transition. @@ -793,7 +793,7 @@ Fraction of the far plane distance added as a buffer. ### .globeInertia ```js -globeInertia: Quaternion +globeInertia: Quaternion = new Quaternion() ``` Accumulated globe rotation inertia quaternion. Applied each frame when globe inertia is active. @@ -820,7 +820,7 @@ The ellipsoid model used for surface interaction and up-direction calculation. ### .ellipsoidGroup ```js -ellipsoidGroup: Group +ellipsoidGroup: Group = new Group() ``` The Three.js group whose world matrix defines the ellipsoid's coordinate frame. @@ -926,7 +926,7 @@ Add `tiles.group` to your scene and call `tiles.update()` each frame. ### .autoDisableRendererCulling ```js -autoDisableRendererCulling: boolean +autoDisableRendererCulling: boolean = true ``` If `true`, all tile meshes automatically have `frustumCulled` set to `false` since the @@ -967,7 +967,7 @@ Array of cameras registered with this renderer. ### .manager ```js -manager: LoadingManager +manager: LoadingManager = new LoadingManager() ``` The `LoadingManager` used when loading tile geometry. diff --git a/src/three/renderer/controls/CameraTransitionManager.js b/src/three/renderer/controls/CameraTransitionManager.js index 933da54b3..3b526a198 100644 --- a/src/three/renderer/controls/CameraTransitionManager.js +++ b/src/three/renderer/controls/CameraTransitionManager.js @@ -120,6 +120,7 @@ export class CameraTransitionManager extends EventDispatcher { /** * World-space point that remains visually fixed during the transition. * @type {Vector3} + * @default new Vector3() */ this.fixedPoint = new Vector3(); diff --git a/src/three/renderer/controls/GlobeControls.js b/src/three/renderer/controls/GlobeControls.js index 50b6688d5..506e7084a 100644 --- a/src/three/renderer/controls/GlobeControls.js +++ b/src/three/renderer/controls/GlobeControls.js @@ -103,6 +103,7 @@ export class GlobeControls extends EnvironmentControls { /** * Accumulated globe rotation inertia quaternion. Applied each frame when globe inertia is active. * @type {Quaternion} + * @default new Quaternion() */ this.globeInertia = new Quaternion(); @@ -123,6 +124,7 @@ export class GlobeControls extends EnvironmentControls { /** * The Three.js group whose world matrix defines the ellipsoid's coordinate frame. * @type {Group} + * @default new Group() */ this.ellipsoidGroup = new Group(); this._ellipsoidFrameInverse = new Matrix4(); diff --git a/src/three/renderer/tiles/TilesRenderer.js b/src/three/renderer/tiles/TilesRenderer.js index fbced130c..e43eea0aa 100644 --- a/src/three/renderer/tiles/TilesRenderer.js +++ b/src/three/renderer/tiles/TilesRenderer.js @@ -57,6 +57,7 @@ export class TilesRenderer extends TilesRendererBase { * tiles renderer performs its own frustum culling. If `displayActiveTiles` is `true` or * multiple cameras are being used, consider setting this to `false`. * @type {boolean} + * @default true */ get autoDisableRendererCulling() { @@ -129,6 +130,7 @@ export class TilesRenderer extends TilesRendererBase { /** * The `LoadingManager` used when loading tile geometry. * @type {LoadingManager} + * @default new LoadingManager() */ this.manager = new LoadingManager(); From 361aa9644db0a295c5d96d81e8c75093f719edcb Mon Sep 17 00:00:00 2001 From: Garrett Johnson Date: Wed, 20 May 2026 13:15:52 +0900 Subject: [PATCH 12/12] Update --- src/core/renderer/API.md | 4 ++-- src/core/renderer/loaders/LoaderBase.js | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/renderer/API.md b/src/core/renderer/API.md index 5d28c9502..1d1da551a 100644 --- a/src/core/renderer/API.md +++ b/src/core/renderer/API.md @@ -85,7 +85,7 @@ Base class for all 3D Tiles content loaders. Handles fetching and parsing tile c ### .fetchOptions ```js -fetchOptions: Object +fetchOptions: Object = {} ``` Options passed to `fetch` when loading tile content. @@ -94,7 +94,7 @@ Options passed to `fetch` when loading tile content. ### .workingPath ```js -workingPath: string +workingPath: string = '' ``` Base URL used to resolve relative external URLs. diff --git a/src/core/renderer/loaders/LoaderBase.js b/src/core/renderer/loaders/LoaderBase.js index 476892a2b..dbaf54513 100644 --- a/src/core/renderer/loaders/LoaderBase.js +++ b/src/core/renderer/loaders/LoaderBase.js @@ -10,12 +10,14 @@ export class LoaderBase { /** * Options passed to `fetch` when loading tile content. * @type {Object} + * @default {} */ this.fetchOptions = {}; /** * Base URL used to resolve relative external URLs. * @type {string} + * @default '' */ this.workingPath = '';