worldorbit 2.5.17 → 3.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.
Files changed (203) hide show
  1. package/README.md +91 -18
  2. package/dist/browser/core/dist/atlas-edit.d.ts +11 -0
  3. package/dist/browser/core/dist/atlas-edit.js +347 -0
  4. package/dist/browser/core/dist/atlas-utils.d.ts +22 -0
  5. package/dist/browser/core/dist/atlas-utils.js +189 -0
  6. package/dist/browser/core/dist/atlas-validate.d.ts +2 -0
  7. package/dist/browser/core/dist/atlas-validate.js +488 -0
  8. package/dist/browser/core/dist/diagnostics.d.ts +10 -0
  9. package/dist/browser/core/dist/diagnostics.js +109 -0
  10. package/dist/browser/core/dist/draft-parse.d.ts +3 -0
  11. package/dist/browser/core/dist/draft-parse.js +1654 -0
  12. package/dist/browser/core/dist/draft.d.ts +21 -0
  13. package/dist/browser/core/dist/draft.js +482 -0
  14. package/dist/browser/core/dist/errors.d.ts +7 -0
  15. package/dist/browser/core/dist/errors.js +16 -0
  16. package/dist/browser/core/dist/format.d.ts +4 -0
  17. package/dist/browser/core/dist/format.js +613 -0
  18. package/dist/browser/core/dist/index.d.ts +29 -0
  19. package/dist/browser/core/dist/index.js +35 -6101
  20. package/dist/browser/core/dist/load.d.ts +4 -0
  21. package/dist/browser/core/dist/load.js +182 -0
  22. package/dist/browser/core/dist/markdown.d.ts +2 -0
  23. package/dist/browser/core/dist/markdown.js +37 -0
  24. package/dist/browser/core/dist/normalize.d.ts +2 -0
  25. package/dist/browser/core/dist/normalize.js +312 -0
  26. package/dist/browser/core/dist/parse.d.ts +2 -0
  27. package/dist/browser/core/dist/parse.js +133 -0
  28. package/dist/browser/core/dist/scene.d.ts +3 -0
  29. package/dist/browser/core/dist/scene.js +1901 -0
  30. package/dist/browser/core/dist/schema.d.ts +8 -0
  31. package/dist/browser/core/dist/schema.js +298 -0
  32. package/dist/browser/core/dist/spatial-scene.d.ts +3 -0
  33. package/dist/browser/core/dist/spatial-scene.js +420 -0
  34. package/dist/browser/core/dist/tokenize.d.ts +4 -0
  35. package/dist/browser/core/dist/tokenize.js +68 -0
  36. package/dist/browser/core/dist/types.d.ts +637 -0
  37. package/dist/browser/core/dist/types.js +1 -0
  38. package/dist/browser/core/dist/validate.d.ts +2 -0
  39. package/dist/browser/core/dist/validate.js +56 -0
  40. package/dist/browser/editor/dist/editor.d.ts +2 -0
  41. package/dist/browser/editor/dist/editor.js +3700 -0
  42. package/dist/browser/editor/dist/index.d.ts +2 -0
  43. package/dist/browser/editor/dist/index.js +1 -11702
  44. package/dist/browser/editor/dist/types.d.ts +59 -0
  45. package/dist/browser/editor/dist/types.js +1 -0
  46. package/dist/browser/markdown/dist/html.d.ts +3 -0
  47. package/dist/browser/markdown/dist/html.js +64 -0
  48. package/dist/browser/markdown/dist/index.d.ts +4 -0
  49. package/dist/browser/markdown/dist/index.js +3 -5766
  50. package/dist/browser/markdown/dist/rehype.d.ts +10 -0
  51. package/dist/browser/markdown/dist/rehype.js +49 -0
  52. package/dist/browser/markdown/dist/remark.d.ts +9 -0
  53. package/dist/browser/markdown/dist/remark.js +28 -0
  54. package/dist/browser/markdown/dist/types.d.ts +11 -0
  55. package/dist/browser/markdown/dist/types.js +1 -0
  56. package/dist/browser/viewer/dist/atlas-state.d.ts +12 -0
  57. package/dist/browser/viewer/dist/atlas-state.js +269 -0
  58. package/dist/browser/viewer/dist/atlas-viewer.d.ts +2 -0
  59. package/dist/browser/viewer/dist/atlas-viewer.js +495 -0
  60. package/dist/browser/viewer/dist/custom-element.d.ts +1 -0
  61. package/dist/browser/viewer/dist/custom-element.js +78 -0
  62. package/dist/browser/viewer/dist/embed.d.ts +24 -0
  63. package/dist/browser/viewer/dist/embed.js +172 -0
  64. package/dist/browser/viewer/dist/errors.d.ts +6 -0
  65. package/dist/browser/viewer/dist/errors.js +12 -0
  66. package/dist/browser/viewer/dist/index.d.ts +10 -0
  67. package/dist/browser/viewer/dist/index.js +9 -7901
  68. package/dist/browser/viewer/dist/minimap.d.ts +3 -0
  69. package/dist/browser/viewer/dist/minimap.js +63 -0
  70. package/dist/browser/viewer/dist/render.d.ts +6 -0
  71. package/dist/browser/viewer/dist/render.js +670 -0
  72. package/dist/browser/viewer/dist/runtime-3d.d.ts +19 -0
  73. package/dist/browser/viewer/dist/runtime-3d.js +494 -0
  74. package/dist/browser/viewer/dist/theme.d.ts +4 -0
  75. package/dist/browser/viewer/dist/theme.js +103 -0
  76. package/dist/browser/viewer/dist/tooltip.d.ts +3 -0
  77. package/dist/browser/viewer/dist/tooltip.js +198 -0
  78. package/dist/browser/viewer/dist/types.d.ts +292 -0
  79. package/dist/browser/viewer/dist/types.js +1 -0
  80. package/dist/browser/viewer/dist/vendor/three.module.js +53032 -0
  81. package/dist/browser/viewer/dist/viewer-state.d.ts +19 -0
  82. package/dist/browser/viewer/dist/viewer-state.js +162 -0
  83. package/dist/browser/viewer/dist/viewer.d.ts +2 -0
  84. package/dist/browser/viewer/dist/viewer.js +1662 -0
  85. package/dist/unpkg/core/dist/atlas-edit.d.ts +11 -0
  86. package/dist/unpkg/core/dist/atlas-edit.js +347 -0
  87. package/dist/unpkg/core/dist/atlas-utils.d.ts +22 -0
  88. package/dist/unpkg/core/dist/atlas-utils.js +189 -0
  89. package/dist/unpkg/core/dist/atlas-validate.d.ts +2 -0
  90. package/dist/unpkg/core/dist/atlas-validate.js +488 -0
  91. package/dist/unpkg/core/dist/diagnostics.d.ts +10 -0
  92. package/dist/unpkg/core/dist/diagnostics.js +109 -0
  93. package/dist/unpkg/core/dist/draft-parse.d.ts +3 -0
  94. package/dist/unpkg/core/dist/draft-parse.js +1654 -0
  95. package/dist/unpkg/core/dist/draft.d.ts +21 -0
  96. package/dist/unpkg/core/dist/draft.js +482 -0
  97. package/dist/unpkg/core/dist/errors.d.ts +7 -0
  98. package/dist/unpkg/core/dist/errors.js +16 -0
  99. package/dist/unpkg/core/dist/format.d.ts +4 -0
  100. package/dist/unpkg/core/dist/format.js +613 -0
  101. package/dist/unpkg/core/dist/index.d.ts +29 -0
  102. package/dist/unpkg/core/dist/index.js +35 -6173
  103. package/dist/unpkg/core/dist/load.d.ts +4 -0
  104. package/dist/unpkg/core/dist/load.js +182 -0
  105. package/dist/unpkg/core/dist/markdown.d.ts +2 -0
  106. package/dist/unpkg/core/dist/markdown.js +37 -0
  107. package/dist/unpkg/core/dist/normalize.d.ts +2 -0
  108. package/dist/unpkg/core/dist/normalize.js +312 -0
  109. package/dist/unpkg/core/dist/parse.d.ts +2 -0
  110. package/dist/unpkg/core/dist/parse.js +133 -0
  111. package/dist/unpkg/core/dist/scene.d.ts +3 -0
  112. package/dist/unpkg/core/dist/scene.js +1901 -0
  113. package/dist/unpkg/core/dist/schema.d.ts +8 -0
  114. package/dist/unpkg/core/dist/schema.js +298 -0
  115. package/dist/unpkg/core/dist/spatial-scene.d.ts +3 -0
  116. package/dist/unpkg/core/dist/spatial-scene.js +420 -0
  117. package/dist/unpkg/core/dist/tokenize.d.ts +4 -0
  118. package/dist/unpkg/core/dist/tokenize.js +68 -0
  119. package/dist/unpkg/core/dist/types.d.ts +637 -0
  120. package/dist/unpkg/core/dist/types.js +1 -0
  121. package/dist/unpkg/core/dist/validate.d.ts +2 -0
  122. package/dist/unpkg/core/dist/validate.js +56 -0
  123. package/dist/unpkg/editor/dist/editor.d.ts +2 -0
  124. package/dist/unpkg/editor/dist/editor.js +3700 -0
  125. package/dist/unpkg/editor/dist/index.d.ts +2 -0
  126. package/dist/unpkg/editor/dist/index.js +1 -11727
  127. package/dist/unpkg/editor/dist/types.d.ts +59 -0
  128. package/dist/unpkg/editor/dist/types.js +1 -0
  129. package/dist/unpkg/markdown/dist/html.d.ts +3 -0
  130. package/dist/unpkg/markdown/dist/html.js +64 -0
  131. package/dist/unpkg/markdown/dist/index.d.ts +4 -0
  132. package/dist/unpkg/markdown/dist/index.js +3 -5794
  133. package/dist/unpkg/markdown/dist/rehype.d.ts +10 -0
  134. package/dist/unpkg/markdown/dist/rehype.js +49 -0
  135. package/dist/unpkg/markdown/dist/remark.d.ts +9 -0
  136. package/dist/unpkg/markdown/dist/remark.js +28 -0
  137. package/dist/unpkg/markdown/dist/types.d.ts +11 -0
  138. package/dist/unpkg/markdown/dist/types.js +1 -0
  139. package/dist/unpkg/viewer/dist/atlas-state.d.ts +12 -0
  140. package/dist/unpkg/viewer/dist/atlas-state.js +269 -0
  141. package/dist/unpkg/viewer/dist/atlas-viewer.d.ts +2 -0
  142. package/dist/unpkg/viewer/dist/atlas-viewer.js +495 -0
  143. package/dist/unpkg/viewer/dist/custom-element.d.ts +1 -0
  144. package/dist/unpkg/viewer/dist/custom-element.js +78 -0
  145. package/dist/unpkg/viewer/dist/embed.d.ts +24 -0
  146. package/dist/unpkg/viewer/dist/embed.js +172 -0
  147. package/dist/unpkg/viewer/dist/errors.d.ts +6 -0
  148. package/dist/unpkg/viewer/dist/errors.js +12 -0
  149. package/dist/unpkg/viewer/dist/index.d.ts +10 -0
  150. package/dist/unpkg/viewer/dist/index.js +9 -7958
  151. package/dist/unpkg/viewer/dist/minimap.d.ts +3 -0
  152. package/dist/unpkg/viewer/dist/minimap.js +63 -0
  153. package/dist/unpkg/viewer/dist/render.d.ts +6 -0
  154. package/dist/unpkg/viewer/dist/render.js +670 -0
  155. package/dist/unpkg/viewer/dist/runtime-3d.d.ts +19 -0
  156. package/dist/unpkg/viewer/dist/runtime-3d.js +494 -0
  157. package/dist/unpkg/viewer/dist/theme.d.ts +4 -0
  158. package/dist/unpkg/viewer/dist/theme.js +103 -0
  159. package/dist/unpkg/viewer/dist/tooltip.d.ts +3 -0
  160. package/dist/unpkg/viewer/dist/tooltip.js +198 -0
  161. package/dist/unpkg/viewer/dist/types.d.ts +292 -0
  162. package/dist/unpkg/viewer/dist/types.js +1 -0
  163. package/dist/unpkg/viewer/dist/vendor/three.module.js +53032 -0
  164. package/dist/unpkg/viewer/dist/viewer-state.d.ts +19 -0
  165. package/dist/unpkg/viewer/dist/viewer-state.js +162 -0
  166. package/dist/unpkg/viewer/dist/viewer.d.ts +2 -0
  167. package/dist/unpkg/viewer/dist/viewer.js +1662 -0
  168. package/dist/unpkg/worldorbit-core.min.js +1 -12
  169. package/dist/unpkg/worldorbit-editor.min.js +1 -894
  170. package/dist/unpkg/worldorbit-markdown.min.js +1 -103
  171. package/dist/unpkg/worldorbit-viewer.min.js +1 -259
  172. package/dist/unpkg/worldorbit.js +2 -9243
  173. package/dist/unpkg/worldorbit.min.js +2 -263
  174. package/package.json +1 -1
  175. package/packages/core/dist/atlas-edit.js +1 -1
  176. package/packages/core/dist/atlas-validate.js +99 -10
  177. package/packages/core/dist/draft-parse.js +190 -15
  178. package/packages/core/dist/draft.js +50 -11
  179. package/packages/core/dist/format.js +36 -5
  180. package/packages/core/dist/index.d.ts +1 -0
  181. package/packages/core/dist/index.js +1 -0
  182. package/packages/core/dist/load.js +9 -2
  183. package/packages/core/dist/scene.js +158 -24
  184. package/packages/core/dist/spatial-scene.d.ts +3 -0
  185. package/packages/core/dist/spatial-scene.js +420 -0
  186. package/packages/core/dist/types.d.ts +124 -2
  187. package/packages/editor/dist/editor.js +130 -8
  188. package/packages/editor/dist/types.d.ts +4 -0
  189. package/packages/markdown/dist/html.js +10 -3
  190. package/packages/viewer/dist/atlas-state.js +8 -2
  191. package/packages/viewer/dist/atlas-viewer.js +20 -8
  192. package/packages/viewer/dist/custom-element.js +18 -4
  193. package/packages/viewer/dist/embed.d.ts +5 -1
  194. package/packages/viewer/dist/embed.js +58 -24
  195. package/packages/viewer/dist/errors.d.ts +6 -0
  196. package/packages/viewer/dist/errors.js +12 -0
  197. package/packages/viewer/dist/index.d.ts +1 -0
  198. package/packages/viewer/dist/index.js +1 -0
  199. package/packages/viewer/dist/runtime-3d.d.ts +19 -0
  200. package/packages/viewer/dist/runtime-3d.js +494 -0
  201. package/packages/viewer/dist/types.d.ts +25 -3
  202. package/packages/viewer/dist/vendor/three.module.js +53032 -0
  203. package/packages/viewer/dist/viewer.js +517 -41
@@ -38,15 +38,17 @@ export function formatDocument(document, options = {}) {
38
38
  const schema = options.schema ?? "auto";
39
39
  const useDraft = schema === "2.0" ||
40
40
  schema === "2.1" ||
41
+ schema === "2.5" ||
41
42
  schema === "2.0-draft" ||
42
43
  document.version === "2.0" ||
43
44
  document.version === "2.1" ||
45
+ document.version === "2.5" ||
44
46
  document.version === "2.0-draft";
45
47
  if (useDraft) {
46
48
  if (schema === "2.0-draft") {
47
49
  const legacyDraftDocument = document.version === "2.0-draft"
48
50
  ? document
49
- : document.version === "2.0" || document.version === "2.1"
51
+ : document.version === "2.0" || document.version === "2.1" || document.version === "2.5"
50
52
  ? {
51
53
  ...document,
52
54
  version: "2.0-draft",
@@ -55,7 +57,7 @@ export function formatDocument(document, options = {}) {
55
57
  : upgradeDocumentToDraftV2(document);
56
58
  return formatDraftDocument(legacyDraftDocument);
57
59
  }
58
- const atlasDocument = document.version === "2.0" || document.version === "2.1"
60
+ const atlasDocument = document.version === "2.0" || document.version === "2.1" || document.version === "2.5"
59
61
  ? document
60
62
  : document.version === "2.0-draft"
61
63
  ? {
@@ -64,11 +66,11 @@ export function formatDocument(document, options = {}) {
64
66
  schemaVersion: "2.0",
65
67
  }
66
68
  : upgradeDocumentToV2(document);
67
- if (schema === "2.1" && atlasDocument.version !== "2.1") {
69
+ if ((schema === "2.0" || schema === "2.1" || schema === "2.5") && atlasDocument.version !== schema) {
68
70
  return formatAtlasDocument({
69
71
  ...atlasDocument,
70
- version: "2.1",
71
- schemaVersion: "2.1",
72
+ version: schema,
73
+ schemaVersion: schema,
72
74
  });
73
75
  }
74
76
  return formatAtlasDocument(atlasDocument);
@@ -349,6 +351,21 @@ function formatAtlasViewpoint(viewpoint) {
349
351
  if (viewpoint.rotationDeg !== 0) {
350
352
  lines.push(` rotation ${viewpoint.rotationDeg}`);
351
353
  }
354
+ if (viewpoint.camera && hasCameraValues(viewpoint.camera)) {
355
+ lines.push(" camera");
356
+ if (viewpoint.camera.azimuth !== null) {
357
+ lines.push(` azimuth ${viewpoint.camera.azimuth}`);
358
+ }
359
+ if (viewpoint.camera.elevation !== null) {
360
+ lines.push(` elevation ${viewpoint.camera.elevation}`);
361
+ }
362
+ if (viewpoint.camera.roll !== null) {
363
+ lines.push(` roll ${viewpoint.camera.roll}`);
364
+ }
365
+ if (viewpoint.camera.distance !== null) {
366
+ lines.push(` distance ${viewpoint.camera.distance}`);
367
+ }
368
+ }
352
369
  const layerTokens = formatDraftLayers(viewpoint.layers);
353
370
  if (layerTokens.length > 0) {
354
371
  lines.push(` layers ${layerTokens.join(" ")}`);
@@ -448,6 +465,12 @@ function formatAtlasEvent(event) {
448
465
  if (event.visibility) {
449
466
  lines.push(` visibility ${quoteIfNeeded(event.visibility)}`);
450
467
  }
468
+ if (event.epoch) {
469
+ lines.push(` epoch ${quoteIfNeeded(event.epoch)}`);
470
+ }
471
+ if (event.referencePlane) {
472
+ lines.push(` referencePlane ${quoteIfNeeded(event.referencePlane)}`);
473
+ }
451
474
  if (event.tags.length > 0) {
452
475
  lines.push(` tags ${event.tags.map(quoteIfNeeded).join(" ")}`);
453
476
  }
@@ -472,10 +495,18 @@ function formatAtlasEvent(event) {
472
495
  function formatEventPoseFields(pose) {
473
496
  return [
474
497
  ...formatPlacement(pose.placement),
498
+ ...(pose.epoch ? [`epoch ${quoteIfNeeded(pose.epoch)}`] : []),
499
+ ...(pose.referencePlane ? [`referencePlane ${quoteIfNeeded(pose.referencePlane)}`] : []),
475
500
  ...formatOptionalUnit("inner", pose.inner),
476
501
  ...formatOptionalUnit("outer", pose.outer),
477
502
  ];
478
503
  }
504
+ function hasCameraValues(camera) {
505
+ return (camera.azimuth !== null ||
506
+ camera.elevation !== null ||
507
+ camera.roll !== null ||
508
+ camera.distance !== null);
509
+ }
479
510
  function formatValue(value) {
480
511
  if (Array.isArray(value)) {
481
512
  return value.map((item) => quoteIfNeeded(item)).join(" ");
@@ -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";
@@ -5,8 +5,9 @@ import { WorldOrbitError } from "./errors.js";
5
5
  import { normalizeDocument } from "./normalize.js";
6
6
  import { parseWorldOrbit } from "./parse.js";
7
7
  import { validateDocument } from "./validate.js";
8
- const ATLAS_SCHEMA_PATTERN = /^schema\s+2(?:\.0|\.1)?$/i;
8
+ const ATLAS_SCHEMA_PATTERN = /^schema\s+2(?:\.0|\.1|\.5)?$/i;
9
9
  const ATLAS_SCHEMA_21_PATTERN = /^schema\s+2\.1$/i;
10
+ const ATLAS_SCHEMA_25_PATTERN = /^schema\s+2\.5$/i;
10
11
  const LEGACY_DRAFT_SCHEMA_PATTERN = /^schema\s+2\.0-draft$/i;
11
12
  export function detectWorldOrbitSchemaVersion(source) {
12
13
  for (const line of stripCommentsForSchemaDetection(source).split(/\r?\n/)) {
@@ -20,6 +21,9 @@ export function detectWorldOrbitSchemaVersion(source) {
20
21
  if (ATLAS_SCHEMA_21_PATTERN.test(trimmed)) {
21
22
  return "2.1";
22
23
  }
24
+ if (ATLAS_SCHEMA_25_PATTERN.test(trimmed)) {
25
+ return "2.5";
26
+ }
23
27
  if (ATLAS_SCHEMA_PATTERN.test(trimmed)) {
24
28
  return "2.0";
25
29
  }
@@ -80,7 +84,10 @@ export function loadWorldOrbitSource(source) {
80
84
  }
81
85
  export function loadWorldOrbitSourceWithDiagnostics(source) {
82
86
  const schemaVersion = detectWorldOrbitSchemaVersion(source);
83
- if (schemaVersion === "2.0" || schemaVersion === "2.0-draft" || schemaVersion === "2.1") {
87
+ if (schemaVersion === "2.0" ||
88
+ schemaVersion === "2.0-draft" ||
89
+ schemaVersion === "2.1" ||
90
+ schemaVersion === "2.5") {
84
91
  return loadAtlasSourceWithDiagnostics(source, schemaVersion);
85
92
  }
86
93
  let ast;
@@ -14,7 +14,9 @@ export function renderDocumentToScene(document, options = {}) {
14
14
  const height = frame.height;
15
15
  const padding = frame.padding;
16
16
  const layoutPreset = resolveLayoutPreset(document);
17
- const projection = resolveProjection(document, options.projection);
17
+ const schemaProjection = resolveProjection(document, options.projection);
18
+ const camera = normalizeViewCamera(options.camera ?? null);
19
+ const renderProjection = resolveRenderProjection(schemaProjection, camera);
18
20
  const scaleModel = resolveScaleModel(layoutPreset, options.scaleModel);
19
21
  const spacingFactor = layoutPresetSpacing(layoutPreset);
20
22
  const systemId = document.system?.id ?? null;
@@ -57,7 +59,7 @@ export function renderDocumentToScene(document, options = {}) {
57
59
  surfaceChildren,
58
60
  objectMap,
59
61
  spacingFactor,
60
- projection,
62
+ projection: renderProjection,
61
63
  scaleModel,
62
64
  };
63
65
  const primaryRoot = rootObjects.find((object) => object.type === "star") ?? rootObjects[0] ?? null;
@@ -72,7 +74,7 @@ export function renderDocumentToScene(document, options = {}) {
72
74
  scaleModel.orbitDistanceMultiplier;
73
75
  secondaryRoots.forEach((object, index) => {
74
76
  const angle = angleForIndex(index, secondaryRoots.length, -Math.PI / 2);
75
- const offset = projectPolarOffset(angle, rootRingRadius, projection, 1);
77
+ const offset = projectPolarOffset(angle, rootRingRadius, renderProjection, 1);
76
78
  placeObject(object, centerX + offset.x, centerY + offset.y, 0, positions, orbitDrafts, leaderDrafts, context);
77
79
  });
78
80
  }
@@ -137,28 +139,35 @@ export function renderDocumentToScene(document, options = {}) {
137
139
  const layers = createSceneLayers(orbitVisuals, relations, events, leaders, objects, labels);
138
140
  const groups = createSceneGroups(objects, orbitVisuals, leaders, labels, relationships, scaleModel.labelMultiplier);
139
141
  const semanticGroups = createSceneSemanticGroups(document, objects);
140
- const viewpoints = createSceneViewpoints(document, projection, frame.preset, relationships, objectMap);
142
+ const viewpoints = createSceneViewpoints(document, schemaProjection, frame.preset, relationships, objectMap);
141
143
  const contentBounds = calculateContentBounds(width, height, objects, orbitVisuals, leaders, labels, scaleModel.labelMultiplier);
142
144
  return {
143
145
  width,
144
146
  height,
145
147
  padding,
146
148
  renderPreset: frame.preset,
147
- projection,
149
+ projection: schemaProjection,
150
+ renderProjection,
151
+ camera,
148
152
  scaleModel,
149
153
  title: String(document.system?.title ?? document.system?.properties.title ?? document.system?.id ?? "WorldOrbit") ||
150
154
  "WorldOrbit",
151
- subtitle: `${capitalizeLabel(projection)} view - ${capitalizeLabel(layoutPreset)} layout`,
155
+ subtitle: buildSceneSubtitle(schemaProjection, renderProjection, layoutPreset, camera),
152
156
  systemId,
153
- viewMode: projection,
157
+ viewMode: schemaProjection,
154
158
  layoutPreset,
155
159
  metadata: {
156
160
  format: document.format,
157
161
  version: document.version,
158
- view: projection,
162
+ view: schemaProjection,
163
+ renderProjection,
159
164
  scale: String(document.system?.properties.scale ?? layoutPreset),
160
165
  units: String(document.system?.properties.units ?? "mixed"),
161
166
  preset: frame.preset ?? "custom",
167
+ ...(camera?.azimuth !== null ? { "camera.azimuth": String(camera?.azimuth) } : {}),
168
+ ...(camera?.elevation !== null ? { "camera.elevation": String(camera?.elevation) } : {}),
169
+ ...(camera?.roll !== null ? { "camera.roll": String(camera?.roll) } : {}),
170
+ ...(camera?.distance !== null ? { "camera.distance": String(camera?.distance) } : {}),
162
171
  },
163
172
  contentBounds,
164
173
  layers,
@@ -195,23 +204,42 @@ function createEffectiveObjects(objects, events, activeEventId) {
195
204
  return cloned;
196
205
  }
197
206
  const objectMap = new Map(cloned.map((object) => [object.id, object]));
207
+ const referencedIds = new Set([
208
+ ...(activeEvent.targetObjectId ? [activeEvent.targetObjectId] : []),
209
+ ...activeEvent.participantObjectIds,
210
+ ...activeEvent.positions.map((pose) => pose.objectId),
211
+ ]);
212
+ for (const objectId of referencedIds) {
213
+ const object = objectMap.get(objectId);
214
+ if (!object) {
215
+ continue;
216
+ }
217
+ if (activeEvent.epoch) {
218
+ object.epoch = activeEvent.epoch;
219
+ }
220
+ if (activeEvent.referencePlane) {
221
+ object.referencePlane = activeEvent.referencePlane;
222
+ }
223
+ }
198
224
  for (const pose of activeEvent.positions) {
199
225
  const object = objectMap.get(pose.objectId);
200
226
  if (!object) {
201
227
  continue;
202
228
  }
203
- object.placement = pose.placement ? structuredClone(pose.placement) : null;
229
+ if (pose.placement) {
230
+ object.placement = structuredClone(pose.placement);
231
+ }
204
232
  if (pose.inner) {
205
233
  object.properties.inner = { ...pose.inner };
206
234
  }
207
- else {
208
- delete object.properties.inner;
209
- }
210
235
  if (pose.outer) {
211
236
  object.properties.outer = { ...pose.outer };
212
237
  }
213
- else {
214
- delete object.properties.outer;
238
+ if (pose.epoch) {
239
+ object.epoch = pose.epoch;
240
+ }
241
+ if (pose.referencePlane) {
242
+ object.referencePlane = pose.referencePlane;
215
243
  }
216
244
  }
217
245
  return cloned;
@@ -252,12 +280,69 @@ function scenePresetDefaults(preset) {
252
280
  }
253
281
  }
254
282
  function resolveProjection(document, projection) {
255
- if (projection === "topdown" || projection === "isometric") {
283
+ if (projection === "topdown" ||
284
+ projection === "isometric" ||
285
+ projection === "orthographic" ||
286
+ projection === "perspective") {
256
287
  return projection;
257
288
  }
258
- return String(document.system?.properties.view ?? "topdown").toLowerCase() === "isometric"
259
- ? "isometric"
260
- : "topdown";
289
+ const documentView = String(document.system?.properties.view ?? "topdown").toLowerCase();
290
+ return parseViewProjection(documentView) ?? "topdown";
291
+ }
292
+ function resolveRenderProjection(projection, camera) {
293
+ switch (projection) {
294
+ case "topdown":
295
+ return "topdown";
296
+ case "isometric":
297
+ return "isometric";
298
+ case "orthographic":
299
+ return camera && (camera.azimuth !== null || camera.elevation !== null || camera.roll !== null)
300
+ ? "isometric"
301
+ : "topdown";
302
+ case "perspective":
303
+ return "isometric";
304
+ }
305
+ }
306
+ function normalizeViewCamera(camera) {
307
+ if (!camera) {
308
+ return null;
309
+ }
310
+ const normalized = {
311
+ azimuth: normalizeFiniteCameraValue(camera.azimuth),
312
+ elevation: normalizeFiniteCameraValue(camera.elevation),
313
+ roll: normalizeFiniteCameraValue(camera.roll),
314
+ distance: normalizePositiveCameraDistance(camera.distance),
315
+ };
316
+ return normalized.azimuth !== null ||
317
+ normalized.elevation !== null ||
318
+ normalized.roll !== null ||
319
+ normalized.distance !== null
320
+ ? normalized
321
+ : null;
322
+ }
323
+ function normalizeFiniteCameraValue(value) {
324
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
325
+ }
326
+ function normalizePositiveCameraDistance(value) {
327
+ return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : null;
328
+ }
329
+ function buildSceneSubtitle(projection, renderProjection, layoutPreset, camera) {
330
+ const parts = [`${capitalizeLabel(projection)} view`, `${capitalizeLabel(layoutPreset)} layout`];
331
+ if (projection !== renderProjection) {
332
+ parts.push(`2D ${renderProjection} fallback`);
333
+ }
334
+ if (camera) {
335
+ const cameraParts = [
336
+ camera.azimuth !== null ? `az ${camera.azimuth}` : null,
337
+ camera.elevation !== null ? `el ${camera.elevation}` : null,
338
+ camera.roll !== null ? `roll ${camera.roll}` : null,
339
+ camera.distance !== null ? `dist ${camera.distance}` : null,
340
+ ].filter(Boolean);
341
+ if (cameraParts.length > 0) {
342
+ parts.push(`camera ${cameraParts.join(" / ")}`);
343
+ }
344
+ }
345
+ return parts.join(" - ");
261
346
  }
262
347
  function resolveScaleModel(layoutPreset, overrides) {
263
348
  const defaults = defaultScaleModel(layoutPreset);
@@ -728,6 +813,8 @@ function createSceneViewpoints(document, projection, preset, relationships, obje
728
813
  function createGeneratedOverviewViewpoint(document, projection, preset) {
729
814
  const title = document.system?.title ?? document.system?.properties.title;
730
815
  const label = title ? `${String(title)} Overview` : "Overview";
816
+ const camera = normalizeViewCamera(null);
817
+ const renderProjection = resolveRenderProjection(projection, camera);
731
818
  return {
732
819
  id: "overview",
733
820
  label,
@@ -736,6 +823,8 @@ function createGeneratedOverviewViewpoint(document, projection, preset) {
736
823
  selectedObjectId: null,
737
824
  eventIds: [],
738
825
  projection,
826
+ renderProjection,
827
+ camera,
739
828
  preset,
740
829
  rotationDeg: 0,
741
830
  scale: null,
@@ -785,6 +874,30 @@ function applyViewpointField(draft, field, value, document, projection, preset,
785
874
  case "angle":
786
875
  draft.rotationDeg = parseFiniteNumber(normalizedValue) ?? draft.rotationDeg ?? 0;
787
876
  return;
877
+ case "camera.azimuth":
878
+ draft.camera = {
879
+ ...(draft.camera ?? createEmptyViewCamera()),
880
+ azimuth: parseFiniteNumber(normalizedValue),
881
+ };
882
+ return;
883
+ case "camera.elevation":
884
+ draft.camera = {
885
+ ...(draft.camera ?? createEmptyViewCamera()),
886
+ elevation: parseFiniteNumber(normalizedValue),
887
+ };
888
+ return;
889
+ case "camera.roll":
890
+ draft.camera = {
891
+ ...(draft.camera ?? createEmptyViewCamera()),
892
+ roll: parseFiniteNumber(normalizedValue),
893
+ };
894
+ return;
895
+ case "camera.distance":
896
+ draft.camera = {
897
+ ...(draft.camera ?? createEmptyViewCamera()),
898
+ distance: parsePositiveNumber(normalizedValue),
899
+ };
900
+ return;
788
901
  case "zoom":
789
902
  case "scale":
790
903
  draft.scale = parsePositiveNumber(normalizedValue);
@@ -826,6 +939,9 @@ function finalizeViewpointDraft(draft, projection, preset, objectMap) {
826
939
  : objectId;
827
940
  const filter = normalizeViewpointFilter(draft.filter);
828
941
  const label = draft.label?.trim() || humanizeIdentifier(draft.id);
942
+ const resolvedProjection = draft.projection ?? projection;
943
+ const camera = normalizeViewCamera(draft.camera ?? null);
944
+ const renderProjection = resolveRenderProjection(resolvedProjection, camera);
829
945
  return {
830
946
  id: draft.id,
831
947
  label,
@@ -833,7 +949,9 @@ function finalizeViewpointDraft(draft, projection, preset, objectMap) {
833
949
  objectId,
834
950
  selectedObjectId,
835
951
  eventIds: [...new Set(draft.eventIds ?? [])],
836
- projection: draft.projection ?? projection,
952
+ projection: resolvedProjection,
953
+ renderProjection,
954
+ camera,
837
955
  preset: draft.preset ?? preset,
838
956
  rotationDeg: draft.rotationDeg ?? 0,
839
957
  scale: draft.scale ?? null,
@@ -850,6 +968,14 @@ function createEmptyViewpointFilter() {
850
968
  groupIds: [],
851
969
  };
852
970
  }
971
+ function createEmptyViewCamera() {
972
+ return {
973
+ azimuth: null,
974
+ elevation: null,
975
+ roll: null,
976
+ distance: null,
977
+ };
978
+ }
853
979
  function normalizeViewpointFilter(filter) {
854
980
  if (!filter) {
855
981
  return null;
@@ -868,11 +994,18 @@ function normalizeViewpointFilter(filter) {
868
994
  : null;
869
995
  }
870
996
  function parseViewProjection(value) {
871
- return value.toLowerCase() === "isometric"
872
- ? "isometric"
873
- : value.toLowerCase() === "topdown"
874
- ? "topdown"
875
- : null;
997
+ switch (value.toLowerCase()) {
998
+ case "topdown":
999
+ return "topdown";
1000
+ case "isometric":
1001
+ return "isometric";
1002
+ case "orthographic":
1003
+ return "orthographic";
1004
+ case "perspective":
1005
+ return "perspective";
1006
+ default:
1007
+ return null;
1008
+ }
876
1009
  }
877
1010
  function parseRenderPreset(value) {
878
1011
  const normalized = value.toLowerCase();
@@ -930,6 +1063,7 @@ function parseViewpointObjectTypes(value) {
930
1063
  function parseViewpointGroups(value, document, relationships, objectMap) {
931
1064
  return splitListValue(value).map((entry) => {
932
1065
  if (document.schemaVersion === "2.1" ||
1066
+ document.schemaVersion === "2.5" ||
933
1067
  document.groups.some((group) => group.id === entry)) {
934
1068
  return entry;
935
1069
  }
@@ -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>;