three-stdlib 2.8.2 → 2.8.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. package/{BufferGeometryUtils-582025b8.js → BufferGeometryUtils-1a7a235c.js} +2 -1
  2. package/{BufferGeometryUtils-9eb5c2e7.js → BufferGeometryUtils-971dfde3.js} +0 -0
  3. package/animation/MMDAnimationHelper.d.ts +17 -17
  4. package/animation/MMDPhysics.d.ts +3 -3
  5. package/csm/CSM.d.ts +47 -22
  6. package/csm/CSMHelper.d.ts +20 -7
  7. package/effects/OutlineEffect.d.ts +4 -4
  8. package/effects/OutlineEffect.js +8 -2
  9. package/exporters/GLTFExporter.js +5 -10
  10. package/geometries/ConvexGeometry.d.ts +1 -1
  11. package/geometries/ParametricGeometries.d.ts +4 -2
  12. package/helpers/RectAreaLightHelper.d.ts +3 -3
  13. package/index.cjs.js +1 -1
  14. package/index.d.ts +9 -4
  15. package/index.js +9 -4
  16. package/libs/MotionControllers.cjs.js +1 -0
  17. package/libs/MotionControllers.js +403 -0
  18. package/loaders/AssimpLoader.js +39 -10
  19. package/loaders/ColladaLoader.js +22 -5
  20. package/loaders/EXRLoader.js +5 -1
  21. package/loaders/FBXLoader.js +10 -2
  22. package/loaders/GLTFLoader.cjs.js +1 -1
  23. package/loaders/GLTFLoader.d.ts +44 -20
  24. package/loaders/GLTFLoader.js +0 -1
  25. package/loaders/LDrawLoader.d.ts +6 -0
  26. package/loaders/MTLLoader.d.ts +18 -18
  27. package/loaders/RGBMLoader.d.ts +10 -10
  28. package/loaders/RGBMLoader.js +253 -178
  29. package/loaders/SVGLoader.d.ts +5 -3
  30. package/loaders/SVGLoader.js +10 -5
  31. package/loaders/lwo/IFFParser.js +4 -1
  32. package/math/OBB.d.ts +1 -1
  33. package/misc/GPUComputationRenderer.d.ts +8 -6
  34. package/misc/MD2CharacterComplex.js +9 -2
  35. package/misc/Volume.d.ts +2 -0
  36. package/modifiers/CurveModifier.cjs.js +1 -1
  37. package/modifiers/CurveModifier.js +1 -1
  38. package/modifiers/EdgeSplitModifier.cjs.js +1 -1
  39. package/modifiers/SimplifyModifier.cjs.js +1 -1
  40. package/nodes/inputs/ColorNode.d.ts +2 -2
  41. package/nodes/inputs/TextureNode.d.ts +3 -2
  42. package/nodes/materials/StandardNodeMaterial.d.ts +1 -1
  43. package/nodes/materials/nodes/StandardNode.d.ts +1 -0
  44. package/nodes/utils/ColorSpaceNode.d.ts +1 -1
  45. package/nodes/utils/JoinNode.d.ts +1 -0
  46. package/objects/MarchingCubes.d.ts +12 -4
  47. package/objects/Reflector.d.ts +4 -2
  48. package/objects/ReflectorForSSRPass.d.ts +6 -6
  49. package/objects/Refractor.d.ts +4 -2
  50. package/objects/Water.d.ts +4 -3
  51. package/objects/Water2.d.ts +12 -3
  52. package/package.json +2 -3
  53. package/postprocessing/ClearPass.d.ts +3 -3
  54. package/postprocessing/SAOPass.d.ts +3 -2
  55. package/postprocessing/SSAARenderPass.d.ts +3 -3
  56. package/postprocessing/SSAOPass.d.ts +3 -2
  57. package/postprocessing/SSRPass.d.ts +14 -17
  58. package/postprocessing/TAARenderPass.d.ts +2 -2
  59. package/renderers/CSS2DRenderer.d.ts +5 -1
  60. package/renderers/CSS3DRenderer.d.ts +5 -1
  61. package/renderers/webgpu/WebGPUTextures.js +62 -41
  62. package/shaders/SSRShader.d.ts +1 -2
  63. package/utils/BufferGeometryUtils.cjs.js +1 -1
  64. package/utils/BufferGeometryUtils.js +2 -1
  65. package/utils/LDrawUtils.cjs.js +1 -1
  66. package/utils/LDrawUtils.d.ts +5 -0
  67. package/utils/LDrawUtils.js +1 -1
  68. package/utils/RoughnessMipmapper.js +5 -1
  69. package/utils/SceneUtils.d.ts +10 -12
  70. package/utils/ShadowMapViewer.js +4 -1
  71. package/webxr/OculusHandModel.cjs.js +1 -0
  72. package/webxr/OculusHandModel.d.ts +19 -0
  73. package/webxr/OculusHandModel.js +72 -0
  74. package/webxr/OculusHandPointerModel.cjs.js +1 -0
  75. package/webxr/OculusHandPointerModel.d.ts +63 -0
  76. package/webxr/OculusHandPointerModel.js +248 -0
  77. package/webxr/Text2D.cjs.js +1 -0
  78. package/webxr/Text2D.d.ts +3 -0
  79. package/webxr/Text2D.js +32 -0
  80. package/webxr/VRButton.cjs.js +1 -1
  81. package/webxr/VRButton.js +17 -1
  82. package/webxr/XRControllerModelFactory.cjs.js +1 -1
  83. package/webxr/XRControllerModelFactory.js +65 -66
  84. package/webxr/XREstimatedLight.cjs.js +1 -1
  85. package/webxr/XREstimatedLight.js +1 -0
  86. package/webxr/XRHandMeshModel.cjs.js +1 -0
  87. package/webxr/XRHandMeshModel.d.ts +11 -0
  88. package/webxr/XRHandMeshModel.js +55 -0
  89. package/webxr/XRHandModelFactory.cjs.js +1 -1
  90. package/webxr/XRHandModelFactory.d.ts +3 -3
  91. package/webxr/XRHandModelFactory.js +47 -50
  92. package/webxr/XRHandPrimitiveModel.cjs.js +1 -1
  93. package/webxr/XRHandPrimitiveModel.d.ts +1 -1
  94. package/webxr/XRHandPrimitiveModel.js +31 -41
  95. package/csm/Frustum.d.ts +0 -16
  96. package/csm/Shader.d.ts +0 -6
  97. package/loaders/XLoader.d.ts +0 -19
  98. package/shaders/FresnelShader.d.ts +0 -13
  99. package/shaders/ParallaxShader.d.ts +0 -20
  100. package/utils/RoughnessMipmapper.d.ts +0 -7
  101. package/webxr/XRHandOculusMeshModel.cjs.js +0 -1
  102. package/webxr/XRHandOculusMeshModel.d.ts +0 -23
  103. package/webxr/XRHandOculusMeshModel.js +0 -89
package/index.d.ts CHANGED
@@ -233,12 +233,16 @@ export * from './postprocessing/ShaderPass';
233
233
  export * from './postprocessing/SSAARenderPass';
234
234
  export * from './postprocessing/RenderPass';
235
235
  export * from './postprocessing/BloomPass';
236
- export * from './webxr/XRHandModelFactory';
237
- export * from './webxr/XREstimatedLight';
238
- export * from './webxr/XRHandOculusMeshModel';
236
+ export * from './webxr/ARButton';
237
+ export * from './webxr/OculusHandModel';
238
+ export * from './webxr/OculusHandPointerModel';
239
+ export * from './webxr/Text2D';
239
240
  export * from './webxr/VRButton';
241
+ export * from './webxr/XRControllerModelFactory';
242
+ export * from './webxr/XREstimatedLight';
243
+ export * from './webxr/XRHandMeshModel';
244
+ export * from './webxr/XRHandModelFactory';
240
245
  export * from './webxr/XRHandPrimitiveModel';
241
- export * from './webxr/ARButton';
242
246
  export * from './geometries/ParametricGeometries';
243
247
  export * from './geometries/ConvexGeometry';
244
248
  export * from './geometries/LightningStrike';
@@ -384,3 +388,4 @@ export * from './curves/NURBSSurface';
384
388
  export * from './curves/CurveExtras';
385
389
  export * from './deprecated/Geometry';
386
390
  export * from './libs/MeshoptDecoder';
391
+ export * from './libs/MotionControllers';
package/index.js CHANGED
@@ -178,12 +178,16 @@ export { ShaderPass } from './postprocessing/ShaderPass.js';
178
178
  export { SSAARenderPass } from './postprocessing/SSAARenderPass.js';
179
179
  export { RenderPass } from './postprocessing/RenderPass.js';
180
180
  export { BloomPass } from './postprocessing/BloomPass.js';
181
- export { XRHandModelFactory } from './webxr/XRHandModelFactory.js';
182
- export { XREstimatedLight } from './webxr/XREstimatedLight.js';
183
- export { XRHandOculusMeshModel } from './webxr/XRHandOculusMeshModel.js';
181
+ export { ARButton } from './webxr/ARButton.js';
182
+ export { OculusHandModel } from './webxr/OculusHandModel.js';
183
+ export { OculusHandPointerModel } from './webxr/OculusHandPointerModel.js';
184
+ export { createText } from './webxr/Text2D.js';
184
185
  export { VRButton } from './webxr/VRButton.js';
186
+ export { XRControllerModelFactory } from './webxr/XRControllerModelFactory.js';
187
+ export { XREstimatedLight } from './webxr/XREstimatedLight.js';
188
+ export { XRHandMeshModel } from './webxr/XRHandMeshModel.js';
189
+ export { XRHandModelFactory } from './webxr/XRHandModelFactory.js';
185
190
  export { XRHandPrimitiveModel } from './webxr/XRHandPrimitiveModel.js';
186
- export { ARButton } from './webxr/ARButton.js';
187
191
  export { ParametricGeometries } from './geometries/ParametricGeometries.js';
188
192
  export { ConvexGeometry } from './geometries/ConvexGeometry.js';
189
193
  export { LightningStrike } from './geometries/LightningStrike.js';
@@ -327,3 +331,4 @@ export { NURBSSurface } from './curves/NURBSSurface.js';
327
331
  export { CinquefoilKnot, DecoratedTorusKnot4a, DecoratedTorusKnot4b, DecoratedTorusKnot5a, DecoratedTorusKnot5c, FigureEightPolynomialKnot, GrannyKnot, HeartCurve, HelixCurve, KnotCurve, TorusKnot, TrefoilKnot, TrefoilPolynomialKnot, VivianiCurve, scaleTo } from './curves/CurveExtras.js';
328
332
  export { Face3, Geometry } from './deprecated/Geometry.js';
329
333
  export { MeshoptDecoder } from './libs/MeshoptDecoder.js';
334
+ export { MotionController, MotionControllerConstants, fetchProfile, fetchProfilesList } from './libs/MotionControllers.js';
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});const e={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 t(e){const t=await fetch(e);if(t.ok)return t.json();throw new Error(t.statusText)}async function s(e){if(!e)throw new Error("No basePath supplied");return await t(`${e}/profilesList.json`)}const o={xAxis:0,yAxis:0,button:0,state:e.ComponentState.DEFAULT};class a{constructor(t){this.componentProperty=t.componentProperty,this.states=t.states,this.valueNodeName=t.valueNodeName,this.valueNodeProperty=t.valueNodeProperty,this.valueNodeProperty===e.VisualResponseProperty.TRANSFORM&&(this.minNodeName=t.minNodeName,this.maxNodeName=t.maxNodeName),this.value=0,this.updateFromComponent(o)}updateFromComponent({xAxis:t,yAxis:s,button:o,state:a}){const{normalizedXAxis:i,normalizedYAxis:n}=function(e=0,t=0){let s=e,o=t;if(Math.sqrt(e*e+t*t)>1){const a=Math.atan2(t,e);s=Math.cos(a),o=Math.sin(a)}return{normalizedXAxis:.5*s+.5,normalizedYAxis:.5*o+.5}}(t,s);switch(this.componentProperty){case e.ComponentProperty.X_AXIS:this.value=this.states.includes(a)?i:.5;break;case e.ComponentProperty.Y_AXIS:this.value=this.states.includes(a)?n:.5;break;case e.ComponentProperty.BUTTON:this.value=this.states.includes(a)?o:0;break;case e.ComponentProperty.STATE:this.valueNodeProperty===e.VisualResponseProperty.VISIBILITY?this.value=this.states.includes(a):this.value=this.states.includes(a)?1:0;break;default:throw new Error(`Unexpected visualResponse componentProperty ${this.componentProperty}`)}}}class i{constructor(t,s){if(!(t&&s&&s.visualResponses&&s.gamepadIndices&&0!==Object.keys(s.gamepadIndices).length))throw new Error("Invalid arguments supplied");this.id=t,this.type=s.type,this.rootNodeName=s.rootNodeName,this.touchPointNodeName=s.touchPointNodeName,this.visualResponses={},Object.keys(s.visualResponses).forEach((e=>{const t=new a(s.visualResponses[e]);this.visualResponses[e]=t})),this.gamepadIndices=Object.assign({},s.gamepadIndices),this.values={state:e.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(t){if(this.values.state=e.ComponentState.DEFAULT,void 0!==this.gamepadIndices.button&&t.buttons.length>this.gamepadIndices.button){const s=t.buttons[this.gamepadIndices.button];this.values.button=s.value,this.values.button=this.values.button<0?0:this.values.button,this.values.button=this.values.button>1?1:this.values.button,s.pressed||1===this.values.button?this.values.state=e.ComponentState.PRESSED:(s.touched||this.values.button>e.ButtonTouchThreshold)&&(this.values.state=e.ComponentState.TOUCHED)}void 0!==this.gamepadIndices.xAxis&&t.axes.length>this.gamepadIndices.xAxis&&(this.values.xAxis=t.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===e.ComponentState.DEFAULT&&Math.abs(this.values.xAxis)>e.AxisTouchThreshold&&(this.values.state=e.ComponentState.TOUCHED)),void 0!==this.gamepadIndices.yAxis&&t.axes.length>this.gamepadIndices.yAxis&&(this.values.yAxis=t.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===e.ComponentState.DEFAULT&&Math.abs(this.values.yAxis)>e.AxisTouchThreshold&&(this.values.state=e.ComponentState.TOUCHED)),Object.values(this.visualResponses).forEach((e=>{e.updateFromComponent(this.values)}))}}exports.MotionController=class{constructor(e,t,s){if(!e)throw new Error("No xrInputSource supplied");if(!t)throw new Error("No profile supplied");this.xrInputSource=e,this.assetUrl=s,this.id=t.profileId,this.layoutDescription=t.layouts[e.handedness],this.components={},Object.keys(this.layoutDescription.components).forEach((e=>{const t=this.layoutDescription.components[e];this.components[e]=new i(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=e,exports.fetchProfile=async function(e,o,a=null,i=!0){if(!e)throw new Error("No xrInputSource supplied");if(!o)throw new Error("No basePath supplied");const n=await s(o);let r;if(e.profiles.some((e=>{const t=n[e];return t&&(r={profileId:e,profilePath:`${o}/${t.path}`,deprecated:!!t.deprecated}),!!r})),!r){if(!a)throw new Error("No matching profile name found");const e=n[a];if(!e)throw new Error(`No matching profile name found and default profile "${a}" missing.`);r={profileId:a,profilePath:`${o}/${e.path}`,deprecated:!!e.deprecated}}const h=await t(r.profilePath);let u;if(i){let t;if(t="any"===e.handedness?h.layouts[Object.keys(h.layouts)[0]]:h.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:h,assetPath:u}},exports.fetchProfilesList=s;
@@ -0,0 +1,403 @@
1
+ /**
2
+ * @webxr-input-profiles/motion-controllers 1.0.0 https://github.com/immersive-web/webxr-input-profiles
3
+ */
4
+ const MotionControllerConstants = {
5
+ Handedness: Object.freeze({
6
+ NONE: 'none',
7
+ LEFT: 'left',
8
+ RIGHT: 'right'
9
+ }),
10
+ ComponentState: Object.freeze({
11
+ DEFAULT: 'default',
12
+ TOUCHED: 'touched',
13
+ PRESSED: 'pressed'
14
+ }),
15
+ ComponentProperty: Object.freeze({
16
+ BUTTON: 'button',
17
+ X_AXIS: 'xAxis',
18
+ Y_AXIS: 'yAxis',
19
+ STATE: 'state'
20
+ }),
21
+ ComponentType: Object.freeze({
22
+ TRIGGER: 'trigger',
23
+ SQUEEZE: 'squeeze',
24
+ TOUCHPAD: 'touchpad',
25
+ THUMBSTICK: 'thumbstick',
26
+ BUTTON: 'button'
27
+ }),
28
+ ButtonTouchThreshold: 0.05,
29
+ AxisTouchThreshold: 0.1,
30
+ VisualResponseProperty: Object.freeze({
31
+ TRANSFORM: 'transform',
32
+ VISIBILITY: 'visibility'
33
+ })
34
+ };
35
+ /**
36
+ * @description Static helper function to fetch a JSON file and turn it into a JS object
37
+ * @param {string} path - Path to JSON file to be fetched
38
+ */
39
+
40
+ async function fetchJsonFile(path) {
41
+ const response = await fetch(path);
42
+
43
+ if (!response.ok) {
44
+ throw new Error(response.statusText);
45
+ } else {
46
+ return response.json();
47
+ }
48
+ }
49
+
50
+ async function fetchProfilesList(basePath) {
51
+ if (!basePath) {
52
+ throw new Error('No basePath supplied');
53
+ }
54
+
55
+ const profileListFileName = 'profilesList.json';
56
+ const profilesList = await fetchJsonFile(`${basePath}/${profileListFileName}`);
57
+ return profilesList;
58
+ }
59
+
60
+ async function fetchProfile(xrInputSource, basePath, defaultProfile = null, getAssetPath = true) {
61
+ if (!xrInputSource) {
62
+ throw new Error('No xrInputSource supplied');
63
+ }
64
+
65
+ if (!basePath) {
66
+ throw new Error('No basePath supplied');
67
+ } // Get the list of profiles
68
+
69
+
70
+ const supportedProfilesList = await fetchProfilesList(basePath); // Find the relative path to the first requested profile that is recognized
71
+
72
+ let match;
73
+ xrInputSource.profiles.some(profileId => {
74
+ const supportedProfile = supportedProfilesList[profileId];
75
+
76
+ if (supportedProfile) {
77
+ match = {
78
+ profileId,
79
+ profilePath: `${basePath}/${supportedProfile.path}`,
80
+ deprecated: !!supportedProfile.deprecated
81
+ };
82
+ }
83
+
84
+ return !!match;
85
+ });
86
+
87
+ if (!match) {
88
+ if (!defaultProfile) {
89
+ throw new Error('No matching profile name found');
90
+ }
91
+
92
+ const supportedProfile = supportedProfilesList[defaultProfile];
93
+
94
+ if (!supportedProfile) {
95
+ throw new Error(`No matching profile name found and default profile "${defaultProfile}" missing.`);
96
+ }
97
+
98
+ match = {
99
+ profileId: defaultProfile,
100
+ profilePath: `${basePath}/${supportedProfile.path}`,
101
+ deprecated: !!supportedProfile.deprecated
102
+ };
103
+ }
104
+
105
+ const profile = await fetchJsonFile(match.profilePath);
106
+ let assetPath;
107
+
108
+ if (getAssetPath) {
109
+ let layout;
110
+
111
+ if (xrInputSource.handedness === 'any') {
112
+ layout = profile.layouts[Object.keys(profile.layouts)[0]];
113
+ } else {
114
+ layout = profile.layouts[xrInputSource.handedness];
115
+ }
116
+
117
+ if (!layout) {
118
+ throw new Error(`No matching handedness, ${xrInputSource.handedness}, in profile ${match.profileId}`);
119
+ }
120
+
121
+ if (layout.assetPath) {
122
+ assetPath = match.profilePath.replace('profile.json', layout.assetPath);
123
+ }
124
+ }
125
+
126
+ return {
127
+ profile,
128
+ assetPath
129
+ };
130
+ }
131
+ /** @constant {Object} */
132
+
133
+
134
+ const defaultComponentValues = {
135
+ xAxis: 0,
136
+ yAxis: 0,
137
+ button: 0,
138
+ state: MotionControllerConstants.ComponentState.DEFAULT
139
+ };
140
+ /**
141
+ * @description Converts an X, Y coordinate from the range -1 to 1 (as reported by the Gamepad
142
+ * API) to the range 0 to 1 (for interpolation). Also caps the X, Y values to be bounded within
143
+ * a circle. This ensures that thumbsticks are not animated outside the bounds of their physical
144
+ * 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
+ */
148
+
149
+ function normalizeAxes(x = 0, y = 0) {
150
+ let xAxis = x;
151
+ let yAxis = y; // Determine if the point is outside the bounds of the circle
152
+ // and, if so, place it on the edge of the circle
153
+
154
+ const hypotenuse = Math.sqrt(x * x + y * y);
155
+
156
+ if (hypotenuse > 1) {
157
+ const theta = Math.atan2(y, x);
158
+ xAxis = Math.cos(theta);
159
+ yAxis = Math.sin(theta);
160
+ } // Scale and move the circle so values are in the interpolation range. The circle's origin moves
161
+ // from (0, 0) to (0.5, 0.5). The circle's radius scales from 1 to be 0.5.
162
+
163
+
164
+ const result = {
165
+ normalizedXAxis: xAxis * 0.5 + 0.5,
166
+ normalizedYAxis: yAxis * 0.5 + 0.5
167
+ };
168
+ return result;
169
+ }
170
+ /**
171
+ * Contains the description of how the 3D model should visually respond to a specific user input.
172
+ * This is accomplished by initializing the object with the name of a node in the 3D model and
173
+ * property that need to be modified in response to user input, the name of the nodes representing
174
+ * the allowable range of motion, and the name of the input which triggers the change. In response
175
+ * to the named input changing, this object computes the appropriate weighting to use for
176
+ * interpolating between the range of motion nodes.
177
+ */
178
+
179
+
180
+ class VisualResponse {
181
+ constructor(visualResponseDescription) {
182
+ this.componentProperty = visualResponseDescription.componentProperty;
183
+ this.states = visualResponseDescription.states;
184
+ this.valueNodeName = visualResponseDescription.valueNodeName;
185
+ this.valueNodeProperty = visualResponseDescription.valueNodeProperty;
186
+
187
+ if (this.valueNodeProperty === MotionControllerConstants.VisualResponseProperty.TRANSFORM) {
188
+ this.minNodeName = visualResponseDescription.minNodeName;
189
+ this.maxNodeName = visualResponseDescription.maxNodeName;
190
+ } // Initializes the response's current value based on default data
191
+
192
+
193
+ this.value = 0;
194
+ this.updateFromComponent(defaultComponentValues);
195
+ }
196
+ /**
197
+ * Computes the visual response's interpolation weight based on component state
198
+ * @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
202
+ * @param {string} state - The component's active state
203
+ */
204
+
205
+
206
+ updateFromComponent({
207
+ xAxis,
208
+ yAxis,
209
+ button,
210
+ state
211
+ }) {
212
+ const {
213
+ normalizedXAxis,
214
+ normalizedYAxis
215
+ } = normalizeAxes(xAxis, yAxis);
216
+
217
+ switch (this.componentProperty) {
218
+ case MotionControllerConstants.ComponentProperty.X_AXIS:
219
+ this.value = this.states.includes(state) ? normalizedXAxis : 0.5;
220
+ break;
221
+
222
+ case MotionControllerConstants.ComponentProperty.Y_AXIS:
223
+ this.value = this.states.includes(state) ? normalizedYAxis : 0.5;
224
+ break;
225
+
226
+ case MotionControllerConstants.ComponentProperty.BUTTON:
227
+ this.value = this.states.includes(state) ? button : 0;
228
+ break;
229
+
230
+ case MotionControllerConstants.ComponentProperty.STATE:
231
+ if (this.valueNodeProperty === MotionControllerConstants.VisualResponseProperty.VISIBILITY) {
232
+ this.value = this.states.includes(state);
233
+ } else {
234
+ this.value = this.states.includes(state) ? 1.0 : 0.0;
235
+ }
236
+
237
+ break;
238
+
239
+ default:
240
+ throw new Error(`Unexpected visualResponse componentProperty ${this.componentProperty}`);
241
+ }
242
+ }
243
+
244
+ }
245
+
246
+ class Component {
247
+ /**
248
+ * @param {Object} componentId - Id of the component
249
+ * @param {Object} componentDescription - Description of the component to be created
250
+ */
251
+ constructor(componentId, componentDescription) {
252
+ if (!componentId || !componentDescription || !componentDescription.visualResponses || !componentDescription.gamepadIndices || Object.keys(componentDescription.gamepadIndices).length === 0) {
253
+ throw new Error('Invalid arguments supplied');
254
+ }
255
+
256
+ this.id = componentId;
257
+ this.type = componentDescription.type;
258
+ this.rootNodeName = componentDescription.rootNodeName;
259
+ this.touchPointNodeName = componentDescription.touchPointNodeName; // Build all the visual responses for this component
260
+
261
+ this.visualResponses = {};
262
+ Object.keys(componentDescription.visualResponses).forEach(responseName => {
263
+ const visualResponse = new VisualResponse(componentDescription.visualResponses[responseName]);
264
+ this.visualResponses[responseName] = visualResponse;
265
+ }); // Set default values
266
+
267
+ this.gamepadIndices = Object.assign({}, componentDescription.gamepadIndices);
268
+ this.values = {
269
+ state: MotionControllerConstants.ComponentState.DEFAULT,
270
+ button: this.gamepadIndices.button !== undefined ? 0 : undefined,
271
+ xAxis: this.gamepadIndices.xAxis !== undefined ? 0 : undefined,
272
+ yAxis: this.gamepadIndices.yAxis !== undefined ? 0 : undefined
273
+ };
274
+ }
275
+
276
+ get data() {
277
+ const data = {
278
+ id: this.id,
279
+ ...this.values
280
+ };
281
+ return data;
282
+ }
283
+ /**
284
+ * @description Poll for updated data based on current gamepad state
285
+ * @param {Object} gamepad - The gamepad object from which the component data should be polled
286
+ */
287
+
288
+
289
+ updateFromGamepad(gamepad) {
290
+ // Set the state to default before processing other data sources
291
+ this.values.state = MotionControllerConstants.ComponentState.DEFAULT; // Get and normalize button
292
+
293
+ if (this.gamepadIndices.button !== undefined && gamepad.buttons.length > this.gamepadIndices.button) {
294
+ const gamepadButton = gamepad.buttons[this.gamepadIndices.button];
295
+ this.values.button = gamepadButton.value;
296
+ this.values.button = this.values.button < 0 ? 0 : this.values.button;
297
+ this.values.button = this.values.button > 1 ? 1 : this.values.button; // Set the state based on the button
298
+
299
+ if (gamepadButton.pressed || this.values.button === 1) {
300
+ this.values.state = MotionControllerConstants.ComponentState.PRESSED;
301
+ } else if (gamepadButton.touched || this.values.button > MotionControllerConstants.ButtonTouchThreshold) {
302
+ this.values.state = MotionControllerConstants.ComponentState.TOUCHED;
303
+ }
304
+ } // Get and normalize x axis value
305
+
306
+
307
+ if (this.gamepadIndices.xAxis !== undefined && gamepad.axes.length > this.gamepadIndices.xAxis) {
308
+ this.values.xAxis = gamepad.axes[this.gamepadIndices.xAxis];
309
+ this.values.xAxis = this.values.xAxis < -1 ? -1 : this.values.xAxis;
310
+ this.values.xAxis = this.values.xAxis > 1 ? 1 : this.values.xAxis; // If the state is still default, check if the xAxis makes it touched
311
+
312
+ if (this.values.state === MotionControllerConstants.ComponentState.DEFAULT && Math.abs(this.values.xAxis) > MotionControllerConstants.AxisTouchThreshold) {
313
+ this.values.state = MotionControllerConstants.ComponentState.TOUCHED;
314
+ }
315
+ } // Get and normalize Y axis value
316
+
317
+
318
+ if (this.gamepadIndices.yAxis !== undefined && gamepad.axes.length > this.gamepadIndices.yAxis) {
319
+ this.values.yAxis = gamepad.axes[this.gamepadIndices.yAxis];
320
+ this.values.yAxis = this.values.yAxis < -1 ? -1 : this.values.yAxis;
321
+ this.values.yAxis = this.values.yAxis > 1 ? 1 : this.values.yAxis; // If the state is still default, check if the yAxis makes it touched
322
+
323
+ if (this.values.state === MotionControllerConstants.ComponentState.DEFAULT && Math.abs(this.values.yAxis) > MotionControllerConstants.AxisTouchThreshold) {
324
+ this.values.state = MotionControllerConstants.ComponentState.TOUCHED;
325
+ }
326
+ } // Update the visual response weights based on the current component data
327
+
328
+
329
+ Object.values(this.visualResponses).forEach(visualResponse => {
330
+ visualResponse.updateFromComponent(this.values);
331
+ });
332
+ }
333
+
334
+ }
335
+ /**
336
+ * @description Builds a motion controller with components and visual responses based on the
337
+ * supplied profile description. Data is polled from the xrInputSource's gamepad.
338
+ * @author Nell Waliczek / https://github.com/NellWaliczek
339
+ */
340
+
341
+
342
+ class MotionController {
343
+ /**
344
+ * @param {Object} xrInputSource - The XRInputSource to build the MotionController around
345
+ * @param {Object} profile - The best matched profile description for the supplied xrInputSource
346
+ * @param {Object} assetUrl
347
+ */
348
+ constructor(xrInputSource, profile, assetUrl) {
349
+ if (!xrInputSource) {
350
+ throw new Error('No xrInputSource supplied');
351
+ }
352
+
353
+ if (!profile) {
354
+ throw new Error('No profile supplied');
355
+ }
356
+
357
+ this.xrInputSource = xrInputSource;
358
+ this.assetUrl = assetUrl;
359
+ this.id = profile.profileId; // Build child components as described in the profile description
360
+
361
+ this.layoutDescription = profile.layouts[xrInputSource.handedness];
362
+ this.components = {};
363
+ Object.keys(this.layoutDescription.components).forEach(componentId => {
364
+ const componentDescription = this.layoutDescription.components[componentId];
365
+ this.components[componentId] = new Component(componentId, componentDescription);
366
+ }); // Initialize components based on current gamepad state
367
+
368
+ this.updateFromGamepad();
369
+ }
370
+
371
+ get gripSpace() {
372
+ return this.xrInputSource.gripSpace;
373
+ }
374
+
375
+ get targetRaySpace() {
376
+ return this.xrInputSource.targetRaySpace;
377
+ }
378
+ /**
379
+ * @description Returns a subset of component data for simplified debugging
380
+ */
381
+
382
+
383
+ get data() {
384
+ const data = [];
385
+ Object.values(this.components).forEach(component => {
386
+ data.push(component.data);
387
+ });
388
+ return data;
389
+ }
390
+ /**
391
+ * @description Poll for updated data based on current gamepad state
392
+ */
393
+
394
+
395
+ updateFromGamepad() {
396
+ Object.values(this.components).forEach(component => {
397
+ component.updateFromGamepad(this.xrInputSource.gamepad);
398
+ });
399
+ }
400
+
401
+ }
402
+
403
+ export { MotionController, MotionControllerConstants, fetchProfile, fetchProfilesList };
@@ -568,12 +568,30 @@ AssimpLoader.prototype = Object.assign(Object.create(Loader.prototype), {
568
568
  if (scene.mMaterials[this.mMaterialIndex]) mat = scene.mMaterials[this.mMaterialIndex].toTHREE(scene);else mat = new MeshLambertMaterial();
569
569
  geometry.setIndex(new BufferAttribute(new Uint32Array(this.mIndexArray), 1));
570
570
  geometry.setAttribute('position', new BufferAttribute(this.mVertexBuffer, 3));
571
- if (this.mNormalBuffer && this.mNormalBuffer.length > 0) geometry.setAttribute('normal', new BufferAttribute(this.mNormalBuffer, 3));
572
- if (this.mColorBuffer && this.mColorBuffer.length > 0) geometry.setAttribute('color', new BufferAttribute(this.mColorBuffer, 4));
573
- if (this.mTexCoordsBuffers[0] && this.mTexCoordsBuffers[0].length > 0) geometry.setAttribute('uv', new BufferAttribute(new Float32Array(this.mTexCoordsBuffers[0]), 2));
574
- if (this.mTexCoordsBuffers[1] && this.mTexCoordsBuffers[1].length > 0) geometry.setAttribute('uv1', new BufferAttribute(new Float32Array(this.mTexCoordsBuffers[1]), 2));
575
- if (this.mTangentBuffer && this.mTangentBuffer.length > 0) geometry.setAttribute('tangents', new BufferAttribute(this.mTangentBuffer, 3));
576
- if (this.mBitangentBuffer && this.mBitangentBuffer.length > 0) geometry.setAttribute('bitangents', new BufferAttribute(this.mBitangentBuffer, 3));
571
+
572
+ if (this.mNormalBuffer && this.mNormalBuffer.length > 0) {
573
+ geometry.setAttribute('normal', new BufferAttribute(this.mNormalBuffer, 3));
574
+ }
575
+
576
+ if (this.mColorBuffer && this.mColorBuffer.length > 0) {
577
+ geometry.setAttribute('color', new BufferAttribute(this.mColorBuffer, 4));
578
+ }
579
+
580
+ if (this.mTexCoordsBuffers[0] && this.mTexCoordsBuffers[0].length > 0) {
581
+ geometry.setAttribute('uv', new BufferAttribute(new Float32Array(this.mTexCoordsBuffers[0]), 2));
582
+ }
583
+
584
+ if (this.mTexCoordsBuffers[1] && this.mTexCoordsBuffers[1].length > 0) {
585
+ geometry.setAttribute('uv1', new BufferAttribute(new Float32Array(this.mTexCoordsBuffers[1]), 2));
586
+ }
587
+
588
+ if (this.mTangentBuffer && this.mTangentBuffer.length > 0) {
589
+ geometry.setAttribute('tangents', new BufferAttribute(this.mTangentBuffer, 3));
590
+ }
591
+
592
+ if (this.mBitangentBuffer && this.mBitangentBuffer.length > 0) {
593
+ geometry.setAttribute('bitangents', new BufferAttribute(this.mBitangentBuffer, 3));
594
+ }
577
595
 
578
596
  if (this.mBones.length > 0) {
579
597
  var weights = [];
@@ -824,10 +842,21 @@ AssimpLoader.prototype = Object.assign(Object.create(Loader.prototype), {
824
842
  var mat = new MeshPhongMaterial();
825
843
 
826
844
  for (let i = 0; i < this.mProperties.length; i++) {
827
- if (nameTypeMapping[this.mProperties[i].mKey] == 'float') mat[namePropMapping[this.mProperties[i].mKey]] = this.mProperties[i].dataAsFloat();
828
- if (nameTypeMapping[this.mProperties[i].mKey] == 'color') mat[namePropMapping[this.mProperties[i].mKey]] = this.mProperties[i].dataAsColor();
829
- if (nameTypeMapping[this.mProperties[i].mKey] == 'bool') mat[namePropMapping[this.mProperties[i].mKey]] = this.mProperties[i].dataAsBool();
830
- if (nameTypeMapping[this.mProperties[i].mKey] == 'string') mat[namePropMapping[this.mProperties[i].mKey]] = this.mProperties[i].dataAsString();
845
+ if (nameTypeMapping[this.mProperties[i].mKey] == 'float') {
846
+ mat[namePropMapping[this.mProperties[i].mKey]] = this.mProperties[i].dataAsFloat();
847
+ }
848
+
849
+ if (nameTypeMapping[this.mProperties[i].mKey] == 'color') {
850
+ mat[namePropMapping[this.mProperties[i].mKey]] = this.mProperties[i].dataAsColor();
851
+ }
852
+
853
+ if (nameTypeMapping[this.mProperties[i].mKey] == 'bool') {
854
+ mat[namePropMapping[this.mProperties[i].mKey]] = this.mProperties[i].dataAsBool();
855
+ }
856
+
857
+ if (nameTypeMapping[this.mProperties[i].mKey] == 'string') {
858
+ mat[namePropMapping[this.mProperties[i].mKey]] = this.mProperties[i].dataAsString();
859
+ }
831
860
 
832
861
  if (nameTypeMapping[this.mProperties[i].mKey] == 'map') {
833
862
  var prop = this.mProperties[i];
@@ -370,7 +370,11 @@ class ColladaLoader extends Loader {
370
370
  }
371
371
 
372
372
  if (positionData.length > 0) tracks.push(new VectorKeyframeTrack(name + '.position', times, positionData));
373
- if (quaternionData.length > 0) tracks.push(new QuaternionKeyframeTrack(name + '.quaternion', times, quaternionData));
373
+
374
+ if (quaternionData.length > 0) {
375
+ tracks.push(new QuaternionKeyframeTrack(name + '.quaternion', times, quaternionData));
376
+ }
377
+
374
378
  if (scaleData.length > 0) tracks.push(new VectorKeyframeTrack(name + '.scale', times, scaleData));
375
379
  return tracks;
376
380
  }
@@ -1835,13 +1839,26 @@ class ColladaLoader extends Loader {
1835
1839
  } // build geometry
1836
1840
 
1837
1841
 
1838
- if (position.array.length > 0) geometry.setAttribute('position', new Float32BufferAttribute(position.array, position.stride));
1839
- if (normal.array.length > 0) geometry.setAttribute('normal', new Float32BufferAttribute(normal.array, normal.stride));
1842
+ if (position.array.length > 0) {
1843
+ geometry.setAttribute('position', new Float32BufferAttribute(position.array, position.stride));
1844
+ }
1845
+
1846
+ if (normal.array.length > 0) {
1847
+ geometry.setAttribute('normal', new Float32BufferAttribute(normal.array, normal.stride));
1848
+ }
1849
+
1840
1850
  if (color.array.length > 0) geometry.setAttribute('color', new Float32BufferAttribute(color.array, color.stride));
1841
1851
  if (uv.array.length > 0) geometry.setAttribute('uv', new Float32BufferAttribute(uv.array, uv.stride));
1842
1852
  if (uv2.array.length > 0) geometry.setAttribute('uv2', new Float32BufferAttribute(uv2.array, uv2.stride));
1843
- if (skinIndex.array.length > 0) geometry.setAttribute('skinIndex', new Float32BufferAttribute(skinIndex.array, skinIndex.stride));
1844
- if (skinWeight.array.length > 0) geometry.setAttribute('skinWeight', new Float32BufferAttribute(skinWeight.array, skinWeight.stride));
1853
+
1854
+ if (skinIndex.array.length > 0) {
1855
+ geometry.setAttribute('skinIndex', new Float32BufferAttribute(skinIndex.array, skinIndex.stride));
1856
+ }
1857
+
1858
+ if (skinWeight.array.length > 0) {
1859
+ geometry.setAttribute('skinWeight', new Float32BufferAttribute(skinWeight.array, skinWeight.stride));
1860
+ }
1861
+
1845
1862
  build.data = geometry;
1846
1863
  build.type = primitives[0].type;
1847
1864
  build.materialKeys = materialKeys;
@@ -1067,7 +1067,11 @@ class EXRLoader extends DataTextureLoader {
1067
1067
  totalDcUncompressedCount: parseInt64(inDataView, inOffset),
1068
1068
  acCompression: parseInt64(inDataView, inOffset)
1069
1069
  };
1070
- if (dwaHeader.version < 2) throw 'EXRLoader.parse: ' + EXRHeader.compression + ' version ' + dwaHeader.version + ' is unsupported'; // Read channel ruleset information
1070
+
1071
+ if (dwaHeader.version < 2) {
1072
+ throw 'EXRLoader.parse: ' + EXRHeader.compression + ' version ' + dwaHeader.version + ' is unsupported';
1073
+ } // Read channel ruleset information
1074
+
1071
1075
 
1072
1076
  var channelRules = new Array();
1073
1077
  var ruleSize = parseUint16(inDataView, inOffset) - INT16_SIZE;
@@ -514,7 +514,11 @@ class FBXTreeParser {
514
514
  if (deformerNode.attrType === 'Skin') {
515
515
  const skeleton = this.parseSkeleton(relationships, DeformerNodes);
516
516
  skeleton.ID = nodeID;
517
- if (relationships.parents.length > 1) console.warn('THREE.FBXLoader: skeleton attached to more than one geometry is not supported.');
517
+
518
+ if (relationships.parents.length > 1) {
519
+ console.warn('THREE.FBXLoader: skeleton attached to more than one geometry is not supported.');
520
+ }
521
+
518
522
  skeleton.geometryID = relationships.parents[0].ID;
519
523
  skeletons[nodeID] = skeleton;
520
524
  } else if (deformerNode.attrType === 'BlendShape') {
@@ -523,7 +527,11 @@ class FBXTreeParser {
523
527
  };
524
528
  morphTarget.rawTargets = this.parseMorphTargets(relationships, DeformerNodes);
525
529
  morphTarget.id = nodeID;
526
- if (relationships.parents.length > 1) console.warn('THREE.FBXLoader: morph target attached to more than one geometry is not supported.');
530
+
531
+ if (relationships.parents.length > 1) {
532
+ console.warn('THREE.FBXLoader: morph target attached to more than one geometry is not supported.');
533
+ }
534
+
527
535
  morphTargets[nodeID] = morphTarget;
528
536
  }
529
537
  }