three-stdlib 2.11.1 → 2.13.0

Sign up to get free protection for your applications and to get access to all the features.
package/index.d.ts CHANGED
@@ -104,6 +104,7 @@ export * from './objects/ReflectorRTT';
104
104
  export * from './objects/ReflectorForSSRPass';
105
105
  export * from './objects/Sky';
106
106
  export * from './objects/Water2';
107
+ export * from './objects/GroundProjectedEnv';
107
108
  export * from './utils/SceneUtils';
108
109
  export * from './utils/UVsDebug';
109
110
  export * from './utils/GeometryUtils';
package/index.js CHANGED
@@ -50,6 +50,7 @@ export { ReflectorRTT } from './objects/ReflectorRTT.js';
50
50
  export { ReflectorForSSRPass } from './objects/ReflectorForSSRPass.js';
51
51
  export { Sky } from './objects/Sky.js';
52
52
  export { Water2 } from './objects/Water2.js';
53
+ export { GroundProjectedEnv } from './objects/GroundProjectedEnv.js';
53
54
  export { SceneUtils } from './utils/SceneUtils.js';
54
55
  export { UVsDebug } from './utils/UVsDebug.js';
55
56
  export { GeometryUtils } from './utils/GeometryUtils.js';
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("three");class n extends e.Mesh{constructor(n,o){var t,r;const i=(a=n)&&a.isCubeTexture;var a;const c=(null!=(t=i?null===(r=n.image[0])||void 0===r?void 0:r.width:n.image.width)?t:1024)/4,s=Math.floor(Math.log2(c)),l=Math.pow(2,s),d=[i?"#define ENVMAP_TYPE_CUBE":"","#define CUBEUV_TEXEL_WIDTH "+1/(3*Math.max(l,112)),"#define CUBEUV_TEXEL_HEIGHT "+1/(4*l),`#define CUBEUV_MAX_MIP ${s}.0`].join("\n")+"\n #define ENVMAP_TYPE_CUBE_UV\n varying vec3 vWorldPosition;\n uniform float radius;\n uniform float height;\n uniform float angle;\n #ifdef ENVMAP_TYPE_CUBE\n uniform samplerCube map;\n #else\n uniform sampler2D map;\n #endif\n // From: https://www.shadertoy.com/view/4tsBD7\n float diskIntersectWithBackFaceCulling( vec3 ro, vec3 rd, vec3 c, vec3 n, float r ) \n {\n float d = dot ( rd, n );\n \n if( d > 0.0 ) { return 1e6; }\n \n vec3 o = ro - c;\n float t = - dot( n, o ) / d;\n vec3 q = o + rd * t;\n \n return ( dot( q, q ) < r * r ) ? t : 1e6;\n }\n // From: https://www.iquilezles.org/www/articles/intersectors/intersectors.htm\n float sphereIntersect( vec3 ro, vec3 rd, vec3 ce, float ra ) \n {\n vec3 oc = ro - ce;\n float b = dot( oc, rd );\n float c = dot( oc, oc ) - ra * ra;\n float h = b * b - c;\n \n if( h < 0.0 ) { return -1.0; }\n \n h = sqrt( h );\n \n return - b + h;\n }\n vec3 project() \n {\n vec3 p = normalize( vWorldPosition );\n vec3 camPos = cameraPosition;\n camPos.y -= height;\n float intersection = sphereIntersect( camPos, p, vec3( 0.0 ), radius );\n if( intersection > 0.0 ) {\n \n vec3 h = vec3( 0.0, - height, 0.0 );\n float intersection2 = diskIntersectWithBackFaceCulling( camPos, p, h, vec3( 0.0, 1.0, 0.0 ), radius );\n p = ( camPos + min( intersection, intersection2 ) * p ) / radius;\n } else {\n p = vec3( 0.0, 1.0, 0.0 );\n }\n return p;\n }\n #include <common>\n #include <cube_uv_reflection_fragment>\n void main() \n {\n vec3 projectedWorldPosition = project();\n \n #ifdef ENVMAP_TYPE_CUBE\n vec3 outcolor = textureCube( map, projectedWorldPosition ).rgb;\n #else\n vec3 direction = normalize( projectedWorldPosition );\n vec2 uv = equirectUv( direction );\n vec3 outcolor = texture2D( map, uv ).rgb;\n #endif\n gl_FragColor = vec4( outcolor, 1.0 );\n #include <tonemapping_fragment>\n #include <encodings_fragment>\n }\n ",u={map:{value:n},height:{value:(null==o?void 0:o.height)||15},radius:{value:(null==o?void 0:o.radius)||100}};super(new e.IcosahedronGeometry(1,16),new e.ShaderMaterial({uniforms:u,fragmentShader:d,vertexShader:"\n varying vec3 vWorldPosition;\n void main() \n {\n vec4 worldPosition = ( modelMatrix * vec4( position, 1.0 ) );\n vWorldPosition = worldPosition.xyz;\n \n gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n }\n ",side:e.DoubleSide}))}set radius(e){this.material.uniforms.radius.value=e}get radius(){return this.material.uniforms.radius.value}set height(e){this.material.uniforms.height.value=e}get height(){return this.material.uniforms.height.value}}exports.GroundProjectedEnv=n;
@@ -0,0 +1,12 @@
1
+ import { Mesh, ShaderMaterial, Texture, CubeTexture, BufferGeometry } from 'three';
2
+ export interface GroundProjectedEnvParameters {
3
+ height?: number;
4
+ radius?: number;
5
+ }
6
+ export declare class GroundProjectedEnv extends Mesh<BufferGeometry, ShaderMaterial> {
7
+ constructor(texture: CubeTexture | Texture, options?: GroundProjectedEnvParameters);
8
+ set radius(radius: number);
9
+ get radius(): number;
10
+ set height(height: number);
11
+ get height(): number;
12
+ }
@@ -0,0 +1,145 @@
1
+ import { Mesh, IcosahedronGeometry, ShaderMaterial, DoubleSide } from 'three';
2
+
3
+ const isCubeTexture = def => def && def.isCubeTexture;
4
+
5
+ class GroundProjectedEnv extends Mesh {
6
+ constructor(texture, options) {
7
+ var _ref, _texture$image$;
8
+
9
+ const isCubeMap = isCubeTexture(texture);
10
+ const w = (_ref = isCubeMap ? (_texture$image$ = texture.image[0]) === null || _texture$image$ === void 0 ? void 0 : _texture$image$.width : texture.image.width) != null ? _ref : 1024;
11
+ const cubeSize = w / 4;
12
+
13
+ const _lodMax = Math.floor(Math.log2(cubeSize));
14
+
15
+ const _cubeSize = Math.pow(2, _lodMax);
16
+
17
+ const width = 3 * Math.max(_cubeSize, 16 * 7);
18
+ const height = 4 * _cubeSize;
19
+ const defines = [isCubeMap ? '#define ENVMAP_TYPE_CUBE' : '', `#define CUBEUV_TEXEL_WIDTH ${1.0 / width}`, `#define CUBEUV_TEXEL_HEIGHT ${1.0 / height}`, `#define CUBEUV_MAX_MIP ${_lodMax}.0`];
20
+ const vertexShader =
21
+ /* glsl */
22
+ `
23
+ varying vec3 vWorldPosition;
24
+ void main()
25
+ {
26
+ vec4 worldPosition = ( modelMatrix * vec4( position, 1.0 ) );
27
+ vWorldPosition = worldPosition.xyz;
28
+
29
+ gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
30
+ }
31
+ `;
32
+ const fragmentShader = defines.join('\n') +
33
+ /* glsl */
34
+ `
35
+ #define ENVMAP_TYPE_CUBE_UV
36
+ varying vec3 vWorldPosition;
37
+ uniform float radius;
38
+ uniform float height;
39
+ uniform float angle;
40
+ #ifdef ENVMAP_TYPE_CUBE
41
+ uniform samplerCube map;
42
+ #else
43
+ uniform sampler2D map;
44
+ #endif
45
+ // From: https://www.shadertoy.com/view/4tsBD7
46
+ float diskIntersectWithBackFaceCulling( vec3 ro, vec3 rd, vec3 c, vec3 n, float r )
47
+ {
48
+ float d = dot ( rd, n );
49
+
50
+ if( d > 0.0 ) { return 1e6; }
51
+
52
+ vec3 o = ro - c;
53
+ float t = - dot( n, o ) / d;
54
+ vec3 q = o + rd * t;
55
+
56
+ return ( dot( q, q ) < r * r ) ? t : 1e6;
57
+ }
58
+ // From: https://www.iquilezles.org/www/articles/intersectors/intersectors.htm
59
+ float sphereIntersect( vec3 ro, vec3 rd, vec3 ce, float ra )
60
+ {
61
+ vec3 oc = ro - ce;
62
+ float b = dot( oc, rd );
63
+ float c = dot( oc, oc ) - ra * ra;
64
+ float h = b * b - c;
65
+
66
+ if( h < 0.0 ) { return -1.0; }
67
+
68
+ h = sqrt( h );
69
+
70
+ return - b + h;
71
+ }
72
+ vec3 project()
73
+ {
74
+ vec3 p = normalize( vWorldPosition );
75
+ vec3 camPos = cameraPosition;
76
+ camPos.y -= height;
77
+ float intersection = sphereIntersect( camPos, p, vec3( 0.0 ), radius );
78
+ if( intersection > 0.0 ) {
79
+
80
+ vec3 h = vec3( 0.0, - height, 0.0 );
81
+ float intersection2 = diskIntersectWithBackFaceCulling( camPos, p, h, vec3( 0.0, 1.0, 0.0 ), radius );
82
+ p = ( camPos + min( intersection, intersection2 ) * p ) / radius;
83
+ } else {
84
+ p = vec3( 0.0, 1.0, 0.0 );
85
+ }
86
+ return p;
87
+ }
88
+ #include <common>
89
+ #include <cube_uv_reflection_fragment>
90
+ void main()
91
+ {
92
+ vec3 projectedWorldPosition = project();
93
+
94
+ #ifdef ENVMAP_TYPE_CUBE
95
+ vec3 outcolor = textureCube( map, projectedWorldPosition ).rgb;
96
+ #else
97
+ vec3 direction = normalize( projectedWorldPosition );
98
+ vec2 uv = equirectUv( direction );
99
+ vec3 outcolor = texture2D( map, uv ).rgb;
100
+ #endif
101
+ gl_FragColor = vec4( outcolor, 1.0 );
102
+ #include <tonemapping_fragment>
103
+ #include <encodings_fragment>
104
+ }
105
+ `;
106
+ const uniforms = {
107
+ map: {
108
+ value: texture
109
+ },
110
+ height: {
111
+ value: (options === null || options === void 0 ? void 0 : options.height) || 15
112
+ },
113
+ radius: {
114
+ value: (options === null || options === void 0 ? void 0 : options.radius) || 100
115
+ }
116
+ };
117
+ const geometry = new IcosahedronGeometry(1, 16);
118
+ const material = new ShaderMaterial({
119
+ uniforms,
120
+ fragmentShader,
121
+ vertexShader,
122
+ side: DoubleSide
123
+ });
124
+ super(geometry, material);
125
+ }
126
+
127
+ set radius(radius) {
128
+ this.material.uniforms.radius.value = radius;
129
+ }
130
+
131
+ get radius() {
132
+ return this.material.uniforms.radius.value;
133
+ }
134
+
135
+ set height(height) {
136
+ this.material.uniforms.height.value = height;
137
+ }
138
+
139
+ get height() {
140
+ return this.material.uniforms.height.value;
141
+ }
142
+
143
+ }
144
+
145
+ export { GroundProjectedEnv };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "three-stdlib",
3
- "version": "2.11.1",
3
+ "version": "2.13.0",
4
4
  "private": false,
5
5
  "description": "stand-alone library of threejs examples",
6
6
  "main": "index.cjs.js",
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});exports.ARButton=class{static createButton(e,t={}){const n=document.createElement("button");function o(){n.style.display="",n.style.cursor="auto",n.style.left="calc(50% - 75px)",n.style.width="150px",n.onmouseenter=null,n.onmouseleave=null,n.onclick=null,n.textContent="AR NOT SUPPORTED"}function s(e){e.style.position="absolute",e.style.bottom="20px",e.style.padding="12px 6px",e.style.border="1px solid #fff",e.style.borderRadius="4px",e.style.background="rgba(0,0,0,0.1)",e.style.color="#fff",e.style.font="normal 13px sans-serif",e.style.textAlign="center",e.style.opacity="0.5",e.style.outline="none",e.style.zIndex="999"}if("xr"in navigator)return n.id="ARButton",n.style.display="none",s(n),navigator.xr.isSessionSupported("immersive-ar").then((function(s){s?function(){if(void 0===t.domOverlay){var o=document.createElement("div");o.style.display="none",document.body.appendChild(o);var s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("width",38),s.setAttribute("height",38),s.style.position="absolute",s.style.right="20px",s.style.top="20px",s.addEventListener("click",(function(){i.end()})),o.appendChild(s);var l=document.createElementNS("http://www.w3.org/2000/svg","path");l.setAttribute("d","M 12,12 L 28,28 M 28,12 12,28"),l.setAttribute("stroke","#fff"),l.setAttribute("stroke-width",2),s.appendChild(l),void 0===t.optionalFeatures&&(t.optionalFeatures=[]),t.optionalFeatures.push("dom-overlay"),t.domOverlay={root:o}}let i=null;async function r(o){o.addEventListener("end",a),e.xr.setReferenceSpaceType("local"),await e.xr.setSession(o),n.textContent="STOP AR",t.domOverlay.root.style.display="",i=o}function a(){i.removeEventListener("end",a),n.textContent="START AR",t.domOverlay.root.style.display="none",i=null}n.style.display="",n.style.cursor="pointer",n.style.left="calc(50% - 50px)",n.style.width="100px",n.textContent="START AR",n.onmouseenter=function(){n.style.opacity="1.0"},n.onmouseleave=function(){n.style.opacity="0.5"},n.onclick=function(){null===i?navigator.xr.requestSession("immersive-ar",t).then(r):i.end()}}():o()})).catch(o),n;{const e=document.createElement("a");return!1===window.isSecureContext?(e.href=document.location.href.replace(/^http:/,"https:"),e.innerHTML="WEBXR NEEDS HTTPS"):(e.href="https://immersiveweb.dev/",e.innerHTML="WEBXR NOT AVAILABLE"),e.style.left="calc(50% - 90px)",e.style.width="180px",e.style.textDecoration="none",s(e),e}}};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});exports.ARButton=class{static createButton(e,t={}){const n=document.createElement("button");function o(){n.style.display="",n.style.cursor="auto",n.style.left="calc(50% - 75px)",n.style.width="150px",n.onmouseenter=null,n.onmouseleave=null,n.onclick=null,n.textContent="AR NOT SUPPORTED"}function s(e){e.style.position="absolute",e.style.bottom="20px",e.style.padding="12px 6px",e.style.border="1px solid #fff",e.style.borderRadius="4px",e.style.background="rgba(0,0,0,0.1)",e.style.color="#fff",e.style.font="normal 13px sans-serif",e.style.textAlign="center",e.style.opacity="0.5",e.style.outline="none",e.style.zIndex="999"}if("xr"in navigator)return n.id="ARButton",n.style.display="none",s(n),navigator.xr.isSessionSupported("immersive-ar").then((function(s){s?function(){if(void 0===t.domOverlay){const e=document.createElement("div");e.style.display="none",document.body.appendChild(e);const n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("width","38px"),n.setAttribute("height","38px"),n.style.position="absolute",n.style.right="20px",n.style.top="20px",n.addEventListener("click",(function(){var e;null===(e=o)||void 0===e||e.end()})),e.appendChild(n);const s=document.createElementNS("http://www.w3.org/2000/svg","path");s.setAttribute("d","M 12,12 L 28,28 M 28,12 12,28"),s.setAttribute("stroke","#fff"),s.setAttribute("stroke-width","2px"),n.appendChild(s),void 0===t.optionalFeatures&&(t.optionalFeatures=[]),t.optionalFeatures.push("dom-overlay"),t.domOverlay={root:e}}let o=null;async function s(s){s.addEventListener("end",l),e.xr.setReferenceSpaceType("local"),await e.xr.setSession(s),n.textContent="STOP AR",t.domOverlay.root.style.display="",o=s}function l(){o.removeEventListener("end",l),n.textContent="START AR",t.domOverlay.root.style.display="none",o=null}n.style.display="",n.style.cursor="pointer",n.style.left="calc(50% - 50px)",n.style.width="100px",n.textContent="START AR",n.onmouseenter=()=>{n.style.opacity="1.0"},n.onmouseleave=()=>{n.style.opacity="0.5"},n.onclick=()=>{null===o?navigator.xr.requestSession("immersive-ar",t).then(s):o.end()}}():o()})).catch(o),n;{const e=document.createElement("a");return!1===window.isSecureContext?(e.href=document.location.href.replace(/^http:/,"https:"),e.innerHTML="WEBXR NEEDS HTTPS"):(e.href="https://immersiveweb.dev/",e.innerHTML="WEBXR NOT AVAILABLE"),e.style.left="calc(50% - 90px)",e.style.width="180px",e.style.textDecoration="none",s(e),e}}};
@@ -1,5 +1,5 @@
1
- import { WebGLRenderer } from 'three';
2
-
3
- export namespace ARButton {
4
- function createButton(renderer: WebGLRenderer, sessionInit?: any): HTMLElement;
1
+ import { WebGLRenderer, XRSessionInit } from 'three';
2
+ declare class ARButton {
3
+ static createButton(renderer: WebGLRenderer, sessionInit?: XRSessionInit): HTMLButtonElement | HTMLAnchorElement;
5
4
  }
5
+ export { ARButton };
package/webxr/ARButton.js CHANGED
@@ -6,23 +6,25 @@ class ARButton {
6
6
  /*device*/
7
7
  showStartAR() {
8
8
  if (sessionInit.domOverlay === undefined) {
9
- var overlay = document.createElement('div');
9
+ const overlay = document.createElement('div');
10
10
  overlay.style.display = 'none';
11
11
  document.body.appendChild(overlay);
12
- var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
13
- svg.setAttribute('width', 38);
14
- svg.setAttribute('height', 38);
12
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
13
+ svg.setAttribute('width', '38px');
14
+ svg.setAttribute('height', '38px');
15
15
  svg.style.position = 'absolute';
16
16
  svg.style.right = '20px';
17
17
  svg.style.top = '20px';
18
18
  svg.addEventListener('click', function () {
19
- currentSession.end();
19
+ var _currentSession;
20
+
21
+ (_currentSession = currentSession) === null || _currentSession === void 0 ? void 0 : _currentSession.end();
20
22
  });
21
23
  overlay.appendChild(svg);
22
- var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
24
+ const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
23
25
  path.setAttribute('d', 'M 12,12 L 28,28 M 28,12 12,28');
24
26
  path.setAttribute('stroke', '#fff');
25
- path.setAttribute('stroke-width', 2);
27
+ path.setAttribute('stroke-width', '2px');
26
28
  svg.appendChild(path);
27
29
 
28
30
  if (sessionInit.optionalFeatures === undefined) {
@@ -63,15 +65,15 @@ class ARButton {
63
65
  button.style.width = '100px';
64
66
  button.textContent = 'START AR';
65
67
 
66
- button.onmouseenter = function () {
68
+ button.onmouseenter = () => {
67
69
  button.style.opacity = '1.0';
68
70
  };
69
71
 
70
- button.onmouseleave = function () {
72
+ button.onmouseleave = () => {
71
73
  button.style.opacity = '0.5';
72
74
  };
73
75
 
74
- button.onclick = function () {
76
+ button.onclick = () => {
75
77
  if (currentSession === null) {
76
78
  navigator.xr.requestSession('immersive-ar', sessionInit).then(onSessionStarted);
77
79
  } else {
@@ -113,7 +115,8 @@ class ARButton {
113
115
  if ('xr' in navigator) {
114
116
  button.id = 'ARButton';
115
117
  button.style.display = 'none';
116
- stylizeElement(button);
118
+ stylizeElement(button) // Query for session mode
119
+ ;
117
120
  navigator.xr.isSessionSupported('immersive-ar').then(function (supported) {
118
121
  supported ? showStartAR() : showARNotSupported();
119
122
  }).catch(showARNotSupported);
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/defineProperty"),t=require("three"),o=require("./XRHandMeshModel.cjs.js");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}require("../loaders/GLTFLoader.cjs.js");var r=n(e);class s extends t.Object3D{constructor(e,t){super(),r.default(this,"controller",void 0),r.default(this,"motionController",void 0),r.default(this,"envMap",void 0),r.default(this,"mesh",void 0),r.default(this,"xrInputSource",void 0),this.controller=e,this.motionController=null,this.envMap=null,this.mesh=null,this.xrInputSource=null,e.addEventListener("connected",(n=>{const r=n.data;r.hand&&!this.motionController&&(this.xrInputSource=r,this.motionController=new o.XRHandMeshModel(this,e,void 0,r.handedness,"left"===r.handedness?null==t?void 0:t[0]:null==t?void 0:t[1]))})),e.addEventListener("disconnected",(()=>{this.dispose()}))}updateMatrixWorld(e){super.updateMatrixWorld(e),this.motionController&&this.motionController.updateMesh()}getPointerPosition(){const e=this.controller.joints["index-finger-tip"];return e?e.position:null}intersectBoxObject(e){const o=this.getPointerPosition();if(o){const n=new t.Sphere(o,.01),r=(new t.Box3).setFromObject(e);return n.intersectsBox(r)}return!1}checkButton(e){this.intersectBoxObject(e)?e.onPress():e.onClear(),e.isPressed()&&e.whilePressed()}dispose(){this.clear(),this.motionController=null}}exports.OculusHandModel=s;
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/defineProperty"),t=require("three"),o=require("./XRHandMeshModel.cjs.js");function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}require("../loaders/GLTFLoader.cjs.js");var n=r(e);class s extends t.Object3D{constructor(e,t,r){super(),n.default(this,"controller",void 0),n.default(this,"motionController",void 0),n.default(this,"envMap",void 0),n.default(this,"mesh",void 0),n.default(this,"xrInputSource",void 0),this.controller=e,this.motionController=null,this.envMap=null,this.mesh=null,this.xrInputSource=null,e.addEventListener("connected",(n=>{const s=n.data;s.hand&&!this.motionController&&(this.xrInputSource=s,this.motionController=new o.XRHandMeshModel(this,e,void 0,s.handedness,"left"===s.handedness?t:r))})),e.addEventListener("disconnected",(()=>{this.dispose()}))}updateMatrixWorld(e){super.updateMatrixWorld(e),this.motionController&&this.motionController.updateMesh()}getPointerPosition(){const e=this.controller.joints["index-finger-tip"];return e?e.position:null}intersectBoxObject(e){const o=this.getPointerPosition();if(o){const r=new t.Sphere(o,.01),n=(new t.Box3).setFromObject(e);return r.intersectsBox(n)}return!1}checkButton(e){this.intersectBoxObject(e)?e.onPress():e.onClear(),e.isPressed()&&e.whilePressed()}dispose(){this.clear(),this.motionController=null}}exports.OculusHandModel=s;
@@ -12,7 +12,7 @@ declare class OculusHandModel extends Object3D {
12
12
  envMap: Texture | null;
13
13
  mesh: Mesh | null;
14
14
  xrInputSource: XRInputSource | null;
15
- constructor(controller: Object3D, customModels?: string[]);
15
+ constructor(controller: Object3D, leftModelPath?: string, rightModelPath?: string);
16
16
  updateMatrixWorld(force?: boolean): void;
17
17
  getPointerPosition(): Vector3 | null;
18
18
  intersectBoxObject(boxObject: Object3D): boolean;
@@ -6,7 +6,7 @@ const TOUCH_RADIUS = 0.01;
6
6
  const POINTING_JOINT = 'index-finger-tip';
7
7
 
8
8
  class OculusHandModel extends Object3D {
9
- constructor(controller, customModels) {
9
+ constructor(controller, leftModelPath, rightModelPath) {
10
10
  super();
11
11
 
12
12
  _defineProperty(this, "controller", void 0);
@@ -29,7 +29,7 @@ class OculusHandModel extends Object3D {
29
29
 
30
30
  if (xrInputSource.hand && !this.motionController) {
31
31
  this.xrInputSource = xrInputSource;
32
- this.motionController = new XRHandMeshModel(this, controller, undefined, xrInputSource.handedness, xrInputSource.handedness === 'left' ? customModels === null || customModels === void 0 ? void 0 : customModels[0] : customModels === null || customModels === void 0 ? void 0 : customModels[1]);
32
+ this.motionController = new XRHandMeshModel(this, controller, undefined, xrInputSource.handedness, xrInputSource.handedness === 'left' ? leftModelPath : rightModelPath);
33
33
  }
34
34
  });
35
35
  controller.addEventListener('disconnected', () => {
@@ -1 +1 @@
1
- "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}Object.defineProperty(exports,"__esModule",{value:!0});var t=e(require("@babel/runtime/helpers/defineProperty"));class n{static createButton(e,t){t&&console.error('THREE.VRButton: The "options" parameter has been removed. Please set the reference space type via renderer.xr.setReferenceSpaceType() instead.');const o=document.createElement("button");function s(){o.style.display="",o.style.cursor="auto",o.style.left="calc(50% - 75px)",o.style.width="150px",o.onmouseenter=null,o.onmouseleave=null,o.onclick=null,o.textContent="VR NOT SUPPORTED"}function r(e){e.style.position="absolute",e.style.bottom="20px",e.style.padding="12px 6px",e.style.border="1px solid #fff",e.style.borderRadius="4px",e.style.background="rgba(0,0,0,0.1)",e.style.color="#fff",e.style.font="normal 13px sans-serif",e.style.textAlign="center",e.style.opacity="0.5",e.style.outline="none",e.style.zIndex="999"}if("xr"in navigator)return o.id="VRButton",o.style.display="none",r(o),navigator.xr.isSessionSupported("immersive-vr").then((function(t){t?function(){let t=null;async function n(n){n.addEventListener("end",s),await e.xr.setSession(n),o.textContent="EXIT VR",t=n}function s(){t.removeEventListener("end",s),o.textContent="ENTER VR",t=null}o.style.display="",o.style.cursor="pointer",o.style.left="calc(50% - 50px)",o.style.width="100px",o.textContent="ENTER VR",o.onmouseenter=function(){o.style.opacity="1.0"},o.onmouseleave=function(){o.style.opacity="0.5"},o.onclick=function(){if(null===t){const e={optionalFeatures:["local-floor","bounded-floor","hand-tracking","layers"]};navigator.xr.requestSession("immersive-vr",e).then(n)}else t.end()}}():s(),t&&n.xrSessionIsGranted&&o.click()})),o;{const e=document.createElement("a");return!1===window.isSecureContext?(e.href=document.location.href.replace(/^http:/,"https:"),e.innerHTML="WEBXR NEEDS HTTPS"):(e.href="https://immersiveweb.dev/",e.innerHTML="WEBXR NOT AVAILABLE"),e.style.left="calc(50% - 90px)",e.style.width="180px",e.style.textDecoration="none",r(e),e}}static registerSessionGrantedListener(){"xr"in navigator&&navigator.xr.addEventListener("sessiongranted",(()=>{n.xrSessionIsGranted=!0}))}}t.default(n,"xrSessionIsGranted",!1),exports.VRButton=n;
1
+ "use strict";function e(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}Object.defineProperty(exports,"__esModule",{value:!0});var t=e(require("@babel/runtime/helpers/defineProperty"));class n{static createButton(e,t={}){const o=document.createElement("button");function s(){o.style.display="",o.style.cursor="auto",o.style.left="calc(50% - 75px)",o.style.width="150px",o.onmouseenter=null,o.onmouseleave=null,o.onclick=null,o.textContent="VR NOT SUPPORTED"}function r(e){e.style.position="absolute",e.style.bottom="20px",e.style.padding="12px 6px",e.style.border="1px solid #fff",e.style.borderRadius="4px",e.style.background="rgba(0,0,0,0.1)",e.style.color="#fff",e.style.font="normal 13px sans-serif",e.style.textAlign="center",e.style.opacity="0.5",e.style.outline="none",e.style.zIndex="999"}if("xr"in navigator)return r(o),o.id="VRButton",o.style.display="none",navigator.xr.isSessionSupported("immersive-vr").then((r=>{r?function(){let n=null;async function s(t){t.addEventListener("end",r),await e.xr.setSession(t),o.textContent="EXIT VR",n=t}function r(){n.removeEventListener("end",r),o.textContent="ENTER VR",n=null}o.style.display="",o.style.cursor="pointer",o.style.left="calc(50% - 50px)",o.style.width="100px",o.textContent="ENTER VR",o.onmouseenter=()=>{o.style.opacity="1.0"},o.onmouseleave=()=>{o.style.opacity="0.5"},o.onclick=()=>{if(null===n){var e;const n=[t.optionalFeatures,"local-floor","bounded-floor","hand-tracking"].flat().filter(Boolean);null===(e=navigator.xr)||void 0===e||e.requestSession("immersive-vr",{...t,optionalFeatures:n}).then(s)}else n.end()}}():s(),r&&n.xrSessionIsGranted&&o.click()})),o;{const e=document.createElement("a");return!1===window.isSecureContext?(e.href=document.location.href.replace(/^http:/,"https:"),e.innerHTML="WEBXR NEEDS HTTPS"):(e.href="https://immersiveweb.dev/",e.innerHTML="WEBXR NOT AVAILABLE"),e.style.left="calc(50% - 90px)",e.style.width="180px",e.style.textDecoration="none",r(e),e}}static registerSessionGrantedListener(){"xr"in navigator&&navigator.xr.addEventListener("sessiongranted",(()=>{n.xrSessionIsGranted=!0}))}}t.default(n,"xrSessionIsGranted",!1),exports.VRButton=n;
@@ -1,5 +1,7 @@
1
- import { WebGLRenderer } from 'three';
2
-
3
- export namespace VRButton {
4
- function createButton(renderer: WebGLRenderer): HTMLElement;
1
+ import { WebGLRenderer, XRSessionInit } from 'three';
2
+ declare class VRButton {
3
+ static createButton(renderer: WebGLRenderer, sessionInit?: XRSessionInit): HTMLButtonElement | HTMLAnchorElement;
4
+ static xrSessionIsGranted: boolean;
5
+ static registerSessionGrantedListener(): void;
5
6
  }
7
+ export { VRButton };
package/webxr/VRButton.js CHANGED
@@ -1,11 +1,7 @@
1
1
  import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
2
2
 
3
3
  class VRButton {
4
- static createButton(renderer, options) {
5
- if (options) {
6
- console.error('THREE.VRButton: The "options" parameter has been removed. Please set the reference space type via renderer.xr.setReferenceSpaceType() instead.');
7
- }
8
-
4
+ static createButton(renderer, sessionInit = {}) {
9
5
  const button = document.createElement('button');
10
6
 
11
7
  function
@@ -35,26 +31,28 @@ class VRButton {
35
31
  button.style.width = '100px';
36
32
  button.textContent = 'ENTER VR';
37
33
 
38
- button.onmouseenter = function () {
34
+ button.onmouseenter = () => {
39
35
  button.style.opacity = '1.0';
40
36
  };
41
37
 
42
- button.onmouseleave = function () {
38
+ button.onmouseleave = () => {
43
39
  button.style.opacity = '0.5';
44
40
  };
45
41
 
46
- button.onclick = function () {
42
+ button.onclick = () => {
47
43
  if (currentSession === null) {
44
+ var _xr;
45
+
48
46
  // WebXR's requestReferenceSpace only works if the corresponding feature
49
47
  // was requested at session creation time. For simplicity, just ask for
50
48
  // the interesting ones as optional features, but be aware that the
51
49
  // requestReferenceSpace call will fail if it turns out to be unavailable.
52
50
  // ('local' is always available for immersive sessions and doesn't need to
53
51
  // be requested separately.)
54
- const sessionInit = {
55
- optionalFeatures: ['local-floor', 'bounded-floor', 'hand-tracking', 'layers']
56
- };
57
- navigator.xr.requestSession('immersive-vr', sessionInit).then(onSessionStarted);
52
+ const optionalFeatures = [sessionInit.optionalFeatures, 'local-floor', 'bounded-floor', 'hand-tracking'].flat().filter(Boolean);
53
+ (_xr = navigator.xr) === null || _xr === void 0 ? void 0 : _xr.requestSession('immersive-vr', { ...sessionInit,
54
+ optionalFeatures
55
+ }).then(onSessionStarted);
58
56
  } else {
59
57
  currentSession.end();
60
58
  }
@@ -92,10 +90,11 @@ class VRButton {
92
90
  }
93
91
 
94
92
  if ('xr' in navigator) {
95
- button.id = 'VRButton';
96
- button.style.display = 'none';
97
93
  stylizeElement(button);
98
- navigator.xr.isSessionSupported('immersive-vr').then(function (supported) {
94
+ button.id = 'VRButton';
95
+ button.style.display = 'none' // Query for session mode
96
+ ;
97
+ navigator.xr.isSessionSupported('immersive-vr').then(supported => {
99
98
  supported ? showEnterVR() : showWebXRNotFound();
100
99
 
101
100
  if (supported && VRButton.xrSessionIsGranted) {
@@ -3,7 +3,7 @@ declare class XRHandMeshModel {
3
3
  controller: Object3D;
4
4
  handModel: Object3D;
5
5
  bones: Object3D[];
6
- constructor(handModel: Object3D, controller: Object3D, path: string | undefined, handedness: string, customModel?: string);
6
+ constructor(handModel: Object3D, controller: Object3D, path: string | undefined, handedness: string, customModelPath?: string);
7
7
  updateMesh(): void;
8
8
  }
9
9
  export { XRHandMeshModel };
@@ -4,7 +4,7 @@ import { GLTFLoader } from '../loaders/GLTFLoader.js';
4
4
  const DEFAULT_HAND_PROFILE_PATH = 'https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@1.0/dist/profiles/generic-hand/';
5
5
 
6
6
  class XRHandMeshModel {
7
- constructor(handModel, controller, path = DEFAULT_HAND_PROFILE_PATH, handedness, customModel) {
7
+ constructor(handModel, controller, path = DEFAULT_HAND_PROFILE_PATH, handedness, customModelPath) {
8
8
  _defineProperty(this, "controller", void 0);
9
9
 
10
10
  _defineProperty(this, "handModel", void 0);
@@ -15,8 +15,8 @@ class XRHandMeshModel {
15
15
  this.handModel = handModel;
16
16
  this.bones = [];
17
17
  const loader = new GLTFLoader();
18
- if (!customModel) loader.setPath(path);
19
- loader.load(customModel != null ? customModel : `${handedness}.glb`, gltf => {
18
+ if (!customModelPath) loader.setPath(path);
19
+ loader.load(customModelPath != null ? customModelPath : `${handedness}.glb`, gltf => {
20
20
  const object = gltf.scene.children[0];
21
21
  this.handModel.add(object);
22
22
  const mesh = object.getObjectByProperty('type', 'SkinnedMesh');