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
![](https://avatars.githubusercontent.com/u/86115165?v=4?s=100) Alejandro Laufer 🐛 💻 |
![](https://avatars.githubusercontent.com/u/1862172?v=4?s=100) Gianmarco 💻 |
![](https://avatars.githubusercontent.com/u/8783766?v=4?s=100) David Peicho 💻 |
- ![](https://avatars.githubusercontent.com/u/98544661?v=4?s=100) Subhankar Pal 💻 📖 |
![](https://avatars.githubusercontent.com/u/380881?v=4?s=100) Maccesch 💻 ⚠️ |
+ ![](https://avatars.githubusercontent.com/u/98544661?v=4?s=100) Subhankar Pal 💻 |
+ ![](https://avatars.githubusercontent.com/u/298046?v=4?s=100) 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"