three-stdlib 2.20.4 → 2.21.0
Sign up to get free protection for your applications and to get access to all the features.
- package/index.cjs.js +1 -1
- package/index.d.ts +1 -0
- package/libs/MotionControllers.cjs.js +1 -1
- package/libs/MotionControllers.d.ts +132 -0
- package/libs/MotionControllers.js +65 -13
- package/package.json +1 -1
- package/renderers/CSS2DRenderer.cjs.js +1 -1
- package/renderers/CSS2DRenderer.js +124 -99
- package/webxr/XRControllerModelFactory.cjs.js +1 -1
- package/webxr/XRControllerModelFactory.d.ts +12 -12
- package/webxr/XRControllerModelFactory.js +46 -21
package/index.d.ts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const
|
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"));const s={Handedness:Object.freeze({NONE:"none",LEFT:"left",RIGHT:"right"}),ComponentState:Object.freeze({DEFAULT:"default",TOUCHED:"touched",PRESSED:"pressed"}),ComponentProperty:Object.freeze({BUTTON:"button",X_AXIS:"xAxis",Y_AXIS:"yAxis",STATE:"state"}),ComponentType:Object.freeze({TRIGGER:"trigger",SQUEEZE:"squeeze",TOUCHPAD:"touchpad",THUMBSTICK:"thumbstick",BUTTON:"button"}),ButtonTouchThreshold:.05,AxisTouchThreshold:.1,VisualResponseProperty:Object.freeze({TRANSFORM:"transform",VISIBILITY:"visibility"})};async function o(e){const t=await fetch(e);if(t.ok)return t.json();throw new Error(t.statusText)}async function i(e){if(!e)throw new Error("No basePath supplied");return await o(`${e}/profilesList.json`)}const a={xAxis:0,yAxis:0,button:0,state:s.ComponentState.DEFAULT};class n{constructor(e){t.default(this,"value",void 0),t.default(this,"componentProperty",void 0),t.default(this,"states",void 0),t.default(this,"valueNodeName",void 0),t.default(this,"valueNodeProperty",void 0),t.default(this,"minNodeName",void 0),t.default(this,"maxNodeName",void 0),t.default(this,"valueNode",void 0),t.default(this,"minNode",void 0),t.default(this,"maxNode",void 0),this.componentProperty=e.componentProperty,this.states=e.states,this.valueNodeName=e.valueNodeName,this.valueNodeProperty=e.valueNodeProperty,this.valueNodeProperty===s.VisualResponseProperty.TRANSFORM&&(this.minNodeName=e.minNodeName,this.maxNodeName=e.maxNodeName),this.value=0,this.updateFromComponent(a)}updateFromComponent({xAxis:e,yAxis:t,button:o,state:i}){const{normalizedXAxis:a,normalizedYAxis:n}=function(e=0,t=0){let s=e,o=t;if(Math.sqrt(e*e+t*t)>1){const i=Math.atan2(t,e);s=Math.cos(i),o=Math.sin(i)}return{normalizedXAxis:.5*s+.5,normalizedYAxis:.5*o+.5}}(e,t);switch(this.componentProperty){case s.ComponentProperty.X_AXIS:this.value=this.states.includes(i)?a:.5;break;case s.ComponentProperty.Y_AXIS:this.value=this.states.includes(i)?n:.5;break;case s.ComponentProperty.BUTTON:this.value=this.states.includes(i)&&o?o:0;break;case s.ComponentProperty.STATE:this.valueNodeProperty===s.VisualResponseProperty.VISIBILITY?this.value=this.states.includes(i):this.value=this.states.includes(i)?1:0;break;default:throw new Error(`Unexpected visualResponse componentProperty ${this.componentProperty}`)}}}class r{constructor(e,o){if(t.default(this,"id",void 0),t.default(this,"values",void 0),t.default(this,"type",void 0),t.default(this,"gamepadIndices",void 0),t.default(this,"rootNodeName",void 0),t.default(this,"visualResponses",void 0),t.default(this,"touchPointNodeName",void 0),t.default(this,"touchPointNode",void 0),!(e&&o&&o.visualResponses&&o.gamepadIndices&&0!==Object.keys(o.gamepadIndices).length))throw new Error("Invalid arguments supplied");this.id=e,this.type=o.type,this.rootNodeName=o.rootNodeName,this.touchPointNodeName=o.touchPointNodeName,this.visualResponses={},Object.keys(o.visualResponses).forEach((e=>{const t=new n(o.visualResponses[e]);this.visualResponses[e]=t})),this.gamepadIndices=Object.assign({},o.gamepadIndices),this.values={state:s.ComponentState.DEFAULT,button:void 0!==this.gamepadIndices.button?0:void 0,xAxis:void 0!==this.gamepadIndices.xAxis?0:void 0,yAxis:void 0!==this.gamepadIndices.yAxis?0:void 0}}get data(){return{id:this.id,...this.values}}updateFromGamepad(e){if(this.values.state=s.ComponentState.DEFAULT,void 0!==this.gamepadIndices.button&&e.buttons.length>this.gamepadIndices.button){const t=e.buttons[this.gamepadIndices.button];this.values.button=t.value,this.values.button=this.values.button<0?0:this.values.button,this.values.button=this.values.button>1?1:this.values.button,t.pressed||1===this.values.button?this.values.state=s.ComponentState.PRESSED:(t.touched||this.values.button>s.ButtonTouchThreshold)&&(this.values.state=s.ComponentState.TOUCHED)}void 0!==this.gamepadIndices.xAxis&&e.axes.length>this.gamepadIndices.xAxis&&(this.values.xAxis=e.axes[this.gamepadIndices.xAxis],this.values.xAxis=this.values.xAxis<-1?-1:this.values.xAxis,this.values.xAxis=this.values.xAxis>1?1:this.values.xAxis,this.values.state===s.ComponentState.DEFAULT&&Math.abs(this.values.xAxis)>s.AxisTouchThreshold&&(this.values.state=s.ComponentState.TOUCHED)),void 0!==this.gamepadIndices.yAxis&&e.axes.length>this.gamepadIndices.yAxis&&(this.values.yAxis=e.axes[this.gamepadIndices.yAxis],this.values.yAxis=this.values.yAxis<-1?-1:this.values.yAxis,this.values.yAxis=this.values.yAxis>1?1:this.values.yAxis,this.values.state===s.ComponentState.DEFAULT&&Math.abs(this.values.yAxis)>s.AxisTouchThreshold&&(this.values.state=s.ComponentState.TOUCHED)),Object.values(this.visualResponses).forEach((e=>{e.updateFromComponent(this.values)}))}}exports.MotionController=class{constructor(e,s,o){if(t.default(this,"xrInputSource",void 0),t.default(this,"assetUrl",void 0),t.default(this,"layoutDescription",void 0),t.default(this,"id",void 0),t.default(this,"components",void 0),!e)throw new Error("No xrInputSource supplied");if(!s)throw new Error("No profile supplied");if(!s.layouts[e.handedness])throw new Error("No layout for "+e.handedness+" handedness");this.xrInputSource=e,this.assetUrl=o,this.id=s.profileId,this.layoutDescription=s.layouts[e.handedness],this.components={},Object.keys(this.layoutDescription.components).forEach((e=>{const t=this.layoutDescription.components[e];this.components[e]=new r(e,t)})),this.updateFromGamepad()}get gripSpace(){return this.xrInputSource.gripSpace}get targetRaySpace(){return this.xrInputSource.targetRaySpace}get data(){const e=[];return Object.values(this.components).forEach((t=>{e.push(t.data)})),e}updateFromGamepad(){Object.values(this.components).forEach((e=>{e.updateFromGamepad(this.xrInputSource.gamepad)}))}},exports.MotionControllerConstants=s,exports.fetchProfile=async function(e,t,s=null,a=!0){if(!e)throw new Error("No xrInputSource supplied");if(!t)throw new Error("No basePath supplied");const n=await i(t);let r;if(e.profiles.some((e=>{const s=n[e];return s&&(r={profileId:e,profilePath:`${t}/${s.path}`,deprecated:!!s.deprecated}),!!r})),!r){if(!s)throw new Error("No matching profile name found");const e=n[s];if(!e)throw new Error(`No matching profile name found and default profile "${s}" missing.`);r={profileId:s,profilePath:`${t}/${e.path}`,deprecated:!!e.deprecated}}const d=await o(r.profilePath);let u;if(a){let t;if(t="any"===e.handedness?d.layouts[Object.keys(d.layouts)[0]]:d.layouts[e.handedness],!t)throw new Error(`No matching handedness, ${e.handedness}, in profile ${r.profileId}`);t.assetPath&&(u=r.profilePath.replace("profile.json",t.assetPath))}return{profile:d,assetPath:u}},exports.fetchProfilesList=i;
|
@@ -0,0 +1,132 @@
|
|
1
|
+
import type { Object3D, XRGamepad, XRHandedness, XRInputSource } from 'three';
|
2
|
+
interface GamepadIndices {
|
3
|
+
button: number;
|
4
|
+
xAxis?: number;
|
5
|
+
yAxis?: number;
|
6
|
+
}
|
7
|
+
interface VisualResponseDescription {
|
8
|
+
componentProperty: string;
|
9
|
+
states: string[];
|
10
|
+
valueNodeProperty: string;
|
11
|
+
valueNodeName: string;
|
12
|
+
minNodeName?: string;
|
13
|
+
maxNodeName?: string;
|
14
|
+
}
|
15
|
+
declare type VisualResponses = Record<string, VisualResponseDescription>;
|
16
|
+
interface ComponentDescription {
|
17
|
+
type: string;
|
18
|
+
gamepadIndices: GamepadIndices;
|
19
|
+
rootNodeName: string;
|
20
|
+
visualResponses: VisualResponses;
|
21
|
+
touchPointNodeName?: string;
|
22
|
+
}
|
23
|
+
interface Components {
|
24
|
+
[componentKey: string]: ComponentDescription;
|
25
|
+
}
|
26
|
+
interface LayoutDescription {
|
27
|
+
selectComponentId: string;
|
28
|
+
components: Components;
|
29
|
+
gamepadMapping: string;
|
30
|
+
rootNodeName: string;
|
31
|
+
assetPath: string;
|
32
|
+
}
|
33
|
+
declare type Layouts = Partial<Record<XRHandedness, LayoutDescription>>;
|
34
|
+
export interface Profile {
|
35
|
+
profileId: string;
|
36
|
+
fallbackProfileIds: string[];
|
37
|
+
layouts: Layouts;
|
38
|
+
}
|
39
|
+
interface ProfilesList {
|
40
|
+
[profileId: string]: {
|
41
|
+
path: string;
|
42
|
+
deprecated?: boolean;
|
43
|
+
} | undefined;
|
44
|
+
}
|
45
|
+
declare const MotionControllerConstants: {
|
46
|
+
Handedness: Readonly<{
|
47
|
+
NONE: string;
|
48
|
+
LEFT: string;
|
49
|
+
RIGHT: string;
|
50
|
+
}>;
|
51
|
+
ComponentState: Readonly<{
|
52
|
+
DEFAULT: string;
|
53
|
+
TOUCHED: string;
|
54
|
+
PRESSED: string;
|
55
|
+
}>;
|
56
|
+
ComponentProperty: Readonly<{
|
57
|
+
BUTTON: string;
|
58
|
+
X_AXIS: string;
|
59
|
+
Y_AXIS: string;
|
60
|
+
STATE: string;
|
61
|
+
}>;
|
62
|
+
ComponentType: Readonly<{
|
63
|
+
TRIGGER: string;
|
64
|
+
SQUEEZE: string;
|
65
|
+
TOUCHPAD: string;
|
66
|
+
THUMBSTICK: string;
|
67
|
+
BUTTON: string;
|
68
|
+
}>;
|
69
|
+
ButtonTouchThreshold: number;
|
70
|
+
AxisTouchThreshold: number;
|
71
|
+
VisualResponseProperty: Readonly<{
|
72
|
+
TRANSFORM: string;
|
73
|
+
VISIBILITY: string;
|
74
|
+
}>;
|
75
|
+
};
|
76
|
+
declare function fetchProfilesList(basePath: string): Promise<ProfilesList>;
|
77
|
+
declare function fetchProfile(xrInputSource: XRInputSource, basePath: string, defaultProfile?: string | null, getAssetPath?: boolean): Promise<{
|
78
|
+
profile: Profile;
|
79
|
+
assetPath: string | undefined;
|
80
|
+
}>;
|
81
|
+
declare class VisualResponse implements VisualResponseDescription {
|
82
|
+
value: number | boolean;
|
83
|
+
componentProperty: string;
|
84
|
+
states: string[];
|
85
|
+
valueNodeName: string;
|
86
|
+
valueNodeProperty: string;
|
87
|
+
minNodeName?: string;
|
88
|
+
maxNodeName?: string;
|
89
|
+
valueNode: Object3D | undefined;
|
90
|
+
minNode: Object3D | undefined;
|
91
|
+
maxNode: Object3D | undefined;
|
92
|
+
constructor(visualResponseDescription: VisualResponseDescription);
|
93
|
+
updateFromComponent({ xAxis, yAxis, button, state, }: {
|
94
|
+
xAxis?: number;
|
95
|
+
yAxis?: number;
|
96
|
+
button?: number;
|
97
|
+
state: string;
|
98
|
+
}): void;
|
99
|
+
}
|
100
|
+
declare class Component implements ComponentDescription {
|
101
|
+
id: string;
|
102
|
+
values: {
|
103
|
+
state: string;
|
104
|
+
button: number | undefined;
|
105
|
+
xAxis: number | undefined;
|
106
|
+
yAxis: number | undefined;
|
107
|
+
};
|
108
|
+
type: string;
|
109
|
+
gamepadIndices: GamepadIndices;
|
110
|
+
rootNodeName: string;
|
111
|
+
visualResponses: Record<string, VisualResponse>;
|
112
|
+
touchPointNodeName?: string | undefined;
|
113
|
+
touchPointNode?: Object3D;
|
114
|
+
constructor(componentId: string, componentDescription: ComponentDescription);
|
115
|
+
get data(): {
|
116
|
+
id: Component['id'];
|
117
|
+
} & Component['values'];
|
118
|
+
updateFromGamepad(gamepad: XRGamepad): void;
|
119
|
+
}
|
120
|
+
declare class MotionController {
|
121
|
+
xrInputSource: XRInputSource;
|
122
|
+
assetUrl: string;
|
123
|
+
layoutDescription: LayoutDescription;
|
124
|
+
id: string;
|
125
|
+
components: Record<string, Component>;
|
126
|
+
constructor(xrInputSource: XRInputSource, profile: Profile, assetUrl: string);
|
127
|
+
get gripSpace(): XRInputSource['gripSpace'];
|
128
|
+
get targetRaySpace(): XRInputSource['targetRaySpace'];
|
129
|
+
get data(): Array<Component['data']>;
|
130
|
+
updateFromGamepad(): void;
|
131
|
+
}
|
132
|
+
export { MotionControllerConstants, MotionController, fetchProfile, fetchProfilesList };
|
@@ -1,3 +1,5 @@
|
|
1
|
+
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
|
2
|
+
|
1
3
|
/**
|
2
4
|
* @webxr-input-profiles/motion-controllers 1.0.0 https://github.com/immersive-web/webxr-input-profiles
|
3
5
|
*/
|
@@ -69,7 +71,7 @@ async function fetchProfile(xrInputSource, basePath, defaultProfile = null, getA
|
|
69
71
|
|
70
72
|
const supportedProfilesList = await fetchProfilesList(basePath); // Find the relative path to the first requested profile that is recognized
|
71
73
|
|
72
|
-
let match;
|
74
|
+
let match = undefined;
|
73
75
|
xrInputSource.profiles.some(profileId => {
|
74
76
|
const supportedProfile = supportedProfilesList[profileId];
|
75
77
|
|
@@ -103,7 +105,7 @@ async function fetchProfile(xrInputSource, basePath, defaultProfile = null, getA
|
|
103
105
|
}
|
104
106
|
|
105
107
|
const profile = await fetchJsonFile(match.profilePath);
|
106
|
-
let assetPath;
|
108
|
+
let assetPath = undefined;
|
107
109
|
|
108
110
|
if (getAssetPath) {
|
109
111
|
let layout;
|
@@ -142,8 +144,8 @@ const defaultComponentValues = {
|
|
142
144
|
* API) to the range 0 to 1 (for interpolation). Also caps the X, Y values to be bounded within
|
143
145
|
* a circle. This ensures that thumbsticks are not animated outside the bounds of their physical
|
144
146
|
* range of motion and touchpads do not report touch locations off their physical bounds.
|
145
|
-
* @param {number} x The original x coordinate in the range -1 to 1
|
146
|
-
* @param {number} y The original y coordinate in the range -1 to 1
|
147
|
+
* @param {number | undefined} x The original x coordinate in the range -1 to 1
|
148
|
+
* @param {number | undefined} y The original y coordinate in the range -1 to 1
|
147
149
|
*/
|
148
150
|
|
149
151
|
function normalizeAxes(x = 0, y = 0) {
|
@@ -179,6 +181,26 @@ function normalizeAxes(x = 0, y = 0) {
|
|
179
181
|
|
180
182
|
class VisualResponse {
|
181
183
|
constructor(visualResponseDescription) {
|
184
|
+
_defineProperty(this, "value", void 0);
|
185
|
+
|
186
|
+
_defineProperty(this, "componentProperty", void 0);
|
187
|
+
|
188
|
+
_defineProperty(this, "states", void 0);
|
189
|
+
|
190
|
+
_defineProperty(this, "valueNodeName", void 0);
|
191
|
+
|
192
|
+
_defineProperty(this, "valueNodeProperty", void 0);
|
193
|
+
|
194
|
+
_defineProperty(this, "minNodeName", void 0);
|
195
|
+
|
196
|
+
_defineProperty(this, "maxNodeName", void 0);
|
197
|
+
|
198
|
+
_defineProperty(this, "valueNode", void 0);
|
199
|
+
|
200
|
+
_defineProperty(this, "minNode", void 0);
|
201
|
+
|
202
|
+
_defineProperty(this, "maxNode", void 0);
|
203
|
+
|
182
204
|
this.componentProperty = visualResponseDescription.componentProperty;
|
183
205
|
this.states = visualResponseDescription.states;
|
184
206
|
this.valueNodeName = visualResponseDescription.valueNodeName;
|
@@ -196,9 +218,9 @@ class VisualResponse {
|
|
196
218
|
/**
|
197
219
|
* Computes the visual response's interpolation weight based on component state
|
198
220
|
* @param {Object} componentValues - The component from which to update
|
199
|
-
* @param {number} xAxis - The reported X axis value of the component
|
200
|
-
* @param {number} yAxis - The reported Y axis value of the component
|
201
|
-
* @param {number} button - The reported value of the component's button
|
221
|
+
* @param {number | undefined} xAxis - The reported X axis value of the component
|
222
|
+
* @param {number | undefined} yAxis - The reported Y axis value of the component
|
223
|
+
* @param {number | undefined} button - The reported value of the component's button
|
202
224
|
* @param {string} state - The component's active state
|
203
225
|
*/
|
204
226
|
|
@@ -224,7 +246,7 @@ class VisualResponse {
|
|
224
246
|
break;
|
225
247
|
|
226
248
|
case MotionControllerConstants.ComponentProperty.BUTTON:
|
227
|
-
this.value = this.states.includes(state) ? button : 0;
|
249
|
+
this.value = this.states.includes(state) && button ? button : 0;
|
228
250
|
break;
|
229
251
|
|
230
252
|
case MotionControllerConstants.ComponentProperty.STATE:
|
@@ -245,10 +267,26 @@ class VisualResponse {
|
|
245
267
|
|
246
268
|
class Component {
|
247
269
|
/**
|
248
|
-
* @param {
|
249
|
-
* @param {
|
270
|
+
* @param {string} componentId - Id of the component
|
271
|
+
* @param {InputProfileComponent} componentDescription - Description of the component to be created
|
250
272
|
*/
|
251
273
|
constructor(componentId, componentDescription) {
|
274
|
+
_defineProperty(this, "id", void 0);
|
275
|
+
|
276
|
+
_defineProperty(this, "values", void 0);
|
277
|
+
|
278
|
+
_defineProperty(this, "type", void 0);
|
279
|
+
|
280
|
+
_defineProperty(this, "gamepadIndices", void 0);
|
281
|
+
|
282
|
+
_defineProperty(this, "rootNodeName", void 0);
|
283
|
+
|
284
|
+
_defineProperty(this, "visualResponses", void 0);
|
285
|
+
|
286
|
+
_defineProperty(this, "touchPointNodeName", void 0);
|
287
|
+
|
288
|
+
_defineProperty(this, "touchPointNode", void 0);
|
289
|
+
|
252
290
|
if (!componentId || !componentDescription || !componentDescription.visualResponses || !componentDescription.gamepadIndices || Object.keys(componentDescription.gamepadIndices).length === 0) {
|
253
291
|
throw new Error('Invalid arguments supplied');
|
254
292
|
}
|
@@ -341,11 +379,21 @@ class Component {
|
|
341
379
|
|
342
380
|
class MotionController {
|
343
381
|
/**
|
344
|
-
* @param {
|
345
|
-
* @param {
|
346
|
-
* @param {
|
382
|
+
* @param {XRInputSource} xrInputSource - The XRInputSource to build the MotionController around
|
383
|
+
* @param {Profile} profile - The best matched profile description for the supplied xrInputSource
|
384
|
+
* @param {string} assetUrl
|
347
385
|
*/
|
348
386
|
constructor(xrInputSource, profile, assetUrl) {
|
387
|
+
_defineProperty(this, "xrInputSource", void 0);
|
388
|
+
|
389
|
+
_defineProperty(this, "assetUrl", void 0);
|
390
|
+
|
391
|
+
_defineProperty(this, "layoutDescription", void 0);
|
392
|
+
|
393
|
+
_defineProperty(this, "id", void 0);
|
394
|
+
|
395
|
+
_defineProperty(this, "components", void 0);
|
396
|
+
|
349
397
|
if (!xrInputSource) {
|
350
398
|
throw new Error('No xrInputSource supplied');
|
351
399
|
}
|
@@ -354,6 +402,10 @@ class MotionController {
|
|
354
402
|
throw new Error('No profile supplied');
|
355
403
|
}
|
356
404
|
|
405
|
+
if (!profile.layouts[xrInputSource.handedness]) {
|
406
|
+
throw new Error('No layout for ' + xrInputSource.handedness + ' handedness');
|
407
|
+
}
|
408
|
+
|
357
409
|
this.xrInputSource = xrInputSource;
|
358
410
|
this.assetUrl = assetUrl;
|
359
411
|
this.id = profile.profileId; // Build child components as described in the profile description
|
package/package.json
CHANGED
@@ -1 +1 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("three")
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("three");class t extends e.Object3D{constructor(e=document.createElement("div")){super(),this.isCSS2DObject=!0,this.element=e,this.element.style.position="absolute",this.element.style.userSelect="none",this.element.setAttribute("draggable",!1),this.addEventListener("removed",(function(){this.traverse((function(e){e.element instanceof Element&&null!==e.element.parentNode&&e.element.parentNode.removeChild(e.element)}))}))}copy(e,t){return super.copy(e,t),this.element=e.element.cloneNode(!0),this}}const r=new e.Vector3,n=new e.Matrix4,o=new e.Matrix4,i=new e.Vector3,s=new e.Vector3;exports.CSS2DObject=t,exports.CSS2DRenderer=class{constructor(e={}){const t=this;let l,a,d,c;const u={objects:new WeakMap},m=void 0!==e.element?e.element:document.createElement("div");function p(e,n,i){if(e.isCSS2DObject){r.setFromMatrixPosition(e.matrixWorld),r.applyMatrix4(o);const s=!0===e.visible&&r.z>=-1&&r.z<=1&&!0===e.layers.test(i.layers);if(e.element.style.display=!0===s?"":"none",!0===s){e.onBeforeRender(t,n,i);const o=e.element;o.style.transform="translate(-50%,-50%) translate("+(r.x*d+d)+"px,"+(-r.y*c+c)+"px)",o.parentNode!==m&&m.appendChild(o),e.onAfterRender(t,n,i)}const l={distanceToCameraSquared:h(i,e)};u.objects.set(e,l)}for(let t=0,r=e.children.length;t<r;t++)p(e.children[t],n,i)}function h(e,t){return i.setFromMatrixPosition(e.matrixWorld),s.setFromMatrixPosition(t.matrixWorld),i.distanceToSquared(s)}m.style.overflow="hidden",this.domElement=m,this.getSize=function(){return{width:l,height:a}},this.render=function(e,t){!0!==e.matrixWorldAutoUpdate&&!0!==e.autoUpdate||e.updateMatrixWorld(),null!==t.parent||null!=t.matrixWorldAutoUpdate&&!0!==t.matrixWorldAutoUpdate||t.updateMatrixWorld(),n.copy(t.matrixWorldInverse),o.multiplyMatrices(t.projectionMatrix,n),p(e,e,t),function(e){const t=function(e){const t=[];return e.traverse((function(e){e.isCSS2DObject&&t.push(e)})),t}(e).sort((function(e,t){if(e.renderOrder!==t.renderOrder)return t.renderOrder-e.renderOrder;return u.objects.get(e).distanceToCameraSquared-u.objects.get(t).distanceToCameraSquared})),r=t.length;for(let e=0,n=t.length;e<n;e++)t[e].element.style.zIndex=r-e}(e)},this.setSize=function(e,t){l=e,a=t,d=l/2,c=a/2,m.style.width=e+"px",m.style.height=t+"px"}}};
|
@@ -1,124 +1,149 @@
|
|
1
1
|
import { Object3D, Vector3, Matrix4 } from 'three';
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
this.
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
class CSS2DObject extends Object3D {
|
4
|
+
constructor(element = document.createElement('div')) {
|
5
|
+
super();
|
6
|
+
this.isCSS2DObject = true;
|
7
|
+
this.element = element;
|
8
|
+
this.element.style.position = 'absolute';
|
9
|
+
this.element.style.userSelect = 'none';
|
10
|
+
this.element.setAttribute('draggable', false);
|
11
|
+
this.addEventListener('removed', function () {
|
12
|
+
this.traverse(function (object) {
|
13
|
+
if (object.element instanceof Element && object.element.parentNode !== null) {
|
14
|
+
object.element.parentNode.removeChild(object.element);
|
15
|
+
}
|
16
|
+
});
|
12
17
|
});
|
13
|
-
}
|
14
|
-
};
|
18
|
+
}
|
15
19
|
|
16
|
-
|
17
|
-
|
18
|
-
copy: function (source, recursive) {
|
19
|
-
Object3D.prototype.copy.call(this, source, recursive);
|
20
|
+
copy(source, recursive) {
|
21
|
+
super.copy(source, recursive);
|
20
22
|
this.element = source.element.cloneNode(true);
|
21
23
|
return this;
|
22
24
|
}
|
23
|
-
}); //
|
24
25
|
|
25
|
-
|
26
|
-
|
26
|
+
}
|
27
|
+
|
28
|
+
const _vector = /*#__PURE__*/new Vector3();
|
29
|
+
|
30
|
+
const _viewMatrix = /*#__PURE__*/new Matrix4();
|
31
|
+
|
32
|
+
const _viewProjectionMatrix = /*#__PURE__*/new Matrix4();
|
27
33
|
|
28
|
-
|
34
|
+
const _a = /*#__PURE__*/new Vector3();
|
29
35
|
|
30
|
-
|
36
|
+
const _b = /*#__PURE__*/new Vector3();
|
31
37
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
var cache = {
|
36
|
-
objects: new WeakMap()
|
37
|
-
};
|
38
|
-
var domElement = document.createElement('div');
|
39
|
-
domElement.style.overflow = 'hidden';
|
40
|
-
this.domElement = domElement;
|
38
|
+
class CSS2DRenderer {
|
39
|
+
constructor(parameters = {}) {
|
40
|
+
const _this = this;
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
let _width, _height;
|
43
|
+
|
44
|
+
let _widthHalf, _heightHalf;
|
45
|
+
|
46
|
+
const cache = {
|
47
|
+
objects: new WeakMap()
|
46
48
|
};
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
domElement.style.height = height + 'px';
|
56
|
-
};
|
57
|
-
|
58
|
-
var renderObject = function (object, scene, camera) {
|
59
|
-
if (object instanceof CSS2DObject) {
|
60
|
-
object.onBeforeRender(_this, scene, camera);
|
61
|
-
vector.setFromMatrixPosition(object.matrixWorld);
|
62
|
-
vector.applyMatrix4(viewProjectionMatrix);
|
63
|
-
var element = object.element;
|
64
|
-
element.style.transform = 'translate(-50%,-50%) translate(' + (vector.x * _widthHalf + _widthHalf) + 'px,' + (-vector.y * _heightHalf + _heightHalf) + 'px)';
|
65
|
-
element.style.display = object.visible && vector.z >= -1 && vector.z <= 1 ? '' : 'none';
|
66
|
-
var objectData = {
|
67
|
-
distanceToCameraSquared: getDistanceToSquared(camera, object)
|
49
|
+
const domElement = parameters.element !== undefined ? parameters.element : document.createElement('div');
|
50
|
+
domElement.style.overflow = 'hidden';
|
51
|
+
this.domElement = domElement;
|
52
|
+
|
53
|
+
this.getSize = function () {
|
54
|
+
return {
|
55
|
+
width: _width,
|
56
|
+
height: _height
|
68
57
|
};
|
69
|
-
|
58
|
+
};
|
59
|
+
|
60
|
+
this.render = function (scene, camera) {
|
61
|
+
if (scene.matrixWorldAutoUpdate === true || scene.autoUpdate === true) scene.updateMatrixWorld();
|
62
|
+
if (camera.parent === null && (camera.matrixWorldAutoUpdate == null || camera.matrixWorldAutoUpdate === true)) camera.updateMatrixWorld();
|
63
|
+
|
64
|
+
_viewMatrix.copy(camera.matrixWorldInverse);
|
65
|
+
|
66
|
+
_viewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, _viewMatrix);
|
67
|
+
|
68
|
+
renderObject(scene, scene, camera);
|
69
|
+
zOrder(scene);
|
70
|
+
};
|
71
|
+
|
72
|
+
this.setSize = function (width, height) {
|
73
|
+
_width = width;
|
74
|
+
_height = height;
|
75
|
+
_widthHalf = _width / 2;
|
76
|
+
_heightHalf = _height / 2;
|
77
|
+
domElement.style.width = width + 'px';
|
78
|
+
domElement.style.height = height + 'px';
|
79
|
+
};
|
80
|
+
|
81
|
+
function renderObject(object, scene, camera) {
|
82
|
+
if (object.isCSS2DObject) {
|
83
|
+
_vector.setFromMatrixPosition(object.matrixWorld);
|
84
|
+
|
85
|
+
_vector.applyMatrix4(_viewProjectionMatrix);
|
70
86
|
|
71
|
-
|
72
|
-
|
87
|
+
const visible = object.visible === true && _vector.z >= -1 && _vector.z <= 1 && object.layers.test(camera.layers) === true;
|
88
|
+
object.element.style.display = visible === true ? '' : 'none';
|
89
|
+
|
90
|
+
if (visible === true) {
|
91
|
+
object.onBeforeRender(_this, scene, camera);
|
92
|
+
const element = object.element;
|
93
|
+
element.style.transform = 'translate(-50%,-50%) translate(' + (_vector.x * _widthHalf + _widthHalf) + 'px,' + (-_vector.y * _heightHalf + _heightHalf) + 'px)';
|
94
|
+
|
95
|
+
if (element.parentNode !== domElement) {
|
96
|
+
domElement.appendChild(element);
|
97
|
+
}
|
98
|
+
|
99
|
+
object.onAfterRender(_this, scene, camera);
|
100
|
+
}
|
101
|
+
|
102
|
+
const objectData = {
|
103
|
+
distanceToCameraSquared: getDistanceToSquared(camera, object)
|
104
|
+
};
|
105
|
+
cache.objects.set(object, objectData);
|
73
106
|
}
|
74
107
|
|
75
|
-
|
108
|
+
for (let i = 0, l = object.children.length; i < l; i++) {
|
109
|
+
renderObject(object.children[i], scene, camera);
|
110
|
+
}
|
76
111
|
}
|
77
112
|
|
78
|
-
|
79
|
-
|
113
|
+
function getDistanceToSquared(object1, object2) {
|
114
|
+
_a.setFromMatrixPosition(object1.matrixWorld);
|
115
|
+
|
116
|
+
_b.setFromMatrixPosition(object2.matrixWorld);
|
117
|
+
|
118
|
+
return _a.distanceToSquared(_b);
|
80
119
|
}
|
81
|
-
};
|
82
|
-
|
83
|
-
var getDistanceToSquared = function () {
|
84
|
-
var a = new Vector3();
|
85
|
-
var b = new Vector3();
|
86
|
-
return function (object1, object2) {
|
87
|
-
a.setFromMatrixPosition(object1.matrixWorld);
|
88
|
-
b.setFromMatrixPosition(object2.matrixWorld);
|
89
|
-
return a.distanceToSquared(b);
|
90
|
-
};
|
91
|
-
}();
|
92
120
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
});
|
107
|
-
var zMax = sorted.length;
|
121
|
+
function filterAndFlatten(scene) {
|
122
|
+
const result = [];
|
123
|
+
scene.traverse(function (object) {
|
124
|
+
if (object.isCSS2DObject) result.push(object);
|
125
|
+
});
|
126
|
+
return result;
|
127
|
+
}
|
128
|
+
|
129
|
+
function zOrder(scene) {
|
130
|
+
const sorted = filterAndFlatten(scene).sort(function (a, b) {
|
131
|
+
if (a.renderOrder !== b.renderOrder) {
|
132
|
+
return b.renderOrder - a.renderOrder;
|
133
|
+
}
|
108
134
|
|
109
|
-
|
110
|
-
|
135
|
+
const distanceA = cache.objects.get(a).distanceToCameraSquared;
|
136
|
+
const distanceB = cache.objects.get(b).distanceToCameraSquared;
|
137
|
+
return distanceA - distanceB;
|
138
|
+
});
|
139
|
+
const zMax = sorted.length;
|
140
|
+
|
141
|
+
for (let i = 0, l = sorted.length; i < l; i++) {
|
142
|
+
sorted[i].element.style.zIndex = zMax - i;
|
143
|
+
}
|
111
144
|
}
|
112
|
-
}
|
113
|
-
|
114
|
-
|
115
|
-
if (scene.autoUpdate === true) scene.updateMatrixWorld();
|
116
|
-
if (camera.parent === null) camera.updateMatrixWorld();
|
117
|
-
viewMatrix.copy(camera.matrixWorldInverse);
|
118
|
-
viewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, viewMatrix);
|
119
|
-
renderObject(scene, scene, camera);
|
120
|
-
zOrder(scene);
|
121
|
-
};
|
122
|
-
};
|
145
|
+
}
|
146
|
+
|
147
|
+
}
|
123
148
|
|
124
149
|
export { CSS2DObject, CSS2DRenderer };
|
@@ -1 +1 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@babel/runtime/helpers/defineProperty"),o=require("three"),t=require("../loaders/GLTFLoader.cjs.js"),n=require("../libs/MotionControllers.cjs.js");function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=r(e);const a=(e,t)=>{t.traverse((t=>{t instanceof o.Mesh&&"envMap"in t.material&&(t.material.envMap=e,t.material.needsUpdate=!0)}))};class l extends o.Object3D{constructor(){super(),s.default(this,"envMap",void 0),s.default(this,"motionController",void 0),this.motionController=null,this.envMap=null}setEnvironmentMap(e){return this.envMap==e||(this.envMap=e,a(this.envMap,this)),this}updateMatrixWorld(e){super.updateMatrixWorld(e),this.motionController&&(this.motionController.updateFromGamepad(),Object.values(this.motionController.components).forEach((e=>{Object.values(e.visualResponses).forEach((e=>{const{valueNode:o,minNode:t,maxNode:r,value:s,valueNodeProperty:a}=e;o&&(a===n.MotionControllerConstants.VisualResponseProperty.VISIBILITY&&"boolean"==typeof s?o.visible=s:a===n.MotionControllerConstants.VisualResponseProperty.TRANSFORM&&t&&r&&"number"==typeof s&&(o.quaternion.slerpQuaternions(t.quaternion,r.quaternion,s),o.position.lerpVectors(t.position,r.position,s)))}))})))}}function i(e,t){!function(e,t){Object.values(e.components).forEach((e=>{const{type:r,touchPointNodeName:s,visualResponses:a}=e;if(r===n.MotionControllerConstants.ComponentType.TOUCHPAD&&s)if(e.touchPointNode=t.getObjectByName(s),e.touchPointNode){const t=new o.SphereGeometry(.001),n=new o.MeshBasicMaterial({color:255}),r=new o.Mesh(t,n);e.touchPointNode.add(r)}else console.warn(`Could not find touch dot, ${e.touchPointNodeName}, in touchpad component ${e.id}`);Object.values(a).forEach((e=>{const{valueNodeName:o,minNodeName:r,maxNodeName:s,valueNodeProperty:a}=e;if(a===n.MotionControllerConstants.VisualResponseProperty.TRANSFORM&&r&&s){if(e.minNode=t.getObjectByName(r),e.maxNode=t.getObjectByName(s),!e.minNode)return void console.warn(`Could not find ${r} in the model`);if(!e.maxNode)return void console.warn(`Could not find ${s} in the model`)}e.valueNode=t.getObjectByName(o),e.valueNode||console.warn(`Could not find ${o} in the model`)}))}))}(e.motionController,t),e.envMap&&a(e.envMap,t),e.add(t)}exports.XRControllerModelFactory=class{constructor(e=null){s.default(this,"gltfLoader",void 0),s.default(this,"path",void 0),s.default(this,"_assetCache",void 0),this.gltfLoader=e,this.path="https://cdn.jsdelivr.net/npm/@webxr-input-profiles/assets@1.0/dist/profiles",this._assetCache={},this.gltfLoader||(this.gltfLoader=new t.GLTFLoader)}createControllerModel(e){const o=new l;let t=null;return e.addEventListener("connected",(e=>{const r=e.data;"tracked-pointer"===r.targetRayMode&&r.gamepad&&n.fetchProfile(r,this.path,"generic-trigger").then((({profile:e,assetPath:s})=>{if(!s)throw new Error("no asset path");o.motionController=new n.MotionController(r,e,s);const a=o.motionController.assetUrl,l=this._assetCache[a];if(l)t=l.scene.clone(),i(o,t);else{if(!this.gltfLoader)throw new Error("GLTFLoader not set.");this.gltfLoader.setPath(""),this.gltfLoader.load(o.motionController.assetUrl,(e=>{o.motionController?(this._assetCache[a]=e,t=e.scene.clone(),i(o,t)):console.warn("motionController gone while gltf load, bailing...")}),null,(()=>{throw new Error(`Asset ${a} missing or malformed.`)}))}})).catch((e=>{console.warn(e)}))})),e.addEventListener("disconnected",(()=>{o.motionController=null,t&&o.remove(t),t=null})),o}};
|
@@ -1,19 +1,19 @@
|
|
1
|
-
import {
|
2
|
-
|
1
|
+
import { Object3D } from 'three';
|
2
|
+
import type { Texture, Group } from 'three';
|
3
3
|
import { GLTFLoader } from '../loaders/GLTFLoader';
|
4
|
-
|
5
|
-
|
4
|
+
import { MotionController } from '../libs/MotionControllers';
|
5
|
+
declare class XRControllerModel extends Object3D {
|
6
|
+
envMap: Texture | null;
|
7
|
+
motionController: MotionController | null;
|
6
8
|
constructor();
|
7
|
-
|
8
|
-
motionController: any;
|
9
|
-
|
10
9
|
setEnvironmentMap(envMap: Texture): XRControllerModel;
|
10
|
+
updateMatrixWorld(force: boolean): void;
|
11
11
|
}
|
12
|
-
|
13
|
-
|
14
|
-
constructor(gltfLoader?: GLTFLoader);
|
15
|
-
gltfLoader: GLTFLoader | null;
|
12
|
+
declare class XRControllerModelFactory {
|
13
|
+
gltfLoader: GLTFLoader;
|
16
14
|
path: string;
|
17
|
-
|
15
|
+
private _assetCache;
|
16
|
+
constructor(gltfLoader?: GLTFLoader);
|
18
17
|
createControllerModel(controller: Group): XRControllerModel;
|
19
18
|
}
|
19
|
+
export { XRControllerModelFactory };
|