@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.
- package/CHANGELOG.md +51 -0
- package/README.md +4 -2
- package/dist/assetRegistry.d.ts +49 -0
- package/dist/assetRegistry.d.ts.map +1 -0
- package/dist/assets.d.ts +18 -5
- package/dist/assets.d.ts.map +1 -1
- package/dist/boxSelect.d.ts +150 -0
- package/dist/boxSelect.d.ts.map +1 -0
- package/dist/dom/canvas.d.ts +7 -0
- package/dist/dom/canvas.d.ts.map +1 -1
- package/dist/dom/pointer.d.ts.map +1 -1
- package/dist/dom/webgl.d.ts.map +1 -1
- package/dist/dom/webgpu.d.ts.map +1 -1
- package/dist/element.d.ts +60 -0
- package/dist/element.d.ts.map +1 -1
- package/dist/environment.d.ts +6 -0
- package/dist/environment.d.ts.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +745 -60
- package/dist/index.js.map +19 -12
- package/dist/inspector.d.ts +24 -0
- package/dist/inspector.d.ts.map +1 -0
- package/dist/measuringTape.d.ts +76 -0
- package/dist/measuringTape.d.ts.map +1 -0
- package/dist/mount.d.ts.map +1 -1
- package/dist/pivotControls.d.ts +106 -0
- package/dist/pivotControls.d.ts.map +1 -0
- package/dist/transformGizmo.d.ts +158 -0
- package/dist/transformGizmo.d.ts.map +1 -0
- package/dist/view.d.ts +23 -0
- package/dist/view.d.ts.map +1 -1
- package/dist/viewportGizmo.d.ts +146 -0
- package/dist/viewportGizmo.d.ts.map +1 -0
- package/package.json +8 -8
- package/src/assetRegistry.ts +218 -0
- package/src/assets.ts +96 -39
- package/src/boxSelect.ts +158 -0
- package/src/dom/canvas.ts +12 -0
- package/src/dom/pointer.ts +14 -1
- package/src/dom/webgl.ts +15 -0
- package/src/dom/webgpu.ts +15 -0
- package/src/element.ts +6 -0
- package/src/environment.ts +6 -1
- package/src/index.ts +10 -0
- package/src/inspector.ts +112 -0
- package/src/measuringTape.ts +124 -0
- package/src/mount.ts +24 -1
- package/src/pivotControls.ts +118 -0
- package/src/transformGizmo.ts +131 -0
- package/src/view.ts +28 -0
- 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.
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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.
|
|
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
|
|
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
|
|
2015
|
+
var nothing2 = [];
|
|
1687
2016
|
var routedWhileOpen = (latch, route) => (value) => {
|
|
1688
2017
|
if (!latch.isOpen())
|
|
1689
|
-
return
|
|
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
|
|
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
|
|
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 =
|
|
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
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
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=
|
|
2725
|
+
//# debugId=91E3923C3006D06864756E2164756E21
|
|
2041
2726
|
//# sourceMappingURL=index.js.map
|