@opsydyn/effect-three-foldkit 0.3.0 → 0.6.4

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 (52) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/README.md +4 -2
  3. package/dist/assetRegistry.d.ts +49 -0
  4. package/dist/assetRegistry.d.ts.map +1 -0
  5. package/dist/assets.d.ts +18 -5
  6. package/dist/assets.d.ts.map +1 -1
  7. package/dist/boxSelect.d.ts +150 -0
  8. package/dist/boxSelect.d.ts.map +1 -0
  9. package/dist/dom/canvas.d.ts +7 -0
  10. package/dist/dom/canvas.d.ts.map +1 -1
  11. package/dist/dom/pointer.d.ts.map +1 -1
  12. package/dist/dom/webgl.d.ts.map +1 -1
  13. package/dist/dom/webgpu.d.ts.map +1 -1
  14. package/dist/element.d.ts +60 -0
  15. package/dist/element.d.ts.map +1 -1
  16. package/dist/environment.d.ts +6 -0
  17. package/dist/environment.d.ts.map +1 -1
  18. package/dist/index.d.ts +7 -1
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +745 -60
  21. package/dist/index.js.map +19 -12
  22. package/dist/inspector.d.ts +24 -0
  23. package/dist/inspector.d.ts.map +1 -0
  24. package/dist/measuringTape.d.ts +76 -0
  25. package/dist/measuringTape.d.ts.map +1 -0
  26. package/dist/mount.d.ts.map +1 -1
  27. package/dist/pivotControls.d.ts +106 -0
  28. package/dist/pivotControls.d.ts.map +1 -0
  29. package/dist/transformGizmo.d.ts +158 -0
  30. package/dist/transformGizmo.d.ts.map +1 -0
  31. package/dist/view.d.ts +23 -0
  32. package/dist/view.d.ts.map +1 -1
  33. package/dist/viewportGizmo.d.ts +146 -0
  34. package/dist/viewportGizmo.d.ts.map +1 -0
  35. package/package.json +8 -8
  36. package/src/assetRegistry.ts +218 -0
  37. package/src/assets.ts +96 -39
  38. package/src/boxSelect.ts +158 -0
  39. package/src/dom/canvas.ts +12 -0
  40. package/src/dom/pointer.ts +14 -1
  41. package/src/dom/webgl.ts +15 -0
  42. package/src/dom/webgpu.ts +15 -0
  43. package/src/element.ts +6 -0
  44. package/src/environment.ts +6 -1
  45. package/src/index.ts +10 -0
  46. package/src/inspector.ts +112 -0
  47. package/src/measuringTape.ts +124 -0
  48. package/src/mount.ts +24 -1
  49. package/src/pivotControls.ts +118 -0
  50. package/src/transformGizmo.ts +131 -0
  51. package/src/view.ts +28 -0
  52. package/src/viewportGizmo.ts +119 -0
package/dist/index.js CHANGED
@@ -1,7 +1,91 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __returnValue = (v) => v;
3
+ function __exportSetter(name, newValue) {
4
+ this[name] = __returnValue.bind(null, newValue);
5
+ }
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true,
11
+ configurable: true,
12
+ set: __exportSetter.bind(all, name)
13
+ });
14
+ };
15
+
16
+ // src/boxSelect.ts
17
+ var exports_boxSelect = {};
18
+ __export(exports_boxSelect, {
19
+ Box: () => Box,
20
+ Message: () => Message,
21
+ Model: () => Model,
22
+ OutMessage: () => OutMessage,
23
+ claims: () => claims,
24
+ dragOf: () => dragOf,
25
+ drawing: () => drawing2,
26
+ init: () => init,
27
+ inside: () => inside,
28
+ rectangle: () => rectangle,
29
+ update: () => update
30
+ });
31
+
32
+ // src/measuringTape.ts
33
+ var exports_measuringTape = {};
34
+ __export(exports_measuringTape, {
35
+ Message: () => Message2,
36
+ Model: () => Model2,
37
+ OutMessage: () => OutMessage2,
38
+ init: () => init2,
39
+ label: () => label,
40
+ length: () => length,
41
+ nodes: () => nodes,
42
+ update: () => update2
43
+ });
44
+
45
+ // src/pivotControls.ts
46
+ var exports_pivotControls = {};
47
+ __export(exports_pivotControls, {
48
+ Message: () => Message3,
49
+ Model: () => Model3,
50
+ OutMessage: () => OutMessage3,
51
+ handleOf: () => handleOf,
52
+ held: () => held,
53
+ init: () => init3,
54
+ nodes: () => nodes2,
55
+ update: () => update3
56
+ });
57
+
58
+ // src/transformGizmo.ts
59
+ var exports_transformGizmo = {};
60
+ __export(exports_transformGizmo, {
61
+ Message: () => Message4,
62
+ Model: () => Model4,
63
+ OutMessage: () => OutMessage4,
64
+ handleOf: () => handleOf2,
65
+ held: () => held2,
66
+ init: () => init4,
67
+ nodes: () => nodes3,
68
+ update: () => update4
69
+ });
70
+
71
+ // src/viewportGizmo.ts
72
+ var exports_viewportGizmo = {};
73
+ __export(exports_viewportGizmo, {
74
+ Message: () => Message5,
75
+ Model: () => Model5,
76
+ OutMessage: () => OutMessage5,
77
+ axisOf: () => axisOf,
78
+ hud: () => hud,
79
+ init: () => init5,
80
+ nodes: () => nodes4,
81
+ update: () => update5
82
+ });
83
+
1
84
  // src/assets.ts
2
85
  import { Data, Effect } from "effect";
3
86
  import {
4
87
  EquirectangularReflectionMapping,
88
+ LoadingManager,
5
89
  SRGBColorSpace,
6
90
  TextureLoader
7
91
  } from "three";
@@ -41,6 +125,48 @@ var namesIn = (root) => {
41
125
  // src/assets.ts
42
126
  class AssetLoadError extends Data.TaggedError("AssetLoadError") {
43
127
  }
128
+ var nothing = [];
129
+ var plain = (release) => ({ parts: nothing, clips: nothing, release });
130
+ var lentTexture = (store, id, texture) => {
131
+ texture.colorSpace = SRGBColorSpace;
132
+ const withdraw = store.lendTexture(id, texture);
133
+ return plain(() => {
134
+ withdraw();
135
+ texture.dispose();
136
+ });
137
+ };
138
+ var lentModel = (store, id, gltf) => {
139
+ gltf.scene.animations = gltf.animations;
140
+ const withdraw = store.lend(id, gltf.scene);
141
+ return {
142
+ parts: namesIn(gltf.scene),
143
+ clips: gltf.animations.map((clip) => clip.name),
144
+ release: () => {
145
+ withdraw();
146
+ disposeModel(gltf.scene);
147
+ }
148
+ };
149
+ };
150
+ var lentEnvironment = (store, id, texture) => {
151
+ texture.mapping = EquirectangularReflectionMapping;
152
+ const withdraw = store.lendTexture(id, texture);
153
+ return plain(() => {
154
+ withdraw();
155
+ texture.dispose();
156
+ });
157
+ };
158
+ var lentFont = (store, id, font) => plain(store.lendFont(id, font));
159
+ var loadAndLend = {
160
+ model: async (store, { id, url }, manager) => lentModel(store, id, await new GLTFLoader(manager).loadAsync(url)),
161
+ texture: async (store, { id, url }, manager) => lentTexture(store, id, await new TextureLoader(manager).loadAsync(url)),
162
+ environment: async (store, { id, url }, manager) => lentEnvironment(store, id, await new HDRLoader(manager).loadAsync(url)),
163
+ font: async (store, { id, url }, manager) => lentFont(store, id, await new FontLoader(manager).loadAsync(url))
164
+ };
165
+ var assetLoader = (store) => (asset, signal) => {
166
+ const manager = new LoadingManager;
167
+ signal.addEventListener("abort", () => manager.abort(), { once: true });
168
+ return loadAndLend[asset.kind](store, asset, manager);
169
+ };
44
170
  var makeAssets = (store) => {
45
171
  const releases = new Map;
46
172
  const own = (id, release) => {
@@ -48,39 +174,21 @@ var makeAssets = (store) => {
48
174
  releases.set(id, release);
49
175
  };
50
176
  const lendTexture = (id) => (texture) => {
51
- texture.colorSpace = SRGBColorSpace;
52
- const withdraw = store.lendTexture(id, texture);
53
- own(id, () => {
54
- withdraw();
55
- texture.dispose();
56
- });
177
+ own(id, lentTexture(store, id, texture).release);
57
178
  return id;
58
179
  };
59
180
  const lendModel = (id) => (gltf) => {
60
- gltf.scene.animations = gltf.animations;
61
- const withdraw = store.lend(id, gltf.scene);
62
- own(id, () => {
63
- withdraw();
64
- disposeModel(gltf.scene);
65
- });
66
- const info = {
67
- id,
68
- parts: namesIn(gltf.scene),
69
- clips: gltf.animations.map((clip) => clip.name)
70
- };
181
+ const lent = lentModel(store, id, gltf);
182
+ own(id, lent.release);
183
+ const info = { id, parts: lent.parts, clips: lent.clips };
71
184
  return info;
72
185
  };
73
186
  const lendEnvironment = (id) => (texture) => {
74
- texture.mapping = EquirectangularReflectionMapping;
75
- const withdraw = store.lendTexture(id, texture);
76
- own(id, () => {
77
- withdraw();
78
- texture.dispose();
79
- });
187
+ own(id, lentEnvironment(store, id, texture).release);
80
188
  return id;
81
189
  };
82
190
  const lendFont = (id) => (font) => {
83
- own(id, store.lendFont(id, font));
191
+ own(id, lentFont(store, id, font).release);
84
192
  return id;
85
193
  };
86
194
  const releaseAll = () => {
@@ -162,6 +270,7 @@ var modifiersOf = (event) => ({
162
270
  meta: event.metaKey,
163
271
  alt: event.altKey
164
272
  });
273
+ var deviceOf = (event) => event instanceof PointerEvent && (event.pointerType === "touch" || event.pointerType === "pen") ? event.pointerType : "mouse";
165
274
  var pointerIdOf = (event) => event instanceof PointerEvent ? event.pointerId : 0;
166
275
  var wheelScale = [1, 16, 100];
167
276
  var toPointerInput = (event, rect) => {
@@ -180,7 +289,8 @@ var toPointerInput = (event, rect) => {
180
289
  y,
181
290
  button: event.button,
182
291
  pointer,
183
- modifiers: modifiersOf(event)
292
+ modifiers: modifiersOf(event),
293
+ device: deviceOf(event)
184
294
  };
185
295
  case "pointerup":
186
296
  return { _tag: "PointerUp", x, y, button: event.button, pointer };
@@ -556,6 +666,21 @@ var webglRendererFactory = (canvas, options = {}) => ({
556
666
  scissored = true;
557
667
  renderer.render(scene, camera);
558
668
  },
669
+ renderOver: (scene, camera) => {
670
+ if (renderer.xr.isPresenting)
671
+ return;
672
+ if (scissored) {
673
+ const { width, height } = renderer.getSize(drawingSize);
674
+ renderer.setScissorTest(false);
675
+ renderer.setViewport(0, 0, width, height);
676
+ scissored = false;
677
+ }
678
+ const autoClear = renderer.autoClear;
679
+ renderer.autoClear = false;
680
+ renderer.clearDepth();
681
+ renderer.render(scene, camera);
682
+ renderer.autoClear = autoClear;
683
+ },
559
684
  createTarget: (width, height) => createTarget(targets, width, height),
560
685
  createEnvironment: () => createRoom(renderer),
561
686
  configure: (settings) => {
@@ -783,6 +908,21 @@ var webgpuRendererFactory = (canvas, options = {}) => ({
783
908
  scissored = true;
784
909
  renderer.render(scene, camera);
785
910
  },
911
+ renderOver: (scene, camera) => {
912
+ if (renderer.xr.isPresenting)
913
+ return;
914
+ if (scissored) {
915
+ const { width, height } = renderer.getSize(drawingSize2);
916
+ renderer.setScissorTest(false);
917
+ renderer.setViewport(0, 0, width, height);
918
+ scissored = false;
919
+ }
920
+ const autoClear = renderer.autoClear;
921
+ renderer.autoClear = false;
922
+ renderer.clearDepth();
923
+ renderer.render(scene, camera);
924
+ renderer.autoClear = autoClear;
925
+ },
786
926
  createTarget: (width, height) => createTarget2(targets, width, height),
787
927
  createEnvironment: () => createRoom2(renderer),
788
928
  configure: (settings) => {
@@ -852,9 +992,11 @@ var sceneElement = CustomElement.define({
852
992
  "scene-drag": SceneSchema.DragDetail,
853
993
  "scene-drag-end": SceneSchema.DragDetail,
854
994
  "scene-gesture": SceneSchema.GestureDetail,
995
+ "scene-gesture-end": SceneSchema.GestureEndDetail,
855
996
  "scene-auto-rotated": SceneSchema.AutoRotatedDetail,
856
997
  "scene-collision": SceneSchema.CollisionDetail,
857
998
  "scene-contact-force": SceneSchema.ContactForceDetail,
999
+ "scene-physics-reached": SceneSchema.PhysicsReachedDetail,
858
1000
  "scene-measured": SceneSchema.MeasuredDetail,
859
1001
  "scene-label-measured": SceneSchema.LabelMeasuredDetail,
860
1002
  "scene-xr": XrSessionDetail,
@@ -866,6 +1008,8 @@ var sceneElement = CustomElement.define({
866
1008
  "scene-xr-meshes": SceneSchema.XrMeshesDetail,
867
1009
  "scene-performance": SceneSchema.PerformanceDetail,
868
1010
  "scene-error": Schema.Struct({ error: SceneError }),
1011
+ "scene-asset-loaded": SceneSchema.AssetLoadedDetail,
1012
+ "scene-asset-failed": SceneSchema.AssetFailedDetail,
869
1013
  "scene-reconciled": ReconciledDetail
870
1014
  }
871
1015
  });
@@ -883,9 +1027,11 @@ var domEventName = {
883
1027
  Drag: "scene-drag",
884
1028
  DragEnd: "scene-drag-end",
885
1029
  Gesture: "scene-gesture",
1030
+ GestureEnd: "scene-gesture-end",
886
1031
  AutoRotated: "scene-auto-rotated",
887
1032
  Collision: "scene-collision",
888
1033
  ContactForce: "scene-contact-force",
1034
+ PhysicsReached: "scene-physics-reached",
889
1035
  Measured: "scene-measured",
890
1036
  LabelMeasured: "scene-label-measured",
891
1037
  XrStick: "scene-xr-stick",
@@ -960,6 +1106,135 @@ import {
960
1106
  createResourceStore
961
1107
  } from "@opsydyn/effect-three";
962
1108
 
1109
+ // src/assetRegistry.ts
1110
+ import { assetsEqual } from "@opsydyn/effect-three";
1111
+ var sameAsset = (a, b) => a.kind === b.kind && a.url === b.url && a.levels.length === b.levels.length && a.levels.every((level, i) => level === b.levels[i]);
1112
+ var urlsOf = (asset) => [...asset.levels, asset.url];
1113
+ var reasonOf = (asset, cause) => cause instanceof Error && cause.message !== "" ? `Could not load ${asset.url}: ${cause.message}` : `Could not load ${asset.url}`;
1114
+ var taken = (asset, holding) => ({
1115
+ _tag: "Failed",
1116
+ ...asset,
1117
+ reason: `"${asset.id}" is already ${holding.url} for another scene`
1118
+ });
1119
+ var makeAssetRegistry = (load) => {
1120
+ const entries = new Map;
1121
+ const asking = new Map;
1122
+ const tellAll = (entry, notice) => {
1123
+ for (const holder of entry.holders)
1124
+ asking.get(holder)?.notify(notice);
1125
+ };
1126
+ const loadedNotice = (entry, level, lent) => ({
1127
+ _tag: "Loaded",
1128
+ ...entry.asset,
1129
+ level,
1130
+ final: level === entry.asset.levels.length,
1131
+ parts: lent.parts,
1132
+ clips: lent.clips
1133
+ });
1134
+ const noticesOf = (entry) => [
1135
+ ...entry.shown === undefined ? [] : [loadedNotice(entry, entry.shown.level, entry.shown.lent)],
1136
+ ...entry.failure === undefined ? [] : [{ _tag: "Failed", ...entry.asset, reason: entry.failure }]
1137
+ ];
1138
+ const start = (asset) => {
1139
+ const urls = urlsOf(asset);
1140
+ const finest = urls.length - 1;
1141
+ const entry = {
1142
+ asset,
1143
+ holders: new Set,
1144
+ controllers: urls.map(() => new AbortController),
1145
+ shown: undefined,
1146
+ failure: undefined
1147
+ };
1148
+ entries.set(asset.id, entry);
1149
+ function current(level) {
1150
+ return entries.get(asset.id) === entry && entry.controllers[level]?.signal.aborted === false;
1151
+ }
1152
+ function loaded(level) {
1153
+ return (lent) => {
1154
+ if (!current(level) || entry.shown !== undefined && entry.shown.level >= level) {
1155
+ lent.release();
1156
+ return;
1157
+ }
1158
+ const before = entry.shown;
1159
+ entry.shown = { level, lent };
1160
+ before?.lent.release();
1161
+ if (level === finest)
1162
+ for (const coarser of entry.controllers.slice(0, level))
1163
+ coarser.abort();
1164
+ tellAll(entry, loadedNotice(entry, level, lent));
1165
+ };
1166
+ }
1167
+ function failed(level) {
1168
+ return (cause) => {
1169
+ if (!current(level) || level !== finest)
1170
+ return;
1171
+ const reason = reasonOf({ ...asset, url: urls[level] ?? asset.url }, cause);
1172
+ entry.failure = reason;
1173
+ tellAll(entry, { _tag: "Failed", ...asset, reason });
1174
+ };
1175
+ }
1176
+ urls.forEach((url, level) => {
1177
+ const signal = entry.controllers[level]?.signal ?? AbortSignal.abort();
1178
+ load({ ...asset, url }, signal).then(loaded(level), failed(level));
1179
+ });
1180
+ return entry;
1181
+ };
1182
+ const end = (entry) => {
1183
+ entries.delete(entry.asset.id);
1184
+ for (const controller of entry.controllers)
1185
+ controller.abort();
1186
+ entry.shown?.lent.release();
1187
+ };
1188
+ const letGo = (holder, id) => {
1189
+ const entry = entries.get(id);
1190
+ if (entry === undefined || !entry.holders.delete(holder) || entry.holders.size > 0)
1191
+ return;
1192
+ end(entry);
1193
+ for (const [waiting, { assets }] of asking) {
1194
+ if (assets.some((asset) => asset.id === id))
1195
+ hold(waiting, assets);
1196
+ }
1197
+ };
1198
+ const hold = (holder, assets) => {
1199
+ for (const asset of assets) {
1200
+ const entry = entries.get(asset.id) ?? start(asset);
1201
+ if (!sameAsset(entry.asset, asset)) {
1202
+ asking.get(holder)?.notify(taken(asset, entry.asset));
1203
+ continue;
1204
+ }
1205
+ if (entry.holders.has(holder))
1206
+ continue;
1207
+ entry.holders.add(holder);
1208
+ for (const notice of noticesOf(entry))
1209
+ asking.get(holder)?.notify(notice);
1210
+ }
1211
+ };
1212
+ const want = (holder, assets, notify) => {
1213
+ const before = asking.get(holder);
1214
+ asking.set(holder, { assets, notify });
1215
+ if (before !== undefined && assetsEqual(before.assets, assets))
1216
+ return;
1217
+ for (const old of before?.assets ?? []) {
1218
+ const still = assets.find((asset) => asset.id === old.id);
1219
+ if (still === undefined || !sameAsset(still, old))
1220
+ letGo(holder, old.id);
1221
+ }
1222
+ hold(holder, assets);
1223
+ };
1224
+ const release = (holder) => {
1225
+ want(holder, [], () => {
1226
+ return;
1227
+ });
1228
+ asking.delete(holder);
1229
+ };
1230
+ const dispose = () => {
1231
+ asking.clear();
1232
+ for (const entry of [...entries.values()])
1233
+ end(entry);
1234
+ };
1235
+ return { want, release, dispose };
1236
+ };
1237
+
963
1238
  // src/dom/xr.ts
964
1239
  import { Group as Group2 } from "three";
965
1240
 
@@ -1614,6 +1889,7 @@ var createXrHub = (system) => {
1614
1889
  var makeEnvironment = (host, options = {}) => {
1615
1890
  const store = createResourceStore();
1616
1891
  const assets = makeAssets(store);
1892
+ const assetRegistry = makeAssetRegistry(assetLoader(store));
1617
1893
  const xrHub = createXrHub(() => host.navigator?.xr);
1618
1894
  return {
1619
1895
  host,
@@ -1625,14 +1901,62 @@ var makeEnvironment = (host, options = {}) => {
1625
1901
  physics: Promise.resolve(options.physics),
1626
1902
  labels: options.labels,
1627
1903
  assets,
1904
+ assetRegistry,
1628
1905
  xr: makeXr(xrHub),
1629
1906
  xrHub,
1630
1907
  dispose: () => {
1908
+ assetRegistry.dispose();
1631
1909
  assets.dispose();
1632
1910
  store.dispose();
1633
1911
  }
1634
1912
  };
1635
1913
  };
1914
+ // src/inspector.ts
1915
+ var axisNames = ["x", "y", "z"];
1916
+ var nameOf = (field) => field.path.filter((part) => typeof part === "string").join(" ") || field.label;
1917
+ var hex = (colour) => `#${colour.toString(16).padStart(6, "0")}`;
1918
+ var numberInput = (h, label, value, report) => h.input([
1919
+ h.Type("number"),
1920
+ h.Step("any"),
1921
+ h.Value(String(value)),
1922
+ h.AriaLabel(label),
1923
+ h.OnChange(report)
1924
+ ]);
1925
+ var controlOf = (h, field, onEdit) => {
1926
+ const name = nameOf(field);
1927
+ switch (field._tag) {
1928
+ case "Number":
1929
+ return numberInput(h, name, field.value, (raw) => onEdit(field.path, Number(raw)));
1930
+ case "Text":
1931
+ return h.input([
1932
+ h.Type("text"),
1933
+ h.Value(field.value),
1934
+ h.AriaLabel(name),
1935
+ h.OnChange((raw) => onEdit(field.path, raw))
1936
+ ]);
1937
+ case "Toggle":
1938
+ return h.input([
1939
+ h.Type("checkbox"),
1940
+ h.Checked(field.value),
1941
+ h.AriaLabel(name),
1942
+ h.OnClick(onEdit(field.path, !field.value))
1943
+ ]);
1944
+ case "Choice":
1945
+ return h.select([h.AriaLabel(name), h.OnChange((raw) => onEdit(field.path, raw))], field.options.map((option) => h.option([h.Value(option), h.Selected(option === field.value)], [option])));
1946
+ case "Colour":
1947
+ return h.input([
1948
+ h.Type("color"),
1949
+ h.Value(hex(field.value)),
1950
+ h.AriaLabel(name),
1951
+ h.OnInput((raw) => onEdit(field.path, Number.parseInt(raw.slice(1), 16)))
1952
+ ]);
1953
+ case "Vector":
1954
+ return h.span([h.Class("e3-inspector-vector")], field.value.map((component, index) => numberInput(h, `${name} ${axisNames[index] ?? index}`, component, (raw) => onEdit([...field.path, index], Number(raw)))));
1955
+ case "Fixed":
1956
+ return h.span([h.Class("e3-inspector-fixed")], [field.text]);
1957
+ }
1958
+ };
1959
+ var inspectorView = (h, fields, onEdit) => h.div([h.Class("e3-inspector")], fields.map((field) => h.keyed("label")(field.path.join("."), [h.Class("e3-inspector-row")], [h.span([h.Class("e3-inspector-name")], [nameOf(field)]), controlOf(h, field, onEdit)])));
1636
1960
  // src/mount.ts
1637
1961
  import {
1638
1962
  createGatedFrames,
@@ -1660,6 +1984,11 @@ var dispatchSceneEvent = (element, event) => {
1660
1984
  var dispatchSceneError = (element, error) => {
1661
1985
  element.dispatchEvent(new CustomEvent("scene-error", { detail: { error } }));
1662
1986
  };
1987
+ var dispatchAssetNotice = (element, notice) => {
1988
+ const { _tag, ...detail } = notice;
1989
+ const name = _tag === "Loaded" ? "scene-asset-loaded" : "scene-asset-failed";
1990
+ element.dispatchEvent(new CustomEvent(name, { detail }));
1991
+ };
1663
1992
  var canvasIn = (host) => () => appendCanvas(host);
1664
1993
  var removal = (node) => () => node.remove();
1665
1994
  var sceneEventDispatch = (element, live) => (event) => () => {
@@ -1683,10 +2012,10 @@ var createLatch = (open) => {
1683
2012
  }
1684
2013
  };
1685
2014
  };
1686
- var nothing = [];
2015
+ var nothing2 = [];
1687
2016
  var routedWhileOpen = (latch, route) => (value) => {
1688
2017
  if (!latch.isOpen())
1689
- return nothing;
2018
+ return nothing2;
1690
2019
  return route(value);
1691
2020
  };
1692
2021
  var applying = (f, value) => () => f(value);
@@ -1857,11 +2186,21 @@ var connectObserver = (observe) => (queue) => {
1857
2186
  return Effect3.acquireRelease(connect, Effect3.sync);
1858
2187
  };
1859
2188
  var observed = (observe) => Stream.callback(connectObserver(observe));
2189
+ var asking = (mounted, scene) => () => mounted.environment.assetRegistry.want(mounted.element, scene.assets, (notice) => dispatchAssetNotice(mounted.element, notice));
2190
+ var lettingGo = (mounted) => () => mounted.environment.assetRegistry.release(mounted.element);
2191
+ var acquireAssets = (mounted, initial) => {
2192
+ const ask = Effect3.sync(asking(mounted, initial));
2193
+ return Effect3.acquireRelease(ask, () => Effect3.sync(lettingGo(mounted)));
2194
+ };
2195
+ var updated = (mounted) => (scene) => {
2196
+ const ask = Effect3.sync(asking(mounted, scene));
2197
+ return Effect3.tap(mounted.handle.update(scene), () => ask);
2198
+ };
1860
2199
  var applyUpdate = (mounted) => (value) => {
1861
2200
  const reportError = sceneErrorDispatch(mounted.element);
1862
2201
  const reportReconciled = afterUpdate(reconciledDispatch(mounted.element, mounted.environment.store), [touchActionSync(mounted.canvas, mounted.handle.graph), mounted.overlays.rewrite]);
1863
2202
  const decoded = decodeScene(value);
1864
- const applied = decoded.pipe(Effect3.flatMap(mounted.handle.update), Effect3.flatMap((ops) => Effect3.sync(reportReconciled(ops))));
2203
+ const applied = decoded.pipe(Effect3.flatMap(updated(mounted)), Effect3.flatMap((ops) => Effect3.sync(reportReconciled(ops))));
1865
2204
  return applied.pipe(Effect3.catchTags({
1866
2205
  SchemaError: (error) => Effect3.sync(reportError({ _tag: "MalformedScene", issue: error.message })),
1867
2206
  InvalidScene: ({ error }) => Effect3.sync(reportError(error))
@@ -1922,6 +2261,7 @@ function* runScene(environment, element, viewStateChanges) {
1922
2261
  gate: createFrameGate(frames),
1923
2262
  live: createLatch(true)
1924
2263
  };
2264
+ yield* acquireAssets(mounted, initial);
1925
2265
  yield* acquirePointer(canvas, mounted);
1926
2266
  yield* acquireXrTarget(mounted);
1927
2267
  yield* Effect3.sync(touchActionSync(canvas, handle.graph));
@@ -1945,8 +2285,343 @@ var makeSceneMount = (environment) => Mount.define("EffectThreeScene", {
1945
2285
  messages: [SceneLifecycle.StartedScene, SceneLifecycle.FailedScene],
1946
2286
  execute: mountScene(environment)
1947
2287
  });
2288
+ // src/boxSelect.ts
2289
+ import { boxSelect, SceneSchema as SceneSchema3 } from "@opsydyn/effect-three";
2290
+ import { Option as Option2, Schema as Schema3 } from "effect";
2291
+ import { defineMessageUnion as defineMessageUnion2 } from "foldkit/message";
2292
+ var Corner = Schema3.Struct({ x: Schema3.Finite, y: Schema3.Finite });
2293
+ var Selectable = Schema3.Struct({ key: Schema3.String, at: SceneSchema3.Vec3 });
2294
+ var Box = Schema3.Struct({
2295
+ from: Corner,
2296
+ to: Corner,
2297
+ width: Schema3.Finite,
2298
+ height: Schema3.Finite
2299
+ });
2300
+ var Model = Schema3.Struct({ box: Schema3.Option(Box) });
2301
+ var Message = defineMessageUnion2({
2302
+ Dragged: {
2303
+ x: Schema3.Finite,
2304
+ y: Schema3.Finite,
2305
+ deltaX: Schema3.Finite,
2306
+ deltaY: Schema3.Finite,
2307
+ width: Schema3.Finite,
2308
+ height: Schema3.Finite
2309
+ },
2310
+ Ended: { camera: SceneSchema3.Camera, selectable: Schema3.Array(Selectable) },
2311
+ Cancelled: {}
2312
+ });
2313
+ var OutMessage = defineMessageUnion2({
2314
+ Selected: { keys: Schema3.Array(Schema3.String) }
2315
+ });
2316
+ var init = () => ({ box: Option2.none() });
2317
+ var moved = (box, deltaX, deltaY) => ({
2318
+ ...box,
2319
+ to: { x: box.to.x + deltaX * 2 / box.width, y: box.to.y - deltaY * 2 / box.height }
2320
+ });
2321
+ var dragged = (model, message) => {
2322
+ const { x, y, deltaX, deltaY, width, height } = message;
2323
+ const start = { from: { x, y }, to: { x, y }, width, height };
2324
+ const box = Option2.getOrElse(model.box, () => start);
2325
+ return { box: Option2.some(moved(box, deltaX, deltaY)) };
2326
+ };
2327
+ var keysIn = (box, camera, selectable) => boxSelect(camera, box, box.from, box.to, selectable);
2328
+ var ended = (model, camera, selectable) => Option2.match(model.box, {
2329
+ onNone: () => ({ model }),
2330
+ onSome: (box) => ({
2331
+ model: init(),
2332
+ outMessage: OutMessage.Selected({ keys: keysIn(box, camera, selectable) })
2333
+ })
2334
+ });
2335
+ var update = (model, message) => Message.match(message, {
2336
+ Dragged: (drag) => ({ model: dragged(model, drag) }),
2337
+ Ended: ({ camera, selectable }) => ended(model, camera, selectable),
2338
+ Cancelled: () => ({ model: init() })
2339
+ });
2340
+ var drawing2 = (model) => Option2.isSome(model.box);
2341
+ var primaryButton = 0;
2342
+ var startsBox = (drag) => drag.button === primaryButton && drag.modifiers.shift && drag.key === undefined;
2343
+ var claims = (model, drag) => drawing2(model) || startsBox(drag);
2344
+ var dragOf = (gesture) => Message.Dragged({
2345
+ x: gesture.x,
2346
+ y: gesture.y,
2347
+ deltaX: gesture.deltaX,
2348
+ deltaY: gesture.deltaY,
2349
+ width: gesture.width,
2350
+ height: gesture.height
2351
+ });
2352
+ var inside = (model, camera, selectable) => Option2.match(model.box, {
2353
+ onNone: () => [],
2354
+ onSome: (box) => keysIn(box, camera, selectable)
2355
+ });
2356
+ var onCanvas = (box) => {
2357
+ const left = (Math.min(box.from.x, box.to.x) + 1) / 2 * box.width;
2358
+ const right = (Math.max(box.from.x, box.to.x) + 1) / 2 * box.width;
2359
+ const top = (1 - Math.max(box.from.y, box.to.y)) / 2 * box.height;
2360
+ const bottom = (1 - Math.min(box.from.y, box.to.y)) / 2 * box.height;
2361
+ return { left, top, width: right - left, height: bottom - top };
2362
+ };
2363
+ var rectangle = (model) => Option2.map(model.box, onCanvas);
2364
+ // src/measuringTape.ts
2365
+ import {
2366
+ clearTape,
2367
+ overlay,
2368
+ placeTapeEnd,
2369
+ pointTape,
2370
+ SceneSchema as SceneSchema4,
2371
+ tape,
2372
+ tapeLength,
2373
+ tapeMiddle,
2374
+ tapeNodes
2375
+ } from "@opsydyn/effect-three";
2376
+ import { Option as Option3, Schema as Schema4 } from "effect";
2377
+ import { defineMessageUnion as defineMessageUnion3 } from "foldkit/message";
2378
+ var Model2 = Schema4.Struct({
2379
+ key: Schema4.String,
2380
+ tape: SceneSchema4.Tape
2381
+ });
2382
+ var Message2 = defineMessageUnion3({
2383
+ Placed: { point: SceneSchema4.Vec3 },
2384
+ Pointed: { point: Schema4.NullOr(SceneSchema4.Vec3) },
2385
+ Cleared: {},
2386
+ ChoseSnap: { snap: SceneSchema4.Tape.fields.snap }
2387
+ });
2388
+ var OutMessage2 = defineMessageUnion3({
2389
+ Measured: { from: SceneSchema4.Vec3, to: SceneSchema4.Vec3, length: Schema4.Finite }
2390
+ });
2391
+ var init2 = (key, options = {}) => ({
2392
+ key,
2393
+ tape: tape(options)
2394
+ });
2395
+ var measured = (next) => Option3.match(Option3.all([Option3.fromNullishOr(next.tape.from), Option3.fromNullishOr(next.tape.to)]), {
2396
+ onNone: () => ({ model: next }),
2397
+ onSome: ([from, to]) => ({
2398
+ model: next,
2399
+ outMessage: OutMessage2.Measured({ from, to, length: tapeLength(next.tape) ?? 0 })
2400
+ })
2401
+ });
2402
+ var update2 = (model, message) => Message2.match(message, {
2403
+ Placed: ({ point }) => measured({ ...model, tape: placeTapeEnd(model.tape, point) }),
2404
+ Pointed: ({ point }) => ({ model: { ...model, tape: pointTape(model.tape, point) } }),
2405
+ Cleared: () => ({ model: { ...model, tape: clearTape(model.tape) } }),
2406
+ ChoseSnap: ({ snap }) => ({ model: { ...model, tape: { ...model.tape, snap } } })
2407
+ });
2408
+ var length = (model) => Option3.fromNullishOr(tapeLength(model.tape));
2409
+ var nodes = (model, look = {}) => tapeNodes(model.key, model.tape, look);
2410
+ var classOf = (h, className) => Option3.match(Option3.fromNullishOr(className), {
2411
+ onNone: () => [],
2412
+ onSome: (name) => [h.Class(name)]
2413
+ });
2414
+ var label = (model, h, options = {}) => Option3.match(Option3.all([length(model), Option3.fromNullishOr(tapeMiddle(model.tape))]), {
2415
+ onNone: () => [],
2416
+ onSome: ([measuredLength, middle]) => [
2417
+ {
2418
+ overlay: overlay({ key: `${model.key}:label`, position: middle, center: true }),
2419
+ content: h.span(classOf(h, options.className), [
2420
+ `${measuredLength.toFixed(2)} ${options.unit ?? "m"}`
2421
+ ]),
2422
+ pointerEvents: "none"
2423
+ }
2424
+ ]
2425
+ });
2426
+ // src/pivotControls.ts
2427
+ import {
2428
+ dragPivot,
2429
+ hoverPivot,
2430
+ pivot,
2431
+ pivotHandleOf,
2432
+ pivotNodes,
2433
+ pressPivot,
2434
+ releasePivot,
2435
+ SceneSchema as SceneSchema5
2436
+ } from "@opsydyn/effect-three";
2437
+ import { Option as Option4, Schema as Schema5 } from "effect";
2438
+ import { defineMessageUnion as defineMessageUnion4 } from "foldkit/message";
2439
+ var Model3 = Schema5.Struct({
2440
+ key: Schema5.String,
2441
+ pivot: SceneSchema5.Pivot,
2442
+ last: Schema5.Option(SceneSchema5.Placement)
2443
+ });
2444
+ var Handle = SceneSchema5.PivotHandle;
2445
+ var Message3 = defineMessageUnion4({
2446
+ Pressed: { handle: Handle, point: SceneSchema5.Vec3, placement: SceneSchema5.Placement },
2447
+ Dragged: { origin: SceneSchema5.Vec3, direction: SceneSchema5.Vec3, snap: Schema5.Boolean },
2448
+ Released: {},
2449
+ Hovered: { handle: Schema5.NullOr(Handle) }
2450
+ });
2451
+ var OutMessage3 = defineMessageUnion4({
2452
+ Moved: { placement: SceneSchema5.Placement },
2453
+ Finished: { placement: SceneSchema5.Placement }
2454
+ });
2455
+ var init3 = (key, options = {}) => ({
2456
+ key,
2457
+ pivot: pivot(options),
2458
+ last: Option4.none()
2459
+ });
2460
+ var withPivot = (model, next) => ({ ...model, pivot: next });
2461
+ var finished = (model) => ({
2462
+ model: { ...withPivot(model, releasePivot(model.pivot)), last: Option4.none() },
2463
+ ...Option4.match(model.last, {
2464
+ onNone: () => ({}),
2465
+ onSome: (placement) => ({ outMessage: OutMessage3.Finished({ placement }) })
2466
+ })
2467
+ });
2468
+ var dragged2 = (model, origin, direction, snap) => {
2469
+ const placement = Option4.fromNullishOr(dragPivot(model.pivot, { origin, direction }, { snap }));
2470
+ return Option4.match(placement, {
2471
+ onNone: () => ({ model }),
2472
+ onSome: (placement) => ({
2473
+ model: { ...model, last: Option4.some(placement) },
2474
+ outMessage: OutMessage3.Moved({ placement })
2475
+ })
2476
+ });
2477
+ };
2478
+ var update3 = (model, message) => Message3.match(message, {
2479
+ Pressed: ({ handle, point, placement }) => ({
2480
+ model: {
2481
+ ...withPivot(model, pressPivot(model.pivot, placement, handle, point)),
2482
+ last: Option4.none()
2483
+ }
2484
+ }),
2485
+ Dragged: ({ origin, direction, snap }) => dragged2(model, origin, direction, snap),
2486
+ Released: () => finished(model),
2487
+ Hovered: ({ handle }) => ({ model: withPivot(model, hoverPivot(model.pivot, handle)) })
2488
+ });
2489
+ var handleOf = (model, key) => Option4.fromNullishOr(pivotHandleOf(model.key, key));
2490
+ var held = (model) => model.pivot.grab !== null;
2491
+ var nodes2 = (model, placement) => pivotNodes(model.key, model.pivot, placement);
2492
+ // src/transformGizmo.ts
2493
+ import {
2494
+ dragGizmo,
2495
+ gizmo,
2496
+ gizmoHandleOf,
2497
+ gizmoNodes,
2498
+ hoverGizmo,
2499
+ pressGizmo,
2500
+ releaseGizmo,
2501
+ SceneSchema as SceneSchema6
2502
+ } from "@opsydyn/effect-three";
2503
+ import { Option as Option5, Schema as Schema6 } from "effect";
2504
+ import { defineMessageUnion as defineMessageUnion5 } from "foldkit/message";
2505
+ var Model4 = Schema6.Struct({
2506
+ key: Schema6.String,
2507
+ gizmo: SceneSchema6.Gizmo,
2508
+ last: Schema6.Option(SceneSchema6.Placement)
2509
+ });
2510
+ var Handle2 = Schema6.Literals(["x", "y", "z", "xy", "yz", "xz", "xyz"]);
2511
+ var Message4 = defineMessageUnion5({
2512
+ Pressed: {
2513
+ handle: Handle2,
2514
+ origin: SceneSchema6.Vec3,
2515
+ direction: SceneSchema6.Vec3,
2516
+ placement: SceneSchema6.Placement,
2517
+ camera: SceneSchema6.Camera
2518
+ },
2519
+ Dragged: { origin: SceneSchema6.Vec3, direction: SceneSchema6.Vec3 },
2520
+ Released: {},
2521
+ Hovered: { handle: Schema6.NullOr(Handle2) },
2522
+ ChoseMode: { mode: Schema6.Literals(["translate", "rotate", "scale"]) },
2523
+ ChoseSpace: { space: Schema6.Literals(["world", "local"]) }
2524
+ });
2525
+ var OutMessage4 = defineMessageUnion5({
2526
+ Moved: { placement: SceneSchema6.Placement },
2527
+ Finished: { placement: SceneSchema6.Placement }
2528
+ });
2529
+ var init4 = (key, options = {}) => ({
2530
+ key,
2531
+ gizmo: gizmo(options),
2532
+ last: Option5.none()
2533
+ });
2534
+ var withGizmo = (model, next) => ({ ...model, gizmo: next });
2535
+ var finished2 = (model) => ({
2536
+ model: { ...withGizmo(model, releaseGizmo(model.gizmo)), last: Option5.none() },
2537
+ ...Option5.match(model.last, {
2538
+ onNone: () => ({}),
2539
+ onSome: (placement) => ({ outMessage: OutMessage4.Finished({ placement }) })
2540
+ })
2541
+ });
2542
+ var dragged3 = (model, origin, direction) => {
2543
+ const placement = Option5.fromNullishOr(dragGizmo(model.gizmo, { origin, direction }));
2544
+ return Option5.match(placement, {
2545
+ onNone: () => ({ model }),
2546
+ onSome: (placement) => ({
2547
+ model: { ...model, last: Option5.some(placement) },
2548
+ outMessage: OutMessage4.Moved({ placement })
2549
+ })
2550
+ });
2551
+ };
2552
+ var update4 = (model, message) => Message4.match(message, {
2553
+ Pressed: ({ handle, origin, direction, placement, camera }) => ({
2554
+ model: {
2555
+ ...withGizmo(model, pressGizmo(model.gizmo, placement, handle, { origin, direction }, camera)),
2556
+ last: Option5.none()
2557
+ }
2558
+ }),
2559
+ Dragged: ({ origin, direction }) => dragged3(model, origin, direction),
2560
+ Released: () => finished2(model),
2561
+ Hovered: ({ handle }) => ({ model: withGizmo(model, hoverGizmo(model.gizmo, handle)) }),
2562
+ ChoseMode: ({ mode }) => ({ model: withGizmo(model, { ...model.gizmo, mode }) }),
2563
+ ChoseSpace: ({ space }) => ({ model: withGizmo(model, { ...model.gizmo, space }) })
2564
+ });
2565
+ var handleOf2 = (model, key) => Option5.fromNullishOr(gizmoHandleOf(model.key, key));
2566
+ var held2 = (model) => model.gizmo.grab !== null;
2567
+ var nodes3 = (model, placement, camera) => gizmoNodes(model.key, model.gizmo, placement, camera);
2568
+ // src/viewportGizmo.ts
2569
+ import {
2570
+ cameraAlong,
2571
+ hud as describeHud,
2572
+ SceneSchema as SceneSchema7,
2573
+ viewportAxisOf,
2574
+ viewportGizmoNodes
2575
+ } from "@opsydyn/effect-three";
2576
+ import { Option as Option6, Schema as Schema7 } from "effect";
2577
+ import { defineMessageUnion as defineMessageUnion6 } from "foldkit/message";
2578
+ var Axis = Schema7.Literals(["x", "y", "z", "-x", "-y", "-z"]);
2579
+ var Model5 = Schema7.Struct({
2580
+ key: Schema7.String,
2581
+ hovered: Schema7.NullOr(Axis),
2582
+ hideNegativeAxes: Schema7.Boolean
2583
+ });
2584
+ var Message5 = defineMessageUnion6({
2585
+ Entered: { key: Schema7.String },
2586
+ Left: { key: Schema7.String },
2587
+ Pressed: { key: Schema7.String, camera: SceneSchema7.Camera }
2588
+ });
2589
+ var OutMessage5 = defineMessageUnion6({
2590
+ Turned: { camera: SceneSchema7.Camera }
2591
+ });
2592
+ var init5 = (key, options = {}) => ({
2593
+ key,
2594
+ hovered: null,
2595
+ hideNegativeAxes: options.hideNegativeAxes ?? false
2596
+ });
2597
+ var axisOf = (model, key) => Option6.fromNullishOr(viewportAxisOf(model.key, key));
2598
+ var entered = (model, key) => Option6.match(axisOf(model, key), {
2599
+ onNone: () => model,
2600
+ onSome: (axis) => ({ ...model, hovered: axis })
2601
+ });
2602
+ var left = (model, key) => Option6.match(axisOf(model, key), {
2603
+ onNone: () => model,
2604
+ onSome: () => ({ ...model, hovered: null })
2605
+ });
2606
+ var pressed = (model, key, camera) => Option6.match(axisOf(model, key), {
2607
+ onNone: () => ({ model }),
2608
+ onSome: (axis) => ({
2609
+ model,
2610
+ outMessage: OutMessage5.Turned({ camera: cameraAlong(camera, axis) })
2611
+ })
2612
+ });
2613
+ var update5 = (model, message) => Message5.match(message, {
2614
+ Entered: ({ key }) => ({ model: entered(model, key) }),
2615
+ Left: ({ key }) => ({ model: left(model, key) }),
2616
+ Pressed: ({ key, camera }) => pressed(model, key, camera)
2617
+ });
2618
+ var nodes4 = (model, camera) => viewportGizmoNodes(model.key, camera, {
2619
+ hovered: model.hovered,
2620
+ hideNegativeAxes: model.hideNegativeAxes
2621
+ });
2622
+ var hud = (model, camera, placement = {}) => describeHud({ ...placement, children: [nodes4(model, camera)] });
1948
2623
  // src/view.ts
1949
- import { Array as Arr, Option as Option2 } from "effect";
2624
+ import { Array as Arr, Option as Option7 } from "effect";
1950
2625
  import { Mount as Mount2 } from "foldkit";
1951
2626
 
1952
2627
  // src/overlayView.ts
@@ -1973,39 +2648,43 @@ var overlayLayer = (h, overlays) => overlays.length === 0 ? [] : [
1973
2648
  ];
1974
2649
 
1975
2650
  // src/view.ts
1976
- var given = Option2.fromNullishOr;
2651
+ var given = Option7.fromNullishOr;
1977
2652
  var view = (config, h) => {
1978
2653
  const element = sceneElement.withMessage(h);
1979
2654
  const optional = Arr.getSomes([
1980
- Option2.map(given(config.onClick), element.OnSceneClick),
1981
- Option2.map(given(config.onDoubleClick), element.OnSceneDoubleClick),
1982
- Option2.map(given(config.onContextMenu), element.OnSceneContextMenu),
1983
- Option2.map(given(config.onPointerDown), element.OnScenePointerDown),
1984
- Option2.map(given(config.onPointerUp), element.OnScenePointerUp),
1985
- Option2.map(given(config.onPointerEnter), element.OnScenePointerEnter),
1986
- Option2.map(given(config.onPointerMove), element.OnScenePointerMove),
1987
- Option2.map(given(config.onPointerLeave), element.OnScenePointerLeave),
1988
- Option2.map(given(config.onPointerMissed), element.OnScenePointerMissed),
1989
- Option2.map(given(config.onWheel), element.OnSceneWheel),
1990
- Option2.map(given(config.onDrag), element.OnSceneDrag),
1991
- Option2.map(given(config.onDragEnd), element.OnSceneDragEnd),
1992
- Option2.map(given(config.onCollision), element.OnSceneCollision),
1993
- Option2.map(given(config.onContactForce), element.OnSceneContactForce),
1994
- Option2.map(given(config.onMeasured), element.OnSceneMeasured),
1995
- Option2.map(given(config.onLabelMeasured), element.OnSceneLabelMeasured),
1996
- Option2.map(given(config.onXRSession), element.OnSceneXr),
1997
- Option2.map(given(config.onXRStick), element.OnSceneXrStick),
1998
- Option2.map(given(config.onXRButton), element.OnSceneXrButton),
1999
- Option2.map(given(config.onXRSurface), element.OnSceneXrSurface),
2000
- Option2.map(given(config.onXRMoved), element.OnSceneXrMoved),
2001
- Option2.map(given(config.onXRPlanes), element.OnSceneXrPlanes),
2002
- Option2.map(given(config.onXRMeshes), element.OnSceneXrMeshes),
2003
- Option2.map(given(config.onAutoRotated), element.OnSceneAutoRotated),
2004
- Option2.map(given(config.onGesture), (toMessage) => element.OnSceneGesture((detail) => toMessage(detail.gesture))),
2005
- Option2.map(given(config.onPerformanceChange), element.OnScenePerformance),
2006
- Option2.map(given(config.onError), element.OnSceneError),
2007
- Option2.map(given(config.onReconciled), element.OnSceneReconciled),
2008
- Option2.map(given(config.className), h.Class)
2655
+ Option7.map(given(config.onClick), element.OnSceneClick),
2656
+ Option7.map(given(config.onDoubleClick), element.OnSceneDoubleClick),
2657
+ Option7.map(given(config.onContextMenu), element.OnSceneContextMenu),
2658
+ Option7.map(given(config.onPointerDown), element.OnScenePointerDown),
2659
+ Option7.map(given(config.onPointerUp), element.OnScenePointerUp),
2660
+ Option7.map(given(config.onPointerEnter), element.OnScenePointerEnter),
2661
+ Option7.map(given(config.onPointerMove), element.OnScenePointerMove),
2662
+ Option7.map(given(config.onPointerLeave), element.OnScenePointerLeave),
2663
+ Option7.map(given(config.onPointerMissed), element.OnScenePointerMissed),
2664
+ Option7.map(given(config.onWheel), element.OnSceneWheel),
2665
+ Option7.map(given(config.onDrag), element.OnSceneDrag),
2666
+ Option7.map(given(config.onDragEnd), element.OnSceneDragEnd),
2667
+ Option7.map(given(config.onCollision), element.OnSceneCollision),
2668
+ Option7.map(given(config.onContactForce), element.OnSceneContactForce),
2669
+ Option7.map(given(config.onPhysicsReached), element.OnScenePhysicsReached),
2670
+ Option7.map(given(config.onMeasured), element.OnSceneMeasured),
2671
+ Option7.map(given(config.onLabelMeasured), element.OnSceneLabelMeasured),
2672
+ Option7.map(given(config.onXRSession), element.OnSceneXr),
2673
+ Option7.map(given(config.onXRStick), element.OnSceneXrStick),
2674
+ Option7.map(given(config.onXRButton), element.OnSceneXrButton),
2675
+ Option7.map(given(config.onXRSurface), element.OnSceneXrSurface),
2676
+ Option7.map(given(config.onXRMoved), element.OnSceneXrMoved),
2677
+ Option7.map(given(config.onXRPlanes), element.OnSceneXrPlanes),
2678
+ Option7.map(given(config.onXRMeshes), element.OnSceneXrMeshes),
2679
+ Option7.map(given(config.onAutoRotated), element.OnSceneAutoRotated),
2680
+ Option7.map(given(config.onGesture), (toMessage) => element.OnSceneGesture((detail) => toMessage(detail.gesture))),
2681
+ Option7.map(given(config.onGestureEnd), element.OnSceneGestureEnd),
2682
+ Option7.map(given(config.onPerformanceChange), element.OnScenePerformance),
2683
+ Option7.map(given(config.onError), element.OnSceneError),
2684
+ Option7.map(given(config.onAssetLoaded), element.OnSceneAssetLoaded),
2685
+ Option7.map(given(config.onAssetFailed), element.OnSceneAssetFailed),
2686
+ Option7.map(given(config.onReconciled), element.OnSceneReconciled),
2687
+ Option7.map(given(config.className), h.Class)
2009
2688
  ]);
2010
2689
  const lifecycle = Mount2.mapMessage(config.mount(), config.onLifecycle);
2011
2690
  const overlays = config.overlays ?? [];
@@ -2014,9 +2693,14 @@ var view = (config, h) => {
2014
2693
  };
2015
2694
  export {
2016
2695
  AssetLoadError,
2696
+ exports_boxSelect as BoxSelect,
2697
+ exports_measuringTape as MeasuringTape,
2698
+ exports_pivotControls as PivotControls,
2017
2699
  ReconciledDetail,
2018
2700
  SceneError,
2019
2701
  SceneLifecycle,
2702
+ exports_transformGizmo as TransformGizmo,
2703
+ exports_viewportGizmo as ViewportGizmo,
2020
2704
  XrSessionDetail,
2021
2705
  XrUnavailable,
2022
2706
  animationFrameScheduler,
@@ -2024,6 +2708,7 @@ export {
2024
2708
  claimsContextMenu,
2025
2709
  defaultPixelRatio,
2026
2710
  domEventName,
2711
+ inspectorView,
2027
2712
  makeAssets,
2028
2713
  makeEnvironment,
2029
2714
  makeSceneMount,
@@ -2037,5 +2722,5 @@ export {
2037
2722
  webgpuRendererFactory
2038
2723
  };
2039
2724
 
2040
- //# debugId=4118984BABDF337D64756E2164756E21
2725
+ //# debugId=91E3923C3006D06864756E2164756E21
2041
2726
  //# sourceMappingURL=index.js.map