worldorbit 3.2.0 → 3.2.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.
@@ -31873,11 +31873,12 @@ void main() {
31873
31873
  const schemaProjection = resolveProjection(document2, options.projection);
31874
31874
  const camera = normalizeViewCamera(options.camera ?? null);
31875
31875
  const renderProjection = resolveRenderProjection(schemaProjection, camera);
31876
- const scaleModel = resolveScaleModel(layoutPreset, options.scaleModel);
31877
31876
  const spacingFactor = layoutPresetSpacing(layoutPreset);
31877
+ const scaleModel = resolveScaleModel(layoutPreset, options.scaleModel, options.bodyScaleMode);
31878
31878
  const systemId = document2.system?.id ?? null;
31879
31879
  const activeEventId = options.activeEventId ?? null;
31880
31880
  const effectiveObjects = createEffectiveObjects(document2.objects, document2.events ?? [], activeEventId);
31881
+ const sceneMetricScale = resolveSceneMetricScale(effectiveObjects, width, height, padding, spacingFactor, scaleModel);
31881
31882
  const objectMap = new Map(effectiveObjects.map((object) => [object.id, object]));
31882
31883
  const relationships = buildSceneRelationships(effectiveObjects, objectMap);
31883
31884
  const positions = /* @__PURE__ */ new Map();
@@ -31916,7 +31917,8 @@ void main() {
31916
31917
  objectMap,
31917
31918
  spacingFactor,
31918
31919
  projection: renderProjection,
31919
- scaleModel
31920
+ scaleModel,
31921
+ sceneMetricScale
31920
31922
  };
31921
31923
  const primaryRoot = rootObjects.find((object) => object.type === "star") ?? rootObjects[0] ?? null;
31922
31924
  if (primaryRoot) {
@@ -31932,14 +31934,14 @@ void main() {
31932
31934
  });
31933
31935
  }
31934
31936
  freeObjects.forEach((object, index) => {
31935
- const x = width - padding - 140 - freePlacementOffsetPx(object.placement?.mode === "free" ? object.placement.distance : void 0, scaleModel);
31937
+ const x = width - padding - 140 - freePlacementOffsetPx(object.placement?.mode === "free" ? object.placement.distance : void 0, scaleModel, sceneMetricScale);
31936
31938
  const rowStep = Math.max(76, (height - padding * 2 - 180) / Math.max(1, freeObjects.length) * spacingFactor) * scaleModel.freePlacementMultiplier;
31937
31939
  const y = padding + 92 + index * rowStep;
31938
31940
  positions.set(object.id, {
31939
31941
  object,
31940
31942
  x,
31941
31943
  y,
31942
- radius: visualRadiusFor(object, 0, scaleModel),
31944
+ radius: visualRadiusFor(object, 0, scaleModel, sceneMetricScale),
31943
31945
  sortKey: computeSortKey(x, y, 0)
31944
31946
  });
31945
31947
  leaderDrafts.push({
@@ -31962,7 +31964,7 @@ void main() {
31962
31964
  object,
31963
31965
  x: resolved.x,
31964
31966
  y: resolved.y,
31965
- radius: visualRadiusFor(object, 2, scaleModel),
31967
+ radius: visualRadiusFor(object, 2, scaleModel, sceneMetricScale),
31966
31968
  sortKey: computeSortKey(resolved.x, resolved.y, 2),
31967
31969
  anchorX: resolved.anchorX,
31968
31970
  anchorY: resolved.anchorY
@@ -32013,6 +32015,7 @@ void main() {
32013
32015
  scale: String(document2.system?.properties.scale ?? layoutPreset),
32014
32016
  units: String(document2.system?.properties.units ?? "mixed"),
32015
32017
  preset: frame.preset ?? "custom",
32018
+ "body.scaleMode": scaleModel.bodyScaleMode,
32016
32019
  ...camera?.azimuth !== null ? { "camera.azimuth": String(camera?.azimuth) } : {},
32017
32020
  ...camera?.elevation !== null ? { "camera.elevation": String(camera?.elevation) } : {},
32018
32021
  ...camera?.roll !== null ? { "camera.roll": String(camera?.roll) } : {},
@@ -32183,10 +32186,11 @@ void main() {
32183
32186
  }
32184
32187
  return parts.join(" - ");
32185
32188
  }
32186
- function resolveScaleModel(layoutPreset, overrides) {
32189
+ function resolveScaleModel(layoutPreset, overrides, bodyScaleMode) {
32187
32190
  const defaults = defaultScaleModel(layoutPreset);
32188
32191
  return {
32189
32192
  ...defaults,
32193
+ ...bodyScaleMode ? { bodyScaleMode } : {},
32190
32194
  ...overrides
32191
32195
  };
32192
32196
  }
@@ -32200,7 +32204,8 @@ void main() {
32200
32204
  freePlacementMultiplier: 0.9,
32201
32205
  ringThicknessMultiplier: 0.92,
32202
32206
  minBodyRadius: 4,
32203
- maxBodyRadius: 36
32207
+ maxBodyRadius: 36,
32208
+ bodyScaleMode: "readable"
32204
32209
  };
32205
32210
  case "presentation":
32206
32211
  return {
@@ -32210,7 +32215,8 @@ void main() {
32210
32215
  freePlacementMultiplier: 1.05,
32211
32216
  ringThicknessMultiplier: 1.16,
32212
32217
  minBodyRadius: 5,
32213
- maxBodyRadius: 48
32218
+ maxBodyRadius: 48,
32219
+ bodyScaleMode: "readable"
32214
32220
  };
32215
32221
  default:
32216
32222
  return {
@@ -32220,7 +32226,8 @@ void main() {
32220
32226
  freePlacementMultiplier: 1,
32221
32227
  ringThicknessMultiplier: 1,
32222
32228
  minBodyRadius: 4,
32223
- maxBodyRadius: 40
32229
+ maxBodyRadius: 40,
32230
+ bodyScaleMode: "readable"
32224
32231
  };
32225
32232
  }
32226
32233
  }
@@ -32234,6 +32241,48 @@ void main() {
32234
32241
  return 1;
32235
32242
  }
32236
32243
  }
32244
+ function resolveSceneMetricScale(objects, width, height, padding, spacingFactor, scaleModel) {
32245
+ const orbitMetrics = [];
32246
+ const bodyMetrics = [];
32247
+ for (const object of objects) {
32248
+ const radiusMetric = objectRadiusMetric(object);
32249
+ if (radiusMetric !== null && radiusMetric > 0) {
32250
+ bodyMetrics.push(radiusMetric);
32251
+ }
32252
+ const placement = object.placement;
32253
+ if (!placement) {
32254
+ continue;
32255
+ }
32256
+ if (placement.mode === "orbit") {
32257
+ const orbitMetricValue = toDistanceMetric(placement.semiMajor ?? placement.distance ?? null);
32258
+ if (orbitMetricValue !== null && orbitMetricValue > 0) {
32259
+ orbitMetrics.push(orbitMetricValue);
32260
+ }
32261
+ continue;
32262
+ }
32263
+ if (placement.mode === "free") {
32264
+ const freeMetric = toDistanceMetric(placement.distance ?? null);
32265
+ if (freeMetric !== null && freeMetric > 0) {
32266
+ orbitMetrics.push(freeMetric);
32267
+ }
32268
+ }
32269
+ }
32270
+ const maxDistanceMetric = Math.max(...orbitMetrics, 0);
32271
+ const maxBodyMetric = Math.max(...bodyMetrics, 0);
32272
+ const baseMetric = Math.max(maxDistanceMetric, maxBodyMetric * 6, 0);
32273
+ const referenceMetric = baseMetric + Math.max(Math.sqrt(baseMetric), maxBodyMetric * 2, maxDistanceMetric > 0 ? 0.25 : 0);
32274
+ if (referenceMetric <= 0) {
32275
+ return {
32276
+ pixelsPerMetric: null,
32277
+ hasExplicitScale: false
32278
+ };
32279
+ }
32280
+ const availableRadius = Math.max(Math.min(width, height) / 2 - padding - 24, 120) * spacingFactor * scaleModel.orbitDistanceMultiplier;
32281
+ return {
32282
+ pixelsPerMetric: availableRadius / referenceMetric,
32283
+ hasExplicitScale: true
32284
+ };
32285
+ }
32237
32286
  function createSceneObject(position, scaleModel, relationships) {
32238
32287
  const { object, x, y, radius, sortKey, anchorX, anchorY } = position;
32239
32288
  const renderPriority = object.renderHints?.renderPriority ?? 0;
@@ -32958,7 +33007,7 @@ void main() {
32958
33007
  object,
32959
33008
  x,
32960
33009
  y,
32961
- radius: visualRadiusFor(object, depth, context.scaleModel),
33010
+ radius: visualRadiusFor(object, depth, context.scaleModel, context.sceneMetricScale),
32962
33011
  sortKey: computeSortKey(x, y, depth)
32963
33012
  });
32964
33013
  placeOrbitingChildren(object, positions, orbitDrafts, leaderDrafts, context, depth + 1);
@@ -32969,7 +33018,7 @@ void main() {
32969
33018
  return;
32970
33019
  }
32971
33020
  const orbiting = [...context.orbitChildren.get(object.id) ?? []].sort(compareOrbiting);
32972
- const orbitMetricContext = computeOrbitMetricContext(orbiting, parent.radius, context.spacingFactor, context.scaleModel);
33021
+ const orbitMetricContext = computeOrbitMetricContext(orbiting, parent.radius, context.spacingFactor, context.scaleModel, context.sceneMetricScale);
32973
33022
  const orbitRadiiPx = resolveOrbitRadiiPx(orbiting, orbitMetricContext);
32974
33023
  orbiting.forEach((child, index) => {
32975
33024
  const orbitGeometry = resolveOrbitGeometry(child, index, orbiting.length, parent, orbitMetricContext, orbitRadiiPx[index] ?? orbitMetricContext.innerPx, context);
@@ -33004,7 +33053,7 @@ void main() {
33004
33053
  object: child,
33005
33054
  x,
33006
33055
  y,
33007
- radius: visualRadiusFor(child, depth + 1, context.scaleModel),
33056
+ radius: visualRadiusFor(child, depth + 1, context.scaleModel, context.sceneMetricScale),
33008
33057
  sortKey: computeSortKey(x, y, depth + 1),
33009
33058
  anchorX,
33010
33059
  anchorY
@@ -33033,10 +33082,11 @@ void main() {
33033
33082
  return 1;
33034
33083
  return left.id.localeCompare(right.id);
33035
33084
  }
33036
- function computeOrbitMetricContext(objects, parentRadius, spacingFactor, scaleModel) {
33085
+ function computeOrbitMetricContext(objects, parentRadius, spacingFactor, scaleModel, sceneMetricScale) {
33037
33086
  const metrics = objects.map((object) => orbitMetric(object));
33038
33087
  const presentMetrics = metrics.filter((value) => value !== null);
33039
- const innerPx = parentRadius + 56 * spacingFactor * scaleModel.orbitDistanceMultiplier;
33088
+ const minimumGapPx = scaleModel.bodyScaleMode === "strict" ? Math.max(2, 8 * spacingFactor * scaleModel.orbitDistanceMultiplier) : (objects.length > 2 ? 54 : 64) * spacingFactor * scaleModel.orbitDistanceMultiplier * 0.42;
33089
+ const innerPx = parentRadius + Math.max(minimumGapPx * 1.2, 24 * spacingFactor);
33040
33090
  const stepPx = (objects.length > 2 ? 54 : 64) * spacingFactor * scaleModel.orbitDistanceMultiplier;
33041
33091
  if (presentMetrics.length === 0) {
33042
33092
  return {
@@ -33047,7 +33097,8 @@ void main() {
33047
33097
  innerPx,
33048
33098
  stepPx,
33049
33099
  pixelSpread: Math.max(stepPx * Math.max(objects.length - 1, 1), stepPx),
33050
- minimumGapPx: stepPx * 0.42
33100
+ minimumGapPx,
33101
+ pixelsPerMetric: sceneMetricScale.pixelsPerMetric
33051
33102
  };
33052
33103
  }
33053
33104
  const minMetric = Math.min(...presentMetrics);
@@ -33061,7 +33112,8 @@ void main() {
33061
33112
  innerPx,
33062
33113
  stepPx,
33063
33114
  pixelSpread: Math.max(stepPx * Math.max(objects.length - 1, 1), stepPx),
33064
- minimumGapPx: stepPx * 0.42
33115
+ minimumGapPx,
33116
+ pixelsPerMetric: sceneMetricScale.pixelsPerMetric
33065
33117
  };
33066
33118
  }
33067
33119
  function resolveOrbitGeometry(object, index, count, parent, metricContext, orbitRadiusPx, context) {
@@ -33113,6 +33165,9 @@ void main() {
33113
33165
  };
33114
33166
  }
33115
33167
  function resolveOrbitRadiusPx(metric, metricContext) {
33168
+ if (metricContext.pixelsPerMetric !== null) {
33169
+ return metric * metricContext.pixelsPerMetric;
33170
+ }
33116
33171
  return metricContext.innerPx + metricContext.stepPx * log2(Math.max(metric, 0) + 1);
33117
33172
  }
33118
33173
  function resolveOrbitRadiiPx(objects, metricContext) {
@@ -33147,6 +33202,10 @@ void main() {
33147
33202
  const outerMetric = toDistanceMetric(toUnitValue(object.properties.outer));
33148
33203
  if (innerMetric !== null && outerMetric !== null) {
33149
33204
  const thicknessMetric = Math.abs(outerMetric - innerMetric);
33205
+ if (metricContext.pixelsPerMetric !== null) {
33206
+ const thicknessPx = thicknessMetric * metricContext.pixelsPerMetric;
33207
+ return scaleModel.bodyScaleMode === "strict" ? Math.max(thicknessPx * scaleModel.ringThicknessMultiplier, 1) : clampNumber(Math.max(thicknessPx * scaleModel.ringThicknessMultiplier, 8), 8, 54);
33208
+ }
33150
33209
  if (metricContext.metricSpread > 0) {
33151
33210
  return clampNumber(thicknessMetric / metricContext.metricSpread * metricContext.pixelSpread * scaleModel.ringThicknessMultiplier, 8, 54);
33152
33211
  }
@@ -33426,8 +33485,8 @@ void main() {
33426
33485
  }
33427
33486
  return positions.get(object.placement.target);
33428
33487
  }
33429
- function visualRadiusFor(object, depth, scaleModel) {
33430
- const explicitRadius = toVisualSizeMetric(object.properties.radius, scaleModel);
33488
+ function visualRadiusFor(object, depth, scaleModel, sceneMetricScale) {
33489
+ const explicitRadius = toVisualSizeMetric(object.properties.radius, scaleModel, sceneMetricScale);
33431
33490
  if (explicitRadius !== null) {
33432
33491
  return explicitRadius;
33433
33492
  }
@@ -33492,18 +33551,27 @@ void main() {
33492
33551
  return value.value;
33493
33552
  }
33494
33553
  }
33495
- function freePlacementOffsetPx(distance, scaleModel) {
33554
+ function freePlacementOffsetPx(distance, scaleModel, sceneMetricScale) {
33496
33555
  const metric = toDistanceMetric(distance ?? null);
33497
33556
  if (metric === null || metric <= 0) {
33498
33557
  return 0;
33499
33558
  }
33559
+ if (sceneMetricScale.pixelsPerMetric !== null) {
33560
+ const scaled = metric * sceneMetricScale.pixelsPerMetric * scaleModel.freePlacementMultiplier;
33561
+ return scaleModel.bodyScaleMode === "strict" ? Math.max(scaled, 0) : clampNumber(scaled, 0, 420);
33562
+ }
33500
33563
  return clampNumber(metric * 96 * scaleModel.freePlacementMultiplier, 0, 420);
33501
33564
  }
33502
- function toVisualSizeMetric(value, scaleModel) {
33565
+ function toVisualSizeMetric(value, scaleModel, sceneMetricScale) {
33503
33566
  const unitValue = toUnitValue(value);
33504
33567
  if (!unitValue) {
33505
33568
  return null;
33506
33569
  }
33570
+ const physicalMetric = toDistanceMetric(unitValue);
33571
+ if (sceneMetricScale.pixelsPerMetric !== null && physicalMetric !== null && physicalMetric > 0) {
33572
+ const scaled = physicalMetric * sceneMetricScale.pixelsPerMetric * scaleModel.bodyRadiusMultiplier;
33573
+ return scaleModel.bodyScaleMode === "strict" ? Math.max(scaled, 0.1) : clampNumber(Math.max(scaled, scaleModel.minBodyRadius), scaleModel.minBodyRadius, scaleModel.maxBodyRadius);
33574
+ }
33507
33575
  let size;
33508
33576
  switch (unitValue.unit) {
33509
33577
  case "sol":
@@ -33521,6 +33589,9 @@ void main() {
33521
33589
  }
33522
33590
  return clampNumber(size * scaleModel.bodyRadiusMultiplier, scaleModel.minBodyRadius, scaleModel.maxBodyRadius);
33523
33591
  }
33592
+ function objectRadiusMetric(object) {
33593
+ return toDistanceMetric(toUnitValue(object.properties.radius));
33594
+ }
33524
33595
  function toUnitValue(value) {
33525
33596
  if (!value || typeof value !== "object" || !("value" in value)) {
33526
33597
  return null;
@@ -33629,6 +33700,7 @@ void main() {
33629
33700
  projection: options.projection,
33630
33701
  camera: options.camera,
33631
33702
  scaleModel: options.scaleModel,
33703
+ bodyScaleMode: options.bodyScaleMode,
33632
33704
  activeEventId: options.activeEventId
33633
33705
  };
33634
33706
  const scene = renderDocumentToScene(document2, renderOptions);
@@ -38040,6 +38112,7 @@ void main() {
38040
38112
  camera: renderOptions.camera ? { ...renderOptions.camera } : null,
38041
38113
  layers: renderOptions.layers ? { ...renderOptions.layers } : void 0,
38042
38114
  scaleModel: renderOptions.scaleModel ? { ...renderOptions.scaleModel } : void 0,
38115
+ bodyScaleMode: renderOptions.bodyScaleMode,
38043
38116
  activeEventId: renderOptions.activeEventId ?? null,
38044
38117
  viewMode: renderOptions.viewMode ?? "2d"
38045
38118
  },
@@ -38068,6 +38141,7 @@ void main() {
38068
38141
  camera: raw.renderOptions?.camera ? { ...raw.renderOptions.camera } : null,
38069
38142
  layers: raw.renderOptions?.layers ? { ...raw.renderOptions.layers } : void 0,
38070
38143
  scaleModel: raw.renderOptions?.scaleModel ? { ...raw.renderOptions.scaleModel } : void 0,
38144
+ bodyScaleMode: raw.renderOptions?.bodyScaleMode,
38071
38145
  activeEventId: raw.activeEventId ?? raw.renderOptions?.activeEventId ?? null,
38072
38146
  viewMode: raw.renderOptions?.viewMode ?? "2d"
38073
38147
  },
@@ -38087,6 +38161,7 @@ void main() {
38087
38161
  camera: atlasState.renderOptions.camera ? { ...atlasState.renderOptions.camera } : null,
38088
38162
  layers: atlasState.renderOptions.layers ? { ...atlasState.renderOptions.layers } : void 0,
38089
38163
  scaleModel: atlasState.renderOptions.scaleModel ? { ...atlasState.renderOptions.scaleModel } : void 0,
38164
+ bodyScaleMode: atlasState.renderOptions.bodyScaleMode,
38090
38165
  activeEventId: atlasState.renderOptions.activeEventId ?? null,
38091
38166
  viewMode: atlasState.renderOptions.viewMode ?? "2d"
38092
38167
  },
@@ -39922,6 +39997,7 @@ void main() {
39922
39997
  padding: options.padding,
39923
39998
  preset: options.preset,
39924
39999
  projection: options.projection,
40000
+ bodyScaleMode: options.bodyScaleMode,
39925
40001
  viewMode: options.viewMode ?? "2d",
39926
40002
  quality: options.quality ?? "balanced",
39927
40003
  style3d: options.style3d ?? "symbolic",
@@ -41346,7 +41422,7 @@ void main() {
41346
41422
  };
41347
41423
  }
41348
41424
  function hasSceneAffectingRenderOptions(options) {
41349
- return options.width !== void 0 || options.height !== void 0 || options.padding !== void 0 || options.preset !== void 0 || options.projection !== void 0 || options.camera !== void 0 || options.scaleModel !== void 0 || options.activeEventId !== void 0;
41425
+ return options.width !== void 0 || options.height !== void 0 || options.padding !== void 0 || options.preset !== void 0 || options.projection !== void 0 || options.camera !== void 0 || options.scaleModel !== void 0 || options.bodyScaleMode !== void 0 || options.activeEventId !== void 0;
41350
41426
  }
41351
41427
  function resolveSourceRenderOptions2(loaded, renderOptions) {
41352
41428
  const atlasDocument = loaded.atlasDocument ?? loaded.draftDocument;