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