worldorbit 2.6.0 → 3.0.1
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/README.md +20 -9
- package/dist/browser/core/dist/atlas-edit.d.ts +11 -0
- package/dist/browser/core/dist/atlas-edit.js +347 -0
- package/dist/browser/core/dist/atlas-utils.d.ts +22 -0
- package/dist/browser/core/dist/atlas-utils.js +189 -0
- package/dist/browser/core/dist/atlas-validate.d.ts +2 -0
- package/dist/browser/core/dist/atlas-validate.js +488 -0
- package/dist/browser/core/dist/diagnostics.d.ts +10 -0
- package/dist/browser/core/dist/diagnostics.js +109 -0
- package/dist/browser/core/dist/draft-parse.d.ts +3 -0
- package/dist/browser/core/dist/draft-parse.js +1654 -0
- package/dist/browser/core/dist/draft.d.ts +21 -0
- package/dist/browser/core/dist/draft.js +482 -0
- package/dist/browser/core/dist/errors.d.ts +7 -0
- package/dist/browser/core/dist/errors.js +16 -0
- package/dist/browser/core/dist/format.d.ts +4 -0
- package/dist/browser/core/dist/format.js +613 -0
- package/dist/browser/core/dist/index.d.ts +29 -0
- package/dist/browser/core/dist/index.js +35 -6542
- package/dist/browser/core/dist/load.d.ts +4 -0
- package/dist/browser/core/dist/load.js +182 -0
- package/dist/browser/core/dist/markdown.d.ts +2 -0
- package/dist/browser/core/dist/markdown.js +37 -0
- package/dist/browser/core/dist/normalize.d.ts +2 -0
- package/dist/browser/core/dist/normalize.js +312 -0
- package/dist/browser/core/dist/parse.d.ts +2 -0
- package/dist/browser/core/dist/parse.js +133 -0
- package/dist/browser/core/dist/scene.d.ts +3 -0
- package/dist/browser/core/dist/scene.js +1901 -0
- package/dist/browser/core/dist/schema.d.ts +8 -0
- package/dist/browser/core/dist/schema.js +298 -0
- package/dist/browser/core/dist/spatial-scene.d.ts +3 -0
- package/dist/browser/core/dist/spatial-scene.js +420 -0
- package/dist/browser/core/dist/tokenize.d.ts +4 -0
- package/dist/browser/core/dist/tokenize.js +68 -0
- package/dist/browser/core/dist/types.d.ts +637 -0
- package/dist/browser/core/dist/types.js +1 -0
- package/dist/browser/core/dist/validate.d.ts +2 -0
- package/dist/browser/core/dist/validate.js +56 -0
- package/dist/browser/editor/dist/editor.d.ts +2 -0
- package/dist/browser/editor/dist/editor.js +3700 -0
- package/dist/browser/editor/dist/index.d.ts +2 -0
- package/dist/browser/editor/dist/index.js +1 -12250
- package/dist/browser/editor/dist/types.d.ts +59 -0
- package/dist/browser/editor/dist/types.js +1 -0
- package/dist/browser/markdown/dist/html.d.ts +3 -0
- package/dist/browser/markdown/dist/html.js +64 -0
- package/dist/browser/markdown/dist/index.d.ts +4 -0
- package/dist/browser/markdown/dist/index.js +3 -6179
- package/dist/browser/markdown/dist/rehype.d.ts +10 -0
- package/dist/browser/markdown/dist/rehype.js +49 -0
- package/dist/browser/markdown/dist/remark.d.ts +9 -0
- package/dist/browser/markdown/dist/remark.js +28 -0
- package/dist/browser/markdown/dist/types.d.ts +11 -0
- package/dist/browser/markdown/dist/types.js +1 -0
- package/dist/browser/viewer/dist/atlas-state.d.ts +12 -0
- package/dist/browser/viewer/dist/atlas-state.js +269 -0
- package/dist/browser/viewer/dist/atlas-viewer.d.ts +2 -0
- package/dist/browser/viewer/dist/atlas-viewer.js +495 -0
- package/dist/browser/viewer/dist/custom-element.d.ts +1 -0
- package/dist/browser/viewer/dist/custom-element.js +78 -0
- package/dist/browser/viewer/dist/embed.d.ts +24 -0
- package/dist/browser/viewer/dist/embed.js +172 -0
- package/dist/browser/viewer/dist/errors.d.ts +6 -0
- package/dist/browser/viewer/dist/errors.js +12 -0
- package/dist/browser/viewer/dist/index.d.ts +10 -0
- package/dist/browser/viewer/dist/index.js +9 -8334
- package/dist/browser/viewer/dist/minimap.d.ts +3 -0
- package/dist/browser/viewer/dist/minimap.js +63 -0
- package/dist/browser/viewer/dist/render.d.ts +6 -0
- package/dist/browser/viewer/dist/render.js +670 -0
- package/dist/browser/viewer/dist/runtime-3d.d.ts +19 -0
- package/dist/browser/viewer/dist/runtime-3d.js +494 -0
- package/dist/browser/viewer/dist/theme.d.ts +4 -0
- package/dist/browser/viewer/dist/theme.js +103 -0
- package/dist/browser/viewer/dist/tooltip.d.ts +3 -0
- package/dist/browser/viewer/dist/tooltip.js +198 -0
- package/dist/browser/viewer/dist/types.d.ts +292 -0
- package/dist/browser/viewer/dist/types.js +1 -0
- package/dist/browser/viewer/dist/vendor/three.module.js +53032 -0
- package/dist/browser/viewer/dist/viewer-state.d.ts +19 -0
- package/dist/browser/viewer/dist/viewer-state.js +162 -0
- package/dist/browser/viewer/dist/viewer.d.ts +2 -0
- package/dist/browser/viewer/dist/viewer.js +1662 -0
- package/dist/unpkg/core/dist/atlas-edit.d.ts +11 -0
- package/dist/unpkg/core/dist/atlas-edit.js +347 -0
- package/dist/unpkg/core/dist/atlas-utils.d.ts +22 -0
- package/dist/unpkg/core/dist/atlas-utils.js +189 -0
- package/dist/unpkg/core/dist/atlas-validate.d.ts +2 -0
- package/dist/unpkg/core/dist/atlas-validate.js +488 -0
- package/dist/unpkg/core/dist/diagnostics.d.ts +10 -0
- package/dist/unpkg/core/dist/diagnostics.js +109 -0
- package/dist/unpkg/core/dist/draft-parse.d.ts +3 -0
- package/dist/unpkg/core/dist/draft-parse.js +1654 -0
- package/dist/unpkg/core/dist/draft.d.ts +21 -0
- package/dist/unpkg/core/dist/draft.js +482 -0
- package/dist/unpkg/core/dist/errors.d.ts +7 -0
- package/dist/unpkg/core/dist/errors.js +16 -0
- package/dist/unpkg/core/dist/format.d.ts +4 -0
- package/dist/unpkg/core/dist/format.js +613 -0
- package/dist/unpkg/core/dist/index.d.ts +29 -0
- package/dist/unpkg/core/dist/index.js +35 -6614
- package/dist/unpkg/core/dist/load.d.ts +4 -0
- package/dist/unpkg/core/dist/load.js +182 -0
- package/dist/unpkg/core/dist/markdown.d.ts +2 -0
- package/dist/unpkg/core/dist/markdown.js +37 -0
- package/dist/unpkg/core/dist/normalize.d.ts +2 -0
- package/dist/unpkg/core/dist/normalize.js +312 -0
- package/dist/unpkg/core/dist/parse.d.ts +2 -0
- package/dist/unpkg/core/dist/parse.js +133 -0
- package/dist/unpkg/core/dist/scene.d.ts +3 -0
- package/dist/unpkg/core/dist/scene.js +1901 -0
- package/dist/unpkg/core/dist/schema.d.ts +8 -0
- package/dist/unpkg/core/dist/schema.js +298 -0
- package/dist/unpkg/core/dist/spatial-scene.d.ts +3 -0
- package/dist/unpkg/core/dist/spatial-scene.js +420 -0
- package/dist/unpkg/core/dist/tokenize.d.ts +4 -0
- package/dist/unpkg/core/dist/tokenize.js +68 -0
- package/dist/unpkg/core/dist/types.d.ts +637 -0
- package/dist/unpkg/core/dist/types.js +1 -0
- package/dist/unpkg/core/dist/validate.d.ts +2 -0
- package/dist/unpkg/core/dist/validate.js +56 -0
- package/dist/unpkg/editor/dist/editor.d.ts +2 -0
- package/dist/unpkg/editor/dist/editor.js +3700 -0
- package/dist/unpkg/editor/dist/index.d.ts +2 -0
- package/dist/unpkg/editor/dist/index.js +1 -12275
- package/dist/unpkg/editor/dist/types.d.ts +59 -0
- package/dist/unpkg/editor/dist/types.js +1 -0
- package/dist/unpkg/markdown/dist/html.d.ts +3 -0
- package/dist/unpkg/markdown/dist/html.js +64 -0
- package/dist/unpkg/markdown/dist/index.d.ts +4 -0
- package/dist/unpkg/markdown/dist/index.js +3 -6207
- package/dist/unpkg/markdown/dist/rehype.d.ts +10 -0
- package/dist/unpkg/markdown/dist/rehype.js +49 -0
- package/dist/unpkg/markdown/dist/remark.d.ts +9 -0
- package/dist/unpkg/markdown/dist/remark.js +28 -0
- package/dist/unpkg/markdown/dist/types.d.ts +11 -0
- package/dist/unpkg/markdown/dist/types.js +1 -0
- package/dist/unpkg/viewer/dist/atlas-state.d.ts +12 -0
- package/dist/unpkg/viewer/dist/atlas-state.js +269 -0
- package/dist/unpkg/viewer/dist/atlas-viewer.d.ts +2 -0
- package/dist/unpkg/viewer/dist/atlas-viewer.js +495 -0
- package/dist/unpkg/viewer/dist/custom-element.d.ts +1 -0
- package/dist/unpkg/viewer/dist/custom-element.js +78 -0
- package/dist/unpkg/viewer/dist/embed.d.ts +24 -0
- package/dist/unpkg/viewer/dist/embed.js +172 -0
- package/dist/unpkg/viewer/dist/errors.d.ts +6 -0
- package/dist/unpkg/viewer/dist/errors.js +12 -0
- package/dist/unpkg/viewer/dist/index.d.ts +10 -0
- package/dist/unpkg/viewer/dist/index.js +9 -8391
- package/dist/unpkg/viewer/dist/minimap.d.ts +3 -0
- package/dist/unpkg/viewer/dist/minimap.js +63 -0
- package/dist/unpkg/viewer/dist/render.d.ts +6 -0
- package/dist/unpkg/viewer/dist/render.js +670 -0
- package/dist/unpkg/viewer/dist/runtime-3d.d.ts +19 -0
- package/dist/unpkg/viewer/dist/runtime-3d.js +494 -0
- package/dist/unpkg/viewer/dist/theme.d.ts +4 -0
- package/dist/unpkg/viewer/dist/theme.js +103 -0
- package/dist/unpkg/viewer/dist/tooltip.d.ts +3 -0
- package/dist/unpkg/viewer/dist/tooltip.js +198 -0
- package/dist/unpkg/viewer/dist/types.d.ts +292 -0
- package/dist/unpkg/viewer/dist/types.js +1 -0
- package/dist/unpkg/viewer/dist/vendor/three.module.js +53032 -0
- package/dist/unpkg/viewer/dist/viewer-state.d.ts +19 -0
- package/dist/unpkg/viewer/dist/viewer-state.js +162 -0
- package/dist/unpkg/viewer/dist/viewer.d.ts +2 -0
- package/dist/unpkg/viewer/dist/viewer.js +1662 -0
- package/dist/unpkg/worldorbit-core.min.js +10 -10
- package/dist/unpkg/worldorbit-editor.min.js +4109 -256
- package/dist/unpkg/worldorbit-markdown.min.js +26 -26
- package/dist/unpkg/worldorbit-viewer.min.js +3945 -92
- package/dist/unpkg/worldorbit.js +32219 -199
- package/dist/unpkg/worldorbit.min.js +3949 -96
- package/package.json +1 -1
- package/packages/core/dist/index.d.ts +1 -0
- package/packages/core/dist/index.js +1 -0
- package/packages/core/dist/spatial-scene.d.ts +3 -0
- package/packages/core/dist/spatial-scene.js +420 -0
- package/packages/core/dist/types.d.ts +105 -0
- package/packages/editor/dist/editor.js +25 -4
- package/packages/editor/dist/types.d.ts +4 -0
- package/packages/markdown/dist/html.js +10 -3
- package/packages/viewer/dist/atlas-state.js +3 -0
- package/packages/viewer/dist/atlas-viewer.js +1 -0
- package/packages/viewer/dist/custom-element.js +18 -4
- package/packages/viewer/dist/embed.d.ts +5 -1
- package/packages/viewer/dist/embed.js +58 -24
- package/packages/viewer/dist/errors.d.ts +6 -0
- package/packages/viewer/dist/errors.js +12 -0
- package/packages/viewer/dist/index.d.ts +1 -0
- package/packages/viewer/dist/index.js +1 -0
- package/packages/viewer/dist/runtime-3d.d.ts +19 -0
- package/packages/viewer/dist/runtime-3d.js +494 -0
- package/packages/viewer/dist/types.d.ts +21 -2
- package/packages/viewer/dist/vendor/three.module.js +53032 -0
- package/packages/viewer/dist/viewer.js +501 -41
package/package.json
CHANGED
|
@@ -7,6 +7,7 @@ export { normalizeDocument } from "./normalize.js";
|
|
|
7
7
|
export { validateDocument } from "./validate.js";
|
|
8
8
|
export { createDiagnostic, diagnosticFromError, normalizeWithDiagnostics, parseWithDiagnostics, validateDocumentWithDiagnostics, } from "./diagnostics.js";
|
|
9
9
|
export { renderDocumentToScene, rotatePoint } from "./scene.js";
|
|
10
|
+
export { evaluateSpatialSceneAtTime, renderDocumentToSpatialScene, } from "./spatial-scene.js";
|
|
10
11
|
export { formatAtlasDocument, formatDocument, formatDraftDocument } from "./format.js";
|
|
11
12
|
export { materializeAtlasDocument, materializeDraftDocument, upgradeDocumentToDraftV2, upgradeDocumentToV2, } from "./draft.js";
|
|
12
13
|
export { parseWorldOrbitAtlas, parseWorldOrbitDraft } from "./draft-parse.js";
|
|
@@ -7,6 +7,7 @@ export { normalizeDocument } from "./normalize.js";
|
|
|
7
7
|
export { validateDocument } from "./validate.js";
|
|
8
8
|
export { createDiagnostic, diagnosticFromError, normalizeWithDiagnostics, parseWithDiagnostics, validateDocumentWithDiagnostics, } from "./diagnostics.js";
|
|
9
9
|
export { renderDocumentToScene, rotatePoint } from "./scene.js";
|
|
10
|
+
export { evaluateSpatialSceneAtTime, renderDocumentToSpatialScene, } from "./spatial-scene.js";
|
|
10
11
|
export { formatAtlasDocument, formatDocument, formatDraftDocument } from "./format.js";
|
|
11
12
|
export { materializeAtlasDocument, materializeDraftDocument, upgradeDocumentToDraftV2, upgradeDocumentToV2, } from "./draft.js";
|
|
12
13
|
export { parseWorldOrbitAtlas, parseWorldOrbitDraft } from "./draft-parse.js";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CoordinatePoint3D, SpatialScene, SpatialSceneRenderOptions, WorldOrbitDocument } from "./types.js";
|
|
2
|
+
export declare function renderDocumentToSpatialScene(document: WorldOrbitDocument, options?: SpatialSceneRenderOptions): SpatialScene;
|
|
3
|
+
export declare function evaluateSpatialSceneAtTime(scene: SpatialScene, timeSeconds: number): Map<string, CoordinatePoint3D>;
|
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
import { renderDocumentToScene } from "./scene.js";
|
|
2
|
+
const DAY_IN_SECONDS = 86_400;
|
|
3
|
+
const YEAR_IN_SECONDS = DAY_IN_SECONDS * 365.25;
|
|
4
|
+
const FASTEST_VISIBLE_ORBIT_SECONDS = 18;
|
|
5
|
+
const SLOWEST_VISIBLE_ORBIT_SECONDS = 180;
|
|
6
|
+
export function renderDocumentToSpatialScene(document, options = {}) {
|
|
7
|
+
const renderOptions = {
|
|
8
|
+
width: options.width,
|
|
9
|
+
height: options.height,
|
|
10
|
+
padding: options.padding,
|
|
11
|
+
preset: options.preset,
|
|
12
|
+
projection: options.projection,
|
|
13
|
+
camera: options.camera,
|
|
14
|
+
scaleModel: options.scaleModel,
|
|
15
|
+
activeEventId: options.activeEventId,
|
|
16
|
+
};
|
|
17
|
+
const scene = renderDocumentToScene(document, renderOptions);
|
|
18
|
+
const scaleModel = resolveSpatialScaleModel(scene.layoutPreset, options.spatialScaleModel);
|
|
19
|
+
const sceneCenter = {
|
|
20
|
+
x: scene.contentBounds.centerX,
|
|
21
|
+
y: scene.contentBounds.centerY,
|
|
22
|
+
};
|
|
23
|
+
const objectMap = new Map(scene.objects.map((object) => [object.objectId, object]));
|
|
24
|
+
const orbitMap = new Map(scene.orbitVisuals.map((orbit) => [orbit.objectId, orbit]));
|
|
25
|
+
const rawMotionMetrics = new Map();
|
|
26
|
+
for (const object of scene.objects) {
|
|
27
|
+
const placement = object.object.placement;
|
|
28
|
+
if (!placement || placement.mode !== "orbit") {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
rawMotionMetrics.set(object.objectId, resolveRawOrbitMetric(placement));
|
|
32
|
+
}
|
|
33
|
+
const minimumMotionMetric = Math.min(...[...rawMotionMetrics.values()].filter((value) => Number.isFinite(value) && value > 0)) || 1;
|
|
34
|
+
const positionCache = new Map();
|
|
35
|
+
const spatialObjects = scene.objects.map((entry) => createSpatialObject(entry, scene, sceneCenter, objectMap, orbitMap, scaleModel, positionCache, minimumMotionMetric));
|
|
36
|
+
const spatialObjectMap = new Map(spatialObjects.map((object) => [object.objectId, object]));
|
|
37
|
+
const spatialOrbits = scene.orbitVisuals.map((orbit) => createSpatialOrbit(orbit, spatialObjectMap, minimumMotionMetric, scene.activeEventId !== null));
|
|
38
|
+
const focusTargets = spatialObjects.map((object) => ({
|
|
39
|
+
objectId: object.objectId,
|
|
40
|
+
center: { ...object.position },
|
|
41
|
+
radius: object.visualRadius + scaleModel.focusPadding,
|
|
42
|
+
}));
|
|
43
|
+
return {
|
|
44
|
+
width: scene.width,
|
|
45
|
+
height: scene.height,
|
|
46
|
+
padding: scene.padding,
|
|
47
|
+
renderPreset: scene.renderPreset,
|
|
48
|
+
projection: scene.projection,
|
|
49
|
+
camera: scene.camera,
|
|
50
|
+
scaleModel,
|
|
51
|
+
title: scene.title,
|
|
52
|
+
subtitle: scene.subtitle,
|
|
53
|
+
systemId: scene.systemId,
|
|
54
|
+
viewMode: "3d",
|
|
55
|
+
layoutPreset: scene.layoutPreset,
|
|
56
|
+
metadata: {
|
|
57
|
+
...scene.metadata,
|
|
58
|
+
"viewer.mode": "3d",
|
|
59
|
+
},
|
|
60
|
+
contentBounds: calculateSpatialBounds(spatialObjects),
|
|
61
|
+
semanticGroups: scene.semanticGroups,
|
|
62
|
+
viewpoints: scene.viewpoints,
|
|
63
|
+
activeEventId: scene.activeEventId,
|
|
64
|
+
timeFrozen: scene.activeEventId !== null,
|
|
65
|
+
objects: spatialObjects,
|
|
66
|
+
orbits: spatialOrbits,
|
|
67
|
+
focusTargets,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function createSpatialObject(entry, scene, sceneCenter, objectMap, orbitMap, scaleModel, positionCache, minimumMotionMetric) {
|
|
71
|
+
const position = resolveSpatialObjectPosition(entry, scene, sceneCenter, objectMap, orbitMap, positionCache);
|
|
72
|
+
const motion = createMotionModel(entry.object, orbitMap.get(entry.objectId), minimumMotionMetric, scene.activeEventId !== null);
|
|
73
|
+
return {
|
|
74
|
+
objectId: entry.objectId,
|
|
75
|
+
object: entry.object,
|
|
76
|
+
parentId: entry.parentId,
|
|
77
|
+
ancestorIds: entry.ancestorIds.slice(),
|
|
78
|
+
childIds: entry.childIds.slice(),
|
|
79
|
+
groupId: entry.groupId,
|
|
80
|
+
semanticGroupIds: entry.semanticGroupIds.slice(),
|
|
81
|
+
position,
|
|
82
|
+
radius: clampNumber(entry.radius * scaleModel.bodyRadiusMultiplier, scaleModel.minBodyRadius, scaleModel.maxBodyRadius),
|
|
83
|
+
visualRadius: clampNumber(entry.visualRadius * scaleModel.bodyRadiusMultiplier, scaleModel.minBodyRadius, scaleModel.maxBodyRadius + 24),
|
|
84
|
+
label: entry.label,
|
|
85
|
+
secondaryLabel: entry.secondaryLabel,
|
|
86
|
+
fillColor: entry.fillColor,
|
|
87
|
+
imageHref: entry.imageHref,
|
|
88
|
+
hidden: entry.hidden,
|
|
89
|
+
motion,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function createSpatialOrbit(orbit, objectMap, minimumMotionMetric, frozen) {
|
|
93
|
+
const owner = objectMap.get(orbit.objectId);
|
|
94
|
+
const parent = objectMap.get(orbit.parentId);
|
|
95
|
+
return {
|
|
96
|
+
objectId: orbit.objectId,
|
|
97
|
+
object: orbit.object,
|
|
98
|
+
parentId: orbit.parentId,
|
|
99
|
+
groupId: orbit.groupId,
|
|
100
|
+
semanticGroupIds: orbit.semanticGroupIds.slice(),
|
|
101
|
+
center: parent?.position ?? { x: 0, y: 0, z: 0 },
|
|
102
|
+
kind: orbit.kind,
|
|
103
|
+
radius: orbit.radius,
|
|
104
|
+
semiMajor: orbit.radius ?? orbit.rx ?? 0,
|
|
105
|
+
semiMinor: orbit.radius ?? orbit.ry ?? 0,
|
|
106
|
+
rotationDeg: orbit.rotationDeg,
|
|
107
|
+
inclinationDeg: owner?.motion?.inclinationDeg ??
|
|
108
|
+
unitValueToDegrees(orbit.object.placement?.mode === "orbit"
|
|
109
|
+
? orbit.object.placement.inclination
|
|
110
|
+
: undefined) ??
|
|
111
|
+
0,
|
|
112
|
+
band: orbit.band,
|
|
113
|
+
bandThickness: orbit.bandThickness,
|
|
114
|
+
hidden: orbit.hidden,
|
|
115
|
+
motion: owner?.motion ??
|
|
116
|
+
createMotionModel(orbit.object, orbit, minimumMotionMetric, frozen),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function resolveSpatialObjectPosition(entry, scene, sceneCenter, objectMap, orbitMap, cache) {
|
|
120
|
+
const cached = cache.get(entry.objectId);
|
|
121
|
+
if (cached) {
|
|
122
|
+
return cached;
|
|
123
|
+
}
|
|
124
|
+
const placement = entry.object.placement;
|
|
125
|
+
let position;
|
|
126
|
+
if (placement?.mode === "orbit" && entry.parentId) {
|
|
127
|
+
const parent = objectMap.get(entry.parentId);
|
|
128
|
+
const parentPosition = parent
|
|
129
|
+
? resolveSpatialObjectPosition(parent, scene, sceneCenter, objectMap, orbitMap, cache)
|
|
130
|
+
: { x: 0, y: 0, z: 0 };
|
|
131
|
+
const orbit = orbitMap.get(entry.objectId);
|
|
132
|
+
const motion = createMotionModel(entry.object, orbit, 1, scene.activeEventId !== null);
|
|
133
|
+
const local = motion
|
|
134
|
+
? computeOrbitPosition(motion, 0)
|
|
135
|
+
: {
|
|
136
|
+
x: (entry.x - sceneCenter.x) * 0.8,
|
|
137
|
+
y: 0,
|
|
138
|
+
z: (entry.y - sceneCenter.y) * 0.8,
|
|
139
|
+
};
|
|
140
|
+
position = addPoint3D(parentPosition, local);
|
|
141
|
+
}
|
|
142
|
+
else if (placement?.mode === "surface" && entry.parentId) {
|
|
143
|
+
const parent = objectMap.get(entry.parentId);
|
|
144
|
+
const parentPosition = parent
|
|
145
|
+
? resolveSpatialObjectPosition(parent, scene, sceneCenter, objectMap, orbitMap, cache)
|
|
146
|
+
: { x: 0, y: 0, z: 0 };
|
|
147
|
+
const parentRadius = parent?.visualRadius ?? 16;
|
|
148
|
+
const seed = hashUnit(entry.objectId);
|
|
149
|
+
const angle = seed * Math.PI * 2;
|
|
150
|
+
position = {
|
|
151
|
+
x: parentPosition.x + Math.cos(angle) * (parentRadius + entry.visualRadius * 0.9),
|
|
152
|
+
y: parentPosition.y + Math.sin(seed * Math.PI) * Math.max(entry.visualRadius * 0.2, 2),
|
|
153
|
+
z: parentPosition.z + Math.sin(angle) * (parentRadius + entry.visualRadius * 0.9),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
else if (placement?.mode === "at" && entry.parentId) {
|
|
157
|
+
const parent = objectMap.get(entry.parentId);
|
|
158
|
+
const parentPosition = parent
|
|
159
|
+
? resolveSpatialObjectPosition(parent, scene, sceneCenter, objectMap, orbitMap, cache)
|
|
160
|
+
: { x: 0, y: 0, z: 0 };
|
|
161
|
+
const anchorX = entry.anchorX ?? parent?.x ?? sceneCenter.x;
|
|
162
|
+
const anchorY = entry.anchorY ?? parent?.y ?? sceneCenter.y;
|
|
163
|
+
position = {
|
|
164
|
+
x: parentPosition.x + (entry.x - anchorX),
|
|
165
|
+
y: parentPosition.y,
|
|
166
|
+
z: parentPosition.z + (entry.y - anchorY),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
position = {
|
|
171
|
+
x: (entry.x - sceneCenter.x) * 0.8,
|
|
172
|
+
y: 0,
|
|
173
|
+
z: (entry.y - sceneCenter.y) * 0.8,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
cache.set(entry.objectId, position);
|
|
177
|
+
return position;
|
|
178
|
+
}
|
|
179
|
+
export function evaluateSpatialSceneAtTime(scene, timeSeconds) {
|
|
180
|
+
const objectMap = new Map(scene.objects.map((object) => [object.objectId, object]));
|
|
181
|
+
const cache = new Map();
|
|
182
|
+
const resolvePosition = (objectId) => {
|
|
183
|
+
const cached = cache.get(objectId);
|
|
184
|
+
if (cached) {
|
|
185
|
+
return cached;
|
|
186
|
+
}
|
|
187
|
+
const object = objectMap.get(objectId);
|
|
188
|
+
if (!object) {
|
|
189
|
+
return { x: 0, y: 0, z: 0 };
|
|
190
|
+
}
|
|
191
|
+
let next = { ...object.position };
|
|
192
|
+
if (object.motion && object.parentId) {
|
|
193
|
+
const parentPosition = resolvePosition(object.parentId);
|
|
194
|
+
const local = computeOrbitPosition(object.motion, scene.timeFrozen ? 0 : timeSeconds);
|
|
195
|
+
next = addPoint3D(parentPosition, local);
|
|
196
|
+
}
|
|
197
|
+
cache.set(objectId, next);
|
|
198
|
+
return next;
|
|
199
|
+
};
|
|
200
|
+
for (const object of scene.objects) {
|
|
201
|
+
resolvePosition(object.objectId);
|
|
202
|
+
}
|
|
203
|
+
return cache;
|
|
204
|
+
}
|
|
205
|
+
function computeOrbitPosition(motion, timeSeconds) {
|
|
206
|
+
const angleDeg = motion.phase0Deg + motion.angularVelocityDegPerSecond * timeSeconds;
|
|
207
|
+
const angle = degreesToRadians(angleDeg);
|
|
208
|
+
const rotation = degreesToRadians(motion.rotationDeg);
|
|
209
|
+
const inclination = degreesToRadians(motion.inclinationDeg);
|
|
210
|
+
const localX = Math.cos(angle) * motion.semiMajor;
|
|
211
|
+
const localZ = Math.sin(angle) * motion.semiMinor;
|
|
212
|
+
const rotatedX = localX * Math.cos(rotation) - localZ * Math.sin(rotation);
|
|
213
|
+
const rotatedZ = localX * Math.sin(rotation) + localZ * Math.cos(rotation);
|
|
214
|
+
return {
|
|
215
|
+
x: rotatedX,
|
|
216
|
+
y: rotatedZ * Math.sin(inclination),
|
|
217
|
+
z: rotatedZ * Math.cos(inclination),
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
function createMotionModel(object, orbit, minimumMotionMetric, frozen) {
|
|
221
|
+
const placement = object.placement;
|
|
222
|
+
if (!placement || placement.mode !== "orbit") {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
const semiMajor = orbit?.radius ??
|
|
226
|
+
orbit?.rx ??
|
|
227
|
+
clampNumber(resolveRawOrbitMetric(placement) * 48, 24, 1_200);
|
|
228
|
+
const semiMinor = orbit?.radius ?? orbit?.ry ?? semiMajor;
|
|
229
|
+
const periodSeconds = unitValueToDurationSeconds(placement.period);
|
|
230
|
+
const rawMetric = resolveRawOrbitMetric(placement);
|
|
231
|
+
const ratio = clampNumber(rawMetric / Math.max(minimumMotionMetric, 0.0001), 1, 20);
|
|
232
|
+
const visualDurationSeconds = periodSeconds
|
|
233
|
+
? clampNumber(FASTEST_VISIBLE_ORBIT_SECONDS * ratio, FASTEST_VISIBLE_ORBIT_SECONDS, SLOWEST_VISIBLE_ORBIT_SECONDS)
|
|
234
|
+
: clampNumber(FASTEST_VISIBLE_ORBIT_SECONDS * Math.pow(ratio, 0.75), FASTEST_VISIBLE_ORBIT_SECONDS, SLOWEST_VISIBLE_ORBIT_SECONDS);
|
|
235
|
+
return {
|
|
236
|
+
phase0Deg: unitValueToDegrees(placement.phase) ?? 0,
|
|
237
|
+
rotationDeg: unitValueToDegrees(placement.angle) ??
|
|
238
|
+
orbit?.rotationDeg ??
|
|
239
|
+
0,
|
|
240
|
+
inclinationDeg: unitValueToDegrees(placement.inclination) ?? 0,
|
|
241
|
+
semiMajor,
|
|
242
|
+
semiMinor,
|
|
243
|
+
eccentricity: placement.eccentricity ?? 0,
|
|
244
|
+
periodSeconds,
|
|
245
|
+
angularVelocityDegPerSecond: 360 / Math.max(visualDurationSeconds, 0.001),
|
|
246
|
+
heuristic: periodSeconds === null,
|
|
247
|
+
frozen,
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
function resolveRawOrbitMetric(placement) {
|
|
251
|
+
const distance = unitValueToDistanceMetric(placement.semiMajor) ??
|
|
252
|
+
unitValueToDistanceMetric(placement.distance) ??
|
|
253
|
+
1;
|
|
254
|
+
return Math.max(distance, 0.01);
|
|
255
|
+
}
|
|
256
|
+
function unitValueToDistanceMetric(value) {
|
|
257
|
+
if (!value) {
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
switch (value.unit) {
|
|
261
|
+
case "au":
|
|
262
|
+
return value.value;
|
|
263
|
+
case "km":
|
|
264
|
+
return value.value / 149_597_870.7;
|
|
265
|
+
case "m":
|
|
266
|
+
return value.value / 149_597_870_700;
|
|
267
|
+
case "re":
|
|
268
|
+
return (value.value * 6_371) / 149_597_870.7;
|
|
269
|
+
case "rj":
|
|
270
|
+
return (value.value * 71_492) / 149_597_870.7;
|
|
271
|
+
case "sol":
|
|
272
|
+
return (value.value * 695_700) / 149_597_870.7;
|
|
273
|
+
case "ly":
|
|
274
|
+
return value.value * 63_241.077;
|
|
275
|
+
case "pc":
|
|
276
|
+
return value.value * 206_264.806;
|
|
277
|
+
case "kpc":
|
|
278
|
+
return value.value * 206_264_806;
|
|
279
|
+
default:
|
|
280
|
+
return value.value;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
function unitValueToDurationSeconds(value) {
|
|
284
|
+
if (!value) {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
switch (value.unit) {
|
|
288
|
+
case "s":
|
|
289
|
+
return value.value;
|
|
290
|
+
case "min":
|
|
291
|
+
return value.value * 60;
|
|
292
|
+
case "h":
|
|
293
|
+
return value.value * 3_600;
|
|
294
|
+
case "d":
|
|
295
|
+
return value.value * DAY_IN_SECONDS;
|
|
296
|
+
case "y":
|
|
297
|
+
return value.value * YEAR_IN_SECONDS;
|
|
298
|
+
case "ky":
|
|
299
|
+
return value.value * YEAR_IN_SECONDS * 1_000;
|
|
300
|
+
case "my":
|
|
301
|
+
return value.value * YEAR_IN_SECONDS * 1_000_000;
|
|
302
|
+
case "gy":
|
|
303
|
+
return value.value * YEAR_IN_SECONDS * 1_000_000_000;
|
|
304
|
+
default:
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
function unitValueToDegrees(value) {
|
|
309
|
+
if (!value) {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
return value.unit === "deg" || value.unit === null ? value.value : null;
|
|
313
|
+
}
|
|
314
|
+
function resolveSpatialScaleModel(layoutPreset, overrides) {
|
|
315
|
+
const defaults = defaultSpatialScaleModel(layoutPreset);
|
|
316
|
+
return {
|
|
317
|
+
...defaults,
|
|
318
|
+
...overrides,
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
function defaultSpatialScaleModel(layoutPreset) {
|
|
322
|
+
switch (layoutPreset) {
|
|
323
|
+
case "compact":
|
|
324
|
+
return {
|
|
325
|
+
orbitDistanceMultiplier: 0.92,
|
|
326
|
+
bodyRadiusMultiplier: 0.92,
|
|
327
|
+
markerSizeMultiplier: 0.92,
|
|
328
|
+
ringThicknessMultiplier: 0.9,
|
|
329
|
+
focusPadding: 10,
|
|
330
|
+
minBodyRadius: 4,
|
|
331
|
+
maxBodyRadius: 34,
|
|
332
|
+
};
|
|
333
|
+
case "presentation":
|
|
334
|
+
return {
|
|
335
|
+
orbitDistanceMultiplier: 1.15,
|
|
336
|
+
bodyRadiusMultiplier: 1.12,
|
|
337
|
+
markerSizeMultiplier: 1.08,
|
|
338
|
+
ringThicknessMultiplier: 1.14,
|
|
339
|
+
focusPadding: 16,
|
|
340
|
+
minBodyRadius: 5,
|
|
341
|
+
maxBodyRadius: 44,
|
|
342
|
+
};
|
|
343
|
+
default:
|
|
344
|
+
return {
|
|
345
|
+
orbitDistanceMultiplier: 1,
|
|
346
|
+
bodyRadiusMultiplier: 1,
|
|
347
|
+
markerSizeMultiplier: 1,
|
|
348
|
+
ringThicknessMultiplier: 1,
|
|
349
|
+
focusPadding: 12,
|
|
350
|
+
minBodyRadius: 4,
|
|
351
|
+
maxBodyRadius: 40,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
function calculateSpatialBounds(objects) {
|
|
356
|
+
if (objects.length === 0) {
|
|
357
|
+
return {
|
|
358
|
+
minX: 0,
|
|
359
|
+
minY: 0,
|
|
360
|
+
minZ: 0,
|
|
361
|
+
maxX: 0,
|
|
362
|
+
maxY: 0,
|
|
363
|
+
maxZ: 0,
|
|
364
|
+
width: 0,
|
|
365
|
+
height: 0,
|
|
366
|
+
depth: 0,
|
|
367
|
+
center: { x: 0, y: 0, z: 0 },
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
371
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
372
|
+
let minZ = Number.POSITIVE_INFINITY;
|
|
373
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
374
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
375
|
+
let maxZ = Number.NEGATIVE_INFINITY;
|
|
376
|
+
for (const object of objects) {
|
|
377
|
+
minX = Math.min(minX, object.position.x - object.visualRadius);
|
|
378
|
+
minY = Math.min(minY, object.position.y - object.visualRadius);
|
|
379
|
+
minZ = Math.min(minZ, object.position.z - object.visualRadius);
|
|
380
|
+
maxX = Math.max(maxX, object.position.x + object.visualRadius);
|
|
381
|
+
maxY = Math.max(maxY, object.position.y + object.visualRadius);
|
|
382
|
+
maxZ = Math.max(maxZ, object.position.z + object.visualRadius);
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
minX,
|
|
386
|
+
minY,
|
|
387
|
+
minZ,
|
|
388
|
+
maxX,
|
|
389
|
+
maxY,
|
|
390
|
+
maxZ,
|
|
391
|
+
width: maxX - minX,
|
|
392
|
+
height: maxY - minY,
|
|
393
|
+
depth: maxZ - minZ,
|
|
394
|
+
center: {
|
|
395
|
+
x: (minX + maxX) / 2,
|
|
396
|
+
y: (minY + maxY) / 2,
|
|
397
|
+
z: (minZ + maxZ) / 2,
|
|
398
|
+
},
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
function addPoint3D(left, right) {
|
|
402
|
+
return {
|
|
403
|
+
x: left.x + right.x,
|
|
404
|
+
y: left.y + right.y,
|
|
405
|
+
z: left.z + right.z,
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
function hashUnit(value) {
|
|
409
|
+
let hash = 0;
|
|
410
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
411
|
+
hash = (hash * 31 + value.charCodeAt(index)) >>> 0;
|
|
412
|
+
}
|
|
413
|
+
return (hash % 10_000) / 10_000;
|
|
414
|
+
}
|
|
415
|
+
function clampNumber(value, min, max) {
|
|
416
|
+
return Math.min(Math.max(value, min), max);
|
|
417
|
+
}
|
|
418
|
+
function degreesToRadians(value) {
|
|
419
|
+
return (value * Math.PI) / 180;
|
|
420
|
+
}
|
|
@@ -12,6 +12,11 @@ export interface CoordinatePoint {
|
|
|
12
12
|
x: number;
|
|
13
13
|
y: number;
|
|
14
14
|
}
|
|
15
|
+
export interface CoordinatePoint3D {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
z: number;
|
|
19
|
+
}
|
|
15
20
|
export interface UnitValue {
|
|
16
21
|
value: number;
|
|
17
22
|
unit: Unit | null;
|
|
@@ -249,6 +254,18 @@ export interface SceneRenderOptions {
|
|
|
249
254
|
scaleModel?: Partial<RenderScaleModel>;
|
|
250
255
|
activeEventId?: string | null;
|
|
251
256
|
}
|
|
257
|
+
export interface SpatialScaleModel {
|
|
258
|
+
orbitDistanceMultiplier: number;
|
|
259
|
+
bodyRadiusMultiplier: number;
|
|
260
|
+
markerSizeMultiplier: number;
|
|
261
|
+
ringThicknessMultiplier: number;
|
|
262
|
+
focusPadding: number;
|
|
263
|
+
minBodyRadius: number;
|
|
264
|
+
maxBodyRadius: number;
|
|
265
|
+
}
|
|
266
|
+
export interface SpatialSceneRenderOptions extends SceneRenderOptions {
|
|
267
|
+
spatialScaleModel?: Partial<SpatialScaleModel>;
|
|
268
|
+
}
|
|
252
269
|
export interface RenderBounds {
|
|
253
270
|
minX: number;
|
|
254
271
|
minY: number;
|
|
@@ -400,6 +417,71 @@ export interface RenderSceneRelation {
|
|
|
400
417
|
y2: number;
|
|
401
418
|
hidden: boolean;
|
|
402
419
|
}
|
|
420
|
+
export interface SpatialBounds {
|
|
421
|
+
minX: number;
|
|
422
|
+
minY: number;
|
|
423
|
+
minZ: number;
|
|
424
|
+
maxX: number;
|
|
425
|
+
maxY: number;
|
|
426
|
+
maxZ: number;
|
|
427
|
+
width: number;
|
|
428
|
+
height: number;
|
|
429
|
+
depth: number;
|
|
430
|
+
center: CoordinatePoint3D;
|
|
431
|
+
}
|
|
432
|
+
export interface OrbitalMotionModel {
|
|
433
|
+
phase0Deg: number;
|
|
434
|
+
rotationDeg: number;
|
|
435
|
+
inclinationDeg: number;
|
|
436
|
+
semiMajor: number;
|
|
437
|
+
semiMinor: number;
|
|
438
|
+
eccentricity: number;
|
|
439
|
+
periodSeconds: number | null;
|
|
440
|
+
angularVelocityDegPerSecond: number;
|
|
441
|
+
heuristic: boolean;
|
|
442
|
+
frozen: boolean;
|
|
443
|
+
}
|
|
444
|
+
export interface SpatialSceneObject {
|
|
445
|
+
objectId: string;
|
|
446
|
+
object: WorldOrbitObject;
|
|
447
|
+
parentId: string | null;
|
|
448
|
+
ancestorIds: string[];
|
|
449
|
+
childIds: string[];
|
|
450
|
+
groupId: string | null;
|
|
451
|
+
semanticGroupIds: string[];
|
|
452
|
+
position: CoordinatePoint3D;
|
|
453
|
+
radius: number;
|
|
454
|
+
visualRadius: number;
|
|
455
|
+
label: string;
|
|
456
|
+
secondaryLabel: string;
|
|
457
|
+
fillColor?: string;
|
|
458
|
+
imageHref?: string;
|
|
459
|
+
hidden: boolean;
|
|
460
|
+
motion: OrbitalMotionModel | null;
|
|
461
|
+
}
|
|
462
|
+
export interface SpatialOrbit {
|
|
463
|
+
objectId: string;
|
|
464
|
+
object: WorldOrbitObject;
|
|
465
|
+
parentId: string;
|
|
466
|
+
groupId: string | null;
|
|
467
|
+
semanticGroupIds: string[];
|
|
468
|
+
center: CoordinatePoint3D;
|
|
469
|
+
kind: "circle" | "ellipse";
|
|
470
|
+
radius?: number;
|
|
471
|
+
semiMajor: number;
|
|
472
|
+
semiMinor: number;
|
|
473
|
+
rotationDeg: number;
|
|
474
|
+
inclinationDeg: number;
|
|
475
|
+
band: boolean;
|
|
476
|
+
bandThickness?: number;
|
|
477
|
+
hidden: boolean;
|
|
478
|
+
motion: OrbitalMotionModel | null;
|
|
479
|
+
}
|
|
480
|
+
export interface SpatialFocusTarget {
|
|
481
|
+
objectId: string;
|
|
482
|
+
center: CoordinatePoint3D;
|
|
483
|
+
radius: number;
|
|
484
|
+
}
|
|
403
485
|
export interface RenderScene {
|
|
404
486
|
width: number;
|
|
405
487
|
height: number;
|
|
@@ -428,6 +510,29 @@ export interface RenderScene {
|
|
|
428
510
|
leaders: RenderLeaderLine[];
|
|
429
511
|
labels: RenderSceneLabel[];
|
|
430
512
|
}
|
|
513
|
+
export interface SpatialScene {
|
|
514
|
+
width: number;
|
|
515
|
+
height: number;
|
|
516
|
+
padding: number;
|
|
517
|
+
renderPreset: RenderPresetName | null;
|
|
518
|
+
projection: ViewProjection;
|
|
519
|
+
camera: WorldOrbitViewCamera | null;
|
|
520
|
+
scaleModel: SpatialScaleModel;
|
|
521
|
+
title: string;
|
|
522
|
+
subtitle: string;
|
|
523
|
+
systemId: string | null;
|
|
524
|
+
viewMode: "3d";
|
|
525
|
+
layoutPreset: SceneLayoutPreset;
|
|
526
|
+
metadata: Record<string, string>;
|
|
527
|
+
contentBounds: SpatialBounds;
|
|
528
|
+
semanticGroups: RenderSceneSemanticGroup[];
|
|
529
|
+
viewpoints: RenderSceneViewpoint[];
|
|
530
|
+
activeEventId: string | null;
|
|
531
|
+
timeFrozen: boolean;
|
|
532
|
+
objects: SpatialSceneObject[];
|
|
533
|
+
orbits: SpatialOrbit[];
|
|
534
|
+
focusTargets: SpatialFocusTarget[];
|
|
535
|
+
}
|
|
431
536
|
export type SceneLayoutPreset = "compact" | "balanced" | "presentation";
|
|
432
537
|
export type FieldValueKind = "string" | "list" | "boolean" | "number" | "unit";
|
|
433
538
|
export type UnitFamily = "distance" | "radius" | "mass" | "duration" | "angle" | "generic";
|
|
@@ -246,6 +246,7 @@ export function createWorldOrbitEditor(container, options = {}) {
|
|
|
246
246
|
const showInspector = options.showInspector ?? true;
|
|
247
247
|
const showPreview = options.showPreview ?? true;
|
|
248
248
|
const shortcutsEnabled = options.shortcuts ?? true;
|
|
249
|
+
let viewMode = options.viewMode ?? "2d";
|
|
249
250
|
container.classList.add("wo-editor");
|
|
250
251
|
container.dataset.woShowInspector = String(showInspector);
|
|
251
252
|
container.dataset.woShowTextPane = String(showTextPane);
|
|
@@ -271,6 +272,7 @@ export function createWorldOrbitEditor(container, options = {}) {
|
|
|
271
272
|
height: options.viewerHeight ?? 680,
|
|
272
273
|
preset: atlasDocument.system?.defaults.preset ?? "atlas-card",
|
|
273
274
|
projection: "document",
|
|
275
|
+
viewMode,
|
|
274
276
|
minimap: true,
|
|
275
277
|
tooltipMode: "hover",
|
|
276
278
|
onSelectionChange(selectedObject) {
|
|
@@ -337,6 +339,22 @@ export function createWorldOrbitEditor(container, options = {}) {
|
|
|
337
339
|
getSelection() {
|
|
338
340
|
return selection ? { path: { ...selection } } : null;
|
|
339
341
|
},
|
|
342
|
+
getViewMode() {
|
|
343
|
+
return viewMode;
|
|
344
|
+
},
|
|
345
|
+
setViewMode(mode) {
|
|
346
|
+
const previousViewMode = viewMode;
|
|
347
|
+
try {
|
|
348
|
+
viewer.setViewMode(mode);
|
|
349
|
+
viewMode = mode;
|
|
350
|
+
renderStageOverlay();
|
|
351
|
+
renderPreviewNow();
|
|
352
|
+
}
|
|
353
|
+
catch (error) {
|
|
354
|
+
viewMode = previousViewMode;
|
|
355
|
+
throw error;
|
|
356
|
+
}
|
|
357
|
+
},
|
|
340
358
|
isDirty() {
|
|
341
359
|
return dirty;
|
|
342
360
|
},
|
|
@@ -461,7 +479,7 @@ export function createWorldOrbitEditor(container, options = {}) {
|
|
|
461
479
|
return viewer.exportSvg();
|
|
462
480
|
},
|
|
463
481
|
exportEmbedMarkup() {
|
|
464
|
-
return buildEmbedMarkup(getCurrentSourceForExport(), atlasDocument);
|
|
482
|
+
return buildEmbedMarkup(getCurrentSourceForExport(), atlasDocument, viewMode);
|
|
465
483
|
},
|
|
466
484
|
destroy() {
|
|
467
485
|
if (destroyed) {
|
|
@@ -906,6 +924,9 @@ export function createWorldOrbitEditor(container, options = {}) {
|
|
|
906
924
|
return;
|
|
907
925
|
}
|
|
908
926
|
overlay.innerHTML = "";
|
|
927
|
+
if (viewMode === "3d") {
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
909
930
|
const selectedObjectId = selection?.kind === "object"
|
|
910
931
|
? selection.id ?? null
|
|
911
932
|
: selection?.kind === "event-pose"
|
|
@@ -1577,7 +1598,7 @@ export function createWorldOrbitEditor(container, options = {}) {
|
|
|
1577
1598
|
previewVisual.innerHTML = nextSvg;
|
|
1578
1599
|
lastPreviewSvg = nextSvg;
|
|
1579
1600
|
}
|
|
1580
|
-
const nextMarkup = buildEmbedMarkup(getCurrentSourceForExport(), atlasDocument);
|
|
1601
|
+
const nextMarkup = buildEmbedMarkup(getCurrentSourceForExport(), atlasDocument, viewMode);
|
|
1581
1602
|
if (previewMarkup && nextMarkup !== lastPreviewMarkup) {
|
|
1582
1603
|
previewMarkup.textContent = nextMarkup;
|
|
1583
1604
|
lastPreviewMarkup = nextMarkup;
|
|
@@ -2969,9 +2990,9 @@ function mapDiagnosticFieldToInputNames(selection, field) {
|
|
|
2969
2990
|
return [`prop-${field}`];
|
|
2970
2991
|
}
|
|
2971
2992
|
}
|
|
2972
|
-
function buildEmbedMarkup(source, document) {
|
|
2993
|
+
function buildEmbedMarkup(source, document, viewMode) {
|
|
2973
2994
|
return renderWorldOrbitBlock(source, {
|
|
2974
|
-
mode: "interactive",
|
|
2995
|
+
mode: viewMode === "3d" ? "interactive-3d" : "interactive-2d",
|
|
2975
2996
|
preset: document.system?.defaults.preset ?? "atlas-card",
|
|
2976
2997
|
projection: document.system?.defaults.view ?? "topdown",
|
|
2977
2998
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AtlasDocumentPath, AtlasResolvedDiagnostic, WorldOrbitAtlasDocument, WorldOrbitEvent, WorldOrbitAtlasSystem, WorldOrbitAtlasViewpoint, WorldOrbitObject } from "@worldorbit/core";
|
|
2
|
+
import type { WorldOrbitViewMode } from "@worldorbit/viewer";
|
|
2
3
|
export interface WorldOrbitEditorSelection {
|
|
3
4
|
path: AtlasDocumentPath | null;
|
|
4
5
|
}
|
|
@@ -16,6 +17,7 @@ export interface WorldOrbitEditorOptions {
|
|
|
16
17
|
showPreview?: boolean;
|
|
17
18
|
viewerWidth?: number;
|
|
18
19
|
viewerHeight?: number;
|
|
20
|
+
viewMode?: WorldOrbitViewMode;
|
|
19
21
|
shortcuts?: boolean;
|
|
20
22
|
onChange?: (snapshot: WorldOrbitEditorSnapshot) => void;
|
|
21
23
|
onDiagnosticsChange?: (diagnostics: AtlasResolvedDiagnostic[]) => void;
|
|
@@ -29,6 +31,8 @@ export interface WorldOrbitEditor {
|
|
|
29
31
|
getAtlasDocument(): WorldOrbitAtlasDocument;
|
|
30
32
|
getDiagnostics(): AtlasResolvedDiagnostic[];
|
|
31
33
|
getSelection(): WorldOrbitEditorSelection | null;
|
|
34
|
+
getViewMode(): WorldOrbitViewMode;
|
|
35
|
+
setViewMode(mode: WorldOrbitViewMode): void;
|
|
32
36
|
isDirty(): boolean;
|
|
33
37
|
markSaved(): void;
|
|
34
38
|
selectPath(path: AtlasDocumentPath | null): void;
|