@splnlss/3d-story-viewer 0.5.4 → 0.5.6

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/build/viewer.js CHANGED
@@ -6471,7 +6471,7 @@ const QUAD_INDICES$1 = new Uint16Array([0, 1, 2, 0, 2, 3]);
6471
6471
  const workerUrl$1 = new URL("assets/viewer/spark-old-worker-932b4a2c87ca.js", import.meta.url).href;
6472
6472
  const workerWasmUrl$1 = new URL("assets/viewer/spark-worker-015de49d2d00.wasm", import.meta.url).href;
6473
6473
  function WorkerWrapper$1(options) {
6474
- const url = new URL(workerUrl$1);
6474
+ const url = new URL(workerUrl$1, globalThis.location.href);
6475
6475
  url.searchParams.set("wasm", workerWasmUrl$1);
6476
6476
  return new Worker(url, {
6477
6477
  name: options == null ? void 0 : options.name
@@ -8218,7 +8218,7 @@ async function withWorker(callback) {
8218
8218
  const workerUrl = new URL("assets/viewer/spark-worker-5ec8a483b87c.js", import.meta.url).href;
8219
8219
  const workerWasmUrl = new URL("assets/viewer/spark-worker-015de49d2d00.wasm", import.meta.url).href;
8220
8220
  function WorkerWrapper$2(options) {
8221
- const url = new URL(workerUrl);
8221
+ const url = new URL(workerUrl, globalThis.location.href);
8222
8222
  url.searchParams.set("wasm", workerWasmUrl);
8223
8223
  return new Worker(url, {
8224
8224
  name: options == null ? void 0 : options.name
@@ -12111,7 +12111,7 @@ const _SplatAccumulator = class _SplatAccumulator2 {
12111
12111
  this.time = 0;
12112
12112
  this.deltaTime = 0;
12113
12113
  this.viewToWorld = new Matrix4();
12114
- this.viewOrigin = new Vector3();
12114
+ this.renderOrigin = new Vector3();
12115
12115
  this.viewDirection = new Vector3();
12116
12116
  this.maxSplats = 0;
12117
12117
  this.numSplats = 0;
@@ -12394,10 +12394,10 @@ const _SplatAccumulator = class _SplatAccumulator2 {
12394
12394
  lodInstances
12395
12395
  }) {
12396
12396
  var _a22;
12397
- this.viewToWorld.copy(camera.matrixWorld);
12398
- camera.getWorldPosition(this.viewOrigin);
12397
+ camera.getWorldPosition(this.renderOrigin);
12398
+ this.viewToWorld.copy(camera.matrixWorld).setPosition(0, 0, 0);
12399
12399
  camera.getWorldDirection(this.viewDirection);
12400
- _SplatAccumulator2.viewCenterUniform.value.copy(this.viewOrigin);
12400
+ _SplatAccumulator2.viewCenterUniform.value.set(0, 0, 0);
12401
12401
  _SplatAccumulator2.viewDirUniform.value.copy(this.viewDirection);
12402
12402
  _SplatAccumulator2.sortRadialUniform.value = sortRadial;
12403
12403
  this.time = time;
@@ -12431,6 +12431,7 @@ const _SplatAccumulator = class _SplatAccumulator2 {
12431
12431
  time: this.time,
12432
12432
  deltaTime: this.deltaTime,
12433
12433
  viewToWorld: this.viewToWorld,
12434
+ renderOrigin: this.renderOrigin,
12434
12435
  camera,
12435
12436
  renderSize,
12436
12437
  globalEdits,
@@ -12695,6 +12696,14 @@ const _SparkRenderer = class _SparkRenderer2 extends Mesh {
12695
12696
  this.sortTimeoutId = -1;
12696
12697
  this.sortedCenter = new Vector3().setScalar(Number.NEGATIVE_INFINITY);
12697
12698
  this.sortedDir = new Vector3().setScalar(0);
12699
+ this.accumToCamera = new Matrix4();
12700
+ this.accumToCameraScale = new Vector3();
12701
+ this.renderCameraToWorld = new Matrix4();
12702
+ this.renderCameraOrigin = new Vector3();
12703
+ this.lodCameraToWorld = new Matrix4();
12704
+ this.lodCameraScale = new Vector3();
12705
+ this.lodViewToObject = new Matrix4();
12706
+ this.lodMeshOrigin = new Vector3();
12698
12707
  this.readback32 = new Uint32Array(0);
12699
12708
  this.lastLodRaycastTime = 0;
12700
12709
  this.lodWorker = null;
@@ -12936,17 +12945,14 @@ const _SparkRenderer = class _SparkRenderer2 extends Mesh {
12936
12945
  this.uniforms.far.value = typedCamera.far;
12937
12946
  const geometry = this.geometry;
12938
12947
  geometry.instanceCount = spark.activeSplats;
12939
- const accumToWorld = new Matrix4();
12940
- if (!this.display.extSplats) {
12941
- accumToWorld.makeTranslation(spark.display.viewOrigin);
12942
- }
12943
- const cameraToWorld = camera.matrixWorld.clone();
12944
- const worldToCamera = cameraToWorld.invert();
12945
- const accumToCamera = worldToCamera.multiply(accumToWorld);
12948
+ const renderCameraToWorld = this.renderCameraToWorld.copy(camera.matrixWorld).setPosition(
12949
+ this.renderCameraOrigin.setFromMatrixPosition(camera.matrixWorld).sub(spark.display.renderOrigin)
12950
+ );
12951
+ const accumToCamera = this.accumToCamera.copy(renderCameraToWorld).invert();
12946
12952
  accumToCamera.decompose(
12947
12953
  this.uniforms.renderToViewPos.value,
12948
12954
  this.uniforms.renderToViewQuat.value,
12949
- new Vector3()
12955
+ this.accumToCameraScale
12950
12956
  );
12951
12957
  this.uniforms.renderToViewBasis.value.setFromMatrix4(accumToCamera);
12952
12958
  this.uniforms.maxStdDev.value = spark.maxStdDev;
@@ -13123,7 +13129,7 @@ const _SparkRenderer = class _SparkRenderer2 extends Mesh {
13123
13129
  await new Promise((resolve) => setTimeout(resolve, this.readPause));
13124
13130
  }
13125
13131
  const current = this.current;
13126
- this.sortedCenter.copy(current.viewOrigin);
13132
+ this.sortedCenter.copy(current.renderOrigin);
13127
13133
  this.sortedDir.copy(current.viewDirection);
13128
13134
  const { numSplats, maxSplats } = current;
13129
13135
  const rows = Math.max(1, Math.ceil(maxSplats / 16384));
@@ -13244,8 +13250,9 @@ const _SparkRenderer = class _SparkRenderer2 extends Mesh {
13244
13250
  const viewPos = new Vector3();
13245
13251
  const viewQuat = new Quaternion();
13246
13252
  this.current.viewToWorld.decompose(viewPos, viewQuat, new Vector3());
13253
+ const lodPos = this.lodPosOverride ?? this.current.renderOrigin;
13247
13254
  if (this.lodPosOverride) {
13248
- viewPos.copy(this.lodPosOverride);
13255
+ viewPos.copy(this.lodPosOverride).sub(this.current.renderOrigin);
13249
13256
  }
13250
13257
  if (this.lodQuatOverride) {
13251
13258
  viewQuat.copy(this.lodQuatOverride).normalize();
@@ -13254,7 +13261,7 @@ const _SparkRenderer = class _SparkRenderer2 extends Mesh {
13254
13261
  if (this.lastLod.pixelScaleLimit !== pixelScaleLimit || this.lastLod.maxSplats !== maxSplats) {
13255
13262
  this.lodDirty = true;
13256
13263
  }
13257
- const distance2 = viewPos.distanceTo(this.lastLod.pos);
13264
+ const distance2 = lodPos.distanceTo(this.lastLod.pos);
13258
13265
  const distanceRamp = Math.max(0, 1 - distance2 / 1);
13259
13266
  const dot2 = viewQuat.dot(this.lastLod.quat);
13260
13267
  const quatRamp = Math.max(0, 1 - (1 - dot2) / 0.01);
@@ -13354,10 +13361,10 @@ const _SparkRenderer = class _SparkRenderer2 extends Mesh {
13354
13361
  const deltaPred = new Vector3();
13355
13362
  if (this.lastLod) {
13356
13363
  const deltaTime = Math.max(1, now22 - this.lastLod.timestamp);
13357
- deltaPred.copy(viewPos).sub(this.lastLod.pos).multiplyScalar(this.lastTraverseTime / deltaTime);
13364
+ deltaPred.copy(lodPos).sub(this.lastLod.pos).multiplyScalar(this.lastTraverseTime / deltaTime);
13358
13365
  }
13359
13366
  this.lastLod = {
13360
- pos: viewPos,
13367
+ pos: lodPos.clone(),
13361
13368
  quat: viewQuat,
13362
13369
  pixelScaleLimit,
13363
13370
  maxSplats,
@@ -13369,8 +13376,10 @@ const _SparkRenderer = class _SparkRenderer2 extends Mesh {
13369
13376
  deltaPred,
13370
13377
  lodMeshes,
13371
13378
  maxSplats,
13379
+ this.lastLod.pos,
13372
13380
  viewPos,
13373
13381
  viewQuat,
13382
+ this.current.renderOrigin,
13374
13383
  pixelScaleLimit
13375
13384
  );
13376
13385
  this.currentLod = this.lastLod;
@@ -13395,18 +13404,20 @@ const _SparkRenderer = class _SparkRenderer2 extends Mesh {
13395
13404
  this.lodIdToSplats.set(lodId, splats);
13396
13405
  }
13397
13406
  }
13398
- async updateLodInstances(worker, deltaPred, lodMeshes, maxSplats, viewPos, viewQuat, pixelScaleLimit) {
13407
+ async updateLodInstances(worker, deltaPred, lodMeshes, maxSplats, lodPos, viewPos, viewQuat, renderOrigin, pixelScaleLimit) {
13399
13408
  const uuidToMesh = /* @__PURE__ */ new Map();
13400
- const cameraToWorld = new Matrix4().compose(
13409
+ const cameraToWorld = this.lodCameraToWorld.compose(
13401
13410
  viewPos,
13402
13411
  viewQuat,
13403
- new Vector3().setScalar(1)
13412
+ this.lodCameraScale.setScalar(1)
13404
13413
  );
13405
13414
  const instances = lodMeshes.reduce(
13406
13415
  (instances2, mesh) => {
13407
13416
  var _a22, _b2;
13408
13417
  uuidToMesh.set(mesh.uuid, mesh);
13409
- const viewToObject = mesh.matrixWorld.clone().invert().multiply(cameraToWorld);
13418
+ const viewToObject = this.lodViewToObject.copy(mesh.matrixWorld).setPosition(
13419
+ this.lodMeshOrigin.setFromMatrixPosition(mesh.matrixWorld).sub(renderOrigin)
13420
+ ).invert().multiply(cameraToWorld);
13410
13421
  const splats = ((_a22 = mesh.packedSplats) == null ? void 0 : _a22.lodSplats) ?? ((_b2 = mesh.extSplats) == null ? void 0 : _b2.lodSplats) ?? mesh.paged;
13411
13422
  if (!splats) {
13412
13423
  return instances2;
@@ -13422,7 +13433,7 @@ const _SparkRenderer = class _SparkRenderer2 extends Mesh {
13422
13433
  instanceId: mesh.uuid,
13423
13434
  lodId: record.lodId,
13424
13435
  rootPage: record.rootPage,
13425
- viewToObjectCols: viewToObject.elements,
13436
+ viewToObjectCols: viewToObject.elements.slice(),
13426
13437
  lodScale: mesh.lodScale,
13427
13438
  behindFoveate: mesh.behindFoveate ?? this.behindFoveate,
13428
13439
  coneFov0: mesh.coneFov0 ?? this.coneFov0,
@@ -13457,7 +13468,7 @@ const _SparkRenderer = class _SparkRenderer2 extends Mesh {
13457
13468
  const meshPosition = mesh.getWorldPosition(new Vector3());
13458
13469
  return {
13459
13470
  splats: mesh.paged,
13460
- distance: meshPosition.distanceTo(viewPos)
13471
+ distance: meshPosition.distanceTo(lodPos)
13461
13472
  };
13462
13473
  }).filter((result2) => result2 !== null);
13463
13474
  if (!this.pageSizeWarning && pagedMeshes.length > this.pager.maxPages) {
@@ -15032,6 +15043,11 @@ const _SplatMesh = class _SplatMesh2 extends SplatGenerator {
15032
15043
  this.splatRgba = null;
15033
15044
  this.maxSh = 3;
15034
15045
  this.showLodPageDyno = new DynoInt({ value: 0 });
15046
+ this.objectToRender = new Matrix4();
15047
+ this.objectToRenderOffset = new Vector3();
15048
+ this.worldToObject = new Matrix4();
15049
+ this.worldToView = new Matrix4();
15050
+ this.viewToObjectMatrix = new Matrix4();
15035
15051
  if (options.splats) {
15036
15052
  this.splats = options.splats;
15037
15053
  this.numSplats = options.splats.getNumSplats();
@@ -15433,6 +15449,7 @@ const _SplatMesh = class _SplatMesh2 extends SplatGenerator {
15433
15449
  time,
15434
15450
  deltaTime,
15435
15451
  viewToWorld,
15452
+ renderOrigin,
15436
15453
  camera,
15437
15454
  renderSize,
15438
15455
  globalEdits,
@@ -15464,40 +15481,44 @@ const _SplatMesh = class _SplatMesh2 extends SplatGenerator {
15464
15481
  this.lastSplats = this.context.splats;
15465
15482
  this.generatorDirty = true;
15466
15483
  }
15484
+ this.updateMatrixWorld();
15485
+ const objectToWorld = this.objectToRender.copy(this.matrixWorld);
15486
+ objectToWorld.setPosition(
15487
+ this.objectToRenderOffset.setFromMatrixPosition(this.matrixWorld).sub(renderOrigin)
15488
+ );
15467
15489
  if (!this.covSplats) {
15468
- if (this.context.transform.update(this)) {
15490
+ if (this.context.transform.updateFromMatrix(objectToWorld)) {
15469
15491
  updated = true;
15470
15492
  }
15471
15493
  if (this.context.viewToWorld.updateFromMatrix(viewToWorld) && this.enableViewToWorld) {
15472
15494
  updated = true;
15473
15495
  }
15474
- const worldToView = viewToWorld.clone().invert();
15496
+ const worldToView = this.worldToView.copy(viewToWorld).invert();
15475
15497
  if (this.context.worldToView.updateFromMatrix(worldToView) && this.enableWorldToView) {
15476
15498
  updated = true;
15477
15499
  }
15478
- const objectToWorld = new Matrix4().compose(
15479
- this.context.transform.translate.value,
15480
- this.context.transform.rotate.value,
15481
- new Vector3().setScalar(this.context.transform.scale.value)
15500
+ const viewToObjectMatrix = this.viewToObjectMatrix.multiplyMatrices(
15501
+ this.worldToObject.copy(objectToWorld).invert(),
15502
+ viewToWorld
15482
15503
  );
15483
- const worldToObject = objectToWorld.invert();
15484
- const viewToObjectMatrix = worldToObject.multiply(viewToWorld);
15485
15504
  if (this.context.viewToObject.updateFromMatrix(viewToObjectMatrix) && (this.enableViewToObject || this.context.splats.hasRgbDir())) {
15486
15505
  updated = true;
15487
15506
  }
15488
15507
  } else {
15489
- if (this.context.covTransform.update(this)) {
15508
+ if (this.context.covTransform.updateFromMatrix(objectToWorld)) {
15490
15509
  updated = true;
15491
15510
  }
15492
15511
  if (this.context.covViewToWorld.updateFromMatrix(viewToWorld) && this.enableViewToWorld) {
15493
15512
  updated = true;
15494
15513
  }
15495
- const worldToView = viewToWorld.clone().invert();
15514
+ const worldToView = this.worldToView.copy(viewToWorld).invert();
15496
15515
  if (this.context.covWorldToView.updateFromMatrix(worldToView) && this.enableWorldToView) {
15497
15516
  updated = true;
15498
15517
  }
15499
- const worldToObject = this.matrixWorld.clone().invert();
15500
- const viewToObjectMatrix = worldToObject.multiply(viewToWorld);
15518
+ const viewToObjectMatrix = this.viewToObjectMatrix.multiplyMatrices(
15519
+ this.worldToObject.copy(objectToWorld).invert(),
15520
+ viewToWorld
15521
+ );
15501
15522
  if (this.context.covViewToObject.updateFromMatrix(viewToObjectMatrix) && (this.enableViewToObject || this.context.splats.hasRgbDir())) {
15502
15523
  updated = true;
15503
15524
  }
@@ -17694,6 +17715,7 @@ const _OldSparkRenderer = class _OldSparkRenderer2 extends Mesh {
17694
17715
  this.lastUpdateTime = null;
17695
17716
  this.defaultCameras = [];
17696
17717
  this.lastStochastic = null;
17718
+ this.renderOrigin = new Vector3();
17697
17719
  this.pendingUpdate = {
17698
17720
  scene: null,
17699
17721
  originToWorld: new Matrix4(),
@@ -18033,6 +18055,7 @@ const _OldSparkRenderer = class _OldSparkRenderer2 extends Mesh {
18033
18055
  originToWorld = this.active.toWorld;
18034
18056
  }
18035
18057
  viewToWorld = viewToWorld ?? originToWorld.clone();
18058
+ this.renderOrigin.setFromMatrixPosition(originToWorld);
18036
18059
  const time = this.time ?? this.clock.getElapsedTime();
18037
18060
  const deltaTime = time - (this.lastUpdateTime ?? time);
18038
18061
  this.lastUpdateTime = time;
@@ -18048,6 +18071,7 @@ const _OldSparkRenderer = class _OldSparkRenderer2 extends Mesh {
18048
18071
  time,
18049
18072
  deltaTime,
18050
18073
  viewToWorld,
18074
+ renderOrigin: this.renderOrigin,
18051
18075
  globalEdits
18052
18076
  });
18053
18077
  }
@@ -26496,7 +26520,7 @@ TWEEN.update.bind(TWEEN);
26496
26520
  var exports = {
26497
26521
  Easing
26498
26522
  };
26499
- const Tokens$1 = {
26523
+ const Tokens = {
26500
26524
  CESIUM: void 0,
26501
26525
  GOOGLEMAPS: void 0
26502
26526
  };
@@ -26706,20 +26730,28 @@ class TransitionControls extends EventDispatcher {
26706
26730
  this.lookAt = new Vector3();
26707
26731
  this.cameraTween = null;
26708
26732
  this.lookAtTween = null;
26733
+ this.activeTransition = null;
26709
26734
  this.is2D = false;
26710
26735
  }
26711
26736
  animateTo(position, quaternion, duration = TweenSettings.DURATION) {
26712
- return new Promise((resolve, reject) => {
26737
+ this.cancel();
26738
+ return new Promise((resolve) => {
26713
26739
  const fromPosition = this.camera.position.clone();
26714
26740
  const fromQuaternion = this.camera.quaternion.clone();
26715
26741
  const toPosition = position.clone();
26716
26742
  const toQuaternion = quaternion.clone();
26743
+ const transition = { resolve, toPosition, toQuaternion };
26744
+ this.activeTransition = transition;
26717
26745
  const deltaPosition = toPosition.clone().sub(fromPosition);
26718
26746
  const deltaDistance = deltaPosition.length();
26719
26747
  const deltaQuaternion = toQuaternion.clone().multiply(fromQuaternion.clone().invert());
26720
26748
  const deltaAngle = Math.acos(Math.min(1, deltaQuaternion.w));
26721
- if (deltaDistance < 1 && deltaAngle < 1) {
26722
- resolve();
26749
+ if (duration <= 0 || deltaDistance < 1 && deltaAngle < 1) {
26750
+ this.camera.position.copy(toPosition);
26751
+ this.camera.quaternion.copy(toQuaternion);
26752
+ this.camera.updateMatrixWorld(true);
26753
+ this.activeTransition = null;
26754
+ resolve(true);
26723
26755
  } else {
26724
26756
  const fromLookAt = new Vector3(0, 0, -deltaDistance * 0.25).applyQuaternion(fromQuaternion).add(fromPosition);
26725
26757
  const toLookAt = new Vector3(0, 0, -deltaDistance * 0.25).applyQuaternion(toQuaternion).add(toPosition);
@@ -26730,15 +26762,24 @@ class TransitionControls extends EventDispatcher {
26730
26762
  this.lookAtTween = new Tween(this.lookAt).to(toLookAt, duration).easing(Easing.Quartic.InOut).onComplete(() => {
26731
26763
  this.lookAt.copy(toLookAt);
26732
26764
  this.lookAtTween = null;
26765
+ this.complete(transition);
26733
26766
  }).start();
26734
26767
  this.cameraTween = new Tween(this.camera).to({ position: toPosition, up: toUp }, duration).easing(Easing.Quartic.InOut).onComplete(() => {
26735
26768
  this.camera.position.copy(toPosition);
26736
26769
  this.cameraTween = null;
26737
- resolve();
26770
+ this.complete(transition);
26738
26771
  }).start();
26739
26772
  }
26740
26773
  });
26741
26774
  }
26775
+ complete(transition) {
26776
+ if (this.activeTransition !== transition || this.cameraTween || this.lookAtTween) return;
26777
+ this.camera.position.copy(transition.toPosition);
26778
+ this.camera.quaternion.copy(transition.toQuaternion);
26779
+ this.camera.updateMatrixWorld(true);
26780
+ this.activeTransition = null;
26781
+ transition.resolve(true);
26782
+ }
26742
26783
  update(time) {
26743
26784
  if (this.cameraUpTween) this.cameraUpTween.update(time);
26744
26785
  if (this.cameraTween) this.cameraTween.update(time);
@@ -26748,6 +26789,8 @@ class TransitionControls extends EventDispatcher {
26748
26789
  }
26749
26790
  }
26750
26791
  cancel() {
26792
+ const transition = this.activeTransition;
26793
+ this.activeTransition = null;
26751
26794
  if (this.cameraTween) {
26752
26795
  this.cameraTween.stop();
26753
26796
  this.cameraTween = null;
@@ -26760,6 +26803,7 @@ class TransitionControls extends EventDispatcher {
26760
26803
  this.cameraUpTween.stop();
26761
26804
  this.cameraUpTween = null;
26762
26805
  }
26806
+ transition == null ? void 0 : transition.resolve(false);
26763
26807
  }
26764
26808
  }
26765
26809
  var sky_default$1 = "uniform vec3 sunPosition;uniform float rayleigh;uniform float turbidity;uniform float mieCoefficient;uniform vec3 up;varying vec3 vWorldPosition;varying vec3 vSunDirection;varying float vSunfade;varying vec3 vBetaR;varying vec3 vBetaM;varying float vSunE;const float e=2.71828182845904523536028747135266249775724709369995957;const float pi=3.141592653589793238462643383279502884197169;const vec3 lambda=vec3(680E-9,550E-9,450E-9);const vec3 totalRayleigh=vec3(5.804542996261093E-6,1.3562911419845635E-5,3.0265902468824876E-5);const float v=4.0;const vec3 K=vec3(0.686,0.678,0.666);const vec3 MieConst=vec3(1.8399918514433978E14,2.7798023919660528E14,4.0790479543861094E14);const float cutoffAngle=1.6110731556870734;const float steepness=1.5;const float EE=1000.0;float sunIntensity(float zenithAngleCos){zenithAngleCos=clamp(zenithAngleCos,-1.0,1.0);return EE*max(0.0,1.0-pow(e,-((cutoffAngle-acos(zenithAngleCos))/steepness)));}vec3 totalMie(float T){float c=(0.2*T)*10E-18;return 0.434*c*MieConst;}void main(){vec4 worldPosition=modelMatrix*vec4(position,1.0);vWorldPosition=worldPosition.xyz;gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.0);gl_Position.z=gl_Position.w;vSunDirection=normalize(sunPosition);vSunE=sunIntensity(dot(vSunDirection,up));vSunfade=1.0-clamp(1.0-exp((sunPosition.y/450000.0)),0.0,1.0);float rayleighCoefficient=rayleigh-(1.0*(1.0-vSunfade));vBetaR=totalRayleigh*rayleighCoefficient;vBetaM=totalMie(turbidity)*mieCoefficient;}";
@@ -27152,7 +27196,7 @@ class GeojsonLayer extends ContentLayer {
27152
27196
  this.clear();
27153
27197
  }
27154
27198
  }
27155
- const GAUSSIAN_FORMATS = /* @__PURE__ */ new Set(["ply", "sog"]);
27199
+ const GAUSSIAN_FORMATS = /* @__PURE__ */ new Set(["ply", "sog", "spz"]);
27156
27200
  function geodeticToEcefPosition(longitude, latitude, altitude) {
27157
27201
  const semiMajorAxis = 6378137;
27158
27202
  const eccentricity = 0.081819190842622;
@@ -27189,7 +27233,7 @@ function validateGaussianSplatLayerDefinition(definition) {
27189
27233
  }
27190
27234
  requireNonEmptyString((_a3 = definition.data) == null ? void 0 : _a3.url, "data.url");
27191
27235
  if (!GAUSSIAN_FORMATS.has((_b2 = definition.data) == null ? void 0 : _b2.format)) {
27192
- throw new Error('data.format must be "ply" or "sog".');
27236
+ throw new Error('data.format must be "ply", "sog", or "spz".');
27193
27237
  }
27194
27238
  const renderOrder = ((_c = definition.options) == null ? void 0 : _c.renderOrder) ?? 0;
27195
27239
  if (renderOrder !== 0) {
@@ -27261,7 +27305,8 @@ function makeGaussianSplatTransform(transform) {
27261
27305
  }
27262
27306
  const FORMAT_TYPES = {
27263
27307
  ply: SplatFileType.PLY,
27264
- sog: SplatFileType.PCSOGSZIP
27308
+ sog: SplatFileType.PCSOGSZIP,
27309
+ spz: SplatFileType.SPZ
27265
27310
  };
27266
27311
  function normalizeError(error) {
27267
27312
  return error instanceof Error ? error : new Error(String(error));
@@ -27396,24 +27441,32 @@ const ViewerEvents = (
27396
27441
  }
27397
27442
  );
27398
27443
  class Viewer extends EventDispatcher {
27444
+ /**
27445
+ * @param {HTMLElement | null} container
27446
+ * @param {import('../main.js').ViewerOptions} [options]
27447
+ */
27399
27448
  constructor(container, options = {}) {
27400
27449
  super();
27401
27450
  this.isViewer = true;
27402
27451
  this.type = "viewer";
27403
27452
  this.disposed = false;
27404
27453
  this.sparkRenderer = null;
27405
- Tokens$1.CESIUM = options.cesiumToken || void 0;
27406
- Tokens$1.GOOGLEMAPS = options.googleMapsToken || void 0;
27454
+ this.transparentBackground = options.transparentBackground ?? true;
27455
+ Tokens.CESIUM = options.cesiumToken || void 0;
27456
+ Tokens.GOOGLEMAPS = options.googleMapsToken || void 0;
27407
27457
  this.state = new StateDispatcher({
27408
27458
  time: { type: "f", value: 0 },
27409
27459
  loaded: false,
27410
- added: false
27460
+ added: false,
27461
+ ready: false
27411
27462
  });
27412
27463
  this.renderer = new WebGLRenderer({
27413
27464
  antialias: true,
27414
- powerPreference: "high-performance"
27465
+ powerPreference: "high-performance",
27466
+ alpha: this.transparentBackground,
27467
+ premultipliedAlpha: true
27415
27468
  });
27416
- this.renderer.setClearColor(16777215, 1);
27469
+ this.renderer.setClearColor(this.transparentBackground ? 0 : 16777215, this.transparentBackground ? 0 : 1);
27417
27470
  this.renderer.toneMapping = AgXToneMapping;
27418
27471
  this.renderer.outputColorSpace = SRGBColorSpace;
27419
27472
  this.renderer.toneMappingExposure = 1;
@@ -27446,8 +27499,11 @@ class Viewer extends EventDispatcher {
27446
27499
  };
27447
27500
  this.globeControls.addEventListener("start", this._onGlobeControlsStart);
27448
27501
  this.transitionControls = new TransitionControls(this.camera);
27449
- this.globeManager = new GlobeManager(this.scene, this.camera, this.renderer, { apiToken: Tokens$1.CESIUM, googleMapsToken: Tokens$1.GOOGLEMAPS });
27450
- this.globeControls.setTilesRenderer(this.globeManager.tiles);
27502
+ this.globeManager = new GlobeManager(this.scene, this.camera, this.renderer, { apiToken: Tokens.CESIUM, googleMapsToken: Tokens.GOOGLEMAPS });
27503
+ if (this.globeManager.tiles) {
27504
+ this.globeManager.tiles.group.visible = !this.transparentBackground;
27505
+ this.globeControls.setTilesRenderer(this.globeManager.tiles);
27506
+ }
27451
27507
  this.cameraCoords = {};
27452
27508
  this.pointerCoords = {};
27453
27509
  this.pointerXYZ = new Vector3();
@@ -27489,6 +27545,7 @@ class Viewer extends EventDispatcher {
27489
27545
  if (container) this.appendTo(container);
27490
27546
  this.sky = new Sky();
27491
27547
  this.sky.scale.setScalar(2e7);
27548
+ this.sky.visible = !this.transparentBackground;
27492
27549
  this.scene.add(this.sky);
27493
27550
  const phi = MathUtils.degToRad(80);
27494
27551
  const theta = MathUtils.degToRad(180);
@@ -27496,6 +27553,10 @@ class Viewer extends EventDispatcher {
27496
27553
  this.sky.material.uniforms.sunPosition.value = sunPosition;
27497
27554
  this.pointerRaycaster = new Raycaster();
27498
27555
  this._onPointerMove = (event) => {
27556
+ if (!this.globeManager.tiles) {
27557
+ this.pointerCoords = {};
27558
+ return;
27559
+ }
27499
27560
  const pointer = {};
27500
27561
  pointer.x = event.clientX / window.innerWidth * 2 - 1;
27501
27562
  pointer.y = -(event.clientY / window.innerHeight) * 2 + 1;
@@ -27544,13 +27605,14 @@ class Viewer extends EventDispatcher {
27544
27605
  return coords;
27545
27606
  }
27546
27607
  setBackgroundColor(color) {
27547
- this.renderer.setClearColor(color, 0);
27608
+ this.renderer.setClearColor(color, this.transparentBackground ? 0 : 1);
27548
27609
  }
27549
27610
  appendTo(container) {
27550
27611
  this.container = container;
27551
27612
  this.container.appendChild(this.renderer.domElement);
27552
27613
  this.container.appendChild(this.css2DRenderer.domElement);
27553
27614
  this.resizeView();
27615
+ this.state.update({ added: true });
27554
27616
  this.dispatchEvent({ type: ViewerEvents.APPENDED });
27555
27617
  }
27556
27618
  updateCameraDirections() {
@@ -27822,11 +27884,13 @@ class Viewer extends EventDispatcher {
27822
27884
  let pivot = null;
27823
27885
  const raycaster = new Raycaster();
27824
27886
  raycaster.setFromCamera({ x: 0, y: 0 }, this.camera);
27825
- const intersects = raycaster.intersectObject(this.globeManager.tiles.group, true);
27826
- if (intersects.length > 0) {
27827
- const intersect = intersects[0];
27828
- if (intersect) {
27829
- pivot = intersect.point.clone();
27887
+ if (this.globeManager.tiles) {
27888
+ const intersects = raycaster.intersectObject(this.globeManager.tiles.group, true);
27889
+ if (intersects.length > 0) {
27890
+ const intersect = intersects[0];
27891
+ if (intersect) {
27892
+ pivot = intersect.point.clone();
27893
+ }
27830
27894
  }
27831
27895
  }
27832
27896
  if (!pivot) {
@@ -27837,8 +27901,8 @@ class Viewer extends EventDispatcher {
27837
27901
  async alignCamera(lon, lat, alt, pitch = this.cameraCoords.pitch, yaw = this.cameraCoords.yaw, roll = this.cameraCoords.roll, duration = TweenSettings.DURATION) {
27838
27902
  const targetPosition = new Vector3().fromArray(geodeticToEcefPosition$1(lon, lat, alt));
27839
27903
  const targetQuaternion = geodeticToEcefRotation(lon, lat, pitch, yaw, roll);
27840
- return this.transitionControls.animateTo(targetPosition, targetQuaternion, duration).then(() => {
27841
- this.dispatchEvent({ type: ViewerEvents.TRANSITIONED, lon, lat, alt, pitch, yaw, roll });
27904
+ return this.transitionControls.animateTo(targetPosition, targetQuaternion, duration).then((completed) => {
27905
+ if (completed) this.dispatchEvent({ type: ViewerEvents.TRANSITIONED, lon, lat, alt, pitch, yaw, roll });
27842
27906
  });
27843
27907
  }
27844
27908
  async focusCamera(lon, lat, alt, distance = 2e3, pitch = this.cameraCoords.pitch, duration = TweenSettings.DURATION) {
@@ -27846,8 +27910,8 @@ class Viewer extends EventDispatcher {
27846
27910
  const targetQuaternion = geodeticToEcefRotation(lon, lat, pitch, 0, 0);
27847
27911
  const direction = new Vector3(0, 0, 1).applyQuaternion(targetQuaternion);
27848
27912
  targetPosition.addScaledVector(direction, distance);
27849
- return this.transitionControls.animateTo(targetPosition, targetQuaternion, duration).then(() => {
27850
- this.dispatchEvent({ type: ViewerEvents.TRANSITIONED, lon, lat, alt });
27913
+ return this.transitionControls.animateTo(targetPosition, targetQuaternion, duration).then((completed) => {
27914
+ if (completed) this.dispatchEvent({ type: ViewerEvents.TRANSITIONED, lon, lat, alt });
27851
27915
  });
27852
27916
  }
27853
27917
  async angleCamera(pitch = this.cameraCoords.pitch, yaw = this.cameraCoords.yaw, duration = TweenSettings.DURATION) {
@@ -27858,17 +27922,17 @@ class Viewer extends EventDispatcher {
27858
27922
  const targetQuaternion = geodeticToEcefRotation(lon, lat, pitch, yaw, 0);
27859
27923
  const direction = new Vector3(0, 0, 1).applyQuaternion(targetQuaternion);
27860
27924
  targetPosition.addScaledVector(direction, distance);
27861
- return this.transitionControls.animateTo(targetPosition, targetQuaternion, duration).then(() => {
27862
- this.dispatchEvent({ type: ViewerEvents.TRANSITIONED, lon, lat, alt });
27925
+ return this.transitionControls.animateTo(targetPosition, targetQuaternion, duration).then((completed) => {
27926
+ if (completed) this.dispatchEvent({ type: ViewerEvents.TRANSITIONED, lon, lat, alt });
27863
27927
  });
27864
27928
  }
27865
27929
  setViewMode(mode = "3d") {
27866
27930
  if (mode == "3d") {
27867
27931
  this.globeControls.rotationSpeed = 1;
27868
- this.angleCamera(-60, void 0, 500);
27932
+ return this.angleCamera(-60, void 0, 500);
27869
27933
  } else {
27870
27934
  this.globeControls.rotationSpeed = 0;
27871
- this.angleCamera(-90, 0, 500);
27935
+ return this.angleCamera(-90, 0, 500);
27872
27936
  }
27873
27937
  }
27874
27938
  exportScene() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splnlss/3d-story-viewer",
3
- "version": "0.5.4",
3
+ "version": "0.5.6",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "registry": "https://registry.npmjs.org/"
@@ -25,10 +25,15 @@
25
25
  }
26
26
  },
27
27
  "scripts": {
28
+ "patch:spark": "patch-package --error-on-fail && node scripts/check-spark-backport.mjs",
29
+ "predev": "yarn patch:spark",
28
30
  "dev": "vite",
31
+ "prebuild": "yarn patch:spark",
29
32
  "build": "vite build && tsc -p tsconfig.types.json",
30
33
  "preview": "vite preview",
34
+ "pretest": "yarn patch:spark",
31
35
  "test": "vitest run",
36
+ "pretest:browser": "yarn patch:spark",
32
37
  "test:browser": "playwright test",
33
38
  "test:all": "npm run test && npm run test:browser",
34
39
  "pack:check": "node scripts/check-package-assets.mjs",
@@ -40,6 +45,8 @@
40
45
  "@loaders.gl/gltf": "^4.3.4",
41
46
  "@loaders.gl/polyfills": "^4.3.4",
42
47
  "@playwright/test": "1.62.1",
48
+ "patch-package": "8.0.1",
49
+ "pngjs": "7.0.0",
43
50
  "typescript": "5.9.3",
44
51
  "vitest": "3.2.7"
45
52
  },
@@ -49,6 +56,7 @@
49
56
  "@sveltejs/vite-plugin-svelte": "^5.0.3",
50
57
  "@tweenjs/tween.js": "^25.0.0",
51
58
  "@vitejs/plugin-basic-ssl": "^1.2.0",
59
+ "dotenv": "^17.2.2",
52
60
  "earcut": "^3.0.1",
53
61
  "sass": "^1.83.4",
54
62
  "stats.js": "^0.17.0",
@@ -57,7 +65,6 @@
57
65
  "terser": "^5.37.0",
58
66
  "three": "0.185.1",
59
67
  "vite": "^6.0.5",
60
- "vite-plugin-glsl": "^1.3.1",
61
- "dotenv": "^17.2.2"
68
+ "vite-plugin-glsl": "^1.3.1"
62
69
  }
63
70
  }