worldorbit 3.2.2 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +543 -543
- package/dist/browser/core/dist/atlas-edit.js +146 -1
- package/dist/browser/core/dist/atlas-validate.js +105 -10
- package/dist/browser/core/dist/draft-parse.js +461 -17
- package/dist/browser/core/dist/draft.d.ts +2 -1
- package/dist/browser/core/dist/draft.js +26 -4
- package/dist/browser/core/dist/format.js +126 -5
- package/dist/browser/core/dist/index.d.ts +1 -0
- package/dist/browser/core/dist/index.js +1 -0
- package/dist/browser/core/dist/load.js +12 -2
- package/dist/browser/core/dist/normalize.js +1 -0
- package/dist/browser/core/dist/scene.js +226 -5
- package/dist/browser/core/dist/schema.js +11 -1
- package/dist/browser/core/dist/solver.d.ts +33 -0
- package/dist/browser/core/dist/solver.js +99 -0
- package/dist/browser/core/dist/spatial-scene.js +56 -0
- package/dist/browser/core/dist/types.d.ts +130 -4
- package/dist/browser/editor/dist/editor.js +844 -719
- package/dist/browser/editor/dist/types.d.ts +2 -1
- package/dist/browser/viewer/dist/minimap.js +9 -7
- package/dist/browser/viewer/dist/render.js +78 -18
- package/dist/browser/viewer/dist/runtime-3d.js +2 -0
- package/dist/browser/viewer/dist/theme.js +1 -0
- package/dist/browser/viewer/dist/types.d.ts +7 -0
- package/dist/browser/viewer/dist/viewer.js +34 -3
- package/dist/obsidian-plugin/README.md +141 -124
- package/dist/obsidian-plugin/main.js +82 -68
- package/dist/unpkg/core/dist/atlas-edit.js +146 -1
- package/dist/unpkg/core/dist/atlas-validate.js +105 -10
- package/dist/unpkg/core/dist/draft-parse.js +461 -17
- package/dist/unpkg/core/dist/draft.d.ts +2 -1
- package/dist/unpkg/core/dist/draft.js +26 -4
- package/dist/unpkg/core/dist/format.js +126 -5
- package/dist/unpkg/core/dist/index.d.ts +1 -0
- package/dist/unpkg/core/dist/index.js +1 -0
- package/dist/unpkg/core/dist/load.js +12 -2
- package/dist/unpkg/core/dist/normalize.js +1 -0
- package/dist/unpkg/core/dist/scene.js +226 -5
- package/dist/unpkg/core/dist/schema.js +11 -1
- package/dist/unpkg/core/dist/solver.d.ts +33 -0
- package/dist/unpkg/core/dist/solver.js +99 -0
- package/dist/unpkg/core/dist/spatial-scene.js +56 -0
- package/dist/unpkg/core/dist/types.d.ts +130 -4
- package/dist/unpkg/editor/dist/editor.js +844 -719
- package/dist/unpkg/editor/dist/types.d.ts +2 -1
- package/dist/unpkg/viewer/dist/minimap.js +9 -7
- package/dist/unpkg/viewer/dist/render.js +78 -18
- package/dist/unpkg/viewer/dist/runtime-3d.js +2 -0
- package/dist/unpkg/viewer/dist/theme.js +1 -0
- package/dist/unpkg/viewer/dist/types.d.ts +7 -0
- package/dist/unpkg/viewer/dist/viewer.js +34 -3
- package/dist/unpkg/worldorbit-core.min.js +12 -12
- package/dist/unpkg/worldorbit-editor.min.js +381 -340
- package/dist/unpkg/worldorbit-markdown.min.js +47 -33
- package/dist/unpkg/worldorbit-viewer.min.js +238 -224
- package/dist/unpkg/worldorbit.js +1218 -46
- package/dist/unpkg/worldorbit.min.js +242 -228
- package/package.json +5 -1
- package/packages/core/dist/atlas-edit.js +146 -1
- package/packages/core/dist/atlas-validate.js +105 -10
- package/packages/core/dist/draft-parse.js +461 -17
- package/packages/core/dist/draft.d.ts +2 -1
- package/packages/core/dist/draft.js +26 -4
- package/packages/core/dist/format.js +126 -5
- package/packages/core/dist/index.d.ts +1 -0
- package/packages/core/dist/index.js +1 -0
- package/packages/core/dist/load.js +12 -2
- package/packages/core/dist/normalize.js +1 -0
- package/packages/core/dist/scene.js +226 -5
- package/packages/core/dist/schema.js +11 -1
- package/packages/core/dist/solver.d.ts +33 -0
- package/packages/core/dist/solver.js +99 -0
- package/packages/core/dist/spatial-scene.js +56 -0
- package/packages/core/dist/types.d.ts +130 -4
- package/packages/editor/dist/editor.js +844 -719
- package/packages/editor/dist/types.d.ts +2 -1
- package/packages/viewer/dist/minimap.js +9 -7
- package/packages/viewer/dist/render.js +78 -18
- package/packages/viewer/dist/runtime-3d.js +2 -0
- package/packages/viewer/dist/theme.js +1 -0
- package/packages/viewer/dist/types.d.ts +7 -0
- package/packages/viewer/dist/viewer.js +34 -3
|
@@ -8,6 +8,14 @@ const STRUCTURED_TYPED_BLOCKS = new Set([
|
|
|
8
8
|
"habitability",
|
|
9
9
|
"settlement",
|
|
10
10
|
]);
|
|
11
|
+
const TRAJECTORY_SEGMENT_KINDS = new Set([
|
|
12
|
+
"departure",
|
|
13
|
+
"transfer",
|
|
14
|
+
"flyby",
|
|
15
|
+
"capture",
|
|
16
|
+
"stationkeeping",
|
|
17
|
+
"escape",
|
|
18
|
+
]);
|
|
11
19
|
const DRAFT_OBJECT_FIELD_SPECS = new Map();
|
|
12
20
|
for (const key of [
|
|
13
21
|
"orbit",
|
|
@@ -40,6 +48,7 @@ for (const key of [
|
|
|
40
48
|
"on",
|
|
41
49
|
"source",
|
|
42
50
|
"cycle",
|
|
51
|
+
"trajectory",
|
|
43
52
|
]) {
|
|
44
53
|
const schema = getFieldSchema(key);
|
|
45
54
|
if (schema) {
|
|
@@ -65,10 +74,11 @@ for (const spec of [
|
|
|
65
74
|
{ key: "validate", inlineMode: "single", allowRepeat: true },
|
|
66
75
|
{ key: "locked", inlineMode: "multiple", allowRepeat: false },
|
|
67
76
|
{ key: "tolerance", inlineMode: "pair", allowRepeat: true },
|
|
77
|
+
{ key: "trajectory", inlineMode: "single", allowRepeat: false },
|
|
68
78
|
]) {
|
|
69
79
|
DRAFT_OBJECT_FIELD_SPECS.set(spec.key, {
|
|
70
80
|
key: spec.key,
|
|
71
|
-
version: "2.1",
|
|
81
|
+
version: spec.key === "trajectory" ? "3.0" : "2.1",
|
|
72
82
|
inlineMode: spec.inlineMode,
|
|
73
83
|
allowRepeat: spec.allowRepeat,
|
|
74
84
|
});
|
|
@@ -90,6 +100,8 @@ const EVENT_POSE_FIELD_KEYS = new Set([
|
|
|
90
100
|
"outer",
|
|
91
101
|
"epoch",
|
|
92
102
|
"referencePlane",
|
|
103
|
+
"segment",
|
|
104
|
+
"maneuver",
|
|
93
105
|
]);
|
|
94
106
|
export function parseWorldOrbitAtlas(source) {
|
|
95
107
|
return parseAtlasSource(source);
|
|
@@ -109,6 +121,7 @@ function parseAtlasSource(source, forcedOutputVersion) {
|
|
|
109
121
|
const groups = [];
|
|
110
122
|
const relations = [];
|
|
111
123
|
const events = [];
|
|
124
|
+
const trajectories = [];
|
|
112
125
|
const eventPoseNodes = new Map();
|
|
113
126
|
let sawDefaults = false;
|
|
114
127
|
let sawAtlas = false;
|
|
@@ -117,6 +130,7 @@ function parseAtlasSource(source, forcedOutputVersion) {
|
|
|
117
130
|
const groupIds = new Set();
|
|
118
131
|
const relationIds = new Set();
|
|
119
132
|
const eventIds = new Set();
|
|
133
|
+
const trajectoryIds = new Set();
|
|
120
134
|
for (let index = 0; index < lines.length; index++) {
|
|
121
135
|
const rawLine = lines[index];
|
|
122
136
|
const lineNumber = index + 1;
|
|
@@ -147,7 +161,7 @@ function parseAtlasSource(source, forcedOutputVersion) {
|
|
|
147
161
|
continue;
|
|
148
162
|
}
|
|
149
163
|
if (indent === 0) {
|
|
150
|
-
section = startTopLevelSection(tokens, lineNumber, sourceSchemaVersion, diagnostics, system, objectNodes, groups, relations, events, eventPoseNodes, viewpointIds, annotationIds, groupIds, relationIds, eventIds, { sawDefaults, sawAtlas });
|
|
164
|
+
section = startTopLevelSection(tokens, lineNumber, sourceSchemaVersion, diagnostics, system, objectNodes, groups, relations, events, trajectories, eventPoseNodes, viewpointIds, annotationIds, groupIds, relationIds, eventIds, trajectoryIds, { sawDefaults, sawAtlas });
|
|
151
165
|
if (section.kind === "system") {
|
|
152
166
|
system = section.system;
|
|
153
167
|
}
|
|
@@ -165,7 +179,7 @@ function parseAtlasSource(source, forcedOutputVersion) {
|
|
|
165
179
|
handleSectionLine(section, indent, tokens, lineNumber);
|
|
166
180
|
}
|
|
167
181
|
if (!sawSchemaHeader) {
|
|
168
|
-
throw new WorldOrbitError('Missing required atlas schema header "schema 2.0"');
|
|
182
|
+
throw new WorldOrbitError('Missing required atlas schema header "schema 2.0", "schema 3.0", or "schema 3.1"');
|
|
169
183
|
}
|
|
170
184
|
const objects = objectNodes.map((node) => normalizeDraftObject(node, sourceSchemaVersion, diagnostics));
|
|
171
185
|
const normalizedEvents = events.map((event) => normalizeDraftEvent(event, eventPoseNodes.get(event.id) ?? []));
|
|
@@ -179,6 +193,7 @@ function parseAtlasSource(source, forcedOutputVersion) {
|
|
|
179
193
|
groups,
|
|
180
194
|
relations,
|
|
181
195
|
events: normalizedEvents,
|
|
196
|
+
trajectories,
|
|
182
197
|
objects,
|
|
183
198
|
diagnostics,
|
|
184
199
|
};
|
|
@@ -210,21 +225,25 @@ function parseAtlasSource(source, forcedOutputVersion) {
|
|
|
210
225
|
function assertDraftSchemaHeader(tokens, line) {
|
|
211
226
|
if (tokens.length !== 2 ||
|
|
212
227
|
tokens[0].value.toLowerCase() !== "schema" ||
|
|
213
|
-
!["2.0-draft", "2.0", "2.1", "2.5", "2.6"].includes(tokens[1].value.toLowerCase())) {
|
|
214
|
-
throw new WorldOrbitError('Expected atlas header "schema 2.0", "schema 2.1", "schema 2.5", "schema 2.6", or legacy "schema 2.0-draft"', line, tokens[0]?.column ?? 1);
|
|
228
|
+
!["2.0-draft", "2.0", "2.1", "2.5", "2.6", "3.0", "3.1"].includes(tokens[1].value.toLowerCase())) {
|
|
229
|
+
throw new WorldOrbitError('Expected atlas header "schema 2.0", "schema 2.1", "schema 2.5", "schema 2.6", "schema 3.0", "schema 3.1", or legacy "schema 2.0-draft"', line, tokens[0]?.column ?? 1);
|
|
215
230
|
}
|
|
216
231
|
const version = tokens[1].value.toLowerCase();
|
|
217
232
|
return version === "2.6"
|
|
218
233
|
? "2.6"
|
|
219
|
-
: version === "
|
|
220
|
-
? "
|
|
221
|
-
: version === "
|
|
222
|
-
? "
|
|
223
|
-
: version === "2.
|
|
224
|
-
? "2.
|
|
225
|
-
: "2.
|
|
226
|
-
|
|
227
|
-
|
|
234
|
+
: version === "3.0"
|
|
235
|
+
? "3.0"
|
|
236
|
+
: version === "3.1"
|
|
237
|
+
? "3.1"
|
|
238
|
+
: version === "2.5"
|
|
239
|
+
? "2.5"
|
|
240
|
+
: version === "2.1"
|
|
241
|
+
? "2.1"
|
|
242
|
+
: version === "2.0-draft"
|
|
243
|
+
? "2.0-draft"
|
|
244
|
+
: "2.0";
|
|
245
|
+
}
|
|
246
|
+
function startTopLevelSection(tokens, line, sourceSchemaVersion, diagnostics, system, objectNodes, groups, relations, events, trajectories, eventPoseNodes, viewpointIds, annotationIds, groupIds, relationIds, eventIds, trajectoryIds, flags) {
|
|
228
247
|
const keyword = tokens[0]?.value.toLowerCase();
|
|
229
248
|
switch (keyword) {
|
|
230
249
|
case "system":
|
|
@@ -278,6 +297,9 @@ function startTopLevelSection(tokens, line, sourceSchemaVersion, diagnostics, sy
|
|
|
278
297
|
case "event":
|
|
279
298
|
warnIfSchema21Feature(sourceSchemaVersion, diagnostics, "event", { line, column: tokens[0].column });
|
|
280
299
|
return startEventSection(tokens, line, events, eventPoseNodes, eventIds, sourceSchemaVersion, diagnostics);
|
|
300
|
+
case "trajectory":
|
|
301
|
+
warnIfSchema30Feature(sourceSchemaVersion, diagnostics, "trajectory", { line, column: tokens[0].column });
|
|
302
|
+
return startTrajectorySection(tokens, line, trajectories, trajectoryIds, sourceSchemaVersion, diagnostics);
|
|
281
303
|
case "object":
|
|
282
304
|
return startObjectSection(tokens, line, sourceSchemaVersion, diagnostics, objectNodes);
|
|
283
305
|
default:
|
|
@@ -485,6 +507,51 @@ function startEventSection(tokens, line, events, eventPoseNodes, eventIds, sourc
|
|
|
485
507
|
activePoseSeenFields: new Set(),
|
|
486
508
|
};
|
|
487
509
|
}
|
|
510
|
+
function startTrajectorySection(tokens, line, trajectories, trajectoryIds, sourceSchemaVersion, diagnostics) {
|
|
511
|
+
if (tokens.length !== 2) {
|
|
512
|
+
throw new WorldOrbitError("Invalid trajectory declaration", line, tokens[0]?.column ?? 1);
|
|
513
|
+
}
|
|
514
|
+
const id = normalizeIdentifier(tokens[1].value);
|
|
515
|
+
if (!id) {
|
|
516
|
+
throw new WorldOrbitError("Trajectory id must not be empty", line, tokens[1].column);
|
|
517
|
+
}
|
|
518
|
+
if (trajectoryIds.has(id)) {
|
|
519
|
+
throw new WorldOrbitError(`Duplicate trajectory id "${id}"`, line, tokens[1].column);
|
|
520
|
+
}
|
|
521
|
+
const trajectory = {
|
|
522
|
+
id,
|
|
523
|
+
label: humanizeIdentifier(id),
|
|
524
|
+
summary: null,
|
|
525
|
+
craftObjectId: null,
|
|
526
|
+
tags: [],
|
|
527
|
+
color: null,
|
|
528
|
+
renderMode: null,
|
|
529
|
+
stroke: null,
|
|
530
|
+
strokeWidth: null,
|
|
531
|
+
marker: null,
|
|
532
|
+
labelMode: null,
|
|
533
|
+
showWaypoints: null,
|
|
534
|
+
hidden: false,
|
|
535
|
+
segments: [],
|
|
536
|
+
};
|
|
537
|
+
trajectories.push(trajectory);
|
|
538
|
+
trajectoryIds.add(id);
|
|
539
|
+
return {
|
|
540
|
+
kind: "trajectory",
|
|
541
|
+
trajectory,
|
|
542
|
+
sourceSchemaVersion,
|
|
543
|
+
diagnostics,
|
|
544
|
+
seenFields: new Set(),
|
|
545
|
+
inSegment: false,
|
|
546
|
+
segmentIndent: null,
|
|
547
|
+
activeSegment: null,
|
|
548
|
+
activeSegmentSeenFields: new Set(),
|
|
549
|
+
inManeuver: false,
|
|
550
|
+
maneuverIndent: null,
|
|
551
|
+
activeManeuver: null,
|
|
552
|
+
activeManeuverSeenFields: new Set(),
|
|
553
|
+
};
|
|
554
|
+
}
|
|
488
555
|
function startObjectSection(tokens, line, sourceSchemaVersion, diagnostics, objectNodes) {
|
|
489
556
|
if (tokens.length < 3) {
|
|
490
557
|
throw new WorldOrbitError("Invalid atlas object declaration", line, tokens[0]?.column ?? 1);
|
|
@@ -544,6 +611,9 @@ function handleSectionLine(section, indent, tokens, line) {
|
|
|
544
611
|
case "event":
|
|
545
612
|
applyEventField(section, indent, tokens, line);
|
|
546
613
|
return;
|
|
614
|
+
case "trajectory":
|
|
615
|
+
applyTrajectoryField(section, indent, tokens, line);
|
|
616
|
+
return;
|
|
547
617
|
case "object":
|
|
548
618
|
applyObjectField(section, indent, tokens, line);
|
|
549
619
|
return;
|
|
@@ -863,6 +933,13 @@ function applyEventField(section, indent, tokens, line) {
|
|
|
863
933
|
column: tokens[0]?.column ?? 1,
|
|
864
934
|
});
|
|
865
935
|
}
|
|
936
|
+
if (tokens[0]?.value === "segment" ||
|
|
937
|
+
tokens[0]?.value === "maneuver") {
|
|
938
|
+
warnIfSchema30Feature(section.sourceSchemaVersion, section.diagnostics, `pose.${tokens[0].value}`, {
|
|
939
|
+
line,
|
|
940
|
+
column: tokens[0]?.column ?? 1,
|
|
941
|
+
});
|
|
942
|
+
}
|
|
866
943
|
section.activePose.fields.push(parseEventPoseField(tokens, line, section.activePoseSeenFields));
|
|
867
944
|
return;
|
|
868
945
|
}
|
|
@@ -905,6 +982,13 @@ function applyEventField(section, indent, tokens, line) {
|
|
|
905
982
|
case "summary":
|
|
906
983
|
section.event.summary = joinFieldValue(tokens, line);
|
|
907
984
|
return;
|
|
985
|
+
case "trajectory":
|
|
986
|
+
warnIfSchema30Feature(section.sourceSchemaVersion, section.diagnostics, "event.trajectory", {
|
|
987
|
+
line,
|
|
988
|
+
column: tokens[0].column,
|
|
989
|
+
});
|
|
990
|
+
section.event.trajectoryId = joinFieldValue(tokens, line);
|
|
991
|
+
return;
|
|
908
992
|
case "target":
|
|
909
993
|
section.event.targetObjectId = joinFieldValue(tokens, line);
|
|
910
994
|
return;
|
|
@@ -947,6 +1031,302 @@ function applyEventField(section, indent, tokens, line) {
|
|
|
947
1031
|
throw new WorldOrbitError(`Unknown event field "${tokens[0].value}"`, line, tokens[0].column);
|
|
948
1032
|
}
|
|
949
1033
|
}
|
|
1034
|
+
function applyTrajectoryField(section, indent, tokens, line) {
|
|
1035
|
+
if (section.activeManeuver && indent <= (section.maneuverIndent ?? 0)) {
|
|
1036
|
+
section.activeManeuver = null;
|
|
1037
|
+
section.maneuverIndent = null;
|
|
1038
|
+
section.activeManeuverSeenFields.clear();
|
|
1039
|
+
section.inManeuver = false;
|
|
1040
|
+
}
|
|
1041
|
+
if (section.activeSegment && indent <= (section.segmentIndent ?? 0)) {
|
|
1042
|
+
section.activeSegment = null;
|
|
1043
|
+
section.segmentIndent = null;
|
|
1044
|
+
section.activeSegmentSeenFields.clear();
|
|
1045
|
+
section.inSegment = false;
|
|
1046
|
+
}
|
|
1047
|
+
if (section.activeManeuver) {
|
|
1048
|
+
applyTrajectoryManeuverField(section, tokens, line);
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1051
|
+
if (section.activeSegment) {
|
|
1052
|
+
if (tokens[0]?.value.toLowerCase() === "maneuver") {
|
|
1053
|
+
if (tokens.length !== 2) {
|
|
1054
|
+
throw new WorldOrbitError("Invalid trajectory maneuver declaration", line, tokens[0]?.column ?? 1);
|
|
1055
|
+
}
|
|
1056
|
+
const id = normalizeIdentifier(tokens[1].value);
|
|
1057
|
+
if (!id) {
|
|
1058
|
+
throw new WorldOrbitError("Trajectory maneuver id must not be empty", line, tokens[1].column);
|
|
1059
|
+
}
|
|
1060
|
+
if (section.activeSegment.maneuvers.some((maneuver) => maneuver.id === id)) {
|
|
1061
|
+
throw new WorldOrbitError(`Duplicate trajectory maneuver id "${id}"`, line, tokens[1].column);
|
|
1062
|
+
}
|
|
1063
|
+
const maneuver = {
|
|
1064
|
+
id,
|
|
1065
|
+
kind: "burn",
|
|
1066
|
+
label: null,
|
|
1067
|
+
epoch: null,
|
|
1068
|
+
notes: [],
|
|
1069
|
+
};
|
|
1070
|
+
section.activeSegment.maneuvers.push(maneuver);
|
|
1071
|
+
section.activeManeuver = maneuver;
|
|
1072
|
+
section.inManeuver = true;
|
|
1073
|
+
section.maneuverIndent = indent;
|
|
1074
|
+
section.activeManeuverSeenFields = new Set();
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
applyTrajectorySegmentField(section, tokens, line);
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
if (tokens[0]?.value.toLowerCase() === "segment") {
|
|
1081
|
+
if (tokens.length !== 2) {
|
|
1082
|
+
throw new WorldOrbitError("Invalid trajectory segment declaration", line, tokens[0]?.column ?? 1);
|
|
1083
|
+
}
|
|
1084
|
+
const id = normalizeIdentifier(tokens[1].value);
|
|
1085
|
+
if (!id) {
|
|
1086
|
+
throw new WorldOrbitError("Trajectory segment id must not be empty", line, tokens[1].column);
|
|
1087
|
+
}
|
|
1088
|
+
if (section.trajectory.segments.some((segment) => segment.id === id)) {
|
|
1089
|
+
throw new WorldOrbitError(`Duplicate trajectory segment id "${id}"`, line, tokens[1].column);
|
|
1090
|
+
}
|
|
1091
|
+
const segment = {
|
|
1092
|
+
id,
|
|
1093
|
+
kind: "transfer",
|
|
1094
|
+
label: null,
|
|
1095
|
+
summary: null,
|
|
1096
|
+
fromObjectId: null,
|
|
1097
|
+
toObjectId: null,
|
|
1098
|
+
aroundObjectId: null,
|
|
1099
|
+
assist: null,
|
|
1100
|
+
epoch: null,
|
|
1101
|
+
waypointLabel: null,
|
|
1102
|
+
waypointDate: null,
|
|
1103
|
+
renderHidden: null,
|
|
1104
|
+
sampleDensity: null,
|
|
1105
|
+
notes: [],
|
|
1106
|
+
maneuvers: [],
|
|
1107
|
+
};
|
|
1108
|
+
section.trajectory.segments.push(segment);
|
|
1109
|
+
section.activeSegment = {
|
|
1110
|
+
id,
|
|
1111
|
+
fields: [],
|
|
1112
|
+
maneuvers: segment.maneuvers,
|
|
1113
|
+
assist: null,
|
|
1114
|
+
location: { line, column: tokens[0].column },
|
|
1115
|
+
};
|
|
1116
|
+
section.inSegment = true;
|
|
1117
|
+
section.segmentIndent = indent;
|
|
1118
|
+
section.activeSegmentSeenFields = new Set();
|
|
1119
|
+
return;
|
|
1120
|
+
}
|
|
1121
|
+
const key = requireUniqueField(tokens, section.seenFields, line);
|
|
1122
|
+
const value = joinFieldValue(tokens, line);
|
|
1123
|
+
switch (key) {
|
|
1124
|
+
case "label":
|
|
1125
|
+
section.trajectory.label = value;
|
|
1126
|
+
return;
|
|
1127
|
+
case "summary":
|
|
1128
|
+
section.trajectory.summary = value;
|
|
1129
|
+
return;
|
|
1130
|
+
case "craft":
|
|
1131
|
+
section.trajectory.craftObjectId = value;
|
|
1132
|
+
return;
|
|
1133
|
+
case "tags":
|
|
1134
|
+
section.trajectory.tags = parseTokenList(tokens.slice(1), line, "tags");
|
|
1135
|
+
return;
|
|
1136
|
+
case "color":
|
|
1137
|
+
section.trajectory.color = value;
|
|
1138
|
+
return;
|
|
1139
|
+
case "rendermode":
|
|
1140
|
+
warnIfSchema31Feature(section.sourceSchemaVersion, section.diagnostics, "trajectory.renderMode", {
|
|
1141
|
+
line,
|
|
1142
|
+
column: tokens[0].column,
|
|
1143
|
+
});
|
|
1144
|
+
if (value !== "illustrative" && value !== "solver" && value !== "auto") {
|
|
1145
|
+
throw new WorldOrbitError(`Unknown trajectory render mode "${value}"`, line, tokens[0].column);
|
|
1146
|
+
}
|
|
1147
|
+
section.trajectory.renderMode = value;
|
|
1148
|
+
return;
|
|
1149
|
+
case "stroke":
|
|
1150
|
+
warnIfSchema31Feature(section.sourceSchemaVersion, section.diagnostics, "trajectory.stroke", {
|
|
1151
|
+
line,
|
|
1152
|
+
column: tokens[0].column,
|
|
1153
|
+
});
|
|
1154
|
+
section.trajectory.stroke = value;
|
|
1155
|
+
return;
|
|
1156
|
+
case "strokewidth":
|
|
1157
|
+
warnIfSchema31Feature(section.sourceSchemaVersion, section.diagnostics, "trajectory.strokeWidth", {
|
|
1158
|
+
line,
|
|
1159
|
+
column: tokens[0].column,
|
|
1160
|
+
});
|
|
1161
|
+
section.trajectory.strokeWidth = parsePositiveNumber(value, line, tokens[0].column, "strokeWidth");
|
|
1162
|
+
return;
|
|
1163
|
+
case "marker":
|
|
1164
|
+
warnIfSchema31Feature(section.sourceSchemaVersion, section.diagnostics, "trajectory.marker", {
|
|
1165
|
+
line,
|
|
1166
|
+
column: tokens[0].column,
|
|
1167
|
+
});
|
|
1168
|
+
section.trajectory.marker = value;
|
|
1169
|
+
return;
|
|
1170
|
+
case "labelmode":
|
|
1171
|
+
warnIfSchema31Feature(section.sourceSchemaVersion, section.diagnostics, "trajectory.labelMode", {
|
|
1172
|
+
line,
|
|
1173
|
+
column: tokens[0].column,
|
|
1174
|
+
});
|
|
1175
|
+
section.trajectory.labelMode = value;
|
|
1176
|
+
return;
|
|
1177
|
+
case "showwaypoints":
|
|
1178
|
+
warnIfSchema31Feature(section.sourceSchemaVersion, section.diagnostics, "trajectory.showWaypoints", {
|
|
1179
|
+
line,
|
|
1180
|
+
column: tokens[0].column,
|
|
1181
|
+
});
|
|
1182
|
+
section.trajectory.showWaypoints = parseAtlasBoolean(value, "showWaypoints", {
|
|
1183
|
+
line,
|
|
1184
|
+
column: tokens[0].column,
|
|
1185
|
+
});
|
|
1186
|
+
return;
|
|
1187
|
+
case "hidden":
|
|
1188
|
+
section.trajectory.hidden = parseAtlasBoolean(value, "hidden", {
|
|
1189
|
+
line,
|
|
1190
|
+
column: tokens[0].column,
|
|
1191
|
+
});
|
|
1192
|
+
return;
|
|
1193
|
+
default:
|
|
1194
|
+
throw new WorldOrbitError(`Unknown trajectory field "${tokens[0].value}"`, line, tokens[0].column);
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
function applyTrajectorySegmentField(section, tokens, line) {
|
|
1198
|
+
const segment = section.activeSegment;
|
|
1199
|
+
if (!segment) {
|
|
1200
|
+
return;
|
|
1201
|
+
}
|
|
1202
|
+
const key = requireUniqueField(tokens, section.activeSegmentSeenFields, line);
|
|
1203
|
+
const value = joinFieldValue(tokens, line);
|
|
1204
|
+
const target = section.trajectory.segments.find((entry) => entry.id === segment.id);
|
|
1205
|
+
switch (key) {
|
|
1206
|
+
case "kind": {
|
|
1207
|
+
const normalized = value.toLowerCase();
|
|
1208
|
+
if (!TRAJECTORY_SEGMENT_KINDS.has(normalized)) {
|
|
1209
|
+
throw new WorldOrbitError(`Unknown trajectory segment kind "${value}"`, line, tokens[0].column);
|
|
1210
|
+
}
|
|
1211
|
+
target.kind = normalized;
|
|
1212
|
+
return;
|
|
1213
|
+
}
|
|
1214
|
+
case "label":
|
|
1215
|
+
target.label = value;
|
|
1216
|
+
return;
|
|
1217
|
+
case "summary":
|
|
1218
|
+
target.summary = value;
|
|
1219
|
+
return;
|
|
1220
|
+
case "from":
|
|
1221
|
+
target.fromObjectId = value;
|
|
1222
|
+
return;
|
|
1223
|
+
case "to":
|
|
1224
|
+
target.toObjectId = value;
|
|
1225
|
+
return;
|
|
1226
|
+
case "around":
|
|
1227
|
+
target.aroundObjectId = value;
|
|
1228
|
+
return;
|
|
1229
|
+
case "assist":
|
|
1230
|
+
target.assist = {
|
|
1231
|
+
objectId: value,
|
|
1232
|
+
notes: [],
|
|
1233
|
+
};
|
|
1234
|
+
return;
|
|
1235
|
+
case "epoch":
|
|
1236
|
+
target.epoch = value;
|
|
1237
|
+
return;
|
|
1238
|
+
case "periapsis":
|
|
1239
|
+
target.periapsis = parseAtlasUnitValue(value, { line, column: tokens[0].column }, "periapsis");
|
|
1240
|
+
return;
|
|
1241
|
+
case "apoapsis":
|
|
1242
|
+
target.apoapsis = parseAtlasUnitValue(value, { line, column: tokens[0].column }, "apoapsis");
|
|
1243
|
+
return;
|
|
1244
|
+
case "inclination":
|
|
1245
|
+
target.inclination = parseAtlasUnitValue(value, { line, column: tokens[0].column }, "inclination");
|
|
1246
|
+
return;
|
|
1247
|
+
case "duration":
|
|
1248
|
+
target.duration = parseAtlasUnitValue(value, { line, column: tokens[0].column }, "duration");
|
|
1249
|
+
return;
|
|
1250
|
+
case "deltav":
|
|
1251
|
+
target.deltaV = parseAtlasUnitValue(value, { line, column: tokens[0].column });
|
|
1252
|
+
return;
|
|
1253
|
+
case "phaseangle":
|
|
1254
|
+
target.phaseAngle = parseAtlasUnitValue(value, { line, column: tokens[0].column }, "phaseAngle");
|
|
1255
|
+
return;
|
|
1256
|
+
case "turnangle":
|
|
1257
|
+
target.turnAngle = parseAtlasUnitValue(value, { line, column: tokens[0].column }, "turnAngle");
|
|
1258
|
+
return;
|
|
1259
|
+
case "energy":
|
|
1260
|
+
target.energy = parseAtlasUnitValue(value, { line, column: tokens[0].column });
|
|
1261
|
+
return;
|
|
1262
|
+
case "waypointlabel":
|
|
1263
|
+
warnIfSchema31Feature(section.sourceSchemaVersion, section.diagnostics, "segment.waypointLabel", {
|
|
1264
|
+
line,
|
|
1265
|
+
column: tokens[0].column,
|
|
1266
|
+
});
|
|
1267
|
+
target.waypointLabel = value;
|
|
1268
|
+
return;
|
|
1269
|
+
case "waypointdate":
|
|
1270
|
+
warnIfSchema31Feature(section.sourceSchemaVersion, section.diagnostics, "segment.waypointDate", {
|
|
1271
|
+
line,
|
|
1272
|
+
column: tokens[0].column,
|
|
1273
|
+
});
|
|
1274
|
+
target.waypointDate = value;
|
|
1275
|
+
return;
|
|
1276
|
+
case "renderhidden":
|
|
1277
|
+
warnIfSchema31Feature(section.sourceSchemaVersion, section.diagnostics, "segment.renderHidden", {
|
|
1278
|
+
line,
|
|
1279
|
+
column: tokens[0].column,
|
|
1280
|
+
});
|
|
1281
|
+
target.renderHidden = parseAtlasBoolean(value, "renderHidden", {
|
|
1282
|
+
line,
|
|
1283
|
+
column: tokens[0].column,
|
|
1284
|
+
});
|
|
1285
|
+
return;
|
|
1286
|
+
case "sampledensity":
|
|
1287
|
+
warnIfSchema31Feature(section.sourceSchemaVersion, section.diagnostics, "segment.sampleDensity", {
|
|
1288
|
+
line,
|
|
1289
|
+
column: tokens[0].column,
|
|
1290
|
+
});
|
|
1291
|
+
target.sampleDensity = parsePositiveNumber(value, line, tokens[0].column, "sampleDensity");
|
|
1292
|
+
return;
|
|
1293
|
+
case "notes":
|
|
1294
|
+
target.notes = parseTokenList(tokens.slice(1), line, "notes");
|
|
1295
|
+
return;
|
|
1296
|
+
default:
|
|
1297
|
+
throw new WorldOrbitError(`Unknown trajectory segment field "${tokens[0].value}"`, line, tokens[0].column);
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
function applyTrajectoryManeuverField(section, tokens, line) {
|
|
1301
|
+
const maneuver = section.activeManeuver;
|
|
1302
|
+
if (!maneuver) {
|
|
1303
|
+
return;
|
|
1304
|
+
}
|
|
1305
|
+
const key = requireUniqueField(tokens, section.activeManeuverSeenFields, line);
|
|
1306
|
+
const value = joinFieldValue(tokens, line);
|
|
1307
|
+
switch (key) {
|
|
1308
|
+
case "kind":
|
|
1309
|
+
maneuver.kind = value;
|
|
1310
|
+
return;
|
|
1311
|
+
case "label":
|
|
1312
|
+
maneuver.label = value;
|
|
1313
|
+
return;
|
|
1314
|
+
case "epoch":
|
|
1315
|
+
maneuver.epoch = value;
|
|
1316
|
+
return;
|
|
1317
|
+
case "deltav":
|
|
1318
|
+
maneuver.deltaV = parseAtlasUnitValue(value, { line, column: tokens[0].column });
|
|
1319
|
+
return;
|
|
1320
|
+
case "duration":
|
|
1321
|
+
maneuver.duration = parseAtlasUnitValue(value, { line, column: tokens[0].column }, "duration");
|
|
1322
|
+
return;
|
|
1323
|
+
case "notes":
|
|
1324
|
+
maneuver.notes = parseTokenList(tokens.slice(1), line, "notes");
|
|
1325
|
+
return;
|
|
1326
|
+
default:
|
|
1327
|
+
throw new WorldOrbitError(`Unknown trajectory maneuver field "${tokens[0].value}"`, line, tokens[0].column);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
950
1330
|
function parseEventPoseField(tokens, line, seenFields) {
|
|
951
1331
|
if (tokens.length < 2) {
|
|
952
1332
|
throw new WorldOrbitError("Invalid event pose field line", line, tokens[0]?.column ?? 1);
|
|
@@ -1056,7 +1436,8 @@ function parseLayerTokens(tokens, line, sourceSchemaVersion, diagnostics) {
|
|
|
1056
1436
|
raw === "events" ||
|
|
1057
1437
|
raw === "objects" ||
|
|
1058
1438
|
raw === "labels" ||
|
|
1059
|
-
raw === "metadata"
|
|
1439
|
+
raw === "metadata" ||
|
|
1440
|
+
raw === "trajectories") {
|
|
1060
1441
|
if (raw === "events" && sourceSchemaVersion && diagnostics) {
|
|
1061
1442
|
warnIfSchema21Feature(sourceSchemaVersion, diagnostics, "layers.events", {
|
|
1062
1443
|
line,
|
|
@@ -1181,6 +1562,18 @@ function parseInlineObjectFields(tokens, line, objectType, sourceSchemaVersion,
|
|
|
1181
1562
|
column: keyToken.column,
|
|
1182
1563
|
});
|
|
1183
1564
|
}
|
|
1565
|
+
else if (spec.version === "3.0") {
|
|
1566
|
+
warnIfSchema30Feature(sourceSchemaVersion, diagnostics, keyToken.value, {
|
|
1567
|
+
line,
|
|
1568
|
+
column: keyToken.column,
|
|
1569
|
+
});
|
|
1570
|
+
}
|
|
1571
|
+
else if (spec.version === "3.1") {
|
|
1572
|
+
warnIfSchema31Feature(sourceSchemaVersion, diagnostics, keyToken.value, {
|
|
1573
|
+
line,
|
|
1574
|
+
column: keyToken.column,
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1184
1577
|
index++;
|
|
1185
1578
|
const valueTokens = [];
|
|
1186
1579
|
if (spec.inlineMode === "single") {
|
|
@@ -1233,6 +1626,18 @@ function parseObjectField(tokens, line, objectType, sourceSchemaVersion, diagnos
|
|
|
1233
1626
|
column: tokens[0].column,
|
|
1234
1627
|
});
|
|
1235
1628
|
}
|
|
1629
|
+
else if (spec.version === "3.0") {
|
|
1630
|
+
warnIfSchema30Feature(sourceSchemaVersion, diagnostics, tokens[0].value, {
|
|
1631
|
+
line,
|
|
1632
|
+
column: tokens[0].column,
|
|
1633
|
+
});
|
|
1634
|
+
}
|
|
1635
|
+
else if (spec.version === "3.1") {
|
|
1636
|
+
warnIfSchema31Feature(sourceSchemaVersion, diagnostics, tokens[0].value, {
|
|
1637
|
+
line,
|
|
1638
|
+
column: tokens[0].column,
|
|
1639
|
+
});
|
|
1640
|
+
}
|
|
1236
1641
|
const field = {
|
|
1237
1642
|
type: "field",
|
|
1238
1643
|
key: tokens[0].value,
|
|
@@ -1277,6 +1682,7 @@ function normalizeDraftObject(node, sourceSchemaVersion, diagnostics) {
|
|
|
1277
1682
|
const tolerances = fieldMap.get("tolerance")?.map((field) => parseToleranceField(field));
|
|
1278
1683
|
const typedBlocks = normalizeTypedBlocks(node.typedBlockEntries);
|
|
1279
1684
|
const info = normalizeInfoEntries(node.infoEntries, "info");
|
|
1685
|
+
const trajectoryId = parseOptionalJoinedValue(fieldMap.get("trajectory")?.[0]);
|
|
1280
1686
|
const object = {
|
|
1281
1687
|
type: node.objectType,
|
|
1282
1688
|
id: node.id,
|
|
@@ -1306,6 +1712,8 @@ function normalizeDraftObject(node, sourceSchemaVersion, diagnostics) {
|
|
|
1306
1712
|
object.tolerances = tolerances;
|
|
1307
1713
|
if (typedBlocks && Object.keys(typedBlocks).length > 0)
|
|
1308
1714
|
object.typedBlocks = typedBlocks;
|
|
1715
|
+
if (trajectoryId)
|
|
1716
|
+
object.trajectoryId = trajectoryId;
|
|
1309
1717
|
if (isSchemaOlderThan(sourceSchemaVersion, "2.1")) {
|
|
1310
1718
|
if (object.groups ||
|
|
1311
1719
|
object.epoch ||
|
|
@@ -1317,10 +1725,14 @@ function normalizeDraftObject(node, sourceSchemaVersion, diagnostics) {
|
|
|
1317
1725
|
object.validationRules?.length ||
|
|
1318
1726
|
object.lockedFields?.length ||
|
|
1319
1727
|
object.tolerances?.length ||
|
|
1320
|
-
object.typedBlocks
|
|
1728
|
+
object.typedBlocks ||
|
|
1729
|
+
object.trajectoryId) {
|
|
1321
1730
|
warnIfSchema21Feature(sourceSchemaVersion, diagnostics, node.id, node.location);
|
|
1322
1731
|
}
|
|
1323
1732
|
}
|
|
1733
|
+
if (object.trajectoryId) {
|
|
1734
|
+
warnIfSchema30Feature(sourceSchemaVersion, diagnostics, `${node.id}.trajectory`, node.location);
|
|
1735
|
+
}
|
|
1324
1736
|
return object;
|
|
1325
1737
|
}
|
|
1326
1738
|
function normalizeDraftEvent(event, rawPoses) {
|
|
@@ -1337,6 +1749,8 @@ function normalizeDraftEventPose(rawPose) {
|
|
|
1337
1749
|
return {
|
|
1338
1750
|
objectId: rawPose.objectId,
|
|
1339
1751
|
placement,
|
|
1752
|
+
trajectorySegmentId: parseOptionalJoinedValue(fieldMap.get("segment")?.[0]),
|
|
1753
|
+
trajectoryManeuverId: parseOptionalJoinedValue(fieldMap.get("maneuver")?.[0]),
|
|
1340
1754
|
inner: parseOptionalUnitField(fieldMap.get("inner")?.[0], "inner"),
|
|
1341
1755
|
outer: parseOptionalUnitField(fieldMap.get("outer")?.[0], "outer"),
|
|
1342
1756
|
epoch: parseOptionalJoinedValue(fieldMap.get("epoch")?.[0]),
|
|
@@ -1553,6 +1967,32 @@ function warnIfSchema25Feature(sourceSchemaVersion, diagnostics, featureName, lo
|
|
|
1553
1967
|
column: location.column,
|
|
1554
1968
|
});
|
|
1555
1969
|
}
|
|
1970
|
+
function warnIfSchema30Feature(sourceSchemaVersion, diagnostics, featureName, location) {
|
|
1971
|
+
if (!isSchemaOlderThan(sourceSchemaVersion, "3.0")) {
|
|
1972
|
+
return;
|
|
1973
|
+
}
|
|
1974
|
+
diagnostics.push({
|
|
1975
|
+
code: "parse.schema30.featureCompatibility",
|
|
1976
|
+
severity: "warning",
|
|
1977
|
+
source: "parse",
|
|
1978
|
+
message: `Feature "${featureName}" requires schema 3.0; parsed in compatibility mode because the document header is "schema ${sourceSchemaVersion}".`,
|
|
1979
|
+
line: location.line,
|
|
1980
|
+
column: location.column,
|
|
1981
|
+
});
|
|
1982
|
+
}
|
|
1983
|
+
function warnIfSchema31Feature(sourceSchemaVersion, diagnostics, featureName, location) {
|
|
1984
|
+
if (!isSchemaOlderThan(sourceSchemaVersion, "3.1")) {
|
|
1985
|
+
return;
|
|
1986
|
+
}
|
|
1987
|
+
diagnostics.push({
|
|
1988
|
+
code: "parse.schema31.featureCompatibility",
|
|
1989
|
+
severity: "warning",
|
|
1990
|
+
source: "parse",
|
|
1991
|
+
message: `Feature "${featureName}" requires schema 3.1; parsed in compatibility mode because the document header is "schema ${sourceSchemaVersion}".`,
|
|
1992
|
+
line: location.line,
|
|
1993
|
+
column: location.column,
|
|
1994
|
+
});
|
|
1995
|
+
}
|
|
1556
1996
|
function isSchemaOlderThan(sourceSchemaVersion, requiredVersion) {
|
|
1557
1997
|
return schemaVersionRank(sourceSchemaVersion) < schemaVersionRank(requiredVersion);
|
|
1558
1998
|
}
|
|
@@ -1568,8 +2008,12 @@ function schemaVersionRank(version) {
|
|
|
1568
2008
|
return 3;
|
|
1569
2009
|
case "2.6":
|
|
1570
2010
|
return 4;
|
|
1571
|
-
|
|
2011
|
+
case "3.0":
|
|
1572
2012
|
return 5;
|
|
2013
|
+
case "3.1":
|
|
2014
|
+
return 6;
|
|
2015
|
+
default:
|
|
2016
|
+
return 7;
|
|
1573
2017
|
}
|
|
1574
2018
|
}
|
|
1575
2019
|
function preprocessAtlasSource(source) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { SceneRenderOptions, WorldOrbitAtlasDocument, WorldOrbitEvent, WorldOrbitAtlasSystem, WorldOrbitDiagnostic, WorldOrbitDocument, WorldOrbitObject } from "./types.js";
|
|
1
|
+
import type { SceneRenderOptions, WorldOrbitAtlasDocument, WorldOrbitEvent, WorldOrbitAtlasSystem, WorldOrbitDiagnostic, WorldOrbitDocument, WorldOrbitObject, WorldOrbitTrajectory } from "./types.js";
|
|
2
2
|
interface UpgradeOptions extends Pick<SceneRenderOptions, "preset" | "projection"> {
|
|
3
3
|
}
|
|
4
4
|
export declare function upgradeDocumentToV2(document: WorldOrbitDocument, options?: UpgradeOptions): WorldOrbitAtlasDocument;
|
|
@@ -12,6 +12,7 @@ export declare function upgradeDocumentToDraftV2(document: WorldOrbitDocument, o
|
|
|
12
12
|
groups: import("./types.js").WorldOrbitGroup[];
|
|
13
13
|
relations: import("./types.js").WorldOrbitRelation[];
|
|
14
14
|
events: WorldOrbitEvent[];
|
|
15
|
+
trajectories: WorldOrbitTrajectory[];
|
|
15
16
|
objects: WorldOrbitObject[];
|
|
16
17
|
diagnostics: WorldOrbitDiagnostic[];
|
|
17
18
|
};
|