@d5techs/3dgs-lib 1.4.1 → 1.4.3

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/dist/3dgs-lib.cjs CHANGED
@@ -4265,6 +4265,52 @@ class OBJLoader {
4265
4265
  }
4266
4266
  }
4267
4267
  }
4268
+ function transformSHCoeffsYZSwap$1(sh, base, perChannel) {
4269
+ const SQRT3_2 = Math.sqrt(3) / 2;
4270
+ if (perChannel >= 3) {
4271
+ for (let ch = 0; ch < 3; ch++) {
4272
+ const a = sh[base + ch];
4273
+ const b = sh[base + 3 + ch];
4274
+ sh[base + ch] = -b;
4275
+ sh[base + 3 + ch] = -a;
4276
+ }
4277
+ }
4278
+ if (perChannel >= 8) {
4279
+ for (let ch = 0; ch < 3; ch++) {
4280
+ const g0 = sh[base + 9 + ch];
4281
+ const g1 = sh[base + 12 + ch];
4282
+ const g2 = sh[base + 15 + ch];
4283
+ const g3 = sh[base + 18 + ch];
4284
+ const g4 = sh[base + 21 + ch];
4285
+ sh[base + 9 + ch] = -g3;
4286
+ sh[base + 12 + ch] = g1;
4287
+ sh[base + 15 + ch] = -0.5 * g2 - SQRT3_2 * g4;
4288
+ sh[base + 18 + ch] = -g0;
4289
+ sh[base + 21 + ch] = -SQRT3_2 * g2 + 0.5 * g4;
4290
+ }
4291
+ }
4292
+ if (perChannel >= 15) {
4293
+ const A = Math.sqrt(10) / 4;
4294
+ const B = Math.sqrt(6) / 4;
4295
+ const P = Math.sqrt(15) / 4;
4296
+ for (let ch = 0; ch < 3; ch++) {
4297
+ const g0 = sh[base + 24 + ch];
4298
+ const g1 = sh[base + 27 + ch];
4299
+ const g2 = sh[base + 30 + ch];
4300
+ const g3 = sh[base + 33 + ch];
4301
+ const g4 = sh[base + 36 + ch];
4302
+ const g5 = sh[base + 39 + ch];
4303
+ const g6 = sh[base + 42 + ch];
4304
+ sh[base + 24 + ch] = A * g3 - B * g5;
4305
+ sh[base + 27 + ch] = g1;
4306
+ sh[base + 30 + ch] = B * g3 + A * g5;
4307
+ sh[base + 33 + ch] = A * g0 + B * g2;
4308
+ sh[base + 36 + ch] = -0.25 * g4 - P * g6;
4309
+ sh[base + 39 + ch] = -B * g0 + A * g2;
4310
+ sh[base + 42 + ch] = -P * g4 + 0.25 * g6;
4311
+ }
4312
+ }
4313
+ }
4268
4314
  const TYPE_SIZES$1 = {
4269
4315
  char: 1,
4270
4316
  uchar: 1,
@@ -4491,6 +4537,9 @@ async function loadPLY(url, options = {}) {
4491
4537
  shRest[dstBase + 1] = srcG < shRestProps.length ? readProperty$1(dataView, base, shRestProps[srcG], littleEndian) : 0;
4492
4538
  shRest[dstBase + 2] = srcB < shRestProps.length ? readProperty$1(dataView, base, shRestProps[srcB], littleEndian) : 0;
4493
4539
  }
4540
+ if (swapYZ) {
4541
+ transformSHCoeffsYZSwap$1(shRestBuffer, shOffset, perChannel);
4542
+ }
4494
4543
  splats[i] = {
4495
4544
  mean: swapYZ ? [x, z, y] : [x, y, z],
4496
4545
  scale: swapYZ ? [scale_0, scale_2, scale_1] : [scale_0, scale_1, scale_2],
@@ -4530,6 +4579,52 @@ const TYPE_SIZES = {
4530
4579
  double: 8,
4531
4580
  float64: 8
4532
4581
  };
4582
+ function transformSHCoeffsYZSwap(sh, base, perChannel) {
4583
+ const SQRT3_2 = Math.sqrt(3) / 2;
4584
+ if (perChannel >= 3) {
4585
+ for (let ch = 0; ch < 3; ch++) {
4586
+ const a = sh[base + ch];
4587
+ const b = sh[base + 3 + ch];
4588
+ sh[base + ch] = -b;
4589
+ sh[base + 3 + ch] = -a;
4590
+ }
4591
+ }
4592
+ if (perChannel >= 8) {
4593
+ for (let ch = 0; ch < 3; ch++) {
4594
+ const g0 = sh[base + 9 + ch];
4595
+ const g1 = sh[base + 12 + ch];
4596
+ const g2 = sh[base + 15 + ch];
4597
+ const g3 = sh[base + 18 + ch];
4598
+ const g4 = sh[base + 21 + ch];
4599
+ sh[base + 9 + ch] = -g3;
4600
+ sh[base + 12 + ch] = g1;
4601
+ sh[base + 15 + ch] = -0.5 * g2 - SQRT3_2 * g4;
4602
+ sh[base + 18 + ch] = -g0;
4603
+ sh[base + 21 + ch] = -SQRT3_2 * g2 + 0.5 * g4;
4604
+ }
4605
+ }
4606
+ if (perChannel >= 15) {
4607
+ const A = Math.sqrt(10) / 4;
4608
+ const B = Math.sqrt(6) / 4;
4609
+ const P = Math.sqrt(15) / 4;
4610
+ for (let ch = 0; ch < 3; ch++) {
4611
+ const g0 = sh[base + 24 + ch];
4612
+ const g1 = sh[base + 27 + ch];
4613
+ const g2 = sh[base + 30 + ch];
4614
+ const g3 = sh[base + 33 + ch];
4615
+ const g4 = sh[base + 36 + ch];
4616
+ const g5 = sh[base + 39 + ch];
4617
+ const g6 = sh[base + 42 + ch];
4618
+ sh[base + 24 + ch] = A * g3 - B * g5;
4619
+ sh[base + 27 + ch] = g1;
4620
+ sh[base + 30 + ch] = B * g3 + A * g5;
4621
+ sh[base + 33 + ch] = A * g0 + B * g2;
4622
+ sh[base + 36 + ch] = -0.25 * g4 - P * g6;
4623
+ sh[base + 39 + ch] = -B * g0 + A * g2;
4624
+ sh[base + 42 + ch] = -P * g4 + 0.25 * g6;
4625
+ }
4626
+ }
4627
+ }
4533
4628
  function validatePLYMagic(buffer) {
4534
4629
  const bytes = new Uint8Array(buffer, 0, Math.min(buffer.byteLength, 10));
4535
4630
  const decoder = new TextDecoder("ascii");
@@ -4870,6 +4965,9 @@ async function parsePLYBuffer(buffer, options = {}) {
4870
4965
  shCoeffs[shBase + dstBase + 2] = readProperty(dataView, base + prop.byteOffset, prop.type, littleEndian);
4871
4966
  }
4872
4967
  }
4968
+ if (swapYZ) {
4969
+ transformSHCoeffsYZSwap(shCoeffs, shBase, perChannel);
4970
+ }
4873
4971
  }
4874
4972
  outputIdx++;
4875
4973
  if (onProgress) {
@@ -4954,7 +5052,8 @@ const PLYLoaderMobile = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.def
4954
5052
  __proto__: null,
4955
5053
  compactDataToGPUBuffer,
4956
5054
  loadPLYMobile,
4957
- parsePLYBuffer
5055
+ parsePLYBuffer,
5056
+ transformSHCoeffsYZSwap
4958
5057
  }, Symbol.toStringTag, { value: "Module" }));
4959
5058
  const SPLAT_SIZE = 32;
4960
5059
  const MIN_FILE_SIZE = SPLAT_SIZE;
@@ -14266,6 +14365,7 @@ class HotspotManager {
14266
14365
  if (info.billboard === enabled) return true;
14267
14366
  info.billboard = enabled;
14268
14367
  if (!enabled) {
14368
+ info._lastBillboardMeshPos = void 0;
14269
14369
  this.restoreHotspotOrientation(info);
14270
14370
  }
14271
14371
  return true;
@@ -14403,6 +14503,19 @@ class HotspotManager {
14403
14503
  const camPos = this.camera.position;
14404
14504
  for (const info of this.hotspots) {
14405
14505
  if (!info.billboard) continue;
14506
+ if (info._lastBillboardMeshPos) {
14507
+ const firstMesh = this.meshRenderer.getOverlayMeshByIndex(info.meshStartIndex);
14508
+ if (firstMesh) {
14509
+ const dx = firstMesh.position[0] - info._lastBillboardMeshPos[0];
14510
+ const dy = firstMesh.position[1] - info._lastBillboardMeshPos[1];
14511
+ const dz = firstMesh.position[2] - info._lastBillboardMeshPos[2];
14512
+ if (Math.abs(dx) > 1e-6 || Math.abs(dy) > 1e-6 || Math.abs(dz) > 1e-6) {
14513
+ info.position[0] += dx;
14514
+ info.position[1] += dy;
14515
+ info.position[2] += dz;
14516
+ }
14517
+ }
14518
+ }
14406
14519
  const {
14407
14520
  position,
14408
14521
  normal,
@@ -14454,6 +14567,10 @@ class HotspotManager {
14454
14567
  const owx = (rx * lcx + fx * lcy + zx * lcz) * s;
14455
14568
  const owy = (ry * lcx + fy * lcy + zy * lcz) * s;
14456
14569
  const owz = (rz * lcx + fz * lcy + zz * lcz) * s;
14570
+ const finalMeshX = wx - owx;
14571
+ const finalMeshY = wy - owy;
14572
+ const finalMeshZ = wz - owz;
14573
+ info._lastBillboardMeshPos = [finalMeshX, finalMeshY, finalMeshZ];
14457
14574
  for (let i = 0; i < info.meshCount; i++) {
14458
14575
  const mesh = this.meshRenderer.getOverlayMeshByIndex(
14459
14576
  info.meshStartIndex + i
@@ -16285,7 +16402,7 @@ class App {
16285
16402
  }
16286
16403
  });
16287
16404
  if (coordinateSystem === "blender") {
16288
- const { positions, scales, rotations, count } = compactData;
16405
+ const { positions, scales, rotations, count, shCoeffs } = compactData;
16289
16406
  for (let i = 0; i < count; i++) {
16290
16407
  const i3 = i * 3, i4 = i * 4;
16291
16408
  const py = positions[i3 + 1], pz = positions[i3 + 2];
@@ -16298,6 +16415,9 @@ class App {
16298
16415
  rotations[i4] = -rw;
16299
16416
  rotations[i4 + 2] = rz;
16300
16417
  rotations[i4 + 3] = ry;
16418
+ if (shCoeffs) {
16419
+ transformSHCoeffsYZSwap(shCoeffs, i * 45, 15);
16420
+ }
16301
16421
  }
16302
16422
  }
16303
16423
  if (onProgress) onProgress(90, "upload");