@d5techs/3dgs-lib 1.4.20 → 1.4.22
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 +98 -72
- package/dist/3dgs-lib.cjs.map +1 -1
- package/dist/3dgs-lib.js +98 -72
- package/dist/3dgs-lib.js.map +1 -1
- package/dist/editor/SplatEditor.d.ts +1 -1
- package/dist/gs/SOGEncoder.d.ts +4 -4
- package/package.json +1 -1
package/dist/3dgs-lib.js
CHANGED
|
@@ -6195,83 +6195,109 @@ function inverseSHTransformYZSwap(sh, base, perChannel) {
|
|
|
6195
6195
|
}
|
|
6196
6196
|
}
|
|
6197
6197
|
}
|
|
6198
|
-
function
|
|
6199
|
-
const
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
|
|
6221
|
-
|
|
6222
|
-
|
|
6223
|
-
|
|
6224
|
-
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6198
|
+
function buildCodebook(values, k = 256) {
|
|
6199
|
+
const N = values.length;
|
|
6200
|
+
if (N === 0) return new Array(k).fill(0);
|
|
6201
|
+
const sorted = new Float32Array(values);
|
|
6202
|
+
sorted.sort();
|
|
6203
|
+
const vMin = sorted[0];
|
|
6204
|
+
const vMax = sorted[N - 1];
|
|
6205
|
+
if (vMax - vMin < 1e-20) return new Array(k).fill(vMin);
|
|
6206
|
+
const H = Math.min(1024, N);
|
|
6207
|
+
const vRange = vMax - vMin;
|
|
6208
|
+
const iqr = sorted[Math.floor(N * 0.75)] - sorted[Math.floor(N * 0.25)];
|
|
6209
|
+
const beta = Math.max(0.5, Math.min(0.999, 1 - iqr / vRange));
|
|
6210
|
+
const counts = new Float64Array(H);
|
|
6211
|
+
const sums = new Float64Array(H);
|
|
6212
|
+
for (let i = 0; i < N; i++) {
|
|
6213
|
+
const uniformPos = (sorted[i] - vMin) / vRange;
|
|
6214
|
+
const quantilePos = i / N;
|
|
6215
|
+
const bin = Math.min(H - 1, Math.floor(H * (beta * quantilePos + (1 - beta) * uniformPos)));
|
|
6216
|
+
counts[bin]++;
|
|
6217
|
+
sums[bin] += sorted[i];
|
|
6218
|
+
}
|
|
6219
|
+
const centers = new Float64Array(H);
|
|
6220
|
+
for (let i = 0; i < H; i++) {
|
|
6221
|
+
centers[i] = counts[i] > 0 ? sums[i] / counts[i] : vMin + (i + 0.5) / H * vRange;
|
|
6222
|
+
}
|
|
6223
|
+
const alpha = 0.5;
|
|
6224
|
+
const weights = new Float64Array(H);
|
|
6225
|
+
for (let i = 0; i < H; i++) {
|
|
6226
|
+
weights[i] = counts[i] > 0 ? Math.pow(counts[i], alpha) : 0;
|
|
6227
|
+
}
|
|
6228
|
+
const prefW = new Float64Array(H + 1);
|
|
6229
|
+
const prefWX = new Float64Array(H + 1);
|
|
6230
|
+
const prefWXX = new Float64Array(H + 1);
|
|
6231
|
+
for (let i = 0; i < H; i++) {
|
|
6232
|
+
prefW[i + 1] = prefW[i] + weights[i];
|
|
6233
|
+
prefWX[i + 1] = prefWX[i] + weights[i] * centers[i];
|
|
6234
|
+
prefWXX[i + 1] = prefWXX[i] + weights[i] * centers[i] * centers[i];
|
|
6235
|
+
}
|
|
6236
|
+
const rangeCost = (a, b) => {
|
|
6237
|
+
const w = prefW[b + 1] - prefW[a];
|
|
6238
|
+
if (w <= 0) return 0;
|
|
6239
|
+
const wx = prefWX[b + 1] - prefWX[a];
|
|
6240
|
+
const wxx = prefWXX[b + 1] - prefWXX[a];
|
|
6241
|
+
return wxx - wx * wx / w;
|
|
6242
|
+
};
|
|
6243
|
+
const rangeMean = (a, b) => {
|
|
6244
|
+
const w = prefW[b + 1] - prefW[a];
|
|
6245
|
+
if (w <= 0) return (centers[a] + centers[b]) * 0.5;
|
|
6246
|
+
return (prefWX[b + 1] - prefWX[a]) / w;
|
|
6247
|
+
};
|
|
6248
|
+
let nonEmpty = 0;
|
|
6249
|
+
for (let i = 0; i < H; i++) if (counts[i] > 0) nonEmpty++;
|
|
6250
|
+
const effectiveK = Math.min(k, nonEmpty);
|
|
6251
|
+
const INF = 1e30;
|
|
6252
|
+
let dpPrev = new Float64Array(H).fill(INF);
|
|
6253
|
+
let dpCurr = new Float64Array(H).fill(INF);
|
|
6254
|
+
const splitTable = new Array(effectiveK + 1);
|
|
6255
|
+
const split1 = new Int32Array(H);
|
|
6256
|
+
for (let j = 0; j < H; j++) {
|
|
6257
|
+
dpPrev[j] = rangeCost(0, j);
|
|
6258
|
+
split1[j] = -1;
|
|
6259
|
+
}
|
|
6260
|
+
splitTable[1] = split1;
|
|
6261
|
+
for (let m = 2; m <= effectiveK; m++) {
|
|
6262
|
+
dpCurr.fill(INF);
|
|
6263
|
+
const splitM = new Int32Array(H);
|
|
6264
|
+
for (let j = m - 1; j < H; j++) {
|
|
6265
|
+
let bestCost = INF;
|
|
6266
|
+
let bestS = m - 2;
|
|
6267
|
+
for (let s = m - 2; s < j; s++) {
|
|
6268
|
+
const cost = dpPrev[s] + rangeCost(s + 1, j);
|
|
6269
|
+
if (cost < bestCost) {
|
|
6270
|
+
bestCost = cost;
|
|
6271
|
+
bestS = s;
|
|
6257
6272
|
}
|
|
6258
6273
|
}
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6274
|
+
dpCurr[j] = bestCost;
|
|
6275
|
+
splitM[j] = bestS;
|
|
6276
|
+
}
|
|
6277
|
+
splitTable[m] = splitM;
|
|
6278
|
+
const tmp = dpPrev;
|
|
6279
|
+
dpPrev = dpCurr;
|
|
6280
|
+
dpCurr = tmp;
|
|
6281
|
+
}
|
|
6282
|
+
const centroidValues = new Float32Array(effectiveK);
|
|
6283
|
+
let jj = H - 1;
|
|
6284
|
+
for (let m = effectiveK; m >= 1; m--) {
|
|
6285
|
+
const s = m > 1 ? splitTable[m][jj] : -1;
|
|
6286
|
+
centroidValues[m - 1] = rangeMean(s + 1, jj);
|
|
6287
|
+
jj = s;
|
|
6288
|
+
}
|
|
6289
|
+
centroidValues.sort();
|
|
6290
|
+
const result = new Array(k);
|
|
6291
|
+
for (let i = 0; i < effectiveK; i++) result[i] = centroidValues[i];
|
|
6292
|
+
for (let i = effectiveK; i < k; i++) result[i] = centroidValues[effectiveK - 1];
|
|
6264
6293
|
return result;
|
|
6265
6294
|
}
|
|
6266
6295
|
function findNearest(sortedCB, value) {
|
|
6267
6296
|
let lo = 0, hi = sortedCB.length - 1;
|
|
6268
6297
|
while (lo < hi) {
|
|
6269
6298
|
const mid = lo + hi >> 1;
|
|
6270
|
-
if (sortedCB[mid]
|
|
6271
|
-
else
|
|
6272
|
-
}
|
|
6273
|
-
if (lo > 0 && Math.abs(sortedCB[lo - 1] - value) <= Math.abs(sortedCB[lo] - value)) {
|
|
6274
|
-
return lo - 1;
|
|
6299
|
+
if (value < (sortedCB[mid] + sortedCB[mid + 1]) * 0.5) hi = mid;
|
|
6300
|
+
else lo = mid + 1;
|
|
6275
6301
|
}
|
|
6276
6302
|
return lo;
|
|
6277
6303
|
}
|
|
@@ -6528,7 +6554,7 @@ async function serializeSOG(data, coordinateSystem = "blender", options = {}) {
|
|
|
6528
6554
|
}
|
|
6529
6555
|
const logScales = new Float32Array(count * 3);
|
|
6530
6556
|
for (let i = 0; i < count * 3; i++) logScales[i] = Math.log(Math.max(1e-8, sSca[i]));
|
|
6531
|
-
const scaleCodebook = buildCodebook(logScales, 256
|
|
6557
|
+
const scaleCodebook = buildCodebook(logScales, 256);
|
|
6532
6558
|
const scalesData = new Uint8ClampedArray(totalPixels * 4);
|
|
6533
6559
|
scalesData.fill(255);
|
|
6534
6560
|
for (let i = 0; i < count; i++) {
|
|
@@ -6596,7 +6622,7 @@ async function serializeSOG(data, coordinateSystem = "blender", options = {}) {
|
|
|
6596
6622
|
dcValues[i * 3 + 1] = (sCol[i * 3 + 1] - 0.5) / SH_C0;
|
|
6597
6623
|
dcValues[i * 3 + 2] = (sCol[i * 3 + 2] - 0.5) / SH_C0;
|
|
6598
6624
|
}
|
|
6599
|
-
const dcCodebook = buildCodebook(dcValues, 256
|
|
6625
|
+
const dcCodebook = buildCodebook(dcValues, 256);
|
|
6600
6626
|
const sh0Data = new Uint8ClampedArray(totalPixels * 4);
|
|
6601
6627
|
sh0Data.fill(255);
|
|
6602
6628
|
for (let i = 0; i < count; i++) {
|
|
@@ -6631,7 +6657,7 @@ async function serializeSOG(data, coordinateSystem = "blender", options = {}) {
|
|
|
6631
6657
|
for (let c = 0; c < centroids.length; c++) {
|
|
6632
6658
|
for (let d = 0; d < shDim; d++) allCoeffValues[c * shDim + d] = centroids[c][d];
|
|
6633
6659
|
}
|
|
6634
|
-
const shCodebook = buildCodebook(allCoeffValues, 256
|
|
6660
|
+
const shCodebook = buildCodebook(allCoeffValues, 256);
|
|
6635
6661
|
const centW = 64 * numCoeffs;
|
|
6636
6662
|
const centH = Math.ceil(effectivePaletteSize / 64);
|
|
6637
6663
|
const centData = new Uint8ClampedArray(centW * centH * 4);
|