diff --git a/.all-contributorsrc b/.all-contributorsrc index 829fd5715..9b0180207 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -325,14 +325,23 @@ ] }, { - "login": "subhankar-trisetra", + "login": "subhankar-trisetra", "name": "Subhankar Pal", "avatar_url": "https://avatars.githubusercontent.com/u/98544661?v=4", "profile": "https://subho57.github.io", "contributions": [ - "code", - ], - } + "code" + ] + }, + { + "login": "capnmidnight", + "name": "Sean T. McBeth", + "avatar_url": "https://avatars.githubusercontent.com/u/298046?v=4", + "profile": "http://www.seanmcbeth.com/", + "contributions": [ + "code" + ] + } ], "skipCi": true, "contributorsPerLine": 7 diff --git a/README.md b/README.md index 795cbad4a..a558639b0 100644 --- a/README.md +++ b/README.md @@ -67,8 +67,9 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
Alejandro Laufer

🐛 💻
Gianmarco

💻
David Peicho

💻 -
Subhankar Pal

💻 📖
Maccesch

💻 ⚠️ +
Subhankar Pal

💻 +
Sean T. McBeth

💻 diff --git a/package.json b/package.json index 3abd2c353..99e3005e2 100644 --- a/package.json +++ b/package.json @@ -18,5 +18,8 @@ "prettier": "2.3.2", "pretty-quick": "^3.1.1", "typescript": "next" + }, + "dependencies": { + "@types/webxr": "^0.4.0" } } diff --git a/types/three/examples/jsm/webxr/ARButton.d.ts b/types/three/examples/jsm/webxr/ARButton.d.ts index 5f822266f..9936a667b 100644 --- a/types/three/examples/jsm/webxr/ARButton.d.ts +++ b/types/three/examples/jsm/webxr/ARButton.d.ts @@ -1,5 +1,9 @@ import { WebGLRenderer } from '../../../src/Three'; +export interface ARButtonSessionInit extends XRSessionInit { + domOverlay: { root: HTMLElement }; +} + export namespace ARButton { - function createButton(renderer: WebGLRenderer, sessionInit?: any): HTMLElement; + function createButton(renderer: WebGLRenderer, sessionInit?: Partial): HTMLElement; } diff --git a/types/three/examples/jsm/webxr/OculusHandModel.d.ts b/types/three/examples/jsm/webxr/OculusHandModel.d.ts index 20afcaa7d..218cd61d3 100644 --- a/types/three/examples/jsm/webxr/OculusHandModel.d.ts +++ b/types/three/examples/jsm/webxr/OculusHandModel.d.ts @@ -1,8 +1,9 @@ -import { Object3D, Sphere, Box3, Mesh, Texture, Vector3 } from '../../../src/Three'; +import { Mesh, Object3D, Texture, Vector3 } from '../../../src/Three'; +import { XRHandMeshModel } from './XRHandMeshModel'; export class OculusHandModel extends Object3D { controller: Object3D; - motionController: Object3D | null; + motionController: XRHandMeshModel | null; envMap: Texture | null; mesh: Mesh | null; diff --git a/types/three/examples/jsm/webxr/OculusHandPointerModel.d.ts b/types/three/examples/jsm/webxr/OculusHandPointerModel.d.ts index bda1e7aae..6d95bd930 100644 --- a/types/three/examples/jsm/webxr/OculusHandPointerModel.d.ts +++ b/types/three/examples/jsm/webxr/OculusHandPointerModel.d.ts @@ -1,3 +1,5 @@ +import 'webxr'; + import { BufferGeometry, Intersection, @@ -10,10 +12,12 @@ import { Vector3, } from '../../../src/Three'; +import { XRHandMeshModel } from './XRHandMeshModel'; + export class OculusHandPointerModel extends Object3D { hand: Object3D; controller: Object3D; - motionController: Object3D | null; + motionController: XRHandMeshModel | null; envMap: Texture | null; @@ -31,7 +35,7 @@ export class OculusHandPointerModel extends Object3D { raycaster: Raycaster; visible: boolean; - xrInputSource: unknown; + xrInputSource: XRInputSource; constructor(hand: Object3D, controller: Object3D); diff --git a/types/three/examples/jsm/webxr/XRControllerModelFactory.d.ts b/types/three/examples/jsm/webxr/XRControllerModelFactory.d.ts index 917d39a62..6e976e640 100644 --- a/types/three/examples/jsm/webxr/XRControllerModelFactory.d.ts +++ b/types/three/examples/jsm/webxr/XRControllerModelFactory.d.ts @@ -7,6 +7,8 @@ export class XRControllerModel extends Object3D { motionController: any; + envMap: Texture; + setEnvironmentMap(envMap: Texture): XRControllerModel; } diff --git a/types/three/examples/jsm/webxr/XREstimatedLight.d.ts b/types/three/examples/jsm/webxr/XREstimatedLight.d.ts index de00d3da9..10904c257 100644 --- a/types/three/examples/jsm/webxr/XREstimatedLight.d.ts +++ b/types/three/examples/jsm/webxr/XREstimatedLight.d.ts @@ -1,24 +1,24 @@ -import { DirectionalLight, Group, LightProbe, XRFrame, WebGLRenderer, Texture } from '../../../src/Three'; +import { DirectionalLight, Group, LightProbe, Texture, WebGLRenderer } from '../../../src/Three'; export class SessionLightProbe { xrLight: XREstimatedLight; renderer: WebGLRenderer; - lightProbe: unknown; - xrWebGLBinding: unknown | null; + lightProbe: LightProbe; + xrWebGLBinding: XRWebGLBinding | null; estimationStartCallback: () => void; frameCallback: (this: SessionLightProbe, time: number, xrFrame: XRFrame) => void; constructor( xrLight: XREstimatedLight, renderer: WebGLRenderer, - lightProbe: unknown, + lightProbe: LightProbe, environmentEstimation: boolean, estimationStartCallback: () => void, ); updateReflection: () => void; - onXRFrame: (time: number, xrFrame: XRFrame) => void; + onXRFrame: XRFrameRequestCallback; dispose: () => void; } diff --git a/types/three/examples/jsm/webxr/XRHandModelFactory.d.ts b/types/three/examples/jsm/webxr/XRHandModelFactory.d.ts index a40f73355..e6d4b218e 100644 --- a/types/three/examples/jsm/webxr/XRHandModelFactory.d.ts +++ b/types/three/examples/jsm/webxr/XRHandModelFactory.d.ts @@ -19,7 +19,7 @@ export class XRHandModelFactory { createHandModel( controller: Group, - profile?: 'spheres' | 'boxes' | 'oculus', + profile?: 'spheres' | 'boxes' | 'mesh', options?: XRHandPrimitiveModelOptions, ): XRHandModel; } diff --git a/types/three/src/renderers/WebGLRenderer.d.ts b/types/three/src/renderers/WebGLRenderer.d.ts index d41b0841d..7040c0a65 100644 --- a/types/three/src/renderers/WebGLRenderer.d.ts +++ b/types/three/src/renderers/WebGLRenderer.d.ts @@ -19,7 +19,6 @@ import { WebXRManager } from '../renderers/webxr/WebXRManager'; import { BufferGeometry } from './../core/BufferGeometry'; import { Texture } from '../textures/Texture'; import { Data3DTexture } from '../textures/Data3DTexture'; -import { XRAnimationLoopCallback } from './webxr/WebXR'; import { Vector3 } from '../math/Vector3'; import { Box3 } from '../math/Box3'; import { DataArrayTexture } from '../textures/DataArrayTexture'; @@ -336,7 +335,7 @@ export class WebGLRenderer implements Renderer { * A build in function that can be used instead of requestAnimationFrame. For WebXR projects this function must be used. * @param callback The function will be called every available frame. If `null` is passed it will stop any already ongoing animation. */ - setAnimationLoop(callback: XRAnimationLoopCallback | null): void; + setAnimationLoop(callback: XRFrameRequestCallback | null): void; /** * @deprecated Use {@link WebGLRenderer#setAnimationLoop .setAnimationLoop()} instead. diff --git a/types/three/src/renderers/webxr/WebXR.d.ts b/types/three/src/renderers/webxr/WebXR.d.ts index 3a8fc6558..10f9ea5e7 100644 --- a/types/three/src/renderers/webxr/WebXR.d.ts +++ b/types/three/src/renderers/webxr/WebXR.d.ts @@ -1,328 +1 @@ -export type XRSessionMode = 'inline' | 'immersive-vr' | 'immersive-ar'; - -export type XRReferenceSpaceType = 'viewer' | 'local' | 'local-floor' | 'bounded-floor' | 'unbounded'; - -export type XREnvironmentBlendMode = 'opaque' | 'additive' | 'alpha-blend'; - -export type XRVisibilityState = 'visible' | 'visible-blurred' | 'hidden'; - -export type XRHandedness = 'none' | 'left' | 'right'; - -export type XRTargetRayMode = 'gaze' | 'tracked-pointer' | 'screen'; - -export type XREye = 'none' | 'left' | 'right'; - -export type XREventType = - | 'end' - | 'select' - | 'selectstart' - | 'selectend' - | 'squeeze' - | 'squeezestart' - | 'squeezeend' - | 'inputsourceschange'; - -export type XRAnimationLoopCallback = (time: number, frame?: XRFrame) => void; - -export type XRFrameRequestCallback = (time: number, frame: XRFrame) => void; - -export interface XR extends EventTarget { - requestSession(mode: XRSessionMode, options?: XRSessionInit): Promise; - isSessionSupported(mode: XRSessionMode): Promise; -} - -export interface Window { - XRSession?: Constructor | undefined; - XR?: Constructor | undefined; -} - -export interface Navigator { - xr?: XR | undefined; -} - -export interface XRReferenceSpace extends EventTarget { - getOffsetReferenceSpace(originOffset: XRRigidTransform): XRReferenceSpace; -} -export interface XRHitTestOptionsInit { - space: EventTarget; - offsetRay?: XRRay | undefined; -} - -export interface XRTransientInputHitTestOptionsInit { - profile: string; - offsetRay?: XRRay | undefined; -} - -export interface XRViewport { - readonly x: number; - readonly y: number; - readonly width: number; - readonly height: number; -} - -export interface WebGLRenderingContext { - makeXRCompatible(): Promise; -} - -export interface XRRenderState { - readonly depthNear: number; - readonly depthFar: number; - readonly inlineVerticalFieldOfView?: number | undefined; - readonly baseLayer?: XRWebGLLayer | undefined; -} - -export interface XRRenderStateInit { - depthNear?: number | undefined; - depthFar?: number | undefined; - inlineVerticalFieldOfView?: number | undefined; - baseLayer?: XRWebGLLayer | undefined; -} - -export interface XRGamepad { - readonly id: string; - readonly index: number; // long - readonly connected: boolean; - readonly timestamp: DOMHighResTimeStamp; - readonly mapping: GamepadMappingType; - readonly axes: Float32Array; // FrozenArray; - readonly buttons: GamepadButton[]; // FrozenArray; -} - -export interface XRInputSource { - readonly handedness: XRHandedness; - readonly targetRayMode: XRTargetRayMode; - readonly targetRaySpace: EventTarget; - readonly gripSpace?: EventTarget | undefined; - readonly profiles: string[]; - readonly gamepad: XRGamepad; - readonly hand?: XRHand | undefined; -} - -export interface XRSessionInit { - optionalFeatures?: string[] | undefined; - requiredFeatures?: string[] | undefined; -} - -export interface XRSession extends EventTarget { - requestReferenceSpace(type: XRReferenceSpaceType): Promise; - updateRenderState(renderStateInit: XRRenderStateInit): Promise; - requestAnimationFrame(callback: XRFrameRequestCallback): number; - cancelAnimationFrame(id: number): void; - end(): Promise; - renderState: XRRenderState; - inputSources: XRInputSource[]; - environmentBlendMode: XREnvironmentBlendMode; - visibilityState: XRVisibilityState; - - // hit test - requestHitTestSource(options: XRHitTestOptionsInit): Promise; - requestHitTestSourceForTransientInput( - options: XRTransientInputHitTestOptionsInit, - ): Promise; - - // legacy AR hit test - requestHitTest(ray: XRRay, referenceSpace: XRReferenceSpace): Promise; - - // legacy plane detection - updateWorldTrackingState(options: { planeDetectionState?: { enabled: boolean } | undefined }): void; -} - -export interface XRReferenceSpace extends EventTarget { - getOffsetReferenceSpace(originOffset: XRRigidTransform): XRReferenceSpace; - onreset: any; -} - -export type XRPlaneSet = Set; -export type XRAnchorSet = Set; - -export interface XRFrame { - readonly session: XRSession; - getViewerPose(referenceSpace: XRReferenceSpace): XRViewerPose | undefined; - getPose(space: EventTarget, baseSpace: EventTarget): XRPose | undefined; - - // AR - getHitTestResults(hitTestSource: XRHitTestSource): XRHitTestResult[]; - getHitTestResultsForTransientInput(hitTestSource: XRTransientInputHitTestSource): XRTransientInputHitTestResult[]; - // Anchors - trackedAnchors?: XRAnchorSet | undefined; - createAnchor(pose: XRRigidTransform, space: EventTarget): Promise; - // Planes - worldInformation: { - detectedPlanes?: XRPlaneSet | undefined; - }; - // Hand tracking - getJointPose(joint: XRJointSpace, baseSpace: EventTarget): XRJointPose; -} - -export interface XRViewerPose { - readonly transform: XRRigidTransform; - readonly views: XRView[]; -} - -export interface XRPose { - readonly emulatedPosition: boolean; - readonly transform: XRRigidTransform; -} - -export interface XRWebGLLayerInit { - antialias?: boolean | undefined; - depth?: boolean | undefined; - stencil?: boolean | undefined; - alpha?: boolean | undefined; - ignoreDepthValues?: boolean | undefined; - framebufferScaleFactor?: number | undefined; -} - -export class XRWebGLLayer { - constructor(session: XRSession, gl: WebGLRenderingContext | undefined, options?: XRWebGLLayerInit); - framebuffer: WebGLFramebuffer; - framebufferWidth: number; - framebufferHeight: number; - getViewport(view: XRView): XRViewport; -} - -export interface DOMPointInit { - w?: number | undefined; - x?: number | undefined; - y?: number | undefined; - z?: number | undefined; -} - -export class XRRigidTransform { - constructor(matrix: Float32Array | DOMPointInit, direction?: DOMPointInit); - position: DOMPointReadOnly; - orientation: DOMPointReadOnly; - matrix: Float32Array; - inverse: XRRigidTransform; -} - -export interface XRView { - readonly eye: XREye; - readonly projectionMatrix: Float32Array; - readonly viewMatrix: Float32Array; - readonly transform: XRRigidTransform; -} - -export interface XRRayDirectionInit { - x?: number | undefined; - y?: number | undefined; - z?: number | undefined; - w?: number | undefined; -} - -export class XRRay { - readonly origin: DOMPointReadOnly; - readonly direction: XRRayDirectionInit; - matrix: Float32Array; - - constructor(transformOrOrigin: XRRigidTransform | DOMPointInit, direction?: XRRayDirectionInit); -} - -export enum XRHitTestTrackableType { - 'point', - 'plane', - 'mesh', -} - -export interface XRHitResult { - hitMatrix: Float32Array; -} - -export interface XRTransientInputHitTestResult { - readonly inputSource: XRInputSource; - readonly results: XRHitTestResult[]; -} - -export interface XRHitTestResult { - getPose(baseSpace: EventTarget): XRPose | undefined | null; - // When anchor system is enabled - createAnchor?(pose: XRRigidTransform): Promise; -} - -export interface XRHitTestSource { - cancel(): void; -} - -export interface XRTransientInputHitTestSource { - cancel(): void; -} - -export interface XRHitTestOptionsInit { - space: EventTarget; - entityTypes?: XRHitTestTrackableType[] | undefined; - offsetRay?: XRRay | undefined; -} - -export interface XRTransientInputHitTestOptionsInit { - profile: string; - entityTypes?: XRHitTestTrackableType[] | undefined; - offsetRay?: XRRay | undefined; -} - -export interface XRAnchor { - anchorSpace: EventTarget; - delete(): void; -} - -export interface XRPlane { - orientation: 'Horizontal' | 'Vertical'; - planeSpace: EventTarget; - polygon: DOMPointReadOnly[]; - lastChangedTime: number; -} - -export enum XRHandJoint { - 'wrist', - 'thumb-metacarpal', - 'thumb-phalanx-proximal', - 'thumb-phalanx-distal', - 'thumb-tip', - 'index-finger-metacarpal', - 'index-finger-phalanx-proximal', - 'index-finger-phalanx-intermediate', - 'index-finger-phalanx-distal', - 'index-finger-tip', - 'middle-finger-metacarpal', - 'middle-finger-phalanx-proximal', - 'middle-finger-phalanx-intermediate', - 'middle-finger-phalanx-distal', - 'middle-finger-tip', - 'ring-finger-metacarpal', - 'ring-finger-phalanx-proximal', - 'ring-finger-phalanx-intermediate', - 'ring-finger-phalanx-distal', - 'ring-finger-tip', - 'pinky-finger-metacarpal', - 'pinky-finger-phalanx-proximal', - 'pinky-finger-phalanx-intermediate', - 'pinky-finger-phalanx-distal', - 'pinky-finger-tip', -} - -export interface XRJointSpace extends EventTarget { - readonly jointName: XRHandJoint; -} - -export interface XRJointPose extends XRPose { - readonly radius: number | undefined; -} - -export interface XRHand extends Map { - readonly size: number; -} - -export interface Constructor { - new (...args: any[]): T; - prototype: T; -} - -export interface XRInputSourceChangeEvent { - session: XRSession; - removed: XRInputSource[]; - added: XRInputSource[]; -} - -export interface XRInputSourceEvent extends Event { - readonly frame: XRFrame; - readonly inputSource: XRInputSource; -} +import '@types/webxr'; diff --git a/types/three/src/renderers/webxr/WebXRController.d.ts b/types/three/src/renderers/webxr/WebXRController.d.ts index 061c0ce28..c50a36dda 100644 --- a/types/three/src/renderers/webxr/WebXRController.d.ts +++ b/types/three/src/renderers/webxr/WebXRController.d.ts @@ -1,7 +1,6 @@ import { Group } from '../../objects/Group'; -import { XREventType, XRFrame, XRInputSource, XRReferenceSpace } from './WebXR'; -export type XRControllerEventType = XREventType | 'disconnected' | 'connected'; +export type XRControllerEventType = XRSessionEventType | XRInputSourceEventType | 'disconnected' | 'connected'; export class WebXRController { constructor(); diff --git a/types/three/src/renderers/webxr/WebXRManager.d.ts b/types/three/src/renderers/webxr/WebXRManager.d.ts index 9efba0681..646de65af 100644 --- a/types/three/src/renderers/webxr/WebXRManager.d.ts +++ b/types/three/src/renderers/webxr/WebXRManager.d.ts @@ -1,7 +1,6 @@ import { Group } from '../../objects/Group'; import { Camera } from '../../cameras/Camera'; import { EventDispatcher } from '../../core/EventDispatcher'; -import { XRFrameRequestCallback, XRReferenceSpace, XRReferenceSpaceType, XRSession } from './WebXR'; export class WebXRManager extends EventDispatcher { constructor(renderer: any, gl: WebGLRenderingContext); diff --git a/types/three/test/renderers/webxr/webxr-vr-cube.ts b/types/three/test/renderers/webxr/webxr-vr-cube.ts index 83c884de3..076472ba6 100644 --- a/types/three/test/renderers/webxr/webxr-vr-cube.ts +++ b/types/three/test/renderers/webxr/webxr-vr-cube.ts @@ -9,12 +9,12 @@ const camera = new THREE.PerspectiveCamera(50, 2, 0.1, 10); const scene = new THREE.Scene(); const vrButton = document.createElement('button'); -let currentSession: THREE.XRSession | null = null; +let currentSession: XRSession | null = null; let mesh: THREE.Mesh; init(); -async function onSessionStarted(session: THREE.XRSession): Promise { +async function onSessionStarted(session: XRSession): Promise { session.addEventListener('end', onSessionEnded); await renderer.xr.setSession(session); @@ -34,12 +34,11 @@ function onSessionEnded(): void { currentSession = null; } -async function checkVRSupport(): Promise { - if ('xr' in navigator) { - const xr: THREE.XR = (navigator as any).xr; - const isSupported = await xr.isSessionSupported('immersive-vr').catch(() => false); +async function checkVRSupport(): Promise { + if ('xr' in navigator && navigator.xr) { + const isSupported = await navigator.xr.isSessionSupported('immersive-vr').catch(() => false); if (isSupported) { - return xr; + return navigator.xr; } else { return null; } diff --git a/yarn.lock b/yarn.lock index 2397aa83a..96d4033a0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -121,6 +121,11 @@ resolved "https://registry.yarnpkg.com/@types/parsimmon/-/parsimmon-1.10.6.tgz#8fcf95990514d2a7624aa5f630c13bf2427f9cdd" integrity sha512-FwAQwMRbkhx0J6YELkwIpciVzCcgEqXEbIrIn3a2P5d3kGEHQ3wVhlN3YdVepYP+bZzCYO6OjmD4o9TGOZ40rA== +"@types/webxr@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@types/webxr/-/webxr-0.4.0.tgz#ad06c96a324293e0d5175d13dd5ded5931f90ba3" + integrity sha512-LQvrACV3Pj17GpkwHwXuTd733gfY+D7b9mKdrTmLdO7vo7P/o6209Qqtk63y/FCv/lspdmi0pWz6Qe/ull9kQg== + ajv@^6.12.3: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"