@iwsdk/core 1.0.0-rc.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/gaze/gaze-system.d.ts +207 -0
  2. package/dist/gaze/gaze-system.d.ts.map +1 -0
  3. package/dist/gaze/gaze-system.js +168 -0
  4. package/dist/gaze/gaze-system.js.map +1 -0
  5. package/dist/gaze/index.d.ts +8 -0
  6. package/dist/gaze/index.d.ts.map +1 -0
  7. package/dist/grab/grab-helpers.d.ts +7 -6
  8. package/dist/grab/grab-helpers.d.ts.map +1 -1
  9. package/dist/grab/grab-helpers.js +12 -7
  10. package/dist/grab/grab-helpers.js.map +1 -1
  11. package/dist/grab/grab-system.d.ts.map +1 -1
  12. package/dist/grab/grab-system.js +2 -1
  13. package/dist/grab/grab-system.js.map +1 -1
  14. package/dist/grab/handles.d.ts +10 -1
  15. package/dist/grab/handles.d.ts.map +1 -1
  16. package/dist/grab/handles.js +29 -6
  17. package/dist/grab/handles.js.map +1 -1
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/init/world-initializer.d.ts +49 -0
  23. package/dist/init/world-initializer.d.ts.map +1 -1
  24. package/dist/init/world-initializer.js +21 -8
  25. package/dist/init/world-initializer.js.map +1 -1
  26. package/dist/init/xr.d.ts +14 -0
  27. package/dist/init/xr.d.ts.map +1 -1
  28. package/dist/init/xr.js +19 -0
  29. package/dist/init/xr.js.map +1 -1
  30. package/dist/input/input-system.d.ts +3 -0
  31. package/dist/input/input-system.d.ts.map +1 -1
  32. package/dist/input/input-system.js +72 -6
  33. package/dist/input/input-system.js.map +1 -1
  34. package/dist/input/state-tags.d.ts.map +1 -1
  35. package/dist/input/state-tags.js +2 -0
  36. package/dist/input/state-tags.js.map +1 -1
  37. package/dist/project/normalize.d.ts.map +1 -1
  38. package/dist/project/normalize.js +11 -0
  39. package/dist/project/normalize.js.map +1 -1
  40. package/dist/project/types.d.ts +32 -2
  41. package/dist/project/types.d.ts.map +1 -1
  42. package/dist/project/types.js.map +1 -1
  43. package/dist/project/validation.d.ts.map +1 -1
  44. package/dist/project/validation.js +65 -1
  45. package/dist/project/validation.js.map +1 -1
  46. package/dist/schemas/iwsdk-project.v1.schema.json +45 -3
  47. package/dist/version.d.ts +1 -1
  48. package/dist/version.d.ts.map +1 -1
  49. package/dist/version.js +1 -1
  50. package/dist/version.js.map +1 -1
  51. package/package.json +4 -4
@@ -16,6 +16,7 @@ import { Transform } from '../transform/transform-component.js';
16
16
  * This source code is licensed under the MIT license found in the
17
17
  * LICENSE file in the root directory of this source tree.
18
18
  */
19
+ const NO_GAZE_CANDIDATES = [];
19
20
  /**
20
21
  * Samples XR poses (hands/controllers/head) and gamepads, curates the set of
21
22
  * interactables for pointer raycasting, and attaches minimal event listeners.
@@ -64,6 +65,7 @@ class InputSystem extends createSystem({
64
65
  this.grabDescendants = [];
65
66
  this.shouldSetIntersectables = false;
66
67
  this.listeners = new WeakMap();
68
+ this.listenerEntities = new Set();
67
69
  this.lastBVHUpdate = new WeakMap();
68
70
  }
69
71
  init() {
@@ -76,6 +78,10 @@ class InputSystem extends createSystem({
76
78
  value === VisibilityState.Visible ||
77
79
  this.config.maintainScenePointers.value;
78
80
  }));
81
+ const onSessionBoundary = () => this.clearPointerStates();
82
+ this.xrManager.addEventListener('sessionstart', onSessionBoundary);
83
+ this.xrManager.addEventListener('sessionend', onSessionBoundary);
84
+ this.cleanupFuncs.push(() => this.xrManager.removeEventListener('sessionstart', onSessionBoundary), () => this.xrManager.removeEventListener('sessionend', onSessionBoundary), () => this.cleanupAllEventListeners());
79
85
  // Wire pointer event listeners on qualify; tear them down on disqualify.
80
86
  // Descendant arrays are rebuilt every frame, so no dirty bookkeeping here.
81
87
  // Register the query subscriptions on cleanupFuncs so they're released on
@@ -104,6 +110,10 @@ class InputSystem extends createSystem({
104
110
  }
105
111
  }
106
112
  update(delta, time) {
113
+ // Gaze and hand rays consume the exact same target snapshot this frame.
114
+ this.input.xr.gazeCandidates = this.shouldSetIntersectables
115
+ ? this.rayDescendants
116
+ : NO_GAZE_CANDIDATES;
107
117
  // Update input sampling first
108
118
  this.input.update(this.xrManager, delta, time);
109
119
  // Rebuild interactable descendant arrays every frame so newly parented
@@ -115,7 +125,6 @@ class InputSystem extends createSystem({
115
125
  * Update per-type descendant arrays for optimized pointer intersection
116
126
  */
117
127
  updateDescendantArrays() {
118
- // Clear arrays
119
128
  this.rayDescendants.length = 0;
120
129
  this.touchDescendants.length = 0;
121
130
  this.grabDescendants.length = 0;
@@ -200,16 +209,24 @@ class InputSystem extends createSystem({
200
209
  const enter = (event) => {
201
210
  event.stopPropagation();
202
211
  maybeRefreshBVH();
212
+ pointerState.hovered.add(event.pointerId);
203
213
  if (!entity.hasComponent(Hovered)) {
204
214
  entity.addComponent(Hovered);
205
215
  }
206
216
  };
207
217
  const leave = (event) => {
208
218
  event.stopPropagation();
209
- entity.removeComponent(Hovered);
219
+ pointerState.hovered.delete(event.pointerId);
220
+ if (pointerState.hovered.size === 0) {
221
+ entity.removeComponent(Hovered);
222
+ }
210
223
  // pointerleave can fire without a preceding pointerup for flat geometry
211
- // (poke sphere exits intersection in one frame); clear Pressed defensively.
212
- entity.removeComponent(Pressed);
224
+ // (poke sphere exits intersection in one frame); clear only this
225
+ // pointer's press defensively.
226
+ pointerState.pressed.delete(event.pointerId);
227
+ if (pointerState.pressed.size === 0) {
228
+ entity.removeComponent(Pressed);
229
+ }
213
230
  };
214
231
  const down = (event) => {
215
232
  event.stopPropagation();
@@ -220,19 +237,48 @@ class InputSystem extends createSystem({
220
237
  if (!entity.hasComponent(Hovered)) {
221
238
  entity.addComponent(Hovered);
222
239
  }
240
+ pointerState.hovered.add(event.pointerId);
241
+ pointerState.pressed.add(event.pointerId);
223
242
  if (!entity.hasComponent(Pressed)) {
224
243
  entity.addComponent(Pressed);
225
244
  }
226
245
  };
227
246
  const up = (event) => {
228
247
  event.stopPropagation();
229
- entity.removeComponent(Pressed);
248
+ pointerState.pressed.delete(event.pointerId);
249
+ if (pointerState.pressed.size === 0) {
250
+ entity.removeComponent(Pressed);
251
+ }
252
+ };
253
+ const cancel = (event) => {
254
+ event.stopPropagation();
255
+ pointerState.hovered.delete(event.pointerId);
256
+ pointerState.pressed.delete(event.pointerId);
257
+ if (pointerState.hovered.size === 0) {
258
+ entity.removeComponent(Hovered);
259
+ }
260
+ if (pointerState.pressed.size === 0) {
261
+ entity.removeComponent(Pressed);
262
+ }
263
+ };
264
+ const pointerState = {
265
+ hovered: new Set(),
266
+ pressed: new Set(),
230
267
  };
231
- this.listeners.set(object3D, { enter, leave, down, up });
268
+ this.listeners.set(object3D, {
269
+ enter,
270
+ leave,
271
+ down,
272
+ up,
273
+ cancel,
274
+ ...pointerState,
275
+ });
276
+ this.listenerEntities.add(entity);
232
277
  object3D.addEventListener('pointerenter', enter);
233
278
  object3D.addEventListener('pointerleave', leave);
234
279
  object3D.addEventListener('pointerdown', down);
235
280
  object3D.addEventListener('pointerup', up);
281
+ object3D.addEventListener('pointercancel', cancel);
236
282
  }
237
283
  computeBoundsTreeForEntity(object3D) {
238
284
  object3D.traverse((child) => {
@@ -252,7 +298,24 @@ class InputSystem extends createSystem({
252
298
  }
253
299
  });
254
300
  }
301
+ clearPointerStates() {
302
+ for (const entity of this.listenerEntities) {
303
+ const object3D = entity.object3D;
304
+ const state = object3D ? this.listeners.get(object3D) : undefined;
305
+ state === null || state === void 0 ? void 0 : state.hovered.clear();
306
+ state === null || state === void 0 ? void 0 : state.pressed.clear();
307
+ if (entity.active) {
308
+ entity.removeComponent(Hovered).removeComponent(Pressed);
309
+ }
310
+ }
311
+ }
312
+ cleanupAllEventListeners() {
313
+ for (const entity of [...this.listenerEntities]) {
314
+ this.cleanupEventListeners(entity);
315
+ }
316
+ }
255
317
  cleanupEventListeners(entity) {
318
+ this.listenerEntities.delete(entity);
256
319
  const object3D = entity.object3D;
257
320
  if (!object3D) {
258
321
  return;
@@ -263,6 +326,9 @@ class InputSystem extends createSystem({
263
326
  object3D.removeEventListener('pointerleave', fns.leave);
264
327
  object3D.removeEventListener('pointerdown', fns.down);
265
328
  object3D.removeEventListener('pointerup', fns.up);
329
+ object3D.removeEventListener('pointercancel', fns.cancel);
330
+ fns.hovered.clear();
331
+ fns.pressed.clear();
266
332
  this.listeners.delete(object3D);
267
333
  }
268
334
  // A query also disqualifies an entity when it is destroyed. At that point
@@ -1 +1 @@
1
- {"version":3,"file":"input-system.js","sources":["../../src/input/input-system.ts"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport type { PointerEvent, PointerEventsMap } from '@pmndrs/pointer-events';\nimport { Types } from '../ecs/component.js';\nimport { Entity } from '../ecs/entity.js';\nimport { createSystem } from '../ecs/system.js';\nimport { VisibilityState } from '../ecs/world.js';\nimport { DistanceGrabbable } from '../grab/distance-grabbable.js';\nimport { OneHandGrabbable } from '../grab/one-hand-grabbable.js';\nimport { TwoHandsGrabbable } from '../grab/two-hands-grabbable.js';\nimport { Mesh, Object3D, Object3DEventMap } from '../runtime/index.js';\nimport { Transform } from '../transform/index.js';\nimport {\n Hovered,\n PokeInteractable,\n Pressed,\n RayInteractable,\n} from './state-tags.js';\n\n/**\n * Samples XR poses (hands/controllers/head) and gamepads, curates the set of\n * interactables for pointer raycasting, and attaches minimal event listeners.\n *\n * @remarks\n * - Scheduled after player movement so pointers reflect updated transforms.\n * - Maintains type-specific descendant arrays for optimized pointer intersection.\n * - Adds transient `Hovered` / `Pressed` tags so other systems can react declaratively.\n *\n * @category Input\n * @example React to Hovered / Pressed\n * ```ts\n * export class HighlightSystem extends createSystem({\n * items: { required: [RayInteractable] }\n * }) {\n * update() {\n * this.queries.items.entities.forEach(e => {\n * e.object3D.visible = !e.hasComponent(Pressed);\n * })\n * }\n * }\n * ```\n */\nexport class InputSystem extends createSystem(\n {\n /** Entities interactable via ray pointer */\n rayInteractables: { required: [RayInteractable, Transform] },\n /** Entities interactable via touch/poke pointer */\n pokeInteractables: { required: [PokeInteractable, Transform] },\n /** One-hand grabbable entities */\n oneHandGrabbables: { required: [OneHandGrabbable, Transform] },\n /** Two-hands grabbable entities */\n twoHandsGrabbables: { required: [TwoHandsGrabbable, Transform] },\n /** Distance grabbable entities */\n distanceGrabbables: { required: [DistanceGrabbable, Transform] },\n },\n {\n /** Keep pointer target lists available outside immersive XR for browser canvas input. */\n maintainScenePointers: { type: Types.Boolean, default: false },\n },\n) {\n /** Descendants for ray pointer intersection */\n private rayDescendants: Object3D[] = [];\n /** Descendants for touch/poke pointer intersection */\n private touchDescendants: Object3D[] = [];\n /** Descendants for grab pointer intersection */\n private grabDescendants: Object3D[] = [];\n\n private shouldSetIntersectables = false;\n private listeners = new WeakMap<\n Object3D,\n {\n enter: (e: any) => void;\n leave: (e: any) => void;\n down: (e: any) => void;\n up: (e: any) => void;\n }\n >();\n private lastBVHUpdate = new WeakMap<Object3D, number>();\n\n init(): void {\n this.shouldSetIntersectables =\n this.visibilityState.value === VisibilityState.Visible ||\n this.config.maintainScenePointers.value;\n // React to XR visibility for enabling scoped intersections\n this.cleanupFuncs.push(\n this.visibilityState.subscribe((value) => {\n this.shouldSetIntersectables =\n value === VisibilityState.Visible ||\n this.config.maintainScenePointers.value;\n }),\n );\n\n // Wire pointer event listeners on qualify; tear them down on disqualify.\n // Descendant arrays are rebuilt every frame, so no dirty bookkeeping here.\n // Register the query subscriptions on cleanupFuncs so they're released on\n // system teardown (matching the visibilityState subscription above).\n this.cleanupFuncs.push(\n this.queries.rayInteractables.subscribe('qualify', (entity) => {\n this.setupEventListeners(entity);\n }),\n this.queries.rayInteractables.subscribe('disqualify', (entity) => {\n this.cleanupEventListeners(entity);\n }),\n\n this.queries.pokeInteractables.subscribe('qualify', (entity) => {\n this.setupEventListeners(entity);\n // Enable touch pointers when first poke interactable appears\n this.input.xr.multiPointers.left.toggleSubPointer('touch', true);\n this.input.xr.multiPointers.right.toggleSubPointer('touch', true);\n }),\n this.queries.pokeInteractables.subscribe('disqualify', (entity) => {\n this.cleanupEventListeners(entity);\n // Disable touch pointers when no poke interactables remain\n if (this.queries.pokeInteractables.entities.size === 0) {\n this.input.xr.multiPointers.left.toggleSubPointer('touch', false);\n this.input.xr.multiPointers.right.toggleSubPointer('touch', false);\n }\n }),\n );\n\n // Enable touch pointer if there are already poke interactables\n if (this.queries.pokeInteractables.entities.size > 0) {\n this.input.xr.multiPointers.left.toggleSubPointer('touch', true);\n this.input.xr.multiPointers.right.toggleSubPointer('touch', true);\n }\n }\n\n update(delta: number, time: number): void {\n // Update input sampling first\n this.input.update(this.xrManager, delta, time);\n\n // Rebuild interactable descendant arrays every frame so newly parented\n // entities (TransformSystem runs at priority 0, after this system at -4)\n // become hit-testable on the same frame they're created.\n this.updateDescendantArrays();\n }\n\n /**\n * Update per-type descendant arrays for optimized pointer intersection\n */\n private updateDescendantArrays(): void {\n // Clear arrays\n this.rayDescendants.length = 0;\n this.touchDescendants.length = 0;\n this.grabDescendants.length = 0;\n\n if (!this.shouldSetIntersectables) {\n // Clear all descendant arrays on scene\n (this.scene as any).interactableDescendants = undefined;\n (this.scene as any).rayDescendants = undefined;\n (this.scene as any).touchDescendants = undefined;\n (this.scene as any).grabDescendants = undefined;\n return;\n }\n\n // Collect ray interactables + distance grabbables (both use ray)\n for (const entity of this.queries.rayInteractables.entities) {\n const obj = entity.object3D;\n if (obj) {\n this.rayDescendants.push(obj);\n }\n }\n for (const entity of this.queries.distanceGrabbables.entities) {\n const obj = entity.object3D;\n if (obj && !this.rayDescendants.includes(obj)) {\n this.rayDescendants.push(obj);\n }\n }\n\n // Collect poke/touch interactables\n for (const entity of this.queries.pokeInteractables.entities) {\n const obj = entity.object3D;\n if (obj) {\n this.touchDescendants.push(obj);\n }\n }\n\n // Collect grab interactables (oneHand + twoHands)\n for (const entity of this.queries.oneHandGrabbables.entities) {\n const obj = entity.object3D;\n if (obj) {\n this.grabDescendants.push(obj);\n }\n }\n for (const entity of this.queries.twoHandsGrabbables.entities) {\n const obj = entity.object3D;\n if (obj && !this.grabDescendants.includes(obj)) {\n this.grabDescendants.push(obj);\n }\n }\n\n // Set type-specific arrays on scene\n (this.scene as any).rayDescendants = this.rayDescendants;\n (this.scene as any).touchDescendants = this.touchDescendants;\n (this.scene as any).grabDescendants = this.grabDescendants;\n\n // Also set legacy interactableDescendants as union for backwards compatibility\n const allDescendants = new Set<Object3D>([\n ...this.rayDescendants,\n ...this.touchDescendants,\n ...this.grabDescendants,\n ]);\n (this.scene as any).interactableDescendants = Array.from(allDescendants);\n }\n\n private setupEventListeners(entity: Entity): void {\n const object3D = entity.object3D as Object3D<\n Object3DEventMap & PointerEventsMap\n >;\n if (!object3D) {\n return;\n }\n\n // Skip if already has listeners\n if (this.listeners.has(object3D)) {\n return;\n }\n\n // Compute BVH for all meshes in the entity hierarchy for fast raycasting\n this.computeBoundsTreeForEntity(object3D);\n\n // Enable pointer events for raycasting\n (object3D as any).pointerEvents = 'auto';\n\n // Throttled subtree BVH refresh helper\n const maybeRefreshBVH = () => {\n const now =\n typeof performance !== 'undefined' && performance.now\n ? performance.now()\n : Date.now();\n const last = this.lastBVHUpdate.get(object3D) ?? 0;\n if (now - last > 250) {\n this.computeBoundsTreeForEntity(object3D);\n this.lastBVHUpdate.set(object3D, now);\n }\n };\n\n const enter = (event: PointerEvent) => {\n event.stopPropagation();\n maybeRefreshBVH();\n if (!entity.hasComponent(Hovered)) {\n entity.addComponent(Hovered);\n }\n };\n const leave = (event: PointerEvent) => {\n event.stopPropagation();\n entity.removeComponent(Hovered);\n // pointerleave can fire without a preceding pointerup for flat geometry\n // (poke sphere exits intersection in one frame); clear Pressed defensively.\n entity.removeComponent(Pressed);\n };\n const down = (event: PointerEvent) => {\n event.stopPropagation();\n maybeRefreshBVH();\n // pointerdown implies the pointer is over the entity; ensure Hovered is\n // present even if a pointerleave/pointerdown sequence cleared it\n // (flat-geometry poke: the sphere can exit then re-contact from behind).\n if (!entity.hasComponent(Hovered)) {\n entity.addComponent(Hovered);\n }\n if (!entity.hasComponent(Pressed)) {\n entity.addComponent(Pressed);\n }\n };\n const up = (event: PointerEvent) => {\n event.stopPropagation();\n entity.removeComponent(Pressed);\n };\n\n this.listeners.set(object3D, { enter, leave, down, up });\n (object3D as any).addEventListener('pointerenter', enter);\n (object3D as any).addEventListener('pointerleave', leave);\n (object3D as any).addEventListener('pointerdown', down);\n (object3D as any).addEventListener('pointerup', up);\n }\n\n private computeBoundsTreeForEntity(object3D: Object3D): void {\n object3D.traverse((child) => {\n if ((child as Mesh).isMesh) {\n const mesh = child as Mesh;\n const geometry = (mesh as any).geometry;\n if (\n geometry &&\n !geometry.boundsTree &&\n typeof geometry.computeBoundsTree === 'function'\n ) {\n try {\n geometry.computeBoundsTree();\n } catch (error) {\n console.warn(\n `[InputSystem] Failed to compute BVH for ${mesh.name || 'unnamed'}:`,\n error,\n );\n }\n }\n }\n });\n }\n\n private cleanupEventListeners(entity: Entity): void {\n const object3D = entity.object3D as any;\n if (!object3D) {\n return;\n }\n const fns = this.listeners.get(object3D);\n if (fns) {\n object3D.removeEventListener('pointerenter', fns.enter);\n object3D.removeEventListener('pointerleave', fns.leave);\n object3D.removeEventListener('pointerdown', fns.down);\n object3D.removeEventListener('pointerup', fns.up);\n this.listeners.delete(object3D);\n }\n // A query also disqualifies an entity when it is destroyed. At that point\n // Elics has already cleared its components and rejects further mutations.\n // The listeners still need to be detached from the retained Object3D, but\n // there are no transient input tags left to remove from an inactive entity.\n if (entity.active) {\n entity.removeComponent(Hovered).removeComponent(Pressed);\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"input-system.js","sources":["../../src/input/input-system.ts"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport type { PointerEvent, PointerEventsMap } from '@pmndrs/pointer-events';\nimport { Types } from '../ecs/component.js';\nimport { Entity } from '../ecs/entity.js';\nimport { createSystem } from '../ecs/system.js';\nimport { VisibilityState } from '../ecs/world.js';\nimport { DistanceGrabbable } from '../grab/distance-grabbable.js';\nimport { OneHandGrabbable } from '../grab/one-hand-grabbable.js';\nimport { TwoHandsGrabbable } from '../grab/two-hands-grabbable.js';\nimport { Mesh, Object3D, Object3DEventMap } from '../runtime/index.js';\nimport { Transform } from '../transform/index.js';\nimport {\n Hovered,\n PokeInteractable,\n Pressed,\n RayInteractable,\n} from './state-tags.js';\n\nconst NO_GAZE_CANDIDATES: Object3D[] = [];\n\n/**\n * Samples XR poses (hands/controllers/head) and gamepads, curates the set of\n * interactables for pointer raycasting, and attaches minimal event listeners.\n *\n * @remarks\n * - Scheduled after player movement so pointers reflect updated transforms.\n * - Maintains type-specific descendant arrays for optimized pointer intersection.\n * - Adds transient `Hovered` / `Pressed` tags so other systems can react declaratively.\n *\n * @category Input\n * @example React to Hovered / Pressed\n * ```ts\n * export class HighlightSystem extends createSystem({\n * items: { required: [RayInteractable] }\n * }) {\n * update() {\n * this.queries.items.entities.forEach(e => {\n * e.object3D.visible = !e.hasComponent(Pressed);\n * })\n * }\n * }\n * ```\n */\nexport class InputSystem extends createSystem(\n {\n /** Entities interactable via ray pointer */\n rayInteractables: { required: [RayInteractable, Transform] },\n /** Entities interactable via touch/poke pointer */\n pokeInteractables: { required: [PokeInteractable, Transform] },\n /** One-hand grabbable entities */\n oneHandGrabbables: { required: [OneHandGrabbable, Transform] },\n /** Two-hands grabbable entities */\n twoHandsGrabbables: { required: [TwoHandsGrabbable, Transform] },\n /** Distance grabbable entities */\n distanceGrabbables: { required: [DistanceGrabbable, Transform] },\n },\n {\n /** Keep pointer target lists available outside immersive XR for browser canvas input. */\n maintainScenePointers: { type: Types.Boolean, default: false },\n },\n) {\n /** Descendants for ray pointer intersection */\n private rayDescendants: Object3D[] = [];\n /** Descendants for touch/poke pointer intersection */\n private touchDescendants: Object3D[] = [];\n /** Descendants for grab pointer intersection */\n private grabDescendants: Object3D[] = [];\n private shouldSetIntersectables = false;\n private listeners = new WeakMap<\n Object3D,\n {\n enter: (e: any) => void;\n leave: (e: any) => void;\n down: (e: any) => void;\n up: (e: any) => void;\n cancel: (e: any) => void;\n hovered: Set<number>;\n pressed: Set<number>;\n }\n >();\n private readonly listenerEntities = new Set<Entity>();\n private lastBVHUpdate = new WeakMap<Object3D, number>();\n\n init(): void {\n this.shouldSetIntersectables =\n this.visibilityState.value === VisibilityState.Visible ||\n this.config.maintainScenePointers.value;\n // React to XR visibility for enabling scoped intersections\n this.cleanupFuncs.push(\n this.visibilityState.subscribe((value) => {\n this.shouldSetIntersectables =\n value === VisibilityState.Visible ||\n this.config.maintainScenePointers.value;\n }),\n );\n\n const onSessionBoundary = () => this.clearPointerStates();\n this.xrManager.addEventListener('sessionstart', onSessionBoundary);\n this.xrManager.addEventListener('sessionend', onSessionBoundary);\n this.cleanupFuncs.push(\n () =>\n this.xrManager.removeEventListener('sessionstart', onSessionBoundary),\n () => this.xrManager.removeEventListener('sessionend', onSessionBoundary),\n () => this.cleanupAllEventListeners(),\n );\n\n // Wire pointer event listeners on qualify; tear them down on disqualify.\n // Descendant arrays are rebuilt every frame, so no dirty bookkeeping here.\n // Register the query subscriptions on cleanupFuncs so they're released on\n // system teardown (matching the visibilityState subscription above).\n this.cleanupFuncs.push(\n this.queries.rayInteractables.subscribe('qualify', (entity) => {\n this.setupEventListeners(entity);\n }),\n this.queries.rayInteractables.subscribe('disqualify', (entity) => {\n this.cleanupEventListeners(entity);\n }),\n\n this.queries.pokeInteractables.subscribe('qualify', (entity) => {\n this.setupEventListeners(entity);\n // Enable touch pointers when first poke interactable appears\n this.input.xr.multiPointers.left.toggleSubPointer('touch', true);\n this.input.xr.multiPointers.right.toggleSubPointer('touch', true);\n }),\n this.queries.pokeInteractables.subscribe('disqualify', (entity) => {\n this.cleanupEventListeners(entity);\n // Disable touch pointers when no poke interactables remain\n if (this.queries.pokeInteractables.entities.size === 0) {\n this.input.xr.multiPointers.left.toggleSubPointer('touch', false);\n this.input.xr.multiPointers.right.toggleSubPointer('touch', false);\n }\n }),\n );\n\n // Enable touch pointer if there are already poke interactables\n if (this.queries.pokeInteractables.entities.size > 0) {\n this.input.xr.multiPointers.left.toggleSubPointer('touch', true);\n this.input.xr.multiPointers.right.toggleSubPointer('touch', true);\n }\n }\n\n update(delta: number, time: number): void {\n // Gaze and hand rays consume the exact same target snapshot this frame.\n this.input.xr.gazeCandidates = this.shouldSetIntersectables\n ? this.rayDescendants\n : NO_GAZE_CANDIDATES;\n\n // Update input sampling first\n this.input.update(this.xrManager, delta, time);\n\n // Rebuild interactable descendant arrays every frame so newly parented\n // entities (TransformSystem runs at priority 0, after this system at -4)\n // become hit-testable on the same frame they're created.\n this.updateDescendantArrays();\n }\n\n /**\n * Update per-type descendant arrays for optimized pointer intersection\n */\n private updateDescendantArrays(): void {\n this.rayDescendants.length = 0;\n this.touchDescendants.length = 0;\n this.grabDescendants.length = 0;\n\n if (!this.shouldSetIntersectables) {\n // Clear all descendant arrays on scene\n (this.scene as any).interactableDescendants = undefined;\n (this.scene as any).rayDescendants = undefined;\n (this.scene as any).touchDescendants = undefined;\n (this.scene as any).grabDescendants = undefined;\n return;\n }\n\n // Collect ray interactables + distance grabbables (both use ray)\n for (const entity of this.queries.rayInteractables.entities) {\n const obj = entity.object3D;\n if (obj) {\n this.rayDescendants.push(obj);\n }\n }\n for (const entity of this.queries.distanceGrabbables.entities) {\n const obj = entity.object3D;\n if (obj && !this.rayDescendants.includes(obj)) {\n this.rayDescendants.push(obj);\n }\n }\n\n // Collect poke/touch interactables\n for (const entity of this.queries.pokeInteractables.entities) {\n const obj = entity.object3D;\n if (obj) {\n this.touchDescendants.push(obj);\n }\n }\n\n // Collect grab interactables (oneHand + twoHands)\n for (const entity of this.queries.oneHandGrabbables.entities) {\n const obj = entity.object3D;\n if (obj) {\n this.grabDescendants.push(obj);\n }\n }\n for (const entity of this.queries.twoHandsGrabbables.entities) {\n const obj = entity.object3D;\n if (obj && !this.grabDescendants.includes(obj)) {\n this.grabDescendants.push(obj);\n }\n }\n\n // Set type-specific arrays on scene\n (this.scene as any).rayDescendants = this.rayDescendants;\n (this.scene as any).touchDescendants = this.touchDescendants;\n (this.scene as any).grabDescendants = this.grabDescendants;\n\n // Also set legacy interactableDescendants as union for backwards compatibility\n const allDescendants = new Set<Object3D>([\n ...this.rayDescendants,\n ...this.touchDescendants,\n ...this.grabDescendants,\n ]);\n (this.scene as any).interactableDescendants = Array.from(allDescendants);\n }\n\n private setupEventListeners(entity: Entity): void {\n const object3D = entity.object3D as Object3D<\n Object3DEventMap & PointerEventsMap\n >;\n if (!object3D) {\n return;\n }\n\n // Skip if already has listeners\n if (this.listeners.has(object3D)) {\n return;\n }\n\n // Compute BVH for all meshes in the entity hierarchy for fast raycasting\n this.computeBoundsTreeForEntity(object3D);\n\n // Enable pointer events for raycasting\n (object3D as any).pointerEvents = 'auto';\n\n // Throttled subtree BVH refresh helper\n const maybeRefreshBVH = () => {\n const now =\n typeof performance !== 'undefined' && performance.now\n ? performance.now()\n : Date.now();\n const last = this.lastBVHUpdate.get(object3D) ?? 0;\n if (now - last > 250) {\n this.computeBoundsTreeForEntity(object3D);\n this.lastBVHUpdate.set(object3D, now);\n }\n };\n\n const enter = (event: PointerEvent) => {\n event.stopPropagation();\n maybeRefreshBVH();\n pointerState.hovered.add(event.pointerId);\n if (!entity.hasComponent(Hovered)) {\n entity.addComponent(Hovered);\n }\n };\n const leave = (event: PointerEvent) => {\n event.stopPropagation();\n pointerState.hovered.delete(event.pointerId);\n if (pointerState.hovered.size === 0) {\n entity.removeComponent(Hovered);\n }\n // pointerleave can fire without a preceding pointerup for flat geometry\n // (poke sphere exits intersection in one frame); clear only this\n // pointer's press defensively.\n pointerState.pressed.delete(event.pointerId);\n if (pointerState.pressed.size === 0) {\n entity.removeComponent(Pressed);\n }\n };\n const down = (event: PointerEvent) => {\n event.stopPropagation();\n maybeRefreshBVH();\n // pointerdown implies the pointer is over the entity; ensure Hovered is\n // present even if a pointerleave/pointerdown sequence cleared it\n // (flat-geometry poke: the sphere can exit then re-contact from behind).\n if (!entity.hasComponent(Hovered)) {\n entity.addComponent(Hovered);\n }\n pointerState.hovered.add(event.pointerId);\n pointerState.pressed.add(event.pointerId);\n if (!entity.hasComponent(Pressed)) {\n entity.addComponent(Pressed);\n }\n };\n const up = (event: PointerEvent) => {\n event.stopPropagation();\n pointerState.pressed.delete(event.pointerId);\n if (pointerState.pressed.size === 0) {\n entity.removeComponent(Pressed);\n }\n };\n const cancel = (event: PointerEvent) => {\n event.stopPropagation();\n pointerState.hovered.delete(event.pointerId);\n pointerState.pressed.delete(event.pointerId);\n if (pointerState.hovered.size === 0) {\n entity.removeComponent(Hovered);\n }\n if (pointerState.pressed.size === 0) {\n entity.removeComponent(Pressed);\n }\n };\n\n const pointerState = {\n hovered: new Set<number>(),\n pressed: new Set<number>(),\n };\n this.listeners.set(object3D, {\n enter,\n leave,\n down,\n up,\n cancel,\n ...pointerState,\n });\n this.listenerEntities.add(entity);\n (object3D as any).addEventListener('pointerenter', enter);\n (object3D as any).addEventListener('pointerleave', leave);\n (object3D as any).addEventListener('pointerdown', down);\n (object3D as any).addEventListener('pointerup', up);\n (object3D as any).addEventListener('pointercancel', cancel);\n }\n\n private computeBoundsTreeForEntity(object3D: Object3D): void {\n object3D.traverse((child) => {\n if ((child as Mesh).isMesh) {\n const mesh = child as Mesh;\n const geometry = (mesh as any).geometry;\n if (\n geometry &&\n !geometry.boundsTree &&\n typeof geometry.computeBoundsTree === 'function'\n ) {\n try {\n geometry.computeBoundsTree();\n } catch (error) {\n console.warn(\n `[InputSystem] Failed to compute BVH for ${mesh.name || 'unnamed'}:`,\n error,\n );\n }\n }\n }\n });\n }\n\n private clearPointerStates(): void {\n for (const entity of this.listenerEntities) {\n const object3D = entity.object3D;\n const state = object3D ? this.listeners.get(object3D) : undefined;\n state?.hovered.clear();\n state?.pressed.clear();\n if (entity.active) {\n entity.removeComponent(Hovered).removeComponent(Pressed);\n }\n }\n }\n\n private cleanupAllEventListeners(): void {\n for (const entity of [...this.listenerEntities]) {\n this.cleanupEventListeners(entity);\n }\n }\n\n private cleanupEventListeners(entity: Entity): void {\n this.listenerEntities.delete(entity);\n const object3D = entity.object3D as any;\n if (!object3D) {\n return;\n }\n const fns = this.listeners.get(object3D);\n if (fns) {\n object3D.removeEventListener('pointerenter', fns.enter);\n object3D.removeEventListener('pointerleave', fns.leave);\n object3D.removeEventListener('pointerdown', fns.down);\n object3D.removeEventListener('pointerup', fns.up);\n object3D.removeEventListener('pointercancel', fns.cancel);\n fns.hovered.clear();\n fns.pressed.clear();\n this.listeners.delete(object3D);\n }\n // A query also disqualifies an entity when it is destroyed. At that point\n // Elics has already cleared its components and rejects further mutations.\n // The listeners still need to be detached from the retained Object3D, but\n // there are no transient input tags left to remove from an inactive entity.\n if (entity.active) {\n entity.removeComponent(Hovered).removeComponent(Pressed);\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"state-tags.d.ts","sourceRoot":"","sources":["../../src/input/state-tags.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,eAAe,+BAI3B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,+BAI5B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,+BAInB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,+BAInB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,+BAAkB,CAAC"}
1
+ {"version":3,"file":"state-tags.d.ts","sourceRoot":"","sources":["../../src/input/state-tags.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,eAAe,+BAI3B,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,+BAI5B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,+BAInB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,+BAInB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,YAAY,+BAAkB,CAAC"}
@@ -6,6 +6,8 @@ import { createComponent } from 'elics';
6
6
  * This source code is licensed under the MIT license found in the
7
7
  * LICENSE file in the root directory of this source tree.
8
8
  */
9
+ // Import from the leaf module rather than '../ecs/index.js': the barrel pulls
10
+ // in builtin-components, which imports this file, forming a cycle.
9
11
  /**
10
12
  * Marks an entity as eligible for ray-based pointer interaction.
11
13
  *
@@ -1 +1 @@
1
- {"version":3,"file":"state-tags.js","sources":["../../src/input/state-tags.ts"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport { createComponent } from '../ecs/component.js';\n/**\n * Marks an entity as eligible for ray-based pointer interaction.\n *\n * @remarks\n * - The {@link InputSystem} discovers all entities with `RayInteractable` and\n * registers their Object3D roots as raycast targets.\n * - Used for UI elements, buttons, and clickable objects interacted via ray pointer.\n * - When a pointer enters/leaves or presses/releases on the entity, the system\n * adds/removes the transient tags {@link Hovered} and {@link Pressed}.\n *\n * @category Input\n * @example Highlight on hover\n * ```ts\n * export class HighlightSystem extends createSystem({ items: { required: [RayInteractable] } }) {\n * update() {\n * this.queries.items.entities.forEach(e => {\n * e.object3D.material.emissiveIntensity = e.hasComponent(Hovered) ? 1.0 : 0.0;\n * });\n * }\n * }\n * ```\n */\nexport const RayInteractable = createComponent(\n 'RayInteractable',\n {},\n 'Marks an entity as eligible for ray-based pointer interaction.',\n);\n\n/**\n * Marks an entity as eligible for poke/touch interaction.\n *\n * @remarks\n * - Used for UI elements that can be poked/touched with finger or controller.\n * - Auto-selects when finger crosses the surface (distance <= 0).\n * - Uses hysteresis (separate enter/exit thresholds) to prevent flickering.\n *\n * @category Input\n * @example Create a pokeable button\n * ```ts\n * entity.addComponent(PokeInteractable);\n * ```\n */\nexport const PokeInteractable = createComponent(\n 'PokeInteractable',\n {},\n 'Marks an entity as eligible for poke/touch interaction.',\n);\n\n/**\n * A transient tag set while a pointer is intersecting an interactable.\n *\n * @remarks\n * - Managed by {@link InputSystem}; do not add/remove this component manually.\n * - Use as a declarative condition for hover effects, tooltips, or affordances.\n * - Works with both RayInteractable and PokeInteractable entities.\n *\n * @category Input\n * @hideineditor\n */\nexport const Hovered = createComponent(\n 'Hovered',\n {},\n 'A tag added by InputSystem while a pointer is hovering over the entity.',\n);\n\n/**\n * A transient tag set while a pointer is actively pressing an interactable.\n *\n * @remarks\n * - Managed by {@link InputSystem}; do not add/remove this component manually.\n * - Often used to gate activation logic or pressed-state visuals.\n * - Works with both RayInteractable and PokeInteractable entities.\n *\n * @category Input\n * @hideineditor\n */\nexport const Pressed = createComponent(\n 'Pressed',\n {},\n 'A tag added by InputSystem while the entity is actively pressed.',\n);\n\n/**\n * @deprecated Use `RayInteractable` instead. This will be removed in a future version.\n */\nexport const Interactable = RayInteractable;\n"],"names":[],"mappings":";;AAAA;;;;;AAKG;AAGH;;;;;;;;;;;;;;;;;;;;;AAqBG;AACI,MAAM,eAAe,GAAG,eAAe,CAC5C,iBAAiB,EACjB,EAAE,EACF,gEAAgE;AAGlE;;;;;;;;;;;;;AAaG;AACI,MAAM,gBAAgB,GAAG,eAAe,CAC7C,kBAAkB,EAClB,EAAE,EACF,yDAAyD;AAG3D;;;;;;;;;;AAUG;AACI,MAAM,OAAO,GAAG,eAAe,CACpC,SAAS,EACT,EAAE,EACF,yEAAyE;AAG3E;;;;;;;;;;AAUG;AACI,MAAM,OAAO,GAAG,eAAe,CACpC,SAAS,EACT,EAAE,EACF,kEAAkE;AAGpE;;AAEG;AACI,MAAM,YAAY,GAAG;;;;"}
1
+ {"version":3,"file":"state-tags.js","sources":["../../src/input/state-tags.ts"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n// Import from the leaf module rather than '../ecs/index.js': the barrel pulls\n// in builtin-components, which imports this file, forming a cycle.\nimport { createComponent } from '../ecs/component.js';\n\n/**\n * Marks an entity as eligible for ray-based pointer interaction.\n *\n * @remarks\n * - The {@link InputSystem} discovers all entities with `RayInteractable` and\n * registers their Object3D roots as raycast targets.\n * - Used for UI elements, buttons, and clickable objects interacted via ray pointer.\n * - When a pointer enters/leaves or presses/releases on the entity, the system\n * adds/removes the transient tags {@link Hovered} and {@link Pressed}.\n *\n * @category Input\n * @example Highlight on hover\n * ```ts\n * export class HighlightSystem extends createSystem({ items: { required: [RayInteractable] } }) {\n * update() {\n * this.queries.items.entities.forEach(e => {\n * e.object3D.material.emissiveIntensity = e.hasComponent(Hovered) ? 1.0 : 0.0;\n * });\n * }\n * }\n * ```\n */\nexport const RayInteractable = createComponent(\n 'RayInteractable',\n {},\n 'Marks an entity as eligible for ray-based pointer interaction.',\n);\n\n/**\n * Marks an entity as eligible for poke/touch interaction.\n *\n * @remarks\n * - Used for UI elements that can be poked/touched with finger or controller.\n * - Auto-selects when finger crosses the surface (distance <= 0).\n * - Uses hysteresis (separate enter/exit thresholds) to prevent flickering.\n *\n * @category Input\n * @example Create a pokeable button\n * ```ts\n * entity.addComponent(PokeInteractable);\n * ```\n */\nexport const PokeInteractable = createComponent(\n 'PokeInteractable',\n {},\n 'Marks an entity as eligible for poke/touch interaction.',\n);\n\n/**\n * A transient tag set while a pointer is intersecting an interactable.\n *\n * @remarks\n * - Managed by {@link InputSystem}; do not add/remove this component manually.\n * - Use as a declarative condition for hover effects, tooltips, or affordances.\n * - Works with both RayInteractable and PokeInteractable entities.\n *\n * @category Input\n * @hideineditor\n */\nexport const Hovered = createComponent(\n 'Hovered',\n {},\n 'A tag added by InputSystem while a pointer is hovering over the entity.',\n);\n\n/**\n * A transient tag set while a pointer is actively pressing an interactable.\n *\n * @remarks\n * - Managed by {@link InputSystem}; do not add/remove this component manually.\n * - Often used to gate activation logic or pressed-state visuals.\n * - Works with both RayInteractable and PokeInteractable entities.\n *\n * @category Input\n * @hideineditor\n */\nexport const Pressed = createComponent(\n 'Pressed',\n {},\n 'A tag added by InputSystem while the entity is actively pressed.',\n);\n\n/**\n * @deprecated Use `RayInteractable` instead. This will be removed in a future version.\n */\nexport const Interactable = RayInteractable;\n"],"names":[],"mappings":";;AAAA;;;;;AAKG;AAEH;AACA;AAGA;;;;;;;;;;;;;;;;;;;;;AAqBG;AACI,MAAM,eAAe,GAAG,eAAe,CAC5C,iBAAiB,EACjB,EAAE,EACF,gEAAgE;AAGlE;;;;;;;;;;;;;AAaG;AACI,MAAM,gBAAgB,GAAG,eAAe,CAC7C,kBAAkB,EAClB,EAAE,EACF,yDAAyD;AAG3D;;;;;;;;;;AAUG;AACI,MAAM,OAAO,GAAG,eAAe,CACpC,SAAS,EACT,EAAE,EACF,yEAAyE;AAG3E;;;;;;;;;;AAUG;AACI,MAAM,OAAO,GAAG,eAAe,CACpC,SAAS,EACT,EAAE,EACF,kEAAkE;AAGpE;;AAEG;AACI,MAAM,YAAY,GAAG;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/project/normalize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAEV,2BAA2B,EAC3B,6BAA6B,EAE7B,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAUpB;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,GACb,6BAA6B,CAwC/B;AAED,+EAA+E;AAC/E,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,2BAA2B,CAyC7B;AAED,6EAA6E;AAC7E,wBAAgB,gCAAgC,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,mEAAmE;AACnE,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAEvE"}
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/project/normalize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAEV,2BAA2B,EAC3B,6BAA6B,EAE7B,gBAAgB,EAEjB,MAAM,YAAY,CAAC;AAUpB;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,GACb,6BAA6B,CAwC/B;AAED,+EAA+E;AAC/E,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,2BAA2B,CAgD7B;AAED,6EAA6E;AAC7E,wBAAgB,gCAAgC,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3E;AAED,mEAAmE;AACnE,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAEvE"}
@@ -57,6 +57,7 @@ function normalizeProjectWorldOptions(value) {
57
57
  }
58
58
  /** Normalize manifest-owned development settings for Vite/plugin consumers. */
59
59
  function normalizeProjectDevOptions(value) {
60
+ var _a;
60
61
  assertValidIwsdkProjectManifest(value);
61
62
  const manifest = value;
62
63
  const dev = manifest.dev;
@@ -92,6 +93,13 @@ function normalizeProjectDevOptions(value) {
92
93
  };
93
94
  return {
94
95
  ...(emulator == null ? {} : { emulator }),
96
+ ...(dev.targetDevicePreview == null
97
+ ? {}
98
+ : {
99
+ targetDevicePreview: {
100
+ gazeSimulation: (_a = dev.targetDevicePreview.gazeSimulation) !== null && _a !== void 0 ? _a : 'head',
101
+ },
102
+ }),
95
103
  };
96
104
  }
97
105
  /** Normalize an assets/components module declaration for Vite resolution. */
@@ -181,6 +189,9 @@ function normalizeFeatures(source) {
181
189
  ? source.grabbing
182
190
  : { ...source.grabbing };
183
191
  }
192
+ if (source.gaze != null) {
193
+ features.gaze = { ...source.gaze };
194
+ }
184
195
  if (source.physics != null) {
185
196
  features.physics =
186
197
  typeof source.physics === 'boolean'
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.js","sources":["../../src/project/normalize.ts"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport type { WorldOptions } from '../init/world-initializer.js';\nimport {\n normalizeProjectSourcePath,\n projectSceneSourcePathToRuntimeUrl,\n} from './paths.js';\nimport type {\n IwsdkProjectManifestV1,\n NormalizedProjectDevOptions,\n NormalizedProjectWorldOptions,\n ProjectFeatureOptions,\n ProjectRegexSpec,\n ProjectXRFeatureOptions,\n} from './types.js';\nimport { assertValidIwsdkProjectManifest } from './validation.js';\n\ntype RuntimeXROptions = Exclude<NonNullable<WorldOptions['xr']>, false>;\n\nconst TURNING_METHOD = {\n snap: 1,\n smooth: 2,\n} as const;\n\n/**\n * Normalize the JSON-safe world contract into the existing `World.create`\n * option shape. Asset and component values are intentionally not injected.\n */\nexport function normalizeProjectWorldOptions(\n value: unknown,\n): NormalizedProjectWorldOptions {\n assertValidIwsdkProjectManifest(value);\n const manifest = value as IwsdkProjectManifestV1;\n const source = manifest.world;\n const xr = normalizeXR(source.xr);\n\n return {\n level: projectSceneSourcePathToRuntimeUrl(manifest.scene),\n xr,\n ...(source.input == null\n ? {}\n : {\n input: {\n ...(typeof source.input.canvasPointerEvents === 'object'\n ? {\n canvasPointerEvents: {\n ...source.input.canvasPointerEvents,\n },\n }\n : 'canvasPointerEvents' in source.input\n ? {\n canvasPointerEvents: source.input.canvasPointerEvents,\n }\n : {}),\n },\n }),\n ...(source.render == null\n ? {}\n : {\n render: {\n ...source.render,\n ...(source.render.camera == null\n ? {}\n : { camera: { ...source.render.camera } }),\n },\n }),\n ...(source.features == null\n ? {}\n : { features: normalizeFeatures(source.features) }),\n };\n}\n\n/** Normalize manifest-owned development settings for Vite/plugin consumers. */\nexport function normalizeProjectDevOptions(\n value: unknown,\n): NormalizedProjectDevOptions {\n assertValidIwsdkProjectManifest(value);\n const manifest = value as IwsdkProjectManifestV1;\n const dev = manifest.dev;\n if (dev == null) {\n return {};\n }\n const sourceEmulator = dev.emulator;\n const emulator: NormalizedProjectDevOptions['emulator'] =\n sourceEmulator == null\n ? undefined\n : {\n ...(sourceEmulator.device == null\n ? {}\n : { device: sourceEmulator.device }),\n ...(sourceEmulator.iwer == null ? {} : { iwer: sourceEmulator.iwer }),\n ...(sourceEmulator.environment == null\n ? {}\n : { environment: sourceEmulator.environment }),\n ...(sourceEmulator.activation == null\n ? {}\n : {\n activation:\n typeof sourceEmulator.activation === 'object'\n ? projectRegexSpecToRegExp(sourceEmulator.activation)\n : sourceEmulator.activation,\n }),\n ...(sourceEmulator.injectOnBuild == null\n ? {}\n : { injectOnBuild: sourceEmulator.injectOnBuild }),\n ...(sourceEmulator.userAgentException == null\n ? {}\n : {\n userAgentException: projectRegexSpecToRegExp(\n sourceEmulator.userAgentException,\n ),\n }),\n };\n return {\n ...(emulator == null ? {} : { emulator }),\n };\n}\n\n/** Normalize an assets/components module declaration for Vite resolution. */\nexport function normalizeProjectModuleSourcePath(sourcePath: string): string {\n return normalizeProjectSourcePath(sourcePath, 'module');\n}\n\n/** Reconstruct a validated JSON regular-expression declaration. */\nexport function projectRegexSpecToRegExp(spec: ProjectRegexSpec): RegExp {\n return new RegExp(spec.source, spec.flags ?? '');\n}\n\nfunction normalizeXR(\n source: IwsdkProjectManifestV1['world']['xr'],\n): NonNullable<WorldOptions['xr']> {\n if (source === false) {\n return false;\n }\n const sessionMode = (\n source.mode === 'vr' ? 'immersive-vr' : 'immersive-ar'\n ) as RuntimeXROptions['sessionMode'];\n return {\n sessionMode,\n ...(source.offer == null ? {} : { offer: source.offer }),\n ...(source.referenceSpace == null\n ? {}\n : {\n referenceSpace: cloneReferenceSpace(\n source.referenceSpace,\n ) as RuntimeXROptions['referenceSpace'],\n }),\n ...(source.restoreCameraOnExit == null\n ? {}\n : { restoreCameraOnExit: source.restoreCameraOnExit }),\n ...(source.launchOnSessionGranted == null\n ? {}\n : { launchOnSessionGranted: source.launchOnSessionGranted }),\n ...(source.features == null\n ? {}\n : { features: cloneXRFeatures(source.features) }),\n };\n}\n\nfunction cloneReferenceSpace(\n source: NonNullable<\n Exclude<IwsdkProjectManifestV1['world']['xr'], false>['referenceSpace']\n >,\n) {\n return typeof source === 'string'\n ? source\n : {\n ...source,\n ...(source.fallbackOrder == null\n ? {}\n : { fallbackOrder: [...source.fallbackOrder] }),\n };\n}\n\nfunction cloneXRFeatures(\n source: ProjectXRFeatureOptions,\n): NonNullable<RuntimeXROptions['features']> {\n return Object.fromEntries(\n Object.entries(source).map(([key, value]) => [\n key,\n value != null && typeof value === 'object' ? { ...value } : value,\n ]),\n ) as NonNullable<RuntimeXROptions['features']>;\n}\n\nfunction normalizeFeatures(\n source: ProjectFeatureOptions,\n): NonNullable<WorldOptions['features']> {\n const features: NonNullable<WorldOptions['features']> = {};\n if (source.locomotion != null) {\n if (typeof source.locomotion === 'boolean') {\n features.locomotion = source.locomotion;\n } else {\n const { browserControls, initialPlayerPosition, turningMethod, ...rest } =\n source.locomotion;\n features.locomotion = {\n ...rest,\n ...(initialPlayerPosition == null\n ? {}\n : {\n initialPlayerPosition: [...initialPlayerPosition],\n }),\n ...(typeof browserControls === 'object'\n ? {\n browserControls: {\n ...browserControls,\n },\n }\n : browserControls == null\n ? {}\n : { browserControls }),\n ...(turningMethod == null\n ? {}\n : {\n turningMethod: TURNING_METHOD[turningMethod],\n }),\n } as Exclude<\n NonNullable<WorldOptions['features']>['locomotion'],\n boolean | undefined\n >;\n }\n }\n if (source.grabbing != null) {\n features.grabbing =\n typeof source.grabbing === 'boolean'\n ? source.grabbing\n : { ...source.grabbing };\n }\n if (source.physics != null) {\n features.physics =\n typeof source.physics === 'boolean'\n ? source.physics\n : { ...source.physics };\n }\n if (source.sceneUnderstanding != null) {\n features.sceneUnderstanding =\n typeof source.sceneUnderstanding === 'boolean'\n ? source.sceneUnderstanding\n : { ...source.sceneUnderstanding };\n }\n if (source.environmentRaycast != null) {\n features.environmentRaycast = source.environmentRaycast;\n }\n if (source.camera != null) {\n features.camera = source.camera;\n }\n if (source.spatialUI != null) {\n features.spatialUI =\n typeof source.spatialUI === 'boolean'\n ? source.spatialUI\n : { ...source.spatialUI };\n }\n return features;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"normalize.js","sources":["../../src/project/normalize.ts"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport type { WorldOptions } from '../init/world-initializer.js';\nimport {\n normalizeProjectSourcePath,\n projectSceneSourcePathToRuntimeUrl,\n} from './paths.js';\nimport type {\n IwsdkProjectManifestV1,\n NormalizedProjectDevOptions,\n NormalizedProjectWorldOptions,\n ProjectFeatureOptions,\n ProjectRegexSpec,\n ProjectXRFeatureOptions,\n} from './types.js';\nimport { assertValidIwsdkProjectManifest } from './validation.js';\n\ntype RuntimeXROptions = Exclude<NonNullable<WorldOptions['xr']>, false>;\n\nconst TURNING_METHOD = {\n snap: 1,\n smooth: 2,\n} as const;\n\n/**\n * Normalize the JSON-safe world contract into the existing `World.create`\n * option shape. Asset and component values are intentionally not injected.\n */\nexport function normalizeProjectWorldOptions(\n value: unknown,\n): NormalizedProjectWorldOptions {\n assertValidIwsdkProjectManifest(value);\n const manifest = value as IwsdkProjectManifestV1;\n const source = manifest.world;\n const xr = normalizeXR(source.xr);\n\n return {\n level: projectSceneSourcePathToRuntimeUrl(manifest.scene),\n xr,\n ...(source.input == null\n ? {}\n : {\n input: {\n ...(typeof source.input.canvasPointerEvents === 'object'\n ? {\n canvasPointerEvents: {\n ...source.input.canvasPointerEvents,\n },\n }\n : 'canvasPointerEvents' in source.input\n ? {\n canvasPointerEvents: source.input.canvasPointerEvents,\n }\n : {}),\n },\n }),\n ...(source.render == null\n ? {}\n : {\n render: {\n ...source.render,\n ...(source.render.camera == null\n ? {}\n : { camera: { ...source.render.camera } }),\n },\n }),\n ...(source.features == null\n ? {}\n : { features: normalizeFeatures(source.features) }),\n };\n}\n\n/** Normalize manifest-owned development settings for Vite/plugin consumers. */\nexport function normalizeProjectDevOptions(\n value: unknown,\n): NormalizedProjectDevOptions {\n assertValidIwsdkProjectManifest(value);\n const manifest = value as IwsdkProjectManifestV1;\n const dev = manifest.dev;\n if (dev == null) {\n return {};\n }\n const sourceEmulator = dev.emulator;\n const emulator: NormalizedProjectDevOptions['emulator'] =\n sourceEmulator == null\n ? undefined\n : {\n ...(sourceEmulator.device == null\n ? {}\n : { device: sourceEmulator.device }),\n ...(sourceEmulator.iwer == null ? {} : { iwer: sourceEmulator.iwer }),\n ...(sourceEmulator.environment == null\n ? {}\n : { environment: sourceEmulator.environment }),\n ...(sourceEmulator.activation == null\n ? {}\n : {\n activation:\n typeof sourceEmulator.activation === 'object'\n ? projectRegexSpecToRegExp(sourceEmulator.activation)\n : sourceEmulator.activation,\n }),\n ...(sourceEmulator.injectOnBuild == null\n ? {}\n : { injectOnBuild: sourceEmulator.injectOnBuild }),\n ...(sourceEmulator.userAgentException == null\n ? {}\n : {\n userAgentException: projectRegexSpecToRegExp(\n sourceEmulator.userAgentException,\n ),\n }),\n };\n return {\n ...(emulator == null ? {} : { emulator }),\n ...(dev.targetDevicePreview == null\n ? {}\n : {\n targetDevicePreview: {\n gazeSimulation: dev.targetDevicePreview.gazeSimulation ?? 'head',\n },\n }),\n };\n}\n\n/** Normalize an assets/components module declaration for Vite resolution. */\nexport function normalizeProjectModuleSourcePath(sourcePath: string): string {\n return normalizeProjectSourcePath(sourcePath, 'module');\n}\n\n/** Reconstruct a validated JSON regular-expression declaration. */\nexport function projectRegexSpecToRegExp(spec: ProjectRegexSpec): RegExp {\n return new RegExp(spec.source, spec.flags ?? '');\n}\n\nfunction normalizeXR(\n source: IwsdkProjectManifestV1['world']['xr'],\n): NonNullable<WorldOptions['xr']> {\n if (source === false) {\n return false;\n }\n const sessionMode = (\n source.mode === 'vr' ? 'immersive-vr' : 'immersive-ar'\n ) as RuntimeXROptions['sessionMode'];\n return {\n sessionMode,\n ...(source.offer == null ? {} : { offer: source.offer }),\n ...(source.referenceSpace == null\n ? {}\n : {\n referenceSpace: cloneReferenceSpace(\n source.referenceSpace,\n ) as RuntimeXROptions['referenceSpace'],\n }),\n ...(source.restoreCameraOnExit == null\n ? {}\n : { restoreCameraOnExit: source.restoreCameraOnExit }),\n ...(source.launchOnSessionGranted == null\n ? {}\n : { launchOnSessionGranted: source.launchOnSessionGranted }),\n ...(source.features == null\n ? {}\n : { features: cloneXRFeatures(source.features) }),\n };\n}\n\nfunction cloneReferenceSpace(\n source: NonNullable<\n Exclude<IwsdkProjectManifestV1['world']['xr'], false>['referenceSpace']\n >,\n) {\n return typeof source === 'string'\n ? source\n : {\n ...source,\n ...(source.fallbackOrder == null\n ? {}\n : { fallbackOrder: [...source.fallbackOrder] }),\n };\n}\n\nfunction cloneXRFeatures(\n source: ProjectXRFeatureOptions,\n): NonNullable<RuntimeXROptions['features']> {\n return Object.fromEntries(\n Object.entries(source).map(([key, value]) => [\n key,\n value != null && typeof value === 'object' ? { ...value } : value,\n ]),\n ) as NonNullable<RuntimeXROptions['features']>;\n}\n\nfunction normalizeFeatures(\n source: ProjectFeatureOptions,\n): NonNullable<WorldOptions['features']> {\n const features: NonNullable<WorldOptions['features']> = {};\n if (source.locomotion != null) {\n if (typeof source.locomotion === 'boolean') {\n features.locomotion = source.locomotion;\n } else {\n const { browserControls, initialPlayerPosition, turningMethod, ...rest } =\n source.locomotion;\n features.locomotion = {\n ...rest,\n ...(initialPlayerPosition == null\n ? {}\n : {\n initialPlayerPosition: [...initialPlayerPosition],\n }),\n ...(typeof browserControls === 'object'\n ? {\n browserControls: {\n ...browserControls,\n },\n }\n : browserControls == null\n ? {}\n : { browserControls }),\n ...(turningMethod == null\n ? {}\n : {\n turningMethod: TURNING_METHOD[turningMethod],\n }),\n } as Exclude<\n NonNullable<WorldOptions['features']>['locomotion'],\n boolean | undefined\n >;\n }\n }\n if (source.grabbing != null) {\n features.grabbing =\n typeof source.grabbing === 'boolean'\n ? source.grabbing\n : { ...source.grabbing };\n }\n if (source.gaze != null) {\n features.gaze = { ...source.gaze };\n }\n if (source.physics != null) {\n features.physics =\n typeof source.physics === 'boolean'\n ? source.physics\n : { ...source.physics };\n }\n if (source.sceneUnderstanding != null) {\n features.sceneUnderstanding =\n typeof source.sceneUnderstanding === 'boolean'\n ? source.sceneUnderstanding\n : { ...source.sceneUnderstanding };\n }\n if (source.environmentRaycast != null) {\n features.environmentRaycast = source.environmentRaycast;\n }\n if (source.camera != null) {\n features.camera = source.camera;\n }\n if (source.spatialUI != null) {\n features.spatialUI =\n typeof source.spatialUI === 'boolean'\n ? source.spatialUI\n : { ...source.spatialUI };\n }\n return features;\n}\n"],"names":[],"mappings":"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"}
@@ -32,6 +32,9 @@ export interface ProjectXRFeatureOptions {
32
32
  depthSensing?: ProjectDepthSensingFlag;
33
33
  layers?: ProjectXRFeatureFlag;
34
34
  unbounded?: ProjectXRFeatureFlag;
35
+ gazeTracking?: ProjectXRFeatureFlag;
36
+ /** @deprecated Alias of {@link ProjectXRFeatureOptions.gazeTracking}. */
37
+ eyeTracking?: ProjectXRFeatureFlag;
35
38
  }
36
39
  export type ProjectReferenceSpaceSpec = ProjectReferenceSpaceType | {
37
40
  type?: ProjectReferenceSpaceType;
@@ -90,6 +93,23 @@ export type ProjectPhysicsOptions = boolean | {
90
93
  export type ProjectSceneUnderstandingOptions = boolean | {
91
94
  showWireFrame?: boolean;
92
95
  };
96
+ /**
97
+ * Tuning for gaze + pinch. `GazeSystem` registration is driven by the
98
+ * `xr.features.gazeTracking` session feature, not by this entry — these values
99
+ * only override the system's defaults when gaze is already active.
100
+ */
101
+ export interface ProjectGazeOptions {
102
+ coneAngle?: number;
103
+ maxRayLength?: number;
104
+ dwellWindowSeconds?: number;
105
+ filterMinCutoff?: number;
106
+ filterBeta?: number;
107
+ suppressWhenDirectPointerActive?: boolean;
108
+ pointerTransformFollowsHand?: boolean;
109
+ logDiagnostics?: boolean;
110
+ showDebugReticle?: boolean;
111
+ trackingLossGraceSeconds?: number;
112
+ }
93
113
  export type ProjectSpatialUIOptions = boolean | {
94
114
  forwardHtmlEvents?: boolean;
95
115
  kit?: 'default' | 'horizon';
@@ -98,6 +118,7 @@ export type ProjectSpatialUIOptions = boolean | {
98
118
  export interface ProjectFeatureOptions {
99
119
  locomotion?: ProjectLocomotionOptions;
100
120
  grabbing?: ProjectGrabbingOptions;
121
+ gaze?: ProjectGazeOptions;
101
122
  physics?: ProjectPhysicsOptions;
102
123
  sceneUnderstanding?: ProjectSceneUnderstandingOptions;
103
124
  environmentRaycast?: boolean;
@@ -110,7 +131,7 @@ export interface ProjectWorldConfiguration {
110
131
  render?: ProjectRenderOptions;
111
132
  features?: ProjectFeatureOptions;
112
133
  }
113
- export type ProjectEmulatorDevice = 'metaQuest2' | 'metaQuest3' | 'metaQuestPro' | 'oculusQuest1';
134
+ export type ProjectEmulatorDevice = 'metaQuest2' | 'metaQuest3' | 'metaQuestPro' | 'metaVRGlasses' | 'oculusQuest1';
114
135
  export type ProjectEmulatorEnvironment = 'living_room' | 'meeting_room' | 'music_room' | 'office_large' | 'office_small';
115
136
  export interface ProjectEmulatorOptions {
116
137
  device?: ProjectEmulatorDevice;
@@ -120,8 +141,14 @@ export interface ProjectEmulatorOptions {
120
141
  injectOnBuild?: boolean;
121
142
  userAgentException?: ProjectRegexSpec;
122
143
  }
144
+ export interface ProjectTargetDevicePreviewOptions {
145
+ /** Add a viewer-directed gaze source when the app requests gaze. @defaultValue 'head' */
146
+ gazeSimulation?: 'head' | false;
147
+ }
123
148
  export interface ProjectDevOptions {
124
149
  emulator?: ProjectEmulatorOptions;
150
+ /** Development-only preview layered on the browser's native XR session. */
151
+ targetDevicePreview?: ProjectTargetDevicePreviewOptions;
125
152
  }
126
153
  export interface ProjectModuleDeclaration {
127
154
  /** Extensionless, project-root-confined browser module source path. */
@@ -151,8 +178,11 @@ export interface NormalizedProjectDevOptions {
151
178
  injectOnBuild?: boolean;
152
179
  userAgentException?: RegExp;
153
180
  };
181
+ targetDevicePreview?: {
182
+ gazeSimulation: 'head' | false;
183
+ };
154
184
  }
155
- export type ProjectManifestValidationIssueCode = 'enum' | 'invalid-path' | 'invalid-regex' | 'required' | 'type' | 'unknown-key';
185
+ export type ProjectManifestValidationIssueCode = 'enum' | 'invalid-path' | 'invalid-regex' | 'range' | 'required' | 'type' | 'unknown-key';
156
186
  export interface ProjectManifestValidationIssue {
157
187
  path: string;
158
188
  code: ProjectManifestValidationIssueCode;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/project/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/project/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sources":["../../src/project/types.ts"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport type { WorldOptions } from '../init/world-initializer.js';\n\n/** Version discriminator for the first IWSDK project manifest contract. */\nexport const IWSDK_PROJECT_MANIFEST_VERSION = 'iwsdk.project.v1' as const;\n\n/** JSON representation of a regular expression used by development tooling. */\nexport interface ProjectRegexSpec {\n source: string;\n flags?: string;\n}\n\nexport type ProjectXRMode = 'vr' | 'ar';\nexport type ProjectXROffer = 'none' | 'once' | 'always';\nexport type ProjectReferenceSpaceType =\n | 'bounded-floor'\n | 'local'\n | 'local-floor'\n | 'unbounded'\n | 'viewer';\n\nexport type ProjectXRFeatureFlag = boolean | { required?: boolean };\n\nexport type ProjectDepthSensingFlag =\n | boolean\n | {\n required?: boolean;\n usage?: 'cpu-optimized' | 'gpu-optimized';\n format?: 'luminance-alpha' | 'float32';\n };\n\nexport interface ProjectXRFeatureOptions {\n handTracking?: ProjectXRFeatureFlag;\n anchors?: ProjectXRFeatureFlag;\n hitTest?: ProjectXRFeatureFlag;\n planeDetection?: ProjectXRFeatureFlag;\n meshDetection?: ProjectXRFeatureFlag;\n depthSensing?: ProjectDepthSensingFlag;\n layers?: ProjectXRFeatureFlag;\n unbounded?: ProjectXRFeatureFlag;\n}\n\nexport type ProjectReferenceSpaceSpec =\n | ProjectReferenceSpaceType\n | {\n type?: ProjectReferenceSpaceType;\n required?: boolean;\n fallbackOrder?: ProjectReferenceSpaceType[];\n };\n\nexport interface ProjectXROptions {\n mode: ProjectXRMode;\n offer?: ProjectXROffer;\n referenceSpace?: ProjectReferenceSpaceSpec;\n restoreCameraOnExit?: boolean;\n launchOnSessionGranted?: boolean;\n features?: ProjectXRFeatureOptions;\n}\n\nexport interface ProjectCameraOptions {\n position?: [number, number, number];\n rotation?: [number, number, number];\n quaternion?: [number, number, number, number];\n lookAt?: [number, number, number];\n}\n\nexport interface ProjectRenderOptions {\n fov?: number;\n near?: number;\n far?: number;\n stencil?: boolean;\n camera?: ProjectCameraOptions;\n}\n\nexport type ProjectCanvasPointerEventsOption =\n | boolean\n | {\n enabled?: boolean;\n activeDuringXR?: boolean;\n };\n\nexport interface ProjectInputOptions {\n canvasPointerEvents?: ProjectCanvasPointerEventsOption;\n}\n\nexport type ProjectBrowserLocomotionControls =\n | boolean\n | {\n keyboard?: boolean;\n gamepad?: boolean;\n };\n\nexport type ProjectTurningMethod = 'snap' | 'smooth';\n\nexport type ProjectLocomotionOptions =\n | boolean\n | {\n useWorker?: boolean;\n initialPlayerPosition?: [number, number, number];\n comfortAssistLevel?: number;\n turningMethod?: ProjectTurningMethod;\n enableJumping?: boolean;\n browserControls?: ProjectBrowserLocomotionControls;\n };\n\nexport type ProjectGrabbingOptions =\n | boolean\n | { useHandPinchForGrab?: boolean };\n\nexport type ProjectPhysicsOptions =\n | boolean\n | {\n useWorker?: boolean;\n updateFrequency?: number;\n interpolation?: boolean;\n };\n\nexport type ProjectSceneUnderstandingOptions =\n | boolean\n | { showWireFrame?: boolean };\n\nexport type ProjectSpatialUIOptions =\n | boolean\n | {\n forwardHtmlEvents?: boolean;\n kit?: 'default' | 'horizon';\n preferredColorScheme?: 'system' | 'light' | 'dark';\n };\n\nexport interface ProjectFeatureOptions {\n locomotion?: ProjectLocomotionOptions;\n grabbing?: ProjectGrabbingOptions;\n physics?: ProjectPhysicsOptions;\n sceneUnderstanding?: ProjectSceneUnderstandingOptions;\n environmentRaycast?: boolean;\n camera?: boolean;\n spatialUI?: ProjectSpatialUIOptions;\n}\n\nexport interface ProjectWorldConfiguration {\n xr: false | ProjectXROptions;\n input?: ProjectInputOptions;\n render?: ProjectRenderOptions;\n features?: ProjectFeatureOptions;\n}\n\nexport type ProjectEmulatorDevice =\n | 'metaQuest2'\n | 'metaQuest3'\n | 'metaQuestPro'\n | 'oculusQuest1';\n\nexport type ProjectEmulatorEnvironment =\n | 'living_room'\n | 'meeting_room'\n | 'music_room'\n | 'office_large'\n | 'office_small';\n\nexport interface ProjectEmulatorOptions {\n device?: ProjectEmulatorDevice;\n iwer?: boolean;\n environment?: ProjectEmulatorEnvironment;\n activation?: 'localhost' | 'always' | ProjectRegexSpec;\n injectOnBuild?: boolean;\n userAgentException?: ProjectRegexSpec;\n}\n\nexport interface ProjectDevOptions {\n emulator?: ProjectEmulatorOptions;\n}\n\nexport interface ProjectModuleDeclaration {\n /** Extensionless, project-root-confined browser module source path. */\n module: string;\n}\n\n/** Declarative, JSON-safe IWSDK project authority. */\nexport interface IwsdkProjectManifestV1 {\n $schema?: string;\n version: typeof IWSDK_PROJECT_MANIFEST_VERSION;\n /** Project source path under public/ ending in .iwsdk.scene.json. */\n scene: string;\n assets?: ProjectModuleDeclaration;\n components?: ProjectModuleDeclaration;\n world: ProjectWorldConfiguration;\n dev?: ProjectDevOptions;\n}\n\n/** World options produced before Vite injects executable asset/component manifests. */\nexport type NormalizedProjectWorldOptions = Omit<\n WorldOptions,\n 'assets' | 'components'\n> & {\n level: string;\n};\n\nexport interface NormalizedProjectDevOptions {\n emulator?: {\n device?: ProjectEmulatorDevice;\n iwer?: boolean;\n environment?: ProjectEmulatorEnvironment;\n activation?: 'localhost' | 'always' | RegExp;\n injectOnBuild?: boolean;\n userAgentException?: RegExp;\n };\n}\n\nexport type ProjectManifestValidationIssueCode =\n | 'enum'\n | 'invalid-path'\n | 'invalid-regex'\n | 'required'\n | 'type'\n | 'unknown-key';\n\nexport interface ProjectManifestValidationIssue {\n path: string;\n code: ProjectManifestValidationIssueCode;\n message: string;\n}\n\nexport interface ProjectManifestValidationResult {\n valid: boolean;\n issues: ProjectManifestValidationIssue[];\n}\n"],"names":[],"mappings":"AAAA;;;;;AAKG;AAIH;AACO,MAAM,8BAA8B,GAAG;;;;"}
1
+ {"version":3,"file":"types.js","sources":["../../src/project/types.ts"],"sourcesContent":["/**\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport type { WorldOptions } from '../init/world-initializer.js';\n\n/** Version discriminator for the first IWSDK project manifest contract. */\nexport const IWSDK_PROJECT_MANIFEST_VERSION = 'iwsdk.project.v1' as const;\n\n/** JSON representation of a regular expression used by development tooling. */\nexport interface ProjectRegexSpec {\n source: string;\n flags?: string;\n}\n\nexport type ProjectXRMode = 'vr' | 'ar';\nexport type ProjectXROffer = 'none' | 'once' | 'always';\nexport type ProjectReferenceSpaceType =\n | 'bounded-floor'\n | 'local'\n | 'local-floor'\n | 'unbounded'\n | 'viewer';\n\nexport type ProjectXRFeatureFlag = boolean | { required?: boolean };\n\nexport type ProjectDepthSensingFlag =\n | boolean\n | {\n required?: boolean;\n usage?: 'cpu-optimized' | 'gpu-optimized';\n format?: 'luminance-alpha' | 'float32';\n };\n\nexport interface ProjectXRFeatureOptions {\n handTracking?: ProjectXRFeatureFlag;\n anchors?: ProjectXRFeatureFlag;\n hitTest?: ProjectXRFeatureFlag;\n planeDetection?: ProjectXRFeatureFlag;\n meshDetection?: ProjectXRFeatureFlag;\n depthSensing?: ProjectDepthSensingFlag;\n layers?: ProjectXRFeatureFlag;\n unbounded?: ProjectXRFeatureFlag;\n gazeTracking?: ProjectXRFeatureFlag;\n /** @deprecated Alias of {@link ProjectXRFeatureOptions.gazeTracking}. */\n eyeTracking?: ProjectXRFeatureFlag;\n}\n\nexport type ProjectReferenceSpaceSpec =\n | ProjectReferenceSpaceType\n | {\n type?: ProjectReferenceSpaceType;\n required?: boolean;\n fallbackOrder?: ProjectReferenceSpaceType[];\n };\n\nexport interface ProjectXROptions {\n mode: ProjectXRMode;\n offer?: ProjectXROffer;\n referenceSpace?: ProjectReferenceSpaceSpec;\n restoreCameraOnExit?: boolean;\n launchOnSessionGranted?: boolean;\n features?: ProjectXRFeatureOptions;\n}\n\nexport interface ProjectCameraOptions {\n position?: [number, number, number];\n rotation?: [number, number, number];\n quaternion?: [number, number, number, number];\n lookAt?: [number, number, number];\n}\n\nexport interface ProjectRenderOptions {\n fov?: number;\n near?: number;\n far?: number;\n stencil?: boolean;\n camera?: ProjectCameraOptions;\n}\n\nexport type ProjectCanvasPointerEventsOption =\n | boolean\n | {\n enabled?: boolean;\n activeDuringXR?: boolean;\n };\n\nexport interface ProjectInputOptions {\n canvasPointerEvents?: ProjectCanvasPointerEventsOption;\n}\n\nexport type ProjectBrowserLocomotionControls =\n | boolean\n | {\n keyboard?: boolean;\n gamepad?: boolean;\n };\n\nexport type ProjectTurningMethod = 'snap' | 'smooth';\n\nexport type ProjectLocomotionOptions =\n | boolean\n | {\n useWorker?: boolean;\n initialPlayerPosition?: [number, number, number];\n comfortAssistLevel?: number;\n turningMethod?: ProjectTurningMethod;\n enableJumping?: boolean;\n browserControls?: ProjectBrowserLocomotionControls;\n };\n\nexport type ProjectGrabbingOptions =\n | boolean\n | { useHandPinchForGrab?: boolean };\n\nexport type ProjectPhysicsOptions =\n | boolean\n | {\n useWorker?: boolean;\n updateFrequency?: number;\n interpolation?: boolean;\n };\n\nexport type ProjectSceneUnderstandingOptions =\n | boolean\n | { showWireFrame?: boolean };\n\n/**\n * Tuning for gaze + pinch. `GazeSystem` registration is driven by the\n * `xr.features.gazeTracking` session feature, not by this entry — these values\n * only override the system's defaults when gaze is already active.\n */\nexport interface ProjectGazeOptions {\n coneAngle?: number;\n maxRayLength?: number;\n dwellWindowSeconds?: number;\n filterMinCutoff?: number;\n filterBeta?: number;\n suppressWhenDirectPointerActive?: boolean;\n pointerTransformFollowsHand?: boolean;\n logDiagnostics?: boolean;\n showDebugReticle?: boolean;\n trackingLossGraceSeconds?: number;\n}\n\nexport type ProjectSpatialUIOptions =\n | boolean\n | {\n forwardHtmlEvents?: boolean;\n kit?: 'default' | 'horizon';\n preferredColorScheme?: 'system' | 'light' | 'dark';\n };\n\nexport interface ProjectFeatureOptions {\n locomotion?: ProjectLocomotionOptions;\n grabbing?: ProjectGrabbingOptions;\n gaze?: ProjectGazeOptions;\n physics?: ProjectPhysicsOptions;\n sceneUnderstanding?: ProjectSceneUnderstandingOptions;\n environmentRaycast?: boolean;\n camera?: boolean;\n spatialUI?: ProjectSpatialUIOptions;\n}\n\nexport interface ProjectWorldConfiguration {\n xr: false | ProjectXROptions;\n input?: ProjectInputOptions;\n render?: ProjectRenderOptions;\n features?: ProjectFeatureOptions;\n}\n\nexport type ProjectEmulatorDevice =\n | 'metaQuest2'\n | 'metaQuest3'\n | 'metaQuestPro'\n | 'metaVRGlasses'\n | 'oculusQuest1';\n\nexport type ProjectEmulatorEnvironment =\n | 'living_room'\n | 'meeting_room'\n | 'music_room'\n | 'office_large'\n | 'office_small';\n\nexport interface ProjectEmulatorOptions {\n device?: ProjectEmulatorDevice;\n iwer?: boolean;\n environment?: ProjectEmulatorEnvironment;\n activation?: 'localhost' | 'always' | ProjectRegexSpec;\n injectOnBuild?: boolean;\n userAgentException?: ProjectRegexSpec;\n}\n\nexport interface ProjectTargetDevicePreviewOptions {\n /** Add a viewer-directed gaze source when the app requests gaze. @defaultValue 'head' */\n gazeSimulation?: 'head' | false;\n}\n\nexport interface ProjectDevOptions {\n emulator?: ProjectEmulatorOptions;\n /** Development-only preview layered on the browser's native XR session. */\n targetDevicePreview?: ProjectTargetDevicePreviewOptions;\n}\n\nexport interface ProjectModuleDeclaration {\n /** Extensionless, project-root-confined browser module source path. */\n module: string;\n}\n\n/** Declarative, JSON-safe IWSDK project authority. */\nexport interface IwsdkProjectManifestV1 {\n $schema?: string;\n version: typeof IWSDK_PROJECT_MANIFEST_VERSION;\n /** Project source path under public/ ending in .iwsdk.scene.json. */\n scene: string;\n assets?: ProjectModuleDeclaration;\n components?: ProjectModuleDeclaration;\n world: ProjectWorldConfiguration;\n dev?: ProjectDevOptions;\n}\n\n/** World options produced before Vite injects executable asset/component manifests. */\nexport type NormalizedProjectWorldOptions = Omit<\n WorldOptions,\n 'assets' | 'components'\n> & {\n level: string;\n};\n\nexport interface NormalizedProjectDevOptions {\n emulator?: {\n device?: ProjectEmulatorDevice;\n iwer?: boolean;\n environment?: ProjectEmulatorEnvironment;\n activation?: 'localhost' | 'always' | RegExp;\n injectOnBuild?: boolean;\n userAgentException?: RegExp;\n };\n targetDevicePreview?: {\n gazeSimulation: 'head' | false;\n };\n}\n\nexport type ProjectManifestValidationIssueCode =\n | 'enum'\n | 'invalid-path'\n | 'invalid-regex'\n | 'range'\n | 'required'\n | 'type'\n | 'unknown-key';\n\nexport interface ProjectManifestValidationIssue {\n path: string;\n code: ProjectManifestValidationIssueCode;\n message: string;\n}\n\nexport interface ProjectManifestValidationResult {\n valid: boolean;\n issues: ProjectManifestValidationIssue[];\n}\n"],"names":[],"mappings":"AAAA;;;;;AAKG;AAIH;AACO,MAAM,8BAA8B,GAAG;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/project/validation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,8BAA8B,EAEnC,KAAK,+BAA+B,EACrC,MAAM,YAAY,CAAC;AA0BpB,gEAAgE;AAChE,qBAAa,8BAA+B,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,EAAE,SAAS,8BAA8B,EAAE;gBAAjD,MAAM,EAAE,SAAS,8BAA8B,EAAE;CAQvE;AAED,4DAA4D;AAC5D,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,GACb,+BAA+B,CAoCjC;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,sBAAsB,CAEjC;AAED,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,KAAK,IAAI,sBAAsB,CAKzC"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/project/validation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,8BAA8B,EAEnC,KAAK,+BAA+B,EACrC,MAAM,YAAY,CAAC;AA2BpB,gEAAgE;AAChE,qBAAa,8BAA+B,SAAQ,KAAK;IAC3C,QAAQ,CAAC,MAAM,EAAE,SAAS,8BAA8B,EAAE;gBAAjD,MAAM,EAAE,SAAS,8BAA8B,EAAE;CAQvE;AAED,4DAA4D;AAC5D,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,GACb,+BAA+B,CAoCjC;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,sBAAsB,CAEjC;AAED,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,KAAK,IAAI,sBAAsB,CAKzC"}