UNPKG

@google/model-viewer

Version:

Easily display interactive 3D models on the web and in AR!

276 lines (275 loc) 11.4 kB
import { AnimationActionLoopStyles, AnimationMixerEventMap, Box3, Camera, Event as ThreeEvent, Material, Mesh, Object3D, PerspectiveCamera, Scene, Sphere, Texture, ToneMapping, Vector2, Vector3, WebGLRenderer, XRTargetRaySpace } from 'three'; import { CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer.js'; import ModelViewerElementBase, { EffectComposerInterface, RendererInterface } from '../model-viewer-base.js'; import { ModelViewerElement } from '../model-viewer.js'; import { ModelViewerGLTFInstance } from './gltf-instance/ModelViewerGLTFInstance.js'; import { Hotspot } from './Hotspot.js'; import { Shadow } from './Shadow.js'; export declare const GROUNDED_SKYBOX_SIZE = 10; export interface ModelLoadEvent extends ThreeEvent { url: string; } export interface ModelSceneConfig { element: ModelViewerElementBase; canvas: HTMLCanvasElement; width: number; height: number; } export interface MarkedAnimation { name: string; loopMode: AnimationActionLoopStyles; repetitionCount: number; } export type IlluminationRole = 'primary' | 'secondary'; export declare const IlluminationRole: { [index: string]: IlluminationRole; }; /** * A THREE.Scene object that takes a Model and CanvasHTMLElement and * constructs a framed scene based off of the canvas dimensions. * Provides lights and cameras to be used in a renderer. */ export declare class ModelScene extends Scene { element: ModelViewerElement; canvas: HTMLCanvasElement; annotationRenderer: CSS2DRenderer; effectRenderer: EffectComposerInterface | null; schemaElement: HTMLScriptElement; width: number; height: number; aspect: number; scaleStep: number; renderCount: number; externalRenderer: RendererInterface | null; appendedAnimations: Array<string>; markedAnimations: Array<MarkedAnimation>; camera: PerspectiveCamera; xrCamera: Camera | null; url: string | null; pivot: Object3D<import("three").Object3DEventMap>; target: Object3D<import("three").Object3DEventMap>; animationNames: Array<string>; boundingBox: Box3; boundingSphere: Sphere; size: Vector3; idealAspect: number; framedFoVDeg: number; shadow: Shadow | null; shadowIntensity: number; shadowSoftness: number; bakedShadows: Set<Mesh<import("three").BufferGeometry<import("three").NormalBufferAttributes>, Material | Material[], import("three").Object3DEventMap>>; exposure: number; toneMapping: ToneMapping; canScale: boolean; private isDirty; private goalTarget; private targetDamperX; private targetDamperY; private targetDamperZ; private _currentGLTF; private _model; private mixer; private cancelPendingSourceChange; private animationsByName; private currentAnimationAction; private groundedSkybox; constructor({ canvas, element, width, height }: ModelSceneConfig); /** * Function to create the context lazily, as when there is only one * <model-viewer> element, the renderer's 3D context can be displayed * directly. This extra context is necessary to copy the renderings into when * there are more than one. */ get context(): CanvasRenderingContext2D | null; getCamera(): Camera; queueRender(): void; shouldRender(): boolean; hasRendered(): void; forceRescale(): void; /** * Pass in a THREE.Object3D to be controlled * by this model. */ setObject(model: Object3D): Promise<void>; /** * Sets the model via URL. */ setSource(url: string | null, progressCallback?: (progress: number) => void): Promise<void>; private setupScene; reset(): void; dispose(): void; get currentGLTF(): ModelViewerGLTFInstance | null; /** * Updates the ModelScene for a new container size in CSS pixels. */ setSize(width: number, height: number): void; markBakedShadow(mesh: Mesh): void; unmarkBakedShadow(mesh: Mesh): void; findBakedShadows(group: Object3D): void; checkBakedShadows(): void; applyTransform(): void; updateBoundingBox(): void; /** * Calculates the boundingSphere and idealAspect that allows the 3D * object to be framed tightly in a 2D window of any aspect ratio without * clipping at any camera orbit. The camera's center target point can be * optionally specified. If no center is specified, it defaults to the center * of the bounding box, which means asymmetric models will tend to be tight on * one side instead of both. Proper choice of center can correct this. */ updateFraming(): Promise<void>; setBakedShadowVisibility(visible?: boolean): void; idealCameraDistance(): number; /** * Set's the framedFieldOfView based on the aspect ratio of the window in * order to keep the model fully visible at any camera orientation. */ adjustedFoV(fovDeg: number): number; getNDC(clientX: number, clientY: number): Vector2; /** * Returns the size of the corresponding canvas element. */ getSize(): { width: number; height: number; }; setEnvironmentAndSkybox(environment: Texture | null, skybox: Texture | null): void; setBackground(skybox: Texture | null): void; farRadius(): number; setGroundedSkybox(): void; /** * Sets the point in model coordinates the model should orbit/pivot around. */ setTarget(modelX: number, modelY: number, modelZ: number): void; /** * Set the decay time of, affects the speed of target transitions. */ setTargetDamperDecayTime(decayMilliseconds: number): void; /** * Gets the point in model coordinates the model should orbit/pivot around. */ getTarget(): Vector3; /** * Gets the current target point, which may not equal the goal returned by * getTarget() due to finite input decay smoothing. */ getDynamicTarget(): Vector3; /** * Shifts the model to the target point immediately instead of easing in. */ jumpToGoal(): void; /** * This should be called every frame with the frame delta to cause the target * to transition to its set point. */ updateTarget(delta: number): boolean; /** * Yaw the +z (front) of the model toward the indicated world coordinates. */ pointTowards(worldX: number, worldZ: number): void; get model(): Object3D<import("three").Object3DEventMap> | null; /** * Yaw is the scene's orientation about the y-axis, around the rotation * center. */ set yaw(radiansY: number); get yaw(): number; set animationTime(value: number); get animationTime(): number; set animationTimeScale(value: number); get animationTimeScale(): number; get duration(): number; get hasActiveAnimation(): boolean; /** * Plays an animation if there are any associated with the current model. * Accepts an optional string name of an animation to play. If no name is * provided, or if no animation is found by the given name, always falls back * to playing the first animation. */ playAnimation(name?: string | null, crossfadeTime?: number, loopMode?: AnimationActionLoopStyles, repetitionCount?: number): void; appendAnimation(name?: string, loopMode?: AnimationActionLoopStyles, repetitionCount?: number, weight?: number, timeScale?: number, fade?: boolean | number, warp?: boolean | number, relativeWarp?: boolean, time?: null | number, needsToStop?: boolean): void; detachAnimation(name?: string, fade?: boolean | number): void; updateAnimationLoop(name?: string, loopMode?: AnimationActionLoopStyles, repetitionCount?: number): void; stopAnimation(): void; updateAnimation(step: number): void; subscribeMixerEvent(event: keyof AnimationMixerEventMap, callback: (...args: any[]) => void): void; /** * Call if the object has been changed in such a way that the shadow's * shape has changed (not a rotation about the Y axis). */ updateShadow(): void; renderShadow(renderer: WebGLRenderer): void; private queueShadowRender; /** * Sets the shadow's intensity, lazily creating the shadow as necessary. */ setShadowIntensity(shadowIntensity: number): void; /** * Sets the shadow's softness by mapping a [0, 1] softness parameter to * the shadow's resolution. This involves reallocation, so it should not * be changed frequently. Softer shadows are cheaper to render. */ setShadowSoftness(softness: number): void; /** * Shift the floor vertically from the bottom of the model's bounding box * by offset (should generally be negative). */ setShadowOffset(offset: number): void; getHit(object?: Object3D): import("three").Intersection<Object3D<import("three").Object3DEventMap>> | undefined; hitFromController(controller: XRTargetRaySpace, object?: Object3D): import("three").Intersection<Object3D<import("three").Object3DEventMap>> | undefined; hitFromPoint(ndcPosition: Vector2, object?: Object3D): import("three").Intersection<Object3D<import("three").Object3DEventMap>> | undefined; /** * This method returns the world position, model-space normal and texture * coordinate of the point on the mesh corresponding to the input pixel * coordinates given relative to the model-viewer element. If the mesh * is not hit, the result is null. */ positionAndNormalFromPoint(ndcPosition: Vector2, object?: Object3D): { position: Vector3; normal: Vector3; uv: Vector2 | null; } | null; /** * This method returns a dynamic hotspot ID string of the point on the * mesh corresponding to the input pixel coordinates given relative to the * model-viewer element. The ID string can be used in the data-surface * attribute of the hotspot to make it follow this point on the surface * even as the model animates. If the mesh is not hit, the result is null. */ surfaceFromPoint(ndcPosition: Vector2, object?: Object3D): string | null; /** * The following methods are for operating on the set of Hotspot objects * attached to the scene. These come from DOM elements, provided to slots * by the Annotation Mixin. */ addHotspot(hotspot: Hotspot): void; removeHotspot(hotspot: Hotspot): void; /** * Helper method to apply a function to all hotspots. */ forHotspots(func: (hotspot: Hotspot) => void): void; /** * Lazy initializer for surface hotspots - will only run once. */ updateSurfaceHotspot(hotspot: Hotspot): void; /** * Update positions of surface hotspots to follow model animation. */ animateSurfaceHotspots(): void; /** * Update the CSS visibility of the hotspots based on whether their * normals point toward the camera. */ updateHotspotsVisibility(viewerPosition: Vector3): void; /** * Rotate all hotspots to an absolute orientation given by the input * number of radians. Zero returns them to upright. */ orientHotspots(radians: number): void; /** * Set the rendering visibility of all hotspots. This is used to hide them * during transitions and such. */ setHotspotsVisibility(visible: boolean): void; updateSchema(src: string | null): void; }