@giro3d/giro3d
Version:
A JS/WebGL framework for 3D geospatial data visualization
413 lines • 14.9 kB
TypeScript
import type { OrthographicCamera, PerspectiveCamera } from 'three';
import type { CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer.js';
import { EventDispatcher, Group, Object3D, Scene, Vector2, type ColorRepresentation, type WebGLRenderer, type WebGLRendererParameters } from 'three';
import type Entity from '../entities/Entity';
import type RenderingOptions from '../renderer/RenderingOptions';
import type CoordinateSystem from './geographic/CoordinateSystem';
import type PickOptions from './picking/PickOptions';
import type PickResult from './picking/PickResult';
import type Progress from './Progress';
import C3DEngine from '../renderer/c3DEngine';
import View from '../renderer/View';
import MainLoop from './MainLoop';
import { type MemoryUsageReport } from './MemoryUsage';
/** Frame event payload */
export interface FrameEventPayload {
/** The frame number. */
frame: number;
/** Time elapsed since previous update loop, in milliseconds */
dt: number;
/** `true` if the update loop restarted */
updateLoopRestarted: boolean;
}
/** Entity event payload */
export interface EntityEventPayload {
/** Entity */
entity: Entity;
}
/**
* Events supported by
* [`Instance.addEventListener()`](https://threejs.org/docs/#api/en/core/EventDispatcher.addEventListener)
* and
* [`Instance.removeEventListener()`](https://threejs.org/docs/#api/en/core/EventDispatcher.removeEventListener)
*/
export interface InstanceEvents {
/**
* Fires when an entity is added to the instance.
*/
'entity-added': unknown;
/**
* Fires when an entity is removed from the instance.
*/
'entity-removed': unknown;
/**
* Fires at the start of the update
*/
'update-start': FrameEventPayload;
/**
* Fires before the camera update
*/
'before-camera-update': {
camera: View;
} & FrameEventPayload;
/**
* Fires after the camera update
*/
'after-camera-update': {
camera: View;
} & FrameEventPayload;
/**
* Fires before the entity update
*/
'before-entity-update': EntityEventPayload & FrameEventPayload;
/**
* Fires after the entity update
*/
'after-entity-update': EntityEventPayload & FrameEventPayload;
/**
* Fires before the render
*/
'before-render': FrameEventPayload;
/**
* Fires after the render
*/
'after-render': FrameEventPayload;
/**
* Fires at the end of the update
*/
'update-end': FrameEventPayload;
'picking-start': unknown;
'picking-end': {
/**
* The duration of the picking, in seconds.
*/
elapsed: number;
/**
* The picking results.
*/
results?: PickResult<unknown>[];
};
/**
* Fires when the instance is disposed.
*/
dispose: unknown;
}
/** Options for creating Instance */
export interface InstanceOptions {
/**
* The container for the instance. May be either the `id` of an existing `<div>` element,
* or the element itself.
*/
target: string | HTMLDivElement;
/**
* The coordinate reference system of the scene.
* Must be a cartesian system.
* Must first be registered via {@link CoordinateSystem.register}
*/
crs: CoordinateSystem;
/**
* The [Three.js Scene](https://threejs.org/docs/#api/en/scenes/Scene) instance to use,
* otherwise a default one will be constructed
*/
scene3D?: Scene;
/**
* The background color of the canvas. If `null`, the canvas is transparent.
* If `undefined`, the default color is used.
* @defaultValue `'#030508'`
*/
backgroundColor?: ColorRepresentation | null;
/**
* The renderer to use. Might be either an instance of an existing {@link WebGLRenderer},
* or options to create one. If `undefined`, a new one will be created with default parameters.
*/
renderer?: WebGLRenderer | WebGLRendererParameters;
/**
* The THREE camera to use
*/
camera?: PerspectiveCamera | OrthographicCamera;
}
/**
* Options for picking objects from the Giro3D {@link Instance}.
*/
export interface PickObjectsAtOptions extends PickOptions {
/**
* List of entities to pick from.
* If not provided, will pick from all the objects in the scene.
* Strings consist in the IDs of the object.
*/
where?: (string | Object3D | Entity)[];
/**
* Indicates if the results should be sorted by distance, as Three.js raycasting does.
* This prevents the `limit` option to be fully used as it is applied after sorting,
* thus it may be slow and is disabled by default.
*
* @defaultValue false
*/
sortByDistance?: boolean;
/**
* Indicates if features information are also retrieved from the picked object.
* On complex objects, this may be slow, and therefore is disabled by default.
*
* @defaultValue false
*/
pickFeatures?: boolean;
}
/**
* The instance is the core component of Giro3D. It encapsulates the 3D scene,
* the current camera and one or more {@link Entity | entities}. The instance displays
* the 3D scene in the DOM element specified by the `target` constructor property.
*
* ```js
* // Create a Giro3D instance in the EPSG:3857 coordinate system:
* const instance = new Instance({
* target: 'view',
* crs: CoordinateSystem.epsg3857,
* });
*
* const map = new Map(...);
*
* // Add an entity to the instance
* instance.add(map);
*
* // Bind an event listener on double click
* instance.domElement.addEventListener('dblclick', () => console.log('double click!'));
*
* // Get the camera position
* const position = instance.view.camera.position;
*
* // Set the camera position to be located 10,000 meters above the center of the coordinate system.
* instance.view.camera.position.set(0, 0, 10000);
* instance.view.camera.lookAt(0, 0, 0);
* ```
*/
declare class Instance extends EventDispatcher<InstanceEvents> implements Progress {
private readonly _referenceCrs;
private readonly _viewport;
private readonly _mainLoop;
private readonly _engine;
private readonly _scene;
private readonly _threeObjects;
private readonly _view;
private readonly _entities;
private readonly _resizeObserver?;
private readonly _pickingClock;
private readonly _onContextRestored;
private readonly _onContextLost;
private _resizeTimeout?;
private _disposed;
/**
* Constructs a Giro3D Instance
*
* @param options - Options
*
* ```js
* const instance = new Instance({
* target: 'parentElement', // The id of the <div> to attach the instance
* crs: CoordinateSystem.epsg3857,
* });
* ```
*/
constructor(options: InstanceOptions);
private onContextLost;
private onContextRestored;
/** Gets the canvas that this instance renders into. */
get domElement(): HTMLCanvasElement;
/** Gets the DOM element that contains the Giro3D viewport. */
get viewport(): HTMLDivElement;
/** Gets the CRS used in this instance. */
get coordinateSystem(): CoordinateSystem;
/** Gets whether at least one entity is currently loading data. */
get loading(): boolean;
/**
* Gets the progress (between 0 and 1) of the processing of the entire instance.
* This is the average of the progress values of all entities.
* Note: This value is only meaningful is {@link loading} is `true`.
* Note: if no entity is present in the instance, this will always return 1.
*/
get progress(): number;
/** Gets the main loop */
get mainLoop(): MainLoop;
/** Gets the rendering engine */
get engine(): C3DEngine;
/**
* Gets the rendering options.
*
* Note: you must call {@link notifyChange | notifyChange()} to take
* the changes into account.
*/
get renderingOptions(): RenderingOptions;
/**
* Gets the underlying WebGL renderer.
*/
get renderer(): WebGLRenderer;
/**
* Gets the underlying CSS2DRenderer.
*/
get css2DRenderer(): CSS2DRenderer;
/** Gets the [3D Scene](https://threejs.org/docs/#api/en/scenes/Scene). */
get scene(): Scene;
/** Gets the group containing native Three.js objects. */
get threeObjects(): Group;
/** Gets the view. */
get view(): View;
private _doUpdateRendererSize;
private _updateRendererSize;
/**
* Dispose of this instance object. Free all memory used.
*
* Note: this *will not* dispose the following reusable objects:
* - controls (because they can be attached and detached). For THREE.js controls, use
* `controls.dispose()`
* - Inspectors, use `inspector.detach()`
* - any openlayers objects, please see their individual documentation
*
*/
dispose(): void;
/**
* Add THREE object or Entity to the instance.
*
* If the object or entity has no parent, it will be added to the default tree (i.e under
* `.scene` for entities and under `.threeObjects` for regular Object3Ds.).
*
* If the object or entity already has a parent, then it will not be changed. Check that this
* parent is present in the scene graph (i.e has the `.scene` object as ancestor), otherwise it
* will **never be displayed**.
*
* @example
* // Add Map to instance
* instance.add(new Map(...);
*
* // Add Map to instance then wait for the map to be ready.
* instance.add(new Map(...).then(...);
* @param object - the object to add
* @returns a promise resolved with the new layer object when it is fully initialized
* or rejected if any error occurred.
*/
add<T extends Object3D | Entity>(object: T): Promise<T>;
/**
* Removes the entity or THREE object from the scene.
*
* @param object - the object to remove.
*/
remove(object: Object3D | Entity): void;
/**
* Notifies the scene it needs to be updated due to changes exterior to the
* scene itself (e.g. camera movement).
* non-interactive events (e.g: texture loaded)
*
* @param changeSources - The source(s) of the change. Might be a single object or an array.
* @param options - Notification options.
*/
notifyChange(changeSources?: unknown | unknown[], options?: {
/**
* Should we render the scene?
* @defaultValue true
*/
needsRedraw?: boolean;
/**
* Should the update be immediate? If `false`, the update is deferred to the
* next animation frame.
* @defaultValue false
*/
immediate?: boolean;
}): void;
/**
* Get all top-level objects (entities and regular THREE objects), using an optional filter
* predicate.
*
* ```js
* // get all objects
* const allObjects = instance.getObjects();
* // get all object whose name includes 'foo'
* const fooObjects = instance.getObjects(obj => obj.name === 'foo');
* ```
* @param filter - the optional filter predicate.
* @returns an array containing the queried objects
*/
getObjects(filter?: (obj: Object3D | Entity) => boolean): (Object3D | Entity)[];
/**
* Get all entities, with an optional predicate applied.
*
* ```js
* // get all entities
* const allEntities = instance.getEntities();
*
* // get all entities whose name contains 'building'
* const buildings = instance.getEntities(entity => entity.name.includes('building'));
* ```
* @param filter - the optional filter predicate
* @returns an array containing the queried entities
*/
getEntities(filter?: (obj: Entity) => boolean): Entity[];
/**
* Executes the rendering.
* Internal use only.
*
* @internal
*/
render(): void;
/**
* Extract canvas coordinates from a mouse-event / touch-event.
*
* @param event - event can be a MouseEvent or a TouchEvent
* @param target - The target to set with the result.
* @param touchIdx - Touch index when using a TouchEvent (default: 0)
* @returns canvas coordinates (in pixels, 0-0 = top-left of the instance)
*/
eventToCanvasCoords(event: MouseEvent | TouchEvent, target: Vector2, touchIdx?: number): Vector2;
/**
* Extract normalized coordinates (NDC) from a mouse-event / touch-event.
*
* @param event - event can be a MouseEvent or a TouchEvent
* @param target - The target to set with the result.
* @param touchIdx - Touch index when using a TouchEvent (default: 0)
* @returns NDC coordinates (x and y are [-1, 1])
*/
eventToNormalizedCoords(event: MouseEvent | TouchEvent, target: Vector2, touchIdx?: number): Vector2;
/**
* Convert canvas coordinates to normalized device coordinates (NDC).
*
* @param canvasCoords - (in pixels, 0-0 = top-left of the instance)
* @param target - The target to set with the result.
* @returns NDC coordinates (x and y are [-1, 1])
*/
canvasToNormalizedCoords(canvasCoords: Vector2, target: Vector2): Vector2;
/**
* Convert NDC coordinates to canvas coordinates.
*
* @param ndcCoords - The NDC coordinates to convert
* @param target - The target to set with the result.
* @returns canvas coordinates (in pixels, 0-0 = top-left of the instance)
*/
normalizedToCanvasCoords(ndcCoords: Vector2, target: Vector2): Vector2;
/**
* Gets the object by it's id property.
*
* @param objectId - Object id
* @returns Object found
* @throws Error if object cannot be found
*/
private objectIdToObject;
/**
* Return objects from some layers/objects3d under the mouse in this instance.
*
* @param mouseOrEvt - mouse position in window coordinates, i.e [0, 0] = top-left,
* or `MouseEvent` or `TouchEvent`
* @param options - Options
* @returns An array of objects. Each element contains at least an object
* property which is the Object3D under the cursor. Then depending on the queried
* layer/source, there may be additionnal properties (coming from THREE.Raycaster
* for instance).
* If `options.pickFeatures` if `true`, `features` property may be set.
*
* ```js
* instance.pickObjectsAt(mouseEvent)
* instance.pickObjectsAt(mouseEvent, { radius: 1, where: [entity0, entity1] })
* instance.pickObjectsAt(mouseEvent, { radius: 3, where: [entity0] })
* ```
*/
pickObjectsAt(mouseOrEvt: Vector2 | MouseEvent | TouchEvent, options?: PickObjectsAtOptions): PickResult[];
getMemoryUsage(): MemoryUsageReport;
}
export default Instance;
//# sourceMappingURL=Instance.d.ts.map