@opsydyn/effect-three 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 +56 -0
- package/README.md +15 -1
- package/dist/{index-8cf8t6by.js → index-re3rrfwd.js} +2935 -104
- package/dist/index-re3rrfwd.js.map +56 -0
- package/dist/index-ttwy0znv.js +145 -0
- package/dist/index-ttwy0znv.js.map +12 -0
- package/dist/index.js +557 -147
- package/dist/index.js.map +8 -6
- package/dist/kernel/bodies.d.ts +20 -1
- package/dist/kernel/bodies.d.ts.map +1 -1
- package/dist/kernel/boxSelect.d.ts +22 -0
- package/dist/kernel/boxSelect.d.ts.map +1 -0
- package/dist/kernel/build.d.ts +165 -7
- package/dist/kernel/build.d.ts.map +1 -1
- package/dist/kernel/cameraShake.d.ts.map +1 -1
- package/dist/kernel/describeScene.d.ts +50 -0
- package/dist/kernel/describeScene.d.ts.map +1 -0
- package/dist/kernel/description.d.ts +223 -1
- package/dist/kernel/description.d.ts.map +1 -1
- package/dist/kernel/diff.d.ts +15 -0
- package/dist/kernel/diff.d.ts.map +1 -1
- package/dist/kernel/equality.d.ts +11 -1
- package/dist/kernel/equality.d.ts.map +1 -1
- package/dist/kernel/gizmo.d.ts +69 -0
- package/dist/kernel/gizmo.d.ts.map +1 -0
- package/dist/kernel/history.d.ts +61 -0
- package/dist/kernel/history.d.ts.map +1 -0
- package/dist/kernel/index.d.ts +19 -6
- package/dist/kernel/index.d.ts.map +1 -1
- package/dist/kernel/index.js +124 -3
- package/dist/kernel/index.js.map +1 -1
- package/dist/kernel/inspect.d.ts +85 -0
- package/dist/kernel/inspect.d.ts.map +1 -0
- package/dist/kernel/lineGeometry.d.ts +25 -0
- package/dist/kernel/lineGeometry.d.ts.map +1 -0
- package/dist/kernel/lockstep.d.ts +114 -0
- package/dist/kernel/lockstep.d.ts.map +1 -0
- package/dist/kernel/loop.d.ts.map +1 -1
- package/dist/kernel/materials.d.ts.map +1 -1
- package/dist/kernel/paintOrder.d.ts +53 -0
- package/dist/kernel/paintOrder.d.ts.map +1 -0
- package/dist/kernel/physics.d.ts +39 -0
- package/dist/kernel/physics.d.ts.map +1 -1
- package/dist/kernel/pivot.d.ts +54 -0
- package/dist/kernel/pivot.d.ts.map +1 -0
- package/dist/kernel/pointBuffers.d.ts +17 -0
- package/dist/kernel/pointBuffers.d.ts.map +1 -0
- package/dist/kernel/pointer.d.ts +31 -1
- package/dist/kernel/pointer.d.ts.map +1 -1
- package/dist/kernel/preview.d.ts +32 -0
- package/dist/kernel/preview.d.ts.map +1 -0
- package/dist/kernel/renderKit.d.ts +21 -1
- package/dist/kernel/renderKit.d.ts.map +1 -1
- package/dist/kernel/renderer.d.ts +6 -0
- package/dist/kernel/renderer.d.ts.map +1 -1
- package/dist/kernel/sceneChanges.d.ts +87 -0
- package/dist/kernel/sceneChanges.d.ts.map +1 -0
- package/dist/kernel/sceneGraph.d.ts +9 -1
- package/dist/kernel/sceneGraph.d.ts.map +1 -1
- package/dist/kernel/sceneIndex.d.ts +5 -0
- package/dist/kernel/sceneIndex.d.ts.map +1 -1
- package/dist/kernel/seeded.d.ts +9 -0
- package/dist/kernel/seeded.d.ts.map +1 -0
- package/dist/kernel/shots.d.ts +26 -0
- package/dist/kernel/shots.d.ts.map +1 -0
- package/dist/kernel/tape.d.ts +38 -0
- package/dist/kernel/tape.d.ts.map +1 -0
- package/dist/kernel/timeline.d.ts +60 -0
- package/dist/kernel/timeline.d.ts.map +1 -0
- package/dist/kernel/trail.d.ts +31 -0
- package/dist/kernel/trail.d.ts.map +1 -0
- package/dist/kernel/viewportGizmo.d.ts +25 -0
- package/dist/kernel/viewportGizmo.d.ts.map +1 -0
- package/dist/runtime/Inspector.d.ts +20 -0
- package/dist/runtime/Inspector.d.ts.map +1 -0
- package/dist/runtime/SceneFile.d.ts +462 -0
- package/dist/runtime/SceneFile.d.ts.map +1 -0
- package/dist/runtime/SceneSchema.d.ts +404 -0
- package/dist/runtime/SceneSchema.d.ts.map +1 -1
- package/dist/runtime/errors.d.ts +9 -0
- package/dist/runtime/errors.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +3 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/webgl/index.d.ts.map +1 -1
- package/dist/webgl/index.js +228 -3
- package/dist/webgl/index.js.map +6 -4
- package/dist/webgl/line.d.ts +4 -0
- package/dist/webgl/line.d.ts.map +1 -0
- package/dist/webgl/points.d.ts +4 -0
- package/dist/webgl/points.d.ts.map +1 -0
- package/dist/webgpu/index.d.ts.map +1 -1
- package/dist/webgpu/index.js +206 -26
- package/dist/webgpu/index.js.map +6 -4
- package/dist/webgpu/line.d.ts +4 -0
- package/dist/webgpu/line.d.ts.map +1 -0
- package/dist/webgpu/points.d.ts +4 -0
- package/dist/webgpu/points.d.ts.map +1 -0
- package/package.json +4 -2
- package/src/kernel/bodies.ts +299 -17
- package/src/kernel/boxSelect.ts +73 -0
- package/src/kernel/build.ts +374 -1
- package/src/kernel/cameraShake.ts +3 -13
- package/src/kernel/describeScene.ts +224 -0
- package/src/kernel/description.ts +243 -0
- package/src/kernel/diff.ts +39 -0
- package/src/kernel/equality.ts +123 -0
- package/src/kernel/gizmo.ts +478 -0
- package/src/kernel/history.ts +118 -0
- package/src/kernel/index.ts +110 -1
- package/src/kernel/inspect.ts +214 -0
- package/src/kernel/lineGeometry.ts +75 -0
- package/src/kernel/lockstep.ts +237 -0
- package/src/kernel/loop.ts +7 -0
- package/src/kernel/materials.ts +3 -0
- package/src/kernel/paintOrder.ts +274 -0
- package/src/kernel/physics.ts +86 -1
- package/src/kernel/pivot.ts +418 -0
- package/src/kernel/pointBuffers.ts +115 -0
- package/src/kernel/pointer.ts +98 -17
- package/src/kernel/preview.ts +467 -0
- package/src/kernel/renderKit.ts +23 -1
- package/src/kernel/renderer.ts +6 -0
- package/src/kernel/sceneChanges.ts +265 -0
- package/src/kernel/sceneGraph.ts +354 -11
- package/src/kernel/sceneIndex.ts +8 -0
- package/src/kernel/seeded.ts +18 -0
- package/src/kernel/shots.ts +167 -0
- package/src/kernel/tape.ts +124 -0
- package/src/kernel/timeline.ts +93 -0
- package/src/kernel/trail.ts +170 -0
- package/src/kernel/viewportGizmo.ts +194 -0
- package/src/runtime/Inspector.ts +43 -0
- package/src/runtime/SceneFile.ts +46 -0
- package/src/runtime/SceneSchema.ts +319 -0
- package/src/runtime/errors.ts +6 -0
- package/src/runtime/index.ts +3 -1
- package/src/webgl/index.ts +4 -0
- package/src/webgl/line.ts +66 -0
- package/src/webgl/points.ts +205 -0
- package/src/webgpu/index.ts +4 -0
- package/src/webgpu/line.ts +67 -0
- package/src/webgpu/points.ts +193 -0
- package/dist/index-8cf8t6by.js.map +0 -41
|
@@ -1,3 +1,72 @@
|
|
|
1
|
+
import {
|
|
2
|
+
seededRandom,
|
|
3
|
+
edgePoints,
|
|
4
|
+
edgeLine,
|
|
5
|
+
animatedLook
|
|
6
|
+
} from "./index-ttwy0znv.js";
|
|
7
|
+
var __defProp = Object.defineProperty;
|
|
8
|
+
var __returnValue = (v) => v;
|
|
9
|
+
function __exportSetter(name, newValue) {
|
|
10
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
11
|
+
}
|
|
12
|
+
var __export = (target, all) => {
|
|
13
|
+
for (var name in all)
|
|
14
|
+
__defProp(target, name, {
|
|
15
|
+
get: all[name],
|
|
16
|
+
enumerable: true,
|
|
17
|
+
configurable: true,
|
|
18
|
+
set: __exportSetter.bind(all, name)
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// src/kernel/history.ts
|
|
23
|
+
var exports_history = {};
|
|
24
|
+
__export(exports_history, {
|
|
25
|
+
branches: () => branches,
|
|
26
|
+
canRedo: () => canRedo,
|
|
27
|
+
canUndo: () => canUndo,
|
|
28
|
+
chooseBranch: () => chooseBranch,
|
|
29
|
+
depth: () => depth,
|
|
30
|
+
jumpTo: () => jumpTo,
|
|
31
|
+
make: () => make,
|
|
32
|
+
pathTo: () => pathTo,
|
|
33
|
+
present: () => present,
|
|
34
|
+
presentEntry: () => presentEntry,
|
|
35
|
+
record: () => record,
|
|
36
|
+
redo: () => redo,
|
|
37
|
+
undo: () => undo
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// src/kernel/lockstep.ts
|
|
41
|
+
var exports_lockstep = {};
|
|
42
|
+
__export(exports_lockstep, {
|
|
43
|
+
admit: () => admit,
|
|
44
|
+
advance: () => advance,
|
|
45
|
+
join: () => join,
|
|
46
|
+
leaderAt: () => leaderAt,
|
|
47
|
+
leave: () => leave,
|
|
48
|
+
make: () => make2,
|
|
49
|
+
membersAt: () => membersAt,
|
|
50
|
+
receive: () => receive,
|
|
51
|
+
remove: () => remove,
|
|
52
|
+
send: () => send,
|
|
53
|
+
submit: () => submit,
|
|
54
|
+
waitingOn: () => waitingOn,
|
|
55
|
+
welcomeDue: () => welcomeDue
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// src/kernel/timeline.ts
|
|
59
|
+
var exports_timeline = {};
|
|
60
|
+
__export(exports_timeline, {
|
|
61
|
+
due: () => due,
|
|
62
|
+
extend: () => extend,
|
|
63
|
+
make: () => make3,
|
|
64
|
+
reach: () => reach,
|
|
65
|
+
restart: () => restart,
|
|
66
|
+
schedule: () => schedule,
|
|
67
|
+
until: () => until
|
|
68
|
+
});
|
|
69
|
+
|
|
1
70
|
// src/kernel/description.ts
|
|
2
71
|
var handJoints2 = [
|
|
3
72
|
"wrist",
|
|
@@ -125,6 +194,8 @@ var applyShaded = (material, description, mapChanged = false) => {
|
|
|
125
194
|
};
|
|
126
195
|
var applyBasic = (material, description, textures) => {
|
|
127
196
|
material.color.setHex(description.color);
|
|
197
|
+
material.depthTest = description.depthTest;
|
|
198
|
+
material.depthWrite = description.depthTest;
|
|
128
199
|
const mapChanged = applyMap(material, description.map, textures);
|
|
129
200
|
if (applySurface(material, description) || mapChanged)
|
|
130
201
|
material.needsUpdate = true;
|
|
@@ -489,8 +560,25 @@ var jointsEqual = (a, b) => {
|
|
|
489
560
|
var labelTypeEquals = (a, b) => a.text === b.text && a.font === b.font && Object.is(a.fontSize, b.fontSize) && a.color === b.color && Object.is(a.fillOpacity, b.fillOpacity) && Object.is(a.anchorX, b.anchorX) && Object.is(a.anchorY, b.anchorY) && Object.is(a.maxWidth, b.maxWidth) && Object.is(a.lineHeight, b.lineHeight) && Object.is(a.letterSpacing, b.letterSpacing) && a.textAlign === b.textAlign && Object.is(a.outlineWidth, b.outlineWidth) && a.outlineColor === b.outlineColor && Object.is(a.outlineOpacity, b.outlineOpacity) && Object.is(a.outlineBlur, b.outlineBlur) && Object.is(a.curveRadius, b.curveRadius) && a.colorRanges.length === b.colorRanges.length && a.colorRanges.every((range, i) => colorRangeEquals(range, b.colorRanges[i]));
|
|
490
561
|
var colorRangeEquals = (a, b) => b !== undefined && a.start === b.start && a.color === b.color;
|
|
491
562
|
var labelMaterialEquals = (a, b) => a === b || a !== null && b !== null && materialRefEquals2(a, b);
|
|
563
|
+
var pointLookEquals = (a, b) => {
|
|
564
|
+
if (a === b)
|
|
565
|
+
return true;
|
|
566
|
+
switch (a._tag) {
|
|
567
|
+
case "Dots":
|
|
568
|
+
return b._tag === "Dots" && a.positions.length === b.positions.length && a.positions.every((point, index) => vec3Equals2(point, b.positions[index] ?? point)) && numbersEqual(a.colors, b.colors) && numbersEqual(a.sizes, b.sizes) && Object.is(a.color, b.color) && Object.is(a.size, b.size) && a.sizeAttenuation === b.sizeAttenuation && a.round === b.round && Object.is(a.opacity, b.opacity) && a.transparent === b.transparent;
|
|
569
|
+
case "Sparkles":
|
|
570
|
+
return b._tag === "Sparkles" && a.count === b.count && Object.is(a.speed, b.speed) && Object.is(a.opacity, b.opacity) && vec3Equals2(a.scale, b.scale) && Object.is(a.size, b.size) && Object.is(a.color, b.color) && vec3Equals2(a.noise, b.noise) && Object.is(a.seed, b.seed);
|
|
571
|
+
case "Stars":
|
|
572
|
+
return b._tag === "Stars" && Object.is(a.radius, b.radius) && Object.is(a.depth, b.depth) && a.count === b.count && Object.is(a.factor, b.factor) && Object.is(a.saturation, b.saturation) && a.fade === b.fade && Object.is(a.speed, b.speed) && Object.is(a.seed, b.seed);
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
var trailEquals = (a, b) => a === b || a !== null && b !== null && Object.is(a.width, b.width) && Object.is(a.length, b.length) && Object.is(a.decay, b.decay) && a.local === b.local && Object.is(a.stride, b.stride) && Object.is(a.interval, b.interval) && Object.is(a.color, b.color) && a.taper === b.taper && a.fade === b.fade;
|
|
576
|
+
var edgesEquals = (a, b) => a === b || a !== null && b !== null && Object.is(a.threshold, b.threshold) && Object.is(a.color, b.color) && Object.is(a.width, b.width) && a.worldUnits === b.worldUnits && a.dashed === b.dashed && Object.is(a.dashSize, b.dashSize) && Object.is(a.gapSize, b.gapSize) && Object.is(a.opacity, b.opacity) && a.transparent === b.transparent;
|
|
577
|
+
var lineLookEquals = (a, b) => a.segments === b.segments && Object.is(a.color, b.color) && Object.is(a.width, b.width) && a.worldUnits === b.worldUnits && a.dashed === b.dashed && Object.is(a.dashSize, b.dashSize) && Object.is(a.gapSize, b.gapSize) && Object.is(a.dashScale, b.dashScale) && Object.is(a.dashOffset, b.dashOffset) && Object.is(a.opacity, b.opacity) && a.transparent === b.transparent && (a.points === b.points || a.points.length === b.points.length && a.points.every((point, index) => vec3Equals2(point, b.points[index] ?? point))) && (a.vertexColors === b.vertexColors || a.vertexColors !== null && b.vertexColors !== null && a.vertexColors.length === b.vertexColors.length && a.vertexColors.every((color, index) => Object.is(color, b.vertexColors?.[index])));
|
|
492
578
|
var shaderGridLookEquals = (a, b) => Object.is(a.size[0], b.size[0]) && Object.is(a.size[1], b.size[1]) && Object.is(a.cellSize, b.cellSize) && Object.is(a.cellThickness, b.cellThickness) && a.cellColor === b.cellColor && Object.is(a.sectionSize, b.sectionSize) && Object.is(a.sectionThickness, b.sectionThickness) && a.sectionColor === b.sectionColor && a.infinite === b.infinite && a.followCamera === b.followCamera && Object.is(a.fadeDistance, b.fadeDistance) && Object.is(a.fadeStrength, b.fadeStrength) && Object.is(a.fadeFrom, b.fadeFrom) && a.side === b.side;
|
|
493
|
-
var
|
|
579
|
+
var assetEquals = (a, b) => b !== undefined && a.kind === b.kind && a.id === b.id && a.url === b.url && a.levels.length === b.levels.length && a.levels.every((level, i) => level === b.levels[i]);
|
|
580
|
+
var assetsEqual2 = (a, b) => a === b || a.length === b.length && a.every((asset, i) => assetEquals(asset, b[i]));
|
|
581
|
+
var physicsEquals2 = (a, b) => a === b || a !== null && b !== null && vec3Equals2(a.gravity, b.gravity) && a.paused === b.paused && Object.is(a.timeStep, b.timeStep) && a.interpolate === b.interpolate && a.until === b.until && a.run === b.run && a.snapshotAt === b.snapshotAt && a.keep === b.keep && (a.from === b.from || a.from !== null && b.from !== null && a.from.step === b.from.step && a.from.snapshot === b.from.snapshot) && a.debug === b.debug && jointsEqual(a.joints, b.joints);
|
|
494
582
|
var xrAnchorEquals = (a, b) => b !== undefined && a.id === b.id && vec3Equals2(a.position, b.position) && vec3Equals2(a.rotation, b.rotation);
|
|
495
583
|
var xrEquals2 = (a, b) => a === b || a !== null && b !== null && vec3Equals2(a.origin, b.origin) && Object.is(a.heading, b.heading) && a.referenceSpace === b.referenceSpace && Object.is(a.framebufferScale, b.framebufferScale) && a.hitTest === b.hitTest && a.showInputs === b.showInputs && (a.glide === b.glide || a.glide !== null && b.glide !== null && Object.is(a.glide.speed, b.glide.speed) && a.glide.turn === b.glide.turn && Object.is(a.glide.turnSpeed, b.glide.turnSpeed) && Object.is(a.glide.snapDegrees, b.glide.snapDegrees)) && a.planes === b.planes && a.meshes === b.meshes && a.domOverlay === b.domOverlay && a.anchors.length === b.anchors.length && a.anchors.every((anchor, i) => xrAnchorEquals(anchor, b.anchors[i]));
|
|
496
584
|
var xrSpaceEquals = (a, b) => {
|
|
@@ -658,6 +746,7 @@ var applyTween2 = (object, tween, elapsedSeconds) => {
|
|
|
658
746
|
return false;
|
|
659
747
|
};
|
|
660
748
|
// src/kernel/build.ts
|
|
749
|
+
import { CatmullRomCurve3, Color as Color2, CubicBezierCurve3, QuadraticBezierCurve3, Vector3 as Vector33 } from "three";
|
|
661
750
|
var origin = [0, 0, 0];
|
|
662
751
|
var unitScale = [1, 1, 1];
|
|
663
752
|
var noRotation = { _tag: "Fixed", euler: origin };
|
|
@@ -774,7 +863,8 @@ var basic2 = (options = {}) => ({
|
|
|
774
863
|
opacity: options.opacity ?? 1,
|
|
775
864
|
transparent: options.transparent ?? false,
|
|
776
865
|
side: options.side ?? "front",
|
|
777
|
-
wireframe: options.wireframe ?? false
|
|
866
|
+
wireframe: options.wireframe ?? false,
|
|
867
|
+
depthTest: options.depthTest ?? true
|
|
778
868
|
});
|
|
779
869
|
var lambert2 = (options = {}) => ({
|
|
780
870
|
_tag: "Lambert",
|
|
@@ -888,9 +978,105 @@ var group2 = (options) => ({
|
|
|
888
978
|
children: options.children ?? [],
|
|
889
979
|
body: options.body ?? null,
|
|
890
980
|
follow: options.follow ?? null,
|
|
891
|
-
detail: options.detail ?? null
|
|
981
|
+
detail: options.detail ?? null,
|
|
982
|
+
trail: options.trail ?? null
|
|
892
983
|
});
|
|
893
984
|
var detailed2 = (options) => ({ distances: options.distances, hysteresis: options.hysteresis ?? 0 });
|
|
985
|
+
var line2 = (options) => ({
|
|
986
|
+
_tag: "Line",
|
|
987
|
+
key: options.key,
|
|
988
|
+
position: options.position ?? origin,
|
|
989
|
+
rotation: options.rotation ?? noRotation,
|
|
990
|
+
scale: options.scale ?? unitScale,
|
|
991
|
+
transition: options.transition ?? instantTransition,
|
|
992
|
+
behaviour: options.behaviour ?? null,
|
|
993
|
+
interactive: options.interactive ?? false,
|
|
994
|
+
points: options.points,
|
|
995
|
+
segments: options.segments ?? false,
|
|
996
|
+
color: options.color ?? 16777215,
|
|
997
|
+
vertexColors: options.vertexColors ?? null,
|
|
998
|
+
width: options.width ?? 1,
|
|
999
|
+
worldUnits: options.worldUnits ?? false,
|
|
1000
|
+
dashed: options.dashed ?? false,
|
|
1001
|
+
dashSize: options.dashSize ?? 1,
|
|
1002
|
+
gapSize: options.gapSize ?? 1,
|
|
1003
|
+
dashScale: options.dashScale ?? 1,
|
|
1004
|
+
dashOffset: options.dashOffset ?? 0,
|
|
1005
|
+
opacity: options.opacity ?? 1,
|
|
1006
|
+
transparent: options.transparent ?? false
|
|
1007
|
+
});
|
|
1008
|
+
var asVector = (point) => new Vector33(point[0], point[1], point[2]);
|
|
1009
|
+
var asVec3 = (point) => [point.x, point.y, point.z];
|
|
1010
|
+
var placed = (options, look) => ({
|
|
1011
|
+
_tag: "Points",
|
|
1012
|
+
key: options.key,
|
|
1013
|
+
position: options.position ?? origin,
|
|
1014
|
+
rotation: options.rotation ?? noRotation,
|
|
1015
|
+
scale: options.scale ?? unitScale,
|
|
1016
|
+
transition: options.transition ?? instantTransition,
|
|
1017
|
+
behaviour: options.behaviour ?? null,
|
|
1018
|
+
look
|
|
1019
|
+
});
|
|
1020
|
+
var points2 = (options) => placed(options, {
|
|
1021
|
+
_tag: "Dots",
|
|
1022
|
+
positions: options.positions,
|
|
1023
|
+
colors: options.colors ?? null,
|
|
1024
|
+
sizes: options.sizes ?? null,
|
|
1025
|
+
color: options.color ?? 16777215,
|
|
1026
|
+
size: options.size ?? 1,
|
|
1027
|
+
sizeAttenuation: options.sizeAttenuation ?? true,
|
|
1028
|
+
round: options.round ?? true,
|
|
1029
|
+
opacity: options.opacity ?? 1,
|
|
1030
|
+
transparent: options.transparent ?? false
|
|
1031
|
+
});
|
|
1032
|
+
var sparkles2 = (options) => {
|
|
1033
|
+
const spread = options.spread ?? 1;
|
|
1034
|
+
const noise = options.noise ?? 1;
|
|
1035
|
+
return placed(options, {
|
|
1036
|
+
_tag: "Sparkles",
|
|
1037
|
+
count: options.count ?? 100,
|
|
1038
|
+
speed: options.speed ?? 1,
|
|
1039
|
+
opacity: options.opacity ?? 1,
|
|
1040
|
+
scale: typeof spread === "number" ? [spread, spread, spread] : spread,
|
|
1041
|
+
size: options.size ?? null,
|
|
1042
|
+
color: options.color ?? 16777215,
|
|
1043
|
+
noise: typeof noise === "number" ? [noise, noise, noise] : noise,
|
|
1044
|
+
seed: options.seed ?? 1
|
|
1045
|
+
});
|
|
1046
|
+
};
|
|
1047
|
+
var stars2 = (options) => placed(options, {
|
|
1048
|
+
_tag: "Stars",
|
|
1049
|
+
radius: options.radius ?? 100,
|
|
1050
|
+
depth: options.depth ?? 50,
|
|
1051
|
+
count: options.count ?? 5000,
|
|
1052
|
+
factor: options.factor ?? 4,
|
|
1053
|
+
saturation: options.saturation ?? 0,
|
|
1054
|
+
fade: options.fade ?? false,
|
|
1055
|
+
speed: options.speed ?? 1,
|
|
1056
|
+
seed: options.seed ?? 1
|
|
1057
|
+
});
|
|
1058
|
+
var catmullRomPoints2 = (points, options = {}) => new CatmullRomCurve3(points.map(asVector), options.closed ?? false, options.curveType ?? "centripetal", options.tension ?? 0.5).getPoints(options.segments ?? 20).map(asVec3);
|
|
1059
|
+
var catmullRomPointAt2 = (points, t, options = {}) => asVec3(new CatmullRomCurve3(points.map(asVector), options.closed ?? false, options.curveType ?? "centripetal", options.tension ?? 0.5).getPoint(Math.min(1, Math.max(0, t))));
|
|
1060
|
+
var catmullRomColors2 = (colors, options = {}) => {
|
|
1061
|
+
const segments = options.segments ?? 20;
|
|
1062
|
+
if (colors.length < 2 || colors.length === segments + 1)
|
|
1063
|
+
return colors;
|
|
1064
|
+
const stops = colors.map((color) => new Color2(color));
|
|
1065
|
+
const first = stops[0];
|
|
1066
|
+
if (options.closed === true && first !== undefined)
|
|
1067
|
+
stops.push(first.clone());
|
|
1068
|
+
const divisions = segments / (stops.length - 1);
|
|
1069
|
+
const at = (index) => (stops[Math.floor(index / divisions)] ?? new Color2).clone().lerp(stops[Math.floor(index / divisions) + 1] ?? new Color2, index % divisions / divisions).getHex();
|
|
1070
|
+
const blended = Array.from({ length: segments - 1 }, (_, step) => at(step + 1));
|
|
1071
|
+
return [colors[0] ?? 0, ...blended, stops.at(-1)?.getHex() ?? 0];
|
|
1072
|
+
};
|
|
1073
|
+
var cubicBezierPoints2 = (options) => new CubicBezierCurve3(asVector(options.start), asVector(options.midA), asVector(options.midB), asVector(options.end)).getPoints(options.segments ?? 20).map(asVec3);
|
|
1074
|
+
var quadraticBezierPoints2 = (options) => {
|
|
1075
|
+
const [, startY] = options.start;
|
|
1076
|
+
const [endX, , endZ] = options.end;
|
|
1077
|
+
const mid = options.mid ?? [endX, startY, endZ];
|
|
1078
|
+
return new QuadraticBezierCurve3(asVector(options.start), asVector(mid), asVector(options.end)).getPoints(options.segments ?? 20).map(asVec3);
|
|
1079
|
+
};
|
|
894
1080
|
var headSpace2 = () => ({ _tag: "Head" });
|
|
895
1081
|
var jointSpace2 = (hand, joint) => ({
|
|
896
1082
|
_tag: "Joint",
|
|
@@ -925,7 +1111,31 @@ var mesh2 = (options) => ({
|
|
|
925
1111
|
interactive: options.interactive ?? false,
|
|
926
1112
|
castShadow: options.castShadow ?? false,
|
|
927
1113
|
receiveShadow: options.receiveShadow ?? false,
|
|
928
|
-
body: options.body ?? null
|
|
1114
|
+
body: options.body ?? null,
|
|
1115
|
+
edges: options.edges ?? null,
|
|
1116
|
+
trail: options.trail ?? null
|
|
1117
|
+
});
|
|
1118
|
+
var trail2 = (options = {}) => ({
|
|
1119
|
+
width: options.width ?? 0.2,
|
|
1120
|
+
length: options.length ?? 1,
|
|
1121
|
+
decay: options.decay ?? 1,
|
|
1122
|
+
local: options.local ?? false,
|
|
1123
|
+
stride: options.stride ?? 0,
|
|
1124
|
+
interval: options.interval ?? 1,
|
|
1125
|
+
color: options.color ?? 16738740,
|
|
1126
|
+
taper: options.taper ?? "none",
|
|
1127
|
+
fade: options.fade ?? false
|
|
1128
|
+
});
|
|
1129
|
+
var edges2 = (options = {}) => ({
|
|
1130
|
+
threshold: options.threshold ?? 15,
|
|
1131
|
+
color: options.color ?? 16777215,
|
|
1132
|
+
width: options.width ?? 1,
|
|
1133
|
+
worldUnits: options.worldUnits ?? false,
|
|
1134
|
+
dashed: options.dashed ?? false,
|
|
1135
|
+
dashSize: options.dashSize ?? 1,
|
|
1136
|
+
gapSize: options.gapSize ?? 1,
|
|
1137
|
+
opacity: options.opacity ?? 1,
|
|
1138
|
+
transparent: options.transparent ?? false
|
|
929
1139
|
});
|
|
930
1140
|
var body2 = (options = {}) => ({
|
|
931
1141
|
type: options.type ?? "dynamic",
|
|
@@ -979,6 +1189,11 @@ var physics2 = (options = {}) => ({
|
|
|
979
1189
|
paused: options.paused ?? false,
|
|
980
1190
|
timeStep: options.timeStep ?? 1 / 60,
|
|
981
1191
|
interpolate: options.interpolate ?? true,
|
|
1192
|
+
until: options.until ?? null,
|
|
1193
|
+
run: options.run ?? 0,
|
|
1194
|
+
snapshotAt: options.snapshotAt ?? null,
|
|
1195
|
+
from: options.from ?? null,
|
|
1196
|
+
keep: options.keep ?? 0,
|
|
982
1197
|
debug: options.debug ?? false,
|
|
983
1198
|
joints: options.joints ?? noJoints
|
|
984
1199
|
});
|
|
@@ -1280,6 +1495,13 @@ var contactShadows2 = (options = {}) => {
|
|
|
1280
1495
|
};
|
|
1281
1496
|
var noOverlays = [];
|
|
1282
1497
|
var noMeasures = [];
|
|
1498
|
+
var noAssets = [];
|
|
1499
|
+
var noLevels = [];
|
|
1500
|
+
var assetOf = (kind) => ({ id, url, levels }) => ({ kind, id, url, levels: levels ?? noLevels });
|
|
1501
|
+
var modelAsset2 = assetOf("model");
|
|
1502
|
+
var textureAsset2 = assetOf("texture");
|
|
1503
|
+
var environmentAsset2 = assetOf("environment");
|
|
1504
|
+
var fontAsset2 = assetOf("font");
|
|
1283
1505
|
var defaultZIndexRange = [16777271, 0];
|
|
1284
1506
|
var overlay2 = (options) => ({
|
|
1285
1507
|
key: options.key,
|
|
@@ -1291,11 +1513,17 @@ var overlay2 = (options) => ({
|
|
|
1291
1513
|
zIndexRange: options.zIndexRange ?? defaultZIndexRange,
|
|
1292
1514
|
view: options.view ?? null
|
|
1293
1515
|
});
|
|
1516
|
+
var hud2 = (options) => ({
|
|
1517
|
+
alignment: options.alignment ?? "bottom-right",
|
|
1518
|
+
margin: options.margin ?? [80, 80],
|
|
1519
|
+
children: options.children ?? []
|
|
1520
|
+
});
|
|
1294
1521
|
var scene2 = (options) => ({
|
|
1295
1522
|
camera: options.camera ?? perspectiveCamera2(),
|
|
1296
1523
|
gestures: options.gestures ?? "page",
|
|
1297
1524
|
views: options.views ?? noViews,
|
|
1298
1525
|
renderTextures: options.renderTextures ?? noRenderTextures,
|
|
1526
|
+
hud: options.hud ?? null,
|
|
1299
1527
|
overlays: options.overlays ?? noOverlays,
|
|
1300
1528
|
environment: options.environment ?? null,
|
|
1301
1529
|
sky: options.sky ?? null,
|
|
@@ -1303,6 +1531,7 @@ var scene2 = (options) => ({
|
|
|
1303
1531
|
physics: options.physics ?? null,
|
|
1304
1532
|
xr: options.xr ?? null,
|
|
1305
1533
|
measure: options.measure ?? noMeasures,
|
|
1534
|
+
assets: options.assets ?? noAssets,
|
|
1306
1535
|
render: options.render ?? defaultRenderSettings,
|
|
1307
1536
|
resources: {
|
|
1308
1537
|
geometries: options.resources?.geometries ?? noResources.geometries,
|
|
@@ -1347,6 +1576,10 @@ var indexScene2 = (description, behaviours = new Set) => {
|
|
|
1347
1576
|
if (duplicateView !== undefined) {
|
|
1348
1577
|
return { _tag: "Invalid", error: { _tag: "DuplicateViewKey", key: duplicateView } };
|
|
1349
1578
|
}
|
|
1579
|
+
const duplicateAsset = firstDuplicateInstance(description.assets.map((asset) => ({ key: asset.id })));
|
|
1580
|
+
if (duplicateAsset !== undefined) {
|
|
1581
|
+
return { _tag: "Invalid", error: { _tag: "DuplicateAssetId", id: duplicateAsset } };
|
|
1582
|
+
}
|
|
1350
1583
|
const duplicateOverlay = firstDuplicateInstance(description.overlays);
|
|
1351
1584
|
if (duplicateOverlay !== undefined) {
|
|
1352
1585
|
return { _tag: "Invalid", error: { _tag: "DuplicateOverlayKey", key: duplicateOverlay } };
|
|
@@ -1480,6 +1713,8 @@ var changedFields2 = (prev, next) => {
|
|
|
1480
1713
|
fields.push("follow");
|
|
1481
1714
|
if (!detailEquals(prev.detail, next.detail))
|
|
1482
1715
|
fields.push("detail");
|
|
1716
|
+
if (!trailEquals(prev.trail, next.trail))
|
|
1717
|
+
fields.push("trail");
|
|
1483
1718
|
return fields;
|
|
1484
1719
|
}
|
|
1485
1720
|
case "Mesh": {
|
|
@@ -1507,6 +1742,10 @@ var changedFields2 = (prev, next) => {
|
|
|
1507
1742
|
fields.push("receiveShadow");
|
|
1508
1743
|
if (!bodyEquals2(prev.body, next.body))
|
|
1509
1744
|
fields.push("body");
|
|
1745
|
+
if (!edgesEquals(prev.edges, next.edges))
|
|
1746
|
+
fields.push("edges");
|
|
1747
|
+
if (!trailEquals(prev.trail, next.trail))
|
|
1748
|
+
fields.push("trail");
|
|
1510
1749
|
return fields;
|
|
1511
1750
|
}
|
|
1512
1751
|
case "Instances": {
|
|
@@ -1662,6 +1901,42 @@ var changedFields2 = (prev, next) => {
|
|
|
1662
1901
|
fields.push("shadowBias");
|
|
1663
1902
|
return fields;
|
|
1664
1903
|
}
|
|
1904
|
+
case "Points": {
|
|
1905
|
+
if (prev._tag !== "Points")
|
|
1906
|
+
return;
|
|
1907
|
+
if (!behaviourEquals2(prev.behaviour, next.behaviour))
|
|
1908
|
+
fields.push("behaviour");
|
|
1909
|
+
if (!vec3Equals2(prev.position, next.position))
|
|
1910
|
+
fields.push("position");
|
|
1911
|
+
if (!rotationEquals2(prev.rotation, next.rotation))
|
|
1912
|
+
fields.push("rotation");
|
|
1913
|
+
if (!vec3Equals2(prev.scale, next.scale))
|
|
1914
|
+
fields.push("scale");
|
|
1915
|
+
if (!transitionEquals2(prev.transition, next.transition))
|
|
1916
|
+
fields.push("transition");
|
|
1917
|
+
if (!pointLookEquals(prev.look, next.look))
|
|
1918
|
+
fields.push("look");
|
|
1919
|
+
return fields;
|
|
1920
|
+
}
|
|
1921
|
+
case "Line": {
|
|
1922
|
+
if (prev._tag !== "Line")
|
|
1923
|
+
return;
|
|
1924
|
+
if (!behaviourEquals2(prev.behaviour, next.behaviour))
|
|
1925
|
+
fields.push("behaviour");
|
|
1926
|
+
if (!vec3Equals2(prev.position, next.position))
|
|
1927
|
+
fields.push("position");
|
|
1928
|
+
if (!rotationEquals2(prev.rotation, next.rotation))
|
|
1929
|
+
fields.push("rotation");
|
|
1930
|
+
if (!vec3Equals2(prev.scale, next.scale))
|
|
1931
|
+
fields.push("scale");
|
|
1932
|
+
if (!transitionEquals2(prev.transition, next.transition))
|
|
1933
|
+
fields.push("transition");
|
|
1934
|
+
if (prev.interactive !== next.interactive)
|
|
1935
|
+
fields.push("interactive");
|
|
1936
|
+
if (!lineLookEquals(prev, next))
|
|
1937
|
+
fields.push("line");
|
|
1938
|
+
return fields;
|
|
1939
|
+
}
|
|
1665
1940
|
case "ShaderGrid": {
|
|
1666
1941
|
if (prev._tag !== "ShaderGrid")
|
|
1667
1942
|
return;
|
|
@@ -2352,7 +2627,7 @@ import {
|
|
|
2352
2627
|
Plane,
|
|
2353
2628
|
Ray,
|
|
2354
2629
|
Spherical,
|
|
2355
|
-
Vector3 as
|
|
2630
|
+
Vector3 as Vector34
|
|
2356
2631
|
} from "three";
|
|
2357
2632
|
var defaultOrbit2 = {
|
|
2358
2633
|
enableRotate: true,
|
|
@@ -2379,14 +2654,14 @@ var orbitOptions2 = (options = {}) => ({
|
|
|
2379
2654
|
...options
|
|
2380
2655
|
});
|
|
2381
2656
|
var twoPi = 2 * Math.PI;
|
|
2382
|
-
var offset = new
|
|
2657
|
+
var offset = new Vector34;
|
|
2383
2658
|
var spherical = new Spherical;
|
|
2384
|
-
var target = new
|
|
2385
|
-
var position2 = new
|
|
2386
|
-
var axis = new
|
|
2387
|
-
var panOffset = new
|
|
2659
|
+
var target = new Vector34;
|
|
2660
|
+
var position2 = new Vector34;
|
|
2661
|
+
var axis = new Vector34;
|
|
2662
|
+
var panOffset = new Vector34;
|
|
2388
2663
|
var basis = new Matrix42;
|
|
2389
|
-
var worldUp = new
|
|
2664
|
+
var worldUp = new Vector34(0, 1, 0);
|
|
2390
2665
|
var toVec3 = (vector) => [vector.x, vector.y, vector.z];
|
|
2391
2666
|
var clampAzimuth = (theta, options) => {
|
|
2392
2667
|
let min = options.minAzimuthAngle;
|
|
@@ -2464,9 +2739,9 @@ var panCamera2 = (camera, deltaX, deltaY, area, options = defaultOrbit2) => {
|
|
|
2464
2739
|
return place(camera, options, zoomOf(camera, options));
|
|
2465
2740
|
};
|
|
2466
2741
|
var tiltLimit = Math.cos(70 * MathUtils.DEG2RAD);
|
|
2467
|
-
var pointer = new
|
|
2468
|
-
var before = new
|
|
2469
|
-
var forward = new
|
|
2742
|
+
var pointer = new Vector34;
|
|
2743
|
+
var before = new Vector34;
|
|
2744
|
+
var forward = new Vector34;
|
|
2470
2745
|
var groundRay = new Ray;
|
|
2471
2746
|
var ground = new Plane;
|
|
2472
2747
|
var hostCamera = (camera, cursor, zoom) => {
|
|
@@ -2568,7 +2843,7 @@ var orbitKey2 = (camera, key, modifiers, area, options = defaultOrbit2) => {
|
|
|
2568
2843
|
return rotating ? turned(-turn, 0) : panCamera2(camera, -step, 0, area, options);
|
|
2569
2844
|
}
|
|
2570
2845
|
};
|
|
2571
|
-
var corner = new
|
|
2846
|
+
var corner = new Vector34;
|
|
2572
2847
|
var view = new Matrix42;
|
|
2573
2848
|
var fitDistance = (camera, box, area, margin) => {
|
|
2574
2849
|
const largest = Math.max(box.max[0] - box.min[0], box.max[1] - box.min[1], box.max[2] - box.min[2]);
|
|
@@ -2621,12 +2896,12 @@ import {
|
|
|
2621
2896
|
PerspectiveCamera as PerspectiveCamera2,
|
|
2622
2897
|
Raycaster,
|
|
2623
2898
|
Vector2 as Vector22,
|
|
2624
|
-
Vector3 as
|
|
2899
|
+
Vector3 as Vector35
|
|
2625
2900
|
} from "three";
|
|
2626
|
-
var point = new
|
|
2627
|
-
var cameraPosition = new
|
|
2628
|
-
var direction = new
|
|
2629
|
-
var toPoint = new
|
|
2901
|
+
var point = new Vector35;
|
|
2902
|
+
var cameraPosition = new Vector35;
|
|
2903
|
+
var direction = new Vector35;
|
|
2904
|
+
var toPoint = new Vector35;
|
|
2630
2905
|
var ndc = new Vector22;
|
|
2631
2906
|
var raycaster = new Raycaster;
|
|
2632
2907
|
var lensFor = (graph, overlay) => {
|
|
@@ -2701,7 +2976,7 @@ import {
|
|
|
2701
2976
|
Euler as Euler3,
|
|
2702
2977
|
Matrix4 as Matrix43,
|
|
2703
2978
|
Quaternion as Quaternion3,
|
|
2704
|
-
Vector3 as
|
|
2979
|
+
Vector3 as Vector36
|
|
2705
2980
|
} from "three";
|
|
2706
2981
|
var interactionBits2 = (groups) => {
|
|
2707
2982
|
const mask = (list) => list.reduce((bits, group) => bits | 1 << group, 0);
|
|
@@ -2710,8 +2985,40 @@ var interactionBits2 = (groups) => {
|
|
|
2710
2985
|
const filters = groups.filters === null ? 65535 : mask(groups.filters);
|
|
2711
2986
|
return (mask(groups.memberships) << 16 | filters) >>> 0;
|
|
2712
2987
|
};
|
|
2988
|
+
var run = (first, count) => Array.from({ length: count }, (_, i) => String.fromCharCode(first.charCodeAt(0) + i));
|
|
2989
|
+
var digits = [...run("A", 26), ...run("a", 26), ...run("0", 10), "+", "/"];
|
|
2990
|
+
var digitValues = new Map(digits.map((char, i) => [char, i]));
|
|
2991
|
+
var digit = (value) => digits[value] ?? "";
|
|
2992
|
+
var snapshotText2 = (bytes) => {
|
|
2993
|
+
const out = [];
|
|
2994
|
+
for (let at = 0;at < bytes.length; at += 3) {
|
|
2995
|
+
const a = bytes[at] ?? 0;
|
|
2996
|
+
const b = bytes[at + 1] ?? 0;
|
|
2997
|
+
const c = bytes[at + 2] ?? 0;
|
|
2998
|
+
const left = bytes.length - at;
|
|
2999
|
+
out.push(digit(a >> 2), digit((a & 3) << 4 | b >> 4), left > 1 ? digit((b & 15) << 2 | c >> 6) : "=", left > 2 ? digit(c & 63) : "=");
|
|
3000
|
+
}
|
|
3001
|
+
return out.join("");
|
|
3002
|
+
};
|
|
3003
|
+
var snapshotBytes2 = (text) => {
|
|
3004
|
+
const digits = text.replace(/=+$/, "");
|
|
3005
|
+
const bytes = new Uint8Array(Math.floor(digits.length * 3 / 4));
|
|
3006
|
+
let bits = 0;
|
|
3007
|
+
let held = 0;
|
|
3008
|
+
let at = 0;
|
|
3009
|
+
for (const char of digits) {
|
|
3010
|
+
bits = bits << 6 | (digitValues.get(char) ?? 0);
|
|
3011
|
+
held += 6;
|
|
3012
|
+
if (held >= 8) {
|
|
3013
|
+
held -= 8;
|
|
3014
|
+
bytes[at] = bits >> held & 255;
|
|
3015
|
+
at += 1;
|
|
3016
|
+
}
|
|
3017
|
+
}
|
|
3018
|
+
return bytes;
|
|
3019
|
+
};
|
|
2713
3020
|
var toVec32 = (vector) => [vector.x, vector.y, vector.z];
|
|
2714
|
-
var size = new
|
|
3021
|
+
var size = new Vector36;
|
|
2715
3022
|
var scaledPositions = (geometry, scale) => {
|
|
2716
3023
|
const positions = geometry.getAttribute("position");
|
|
2717
3024
|
const points = new Float32Array(positions.count * 3);
|
|
@@ -2730,7 +3037,7 @@ var triangles = (geometry) => {
|
|
|
2730
3037
|
};
|
|
2731
3038
|
var speck = {
|
|
2732
3039
|
shape: { _tag: "Ball", radius: 0.001 },
|
|
2733
|
-
offset: new
|
|
3040
|
+
offset: new Vector36
|
|
2734
3041
|
};
|
|
2735
3042
|
var shapeFor = (geometry, collider, scale) => {
|
|
2736
3043
|
if (geometry.getAttribute("position") === undefined)
|
|
@@ -2744,7 +3051,7 @@ var shapeFor = (geometry, collider, scale) => {
|
|
|
2744
3051
|
box.getSize(size).multiply(scale).multiplyScalar(0.5);
|
|
2745
3052
|
return {
|
|
2746
3053
|
shape: { _tag: "Cuboid", halfExtents: toVec32(size) },
|
|
2747
|
-
offset: box.getCenter(new
|
|
3054
|
+
offset: box.getCenter(new Vector36).multiply(scale)
|
|
2748
3055
|
};
|
|
2749
3056
|
}
|
|
2750
3057
|
case "ball": {
|
|
@@ -2761,7 +3068,7 @@ var shapeFor = (geometry, collider, scale) => {
|
|
|
2761
3068
|
case "hull":
|
|
2762
3069
|
return {
|
|
2763
3070
|
shape: { _tag: "Hull", points: scaledPositions(geometry, scale) },
|
|
2764
|
-
offset: new
|
|
3071
|
+
offset: new Vector36
|
|
2765
3072
|
};
|
|
2766
3073
|
case "trimesh":
|
|
2767
3074
|
return {
|
|
@@ -2770,7 +3077,7 @@ var shapeFor = (geometry, collider, scale) => {
|
|
|
2770
3077
|
vertices: scaledPositions(geometry, scale),
|
|
2771
3078
|
indices: triangles(geometry)
|
|
2772
3079
|
},
|
|
2773
|
-
offset: new
|
|
3080
|
+
offset: new Vector36
|
|
2774
3081
|
};
|
|
2775
3082
|
}
|
|
2776
3083
|
};
|
|
@@ -2815,11 +3122,11 @@ function describedCollider(collider, scale) {
|
|
|
2815
3122
|
}
|
|
2816
3123
|
var relative = new Matrix43;
|
|
2817
3124
|
var bodyInverse = new Matrix43;
|
|
2818
|
-
var where = new
|
|
3125
|
+
var where = new Vector36;
|
|
2819
3126
|
var turn = new Quaternion3;
|
|
2820
|
-
var relativeScale = new
|
|
2821
|
-
var worldScale = new
|
|
2822
|
-
var worldPosition = new
|
|
3127
|
+
var relativeScale = new Vector36;
|
|
3128
|
+
var worldScale = new Vector36;
|
|
3129
|
+
var worldPosition = new Vector36;
|
|
2823
3130
|
var worldTurn = new Quaternion3;
|
|
2824
3131
|
var isMesh = (object) => ("isMesh" in object) && object.isMesh === true;
|
|
2825
3132
|
function placedCollider2(child, collider, body) {
|
|
@@ -3075,7 +3382,7 @@ var stageBounds2 = (box) => {
|
|
|
3075
3382
|
import { Box3, EquirectangularReflectionMapping, UVMapping } from "three";
|
|
3076
3383
|
|
|
3077
3384
|
// src/kernel/pointer.ts
|
|
3078
|
-
import { Raycaster as Raycaster2, Vector2 as Vector23, Vector3 as
|
|
3385
|
+
import { Raycaster as Raycaster2, Vector2 as Vector23, Vector3 as Vector37 } from "three";
|
|
3079
3386
|
var noModifiers2 = { shift: false, control: false, meta: false, alt: false };
|
|
3080
3387
|
var pointOnPlane2 = (ray, plane) => {
|
|
3081
3388
|
const [nx, ny, nz] = plane.normal;
|
|
@@ -3116,7 +3423,7 @@ var shown = (object) => {
|
|
|
3116
3423
|
var createPicker2 = (graph) => {
|
|
3117
3424
|
const raycaster = new Raycaster2;
|
|
3118
3425
|
const ndc = new Vector23;
|
|
3119
|
-
const normal = new
|
|
3426
|
+
const normal = new Vector37;
|
|
3120
3427
|
const aim = (x, y) => {
|
|
3121
3428
|
graph.scene.updateMatrixWorld();
|
|
3122
3429
|
const views = graph.views();
|
|
@@ -3144,26 +3451,26 @@ var createPicker2 = (graph) => {
|
|
|
3144
3451
|
}
|
|
3145
3452
|
return false;
|
|
3146
3453
|
};
|
|
3147
|
-
const rayOrigin = new
|
|
3148
|
-
const rayDirection = new
|
|
3149
|
-
const nearestHit = (view) => {
|
|
3150
|
-
for (const intersection of raycaster.intersectObjects(
|
|
3454
|
+
const rayOrigin = new Vector37;
|
|
3455
|
+
const rayDirection = new Vector37;
|
|
3456
|
+
const nearestHit = (on, view) => {
|
|
3457
|
+
for (const intersection of raycaster.intersectObjects(on.interactiveObjects(), true)) {
|
|
3151
3458
|
if (!shown(intersection.object))
|
|
3152
3459
|
continue;
|
|
3153
|
-
const owner = keyedOwner(
|
|
3154
|
-
const key = owner === undefined ? undefined :
|
|
3460
|
+
const owner = keyedOwner(on, intersection.object);
|
|
3461
|
+
const key = owner === undefined ? undefined : on.keyOf(owner);
|
|
3155
3462
|
if (owner !== undefined && key !== undefined) {
|
|
3156
3463
|
normal.set(0, 0, 0);
|
|
3157
3464
|
if (intersection.face) {
|
|
3158
3465
|
normal.copy(intersection.face.normal).transformDirection(intersection.object.matrixWorld);
|
|
3159
3466
|
}
|
|
3160
|
-
const instance = intersection.instanceId === undefined ? undefined :
|
|
3467
|
+
const instance = intersection.instanceId === undefined ? undefined : on.instanceKeyOf(intersection.object, intersection.instanceId);
|
|
3161
3468
|
return {
|
|
3162
3469
|
key,
|
|
3163
3470
|
...instance === undefined ? {} : { instance },
|
|
3164
3471
|
...partOf(owner, intersection.object),
|
|
3165
3472
|
...view === undefined ? {} : { view },
|
|
3166
|
-
path: pathOf(
|
|
3473
|
+
path: pathOf(on, owner),
|
|
3167
3474
|
point: toVec33(intersection.point),
|
|
3168
3475
|
distance: intersection.distance,
|
|
3169
3476
|
normal: toVec33(normal),
|
|
@@ -3174,6 +3481,16 @@ var createPicker2 = (graph) => {
|
|
|
3174
3481
|
}
|
|
3175
3482
|
return;
|
|
3176
3483
|
};
|
|
3484
|
+
const hudHit = (x, y) => {
|
|
3485
|
+
const hud = graph.hud();
|
|
3486
|
+
if (hud === undefined || hud.graph.interactiveObjects().length === 0)
|
|
3487
|
+
return;
|
|
3488
|
+
hud.graph.scene.updateMatrixWorld();
|
|
3489
|
+
hud.graph.camera.updateMatrixWorld();
|
|
3490
|
+
ndc.set(x, y);
|
|
3491
|
+
raycaster.setFromCamera(ndc, hud.graph.camera);
|
|
3492
|
+
return nearestHit(hud.graph, undefined);
|
|
3493
|
+
};
|
|
3177
3494
|
const currentRay = () => ({
|
|
3178
3495
|
origin: toVec33(raycaster.ray.origin),
|
|
3179
3496
|
direction: toVec33(raycaster.ray.direction)
|
|
@@ -3200,31 +3517,35 @@ var createPicker2 = (graph) => {
|
|
|
3200
3517
|
holdCameras: graph.holdCameras,
|
|
3201
3518
|
turned: graph.turned,
|
|
3202
3519
|
pick: (x, y) => {
|
|
3520
|
+
const hud = hudHit(x, y);
|
|
3521
|
+
if (hud !== undefined)
|
|
3522
|
+
return hud;
|
|
3203
3523
|
if (graph.interactiveObjects().length === 0)
|
|
3204
3524
|
return;
|
|
3205
3525
|
const view = aim(x, y);
|
|
3206
3526
|
if (view === false)
|
|
3207
3527
|
return;
|
|
3208
|
-
return nearestHit(view);
|
|
3528
|
+
return nearestHit(graph, view);
|
|
3209
3529
|
},
|
|
3210
3530
|
pickRay: (ray) => {
|
|
3211
3531
|
if (graph.interactiveObjects().length === 0)
|
|
3212
3532
|
return;
|
|
3213
3533
|
graph.scene.updateMatrixWorld();
|
|
3214
3534
|
raycaster.set(rayOrigin.fromArray(ray.origin), rayDirection.fromArray(ray.direction).normalize());
|
|
3215
|
-
return nearestHit(undefined);
|
|
3535
|
+
return nearestHit(graph, undefined);
|
|
3216
3536
|
},
|
|
3217
3537
|
viewport: graph.viewport
|
|
3218
3538
|
};
|
|
3219
3539
|
};
|
|
3220
3540
|
var none2 = [];
|
|
3221
|
-
var
|
|
3541
|
+
var missTolerances = { mouse: 2, pen: 2, touch: 10 };
|
|
3222
3542
|
var pointerOf = (input) => ("pointer" in input) && input.pointer !== undefined ? input.pointer : 0;
|
|
3223
3543
|
var createPointerTracker2 = (picker) => {
|
|
3224
3544
|
let position;
|
|
3225
3545
|
const pressedPointers = new Map;
|
|
3226
3546
|
let primary;
|
|
3227
3547
|
let gesturePress;
|
|
3548
|
+
let gestureMoved = false;
|
|
3228
3549
|
let hovered;
|
|
3229
3550
|
let press;
|
|
3230
3551
|
let pressing = false;
|
|
@@ -3254,7 +3575,7 @@ var createPointerTracker2 = (picker) => {
|
|
|
3254
3575
|
}
|
|
3255
3576
|
return;
|
|
3256
3577
|
}
|
|
3257
|
-
if (from?.button === event.button && travel(from, event.x, event.y) <=
|
|
3578
|
+
if (from?.button === event.button && travel(from, event.x, event.y) <= missTolerances[from.device]) {
|
|
3258
3579
|
events.push({ _tag: "PointerMissed", button: event.button });
|
|
3259
3580
|
}
|
|
3260
3581
|
};
|
|
@@ -3289,6 +3610,7 @@ var createPointerTracker2 = (picker) => {
|
|
|
3289
3610
|
pressedPointers.clear();
|
|
3290
3611
|
primary = id;
|
|
3291
3612
|
pressedPointers.set(id, { x: event.x, y: event.y });
|
|
3613
|
+
gestureMoved = false;
|
|
3292
3614
|
const region = picker.region(event.x, event.y);
|
|
3293
3615
|
reportTurned(region, events);
|
|
3294
3616
|
picker.holdCameras(true);
|
|
@@ -3304,6 +3626,7 @@ var createPointerTracker2 = (picker) => {
|
|
|
3304
3626
|
if (from === undefined || gesturePress === undefined)
|
|
3305
3627
|
return;
|
|
3306
3628
|
pressedPointers.set(id, to);
|
|
3629
|
+
gestureMoved = true;
|
|
3307
3630
|
const { view, width, height, x, y } = gesturePress;
|
|
3308
3631
|
const region = { ...view === undefined ? {} : { view }, width, height, x, y };
|
|
3309
3632
|
const moved = pixels(from, to);
|
|
@@ -3342,12 +3665,23 @@ var createPointerTracker2 = (picker) => {
|
|
|
3342
3665
|
}
|
|
3343
3666
|
});
|
|
3344
3667
|
};
|
|
3345
|
-
const endGestures = () => {
|
|
3668
|
+
const endGestures = (events) => {
|
|
3346
3669
|
if (gesturePress !== undefined)
|
|
3347
3670
|
picker.holdCameras(false);
|
|
3671
|
+
if (gesturePress !== undefined && gestureMoved) {
|
|
3672
|
+
const { button, modifiers, key, view } = gesturePress;
|
|
3673
|
+
events.push({
|
|
3674
|
+
_tag: "GestureEnd",
|
|
3675
|
+
button,
|
|
3676
|
+
modifiers,
|
|
3677
|
+
...key === undefined ? {} : { key },
|
|
3678
|
+
...view === undefined ? {} : { view }
|
|
3679
|
+
});
|
|
3680
|
+
}
|
|
3348
3681
|
pressedPointers.clear();
|
|
3349
3682
|
primary = undefined;
|
|
3350
3683
|
gesturePress = undefined;
|
|
3684
|
+
gestureMoved = false;
|
|
3351
3685
|
};
|
|
3352
3686
|
const secondary = (event, id) => {
|
|
3353
3687
|
const events = [];
|
|
@@ -3367,7 +3701,7 @@ var createPointerTracker2 = (picker) => {
|
|
|
3367
3701
|
return secondary(event, id);
|
|
3368
3702
|
const events = [];
|
|
3369
3703
|
if (event._tag === "PointerLeave") {
|
|
3370
|
-
endGestures();
|
|
3704
|
+
endGestures(events);
|
|
3371
3705
|
if (position !== undefined)
|
|
3372
3706
|
endDrag(captured(), position.x, position.y, events);
|
|
3373
3707
|
dragged = false;
|
|
@@ -3392,7 +3726,13 @@ var createPointerTracker2 = (picker) => {
|
|
|
3392
3726
|
moveGesture(id, event, events);
|
|
3393
3727
|
break;
|
|
3394
3728
|
case "PointerDown":
|
|
3395
|
-
press = {
|
|
3729
|
+
press = {
|
|
3730
|
+
key: hit?.key,
|
|
3731
|
+
button: event.button,
|
|
3732
|
+
x: event.x,
|
|
3733
|
+
y: event.y,
|
|
3734
|
+
device: event.device ?? "mouse"
|
|
3735
|
+
};
|
|
3396
3736
|
pressing = true;
|
|
3397
3737
|
dragged = false;
|
|
3398
3738
|
if (hit !== undefined)
|
|
@@ -3402,7 +3742,7 @@ var createPointerTracker2 = (picker) => {
|
|
|
3402
3742
|
case "PointerUp":
|
|
3403
3743
|
release(hit, event, events);
|
|
3404
3744
|
endDrag(drag, event.x, event.y, events);
|
|
3405
|
-
endGestures();
|
|
3745
|
+
endGestures(events);
|
|
3406
3746
|
break;
|
|
3407
3747
|
case "DoubleClick":
|
|
3408
3748
|
if (hit !== undefined && pressed(hit)) {
|
|
@@ -3581,6 +3921,8 @@ var createSceneLoop2 = (options) => {
|
|
|
3581
3921
|
emit({ _tag: "Collision", ...collision });
|
|
3582
3922
|
for (const force of graph.contactForces())
|
|
3583
3923
|
emit({ _tag: "ContactForce", ...force });
|
|
3924
|
+
for (const reached of graph.physicsReached())
|
|
3925
|
+
emit({ _tag: "PhysicsReached", ...reached });
|
|
3584
3926
|
const settings = graph.renderSettings();
|
|
3585
3927
|
if (settings !== configured) {
|
|
3586
3928
|
renderer.configure(settings);
|
|
@@ -3594,6 +3936,11 @@ var createSceneLoop2 = (options) => {
|
|
|
3594
3936
|
renderer.render(graph.scene, graph.camera);
|
|
3595
3937
|
for (const view of views)
|
|
3596
3938
|
renderer.render(graph.scene, view.camera, view.area);
|
|
3939
|
+
const hud = graph.hud();
|
|
3940
|
+
if (hud !== undefined && renderer.renderOver !== undefined) {
|
|
3941
|
+
renderer.renderOver(hud.graph.scene, hud.graph.camera);
|
|
3942
|
+
hud.graph.drawn();
|
|
3943
|
+
}
|
|
3597
3944
|
graph.drawn();
|
|
3598
3945
|
measure();
|
|
3599
3946
|
const overlays = graph.overlays();
|
|
@@ -3678,21 +4025,21 @@ var recordingRendererFactory2 = () => {
|
|
|
3678
4025
|
// src/kernel/sceneGraph.ts
|
|
3679
4026
|
import {
|
|
3680
4027
|
AmbientLight,
|
|
3681
|
-
Color as
|
|
4028
|
+
Color as Color4,
|
|
3682
4029
|
AnimationClip,
|
|
3683
4030
|
AnimationMixer,
|
|
3684
4031
|
DirectionalLight,
|
|
3685
4032
|
Group,
|
|
3686
4033
|
GridHelper,
|
|
3687
4034
|
HemisphereLight,
|
|
3688
|
-
Mesh,
|
|
4035
|
+
Mesh as Mesh2,
|
|
3689
4036
|
OrthographicCamera as OrthographicCamera4,
|
|
3690
4037
|
PerspectiveCamera as PerspectiveCamera3,
|
|
3691
4038
|
PointLight,
|
|
3692
4039
|
Quaternion as Quaternion6,
|
|
3693
4040
|
Scene,
|
|
3694
4041
|
SpotLight,
|
|
3695
|
-
Vector3 as
|
|
4042
|
+
Vector3 as Vector311
|
|
3696
4043
|
} from "three";
|
|
3697
4044
|
import { clone as cloneSkinned } from "three/addons/utils/SkeletonUtils.js";
|
|
3698
4045
|
|
|
@@ -3700,16 +4047,16 @@ import { clone as cloneSkinned } from "three/addons/utils/SkeletonUtils.js";
|
|
|
3700
4047
|
import { Euler as Euler5, Quaternion as Quaternion5 } from "three";
|
|
3701
4048
|
|
|
3702
4049
|
// src/kernel/bodySources.ts
|
|
3703
|
-
import { Euler as Euler4, Matrix4 as Matrix44, Quaternion as Quaternion4, Vector3 as
|
|
4050
|
+
import { Euler as Euler4, Matrix4 as Matrix44, Quaternion as Quaternion4, Vector3 as Vector38 } from "three";
|
|
3704
4051
|
var bodyId = (key, instance) => instance === null ? key : `${key}\x00${instance}`;
|
|
3705
|
-
var position3 = new
|
|
4052
|
+
var position3 = new Vector38;
|
|
3706
4053
|
var quaternion2 = new Quaternion4;
|
|
3707
|
-
var scale2 = new
|
|
4054
|
+
var scale2 = new Vector38;
|
|
3708
4055
|
var matrix2 = new Matrix44;
|
|
3709
4056
|
var local = new Matrix44;
|
|
3710
4057
|
var inverse = new Matrix44;
|
|
3711
4058
|
var euler2 = new Euler4;
|
|
3712
|
-
var ownScale = new
|
|
4059
|
+
var ownScale = new Vector38;
|
|
3713
4060
|
var toPose = (from) => {
|
|
3714
4061
|
from.decompose(position3, quaternion2, scale2);
|
|
3715
4062
|
return {
|
|
@@ -3867,6 +4214,36 @@ var between = (a, b, alpha) => {
|
|
|
3867
4214
|
quaternion: [from.x, from.y, from.z, from.w]
|
|
3868
4215
|
};
|
|
3869
4216
|
};
|
|
4217
|
+
var catchUpAfter = 0.25;
|
|
4218
|
+
var mostPerFrame = 1;
|
|
4219
|
+
var checksumBytes = new DataView(new ArrayBuffer(8));
|
|
4220
|
+
var mixByte = (hash, byte) => Math.imul(hash ^ byte, 16777619) >>> 0;
|
|
4221
|
+
var mixNumber = (hash, value) => {
|
|
4222
|
+
checksumBytes.setFloat64(0, value);
|
|
4223
|
+
let mixed = hash;
|
|
4224
|
+
for (let i = 0;i < 8; i++)
|
|
4225
|
+
mixed = mixByte(mixed, checksumBytes.getUint8(i));
|
|
4226
|
+
return mixed;
|
|
4227
|
+
};
|
|
4228
|
+
var mixText = (hash, text) => {
|
|
4229
|
+
let mixed = hash;
|
|
4230
|
+
for (let i = 0;i < text.length; i++) {
|
|
4231
|
+
const code = text.charCodeAt(i);
|
|
4232
|
+
mixed = mixByte(mixByte(mixed, code & 255), code >>> 8);
|
|
4233
|
+
}
|
|
4234
|
+
return mixed;
|
|
4235
|
+
};
|
|
4236
|
+
var checksumOf = (poses) => {
|
|
4237
|
+
let hash = 2166136261;
|
|
4238
|
+
for (const [id, { position, quaternion }] of poses.toSorted(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) {
|
|
4239
|
+
hash = mixText(hash, id);
|
|
4240
|
+
for (const value of position)
|
|
4241
|
+
hash = mixNumber(hash, value);
|
|
4242
|
+
for (const value of quaternion)
|
|
4243
|
+
hash = mixNumber(hash, value);
|
|
4244
|
+
}
|
|
4245
|
+
return hash.toString(16).padStart(8, "0");
|
|
4246
|
+
};
|
|
3870
4247
|
var remade = (hosted, source, signature) => hosted.source.holder !== source.holder || hosted.source.body.collider !== source.body.collider || !collidersEqual(hosted.source.body.colliders, source.body.colliders) || hosted.signature !== signature;
|
|
3871
4248
|
var resettled = (a, b) => !bodyEquals2({ ...a, impulse: null }, { ...b, impulse: null });
|
|
3872
4249
|
var named = (a, b, ids) => {
|
|
@@ -3892,6 +4269,13 @@ var createBodyHost = (engine, scene) => {
|
|
|
3892
4269
|
const debug = createPhysicsDebug(scene);
|
|
3893
4270
|
let last;
|
|
3894
4271
|
let accumulator = 0;
|
|
4272
|
+
let steps = 0;
|
|
4273
|
+
let reported;
|
|
4274
|
+
let snapped;
|
|
4275
|
+
let reached = [];
|
|
4276
|
+
const kept = new Map;
|
|
4277
|
+
let rushing = false;
|
|
4278
|
+
let restored;
|
|
3895
4279
|
const drawDebug = () => {
|
|
3896
4280
|
if (world !== undefined && settings?.debug === true)
|
|
3897
4281
|
debug.show(world.debugLines());
|
|
@@ -3907,9 +4291,37 @@ var createBodyHost = (engine, scene) => {
|
|
|
3907
4291
|
joined.clear();
|
|
3908
4292
|
accumulator = 0;
|
|
3909
4293
|
last = undefined;
|
|
4294
|
+
steps = 0;
|
|
4295
|
+
reported = undefined;
|
|
4296
|
+
snapped = undefined;
|
|
4297
|
+
reached = [];
|
|
4298
|
+
};
|
|
4299
|
+
const make = (active, physics) => {
|
|
4300
|
+
const { from } = physics;
|
|
4301
|
+
const bytes = from === null ? undefined : from.snapshot === null ? kept.get(from.step) : snapshotBytes2(from.snapshot);
|
|
4302
|
+
if (from === null || bytes === undefined || active.restoreWorld === undefined) {
|
|
4303
|
+
kept.clear();
|
|
4304
|
+
return active.createWorld(physics);
|
|
4305
|
+
}
|
|
4306
|
+
for (const step of kept.keys())
|
|
4307
|
+
if (step > from.step || from.snapshot !== null)
|
|
4308
|
+
kept.delete(step);
|
|
4309
|
+
const made = active.restoreWorld(physics, bytes);
|
|
4310
|
+
steps = from.step;
|
|
4311
|
+
rushing = true;
|
|
4312
|
+
restored = { bodies: new Set(made.bodies), joints: new Set(made.joints) };
|
|
4313
|
+
return made.world;
|
|
4314
|
+
};
|
|
4315
|
+
const adopt = (active, source, signature) => {
|
|
4316
|
+
const pose = active.pose(source.id) ?? source.described();
|
|
4317
|
+
source.place(pose);
|
|
4318
|
+
hosted.set(source.id, { source, signature, previous: pose, current: pose, shown: pose });
|
|
3910
4319
|
};
|
|
4320
|
+
let restarting = false;
|
|
3911
4321
|
const add = (active, source, signature) => {
|
|
3912
|
-
const pose = source.pose();
|
|
4322
|
+
const pose = restarting ? source.described() : source.pose();
|
|
4323
|
+
if (restarting)
|
|
4324
|
+
source.place(pose);
|
|
3913
4325
|
active.add(source.id, source.body, source.colliders(), pose);
|
|
3914
4326
|
if (source.body.impulse !== null)
|
|
3915
4327
|
active.applyImpulse(source.id, source.body.impulse.impulse);
|
|
@@ -3919,6 +4331,10 @@ var createBodyHost = (engine, scene) => {
|
|
|
3919
4331
|
const syncBody = (active, source) => {
|
|
3920
4332
|
const existing = hosted.get(source.id);
|
|
3921
4333
|
const signature = source.signature();
|
|
4334
|
+
if (existing === undefined && restored?.bodies.has(source.id) === true) {
|
|
4335
|
+
adopt(active, source, signature);
|
|
4336
|
+
return;
|
|
4337
|
+
}
|
|
3922
4338
|
if (existing === undefined || remade(existing, source, signature)) {
|
|
3923
4339
|
if (existing !== undefined)
|
|
3924
4340
|
active.remove(source.id);
|
|
@@ -3974,11 +4390,22 @@ var createBodyHost = (engine, scene) => {
|
|
|
3974
4390
|
const sync = (physics, sources) => {
|
|
3975
4391
|
if (physics === null || engine === undefined) {
|
|
3976
4392
|
dispose();
|
|
4393
|
+
kept.clear();
|
|
3977
4394
|
return;
|
|
3978
4395
|
}
|
|
4396
|
+
restarting = settings !== null && settings.run !== physics.run;
|
|
4397
|
+
if (restarting)
|
|
4398
|
+
dispose();
|
|
3979
4399
|
if (world === undefined)
|
|
3980
|
-
world = engine
|
|
3981
|
-
else if (!physicsEquals2(settings && {
|
|
4400
|
+
world = make(engine, physics);
|
|
4401
|
+
else if (!physicsEquals2(settings && {
|
|
4402
|
+
...settings,
|
|
4403
|
+
joints: physics.joints,
|
|
4404
|
+
until: physics.until,
|
|
4405
|
+
snapshotAt: physics.snapshotAt,
|
|
4406
|
+
from: physics.from,
|
|
4407
|
+
keep: physics.keep
|
|
4408
|
+
}, physics)) {
|
|
3982
4409
|
world.configure(physics);
|
|
3983
4410
|
}
|
|
3984
4411
|
settings = physics;
|
|
@@ -3995,7 +4422,22 @@ var createBodyHost = (engine, scene) => {
|
|
|
3995
4422
|
world.remove(id);
|
|
3996
4423
|
hosted.delete(id);
|
|
3997
4424
|
}
|
|
4425
|
+
if (restored !== undefined) {
|
|
4426
|
+
for (const id of restored.bodies)
|
|
4427
|
+
if (!seen.has(id))
|
|
4428
|
+
world.remove(id);
|
|
4429
|
+
for (const joint of physics.joints) {
|
|
4430
|
+
if (restored.joints.has(joint.key))
|
|
4431
|
+
joined.set(joint.key, joint);
|
|
4432
|
+
}
|
|
4433
|
+
for (const id of restored.joints) {
|
|
4434
|
+
if (!joined.has(id))
|
|
4435
|
+
world.removeJoint(id);
|
|
4436
|
+
}
|
|
4437
|
+
restored = undefined;
|
|
4438
|
+
}
|
|
3998
4439
|
syncJoints(world, physics.joints);
|
|
4440
|
+
restarting = false;
|
|
3999
4441
|
drawDebug();
|
|
4000
4442
|
};
|
|
4001
4443
|
const kinematicTargets = (active) => {
|
|
@@ -4004,11 +4446,8 @@ var createBodyHost = (engine, scene) => {
|
|
|
4004
4446
|
active.moveKinematic(id, source.pose());
|
|
4005
4447
|
}
|
|
4006
4448
|
};
|
|
4007
|
-
const
|
|
4008
|
-
for (const
|
|
4009
|
-
body.previous = body.current;
|
|
4010
|
-
kinematicTargets(active);
|
|
4011
|
-
for (const collision of active.step(seconds)) {
|
|
4449
|
+
const heard = (arrived, active) => {
|
|
4450
|
+
for (const collision of arrived) {
|
|
4012
4451
|
collisions.push({
|
|
4013
4452
|
...named(hosted.get(collision.a)?.source, hosted.get(collision.b)?.source, collision),
|
|
4014
4453
|
started: collision.started
|
|
@@ -4021,22 +4460,99 @@ var createBodyHost = (engine, scene) => {
|
|
|
4021
4460
|
...payload
|
|
4022
4461
|
});
|
|
4023
4462
|
}
|
|
4463
|
+
};
|
|
4464
|
+
const step = (active, seconds) => {
|
|
4465
|
+
for (const body of hosted.values())
|
|
4466
|
+
body.previous = body.current;
|
|
4467
|
+
kinematicTargets(active);
|
|
4468
|
+
heard(active.step(seconds), active);
|
|
4469
|
+
for (const [id, body] of hosted)
|
|
4470
|
+
body.current = active.pose(id) ?? body.current;
|
|
4471
|
+
steps += 1;
|
|
4472
|
+
};
|
|
4473
|
+
const collect = (active) => {
|
|
4474
|
+
if (active.received === undefined)
|
|
4475
|
+
return false;
|
|
4476
|
+
const { collisions: arrived, pending } = active.received();
|
|
4477
|
+
heard(arrived, active);
|
|
4024
4478
|
for (const [id, body] of hosted)
|
|
4025
4479
|
body.current = active.pose(id) ?? body.current;
|
|
4480
|
+
return pending;
|
|
4481
|
+
};
|
|
4482
|
+
const free = (active, timeStep, delta) => {
|
|
4483
|
+
accumulator += delta;
|
|
4484
|
+
while (accumulator >= timeStep) {
|
|
4485
|
+
step(active, timeStep);
|
|
4486
|
+
accumulator -= timeStep;
|
|
4487
|
+
}
|
|
4488
|
+
collect(active);
|
|
4489
|
+
return accumulator / timeStep;
|
|
4490
|
+
};
|
|
4491
|
+
const snapshotOwed = (physics, until) => physics.snapshotAt !== null && snapped !== physics.snapshotAt && steps <= physics.snapshotAt && physics.snapshotAt <= until;
|
|
4492
|
+
const report = (active, physics, snapshot) => {
|
|
4493
|
+
const wanted = snapshot || physics.keep > 0;
|
|
4494
|
+
const bytes = wanted ? active.snapshot?.() : undefined;
|
|
4495
|
+
if (wanted && active.snapshot !== undefined && bytes === undefined)
|
|
4496
|
+
return false;
|
|
4497
|
+
if (physics.keep > 0 && bytes !== undefined) {
|
|
4498
|
+
kept.delete(steps);
|
|
4499
|
+
kept.set(steps, bytes);
|
|
4500
|
+
for (const step of kept.keys())
|
|
4501
|
+
if (kept.size > physics.keep)
|
|
4502
|
+
kept.delete(step);
|
|
4503
|
+
}
|
|
4504
|
+
const { run } = physics;
|
|
4505
|
+
reached.push({
|
|
4506
|
+
run,
|
|
4507
|
+
step: steps,
|
|
4508
|
+
checksum: checksumOf([...hosted.keys()].flatMap((id) => posed(active, id))),
|
|
4509
|
+
...snapshot && bytes !== undefined ? { snapshot: snapshotText2(bytes) } : {}
|
|
4510
|
+
});
|
|
4511
|
+
return true;
|
|
4512
|
+
};
|
|
4513
|
+
const driven = (active, physics, until, delta) => {
|
|
4514
|
+
const { timeStep } = physics;
|
|
4515
|
+
const snapping = snapshotOwed(physics, until);
|
|
4516
|
+
const stop = snapping && physics.snapshotAt !== null ? physics.snapshotAt : until;
|
|
4517
|
+
accumulator += delta;
|
|
4518
|
+
const owed = Math.max(0, stop - steps);
|
|
4519
|
+
const paced = Math.floor(accumulator / timeStep);
|
|
4520
|
+
const behind = rushing || owed > Math.ceil(catchUpAfter / timeStep);
|
|
4521
|
+
rushing = false;
|
|
4522
|
+
const count = Math.min(owed, behind ? owed : paced, Math.ceil(mostPerFrame / timeStep));
|
|
4523
|
+
for (let i = 0;i < count; i++)
|
|
4524
|
+
step(active, timeStep);
|
|
4525
|
+
accumulator = Math.max(0, accumulator - count * timeStep);
|
|
4526
|
+
const pending = collect(active);
|
|
4527
|
+
if (steps < stop)
|
|
4528
|
+
return Math.min(1, accumulator / timeStep);
|
|
4529
|
+
if (stop < until) {
|
|
4530
|
+
if (!pending && report(active, physics, true))
|
|
4531
|
+
snapped = stop;
|
|
4532
|
+
return Math.min(1, accumulator / timeStep);
|
|
4533
|
+
}
|
|
4534
|
+
accumulator = 0;
|
|
4535
|
+
if (steps === until && (reported !== until || snapping) && !pending && report(active, physics, snapping)) {
|
|
4536
|
+
reported = until;
|
|
4537
|
+
if (snapping)
|
|
4538
|
+
snapped = until;
|
|
4539
|
+
}
|
|
4540
|
+
return 1;
|
|
4541
|
+
};
|
|
4542
|
+
const posed = (active, id) => {
|
|
4543
|
+
const pose = active.pose(id);
|
|
4544
|
+
return pose === undefined ? [] : [[id, pose]];
|
|
4026
4545
|
};
|
|
4027
4546
|
const tick = (elapsed, animating) => {
|
|
4028
4547
|
const delta = last === undefined ? 0 : Math.min(0.5, Math.max(0, elapsed - last));
|
|
4029
4548
|
last = elapsed;
|
|
4030
|
-
if (world === undefined || settings === null || settings.paused
|
|
4549
|
+
if (world === undefined || settings === null || settings.paused)
|
|
4550
|
+
return;
|
|
4551
|
+
if (settings.until === null && !animating)
|
|
4031
4552
|
return;
|
|
4032
|
-
const timeStep = settings.timeStep;
|
|
4033
|
-
accumulator += delta;
|
|
4034
4553
|
scene.updateMatrixWorld();
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
accumulator -= timeStep;
|
|
4038
|
-
}
|
|
4039
|
-
const alpha = settings.interpolate ? accumulator / timeStep : 1;
|
|
4554
|
+
const progress = settings.until === null ? free(world, settings.timeStep, delta) : driven(world, settings, settings.until, delta);
|
|
4555
|
+
const alpha = settings.interpolate ? progress : 1;
|
|
4040
4556
|
for (const body of hosted.values()) {
|
|
4041
4557
|
if (body.source.body.type === "dynamic") {
|
|
4042
4558
|
body.shown = between(body.previous, body.current, alpha);
|
|
@@ -4064,15 +4580,23 @@ var createBodyHost = (engine, scene) => {
|
|
|
4064
4580
|
contactForces = [];
|
|
4065
4581
|
return drained;
|
|
4066
4582
|
},
|
|
4583
|
+
drainReached: () => {
|
|
4584
|
+
if (reached.length === 0)
|
|
4585
|
+
return reached;
|
|
4586
|
+
const drained = reached;
|
|
4587
|
+
reached = [];
|
|
4588
|
+
return drained;
|
|
4589
|
+
},
|
|
4590
|
+
owesSteps: () => world !== undefined && settings !== null && !settings.paused && settings.until !== null && (steps < settings.until || reported !== settings.until || snapshotOwed(settings, settings.until)),
|
|
4067
4591
|
dispose
|
|
4068
4592
|
};
|
|
4069
4593
|
};
|
|
4070
4594
|
|
|
4071
4595
|
// src/kernel/cameraMotion.ts
|
|
4072
|
-
import { OrthographicCamera as OrthographicCamera3, Spherical as Spherical2, Vector3 as
|
|
4073
|
-
var createPose = () => ({ target: new
|
|
4074
|
-
var offset2 = new
|
|
4075
|
-
var position4 = new
|
|
4596
|
+
import { OrthographicCamera as OrthographicCamera3, Spherical as Spherical2, Vector3 as Vector39 } from "three";
|
|
4597
|
+
var createPose = () => ({ target: new Vector39, spherical: new Spherical2, zoom: 1 });
|
|
4598
|
+
var offset2 = new Vector39;
|
|
4599
|
+
var position4 = new Vector39;
|
|
4076
4600
|
var readPose = (pose, description) => {
|
|
4077
4601
|
pose.target.fromArray(description.lookAt);
|
|
4078
4602
|
offset2.fromArray(description.position).sub(pose.target);
|
|
@@ -4113,8 +4637,8 @@ var createCameraMotion = () => {
|
|
|
4113
4637
|
const current = createPose();
|
|
4114
4638
|
const described = createPose();
|
|
4115
4639
|
const goal = createPose();
|
|
4116
|
-
const goalPosition = new
|
|
4117
|
-
const lookAt = new
|
|
4640
|
+
const goalPosition = new Vector39;
|
|
4641
|
+
const lookAt = new Vector39;
|
|
4118
4642
|
let shown = false;
|
|
4119
4643
|
let easing = false;
|
|
4120
4644
|
let damping = 0;
|
|
@@ -4204,18 +4728,7 @@ var createCameraMotion = () => {
|
|
|
4204
4728
|
|
|
4205
4729
|
// src/kernel/cameraShake.ts
|
|
4206
4730
|
import { SimplexNoise } from "three/addons/math/SimplexNoise.js";
|
|
4207
|
-
var seeded = (seed) => {
|
|
4208
|
-
let state = seed >>> 0;
|
|
4209
|
-
return {
|
|
4210
|
-
random: () => {
|
|
4211
|
-
state = state + 1831565813 >>> 0;
|
|
4212
|
-
let t = state;
|
|
4213
|
-
t = Math.imul(t ^ t >>> 15, t | 1);
|
|
4214
|
-
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
|
4215
|
-
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
4216
|
-
}
|
|
4217
|
-
};
|
|
4218
|
-
};
|
|
4731
|
+
var seeded = (seed) => ({ random: seededRandom(seed) });
|
|
4219
4732
|
var yawNoise = new SimplexNoise(seeded(1));
|
|
4220
4733
|
var pitchNoise = new SimplexNoise(seeded(2));
|
|
4221
4734
|
var rollNoise = new SimplexNoise(seeded(3));
|
|
@@ -4250,8 +4763,147 @@ var createCameraShaker = () => {
|
|
|
4250
4763
|
};
|
|
4251
4764
|
};
|
|
4252
4765
|
|
|
4766
|
+
// src/kernel/trail.ts
|
|
4767
|
+
import {
|
|
4768
|
+
BufferAttribute as BufferAttribute2,
|
|
4769
|
+
BufferGeometry as BufferGeometry3,
|
|
4770
|
+
Color as Color3,
|
|
4771
|
+
DoubleSide as DoubleSide2,
|
|
4772
|
+
Mesh,
|
|
4773
|
+
MeshBasicMaterial as MeshBasicMaterial2,
|
|
4774
|
+
Vector3 as Vector310
|
|
4775
|
+
} from "three";
|
|
4776
|
+
var stepsPerSecond = 60;
|
|
4777
|
+
var widthAt = (trail, along) => {
|
|
4778
|
+
const full = trail.width * 0.1;
|
|
4779
|
+
if (trail.taper === "linear")
|
|
4780
|
+
return full * along;
|
|
4781
|
+
if (trail.taper === "quadratic")
|
|
4782
|
+
return full * along * along;
|
|
4783
|
+
return full;
|
|
4784
|
+
};
|
|
4785
|
+
var createTrailRibbon = (first, start, now) => {
|
|
4786
|
+
let trail = first;
|
|
4787
|
+
let count = 0;
|
|
4788
|
+
let points = new Float32Array(0);
|
|
4789
|
+
const geometry = new BufferGeometry3;
|
|
4790
|
+
const material = new MeshBasicMaterial2({
|
|
4791
|
+
vertexColors: true,
|
|
4792
|
+
transparent: true,
|
|
4793
|
+
side: DoubleSide2,
|
|
4794
|
+
depthWrite: false
|
|
4795
|
+
});
|
|
4796
|
+
const object = new Mesh(geometry, material);
|
|
4797
|
+
object.frustumCulled = false;
|
|
4798
|
+
object.raycast = () => {
|
|
4799
|
+
return;
|
|
4800
|
+
};
|
|
4801
|
+
object.name = "effect-three:trail";
|
|
4802
|
+
const last = new Vector310;
|
|
4803
|
+
const here = new Vector310;
|
|
4804
|
+
const ahead = new Vector310;
|
|
4805
|
+
const behind = new Vector310;
|
|
4806
|
+
const side = new Vector310;
|
|
4807
|
+
const toEye = new Vector310;
|
|
4808
|
+
const tint = new Color3;
|
|
4809
|
+
let clock = now;
|
|
4810
|
+
let phase = 0;
|
|
4811
|
+
const reset = (at, time) => {
|
|
4812
|
+
count = Math.max(2, Math.round(trail.length * 10));
|
|
4813
|
+
points = new Float32Array(count * 3);
|
|
4814
|
+
for (let point = 0;point < count; point++)
|
|
4815
|
+
at.toArray(points, point * 3);
|
|
4816
|
+
const index = [];
|
|
4817
|
+
for (let point = 0;point < count - 1; point++) {
|
|
4818
|
+
const a = point * 2;
|
|
4819
|
+
index.push(a, a + 1, a + 2, a + 1, a + 3, a + 2);
|
|
4820
|
+
}
|
|
4821
|
+
geometry.setIndex(index);
|
|
4822
|
+
geometry.setAttribute("position", new BufferAttribute2(new Float32Array(count * 6), 3));
|
|
4823
|
+
geometry.setAttribute("color", new BufferAttribute2(new Float32Array(count * 8), 4));
|
|
4824
|
+
paint();
|
|
4825
|
+
last.copy(at);
|
|
4826
|
+
clock = time;
|
|
4827
|
+
phase = 0;
|
|
4828
|
+
};
|
|
4829
|
+
const paint = () => {
|
|
4830
|
+
const colors = geometry.getAttribute("color");
|
|
4831
|
+
tint.setHex(trail.color);
|
|
4832
|
+
for (let point = 0;point < count; point++) {
|
|
4833
|
+
const alpha = trail.fade ? point / (count - 1) : 1;
|
|
4834
|
+
colors.setXYZW(point * 2, tint.r, tint.g, tint.b, alpha);
|
|
4835
|
+
colors.setXYZW(point * 2 + 1, tint.r, tint.g, tint.b, alpha);
|
|
4836
|
+
}
|
|
4837
|
+
colors.needsUpdate = true;
|
|
4838
|
+
};
|
|
4839
|
+
const push = (at) => {
|
|
4840
|
+
points.copyWithin(0, 3);
|
|
4841
|
+
at.toArray(points, (count - 1) * 3);
|
|
4842
|
+
};
|
|
4843
|
+
reset(start, now);
|
|
4844
|
+
return {
|
|
4845
|
+
object,
|
|
4846
|
+
record: (position, time) => {
|
|
4847
|
+
const due = Math.min(count, Math.floor((time - clock) * stepsPerSecond));
|
|
4848
|
+
if (due <= 0)
|
|
4849
|
+
return;
|
|
4850
|
+
clock += due / stepsPerSecond;
|
|
4851
|
+
for (let step = 0;step < due; step++) {
|
|
4852
|
+
if (phase === 0) {
|
|
4853
|
+
for (let shift = 0;shift < trail.decay; shift++) {
|
|
4854
|
+
if (position.distanceTo(last) < trail.stride)
|
|
4855
|
+
continue;
|
|
4856
|
+
push(position);
|
|
4857
|
+
}
|
|
4858
|
+
last.copy(position);
|
|
4859
|
+
}
|
|
4860
|
+
phase = (phase + 1) % Math.max(1, Math.round(trail.interval));
|
|
4861
|
+
}
|
|
4862
|
+
},
|
|
4863
|
+
face: (eye) => {
|
|
4864
|
+
const position = geometry.getAttribute("position");
|
|
4865
|
+
for (let point = 0;point < count; point++) {
|
|
4866
|
+
here.fromArray(points, point * 3);
|
|
4867
|
+
ahead.fromArray(points, Math.min(point + 1, count - 1) * 3);
|
|
4868
|
+
behind.fromArray(points, Math.max(point - 1, 0) * 3);
|
|
4869
|
+
side.subVectors(ahead, behind).cross(toEye.subVectors(eye, here));
|
|
4870
|
+
const length = side.length();
|
|
4871
|
+
if (length > 0.000000001)
|
|
4872
|
+
side.multiplyScalar(widthAt(trail, point / (count - 1)) / 2 / length);
|
|
4873
|
+
else
|
|
4874
|
+
side.set(0, 0, 0);
|
|
4875
|
+
position.setXYZ(point * 2, here.x + side.x, here.y + side.y, here.z + side.z);
|
|
4876
|
+
position.setXYZ(point * 2 + 1, here.x - side.x, here.y - side.y, here.z - side.z);
|
|
4877
|
+
}
|
|
4878
|
+
position.needsUpdate = true;
|
|
4879
|
+
},
|
|
4880
|
+
settled: () => {
|
|
4881
|
+
const end = (count - 1) * 3;
|
|
4882
|
+
for (let point = 0;point < end; point += 3) {
|
|
4883
|
+
if (points[point] !== points[end] || points[point + 1] !== points[end + 1])
|
|
4884
|
+
return false;
|
|
4885
|
+
if (points[point + 2] !== points[end + 2])
|
|
4886
|
+
return false;
|
|
4887
|
+
}
|
|
4888
|
+
return true;
|
|
4889
|
+
},
|
|
4890
|
+
restyle: (next, position, time) => {
|
|
4891
|
+
const resized = Math.round(next.length * 10) !== Math.round(trail.length * 10);
|
|
4892
|
+
trail = next;
|
|
4893
|
+
if (resized)
|
|
4894
|
+
reset(position, time);
|
|
4895
|
+
else
|
|
4896
|
+
paint();
|
|
4897
|
+
},
|
|
4898
|
+
dispose: () => {
|
|
4899
|
+
geometry.dispose();
|
|
4900
|
+
material.dispose();
|
|
4901
|
+
}
|
|
4902
|
+
};
|
|
4903
|
+
};
|
|
4904
|
+
|
|
4253
4905
|
// src/kernel/sceneGraph.ts
|
|
4254
|
-
var isPlaced = (entry) => entry._tag === "Group" || entry._tag === "Mesh" || entry._tag === "Instances" || entry._tag === "Borrowed" || entry._tag === "Label";
|
|
4906
|
+
var isPlaced = (entry) => entry._tag === "Group" || entry._tag === "Mesh" || entry._tag === "Instances" || entry._tag === "Borrowed" || entry._tag === "Label" || entry._tag === "Line" || entry._tag === "Points";
|
|
4255
4907
|
var isSurfaced = (entry) => entry._tag === "Mesh" || entry._tag === "Instances";
|
|
4256
4908
|
var writeVec3 = (target, v) => {
|
|
4257
4909
|
target.set(v[0], v[1], v[2]);
|
|
@@ -4345,6 +4997,7 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
4345
4997
|
let views = [];
|
|
4346
4998
|
const textureGraphs = new Map;
|
|
4347
4999
|
let textureList = [];
|
|
5000
|
+
let hudHosted;
|
|
4348
5001
|
let viewDescriptions = [];
|
|
4349
5002
|
let gestures = emptyScene.gestures;
|
|
4350
5003
|
let overlayList = emptyScene.overlays;
|
|
@@ -4446,11 +5099,35 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
4446
5099
|
const keys = new WeakMap;
|
|
4447
5100
|
const spinning = new Set;
|
|
4448
5101
|
const facing = new Set;
|
|
5102
|
+
const facingOrder = [];
|
|
4449
5103
|
const cameraTurn = new Quaternion6;
|
|
4450
5104
|
const parentTurn = new Quaternion6;
|
|
5105
|
+
const sparkling = new Set;
|
|
5106
|
+
const trackSparkle = (entry, node) => {
|
|
5107
|
+
if (animatedLook(node.look))
|
|
5108
|
+
sparkling.add(entry);
|
|
5109
|
+
else
|
|
5110
|
+
sparkling.delete(entry);
|
|
5111
|
+
if (entry._tag === "Points")
|
|
5112
|
+
entry.hosted?.tick(animating ? elapsed : 0);
|
|
5113
|
+
};
|
|
5114
|
+
const sparkle = (entry) => {
|
|
5115
|
+
if (entry._tag === "Points")
|
|
5116
|
+
entry.hosted?.tick(elapsed);
|
|
5117
|
+
};
|
|
5118
|
+
const trailing = new Map;
|
|
5119
|
+
const trailPlace = new Vector311;
|
|
5120
|
+
const eye = new Vector311;
|
|
5121
|
+
const trailsMoving = () => {
|
|
5122
|
+
for (const ribbon of trailing.values())
|
|
5123
|
+
if (!ribbon.settled())
|
|
5124
|
+
return true;
|
|
5125
|
+
return false;
|
|
5126
|
+
};
|
|
5127
|
+
const edged = new Map;
|
|
4451
5128
|
const detailing = new Set;
|
|
4452
|
-
const cameraPlace = new
|
|
4453
|
-
const groupPlace = new
|
|
5129
|
+
const cameraPlace = new Vector311;
|
|
5130
|
+
const groupPlace = new Vector311;
|
|
4454
5131
|
const playing = new Set;
|
|
4455
5132
|
const registry = {
|
|
4456
5133
|
...builtinBehaviours2,
|
|
@@ -4460,7 +5137,7 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
4460
5137
|
const behaving = new Map;
|
|
4461
5138
|
const moving = new Map;
|
|
4462
5139
|
const reparented = new Set;
|
|
4463
|
-
const worldPosition = new
|
|
5140
|
+
const worldPosition = new Vector311;
|
|
4464
5141
|
const interactive = new Set;
|
|
4465
5142
|
let interactiveList;
|
|
4466
5143
|
let index = emptyIndex2;
|
|
@@ -4528,6 +5205,81 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
4528
5205
|
if (lockZ)
|
|
4529
5206
|
object.rotation.z = 0;
|
|
4530
5207
|
};
|
|
5208
|
+
const depthOf = (object) => {
|
|
5209
|
+
let depth = 0;
|
|
5210
|
+
for (let parent = object.parent;parent !== null; parent = parent.parent)
|
|
5211
|
+
depth += 1;
|
|
5212
|
+
return depth;
|
|
5213
|
+
};
|
|
5214
|
+
const faceCameras = () => {
|
|
5215
|
+
facingOrder.length = 0;
|
|
5216
|
+
facing.forEach((entry) => facingOrder.push(entry));
|
|
5217
|
+
facingOrder.sort((a, b) => depthOf(a.object) - depthOf(b.object));
|
|
5218
|
+
facingOrder.forEach(faceCamera);
|
|
5219
|
+
};
|
|
5220
|
+
const trailTarget = (object, local) => local ? trailPlace.copy(object.position) : object.getWorldPosition(trailPlace);
|
|
5221
|
+
const trackTrail = (entry, node) => {
|
|
5222
|
+
const current = trailing.get(entry);
|
|
5223
|
+
if (node.trail === null) {
|
|
5224
|
+
if (current === undefined)
|
|
5225
|
+
return;
|
|
5226
|
+
current.object.removeFromParent();
|
|
5227
|
+
current.dispose();
|
|
5228
|
+
trailing.delete(entry);
|
|
5229
|
+
return;
|
|
5230
|
+
}
|
|
5231
|
+
const start = trailTarget(entry.object, node.trail.local);
|
|
5232
|
+
if (current !== undefined) {
|
|
5233
|
+
current.restyle(node.trail, start, elapsed);
|
|
5234
|
+
return;
|
|
5235
|
+
}
|
|
5236
|
+
const ribbon = createTrailRibbon(node.trail, start, elapsed);
|
|
5237
|
+
scene.add(ribbon.object);
|
|
5238
|
+
trailing.set(entry, ribbon);
|
|
5239
|
+
};
|
|
5240
|
+
const followTrail = (ribbon, entry) => {
|
|
5241
|
+
if (entry._tag !== "Group" && entry._tag !== "Mesh")
|
|
5242
|
+
return;
|
|
5243
|
+
if (entry.node.trail === null)
|
|
5244
|
+
return;
|
|
5245
|
+
ribbon.record(trailTarget(entry.object, entry.node.trail.local), elapsed);
|
|
5246
|
+
ribbon.face(eye);
|
|
5247
|
+
};
|
|
5248
|
+
const unpickable = (part) => {
|
|
5249
|
+
part.raycast = () => {
|
|
5250
|
+
return;
|
|
5251
|
+
};
|
|
5252
|
+
};
|
|
5253
|
+
const trackEdges = (entry, node) => {
|
|
5254
|
+
const current = edged.get(entry);
|
|
5255
|
+
const draw = options.kit?.line;
|
|
5256
|
+
if (node.edges === null || draw === undefined) {
|
|
5257
|
+
if (current === undefined)
|
|
5258
|
+
return;
|
|
5259
|
+
current.hosted.object.removeFromParent();
|
|
5260
|
+
current.hosted.dispose();
|
|
5261
|
+
edged.delete(entry);
|
|
5262
|
+
return;
|
|
5263
|
+
}
|
|
5264
|
+
if (current !== undefined)
|
|
5265
|
+
return;
|
|
5266
|
+
const hosted = draw(edgeLine(node.key, node.edges, []));
|
|
5267
|
+
entry.object.add(hosted.object);
|
|
5268
|
+
edged.set(entry, { hosted, geometry: undefined, edges: undefined });
|
|
5269
|
+
};
|
|
5270
|
+
const refreshEdges = (lines, entry) => {
|
|
5271
|
+
if (entry._tag !== "Mesh" || entry.node.edges === null)
|
|
5272
|
+
return;
|
|
5273
|
+
const { geometry } = entry.object;
|
|
5274
|
+
const look = entry.node.edges;
|
|
5275
|
+
if (geometry === lines.geometry && lines.edges !== undefined && edgesEquals(look, lines.edges)) {
|
|
5276
|
+
return;
|
|
5277
|
+
}
|
|
5278
|
+
lines.hosted.update(edgeLine(entry.node.key, look, edgePoints(geometry, look.threshold)));
|
|
5279
|
+
lines.hosted.object.traverse(unpickable);
|
|
5280
|
+
lines.geometry = geometry;
|
|
5281
|
+
lines.edges = look;
|
|
5282
|
+
};
|
|
4531
5283
|
const childObject = (node, index) => {
|
|
4532
5284
|
const child = node.children[index];
|
|
4533
5285
|
return child === undefined ? undefined : entries.get(child.key)?.object;
|
|
@@ -4592,10 +5344,11 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
4592
5344
|
if (node.follow !== null)
|
|
4593
5345
|
entry.object.visible = false;
|
|
4594
5346
|
trackDetail(entry, node);
|
|
5347
|
+
trackTrail(entry, node);
|
|
4595
5348
|
return entry;
|
|
4596
5349
|
}
|
|
4597
5350
|
case "Mesh": {
|
|
4598
|
-
const object = new
|
|
5351
|
+
const object = new Mesh2(store.acquireGeometry(node.geometry), store.acquireMaterial(node.material));
|
|
4599
5352
|
const entry = { _tag: "Mesh", node, object };
|
|
4600
5353
|
writeVec3(object.position, node.position);
|
|
4601
5354
|
writeVec3(object.scale, node.scale);
|
|
@@ -4604,6 +5357,8 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
4604
5357
|
trackInteractive(object, node.interactive);
|
|
4605
5358
|
object.castShadow = node.castShadow;
|
|
4606
5359
|
object.receiveShadow = node.receiveShadow;
|
|
5360
|
+
trackEdges(entry, node);
|
|
5361
|
+
trackTrail(entry, node);
|
|
4607
5362
|
return entry;
|
|
4608
5363
|
}
|
|
4609
5364
|
case "Instances": {
|
|
@@ -4677,6 +5432,30 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
4677
5432
|
const hosted = options.kit?.shaderGrid(node);
|
|
4678
5433
|
return { _tag: "ShaderGrid", node, object: hosted?.object ?? new Group, hosted };
|
|
4679
5434
|
}
|
|
5435
|
+
case "Points": {
|
|
5436
|
+
const hosted = options.kit?.points?.(node);
|
|
5437
|
+
const entry = { _tag: "Points", node, object: new Group, hosted };
|
|
5438
|
+
if (hosted !== undefined)
|
|
5439
|
+
entry.object.add(hosted.object);
|
|
5440
|
+
writeVec3(entry.object.position, node.position);
|
|
5441
|
+
writeVec3(entry.object.scale, node.scale);
|
|
5442
|
+
trackRotation(entry, node);
|
|
5443
|
+
trackBehaviour(entry, node);
|
|
5444
|
+
trackSparkle(entry, node);
|
|
5445
|
+
return entry;
|
|
5446
|
+
}
|
|
5447
|
+
case "Line": {
|
|
5448
|
+
const hosted = options.kit?.line?.(node);
|
|
5449
|
+
const entry = { _tag: "Line", node, object: new Group, hosted };
|
|
5450
|
+
if (hosted !== undefined)
|
|
5451
|
+
entry.object.add(hosted.object);
|
|
5452
|
+
writeVec3(entry.object.position, node.position);
|
|
5453
|
+
writeVec3(entry.object.scale, node.scale);
|
|
5454
|
+
trackRotation(entry, node);
|
|
5455
|
+
trackBehaviour(entry, node);
|
|
5456
|
+
trackInteractive(entry.object, node.interactive);
|
|
5457
|
+
return entry;
|
|
5458
|
+
}
|
|
4680
5459
|
case "HemisphereLight": {
|
|
4681
5460
|
const object = new HemisphereLight;
|
|
4682
5461
|
writeHemisphereLight(object, node);
|
|
@@ -4701,9 +5480,9 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
4701
5480
|
if (!node.castShadow && !node.receiveShadow)
|
|
4702
5481
|
return;
|
|
4703
5482
|
shown.traverse((part) => {
|
|
4704
|
-
if (part instanceof
|
|
5483
|
+
if (part instanceof Mesh2 && node.castShadow)
|
|
4705
5484
|
part.castShadow = true;
|
|
4706
|
-
if (part instanceof
|
|
5485
|
+
if (part instanceof Mesh2 && node.receiveShadow)
|
|
4707
5486
|
part.receiveShadow = true;
|
|
4708
5487
|
});
|
|
4709
5488
|
};
|
|
@@ -4842,6 +5621,17 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
4842
5621
|
spinning.delete(entry);
|
|
4843
5622
|
facing.delete(entry);
|
|
4844
5623
|
detailing.delete(entry);
|
|
5624
|
+
const lines = edged.get(entry);
|
|
5625
|
+
if (lines !== undefined) {
|
|
5626
|
+
lines.hosted.dispose();
|
|
5627
|
+
edged.delete(entry);
|
|
5628
|
+
}
|
|
5629
|
+
const ribbon = trailing.get(entry);
|
|
5630
|
+
if (ribbon !== undefined) {
|
|
5631
|
+
ribbon.object.removeFromParent();
|
|
5632
|
+
ribbon.dispose();
|
|
5633
|
+
trailing.delete(entry);
|
|
5634
|
+
}
|
|
4845
5635
|
moving.delete(entry);
|
|
4846
5636
|
reparented.delete(entry);
|
|
4847
5637
|
trackInteractive(entry.object, false);
|
|
@@ -4853,8 +5643,10 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
4853
5643
|
entry.object.dispose();
|
|
4854
5644
|
if (entry._tag === "Grid")
|
|
4855
5645
|
disposeGridLines(entry.helper);
|
|
4856
|
-
if (entry._tag === "ShaderGrid")
|
|
5646
|
+
if (entry._tag === "ShaderGrid" || entry._tag === "Line" || entry._tag === "Points") {
|
|
4857
5647
|
entry.hosted?.dispose();
|
|
5648
|
+
}
|
|
5649
|
+
sparkling.delete(entry);
|
|
4858
5650
|
if (entry._tag === "Label") {
|
|
4859
5651
|
entry.hosted?.dispose();
|
|
4860
5652
|
if (entry.node.material !== null && entry.material !== undefined) {
|
|
@@ -4949,6 +5741,12 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
4949
5741
|
retarget(entry, next);
|
|
4950
5742
|
if (fields.includes("rotation"))
|
|
4951
5743
|
trackRotation(entry, next);
|
|
5744
|
+
if (entry._tag === "Mesh" && next._tag === "Mesh" && fields.includes("edges")) {
|
|
5745
|
+
trackEdges(entry, next);
|
|
5746
|
+
}
|
|
5747
|
+
if (entry._tag === "Mesh" && next._tag === "Mesh" && fields.includes("trail")) {
|
|
5748
|
+
trackTrail(entry, next);
|
|
5749
|
+
}
|
|
4952
5750
|
if (fields.includes("behaviour"))
|
|
4953
5751
|
trackBehaviour(entry, next);
|
|
4954
5752
|
if (fields.includes("interactive"))
|
|
@@ -5005,6 +5803,8 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
5005
5803
|
trackInteractive(entry.object, next.interactive);
|
|
5006
5804
|
if (fields.includes("detail"))
|
|
5007
5805
|
trackDetail(entry, next);
|
|
5806
|
+
if (fields.includes("trail"))
|
|
5807
|
+
trackTrail(entry, next);
|
|
5008
5808
|
if (fields.includes("follow")) {
|
|
5009
5809
|
entry.object.visible = next.follow === null;
|
|
5010
5810
|
if (next.follow === null) {
|
|
@@ -5040,6 +5840,34 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
5040
5840
|
entry.node = next;
|
|
5041
5841
|
return;
|
|
5042
5842
|
}
|
|
5843
|
+
if (entry._tag === "Points" && next._tag === "Points") {
|
|
5844
|
+
entry.node = next;
|
|
5845
|
+
if (movesTransform(entry, fields))
|
|
5846
|
+
retarget(entry, next);
|
|
5847
|
+
if (fields.includes("rotation"))
|
|
5848
|
+
trackRotation(entry, next);
|
|
5849
|
+
if (fields.includes("behaviour"))
|
|
5850
|
+
trackBehaviour(entry, next);
|
|
5851
|
+
if (fields.includes("look")) {
|
|
5852
|
+
entry.hosted?.update(next);
|
|
5853
|
+
trackSparkle(entry, next);
|
|
5854
|
+
}
|
|
5855
|
+
return;
|
|
5856
|
+
}
|
|
5857
|
+
if (entry._tag === "Line" && next._tag === "Line") {
|
|
5858
|
+
entry.node = next;
|
|
5859
|
+
if (movesTransform(entry, fields))
|
|
5860
|
+
retarget(entry, next);
|
|
5861
|
+
if (fields.includes("rotation"))
|
|
5862
|
+
trackRotation(entry, next);
|
|
5863
|
+
if (fields.includes("behaviour"))
|
|
5864
|
+
trackBehaviour(entry, next);
|
|
5865
|
+
if (fields.includes("interactive"))
|
|
5866
|
+
trackInteractive(entry.object, next.interactive);
|
|
5867
|
+
if (fields.includes("line"))
|
|
5868
|
+
entry.hosted?.update(next);
|
|
5869
|
+
return;
|
|
5870
|
+
}
|
|
5043
5871
|
if (entry._tag === "ShaderGrid" && next._tag === "ShaderGrid") {
|
|
5044
5872
|
entry.hosted?.update(entry.node, next);
|
|
5045
5873
|
entry.node = next;
|
|
@@ -5169,6 +5997,7 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
5169
5997
|
gestures: "page",
|
|
5170
5998
|
views: [],
|
|
5171
5999
|
renderTextures: [],
|
|
6000
|
+
hud: null,
|
|
5172
6001
|
overlays: [],
|
|
5173
6002
|
environment: null,
|
|
5174
6003
|
sky: null,
|
|
@@ -5176,10 +6005,67 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
5176
6005
|
physics: null,
|
|
5177
6006
|
xr: null,
|
|
5178
6007
|
measure: [],
|
|
6008
|
+
assets: [],
|
|
5179
6009
|
render: parent.render,
|
|
5180
6010
|
resources: parent.resources,
|
|
5181
6011
|
children: texture.children
|
|
5182
6012
|
});
|
|
6013
|
+
const hudCamera = (hud) => {
|
|
6014
|
+
const [marginX, marginY] = hud.margin;
|
|
6015
|
+
const [vertical, horizontal] = hud.alignment.split("-");
|
|
6016
|
+
const across = { left: -viewport.width / 2 + marginX, right: viewport.width / 2 - marginX };
|
|
6017
|
+
const up = { top: viewport.height / 2 - marginY, bottom: -viewport.height / 2 + marginY };
|
|
6018
|
+
const x = across[horizontal] ?? 0;
|
|
6019
|
+
const y = up[vertical] ?? 0;
|
|
6020
|
+
return orthographicCamera2({
|
|
6021
|
+
zoom: 1,
|
|
6022
|
+
near: 0.1,
|
|
6023
|
+
far: 2000,
|
|
6024
|
+
position: [-x, -y, 200],
|
|
6025
|
+
lookAt: [-x, -y, 0]
|
|
6026
|
+
});
|
|
6027
|
+
};
|
|
6028
|
+
const hudScene = (hud, parent) => textureScene({
|
|
6029
|
+
id: "hud",
|
|
6030
|
+
width: viewport.width,
|
|
6031
|
+
height: viewport.height,
|
|
6032
|
+
camera: hudCamera(hud),
|
|
6033
|
+
background: null,
|
|
6034
|
+
children: hud.children
|
|
6035
|
+
}, parent);
|
|
6036
|
+
const syncHud = (next) => {
|
|
6037
|
+
if (next.hud === null) {
|
|
6038
|
+
if (hudHosted === undefined)
|
|
6039
|
+
return [];
|
|
6040
|
+
hudHosted.graph.dispose();
|
|
6041
|
+
hudHosted = undefined;
|
|
6042
|
+
return [{ _tag: "RemoveHud" }];
|
|
6043
|
+
}
|
|
6044
|
+
const created = hudHosted === undefined;
|
|
6045
|
+
const hosted = hudHosted ?? {
|
|
6046
|
+
graph: createSceneGraph2({
|
|
6047
|
+
store,
|
|
6048
|
+
...options.behaviours === undefined ? {} : { behaviours: options.behaviours },
|
|
6049
|
+
...options.kit === undefined ? {} : { kit: options.kit }
|
|
6050
|
+
}),
|
|
6051
|
+
description: next.hud,
|
|
6052
|
+
parent: next
|
|
6053
|
+
};
|
|
6054
|
+
if (created)
|
|
6055
|
+
hosted.graph.resize(viewport.width, viewport.height);
|
|
6056
|
+
const result = hosted.graph.reconcile(hudScene(next.hud, next));
|
|
6057
|
+
hosted.description = next.hud;
|
|
6058
|
+
hosted.parent = next;
|
|
6059
|
+
hudHosted = hosted;
|
|
6060
|
+
const ops = result._tag === "Applied" ? result.ops : [];
|
|
6061
|
+
return created || ops.length > 0 ? [{ _tag: "UpdateHud", ops }] : [];
|
|
6062
|
+
};
|
|
6063
|
+
const refitHud = () => {
|
|
6064
|
+
if (hudHosted === undefined)
|
|
6065
|
+
return;
|
|
6066
|
+
hudHosted.graph.resize(viewport.width, viewport.height);
|
|
6067
|
+
hudHosted.graph.reconcile(hudScene(hudHosted.description, hudHosted.parent));
|
|
6068
|
+
};
|
|
5183
6069
|
function hostedTexture(texture) {
|
|
5184
6070
|
const hosted = textureGraphs.get(texture.id);
|
|
5185
6071
|
if (hosted === undefined)
|
|
@@ -5203,7 +6089,7 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
5203
6089
|
const reframed = existing === undefined || existing.description.width !== texture.width || existing.description.height !== texture.height || existing.description.background !== texture.background;
|
|
5204
6090
|
if (reframed) {
|
|
5205
6091
|
hosted.graph.resize(texture.width, texture.height);
|
|
5206
|
-
hosted.graph.scene.background = texture.background === null ? null : new
|
|
6092
|
+
hosted.graph.scene.background = texture.background === null ? null : new Color4(texture.background);
|
|
5207
6093
|
}
|
|
5208
6094
|
hosted.description = texture;
|
|
5209
6095
|
textureGraphs.set(texture.id, hosted);
|
|
@@ -5228,6 +6114,11 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
5228
6114
|
if (checked._tag === "Invalid")
|
|
5229
6115
|
return checked;
|
|
5230
6116
|
}
|
|
6117
|
+
if (next.hud !== null) {
|
|
6118
|
+
const checked = indexScene2(hudScene(next.hud, next), knownBehaviours);
|
|
6119
|
+
if (checked._tag === "Invalid")
|
|
6120
|
+
return checked;
|
|
6121
|
+
}
|
|
5231
6122
|
const result = diff2(index, next, knownBehaviours);
|
|
5232
6123
|
if (result._tag === "Invalid")
|
|
5233
6124
|
return result;
|
|
@@ -5258,11 +6149,13 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
5258
6149
|
invalidate();
|
|
5259
6150
|
physicsDescription = next.physics;
|
|
5260
6151
|
bodyHost.sync(next.physics, bodySources());
|
|
6152
|
+
if (bodyHost.owesSteps())
|
|
6153
|
+
invalidate();
|
|
5261
6154
|
xrDescription = next.xr;
|
|
5262
6155
|
if (next.measure.join("\x00") !== measured.join("\x00"))
|
|
5263
6156
|
invalidate();
|
|
5264
6157
|
measured = next.measure;
|
|
5265
|
-
const ops = [...result.ops, ...syncTextures(next)];
|
|
6158
|
+
const ops = [...result.ops, ...syncTextures(next), ...syncHud(next)];
|
|
5266
6159
|
if (ops.length > 0)
|
|
5267
6160
|
invalidate();
|
|
5268
6161
|
return { _tag: "Applied", ops };
|
|
@@ -5275,6 +6168,7 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
5275
6168
|
elapsed = elapsedSeconds;
|
|
5276
6169
|
for (const texture of textureList)
|
|
5277
6170
|
texture.graph.tick(elapsedSeconds);
|
|
6171
|
+
hudHosted?.graph.tick(elapsedSeconds);
|
|
5278
6172
|
for (const entry of spinning) {
|
|
5279
6173
|
if (isPlaced(entry)) {
|
|
5280
6174
|
writeRotation2(entry.object.rotation, entry.node.rotation, elapsed);
|
|
@@ -5292,7 +6186,14 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
5292
6186
|
bodyHost.tick(elapsed, animating);
|
|
5293
6187
|
if (facing.size > 0) {
|
|
5294
6188
|
camera.getWorldQuaternion(cameraTurn);
|
|
5295
|
-
|
|
6189
|
+
faceCameras();
|
|
6190
|
+
}
|
|
6191
|
+
edged.forEach(refreshEdges);
|
|
6192
|
+
if (animating)
|
|
6193
|
+
sparkling.forEach(sparkle);
|
|
6194
|
+
if (trailing.size > 0) {
|
|
6195
|
+
camera.getWorldPosition(eye);
|
|
6196
|
+
trailing.forEach(followTrail);
|
|
5296
6197
|
}
|
|
5297
6198
|
if (detailing.size > 0) {
|
|
5298
6199
|
camera.getWorldPosition(cameraPlace);
|
|
@@ -5307,6 +6208,7 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
5307
6208
|
invalidate();
|
|
5308
6209
|
for (const texture of textureList)
|
|
5309
6210
|
texture.graph.setAnimating(next);
|
|
6211
|
+
hudHosted?.graph.setAnimating(next);
|
|
5310
6212
|
animating = next;
|
|
5311
6213
|
if (next)
|
|
5312
6214
|
return;
|
|
@@ -5323,6 +6225,8 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
5323
6225
|
texture.graph.dispose();
|
|
5324
6226
|
textureGraphs.clear();
|
|
5325
6227
|
textureList = [];
|
|
6228
|
+
hudHosted?.graph.dispose();
|
|
6229
|
+
hudHosted = undefined;
|
|
5326
6230
|
for (const entry of entries.values()) {
|
|
5327
6231
|
entry.object.removeFromParent();
|
|
5328
6232
|
release(entry);
|
|
@@ -5355,12 +6259,14 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
5355
6259
|
return viewMotions.get(view)?.turned();
|
|
5356
6260
|
},
|
|
5357
6261
|
renderTextures: () => textureList,
|
|
6262
|
+
hud: () => hudHosted,
|
|
5358
6263
|
gestures: () => gestures,
|
|
5359
6264
|
overlays: () => overlayList,
|
|
5360
6265
|
environment: () => environmentDescription,
|
|
5361
6266
|
contactShadows: () => contactDescription,
|
|
5362
6267
|
collisions: bodyHost.drainCollisions,
|
|
5363
6268
|
contactForces: bodyHost.drainContactForces,
|
|
6269
|
+
physicsReached: bodyHost.drainReached,
|
|
5364
6270
|
xr: () => xrDescription,
|
|
5365
6271
|
measured: () => measured,
|
|
5366
6272
|
labelLayout: (key) => {
|
|
@@ -5383,7 +6289,7 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
5383
6289
|
tick,
|
|
5384
6290
|
elapsedSeconds: () => elapsed,
|
|
5385
6291
|
renderSettings: () => settings,
|
|
5386
|
-
needsFrame: () => dirty || textureList.some((texture) => texture.graph.needsFrame()) || animating && (spinning.size > 0 || moving.size > 0 || behaving.size > 0 || clipsRunning() || cameraMotion.moving() || viewsMoving() || shaking() || bodyHost.needsFrame()),
|
|
6292
|
+
needsFrame: () => dirty || trailsMoving() || textureList.some((texture) => texture.graph.needsFrame()) || (hudHosted?.graph.needsFrame() ?? false) || animating && (spinning.size > 0 || moving.size > 0 || behaving.size > 0 || clipsRunning() || cameraMotion.moving() || viewsMoving() || shaking() || sparkling.size > 0 || bodyHost.needsFrame()) || bodyHost.owesSteps(),
|
|
5387
6293
|
drawn: () => {
|
|
5388
6294
|
dirty = false;
|
|
5389
6295
|
},
|
|
@@ -5410,12 +6316,1937 @@ var createSceneGraph2 = (options = {}) => {
|
|
|
5410
6316
|
viewport = { width, height };
|
|
5411
6317
|
fitCamera(camera, viewport);
|
|
5412
6318
|
hostViews(viewDescriptions);
|
|
6319
|
+
refitHud();
|
|
5413
6320
|
invalidate();
|
|
5414
6321
|
},
|
|
5415
6322
|
dispose
|
|
5416
6323
|
};
|
|
5417
6324
|
};
|
|
5418
|
-
|
|
6325
|
+
// src/kernel/preview.ts
|
|
6326
|
+
import {
|
|
6327
|
+
Box2,
|
|
6328
|
+
Color as Color5,
|
|
6329
|
+
DirectionalLight as DirectionalLight2,
|
|
6330
|
+
HemisphereLight as HemisphereLight2,
|
|
6331
|
+
InstancedMesh as InstancedMesh2,
|
|
6332
|
+
LinearSRGBColorSpace,
|
|
6333
|
+
LineBasicMaterial as LineBasicMaterial2,
|
|
6334
|
+
LineDashedMaterial,
|
|
6335
|
+
Matrix3,
|
|
6336
|
+
Matrix4 as Matrix45,
|
|
6337
|
+
Mesh as Mesh3,
|
|
6338
|
+
MeshBasicMaterial as MeshBasicMaterial3,
|
|
6339
|
+
MeshLambertMaterial as MeshLambertMaterial2,
|
|
6340
|
+
MeshNormalMaterial as MeshNormalMaterial2,
|
|
6341
|
+
MeshPhongMaterial as MeshPhongMaterial2,
|
|
6342
|
+
MeshStandardMaterial as MeshStandardMaterial2,
|
|
6343
|
+
MeshToonMaterial,
|
|
6344
|
+
Light,
|
|
6345
|
+
Line,
|
|
6346
|
+
PointLight as PointLight2,
|
|
6347
|
+
Points,
|
|
6348
|
+
Scene as Scene2,
|
|
6349
|
+
Sprite,
|
|
6350
|
+
PointsMaterial,
|
|
6351
|
+
SpotLight as SpotLight2,
|
|
6352
|
+
SpriteMaterial,
|
|
6353
|
+
SRGBColorSpace,
|
|
6354
|
+
Vector2 as Vector24,
|
|
6355
|
+
Vector3 as Vector313,
|
|
6356
|
+
AmbientLight as AmbientLight2
|
|
6357
|
+
} from "three";
|
|
6358
|
+
import {
|
|
6359
|
+
Projector,
|
|
6360
|
+
RenderableFace,
|
|
6361
|
+
RenderableLine,
|
|
6362
|
+
RenderableSprite
|
|
6363
|
+
} from "three/addons/renderers/Projector.js";
|
|
6364
|
+
|
|
6365
|
+
// src/kernel/paintOrder.ts
|
|
6366
|
+
import { Sphere, Vector3 as Vector312 } from "three";
|
|
6367
|
+
var onPlane = 0.000001;
|
|
6368
|
+
var candidates = 8;
|
|
6369
|
+
var splitCost = 8;
|
|
6370
|
+
var planeOf = (points) => {
|
|
6371
|
+
const [a, b, c] = points;
|
|
6372
|
+
if (a === undefined || b === undefined || c === undefined)
|
|
6373
|
+
return;
|
|
6374
|
+
const normal = new Vector312().subVectors(b, a).cross(new Vector312().subVectors(c, a));
|
|
6375
|
+
if (normal.lengthSq() === 0)
|
|
6376
|
+
return;
|
|
6377
|
+
normal.normalize();
|
|
6378
|
+
return { normal, constant: normal.dot(a) };
|
|
6379
|
+
};
|
|
6380
|
+
var side = (plane, point) => plane.normal.dot(point) - plane.constant;
|
|
6381
|
+
var toleranceAt = (points) => onPlane * Math.max(1, ...points.map((point) => point.length()));
|
|
6382
|
+
var split = (plane, facet) => {
|
|
6383
|
+
const sides = facet.points.map((point) => side(plane, point));
|
|
6384
|
+
const tolerance = toleranceAt(facet.points);
|
|
6385
|
+
if (sides.every((s) => Math.abs(s) <= tolerance))
|
|
6386
|
+
return { on: facet };
|
|
6387
|
+
if (sides.every((s) => s >= -tolerance))
|
|
6388
|
+
return { front: facet };
|
|
6389
|
+
if (sides.every((s) => s <= tolerance))
|
|
6390
|
+
return { back: facet };
|
|
6391
|
+
const front = [];
|
|
6392
|
+
const back = [];
|
|
6393
|
+
facet.points.forEach((point, i) => {
|
|
6394
|
+
const next = facet.points[(i + 1) % facet.points.length] ?? point;
|
|
6395
|
+
const here = sides[i] ?? 0;
|
|
6396
|
+
const there = sides[(i + 1) % sides.length] ?? 0;
|
|
6397
|
+
if (here >= -tolerance)
|
|
6398
|
+
front.push(point);
|
|
6399
|
+
if (here <= tolerance)
|
|
6400
|
+
back.push(point);
|
|
6401
|
+
if (here > tolerance && there < -tolerance || here < -tolerance && there > tolerance) {
|
|
6402
|
+
const crossing = point.clone().lerp(next, here / (here - there));
|
|
6403
|
+
front.push(crossing);
|
|
6404
|
+
back.push(crossing.clone());
|
|
6405
|
+
}
|
|
6406
|
+
});
|
|
6407
|
+
return {
|
|
6408
|
+
...front.length >= 3 ? { front: { ...facet, points: front } } : {},
|
|
6409
|
+
...back.length >= 3 ? { back: { ...facet, points: back } } : {}
|
|
6410
|
+
};
|
|
6411
|
+
};
|
|
6412
|
+
function hidesNone(facet, facets, eye) {
|
|
6413
|
+
const plane = planeOf(facet.points);
|
|
6414
|
+
if (plane === undefined)
|
|
6415
|
+
return true;
|
|
6416
|
+
const tolerance = toleranceAt(facet.points);
|
|
6417
|
+
return side(plane, eye) > tolerance && facets.every((other) => other === facet || other.points.every((point) => side(plane, point) <= tolerance));
|
|
6418
|
+
}
|
|
6419
|
+
var unitOf = (facets, marks, eye) => {
|
|
6420
|
+
const points = [...facets.flatMap((facet) => facet.points), ...marks.map((mark) => mark.at)];
|
|
6421
|
+
const bounds = new Sphere().setFromPoints(points);
|
|
6422
|
+
const selfOrdered = facets.every((facet) => hidesNone(facet, facets, eye));
|
|
6423
|
+
return { facets, marks, bounds, selfOrdered };
|
|
6424
|
+
};
|
|
6425
|
+
var sizeOf = (unit) => unit.facets.length + unit.marks.length;
|
|
6426
|
+
var sideOf = (plane, unit) => {
|
|
6427
|
+
const distance = side(plane, unit.bounds.center);
|
|
6428
|
+
const reach = unit.bounds.radius * (1 + onPlane) + onPlane;
|
|
6429
|
+
return distance > reach ? 1 : distance < -reach ? -1 : 0;
|
|
6430
|
+
};
|
|
6431
|
+
var weigh = (plane, units) => {
|
|
6432
|
+
let cut = 0;
|
|
6433
|
+
let front = 0;
|
|
6434
|
+
let back = 0;
|
|
6435
|
+
for (const unit of units) {
|
|
6436
|
+
const whole = sideOf(plane, unit);
|
|
6437
|
+
if (whole > 0)
|
|
6438
|
+
front += sizeOf(unit);
|
|
6439
|
+
else if (whole < 0)
|
|
6440
|
+
back += sizeOf(unit);
|
|
6441
|
+
else {
|
|
6442
|
+
const parts = unit.facets.map((facet) => split(plane, facet));
|
|
6443
|
+
const ahead = parts.filter((part) => part.front !== undefined).length;
|
|
6444
|
+
const behind = parts.filter((part) => part.back !== undefined).length;
|
|
6445
|
+
if (ahead > 0 && behind > 0)
|
|
6446
|
+
cut++;
|
|
6447
|
+
front += ahead;
|
|
6448
|
+
back += behind;
|
|
6449
|
+
}
|
|
6450
|
+
}
|
|
6451
|
+
return splitCost * cut + Math.abs(front - back);
|
|
6452
|
+
};
|
|
6453
|
+
var partition = (plane, units) => {
|
|
6454
|
+
const front = [];
|
|
6455
|
+
const back = [];
|
|
6456
|
+
const on = [];
|
|
6457
|
+
for (const unit of units) {
|
|
6458
|
+
const whole = sideOf(plane, unit);
|
|
6459
|
+
if (whole > 0)
|
|
6460
|
+
front.push(unit);
|
|
6461
|
+
else if (whole < 0)
|
|
6462
|
+
back.push(unit);
|
|
6463
|
+
else {
|
|
6464
|
+
const ahead = [];
|
|
6465
|
+
const behind = [];
|
|
6466
|
+
for (const facet of unit.facets) {
|
|
6467
|
+
const parts = split(plane, facet);
|
|
6468
|
+
if (parts.front !== undefined)
|
|
6469
|
+
ahead.push(parts.front);
|
|
6470
|
+
if (parts.back !== undefined)
|
|
6471
|
+
behind.push(parts.back);
|
|
6472
|
+
if (parts.on !== undefined)
|
|
6473
|
+
on.push(parts.on);
|
|
6474
|
+
}
|
|
6475
|
+
const marksAhead = unit.marks.filter((mark) => side(plane, mark.at) >= 0);
|
|
6476
|
+
const marksBehind = unit.marks.filter((mark) => side(plane, mark.at) < 0);
|
|
6477
|
+
if (ahead.length + marksAhead.length > 0)
|
|
6478
|
+
front.push({ ...unit, facets: ahead, marks: marksAhead });
|
|
6479
|
+
if (behind.length + marksBehind.length > 0)
|
|
6480
|
+
back.push({ ...unit, facets: behind, marks: marksBehind });
|
|
6481
|
+
}
|
|
6482
|
+
}
|
|
6483
|
+
return { front, back, on };
|
|
6484
|
+
};
|
|
6485
|
+
var planeFor = (units) => {
|
|
6486
|
+
const withFacets = units.filter((unit) => unit.facets.length > 0);
|
|
6487
|
+
const count = Math.min(candidates, withFacets.length);
|
|
6488
|
+
let best;
|
|
6489
|
+
let lightest = Number.POSITIVE_INFINITY;
|
|
6490
|
+
for (let i = 0;i < count; i++) {
|
|
6491
|
+
const unit = withFacets[Math.floor(i * withFacets.length / count)];
|
|
6492
|
+
const facet = unit?.facets[Math.floor(i * (unit?.facets.length ?? 0) / count)];
|
|
6493
|
+
const plane = facet === undefined ? undefined : planeOf(facet.points);
|
|
6494
|
+
if (plane === undefined)
|
|
6495
|
+
continue;
|
|
6496
|
+
const weight = weigh(plane, units);
|
|
6497
|
+
if (weight < lightest) {
|
|
6498
|
+
lightest = weight;
|
|
6499
|
+
best = plane;
|
|
6500
|
+
}
|
|
6501
|
+
}
|
|
6502
|
+
if (best !== undefined)
|
|
6503
|
+
return best;
|
|
6504
|
+
for (const unit of withFacets) {
|
|
6505
|
+
for (const facet of unit.facets) {
|
|
6506
|
+
const plane = planeOf(facet.points);
|
|
6507
|
+
if (plane !== undefined)
|
|
6508
|
+
return plane;
|
|
6509
|
+
}
|
|
6510
|
+
}
|
|
6511
|
+
return;
|
|
6512
|
+
};
|
|
6513
|
+
var distanceFrom = (eye) => (mark) => mark.at.distanceToSquared(eye);
|
|
6514
|
+
var apart = (unit) => [
|
|
6515
|
+
...unit.facets.map((facet) => ({
|
|
6516
|
+
facets: [facet],
|
|
6517
|
+
marks: [],
|
|
6518
|
+
bounds: new Sphere().setFromPoints([...facet.points]),
|
|
6519
|
+
selfOrdered: true
|
|
6520
|
+
})),
|
|
6521
|
+
...unit.marks.map((mark) => ({
|
|
6522
|
+
facets: [],
|
|
6523
|
+
marks: [mark],
|
|
6524
|
+
bounds: new Sphere(mark.at.clone(), 0),
|
|
6525
|
+
selfOrdered: true
|
|
6526
|
+
}))
|
|
6527
|
+
];
|
|
6528
|
+
var paint = (units, eye, into) => {
|
|
6529
|
+
const [only] = units;
|
|
6530
|
+
if (only !== undefined && units.length === 1) {
|
|
6531
|
+
if (only.selfOrdered && only.marks.length === 0) {
|
|
6532
|
+
into.push(...only.facets);
|
|
6533
|
+
return;
|
|
6534
|
+
}
|
|
6535
|
+
if (only.facets.length === 0) {
|
|
6536
|
+
into.push(...only.marks.toSorted((a, b) => distanceFrom(eye)(b) - distanceFrom(eye)(a)));
|
|
6537
|
+
return;
|
|
6538
|
+
}
|
|
6539
|
+
paint(apart(only), eye, into);
|
|
6540
|
+
return;
|
|
6541
|
+
}
|
|
6542
|
+
const plane = planeFor(units);
|
|
6543
|
+
if (plane === undefined) {
|
|
6544
|
+
const marks = units.flatMap((unit) => unit.marks);
|
|
6545
|
+
into.push(...marks.toSorted((a, b) => distanceFrom(eye)(b) - distanceFrom(eye)(a)));
|
|
6546
|
+
return;
|
|
6547
|
+
}
|
|
6548
|
+
const { front, back, on } = partition(plane, units);
|
|
6549
|
+
const facing = side(plane, eye) >= 0;
|
|
6550
|
+
paint(facing ? back : front, eye, into);
|
|
6551
|
+
into.push(...on);
|
|
6552
|
+
paint(facing ? front : back, eye, into);
|
|
6553
|
+
};
|
|
6554
|
+
var paintOrder = (units, eye) => {
|
|
6555
|
+
const into = [];
|
|
6556
|
+
paint(units, eye, into);
|
|
6557
|
+
return into;
|
|
6558
|
+
};
|
|
6559
|
+
|
|
6560
|
+
// src/kernel/preview.ts
|
|
6561
|
+
var overdraw = 0.5;
|
|
6562
|
+
var black = new Color5(0, 0, 0);
|
|
6563
|
+
var irradianceAt = (lights, position, normal, into) => {
|
|
6564
|
+
into.copy(black);
|
|
6565
|
+
const lightPosition = new Vector313;
|
|
6566
|
+
const toLight = new Vector313;
|
|
6567
|
+
const direction = new Vector313;
|
|
6568
|
+
for (const light of lights) {
|
|
6569
|
+
const color = light.color.clone().multiplyScalar(light.intensity);
|
|
6570
|
+
if (light instanceof AmbientLight2) {
|
|
6571
|
+
into.add(color);
|
|
6572
|
+
} else if (light instanceof HemisphereLight2) {
|
|
6573
|
+
lightPosition.setFromMatrixPosition(light.matrixWorld).normalize();
|
|
6574
|
+
const weight = 0.5 * normal.dot(lightPosition) + 0.5;
|
|
6575
|
+
into.add(light.groundColor.clone().lerp(light.color, weight).multiplyScalar(light.intensity));
|
|
6576
|
+
} else if (light instanceof DirectionalLight2) {
|
|
6577
|
+
lightPosition.setFromMatrixPosition(light.matrixWorld);
|
|
6578
|
+
direction.setFromMatrixPosition(light.target.matrixWorld);
|
|
6579
|
+
toLight.subVectors(lightPosition, direction).normalize();
|
|
6580
|
+
into.add(color.multiplyScalar(Math.max(normal.dot(toLight), 0)));
|
|
6581
|
+
} else if (light instanceof PointLight2 || light instanceof SpotLight2) {
|
|
6582
|
+
lightPosition.setFromMatrixPosition(light.matrixWorld);
|
|
6583
|
+
toLight.subVectors(lightPosition, position);
|
|
6584
|
+
const distance = toLight.length();
|
|
6585
|
+
toLight.normalize();
|
|
6586
|
+
const cone = light instanceof SpotLight2 ? spotAttenuation(light, toLight) : 1;
|
|
6587
|
+
const falloff = distanceAttenuation(distance, light.distance, light.decay);
|
|
6588
|
+
into.add(color.multiplyScalar(Math.max(normal.dot(toLight), 0) * cone * falloff));
|
|
6589
|
+
}
|
|
6590
|
+
}
|
|
6591
|
+
return into;
|
|
6592
|
+
};
|
|
6593
|
+
var distanceAttenuation = (distance, cutoff, decay) => {
|
|
6594
|
+
const falloff = 1 / Math.max(distance ** decay, 0.01);
|
|
6595
|
+
return cutoff > 0 ? falloff * Math.min(Math.max(1 - (distance / cutoff) ** 4, 0), 1) ** 2 : falloff;
|
|
6596
|
+
};
|
|
6597
|
+
var smoothstep = (low, high, x) => {
|
|
6598
|
+
const t = Math.min(Math.max((x - low) / (high - low), 0), 1);
|
|
6599
|
+
return t * t * (3 - 2 * t);
|
|
6600
|
+
};
|
|
6601
|
+
var spotAttenuation = (light, toLight) => {
|
|
6602
|
+
const direction = new Vector313().setFromMatrixPosition(light.matrixWorld).sub(new Vector313().setFromMatrixPosition(light.target.matrixWorld)).normalize();
|
|
6603
|
+
return smoothstep(Math.cos(light.angle), Math.cos(light.angle * (1 - light.penumbra)), direction.dot(toLight));
|
|
6604
|
+
};
|
|
6605
|
+
var faceColor = (painter, face, material, centre) => {
|
|
6606
|
+
if (material instanceof MeshBasicMaterial3) {
|
|
6607
|
+
const color = material.color.clone();
|
|
6608
|
+
return material.vertexColors ? color.multiply(face.color) : color;
|
|
6609
|
+
}
|
|
6610
|
+
if (material instanceof MeshNormalMaterial2) {
|
|
6611
|
+
const normal = face.normalModel.clone().applyMatrix3(painter.normalView).normalize();
|
|
6612
|
+
return new Color5(normal.x, normal.y, normal.z).multiplyScalar(0.5).addScalar(0.5);
|
|
6613
|
+
}
|
|
6614
|
+
if (material instanceof MeshLambertMaterial2 || material instanceof MeshPhongMaterial2 || material instanceof MeshStandardMaterial2 || material instanceof MeshToonMaterial) {
|
|
6615
|
+
const diffuse = material.color.clone();
|
|
6616
|
+
if (material.vertexColors)
|
|
6617
|
+
diffuse.multiply(face.color);
|
|
6618
|
+
return irradianceAt(painter.lights, centre, face.normalModel, new Color5).multiply(diffuse).multiplyScalar(1 / Math.PI).add(material.emissive.clone().multiplyScalar(material.emissiveIntensity));
|
|
6619
|
+
}
|
|
6620
|
+
return;
|
|
6621
|
+
};
|
|
6622
|
+
var styleOf = (color, colorSpace) => {
|
|
6623
|
+
const shown = new Color5(Math.min(Math.max(color.r, 0), 1), Math.min(Math.max(color.g, 0), 1), Math.min(Math.max(color.b, 0), 1));
|
|
6624
|
+
return `#${shown.getHexString(colorSpace)}`;
|
|
6625
|
+
};
|
|
6626
|
+
var opacityOf = (material) => material.transparent ? material.opacity : 1;
|
|
6627
|
+
var standInsFor = (object) => {
|
|
6628
|
+
if (!(object instanceof InstancedMesh2)) {
|
|
6629
|
+
const standIn = object.clone(false);
|
|
6630
|
+
standIn.matrix.copy(object.matrixWorld);
|
|
6631
|
+
return [{ standIn }];
|
|
6632
|
+
}
|
|
6633
|
+
const material = Array.isArray(object.material) ? object.material[0] : object.material;
|
|
6634
|
+
if (material === undefined)
|
|
6635
|
+
return [];
|
|
6636
|
+
const matrix = new Matrix45;
|
|
6637
|
+
const standIns = [];
|
|
6638
|
+
for (let i = 0;i < object.count; i++) {
|
|
6639
|
+
object.getMatrixAt(i, matrix);
|
|
6640
|
+
const tinted = object.instanceColor === null ? undefined : material.clone();
|
|
6641
|
+
if (tinted !== undefined && "color" in tinted && tinted.color instanceof Color5) {
|
|
6642
|
+
tinted.color.multiply(object.getColorAt(i, new Color5));
|
|
6643
|
+
}
|
|
6644
|
+
const standIn = new Mesh3(object.geometry, tinted ?? material);
|
|
6645
|
+
standIn.matrix.multiplyMatrices(object.matrixWorld, matrix);
|
|
6646
|
+
standIn.renderOrder = object.renderOrder;
|
|
6647
|
+
standIns.push(tinted === undefined ? { standIn } : { standIn, tinted });
|
|
6648
|
+
}
|
|
6649
|
+
return standIns;
|
|
6650
|
+
};
|
|
6651
|
+
var number = (precision) => (value) => String(Number(value.toFixed(precision)));
|
|
6652
|
+
var widened = (points) => {
|
|
6653
|
+
const out = points.map((point) => point.clone());
|
|
6654
|
+
for (const [i, from] of out.entries()) {
|
|
6655
|
+
const to = out[(i + 1) % out.length];
|
|
6656
|
+
const length = to === undefined ? 0 : from.distanceTo(to);
|
|
6657
|
+
if (to === undefined || length === 0)
|
|
6658
|
+
continue;
|
|
6659
|
+
const step = new Vector24().subVectors(to, from).multiplyScalar(overdraw / length);
|
|
6660
|
+
to.add(step);
|
|
6661
|
+
from.sub(step);
|
|
6662
|
+
}
|
|
6663
|
+
return out;
|
|
6664
|
+
};
|
|
6665
|
+
var facetPaint = (fill, opacity) => opacity < 1 ? `fill="${fill}" fill-opacity="${String(Number(opacity.toFixed(2)))}"` : `fill="${fill}" stroke="${fill}"`;
|
|
6666
|
+
var centreOf2 = (object) => {
|
|
6667
|
+
if (!(object instanceof Mesh3))
|
|
6668
|
+
return new Vector313().setFromMatrixPosition(object.matrixWorld);
|
|
6669
|
+
const geometry = object.geometry;
|
|
6670
|
+
if (geometry.boundingSphere === null)
|
|
6671
|
+
geometry.computeBoundingSphere();
|
|
6672
|
+
return (geometry.boundingSphere?.center.clone() ?? new Vector313).applyMatrix4(object.matrixWorld);
|
|
6673
|
+
};
|
|
6674
|
+
var isDrawn = (object) => object instanceof Mesh3 || object instanceof Line || object instanceof Points || object instanceof Sprite;
|
|
6675
|
+
var previewSvg2 = (description, options) => {
|
|
6676
|
+
const { width, height } = options;
|
|
6677
|
+
const graph = createSceneGraph2({
|
|
6678
|
+
...options.store === undefined ? {} : { store: options.store },
|
|
6679
|
+
...options.behaviours === undefined ? {} : { behaviours: options.behaviours }
|
|
6680
|
+
});
|
|
6681
|
+
const applied = graph.reconcile(description);
|
|
6682
|
+
if (applied._tag === "Invalid") {
|
|
6683
|
+
graph.dispose();
|
|
6684
|
+
return applied;
|
|
6685
|
+
}
|
|
6686
|
+
graph.resize(width, height);
|
|
6687
|
+
graph.tick(options.at ?? 0);
|
|
6688
|
+
const { scene, camera } = graph;
|
|
6689
|
+
scene.updateMatrixWorld();
|
|
6690
|
+
camera.updateMatrixWorld();
|
|
6691
|
+
const lights = [];
|
|
6692
|
+
const drawn = [];
|
|
6693
|
+
scene.traverseVisible((object) => {
|
|
6694
|
+
if (object instanceof Light)
|
|
6695
|
+
lights.push(object);
|
|
6696
|
+
else if (isDrawn(object))
|
|
6697
|
+
drawn.push(object);
|
|
6698
|
+
});
|
|
6699
|
+
const colorSpace = graph.renderSettings().colorSpace === "linear" ? LinearSRGBColorSpace : SRGBColorSpace;
|
|
6700
|
+
const painter = {
|
|
6701
|
+
lights,
|
|
6702
|
+
normalView: new Matrix3().getNormalMatrix(camera.matrixWorldInverse),
|
|
6703
|
+
colorSpace
|
|
6704
|
+
};
|
|
6705
|
+
const halfWidth = width / 2;
|
|
6706
|
+
const halfHeight = height / 2;
|
|
6707
|
+
const at = number(options.precision ?? 1);
|
|
6708
|
+
const eye = new Vector313().setFromMatrixPosition(camera.matrixWorld);
|
|
6709
|
+
const ahead = camera.getWorldDirection(new Vector313);
|
|
6710
|
+
const near = { normal: ahead, constant: ahead.dot(eye) + camera.near };
|
|
6711
|
+
const xy = (x, y) => `${at(x * halfWidth)},${at(-y * halfHeight)}`;
|
|
6712
|
+
function facetOf(face, material, centre, opacity) {
|
|
6713
|
+
const color = faceColor(painter, face, material, centre);
|
|
6714
|
+
if (color === undefined)
|
|
6715
|
+
return;
|
|
6716
|
+
const points = [face.v1, face.v2, face.v3].map((vertex) => vertex.positionWorld.clone());
|
|
6717
|
+
const paint = facetPaint(styleOf(color, colorSpace), opacity);
|
|
6718
|
+
return split(near, { _tag: "Facet", points, item: { paint, d: "" } }).front;
|
|
6719
|
+
}
|
|
6720
|
+
const projector = new Projector;
|
|
6721
|
+
const holder = new Scene2;
|
|
6722
|
+
const units = [];
|
|
6723
|
+
const over = [];
|
|
6724
|
+
const tinted = [];
|
|
6725
|
+
for (const object of drawn) {
|
|
6726
|
+
for (const { standIn, tinted: copy } of standInsFor(object)) {
|
|
6727
|
+
if (copy !== undefined)
|
|
6728
|
+
tinted.push(copy);
|
|
6729
|
+
standIn.matrixAutoUpdate = false;
|
|
6730
|
+
holder.add(standIn);
|
|
6731
|
+
const projected = projector.projectScene(holder, camera, false, true);
|
|
6732
|
+
holder.remove(standIn);
|
|
6733
|
+
const centre = centreOf2(standIn);
|
|
6734
|
+
const facets = [];
|
|
6735
|
+
const marks = [];
|
|
6736
|
+
const keep = (material, item) => {
|
|
6737
|
+
if (!material.depthTest)
|
|
6738
|
+
over.push({ renderOrder: standIn.renderOrder, item });
|
|
6739
|
+
else if (item._tag === "Facet")
|
|
6740
|
+
facets.push(item);
|
|
6741
|
+
else
|
|
6742
|
+
marks.push(item);
|
|
6743
|
+
};
|
|
6744
|
+
for (const element of projected.elements) {
|
|
6745
|
+
const material = element.material;
|
|
6746
|
+
if (material === null || material.opacity === 0)
|
|
6747
|
+
continue;
|
|
6748
|
+
const opacity = opacityOf(material);
|
|
6749
|
+
const faded = opacity < 1 ? ` fill-opacity="${at(opacity)}"` : "";
|
|
6750
|
+
if (element instanceof RenderableFace) {
|
|
6751
|
+
const seen = facetOf(element, material, centre, opacity);
|
|
6752
|
+
if (seen === undefined)
|
|
6753
|
+
continue;
|
|
6754
|
+
keep(material, seen);
|
|
6755
|
+
} else if (element instanceof RenderableLine && material instanceof LineBasicMaterial2) {
|
|
6756
|
+
const a = element.v1.positionScreen;
|
|
6757
|
+
const b = element.v2.positionScreen;
|
|
6758
|
+
const dashes = material instanceof LineDashedMaterial ? ` stroke-dasharray="${at(material.dashSize)},${at(material.gapSize)}"` : "";
|
|
6759
|
+
const stroked = opacity < 1 ? ` stroke-opacity="${at(opacity)}"` : "";
|
|
6760
|
+
keep(material, {
|
|
6761
|
+
_tag: "Mark",
|
|
6762
|
+
at: element.v1.positionWorld.clone().lerp(element.v2.positionWorld, 0.5),
|
|
6763
|
+
item: {
|
|
6764
|
+
paint: `fill="none" stroke="${styleOf(material.color, colorSpace)}"${stroked} stroke-width="${at(material.linewidth)}" stroke-linecap="${material.linecap}"${dashes}`,
|
|
6765
|
+
d: `M${xy(a.x, a.y)}L${xy(b.x, b.y)}`
|
|
6766
|
+
}
|
|
6767
|
+
});
|
|
6768
|
+
} else if (element instanceof RenderableSprite && (material instanceof SpriteMaterial || material instanceof PointsMaterial)) {
|
|
6769
|
+
const size = material instanceof PointsMaterial ? material.size : 1;
|
|
6770
|
+
const w = element.scale.x * halfWidth * size;
|
|
6771
|
+
const h = element.scale.y * halfHeight * size;
|
|
6772
|
+
const x = element.x * halfWidth;
|
|
6773
|
+
const y = -element.y * halfHeight;
|
|
6774
|
+
keep(material, {
|
|
6775
|
+
_tag: "Mark",
|
|
6776
|
+
at: new Vector313(element.x, element.y, element.z).unproject(camera),
|
|
6777
|
+
item: {
|
|
6778
|
+
paint: `fill="${styleOf(material.color, colorSpace)}"${faded}`,
|
|
6779
|
+
d: `M${at(x - w / 2)},${at(y - h / 2)}h${at(w)}v${at(h)}h${at(-w)}z`
|
|
6780
|
+
}
|
|
6781
|
+
});
|
|
6782
|
+
}
|
|
6783
|
+
}
|
|
6784
|
+
if (facets.length + marks.length > 0)
|
|
6785
|
+
units.push(unitOf(facets, marks, eye));
|
|
6786
|
+
}
|
|
6787
|
+
}
|
|
6788
|
+
for (const material of tinted)
|
|
6789
|
+
material.dispose();
|
|
6790
|
+
graph.dispose();
|
|
6791
|
+
const ordered = [
|
|
6792
|
+
...paintOrder(units, eye),
|
|
6793
|
+
...over.toSorted((a, b) => a.renderOrder - b.renderOrder).map(({ item }) => item)
|
|
6794
|
+
];
|
|
6795
|
+
const clip = new Box2(new Vector24(-halfWidth, -halfHeight), new Vector24(halfWidth, halfHeight));
|
|
6796
|
+
const toPicture = (point) => {
|
|
6797
|
+
const projectedPoint = point.clone().project(camera);
|
|
6798
|
+
return new Vector24(projectedPoint.x * halfWidth, -projectedPoint.y * halfHeight);
|
|
6799
|
+
};
|
|
6800
|
+
function outlineOf(shape) {
|
|
6801
|
+
if (shape._tag === "Mark")
|
|
6802
|
+
return shape.item.d;
|
|
6803
|
+
const corners = widened(shape.points.map(toPicture));
|
|
6804
|
+
return new Box2().setFromPoints([...corners]).intersectsBox(clip) ? `M${corners.map((corner) => `${at(corner.x)},${at(corner.y)}`).join("L")}z` : undefined;
|
|
6805
|
+
}
|
|
6806
|
+
const groups = [];
|
|
6807
|
+
for (const shape of ordered) {
|
|
6808
|
+
const outline = outlineOf(shape);
|
|
6809
|
+
const last = groups.at(-1);
|
|
6810
|
+
if (outline === undefined)
|
|
6811
|
+
continue;
|
|
6812
|
+
if (last?.paint === shape.item.paint)
|
|
6813
|
+
last.outlines.push(outline);
|
|
6814
|
+
else
|
|
6815
|
+
groups.push({ paint: shape.item.paint, outlines: [outline] });
|
|
6816
|
+
}
|
|
6817
|
+
const paths = groups.map(({ paint, outlines }) => `<path ${paint} d="${outlines.join("")}"/>`);
|
|
6818
|
+
const background = options.background === undefined || options.background === null ? "" : `<rect x="${at(-halfWidth)}" y="${at(-halfHeight)}" width="${at(width)}" height="${at(height)}" fill="${styleOf(new Color5(options.background), colorSpace)}"/>`;
|
|
6819
|
+
return {
|
|
6820
|
+
_tag: "Preview",
|
|
6821
|
+
svg: `<svg xmlns="http://www.w3.org/2000/svg" width="${at(width)}" height="${at(height)}" viewBox="${at(-halfWidth)} ${at(-halfHeight)} ${at(width)} ${at(height)}">${background}<g stroke-width="0.6" stroke-linejoin="round">${paths.join("")}</g></svg>`
|
|
6822
|
+
};
|
|
6823
|
+
};
|
|
6824
|
+
// src/kernel/gizmo.ts
|
|
6825
|
+
import { Euler as Euler6, Quaternion as Quaternion7, Vector3 as Vector314 } from "three";
|
|
6826
|
+
var gizmo2 = (options = {}) => ({
|
|
6827
|
+
mode: options.mode ?? "translate",
|
|
6828
|
+
space: options.space ?? "world",
|
|
6829
|
+
size: options.size ?? 1,
|
|
6830
|
+
translationSnap: options.translationSnap ?? null,
|
|
6831
|
+
rotationSnap: options.rotationSnap ?? null,
|
|
6832
|
+
scaleSnap: options.scaleSnap ?? null,
|
|
6833
|
+
showX: options.showX ?? true,
|
|
6834
|
+
showY: options.showY ?? true,
|
|
6835
|
+
showZ: options.showZ ?? true,
|
|
6836
|
+
hovered: null,
|
|
6837
|
+
grab: null
|
|
6838
|
+
});
|
|
6839
|
+
var axes = {
|
|
6840
|
+
x: new Vector314(1, 0, 0),
|
|
6841
|
+
y: new Vector314(0, 1, 0),
|
|
6842
|
+
z: new Vector314(0, 0, 1)
|
|
6843
|
+
};
|
|
6844
|
+
var turnOf = (rotation) => new Quaternion7().setFromEuler(new Euler6(rotation[0], rotation[1], rotation[2]));
|
|
6845
|
+
var spaceOf = (state, handle) => {
|
|
6846
|
+
if (state.mode === "scale")
|
|
6847
|
+
return "local";
|
|
6848
|
+
if (handle === "xyz")
|
|
6849
|
+
return "world";
|
|
6850
|
+
return state.space;
|
|
6851
|
+
};
|
|
6852
|
+
var axisIn = (name, space, rotation) => space === "local" ? axes[name].clone().applyQuaternion(turnOf(rotation)) : axes[name].clone();
|
|
6853
|
+
var toVec34 = (vector) => [vector.x, vector.y, vector.z];
|
|
6854
|
+
var dragPlane = (state, handle, start, eye, facingCamera) => {
|
|
6855
|
+
const space = spaceOf(state, handle);
|
|
6856
|
+
const along = (name) => axisIn(name, space, start.rotation);
|
|
6857
|
+
const facing = (axis) => axis.clone().cross(eye.clone().cross(axis));
|
|
6858
|
+
const normals = {
|
|
6859
|
+
x: () => facing(along("x")),
|
|
6860
|
+
y: () => facing(along("y")),
|
|
6861
|
+
z: () => facing(along("z")),
|
|
6862
|
+
xy: () => along("z"),
|
|
6863
|
+
yz: () => along("x"),
|
|
6864
|
+
xz: () => along("y"),
|
|
6865
|
+
xyz: () => facingCamera.clone()
|
|
6866
|
+
};
|
|
6867
|
+
const normal = state.mode === "rotate" ? facingCamera.clone() : normals[handle]();
|
|
6868
|
+
if (normal.lengthSq() < 0.000000000001)
|
|
6869
|
+
normal.copy(eye);
|
|
6870
|
+
normal.normalize();
|
|
6871
|
+
const center = new Vector314(...start.position);
|
|
6872
|
+
return { normal: toVec34(normal), constant: -normal.dot(center) };
|
|
6873
|
+
};
|
|
6874
|
+
var onPlane2 = (grab, ray) => {
|
|
6875
|
+
const point = pointOnPlane2(ray, grab.plane);
|
|
6876
|
+
if (point === undefined)
|
|
6877
|
+
return;
|
|
6878
|
+
return new Vector314(...point).sub(new Vector314(...grab.start.position));
|
|
6879
|
+
};
|
|
6880
|
+
var backwards = (camera) => {
|
|
6881
|
+
const back = new Vector314(...camera.position).sub(new Vector314(...camera.lookAt));
|
|
6882
|
+
return back.lengthSq() > 0.000000000001 ? back.normalize() : new Vector314(0, 0, 1);
|
|
6883
|
+
};
|
|
6884
|
+
var pressGizmo2 = (state, placement, handle, ray, camera) => {
|
|
6885
|
+
const center = new Vector314(...placement.position);
|
|
6886
|
+
const facingCamera = backwards(camera);
|
|
6887
|
+
const towardsEye = new Vector314(...camera.position).sub(center);
|
|
6888
|
+
const distance = towardsEye.length();
|
|
6889
|
+
const eye = camera._tag === "Orthographic" || distance < 0.000000001 ? facingCamera.clone() : towardsEye.normalize();
|
|
6890
|
+
const plane = dragPlane(state, handle, placement, eye, facingCamera);
|
|
6891
|
+
const point = pointOnPlane2(ray, plane);
|
|
6892
|
+
if (point === undefined)
|
|
6893
|
+
return state;
|
|
6894
|
+
const from = toVec34(new Vector314(...point).sub(center));
|
|
6895
|
+
return { ...state, grab: { handle, start: placement, from, plane, eye: toVec34(eye), distance } };
|
|
6896
|
+
};
|
|
6897
|
+
var releaseGizmo2 = (state) => ({ ...state, grab: null });
|
|
6898
|
+
var hoverGizmo2 = (state, handle) => state.hovered === handle ? state : { ...state, hovered: handle };
|
|
6899
|
+
var snapped = (value, step) => step === null ? value : Math.round(value / step) * step;
|
|
6900
|
+
var includes = (handle, axis) => handle.includes(axis);
|
|
6901
|
+
var translated = (state, grab, end) => {
|
|
6902
|
+
const space = spaceOf(state, grab.handle);
|
|
6903
|
+
const offset = end.clone().sub(new Vector314(...grab.from));
|
|
6904
|
+
const turn = turnOf(grab.start.rotation);
|
|
6905
|
+
if (space === "local")
|
|
6906
|
+
offset.applyQuaternion(turn.clone().invert());
|
|
6907
|
+
if (!includes(grab.handle, "x"))
|
|
6908
|
+
offset.x = 0;
|
|
6909
|
+
if (!includes(grab.handle, "y"))
|
|
6910
|
+
offset.y = 0;
|
|
6911
|
+
if (!includes(grab.handle, "z"))
|
|
6912
|
+
offset.z = 0;
|
|
6913
|
+
if (space === "local") {
|
|
6914
|
+
const local = offset.add(new Vector314(...grab.start.position).applyQuaternion(turn.clone().invert()));
|
|
6915
|
+
if (includes(grab.handle, "x"))
|
|
6916
|
+
local.x = snapped(local.x, state.translationSnap);
|
|
6917
|
+
if (includes(grab.handle, "y"))
|
|
6918
|
+
local.y = snapped(local.y, state.translationSnap);
|
|
6919
|
+
if (includes(grab.handle, "z"))
|
|
6920
|
+
local.z = snapped(local.z, state.translationSnap);
|
|
6921
|
+
return { ...grab.start, position: toVec34(local.applyQuaternion(turn)) };
|
|
6922
|
+
}
|
|
6923
|
+
const position = offset.add(new Vector314(...grab.start.position));
|
|
6924
|
+
if (includes(grab.handle, "x"))
|
|
6925
|
+
position.x = snapped(position.x, state.translationSnap);
|
|
6926
|
+
if (includes(grab.handle, "y"))
|
|
6927
|
+
position.y = snapped(position.y, state.translationSnap);
|
|
6928
|
+
if (includes(grab.handle, "z"))
|
|
6929
|
+
position.z = snapped(position.z, state.translationSnap);
|
|
6930
|
+
return { ...grab.start, position: toVec34(position) };
|
|
6931
|
+
};
|
|
6932
|
+
var scaled2 = (state, grab, end) => {
|
|
6933
|
+
const from = new Vector314(...grab.from);
|
|
6934
|
+
const factor = new Vector314(1, 1, 1);
|
|
6935
|
+
if (grab.handle === "xyz") {
|
|
6936
|
+
const ratio = end.length() / Math.max(from.length(), 0.000000001) * (end.dot(from) < 0 ? -1 : 1);
|
|
6937
|
+
factor.setScalar(ratio);
|
|
6938
|
+
} else {
|
|
6939
|
+
const inverse = turnOf(grab.start.rotation).invert();
|
|
6940
|
+
const a = from.clone().applyQuaternion(inverse);
|
|
6941
|
+
const b = end.clone().applyQuaternion(inverse);
|
|
6942
|
+
factor.set(includes(grab.handle, "x") ? b.x / a.x : 1, includes(grab.handle, "y") ? b.y / a.y : 1, includes(grab.handle, "z") ? b.z / a.z : 1);
|
|
6943
|
+
}
|
|
6944
|
+
const step = state.scaleSnap;
|
|
6945
|
+
const each = (index, axis) => {
|
|
6946
|
+
const value = grab.start.scale[index] * factor.getComponent(index);
|
|
6947
|
+
if (step === null || !includes(grab.handle, axis))
|
|
6948
|
+
return value;
|
|
6949
|
+
return snapped(value, step) || step;
|
|
6950
|
+
};
|
|
6951
|
+
return { ...grab.start, scale: [each(0, "x"), each(1, "y"), each(2, "z")] };
|
|
6952
|
+
};
|
|
6953
|
+
var rotated = (state, grab, end) => {
|
|
6954
|
+
if (grab.handle !== "x" && grab.handle !== "y" && grab.handle !== "z")
|
|
6955
|
+
return grab.start;
|
|
6956
|
+
const space = spaceOf(state, grab.handle);
|
|
6957
|
+
const offset = end.clone().sub(new Vector314(...grab.from));
|
|
6958
|
+
const speed = 20 / Math.max(grab.distance, 0.000000001);
|
|
6959
|
+
const axis = axisIn(grab.handle, space, grab.start.rotation);
|
|
6960
|
+
const across = axis.clone().cross(new Vector314(...grab.eye));
|
|
6961
|
+
const angle = snapped(across.lengthSq() < 0.000000000001 ? 0 : offset.dot(across.normalize()) * speed, state.rotationSnap);
|
|
6962
|
+
const start = turnOf(grab.start.rotation);
|
|
6963
|
+
const turn = space === "local" ? start.clone().multiply(new Quaternion7().setFromAxisAngle(axes[grab.handle], angle)) : new Quaternion7().setFromAxisAngle(axes[grab.handle], angle).multiply(start);
|
|
6964
|
+
const euler = new Euler6().setFromQuaternion(turn.normalize());
|
|
6965
|
+
return { ...grab.start, rotation: [euler.x, euler.y, euler.z] };
|
|
6966
|
+
};
|
|
6967
|
+
var dragGizmo2 = (state, ray) => {
|
|
6968
|
+
const grab = state.grab;
|
|
6969
|
+
if (grab === null)
|
|
6970
|
+
return;
|
|
6971
|
+
const end = onPlane2(grab, ray);
|
|
6972
|
+
if (end === undefined)
|
|
6973
|
+
return grab.start;
|
|
6974
|
+
if (state.mode === "translate")
|
|
6975
|
+
return translated(state, grab, end);
|
|
6976
|
+
if (state.mode === "scale")
|
|
6977
|
+
return scaled2(state, grab, end);
|
|
6978
|
+
return rotated(state, grab, end);
|
|
6979
|
+
};
|
|
6980
|
+
var movedAlike2 = (from, to, other) => {
|
|
6981
|
+
const turn = turnOf(to.rotation).multiply(turnOf(from.rotation).invert());
|
|
6982
|
+
const turned = new Euler6().setFromQuaternion(turn.multiply(turnOf(other.rotation)).normalize());
|
|
6983
|
+
const ratio = (axis) => from.scale[axis] === 0 ? 1 : to.scale[axis] / from.scale[axis];
|
|
6984
|
+
const shifted = (axis) => other.position[axis] + to.position[axis] - from.position[axis];
|
|
6985
|
+
return {
|
|
6986
|
+
position: [shifted(0), shifted(1), shifted(2)],
|
|
6987
|
+
rotation: [turned.x, turned.y, turned.z],
|
|
6988
|
+
scale: [other.scale[0] * ratio(0), other.scale[1] * ratio(1), other.scale[2] * ratio(2)]
|
|
6989
|
+
};
|
|
6990
|
+
};
|
|
6991
|
+
var colours = {
|
|
6992
|
+
x: 16725587,
|
|
6993
|
+
y: 9100032,
|
|
6994
|
+
z: 2920447,
|
|
6995
|
+
xy: 2920447,
|
|
6996
|
+
yz: 16725587,
|
|
6997
|
+
xz: 9100032
|
|
6998
|
+
};
|
|
6999
|
+
var highlight = 16776960;
|
|
7000
|
+
var hideThreshold = 0.99;
|
|
7001
|
+
var screenScale = (state, at, camera) => {
|
|
7002
|
+
if (camera._tag === "Orthographic")
|
|
7003
|
+
return 480 / camera.zoom * state.size / 4;
|
|
7004
|
+
const distance = new Vector314(...camera.position).distanceTo(new Vector314(...at));
|
|
7005
|
+
const spread = Math.min(1.9 * Math.tan(Math.PI * camera.fov / 360), 7);
|
|
7006
|
+
return distance * spread * state.size / 4;
|
|
7007
|
+
};
|
|
7008
|
+
var gizmoHandleOf2 = (key, hit) => {
|
|
7009
|
+
const prefix = `${key}:`;
|
|
7010
|
+
if (!hit.startsWith(prefix))
|
|
7011
|
+
return;
|
|
7012
|
+
const name = hit.slice(prefix.length).split(":")[0];
|
|
7013
|
+
const handles = ["x", "y", "z", "xy", "yz", "xz", "xyz"];
|
|
7014
|
+
return handles.find((handle) => handle === name);
|
|
7015
|
+
};
|
|
7016
|
+
var look = (state, handle, colour) => basic2({
|
|
7017
|
+
color: state.grab?.handle === handle || state.hovered === handle ? highlight : colour,
|
|
7018
|
+
transparent: true,
|
|
7019
|
+
opacity: state.grab !== null && state.grab.handle !== handle ? 0.25 : 0.9,
|
|
7020
|
+
depthTest: false
|
|
7021
|
+
});
|
|
7022
|
+
var pointAlong = { x: [0, 0, -Math.PI / 2], y: [0, 0, 0], z: [Math.PI / 2, 0, 0] };
|
|
7023
|
+
var tips = { x: [0.5, 0, 0], y: [0, 0.5, 0], z: [0, 0, 0.5] };
|
|
7024
|
+
var ringRound = { x: [0, Math.PI / 2, 0], y: [Math.PI / 2, 0, 0], z: [0, 0, 0] };
|
|
7025
|
+
var ring = (key, state, axis) => [
|
|
7026
|
+
mesh2({
|
|
7027
|
+
key: `${key}:${axis}`,
|
|
7028
|
+
rotation: fixed2([...ringRound[axis]]),
|
|
7029
|
+
geometry: torus2({ radius: 0.5, tube: 0.02, radialSegments: 6, tubularSegments: 48 }),
|
|
7030
|
+
material: look(state, axis, colours[axis]),
|
|
7031
|
+
interactive: true
|
|
7032
|
+
})
|
|
7033
|
+
];
|
|
7034
|
+
var arrow = (key, state, axis) => {
|
|
7035
|
+
const along = pointAlong[axis];
|
|
7036
|
+
const tipAt = tips[axis];
|
|
7037
|
+
const material = look(state, axis, colours[axis]);
|
|
7038
|
+
return [
|
|
7039
|
+
mesh2({
|
|
7040
|
+
key: `${key}:${axis}:stem`,
|
|
7041
|
+
position: [tipAt[0] / 2, tipAt[1] / 2, tipAt[2] / 2],
|
|
7042
|
+
rotation: fixed2([...along]),
|
|
7043
|
+
geometry: cylinder2({ radiusTop: 0.012, radiusBottom: 0.012, height: 0.5 }),
|
|
7044
|
+
material,
|
|
7045
|
+
interactive: true
|
|
7046
|
+
}),
|
|
7047
|
+
mesh2({
|
|
7048
|
+
key: `${key}:${axis}:tip`,
|
|
7049
|
+
position: tipAt,
|
|
7050
|
+
rotation: fixed2([...along]),
|
|
7051
|
+
geometry: state.mode === "scale" ? box2({ width: 0.08, height: 0.08, depth: 0.08 }) : cone2({ radius: 0.04, height: 0.12, radialSegments: 12 }),
|
|
7052
|
+
material,
|
|
7053
|
+
interactive: true
|
|
7054
|
+
})
|
|
7055
|
+
];
|
|
7056
|
+
};
|
|
7057
|
+
var axisHandles = (key, state, visible) => ["x", "y", "z"].filter(visible).flatMap((axis) => state.mode === "rotate" ? ring(key, state, axis) : arrow(key, state, axis));
|
|
7058
|
+
var planeHandles = (key, state) => {
|
|
7059
|
+
if (state.mode === "rotate")
|
|
7060
|
+
return [];
|
|
7061
|
+
const squares = [
|
|
7062
|
+
{
|
|
7063
|
+
handle: "xy",
|
|
7064
|
+
at: [0.15, 0.15, 0],
|
|
7065
|
+
turn: [0, 0, 0],
|
|
7066
|
+
shown: state.showX && state.showY
|
|
7067
|
+
},
|
|
7068
|
+
{
|
|
7069
|
+
handle: "yz",
|
|
7070
|
+
at: [0, 0.15, 0.15],
|
|
7071
|
+
turn: [0, Math.PI / 2, 0],
|
|
7072
|
+
shown: state.showY && state.showZ
|
|
7073
|
+
},
|
|
7074
|
+
{
|
|
7075
|
+
handle: "xz",
|
|
7076
|
+
at: [0.15, 0, 0.15],
|
|
7077
|
+
turn: [-Math.PI / 2, 0, 0],
|
|
7078
|
+
shown: state.showX && state.showZ
|
|
7079
|
+
}
|
|
7080
|
+
];
|
|
7081
|
+
return squares.filter((square) => square.shown).map((square) => mesh2({
|
|
7082
|
+
key: `${key}:${square.handle}`,
|
|
7083
|
+
position: square.at,
|
|
7084
|
+
rotation: fixed2([...square.turn]),
|
|
7085
|
+
geometry: plane2({ width: 0.12, height: 0.12 }),
|
|
7086
|
+
material: { ...look(state, square.handle, colours[square.handle]), side: "double" },
|
|
7087
|
+
interactive: true
|
|
7088
|
+
}));
|
|
7089
|
+
};
|
|
7090
|
+
var gizmoNodes2 = (key, state, placement, camera) => {
|
|
7091
|
+
const space = spaceOf(state, state.grab?.handle ?? null);
|
|
7092
|
+
const scale = screenScale(state, placement.position, camera);
|
|
7093
|
+
const eye = new Vector314(...camera.position).sub(new Vector314(...placement.position)).normalize();
|
|
7094
|
+
const shown = { x: state.showX, y: state.showY, z: state.showZ };
|
|
7095
|
+
const visible = (axis) => shown[axis] && (state.mode === "rotate" || state.grab?.handle === axis || Math.abs(axisIn(axis, space, placement.rotation).dot(eye)) <= hideThreshold);
|
|
7096
|
+
return group2({
|
|
7097
|
+
key,
|
|
7098
|
+
position: placement.position,
|
|
7099
|
+
rotation: fixed2(space === "local" ? placement.rotation : [0, 0, 0]),
|
|
7100
|
+
scale: [scale, scale, scale],
|
|
7101
|
+
children: [
|
|
7102
|
+
...axisHandles(key, state, visible),
|
|
7103
|
+
...planeHandles(key, state),
|
|
7104
|
+
...state.mode === "rotate" ? [] : [
|
|
7105
|
+
mesh2({
|
|
7106
|
+
key: `${key}:xyz`,
|
|
7107
|
+
geometry: state.mode === "scale" ? box2({ width: 0.1, height: 0.1, depth: 0.1 }) : sphere2({ radius: 0.06, widthSegments: 12, heightSegments: 8 }),
|
|
7108
|
+
material: look(state, "xyz", 16777215),
|
|
7109
|
+
interactive: true
|
|
7110
|
+
})
|
|
7111
|
+
]
|
|
7112
|
+
]
|
|
7113
|
+
});
|
|
7114
|
+
};
|
|
7115
|
+
// src/kernel/boxSelect.ts
|
|
7116
|
+
import { OrthographicCamera as OrthographicCamera5, PerspectiveCamera as PerspectiveCamera4, Vector3 as Vector315 } from "three";
|
|
7117
|
+
var hostCamera2 = (camera, size) => {
|
|
7118
|
+
const host = camera._tag === "Perspective" ? new PerspectiveCamera4(camera.fov, size.width / size.height, camera.near, camera.far) : new OrthographicCamera5(size.width / -2, size.width / 2, size.height / 2, size.height / -2, camera.near, camera.far);
|
|
7119
|
+
if (host instanceof OrthographicCamera5 && camera._tag === "Orthographic") {
|
|
7120
|
+
host.zoom = camera.zoom;
|
|
7121
|
+
}
|
|
7122
|
+
host.position.set(...camera.position);
|
|
7123
|
+
host.lookAt(...camera.lookAt);
|
|
7124
|
+
host.updateMatrixWorld();
|
|
7125
|
+
host.updateProjectionMatrix();
|
|
7126
|
+
return host;
|
|
7127
|
+
};
|
|
7128
|
+
var between2 = (value, a, b) => value >= Math.min(a, b) && value <= Math.max(a, b);
|
|
7129
|
+
var boxSelect2 = (camera, size, from, to, candidates) => {
|
|
7130
|
+
const host = hostCamera2(camera, size);
|
|
7131
|
+
const inside = (candidate) => {
|
|
7132
|
+
const seen = new Vector315(...candidate.at).project(host);
|
|
7133
|
+
return between2(seen.x, from.x, to.x) && between2(seen.y, from.y, to.y) && between2(seen.z, -1, 1);
|
|
7134
|
+
};
|
|
7135
|
+
return candidates.filter(inside).map((candidate) => candidate.key);
|
|
7136
|
+
};
|
|
7137
|
+
// src/kernel/history.ts
|
|
7138
|
+
var make = (value, label = "Start") => ({
|
|
7139
|
+
entries: [{ id: 0, parent: null, label, value, next: null }],
|
|
7140
|
+
current: 0
|
|
7141
|
+
});
|
|
7142
|
+
var entryOf = (state, id) => {
|
|
7143
|
+
const entry = state.entries[id];
|
|
7144
|
+
if (entry === undefined)
|
|
7145
|
+
throw new RangeError(`No history entry ${id}`);
|
|
7146
|
+
return entry;
|
|
7147
|
+
};
|
|
7148
|
+
var presentEntry = (state) => entryOf(state, state.current);
|
|
7149
|
+
var present = (state) => presentEntry(state).value;
|
|
7150
|
+
var withNext = (state, id, next) => ({
|
|
7151
|
+
...state,
|
|
7152
|
+
entries: state.entries.map((entry) => entry.id === id ? { ...entry, next } : entry)
|
|
7153
|
+
});
|
|
7154
|
+
var record = (state, value, label) => {
|
|
7155
|
+
const id = state.entries.length;
|
|
7156
|
+
const grown = {
|
|
7157
|
+
entries: [...state.entries, { id, parent: state.current, label, value, next: null }],
|
|
7158
|
+
current: id
|
|
7159
|
+
};
|
|
7160
|
+
return withNext(grown, state.current, id);
|
|
7161
|
+
};
|
|
7162
|
+
var canUndo = (state) => presentEntry(state).parent !== null;
|
|
7163
|
+
var canRedo = (state) => presentEntry(state).next !== null;
|
|
7164
|
+
var undo = (state) => {
|
|
7165
|
+
const parent = presentEntry(state).parent;
|
|
7166
|
+
return parent === null ? state : { ...state, current: parent };
|
|
7167
|
+
};
|
|
7168
|
+
var redo = (state) => {
|
|
7169
|
+
const next = presentEntry(state).next;
|
|
7170
|
+
return next === null ? state : { ...state, current: next };
|
|
7171
|
+
};
|
|
7172
|
+
var branches = (state) => state.entries.filter((entry) => entry.parent === state.current);
|
|
7173
|
+
var chooseBranch = (state, id) => branches(state).some((entry) => entry.id === id) ? withNext(state, state.current, id) : state;
|
|
7174
|
+
var pathTo = (state, id) => {
|
|
7175
|
+
const path = [];
|
|
7176
|
+
for (let at = id;at !== null; at = entryOf(state, at).parent) {
|
|
7177
|
+
path.unshift(entryOf(state, at));
|
|
7178
|
+
}
|
|
7179
|
+
return path;
|
|
7180
|
+
};
|
|
7181
|
+
var jumpTo = (state, id) => {
|
|
7182
|
+
const path = pathTo(state, id);
|
|
7183
|
+
const chosen = path.slice(1).reduce((at, entry) => withNext(at, entry.parent ?? 0, entry.id), state);
|
|
7184
|
+
return { ...chosen, current: id };
|
|
7185
|
+
};
|
|
7186
|
+
var depth = (state) => pathTo(state, state.current).length - 1;
|
|
7187
|
+
// src/kernel/lockstep.ts
|
|
7188
|
+
var sortedPeers = (members) => members.toSorted((a, b) => a.peer < b.peer ? -1 : a.peer > b.peer ? 1 : 0);
|
|
7189
|
+
var memberAt = (member, turn) => member.from <= turn && (member.until === null || turn < member.until);
|
|
7190
|
+
var membersAt = (state, turn) => sortedPeers(state.members.filter((member) => memberAt(member, turn))).map((member) => member.peer);
|
|
7191
|
+
var leaderAt = (state, turn) => membersAt(state, turn)[0];
|
|
7192
|
+
var make2 = (self, lead = 2) => ({
|
|
7193
|
+
self,
|
|
7194
|
+
members: [{ peer: self, from: 0, until: null }],
|
|
7195
|
+
turn: 0,
|
|
7196
|
+
sent: 0,
|
|
7197
|
+
lead,
|
|
7198
|
+
pending: [],
|
|
7199
|
+
received: []
|
|
7200
|
+
});
|
|
7201
|
+
var join = (self, welcome, heard = []) => ({
|
|
7202
|
+
self,
|
|
7203
|
+
members: welcome.members,
|
|
7204
|
+
turn: welcome.turn,
|
|
7205
|
+
sent: welcome.turn,
|
|
7206
|
+
lead: welcome.lead,
|
|
7207
|
+
pending: [],
|
|
7208
|
+
received: heard.filter((packet) => packet.turn >= welcome.turn)
|
|
7209
|
+
});
|
|
7210
|
+
var submit = (state, input) => ({
|
|
7211
|
+
...state,
|
|
7212
|
+
pending: [...state.pending, { _tag: "Input", input }]
|
|
7213
|
+
});
|
|
7214
|
+
var known = (state, peer) => state.members.some((member) => member.peer === peer && member.until === null) || state.pending.some((entry) => entry._tag === "Admit" && entry.peer === peer);
|
|
7215
|
+
var admit = (state, peer) => leaderAt(state, state.sent) !== state.self || known(state, peer) ? state : { ...state, pending: [...state.pending, { _tag: "Admit", peer }] };
|
|
7216
|
+
var hasPacket = (state, peer, turn) => state.received.some((packet) => packet.peer === peer && packet.turn === turn);
|
|
7217
|
+
var receive = (state, packet) => {
|
|
7218
|
+
if (packet.turn < state.turn || hasPacket(state, packet.peer, packet.turn))
|
|
7219
|
+
return state;
|
|
7220
|
+
const member = state.members.find((each) => each.peer === packet.peer);
|
|
7221
|
+
if (member !== undefined && !memberAt(member, packet.turn))
|
|
7222
|
+
return state;
|
|
7223
|
+
return { ...state, received: [...state.received, packet] };
|
|
7224
|
+
};
|
|
7225
|
+
var send = (state) => {
|
|
7226
|
+
const member = state.members.find((each) => each.peer === state.self);
|
|
7227
|
+
const ahead = state.sent >= state.turn + state.lead;
|
|
7228
|
+
if (member === undefined || !memberAt(member, state.sent) || ahead) {
|
|
7229
|
+
return { state, packet: undefined };
|
|
7230
|
+
}
|
|
7231
|
+
const packet = { peer: state.self, turn: state.sent, entries: state.pending };
|
|
7232
|
+
return {
|
|
7233
|
+
state: { ...state, sent: state.sent + 1, pending: [], received: [...state.received, packet] },
|
|
7234
|
+
packet
|
|
7235
|
+
};
|
|
7236
|
+
};
|
|
7237
|
+
var waitingOn = (state) => membersAt(state, state.turn).filter((peer) => !hasPacket(state, peer, state.turn));
|
|
7238
|
+
var packetsOf = (state, peer, turn) => state.received.filter((packet) => packet.peer === peer && packet.turn === turn);
|
|
7239
|
+
var applyTurn = (state) => {
|
|
7240
|
+
const turn = state.turn;
|
|
7241
|
+
const packets = membersAt(state, turn).flatMap((peer) => packetsOf(state, peer, turn));
|
|
7242
|
+
const entries = packets.flatMap((packet) => packet.entries.map((entry) => ({ peer: packet.peer, entry })));
|
|
7243
|
+
const admitted = entries.flatMap(({ entry }) => entry._tag === "Admit" && !state.members.some((member) => member.peer === entry.peer) ? [{ peer: entry.peer, from: turn + state.lead + 1, until: null }] : []);
|
|
7244
|
+
const applied = entries.flatMap(({ peer, entry }) => entry._tag === "Input" ? [{ turn, peer, input: entry.input }] : []);
|
|
7245
|
+
return {
|
|
7246
|
+
state: {
|
|
7247
|
+
...state,
|
|
7248
|
+
turn: turn + 1,
|
|
7249
|
+
members: [...state.members, ...admitted],
|
|
7250
|
+
received: state.received.filter((packet) => packet.turn > turn)
|
|
7251
|
+
},
|
|
7252
|
+
applied
|
|
7253
|
+
};
|
|
7254
|
+
};
|
|
7255
|
+
var advance = (state) => {
|
|
7256
|
+
let current = state;
|
|
7257
|
+
const applied = [];
|
|
7258
|
+
while (membersAt(current, current.turn).length > 0 && waitingOn(current).length === 0) {
|
|
7259
|
+
const next = applyTurn(current);
|
|
7260
|
+
current = next.state;
|
|
7261
|
+
applied.push(...next.applied);
|
|
7262
|
+
}
|
|
7263
|
+
return { state: current, applied };
|
|
7264
|
+
};
|
|
7265
|
+
var welcomeDue = (before, state) => state.members.filter((member) => member.from > before && member.from <= state.turn).filter((member) => leaderAt(state, member.from - 1) === state.self).map((member) => member.peer);
|
|
7266
|
+
var leave = (state) => state.sent - 1;
|
|
7267
|
+
var remove = (state, peer, until) => ({
|
|
7268
|
+
...state,
|
|
7269
|
+
members: state.members.map((member) => member.peer === peer && (member.until === null || until < member.until) ? { ...member, until } : member),
|
|
7270
|
+
received: state.received.filter((packet) => packet.peer !== peer || packet.turn < until)
|
|
7271
|
+
});
|
|
7272
|
+
// src/kernel/timeline.ts
|
|
7273
|
+
var make3 = (frontier = 0) => ({
|
|
7274
|
+
inputs: [],
|
|
7275
|
+
applied: 0,
|
|
7276
|
+
reached: null,
|
|
7277
|
+
frontier
|
|
7278
|
+
});
|
|
7279
|
+
var schedule = (timeline, step, input) => {
|
|
7280
|
+
const at = timeline.inputs.findIndex((scheduled) => scheduled.step > step);
|
|
7281
|
+
const index = at < 0 ? timeline.inputs.length : at;
|
|
7282
|
+
return {
|
|
7283
|
+
...timeline,
|
|
7284
|
+
inputs: [...timeline.inputs.slice(0, index), { step, input }, ...timeline.inputs.slice(index)]
|
|
7285
|
+
};
|
|
7286
|
+
};
|
|
7287
|
+
var extend = (timeline, frontier) => frontier <= timeline.frontier ? timeline : { ...timeline, frontier };
|
|
7288
|
+
var reach = (timeline, step) => timeline.reached === step ? timeline : { ...timeline, reached: step };
|
|
7289
|
+
var due = (timeline) => {
|
|
7290
|
+
const { reached } = timeline;
|
|
7291
|
+
if (reached === null)
|
|
7292
|
+
return { timeline, inputs: [] };
|
|
7293
|
+
let applied = timeline.applied;
|
|
7294
|
+
while ((timeline.inputs[applied]?.step ?? Infinity) <= reached)
|
|
7295
|
+
applied += 1;
|
|
7296
|
+
if (applied === timeline.applied)
|
|
7297
|
+
return { timeline, inputs: [] };
|
|
7298
|
+
return {
|
|
7299
|
+
timeline: { ...timeline, applied },
|
|
7300
|
+
inputs: timeline.inputs.slice(timeline.applied, applied).map((scheduled) => scheduled.input)
|
|
7301
|
+
};
|
|
7302
|
+
};
|
|
7303
|
+
var until = (timeline) => Math.min(timeline.inputs[timeline.applied]?.step ?? Infinity, timeline.frontier);
|
|
7304
|
+
var restart = (timeline) => ({
|
|
7305
|
+
...timeline,
|
|
7306
|
+
applied: 0,
|
|
7307
|
+
reached: null
|
|
7308
|
+
});
|
|
7309
|
+
// src/kernel/describeScene.ts
|
|
7310
|
+
var extentOf = (geometry) => {
|
|
7311
|
+
switch (geometry._tag) {
|
|
7312
|
+
case "Box":
|
|
7313
|
+
case "RoundedBox":
|
|
7314
|
+
return [geometry.width, geometry.height, geometry.depth];
|
|
7315
|
+
case "Sphere":
|
|
7316
|
+
return [geometry.radius * 2, geometry.radius * 2, geometry.radius * 2];
|
|
7317
|
+
case "Cone":
|
|
7318
|
+
return [geometry.radius * 2, geometry.height, geometry.radius * 2];
|
|
7319
|
+
case "Cylinder": {
|
|
7320
|
+
const across = Math.max(geometry.radiusTop, geometry.radiusBottom) * 2;
|
|
7321
|
+
return [across, geometry.height, across];
|
|
7322
|
+
}
|
|
7323
|
+
case "Capsule":
|
|
7324
|
+
return [geometry.radius * 2, geometry.height + geometry.radius * 2, geometry.radius * 2];
|
|
7325
|
+
case "Torus": {
|
|
7326
|
+
const across = (geometry.radius + geometry.tube) * 2;
|
|
7327
|
+
return [across, across, geometry.tube * 2];
|
|
7328
|
+
}
|
|
7329
|
+
case "Plane":
|
|
7330
|
+
return [geometry.width, geometry.height, 0];
|
|
7331
|
+
case "Circle":
|
|
7332
|
+
return [geometry.radius * 2, geometry.radius * 2, 0];
|
|
7333
|
+
case "Ring":
|
|
7334
|
+
return [geometry.outerRadius * 2, geometry.outerRadius * 2, 0];
|
|
7335
|
+
default:
|
|
7336
|
+
return;
|
|
7337
|
+
}
|
|
7338
|
+
};
|
|
7339
|
+
var scaled3 = (extent, scale) => [
|
|
7340
|
+
extent[0] * Math.abs(scale[0]),
|
|
7341
|
+
extent[1] * Math.abs(scale[1]),
|
|
7342
|
+
extent[2] * Math.abs(scale[2])
|
|
7343
|
+
];
|
|
7344
|
+
var shapeOf = (geometry, description) => {
|
|
7345
|
+
if (geometry._tag === "LentGeometry")
|
|
7346
|
+
return;
|
|
7347
|
+
if (geometry._tag !== "SharedGeometry")
|
|
7348
|
+
return geometry;
|
|
7349
|
+
return description.resources.geometries.find((entry) => entry.id === geometry.id)?.geometry;
|
|
7350
|
+
};
|
|
7351
|
+
var sizeOf2 = (node, description) => {
|
|
7352
|
+
if (node._tag !== "Mesh")
|
|
7353
|
+
return null;
|
|
7354
|
+
const shape = shapeOf(node.geometry, description);
|
|
7355
|
+
const extent = shape === undefined ? undefined : extentOf(shape);
|
|
7356
|
+
return extent === undefined ? null : scaled3(extent, node.scale);
|
|
7357
|
+
};
|
|
7358
|
+
var colourOf = (node) => node._tag === "Mesh" && ("color" in node.material) ? node.material.color : null;
|
|
7359
|
+
var kindOf = (node) => node._tag === "Mesh" ? `Mesh (${node.geometry._tag})` : node._tag;
|
|
7360
|
+
var isLight = (node) => node._tag.endsWith("Light");
|
|
7361
|
+
var lightOf = (node) => {
|
|
7362
|
+
if (!isLight(node) || !("color" in node) || !("intensity" in node))
|
|
7363
|
+
return [];
|
|
7364
|
+
return [
|
|
7365
|
+
{
|
|
7366
|
+
key: node.key,
|
|
7367
|
+
kind: node._tag,
|
|
7368
|
+
colour: node.color,
|
|
7369
|
+
intensity: node.intensity,
|
|
7370
|
+
position: "position" in node ? node.position : null
|
|
7371
|
+
}
|
|
7372
|
+
];
|
|
7373
|
+
};
|
|
7374
|
+
var thingsIn = (nodes, parent, description) => nodes.flatMap((node) => [
|
|
7375
|
+
...isLight(node) ? [] : [
|
|
7376
|
+
{
|
|
7377
|
+
key: node.key,
|
|
7378
|
+
kind: kindOf(node),
|
|
7379
|
+
position: "position" in node ? node.position : [0, 0, 0],
|
|
7380
|
+
size: sizeOf2(node, description),
|
|
7381
|
+
colour: colourOf(node),
|
|
7382
|
+
parent
|
|
7383
|
+
}
|
|
7384
|
+
],
|
|
7385
|
+
...node._tag === "Group" ? thingsIn(node.children, node.key, description) : []
|
|
7386
|
+
]);
|
|
7387
|
+
var lightsIn = (nodes) => nodes.flatMap((node) => [
|
|
7388
|
+
...lightOf(node),
|
|
7389
|
+
...node._tag === "Group" ? lightsIn(node.children) : []
|
|
7390
|
+
]);
|
|
7391
|
+
var thingsBounds2 = (things) => {
|
|
7392
|
+
const sized = things.filter((thing) => thing.parent === null && thing.size !== null);
|
|
7393
|
+
if (sized.length === 0)
|
|
7394
|
+
return null;
|
|
7395
|
+
const edge = (axis, sign) => sized.map((thing) => thing.position[axis] + sign * ((thing.size?.[axis] ?? 0) / 2));
|
|
7396
|
+
const low = (axis) => Math.min(...edge(axis, -1));
|
|
7397
|
+
const high = (axis) => Math.max(...edge(axis, 1));
|
|
7398
|
+
return { min: [low(0), low(1), low(2)], max: [high(0), high(1), high(2)] };
|
|
7399
|
+
};
|
|
7400
|
+
var stagingOf = (description) => [
|
|
7401
|
+
...description.environment === null ? [] : ["environment lighting"],
|
|
7402
|
+
...description.sky === null ? [] : ["sky"],
|
|
7403
|
+
...description.render.shadows === "off" ? [] : [`${description.render.shadows} shadows`],
|
|
7404
|
+
...description.contactShadows === null ? [] : ["contact shadows"],
|
|
7405
|
+
...description.render.effects.map((effect) => effect._tag.toLowerCase()),
|
|
7406
|
+
...description.physics === null ? [] : ["physics"]
|
|
7407
|
+
];
|
|
7408
|
+
var describeScene2 = (description) => {
|
|
7409
|
+
const things = thingsIn(description.children, null, description);
|
|
7410
|
+
return {
|
|
7411
|
+
camera: {
|
|
7412
|
+
kind: description.camera._tag,
|
|
7413
|
+
position: description.camera.position,
|
|
7414
|
+
lookAt: description.camera.lookAt
|
|
7415
|
+
},
|
|
7416
|
+
things,
|
|
7417
|
+
lights: lightsIn(description.children),
|
|
7418
|
+
bounds: thingsBounds2(things),
|
|
7419
|
+
staging: stagingOf(description)
|
|
7420
|
+
};
|
|
7421
|
+
};
|
|
7422
|
+
var number2 = (value) => String(Math.round(value * 100) / 100);
|
|
7423
|
+
var point2 = (at) => `(${at.map(number2).join(", ")})`;
|
|
7424
|
+
var hex = (colour) => `#${colour.toString(16).padStart(6, "0")}`;
|
|
7425
|
+
var thingLine = (thing) => [
|
|
7426
|
+
`- ${thing.key}: ${thing.kind}`,
|
|
7427
|
+
thing.size === null ? "" : `, ${thing.size.map(number2).join(" × ")}`,
|
|
7428
|
+
thing.colour === null ? "" : `, ${hex(thing.colour)}`,
|
|
7429
|
+
`, at ${point2(thing.position)}`,
|
|
7430
|
+
thing.parent === null ? "" : ` in ${thing.parent}`
|
|
7431
|
+
].join("");
|
|
7432
|
+
var lightLine = (light) => `- ${light.key}: ${light.kind}, ${hex(light.colour)} × ${number2(light.intensity)}${light.position === null ? "" : ` at ${point2(light.position)}`}`;
|
|
7433
|
+
var formatSummary2 = (summary) => [
|
|
7434
|
+
`Camera: ${summary.camera.kind.toLowerCase()} at ${point2(summary.camera.position)}, looking at ${point2(summary.camera.lookAt)}`,
|
|
7435
|
+
`Things (${summary.things.length})${summary.bounds === null ? "" : `, within ${point2(summary.bounds.min)} to ${point2(summary.bounds.max)}`}:`,
|
|
7436
|
+
...summary.things.map(thingLine),
|
|
7437
|
+
`Lights (${summary.lights.length}):`,
|
|
7438
|
+
...summary.lights.map(lightLine),
|
|
7439
|
+
`Staging: ${summary.staging.length === 0 ? "none" : summary.staging.join(", ")}`
|
|
7440
|
+
].join(`
|
|
7441
|
+
`);
|
|
7442
|
+
// src/kernel/shots.ts
|
|
7443
|
+
import { Vector3 as Vector316 } from "three";
|
|
7444
|
+
var shotAngles2 = [
|
|
7445
|
+
"front",
|
|
7446
|
+
"back",
|
|
7447
|
+
"left",
|
|
7448
|
+
"right",
|
|
7449
|
+
"top",
|
|
7450
|
+
"three-quarter",
|
|
7451
|
+
"low"
|
|
7452
|
+
];
|
|
7453
|
+
var directionOf = {
|
|
7454
|
+
front: [0, 0.15, 1],
|
|
7455
|
+
back: [0, 0.15, -1],
|
|
7456
|
+
left: [-1, 0.15, 0],
|
|
7457
|
+
right: [1, 0.15, 0],
|
|
7458
|
+
top: [0, 1, 0.0001],
|
|
7459
|
+
"three-quarter": [1, 0.7, 1],
|
|
7460
|
+
low: [0.35, -0.02, 1]
|
|
7461
|
+
};
|
|
7462
|
+
var shotCamera2 = (camera, subject, angle, area = { width: 16, height: 10 }, margin = 1.3) => {
|
|
7463
|
+
const centre = new Vector316(...subject.min).add(new Vector316(...subject.max)).multiplyScalar(0.5);
|
|
7464
|
+
const from = new Vector316(...directionOf[angle]).normalize().add(centre);
|
|
7465
|
+
const aimed = {
|
|
7466
|
+
...camera,
|
|
7467
|
+
position: [from.x, from.y, from.z],
|
|
7468
|
+
lookAt: [centre.x, centre.y, centre.z]
|
|
7469
|
+
};
|
|
7470
|
+
return fitCamera2(aimed, subject, area, margin);
|
|
7471
|
+
};
|
|
7472
|
+
var moods2 = ["studio", "daylight", "sunset", "night"];
|
|
7473
|
+
var moodStaging2 = (mood, prefix = "mood") => {
|
|
7474
|
+
switch (mood) {
|
|
7475
|
+
case "studio":
|
|
7476
|
+
return {
|
|
7477
|
+
lights: [
|
|
7478
|
+
hemisphereLight2({
|
|
7479
|
+
key: `${prefix}:fill`,
|
|
7480
|
+
color: 16777215,
|
|
7481
|
+
groundColor: 7301730,
|
|
7482
|
+
intensity: 0.8
|
|
7483
|
+
}),
|
|
7484
|
+
directionalLight2({
|
|
7485
|
+
key: `${prefix}:key`,
|
|
7486
|
+
position: [4, 7, 3],
|
|
7487
|
+
intensity: 2,
|
|
7488
|
+
castShadow: true
|
|
7489
|
+
})
|
|
7490
|
+
],
|
|
7491
|
+
environment: environment2({ environmentIntensity: 0.35 }),
|
|
7492
|
+
sky: null
|
|
7493
|
+
};
|
|
7494
|
+
case "daylight":
|
|
7495
|
+
return {
|
|
7496
|
+
lights: [
|
|
7497
|
+
hemisphereLight2({
|
|
7498
|
+
key: `${prefix}:sky`,
|
|
7499
|
+
color: 13625087,
|
|
7500
|
+
groundColor: 9075296,
|
|
7501
|
+
intensity: 1
|
|
7502
|
+
}),
|
|
7503
|
+
directionalLight2({
|
|
7504
|
+
key: `${prefix}:sun`,
|
|
7505
|
+
position: [6, 9, 4],
|
|
7506
|
+
intensity: 3,
|
|
7507
|
+
castShadow: true
|
|
7508
|
+
})
|
|
7509
|
+
],
|
|
7510
|
+
environment: environment2({ environmentIntensity: 0.25 }),
|
|
7511
|
+
sky: sky2({ sunPosition: sunPositionFromAngles2(0.85, 0.35) })
|
|
7512
|
+
};
|
|
7513
|
+
case "sunset":
|
|
7514
|
+
return {
|
|
7515
|
+
lights: [
|
|
7516
|
+
hemisphereLight2({
|
|
7517
|
+
key: `${prefix}:sky`,
|
|
7518
|
+
color: 16757370,
|
|
7519
|
+
groundColor: 3811904,
|
|
7520
|
+
intensity: 0.6
|
|
7521
|
+
}),
|
|
7522
|
+
directionalLight2({
|
|
7523
|
+
key: `${prefix}:sun`,
|
|
7524
|
+
color: 16751194,
|
|
7525
|
+
position: [-8, 2.5, 3],
|
|
7526
|
+
intensity: 2.5,
|
|
7527
|
+
castShadow: true
|
|
7528
|
+
})
|
|
7529
|
+
],
|
|
7530
|
+
environment: null,
|
|
7531
|
+
sky: sky2({ sunPosition: sunPositionFromAngles2(0.52, 0.25), turbidity: 8, rayleigh: 3 })
|
|
7532
|
+
};
|
|
7533
|
+
case "night":
|
|
7534
|
+
return {
|
|
7535
|
+
lights: [
|
|
7536
|
+
hemisphereLight2({
|
|
7537
|
+
key: `${prefix}:sky`,
|
|
7538
|
+
color: 3820160,
|
|
7539
|
+
groundColor: 1052696,
|
|
7540
|
+
intensity: 0.35
|
|
7541
|
+
}),
|
|
7542
|
+
directionalLight2({
|
|
7543
|
+
key: `${prefix}:moon`,
|
|
7544
|
+
color: 11190271,
|
|
7545
|
+
position: [-3, 8, -4],
|
|
7546
|
+
intensity: 0.8,
|
|
7547
|
+
castShadow: true
|
|
7548
|
+
})
|
|
7549
|
+
],
|
|
7550
|
+
environment: null,
|
|
7551
|
+
sky: null
|
|
7552
|
+
};
|
|
7553
|
+
}
|
|
7554
|
+
};
|
|
7555
|
+
// src/kernel/inspect.ts
|
|
7556
|
+
var resolve = (ast) => ast._tag === "Suspend" && ("thunk" in ast) ? resolve(ast.thunk()) : ast;
|
|
7557
|
+
var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7558
|
+
var labelOf = (path) => String(path.at(-1) ?? "value");
|
|
7559
|
+
var literalOf = (ast) => ("literal" in ast) ? ast.literal : undefined;
|
|
7560
|
+
var tagOf = (ast) => {
|
|
7561
|
+
const member = resolve(ast);
|
|
7562
|
+
if (!("propertySignatures" in member))
|
|
7563
|
+
return;
|
|
7564
|
+
const tag = member.propertySignatures.find((property) => property.name === "_tag");
|
|
7565
|
+
return tag === undefined ? undefined : literalOf(resolve(tag.type));
|
|
7566
|
+
};
|
|
7567
|
+
var memberFor = (types, value) => {
|
|
7568
|
+
if (isRecord(value) && "_tag" in value) {
|
|
7569
|
+
const tagged = types.find((member) => tagOf(member) === value["_tag"]);
|
|
7570
|
+
if (tagged !== undefined)
|
|
7571
|
+
return tagged;
|
|
7572
|
+
}
|
|
7573
|
+
if (value === null)
|
|
7574
|
+
return types.find((member) => resolve(member)._tag === "Null");
|
|
7575
|
+
return types.find((member) => resolve(member)._tag !== "Null") ?? types[0];
|
|
7576
|
+
};
|
|
7577
|
+
var fixed = (path, text) => ({
|
|
7578
|
+
_tag: "Fixed",
|
|
7579
|
+
path,
|
|
7580
|
+
label: labelOf(path),
|
|
7581
|
+
text
|
|
7582
|
+
});
|
|
7583
|
+
var isVector = (value) => Array.isArray(value) && value.length === 3 && value.every((n) => typeof n === "number");
|
|
7584
|
+
var walk = (given, value, path, hints) => {
|
|
7585
|
+
const ast = resolve(given);
|
|
7586
|
+
const label = labelOf(path);
|
|
7587
|
+
if (hints.colours.includes(ast) && typeof value === "number") {
|
|
7588
|
+
return [{ _tag: "Colour", path, label, value }];
|
|
7589
|
+
}
|
|
7590
|
+
if (hints.vectors.includes(ast) && isVector(value)) {
|
|
7591
|
+
return [{ _tag: "Vector", path, label, value }];
|
|
7592
|
+
}
|
|
7593
|
+
switch (ast._tag) {
|
|
7594
|
+
case "Number":
|
|
7595
|
+
return typeof value === "number" ? [{ _tag: "Number", path, label, value }] : [];
|
|
7596
|
+
case "String":
|
|
7597
|
+
return typeof value === "string" ? [{ _tag: "Text", path, label, value }] : [];
|
|
7598
|
+
case "Boolean":
|
|
7599
|
+
return typeof value === "boolean" ? [{ _tag: "Toggle", path, label, value }] : [];
|
|
7600
|
+
case "Literal":
|
|
7601
|
+
case "Null":
|
|
7602
|
+
return [fixed(path, String(value))];
|
|
7603
|
+
case "Union":
|
|
7604
|
+
return "types" in ast ? unionFields(ast.types, value, path, hints) : [];
|
|
7605
|
+
case "Objects":
|
|
7606
|
+
return "propertySignatures" in ast ? objectFields(ast, value, path, hints) : [];
|
|
7607
|
+
case "Arrays":
|
|
7608
|
+
return "elements" in ast ? arrayFields(ast, value, path, hints) : [];
|
|
7609
|
+
default:
|
|
7610
|
+
return [fixed(path, String(value))];
|
|
7611
|
+
}
|
|
7612
|
+
};
|
|
7613
|
+
var unionFields = (types, value, path, hints) => {
|
|
7614
|
+
const literals = types.map((member) => literalOf(resolve(member)));
|
|
7615
|
+
if (typeof value === "string" && literals.every((literal) => typeof literal === "string")) {
|
|
7616
|
+
return [{ _tag: "Choice", path, label: labelOf(path), value, options: literals.map(String) }];
|
|
7617
|
+
}
|
|
7618
|
+
const member = memberFor(types, value);
|
|
7619
|
+
return member === undefined ? [fixed(path, String(value))] : walk(member, value, path, hints);
|
|
7620
|
+
};
|
|
7621
|
+
var objectFields = (ast, value, path, hints) => {
|
|
7622
|
+
if (!isRecord(value))
|
|
7623
|
+
return [fixed(path, String(value))];
|
|
7624
|
+
return ast.propertySignatures.flatMap((property) => propertyFields(String(property.name), property.type, value, path, hints));
|
|
7625
|
+
};
|
|
7626
|
+
function propertyFields(name, type, value, path, hints) {
|
|
7627
|
+
if (!(name in value))
|
|
7628
|
+
return [];
|
|
7629
|
+
if (name === "_tag")
|
|
7630
|
+
return [fixed([...path, name], String(value[name]))];
|
|
7631
|
+
return walk(type, value[name], [...path, name], hints);
|
|
7632
|
+
}
|
|
7633
|
+
var arrayFields = (ast, value, path, hints) => {
|
|
7634
|
+
if (!Array.isArray(value))
|
|
7635
|
+
return [fixed(path, String(value))];
|
|
7636
|
+
if (ast.rest.length > 0) {
|
|
7637
|
+
return [fixed(path, `${value.length} ${value.length === 1 ? "item" : "items"}`)];
|
|
7638
|
+
}
|
|
7639
|
+
return ast.elements.flatMap((element, index) => walk(element, value[index], [...path, index], hints));
|
|
7640
|
+
};
|
|
7641
|
+
var inspectFields2 = (ast, value, hints = { colours: [], vectors: [] }) => walk(ast, value, [], hints);
|
|
7642
|
+
var setAt2 = (value, path, next) => {
|
|
7643
|
+
const [head, ...rest] = path;
|
|
7644
|
+
if (head === undefined)
|
|
7645
|
+
return next;
|
|
7646
|
+
if (Array.isArray(value) && typeof head === "number") {
|
|
7647
|
+
return value.map((item, index) => index === head ? setAt2(item, rest, next) : item);
|
|
7648
|
+
}
|
|
7649
|
+
if (isRecord(value) && typeof head === "string") {
|
|
7650
|
+
return { ...value, [head]: setAt2(value[head], rest, next) };
|
|
7651
|
+
}
|
|
7652
|
+
return value;
|
|
7653
|
+
};
|
|
7654
|
+
// src/kernel/sceneChanges.ts
|
|
7655
|
+
var settingOf = {
|
|
7656
|
+
SetCamera: "camera",
|
|
7657
|
+
SetViews: "views",
|
|
7658
|
+
SetRenderSettings: "render",
|
|
7659
|
+
DefineResources: "resources"
|
|
7660
|
+
};
|
|
7661
|
+
var comparedSettings = [
|
|
7662
|
+
"gestures",
|
|
7663
|
+
"overlays",
|
|
7664
|
+
"environment",
|
|
7665
|
+
"sky",
|
|
7666
|
+
"contactShadows",
|
|
7667
|
+
"physics",
|
|
7668
|
+
"xr",
|
|
7669
|
+
"measure"
|
|
7670
|
+
];
|
|
7671
|
+
var entriesOf = (value) => Object.entries(value);
|
|
7672
|
+
var same = (a, b) => {
|
|
7673
|
+
if (a === b)
|
|
7674
|
+
return true;
|
|
7675
|
+
if (typeof a !== "object" || typeof b !== "object" || a === null || b === null)
|
|
7676
|
+
return false;
|
|
7677
|
+
if (Array.isArray(a) !== Array.isArray(b))
|
|
7678
|
+
return false;
|
|
7679
|
+
const fieldsA = entriesOf(a);
|
|
7680
|
+
const fieldsB = new Map(entriesOf(b));
|
|
7681
|
+
return fieldsA.length === fieldsB.size && fieldsA.every(([key, value]) => fieldsB.has(key) && same(value, fieldsB.get(key)));
|
|
7682
|
+
};
|
|
7683
|
+
var nodeChange = (op, place) => {
|
|
7684
|
+
switch (op._tag) {
|
|
7685
|
+
case "Create":
|
|
7686
|
+
return [{ place, _tag: "Added", key: op.node.key, kind: op.node._tag, parent: op.parent }];
|
|
7687
|
+
case "Remove":
|
|
7688
|
+
return [{ place, _tag: "Removed", key: op.key }];
|
|
7689
|
+
case "Replace":
|
|
7690
|
+
return [{ place, _tag: "Replaced", key: op.node.key, kind: op.node._tag }];
|
|
7691
|
+
case "Update":
|
|
7692
|
+
return [{ place, _tag: "Changed", key: op.node.key, fields: op.fields }];
|
|
7693
|
+
case "Move":
|
|
7694
|
+
return [{ place, _tag: "Moved", key: op.key, parent: op.parent }];
|
|
7695
|
+
case "Order":
|
|
7696
|
+
return [{ place, _tag: "Reordered", parent: op.parent, keys: op.keys }];
|
|
7697
|
+
default:
|
|
7698
|
+
return [];
|
|
7699
|
+
}
|
|
7700
|
+
};
|
|
7701
|
+
var behavioursIn = (description) => {
|
|
7702
|
+
const names = new Set;
|
|
7703
|
+
const visit = (node) => {
|
|
7704
|
+
if ("behaviour" in node && node.behaviour !== null)
|
|
7705
|
+
names.add(node.behaviour.name);
|
|
7706
|
+
if (node._tag === "Group")
|
|
7707
|
+
node.children.forEach(visit);
|
|
7708
|
+
};
|
|
7709
|
+
description.children.forEach(visit);
|
|
7710
|
+
return names;
|
|
7711
|
+
};
|
|
7712
|
+
var startOf = (before) => {
|
|
7713
|
+
const indexed = indexScene2(before, behavioursIn(before));
|
|
7714
|
+
return indexed._tag === "Indexed" ? indexed.index : emptyIndex2;
|
|
7715
|
+
};
|
|
7716
|
+
var isSetting = (setting) => setting !== undefined;
|
|
7717
|
+
var settingsOf = (before, after, ops) => [
|
|
7718
|
+
...ops.map((op) => settingOf[op._tag]).filter(isSetting),
|
|
7719
|
+
...comparedSettings.filter((setting) => !same(before[setting], after[setting]))
|
|
7720
|
+
];
|
|
7721
|
+
var changesIn = (before, after, place) => {
|
|
7722
|
+
const result = diff2(startOf(before), after, behavioursIn(after));
|
|
7723
|
+
if (result._tag === "Invalid")
|
|
7724
|
+
return result;
|
|
7725
|
+
const settings = settingsOf(before, after, result.ops);
|
|
7726
|
+
const settingsChange = settings.length === 0 ? [] : [{ place, _tag: "Settings", settings }];
|
|
7727
|
+
return {
|
|
7728
|
+
_tag: "Changes",
|
|
7729
|
+
changes: [...settingsChange, ...result.ops.flatMap((op) => nodeChange(op, place))]
|
|
7730
|
+
};
|
|
7731
|
+
};
|
|
7732
|
+
var nestedScene = (parent, children) => ({ ...parent, hud: null, renderTextures: [], children });
|
|
7733
|
+
var hudChanges = (before, after) => {
|
|
7734
|
+
if (before.hud === null && after.hud === null)
|
|
7735
|
+
return { _tag: "Changes", changes: [] };
|
|
7736
|
+
if (after.hud === null)
|
|
7737
|
+
return { _tag: "Changes", changes: [{ place: "hud", _tag: "HudRemoved" }] };
|
|
7738
|
+
const added = before.hud === null ? [{ place: "hud", _tag: "HudAdded" }] : [];
|
|
7739
|
+
const inside = changesIn(nestedScene(before, before.hud?.children ?? []), nestedScene(before, after.hud.children), "hud");
|
|
7740
|
+
return inside._tag === "Invalid" ? inside : { _tag: "Changes", changes: [...added, ...inside.changes] };
|
|
7741
|
+
};
|
|
7742
|
+
var textureChanges = (before, after) => {
|
|
7743
|
+
const changes = [];
|
|
7744
|
+
for (const texture of after.renderTextures) {
|
|
7745
|
+
const was = before.renderTextures.find((candidate) => candidate.id === texture.id);
|
|
7746
|
+
const place = { texture: texture.id };
|
|
7747
|
+
if (was === undefined)
|
|
7748
|
+
changes.push({ place, _tag: "TextureAdded", id: texture.id });
|
|
7749
|
+
const inside = changesIn(nestedScene(before, was?.children ?? []), nestedScene(before, texture.children), place);
|
|
7750
|
+
if (inside._tag === "Invalid")
|
|
7751
|
+
return inside;
|
|
7752
|
+
changes.push(...inside.changes);
|
|
7753
|
+
}
|
|
7754
|
+
for (const texture of before.renderTextures) {
|
|
7755
|
+
if (!after.renderTextures.some((candidate) => candidate.id === texture.id)) {
|
|
7756
|
+
changes.push({ place: { texture: texture.id }, _tag: "TextureRemoved", id: texture.id });
|
|
7757
|
+
}
|
|
7758
|
+
}
|
|
7759
|
+
return { _tag: "Changes", changes };
|
|
7760
|
+
};
|
|
7761
|
+
var sceneChanges2 = (before, after) => {
|
|
7762
|
+
const parts = [
|
|
7763
|
+
changesIn(before, after, "scene"),
|
|
7764
|
+
hudChanges(before, after),
|
|
7765
|
+
textureChanges(before, after)
|
|
7766
|
+
];
|
|
7767
|
+
const invalid = parts.find((part) => part._tag === "Invalid");
|
|
7768
|
+
if (invalid !== undefined)
|
|
7769
|
+
return invalid;
|
|
7770
|
+
return {
|
|
7771
|
+
_tag: "Changes",
|
|
7772
|
+
changes: parts.flatMap((part) => part._tag === "Changes" ? part.changes : [])
|
|
7773
|
+
};
|
|
7774
|
+
};
|
|
7775
|
+
var placeLabel = (place) => {
|
|
7776
|
+
if (place === "scene")
|
|
7777
|
+
return "";
|
|
7778
|
+
return place === "hud" ? "hud " : `texture ${place.texture} `;
|
|
7779
|
+
};
|
|
7780
|
+
var parentLabel = (parent) => parent === null ? "the root" : parent;
|
|
7781
|
+
var lineOf2 = (change) => {
|
|
7782
|
+
const where = placeLabel(change.place);
|
|
7783
|
+
switch (change._tag) {
|
|
7784
|
+
case "Added":
|
|
7785
|
+
return `${where}+ ${change.kind} ${change.key}${change.parent === null ? "" : ` in ${change.parent}`}`;
|
|
7786
|
+
case "Removed":
|
|
7787
|
+
return `${where}- ${change.key}`;
|
|
7788
|
+
case "Replaced":
|
|
7789
|
+
return `${where}± ${change.key}, now a ${change.kind}`;
|
|
7790
|
+
case "Changed":
|
|
7791
|
+
return `${where}~ ${change.key}: ${change.fields.join(", ")}`;
|
|
7792
|
+
case "Moved":
|
|
7793
|
+
return `${where}> ${change.key} to ${parentLabel(change.parent)}`;
|
|
7794
|
+
case "Reordered":
|
|
7795
|
+
return `${where}= order of ${parentLabel(change.parent)}: ${change.keys.join(", ")}`;
|
|
7796
|
+
case "Settings":
|
|
7797
|
+
return `${where}⋯ scene: ${change.settings.join(", ")}`;
|
|
7798
|
+
case "HudAdded":
|
|
7799
|
+
return "+ hud";
|
|
7800
|
+
case "HudRemoved":
|
|
7801
|
+
return "- hud";
|
|
7802
|
+
case "TextureAdded":
|
|
7803
|
+
return `+ texture ${change.id}`;
|
|
7804
|
+
case "TextureRemoved":
|
|
7805
|
+
return `- texture ${change.id}`;
|
|
7806
|
+
}
|
|
7807
|
+
};
|
|
7808
|
+
var formatChanges2 = (changes) => changes.length === 0 ? "No changes." : changes.map(lineOf2).join(`
|
|
7809
|
+
`);
|
|
7810
|
+
// src/kernel/tape.ts
|
|
7811
|
+
var tape2 = (options = {}) => ({
|
|
7812
|
+
from: null,
|
|
7813
|
+
to: null,
|
|
7814
|
+
pointer: null,
|
|
7815
|
+
snap: options.snap ?? null
|
|
7816
|
+
});
|
|
7817
|
+
var snapped2 = (state, point) => {
|
|
7818
|
+
const step = state.snap;
|
|
7819
|
+
if (step === null)
|
|
7820
|
+
return point;
|
|
7821
|
+
return [
|
|
7822
|
+
Math.round(point[0] / step) * step,
|
|
7823
|
+
Math.round(point[1] / step) * step,
|
|
7824
|
+
Math.round(point[2] / step) * step
|
|
7825
|
+
];
|
|
7826
|
+
};
|
|
7827
|
+
var placeTapeEnd2 = (state, point) => {
|
|
7828
|
+
const at = snapped2(state, point);
|
|
7829
|
+
if (state.from !== null && state.to === null)
|
|
7830
|
+
return { ...state, to: at, pointer: null };
|
|
7831
|
+
return { ...state, from: at, to: null, pointer: null };
|
|
7832
|
+
};
|
|
7833
|
+
var pointTape2 = (state, point) => state.from !== null && state.to === null ? { ...state, pointer: point === null ? null : snapped2(state, point) } : state;
|
|
7834
|
+
var clearTape2 = (state) => ({ ...tape2({ snap: state.snap }) });
|
|
7835
|
+
var farEnd = (state) => state.to ?? state.pointer;
|
|
7836
|
+
var distance = (a, b) => Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
|
|
7837
|
+
var tapeLength2 = (state) => {
|
|
7838
|
+
const end = farEnd(state);
|
|
7839
|
+
return state.from === null || end === null ? undefined : distance(state.from, end);
|
|
7840
|
+
};
|
|
7841
|
+
var tapeMiddle2 = (state) => {
|
|
7842
|
+
const end = farEnd(state);
|
|
7843
|
+
if (state.from === null || end === null)
|
|
7844
|
+
return;
|
|
7845
|
+
return [(state.from[0] + end[0]) / 2, (state.from[1] + end[1]) / 2, (state.from[2] + end[2]) / 2];
|
|
7846
|
+
};
|
|
7847
|
+
var endBall = (key, at, look) => mesh2({
|
|
7848
|
+
key,
|
|
7849
|
+
position: at,
|
|
7850
|
+
geometry: sphere2({ radius: look.endRadius, widthSegments: 16, heightSegments: 8 }),
|
|
7851
|
+
material: basic2({ color: look.color })
|
|
7852
|
+
});
|
|
7853
|
+
var tapeNodes2 = (key, state, look = {}) => {
|
|
7854
|
+
const shown = {
|
|
7855
|
+
color: look.color ?? 16763955,
|
|
7856
|
+
width: look.width ?? 3,
|
|
7857
|
+
endRadius: look.endRadius ?? 0.03
|
|
7858
|
+
};
|
|
7859
|
+
const end = farEnd(state);
|
|
7860
|
+
const ends = [state.from, state.to].flatMap((at, index) => at === null ? [] : [endBall(`${key}:end:${index}`, at, shown)]);
|
|
7861
|
+
const span = state.from === null || end === null ? [] : [
|
|
7862
|
+
line2({
|
|
7863
|
+
key: `${key}:line`,
|
|
7864
|
+
points: [state.from, end],
|
|
7865
|
+
color: shown.color,
|
|
7866
|
+
width: shown.width,
|
|
7867
|
+
dashed: state.to === null,
|
|
7868
|
+
dashSize: 0.08,
|
|
7869
|
+
gapSize: 0.05
|
|
7870
|
+
})
|
|
7871
|
+
];
|
|
7872
|
+
return group2({ key, children: [...span, ...ends] });
|
|
7873
|
+
};
|
|
7874
|
+
// src/kernel/pivot.ts
|
|
7875
|
+
import { Euler as Euler7, Quaternion as Quaternion8, Vector3 as Vector317 } from "three";
|
|
7876
|
+
var pivot2 = (options = {}) => ({
|
|
7877
|
+
scale: options.scale ?? 1,
|
|
7878
|
+
depthTest: options.depthTest ?? true,
|
|
7879
|
+
disableAxes: options.disableAxes ?? false,
|
|
7880
|
+
disableSliders: options.disableSliders ?? false,
|
|
7881
|
+
disableRotations: options.disableRotations ?? false,
|
|
7882
|
+
disableScaling: options.disableScaling ?? false,
|
|
7883
|
+
hovered: null,
|
|
7884
|
+
grab: null
|
|
7885
|
+
});
|
|
7886
|
+
var unit = {
|
|
7887
|
+
x: new Vector317(1, 0, 0),
|
|
7888
|
+
y: new Vector317(0, 1, 0),
|
|
7889
|
+
z: new Vector317(0, 0, 1)
|
|
7890
|
+
};
|
|
7891
|
+
var planeOf2 = {
|
|
7892
|
+
z: ["x", "y"],
|
|
7893
|
+
y: ["z", "x"],
|
|
7894
|
+
x: ["y", "z"]
|
|
7895
|
+
};
|
|
7896
|
+
var turnOf2 = (rotation) => new Quaternion8().setFromEuler(new Euler7(rotation[0], rotation[1], rotation[2]));
|
|
7897
|
+
var toVec35 = (vector) => [vector.x, vector.y, vector.z];
|
|
7898
|
+
var kindOf2 = (handle) => handle.split("-")[0];
|
|
7899
|
+
var axisOf = (handle) => handle.split("-")[1];
|
|
7900
|
+
var frameOf = (handle, placement) => {
|
|
7901
|
+
const turn = turnOf2(placement.rotation);
|
|
7902
|
+
const axis = axisOf(handle);
|
|
7903
|
+
const [first, second] = planeOf2[axis];
|
|
7904
|
+
const kind = kindOf2(handle);
|
|
7905
|
+
const flat = kind === "slider" || kind === "rotator";
|
|
7906
|
+
const e1 = (flat ? unit[first] : unit[axis]).clone().applyQuaternion(turn);
|
|
7907
|
+
const e2 = (flat ? unit[second] : unit[axis]).clone().applyQuaternion(turn);
|
|
7908
|
+
return { e1, e2, normal: e1.clone().cross(e2).normalize() };
|
|
7909
|
+
};
|
|
7910
|
+
var pressPivot2 = (state, placement, handle, point) => {
|
|
7911
|
+
const { e1, e2, normal } = frameOf(handle, placement);
|
|
7912
|
+
return {
|
|
7913
|
+
...state,
|
|
7914
|
+
grab: {
|
|
7915
|
+
handle,
|
|
7916
|
+
start: placement,
|
|
7917
|
+
point,
|
|
7918
|
+
e1: toVec35(e1),
|
|
7919
|
+
e2: toVec35(e2),
|
|
7920
|
+
normal: toVec35(kindOf2(handle) === "arrow" || kindOf2(handle) === "sphere" ? e1 : normal)
|
|
7921
|
+
}
|
|
7922
|
+
};
|
|
7923
|
+
};
|
|
7924
|
+
var releasePivot2 = (state) => ({ ...state, grab: null });
|
|
7925
|
+
var hoverPivot2 = (state, handle) => state.hovered === handle ? state : { ...state, hovered: handle };
|
|
7926
|
+
var offsetAlong = (point, direction, ray) => {
|
|
7927
|
+
const origin = new Vector317(...ray.origin);
|
|
7928
|
+
const toward = new Vector317(...ray.direction);
|
|
7929
|
+
const e1 = direction.dot(direction);
|
|
7930
|
+
const e2 = direction.dot(point) - direction.dot(origin);
|
|
7931
|
+
const e3 = direction.dot(toward);
|
|
7932
|
+
if (e3 === 0)
|
|
7933
|
+
return -e2 / e1;
|
|
7934
|
+
const v1 = toward.clone().multiplyScalar(e1 / e3).sub(direction);
|
|
7935
|
+
const v2 = toward.clone().multiplyScalar(e2 / e3).add(origin).sub(point);
|
|
7936
|
+
return -v1.dot(v2) / v1.dot(v1);
|
|
7937
|
+
};
|
|
7938
|
+
var meetPlane = (ray, at, normal) => {
|
|
7939
|
+
const origin = new Vector317(...ray.origin);
|
|
7940
|
+
const toward = new Vector317(...ray.direction);
|
|
7941
|
+
const facing = normal.dot(toward);
|
|
7942
|
+
if (facing === 0)
|
|
7943
|
+
return;
|
|
7944
|
+
return origin.addScaledVector(toward, normal.dot(at.clone().sub(origin)) / facing);
|
|
7945
|
+
};
|
|
7946
|
+
var angleBetween = (from, to, at, e1, e2) => {
|
|
7947
|
+
const a = from.clone().sub(at);
|
|
7948
|
+
const b = to.clone().sub(at);
|
|
7949
|
+
return Math.atan2(b.dot(e2), b.dot(e1)) - Math.atan2(a.dot(e2), a.dot(e1));
|
|
7950
|
+
};
|
|
7951
|
+
var vectorsOf = (grab) => ({
|
|
7952
|
+
point: new Vector317(...grab.point),
|
|
7953
|
+
e1: new Vector317(...grab.e1),
|
|
7954
|
+
e2: new Vector317(...grab.e2),
|
|
7955
|
+
normal: new Vector317(...grab.normal),
|
|
7956
|
+
at: new Vector317(...grab.start.position)
|
|
7957
|
+
});
|
|
7958
|
+
var moved2 = (start, by) => ({
|
|
7959
|
+
...start,
|
|
7960
|
+
position: toVec35(new Vector317(...start.position).add(by))
|
|
7961
|
+
});
|
|
7962
|
+
var arrowDrag = (grab, ray) => {
|
|
7963
|
+
const { point, e1 } = vectorsOf(grab);
|
|
7964
|
+
return moved2(grab.start, e1.clone().multiplyScalar(offsetAlong(point, e1, ray)));
|
|
7965
|
+
};
|
|
7966
|
+
var sliderDrag = (grab, ray) => {
|
|
7967
|
+
const { point, e1, e2, normal, at } = vectorsOf(grab);
|
|
7968
|
+
const meet = meetPlane(ray, at, normal);
|
|
7969
|
+
if (meet === undefined)
|
|
7970
|
+
return grab.start;
|
|
7971
|
+
const offset = meet.sub(point);
|
|
7972
|
+
return moved2(grab.start, e1.multiplyScalar(offset.dot(e1)).add(e2.multiplyScalar(offset.dot(e2))));
|
|
7973
|
+
};
|
|
7974
|
+
var tenDegrees = Math.PI / 18;
|
|
7975
|
+
var rotatorDrag = (grab, ray, snap) => {
|
|
7976
|
+
const { point, e1, e2, normal, at } = vectorsOf(grab);
|
|
7977
|
+
const meet = meetPlane(ray, at, normal);
|
|
7978
|
+
if (meet === undefined)
|
|
7979
|
+
return grab.start;
|
|
7980
|
+
const turned = angleBetween(point, meet, at, e1, e2);
|
|
7981
|
+
const angle = snap ? Math.round(turned / tenDegrees) * tenDegrees : turned;
|
|
7982
|
+
const turn = new Quaternion8().setFromAxisAngle(normal, angle).multiply(turnOf2(grab.start.rotation));
|
|
7983
|
+
const euler = new Euler7().setFromQuaternion(turn.normalize());
|
|
7984
|
+
return { ...grab.start, rotation: [euler.x, euler.y, euler.z] };
|
|
7985
|
+
};
|
|
7986
|
+
var sphereDrag = (state, grab, ray, snap) => {
|
|
7987
|
+
const { point, e1 } = vectorsOf(grab);
|
|
7988
|
+
const grown = 2 ** (offsetAlong(point, e1, ray) / state.scale * 0.2);
|
|
7989
|
+
const factor = Math.max(snap ? Math.round(grown * 10) / 10 : grown, 0.00001);
|
|
7990
|
+
const index = { x: 0, y: 1, z: 2 }[axisOf(grab.handle)];
|
|
7991
|
+
const scale = [
|
|
7992
|
+
grab.start.scale[0] * (index === 0 ? factor : 1),
|
|
7993
|
+
grab.start.scale[1] * (index === 1 ? factor : 1),
|
|
7994
|
+
grab.start.scale[2] * (index === 2 ? factor : 1)
|
|
7995
|
+
];
|
|
7996
|
+
return { ...grab.start, scale };
|
|
7997
|
+
};
|
|
7998
|
+
var dragPivot2 = (state, ray, options = {}) => {
|
|
7999
|
+
const grab = state.grab;
|
|
8000
|
+
if (grab === null)
|
|
8001
|
+
return;
|
|
8002
|
+
const snap = options.snap ?? false;
|
|
8003
|
+
const kind = kindOf2(grab.handle);
|
|
8004
|
+
if (kind === "arrow")
|
|
8005
|
+
return arrowDrag(grab, ray);
|
|
8006
|
+
if (kind === "slider")
|
|
8007
|
+
return sliderDrag(grab, ray);
|
|
8008
|
+
if (kind === "rotator")
|
|
8009
|
+
return rotatorDrag(grab, ray, snap);
|
|
8010
|
+
return sphereDrag(state, grab, ray, snap);
|
|
8011
|
+
};
|
|
8012
|
+
var colours2 = { x: 16719968, y: 2154368, z: 2130175 };
|
|
8013
|
+
var hoveredColour = 16777024;
|
|
8014
|
+
var handles = ["arrow", "slider", "rotator", "sphere"];
|
|
8015
|
+
var pivotHandleOf2 = (key, hit) => {
|
|
8016
|
+
const [owner, name] = hit.split(":");
|
|
8017
|
+
if (owner !== key)
|
|
8018
|
+
return;
|
|
8019
|
+
return handles.flatMap((kind) => ["x", "y", "z"].map((axis) => `${kind}-${axis}`)).find((handle) => handle === name);
|
|
8020
|
+
};
|
|
8021
|
+
var lookOf = (state, handle) => basic2({
|
|
8022
|
+
color: state.grab?.handle === handle || state.hovered === handle ? hoveredColour : colours2[axisOf(handle)],
|
|
8023
|
+
depthTest: state.depthTest,
|
|
8024
|
+
side: "double"
|
|
8025
|
+
});
|
|
8026
|
+
var unseen = basic2({ opacity: 0, transparent: true, depthTest: false });
|
|
8027
|
+
var pointAlong2 = {
|
|
8028
|
+
x: [0, 0, -Math.PI / 2],
|
|
8029
|
+
y: [0, 0, 0],
|
|
8030
|
+
z: [Math.PI / 2, 0, 0]
|
|
8031
|
+
};
|
|
8032
|
+
var along = (axis, distance) => {
|
|
8033
|
+
const { x, y, z } = unit[axis];
|
|
8034
|
+
return [x * distance, y * distance, z * distance];
|
|
8035
|
+
};
|
|
8036
|
+
var arrowNodes = (key, state, axis) => {
|
|
8037
|
+
const handle = `arrow-${axis}`;
|
|
8038
|
+
const size = state.scale;
|
|
8039
|
+
const coneLength = size / 5;
|
|
8040
|
+
const stem = size - coneLength;
|
|
8041
|
+
const material = lookOf(state, handle);
|
|
8042
|
+
return [
|
|
8043
|
+
mesh2({
|
|
8044
|
+
key: `${key}:${handle}:stem`,
|
|
8045
|
+
position: along(axis, stem / 2),
|
|
8046
|
+
rotation: fixed2(pointAlong2[axis]),
|
|
8047
|
+
geometry: cylinder2({ radiusTop: size / 80, radiusBottom: size / 80, height: stem }),
|
|
8048
|
+
material
|
|
8049
|
+
}),
|
|
8050
|
+
mesh2({
|
|
8051
|
+
key: `${key}:${handle}:hit`,
|
|
8052
|
+
position: along(axis, size / 2),
|
|
8053
|
+
rotation: fixed2(pointAlong2[axis]),
|
|
8054
|
+
geometry: cylinder2({ radiusTop: size * 0.07, radiusBottom: size * 0.07, height: size }),
|
|
8055
|
+
material: unseen,
|
|
8056
|
+
interactive: true
|
|
8057
|
+
}),
|
|
8058
|
+
mesh2({
|
|
8059
|
+
key: `${key}:${handle}:cone`,
|
|
8060
|
+
position: along(axis, stem + coneLength / 2),
|
|
8061
|
+
rotation: fixed2(pointAlong2[axis]),
|
|
8062
|
+
geometry: cone2({ radius: size / 20, height: coneLength, radialSegments: 24 }),
|
|
8063
|
+
material,
|
|
8064
|
+
interactive: true
|
|
8065
|
+
})
|
|
8066
|
+
];
|
|
8067
|
+
};
|
|
8068
|
+
var ontoPlane = {
|
|
8069
|
+
z: [0, 0, 0],
|
|
8070
|
+
y: [-Math.PI / 2, 0, -Math.PI / 2],
|
|
8071
|
+
x: [Math.PI / 2, Math.PI / 2, 0]
|
|
8072
|
+
};
|
|
8073
|
+
var sliderNode = (key, state, axis) => {
|
|
8074
|
+
const handle = `slider-${axis}`;
|
|
8075
|
+
const out = state.scale / 7 * 1.7;
|
|
8076
|
+
const side = state.scale * 0.225;
|
|
8077
|
+
return group2({
|
|
8078
|
+
key: `${key}:${handle}`,
|
|
8079
|
+
rotation: fixed2(ontoPlane[axis]),
|
|
8080
|
+
children: [
|
|
8081
|
+
mesh2({
|
|
8082
|
+
key: `${key}:${handle}:square`,
|
|
8083
|
+
position: [out, out, 0],
|
|
8084
|
+
geometry: plane2({ width: side, height: side }),
|
|
8085
|
+
material: lookOf(state, handle),
|
|
8086
|
+
interactive: true
|
|
8087
|
+
})
|
|
8088
|
+
]
|
|
8089
|
+
});
|
|
8090
|
+
};
|
|
8091
|
+
var arcSegments = 8;
|
|
8092
|
+
var rotatorNode = (key, state, axis) => {
|
|
8093
|
+
const handle = `rotator-${axis}`;
|
|
8094
|
+
const radius = state.scale * 0.65;
|
|
8095
|
+
const step = Math.PI / 2 / arcSegments;
|
|
8096
|
+
const chord = 2 * radius * Math.sin(step / 2);
|
|
8097
|
+
const segment = (index, part) => {
|
|
8098
|
+
const middle = step * (index + 0.5);
|
|
8099
|
+
const thickness = part === "line" ? radius / 50 : state.scale * 0.03;
|
|
8100
|
+
return mesh2({
|
|
8101
|
+
key: `${key}:${handle}:${part}:${index}`,
|
|
8102
|
+
position: [Math.cos(middle) * radius, Math.sin(middle) * radius, 0],
|
|
8103
|
+
rotation: fixed2([0, 0, middle]),
|
|
8104
|
+
geometry: cylinder2({ radiusTop: thickness, radiusBottom: thickness, height: chord }),
|
|
8105
|
+
material: part === "line" ? lookOf(state, handle) : unseen,
|
|
8106
|
+
interactive: part === "hit"
|
|
8107
|
+
});
|
|
8108
|
+
};
|
|
8109
|
+
const indices = Array.from({ length: arcSegments }, (_, index) => index);
|
|
8110
|
+
return group2({
|
|
8111
|
+
key: `${key}:${handle}`,
|
|
8112
|
+
rotation: fixed2(ontoPlane[axis]),
|
|
8113
|
+
children: [
|
|
8114
|
+
...indices.map((index) => segment(index, "line")),
|
|
8115
|
+
...indices.map((index) => segment(index, "hit"))
|
|
8116
|
+
]
|
|
8117
|
+
});
|
|
8118
|
+
};
|
|
8119
|
+
var sphereNode = (key, state, axis) => mesh2({
|
|
8120
|
+
key: `${key}:sphere-${axis}`,
|
|
8121
|
+
position: along(axis, state.scale * 1.2),
|
|
8122
|
+
geometry: sphere2({ radius: state.scale / 22.5, widthSegments: 12, heightSegments: 12 }),
|
|
8123
|
+
material: lookOf(state, `sphere-${axis}`),
|
|
8124
|
+
interactive: true
|
|
8125
|
+
});
|
|
8126
|
+
var axesOf = ["x", "y", "z"];
|
|
8127
|
+
var pivotNodes2 = (key, state, placement) => group2({
|
|
8128
|
+
key,
|
|
8129
|
+
position: placement.position,
|
|
8130
|
+
rotation: fixed2(placement.rotation),
|
|
8131
|
+
children: [
|
|
8132
|
+
...state.disableAxes ? [] : axesOf.flatMap((axis) => arrowNodes(key, state, axis)),
|
|
8133
|
+
...state.disableSliders ? [] : axesOf.map((axis) => sliderNode(key, state, axis)),
|
|
8134
|
+
...state.disableRotations ? [] : axesOf.map((axis) => rotatorNode(key, state, axis)),
|
|
8135
|
+
...state.disableScaling ? [] : axesOf.map((axis) => sphereNode(key, state, axis))
|
|
8136
|
+
]
|
|
8137
|
+
});
|
|
8138
|
+
// src/kernel/viewportGizmo.ts
|
|
8139
|
+
import { Euler as Euler8, Matrix4 as Matrix46, Quaternion as Quaternion9, Vector3 as Vector318 } from "three";
|
|
8140
|
+
var colours3 = { x: 16719968, y: 2154368, z: 2130175 };
|
|
8141
|
+
var ink = 0;
|
|
8142
|
+
var directions = {
|
|
8143
|
+
x: [1, 0, 0],
|
|
8144
|
+
y: [0, 1, 0],
|
|
8145
|
+
z: [0, 0, 1],
|
|
8146
|
+
"-x": [-1, 0, 0],
|
|
8147
|
+
"-y": [0, -1, 0],
|
|
8148
|
+
"-z": [0, 0, -1]
|
|
8149
|
+
};
|
|
8150
|
+
var axes2 = ["x", "y", "z", "-x", "-y", "-z"];
|
|
8151
|
+
var cameraTurn = (camera) => new Quaternion9().setFromRotationMatrix(new Matrix46().lookAt(new Vector318(...camera.position), new Vector318(...camera.lookAt), new Vector318(0, 1, 0)));
|
|
8152
|
+
var gizmoTurn = (camera) => {
|
|
8153
|
+
const turn = new Euler8().setFromQuaternion(cameraTurn(camera).invert());
|
|
8154
|
+
return [turn.x, turn.y, turn.z];
|
|
8155
|
+
};
|
|
8156
|
+
var stroke = (key, length, angle, at) => mesh2({
|
|
8157
|
+
key,
|
|
8158
|
+
position: [at[0], at[1], 0.01],
|
|
8159
|
+
rotation: fixed2([0, 0, angle]),
|
|
8160
|
+
geometry: box2({ width: length, height: 0.07, depth: 0.001 }),
|
|
8161
|
+
material: basic2({ color: ink })
|
|
8162
|
+
});
|
|
8163
|
+
var letters = {
|
|
8164
|
+
x: [
|
|
8165
|
+
[0.34, Math.PI / 4, [0, 0]],
|
|
8166
|
+
[0.34, -Math.PI / 4, [0, 0]]
|
|
8167
|
+
],
|
|
8168
|
+
y: [
|
|
8169
|
+
[0.14, Math.PI / 2, [0, -0.07]],
|
|
8170
|
+
[0.17, Math.PI / 3, [0.04, 0.06]],
|
|
8171
|
+
[0.17, -Math.PI / 3, [-0.04, 0.06]]
|
|
8172
|
+
],
|
|
8173
|
+
z: [
|
|
8174
|
+
[0.22, 0, [0, 0.11]],
|
|
8175
|
+
[0.22, 0, [0, -0.11]],
|
|
8176
|
+
[0.3, Math.PI / 4, [0, 0]]
|
|
8177
|
+
]
|
|
8178
|
+
};
|
|
8179
|
+
var isPositive = (axis) => axis.length === 1;
|
|
8180
|
+
var colourOf2 = (axis) => colours3[isPositive(axis) ? axis : axis.slice(1)];
|
|
8181
|
+
var headScale = (axis, hovered) => (isPositive(axis) ? 1 : 0.75) * (axis === hovered ? 1.2 : 1);
|
|
8182
|
+
var labelOf2 = (key, axis) => isPositive(axis) ? letters[axis].map(([length, angle, at], index) => stroke(`${key}:${axis}:letter:${index}`, length, angle, at)) : [];
|
|
8183
|
+
var head = (key, axis, hovered) => {
|
|
8184
|
+
const scale = headScale(axis, hovered);
|
|
8185
|
+
return group2({
|
|
8186
|
+
key: `${key}:${axis}`,
|
|
8187
|
+
position: directions[axis],
|
|
8188
|
+
rotation: billboard2(),
|
|
8189
|
+
scale: [scale, scale, scale],
|
|
8190
|
+
interactive: true,
|
|
8191
|
+
children: [
|
|
8192
|
+
mesh2({
|
|
8193
|
+
key: `${key}:${axis}:disc`,
|
|
8194
|
+
geometry: circle2({ radius: 0.25, segments: 32 }),
|
|
8195
|
+
material: basic2({
|
|
8196
|
+
color: colourOf2(axis),
|
|
8197
|
+
opacity: isPositive(axis) ? 1 : 0.75,
|
|
8198
|
+
transparent: !isPositive(axis)
|
|
8199
|
+
})
|
|
8200
|
+
}),
|
|
8201
|
+
...labelOf2(key, axis)
|
|
8202
|
+
]
|
|
8203
|
+
});
|
|
8204
|
+
};
|
|
8205
|
+
var bar = (key, axis) => {
|
|
8206
|
+
const [x, y, z] = directions[axis];
|
|
8207
|
+
return mesh2({
|
|
8208
|
+
key: `${key}:${axis}:bar`,
|
|
8209
|
+
position: [x * 0.4, y * 0.4, z * 0.4],
|
|
8210
|
+
geometry: box2({
|
|
8211
|
+
width: axis === "x" ? 0.8 : 0.05,
|
|
8212
|
+
height: axis === "y" ? 0.8 : 0.05,
|
|
8213
|
+
depth: axis === "z" ? 0.8 : 0.05
|
|
8214
|
+
}),
|
|
8215
|
+
material: basic2({ color: colours3[axis] })
|
|
8216
|
+
});
|
|
8217
|
+
};
|
|
8218
|
+
var viewportGizmoNodes2 = (key, camera, options = {}) => {
|
|
8219
|
+
const size = options.size ?? 40;
|
|
8220
|
+
const hovered = options.hovered ?? null;
|
|
8221
|
+
const shown = options.hideNegativeAxes === true ? axes2.filter(isPositive) : axes2;
|
|
8222
|
+
return group2({
|
|
8223
|
+
key,
|
|
8224
|
+
rotation: fixed2(gizmoTurn(camera)),
|
|
8225
|
+
scale: [size, size, size],
|
|
8226
|
+
children: [
|
|
8227
|
+
bar(key, "x"),
|
|
8228
|
+
bar(key, "y"),
|
|
8229
|
+
bar(key, "z"),
|
|
8230
|
+
...shown.map((axis) => head(key, axis, hovered))
|
|
8231
|
+
]
|
|
8232
|
+
});
|
|
8233
|
+
};
|
|
8234
|
+
var viewportAxisOf2 = (key, hit) => {
|
|
8235
|
+
const [owner, axis] = hit.split(":");
|
|
8236
|
+
if (owner !== key)
|
|
8237
|
+
return;
|
|
8238
|
+
return axes2.find((candidate) => candidate === axis);
|
|
8239
|
+
};
|
|
8240
|
+
var cameraAlong2 = (camera, axis) => {
|
|
8241
|
+
const target = new Vector318(...camera.lookAt);
|
|
8242
|
+
const distance = new Vector318(...camera.position).distanceTo(target);
|
|
8243
|
+
const direction = new Vector318(...directions[axis]);
|
|
8244
|
+
if (axis === "y" || axis === "-y")
|
|
8245
|
+
direction.z = 0.000001;
|
|
8246
|
+
const position = direction.normalize().multiplyScalar(distance).add(target);
|
|
8247
|
+
return { ...camera, position: [position.x, position.y, position.z] };
|
|
8248
|
+
};
|
|
8249
|
+
export { __export, handJoints2, clipTime2, clipRunning2, createPose2, resetPose2, float2, builtinBehaviours2, spinAngle2, writeRotation2, buildMaterial2, updateMaterial2, vec3Equals2, rotationEquals2, shapeEquals2, geometryRefEquals2, instanceEquals2, instancesEqual2, behaviourEquals2, animationEquals2, transitionEquals2, materialRefEquals2, cameraEquals2, renderSettingsEquals2, effectsEqual2, viewsEqual2, resourcesEqual2, overlaysEqual2, environmentEquals2, skyEquals2, contactShadowsEquals2, bodyEquals2, assetsEqual2, physicsEquals2, xrEquals2, capacityFor2, createPerformanceMonitor2, easeProgress2, startTween2, applyTween2, fixed2, spin2, billboard2, box2, sphere2, plane2, cylinder2, torus2, cone2, capsule2, roundedBox2, backdrop2, ring2, circle2, text2, instant2, ease2, basic2, lambert2, phong2, standard2, physical2, normalMaterial2, shadowMaterial2, grid2, shaderGrid2, sharedGeometry2, lentGeometry2, sharedMaterial2, group2, detailed2, line2, points2, sparkles2, stars2, catmullRomPoints2, catmullRomPointAt2, catmullRomColors2, cubicBezierPoints2, quadraticBezierPoints2, headSpace2, jointSpace2, controllerSpace2, anchorSpace2, planeSpace2, meshSpace2, xrMeshGeometryId2, xrMesh2, xrAnchor2, mesh2, trail2, edges2, body2, interactionGroups2, cuboidCollider2, ballCollider2, capsuleCollider2, cylinderCollider2, coneCollider2, velocityMotor2, positionMotor2, physics2, bodyRef2, joint2, fixedJoint2, sphericalJoint2, revoluteJoint2, prismaticJoint2, ropeJoint2, springJoint2, glide2, xr2, instance2, instances2, behave2, play2, borrowed2, label2, colorRange2, ambientLight2, directionalLight2, pointLight2, spotLight2, hemisphereLight2, perspectiveCamera2, orthographicCamera2, cameraShake2, bloom2, vignette2, film2, renderSettings2, view2, renderTexture2, environment2, sunPositionFromAngles2, sky2, contactShadows2, modelAsset2, textureAsset2, environmentAsset2, fontAsset2, overlay2, hud2, scene2, emptyIndex2, indexScene2, changedFields2, diff2, createResourceStore2, createSceneClock2, createManualFrames2, createGatedFrames2, createFramePacer2, defaultOrbit2, orbitOptions2, rotateCamera2, dollyCamera2, panCamera2, dollyCameraToward2, orbit2, orbitKey2, autoRotated2, fitCamera2, clipCamera2, placeOverlays2, interactionBits2, snapshotText2, snapshotBytes2, colliderFor2, describedColliders2, collidersFor2, colliderSignature2, locomote2, teleport2, glided2, createXrTracker2, environmentPresets2, environmentPresetUrl2, stagePresets2, stage2, centerOffset2, stageBounds2, noModifiers2, pointOnPlane2, createPicker2, createPointerTracker2, createSceneLoop2, recordingRendererFactory2, createSceneGraph2, previewSvg2, gizmo2, pressGizmo2, releaseGizmo2, hoverGizmo2, dragGizmo2, movedAlike2, gizmoHandleOf2, gizmoNodes2, boxSelect2, exports_history, exports_lockstep, exports_timeline, thingsBounds2, describeScene2, formatSummary2, shotAngles2, shotCamera2, moods2, moodStaging2, inspectFields2, setAt2, sceneChanges2, formatChanges2, tape2, placeTapeEnd2, pointTape2, clearTape2, tapeLength2, tapeMiddle2, tapeNodes2, pivot2, pressPivot2, releasePivot2, hoverPivot2, dragPivot2, pivotHandleOf2, pivotNodes2, viewportGizmoNodes2, viewportAxisOf2, cameraAlong2 };
|
|
5419
8250
|
|
|
5420
|
-
//# debugId=
|
|
5421
|
-
//# sourceMappingURL=index-
|
|
8251
|
+
//# debugId=0311CB843C4BF34064756E2164756E21
|
|
8252
|
+
//# sourceMappingURL=index-re3rrfwd.js.map
|