@threepipe/plugin-gaussian-splatting 0.2.1 → 0.2.4
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/CHANGELOG.md +20 -0
- package/README.md +12 -0
- package/dist/assets/{worker-BYCkgQO3.js.map → worker-CZa3bSRr.js.map} +1 -1
- package/dist/gaussian-splats-3d/GaussianSplatsPlugin.d.ts +1 -0
- package/dist/gaussian-splats-3d/GaussianSplatsPlugin.d.ts.map +1 -0
- package/dist/index.js +6 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +6 -6
- package/dist/index.mjs.map +1 -1
- package/dist/three-gaussian-splat/ThreeGaussianSplatPlugin.d.ts +11 -12
- package/dist/three-gaussian-splat/ThreeGaussianSplatPlugin.d.ts.map +1 -1
- package/dist/three-gaussian-splat/cpp-sorter/SortWorkerManager.d.ts +1 -1
- package/dist/three-gaussian-splat/cpp-sorter/SortWorkerManager.d.ts.map +1 -1
- package/dist/three-gaussian-splat/cpp-sorter/worker.d.ts +1 -2
- package/dist/three-gaussian-splat/cpp-sorter/worker.d.ts.map +1 -1
- package/dist/three-gaussian-splat/geometry/GaussianSplatGeometry.d.ts +6 -5
- package/dist/three-gaussian-splat/geometry/GaussianSplatGeometry.d.ts.map +1 -1
- package/dist/three-gaussian-splat/loaders/SplatLoader.d.ts.map +1 -1
- package/dist/three-gaussian-splat/materials/GaussianSplatMaterialExtension.d.ts +1 -1
- package/dist/three-gaussian-splat/materials/GaussianSplatMaterialExtension.d.ts.map +1 -1
- package/dist/three-gaussian-splat/materials/util.d.ts.map +1 -1
- package/docs/.nojekyll +1 -0
- package/docs/assets/hierarchy.js +1 -0
- package/docs/assets/highlight.css +43 -0
- package/docs/assets/icons.js +18 -0
- package/docs/assets/icons.svg +1 -0
- package/docs/assets/main.js +60 -0
- package/docs/assets/navigation.js +1 -0
- package/docs/assets/search.js +1 -0
- package/docs/assets/style.css +1633 -0
- package/docs/classes/GaussianSplattingPlugin.html +27 -0
- package/docs/classes/threeGaussianSplat.GaussianSplatGeometry.html +19 -0
- package/docs/classes/threeGaussianSplat.GaussianSplatMaterialExtension.html +17 -0
- package/docs/classes/threeGaussianSplat.GaussianSplatMaterialPhysical.html +86 -0
- package/docs/classes/threeGaussianSplat.GaussianSplatMaterialRaw.html +51 -0
- package/docs/classes/threeGaussianSplat.GaussianSplatMaterialUnlit.html +60 -0
- package/docs/classes/threeGaussianSplat.GaussianSplatMesh.html +72 -0
- package/docs/classes/threeGaussianSplat.SplatLoader.html +7 -0
- package/docs/classes/threeGaussianSplat.ThreeGaussianSplatPlugin.html +27 -0
- package/docs/functions/threeGaussianSplat.computeFocalLengths.html +1 -0
- package/docs/hierarchy.html +1 -0
- package/docs/index.html +1 -0
- package/docs/modules/threeGaussianSplat.html +1 -0
- package/docs/variables/threeGaussianSplat.gaussianSplatShaders.html +1 -0
- package/package.json +19 -5
- package/src/gaussian-splats-3d/GaussianSplatsPlugin.ts +1 -1
- package/src/three-gaussian-splat/ThreeGaussianSplatPlugin.ts +13 -4
- package/src/three-gaussian-splat/geometry/GaussianSplatGeometry.ts +1 -0
- package/src/three-gaussian-splat/materials/GaussianSplatMaterialExtension.ts +1 -1
- package/src/gaussian-splats-3d/Constants.js +0 -10
- package/src/gaussian-splats-3d/Util.js +0 -147
- package/src/gaussian-splats-3d/loaders/KSplatLoader.js +0 -238
- package/src/gaussian-splats-3d/loaders/LoaderStatus.js +0 -6
- package/src/gaussian-splats-3d/loaders/PlyLoader.js +0 -32
- package/src/gaussian-splats-3d/loaders/PlyParser.js +0 -188
- package/src/gaussian-splats-3d/loaders/SceneFormat.js +0 -5
- package/src/gaussian-splats-3d/loaders/SplatBuffer.js +0 -817
- package/src/gaussian-splats-3d/loaders/SplatBufferGenerator.js +0 -31
- package/src/gaussian-splats-3d/loaders/SplatLoader.js +0 -129
- package/src/gaussian-splats-3d/loaders/SplatParser.js +0 -88
- package/src/gaussian-splats-3d/loaders/SplatPartitioner.js +0 -99
- package/src/gaussian-splats-3d/loaders/UncompressedSplatArray.js +0 -49
- package/src/gaussian-splats-3d/loaders/Utils.js +0 -8
- package/src/gaussian-splats-3d/loaders-ts/SplatLoader.ts +0 -33
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'threepipe';
|
|
2
|
-
import {SplatPartitioner} from './SplatPartitioner.js';
|
|
3
|
-
import {SplatBuffer} from './SplatBuffer.js';
|
|
4
|
-
|
|
5
|
-
export class SplatBufferGenerator {
|
|
6
|
-
|
|
7
|
-
constructor (splatPartitioner, alphaRemovalThreshold, compressionLevel, sectionSize, sceneCenter, blockSize, bucketSize) {
|
|
8
|
-
this.splatPartitioner = splatPartitioner;
|
|
9
|
-
this.alphaRemovalThreshold = alphaRemovalThreshold;
|
|
10
|
-
this.compressionLevel = compressionLevel;
|
|
11
|
-
this.sectionSize = sectionSize;
|
|
12
|
-
this.sceneCenter = sceneCenter ? new THREE.Vector3().copy(sceneCenter) : undefined;
|
|
13
|
-
this.blockSize = blockSize;
|
|
14
|
-
this.bucketSize = bucketSize;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
generateFromUncompressedSplatArray (splatArray) {
|
|
18
|
-
const partitionResults = this.splatPartitioner.partitionUncompressedSplatArray(splatArray);
|
|
19
|
-
return SplatBuffer.generateFromUncompressedSplatArrays(partitionResults.splatArrays,
|
|
20
|
-
this.alphaRemovalThreshold, this.compressionLevel,
|
|
21
|
-
this.sceneCenter, this.blockSize, this.bucketSize,
|
|
22
|
-
partitionResults.parameters);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
static getStandardGenerator (alphaRemovalThreshold = 1, compressionLevel = 1, sectionSize = 0, sceneCenter = new THREE.Vector3(),
|
|
26
|
-
blockSize = SplatBuffer.BucketBlockSize, bucketSize = SplatBuffer.BucketSize) {
|
|
27
|
-
const splatPartitioner = SplatPartitioner.getStandardPartitioner(sectionSize, sceneCenter, blockSize, bucketSize);
|
|
28
|
-
return new SplatBufferGenerator(splatPartitioner, alphaRemovalThreshold, compressionLevel,
|
|
29
|
-
sectionSize, sceneCenter, blockSize, bucketSize);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'threepipe';
|
|
2
|
-
import {SplatBuffer} from './SplatBuffer.js';
|
|
3
|
-
import {SplatBufferGenerator} from './SplatBufferGenerator.js';
|
|
4
|
-
import {SplatParser} from './SplatParser.js';
|
|
5
|
-
import {delayedExecute, fetchWithProgress} from '../Util.js';
|
|
6
|
-
import {LoaderStatus} from './LoaderStatus.js';
|
|
7
|
-
import {Constants} from '../Constants.js';
|
|
8
|
-
|
|
9
|
-
export class SplatLoader {
|
|
10
|
-
|
|
11
|
-
constructor (splatBuffer = null) {
|
|
12
|
-
this.splatBuffer = splatBuffer;
|
|
13
|
-
this.downLoadLink = null;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
loadFromURL (fileName, onProgress, stream, onStreamedSectionProgress, compressionLevel,
|
|
17
|
-
minimumAlpha, optimizeSplatData, sectionSize, sceneCenter, blockSize, bucketSize) {
|
|
18
|
-
|
|
19
|
-
let streamBufferIn;
|
|
20
|
-
let streamBufferOut;
|
|
21
|
-
let streamSplatBuffer;
|
|
22
|
-
let lastSectionBytes = 0;
|
|
23
|
-
let streamSectionSizeBytes = Constants.StreamingSectionSize;
|
|
24
|
-
let sectionCount = 1;
|
|
25
|
-
let maxSplatCount = 0;
|
|
26
|
-
let splatCount = 0;
|
|
27
|
-
|
|
28
|
-
let streamLoadCompleteResolver;
|
|
29
|
-
let streamLoadPromise = new Promise((resolve) => {
|
|
30
|
-
streamLoadCompleteResolver = resolve;
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
let bytesLoaded = 0;
|
|
34
|
-
let chunks = [];
|
|
35
|
-
|
|
36
|
-
const localOnProgress = (percent, percentStr, chunk, fileSize) => {
|
|
37
|
-
const loadComplete = percent >= 100;
|
|
38
|
-
if (!fileSize) stream = false;
|
|
39
|
-
if (stream) {
|
|
40
|
-
const splatDataOffsetBytes = SplatBuffer.HeaderSizeBytes + SplatBuffer.SectionHeaderSizeBytes;
|
|
41
|
-
if (!streamBufferIn) {
|
|
42
|
-
maxSplatCount = fileSize / SplatParser.RowSizeBytes;
|
|
43
|
-
streamBufferIn = new ArrayBuffer(fileSize);
|
|
44
|
-
const splatBufferSizeBytes = splatDataOffsetBytes + SplatBuffer.CompressionLevels[0].BytesPerSplat * maxSplatCount;
|
|
45
|
-
streamBufferOut = new ArrayBuffer(splatBufferSizeBytes);
|
|
46
|
-
SplatBuffer.writeHeaderToBuffer({
|
|
47
|
-
versionMajor: 0,
|
|
48
|
-
versionMinor: 1,
|
|
49
|
-
maxSectionCount: sectionCount,
|
|
50
|
-
sectionCount: sectionCount,
|
|
51
|
-
maxSplatCount: maxSplatCount,
|
|
52
|
-
splatCount: splatCount,
|
|
53
|
-
compressionLevel: 0,
|
|
54
|
-
sceneCenter: new THREE.Vector3(),
|
|
55
|
-
}, streamBufferOut);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (chunk) {
|
|
59
|
-
chunks.push(chunk);
|
|
60
|
-
new Uint8Array(streamBufferIn, bytesLoaded, chunk.byteLength).set(new Uint8Array(chunk));
|
|
61
|
-
bytesLoaded += chunk.byteLength;
|
|
62
|
-
|
|
63
|
-
const bytesLoadedSinceLastSection = bytesLoaded - lastSectionBytes;
|
|
64
|
-
if (bytesLoadedSinceLastSection > streamSectionSizeBytes || loadComplete) {
|
|
65
|
-
const bytesToUpdate = loadComplete ? bytesLoadedSinceLastSection : streamSectionSizeBytes;
|
|
66
|
-
const addedSplatCount = bytesToUpdate / SplatParser.RowSizeBytes;
|
|
67
|
-
const newSplatCount = splatCount + addedSplatCount;
|
|
68
|
-
SplatParser.parseToUncompressedBufferSection(splatCount, newSplatCount, streamBufferIn, 0,
|
|
69
|
-
streamBufferOut, splatDataOffsetBytes);
|
|
70
|
-
splatCount = newSplatCount;
|
|
71
|
-
if (!streamSplatBuffer) {
|
|
72
|
-
SplatBuffer.writeSectionHeaderToBuffer({
|
|
73
|
-
maxSplatCount: maxSplatCount,
|
|
74
|
-
splatCount: splatCount,
|
|
75
|
-
bucketSize: 0,
|
|
76
|
-
bucketCount: 0,
|
|
77
|
-
bucketBlockSize: 0,
|
|
78
|
-
compressionScaleRange: 0,
|
|
79
|
-
storageSizeBytes: 0,
|
|
80
|
-
fullBucketCount: 0,
|
|
81
|
-
partiallyFilledBucketCount: 0,
|
|
82
|
-
}, 0, streamBufferOut, SplatBuffer.HeaderSizeBytes);
|
|
83
|
-
streamSplatBuffer = new SplatBuffer(streamBufferOut, false);
|
|
84
|
-
}
|
|
85
|
-
streamSplatBuffer.updateLoadedCounts(1, splatCount);
|
|
86
|
-
onStreamedSectionProgress(streamSplatBuffer, loadComplete);
|
|
87
|
-
lastSectionBytes += streamSectionSizeBytes;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
if (loadComplete) {
|
|
91
|
-
streamLoadCompleteResolver();
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
if (onProgress) onProgress(percent, percentStr, LoaderStatus.Downloading);
|
|
95
|
-
return stream;
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
return fetchWithProgress(fileName, localOnProgress, true).then((fullBuffer) => {
|
|
99
|
-
if (onProgress) onProgress(0, '0%', LoaderStatus.Processing);
|
|
100
|
-
if (stream) {
|
|
101
|
-
return streamLoadPromise.then(() => {
|
|
102
|
-
if (onProgress) onProgress(100, '100%', LoaderStatus.Done);
|
|
103
|
-
return streamSplatBuffer;
|
|
104
|
-
});
|
|
105
|
-
} else {
|
|
106
|
-
return delayedExecute(() => {
|
|
107
|
-
const splatArray = SplatParser.parseStandardSplatToUncompressedSplatArray(fullBuffer);
|
|
108
|
-
let splatBuffer;
|
|
109
|
-
if (optimizeSplatData) {
|
|
110
|
-
const splatBufferGenerator = SplatBufferGenerator.getStandardGenerator(minimumAlpha, compressionLevel,
|
|
111
|
-
sectionSize, sceneCenter, blockSize,
|
|
112
|
-
bucketSize);
|
|
113
|
-
splatBuffer = splatBufferGenerator.generateFromUncompressedSplatArray(splatArray);
|
|
114
|
-
} else {
|
|
115
|
-
splatBuffer = SplatBuffer.generateFromUncompressedSplatArrays([splatArray], minimumAlpha, 0,
|
|
116
|
-
new THREE.Vector3());
|
|
117
|
-
}
|
|
118
|
-
if (onProgress) onProgress(100, '100%', LoaderStatus.Done);
|
|
119
|
-
return splatBuffer;
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
setFromBuffer (splatBuffer) {
|
|
126
|
-
this.splatBuffer = splatBuffer;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'threepipe';
|
|
2
|
-
import {SplatBuffer} from './SplatBuffer.js';
|
|
3
|
-
import {UncompressedSplatArray} from './UncompressedSplatArray.js';
|
|
4
|
-
|
|
5
|
-
export class SplatParser {
|
|
6
|
-
|
|
7
|
-
static RowSizeBytes = 32;
|
|
8
|
-
static CenterSizeBytes = 12;
|
|
9
|
-
static ScaleSizeBytes = 12;
|
|
10
|
-
static RotationSizeBytes = 4;
|
|
11
|
-
static ColorSizeBytes = 4;
|
|
12
|
-
|
|
13
|
-
static parseToUncompressedBufferSection (fromSplat, toSplat, fromBuffer, fromOffset, toBuffer, toOffset) {
|
|
14
|
-
|
|
15
|
-
const outBytesPerCenter = SplatBuffer.CompressionLevels[0].BytesPerCenter;
|
|
16
|
-
const outBytesPerScale = SplatBuffer.CompressionLevels[0].BytesPerScale;
|
|
17
|
-
const outBytesPerRotation = SplatBuffer.CompressionLevels[0].BytesPerRotation;
|
|
18
|
-
const outBytesPerSplat = SplatBuffer.CompressionLevels[0].BytesPerSplat;
|
|
19
|
-
|
|
20
|
-
for (let i = fromSplat; i < toSplat; i++) {
|
|
21
|
-
const inBase = i * SplatParser.RowSizeBytes + fromOffset;
|
|
22
|
-
const inCenter = new Float32Array(fromBuffer, inBase, 3);
|
|
23
|
-
const inScale = new Float32Array(fromBuffer, inBase + SplatParser.CenterSizeBytes, 3);
|
|
24
|
-
const inColor = new Uint8Array(fromBuffer, inBase + SplatParser.CenterSizeBytes + SplatParser.ScaleSizeBytes, 4);
|
|
25
|
-
const inRotation = new Uint8Array(fromBuffer, inBase + SplatParser.CenterSizeBytes + SplatParser.ScaleSizeBytes +
|
|
26
|
-
SplatParser.RotationSizeBytes, 4);
|
|
27
|
-
|
|
28
|
-
const quat = new THREE.Quaternion((inRotation[1] - 128) / 128, (inRotation[2] - 128) / 128,
|
|
29
|
-
(inRotation[3] - 128) / 128, (inRotation[0] - 128) / 128);
|
|
30
|
-
quat.normalize();
|
|
31
|
-
|
|
32
|
-
const outBase = i * outBytesPerSplat + toOffset;
|
|
33
|
-
const outCenter = new Float32Array(toBuffer, outBase, 3);
|
|
34
|
-
const outScale = new Float32Array(toBuffer, outBase + outBytesPerCenter, 3);
|
|
35
|
-
const outRotation = new Float32Array(toBuffer, outBase + outBytesPerCenter + outBytesPerScale, 4);
|
|
36
|
-
const outColor = new Uint8Array(toBuffer, outBase + outBytesPerCenter + outBytesPerScale + outBytesPerRotation, 4);
|
|
37
|
-
|
|
38
|
-
outCenter[0] = inCenter[0];
|
|
39
|
-
outCenter[1] = inCenter[1];
|
|
40
|
-
outCenter[2] = inCenter[2];
|
|
41
|
-
|
|
42
|
-
outScale[0] = inScale[0];
|
|
43
|
-
outScale[1] = inScale[1];
|
|
44
|
-
outScale[2] = inScale[2];
|
|
45
|
-
|
|
46
|
-
outRotation[0] = quat.w;
|
|
47
|
-
outRotation[1] = quat.x;
|
|
48
|
-
outRotation[2] = quat.y;
|
|
49
|
-
outRotation[3] = quat.z;
|
|
50
|
-
|
|
51
|
-
outColor[0] = inColor[0];
|
|
52
|
-
outColor[1] = inColor[1];
|
|
53
|
-
outColor[2] = inColor[2];
|
|
54
|
-
outColor[3] = inColor[3];
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
static parseStandardSplatToUncompressedSplatArray (inBuffer) {
|
|
59
|
-
// Standard .splat row layout:
|
|
60
|
-
// XYZ - Position (Float32)
|
|
61
|
-
// XYZ - Scale (Float32)
|
|
62
|
-
// RGBA - colors (uint8)
|
|
63
|
-
// IJKL - quaternion/rot (uint8)
|
|
64
|
-
|
|
65
|
-
const splatCount = inBuffer.byteLength / SplatParser.RowSizeBytes;
|
|
66
|
-
|
|
67
|
-
const splatArray = new UncompressedSplatArray();
|
|
68
|
-
|
|
69
|
-
for (let i = 0; i < splatCount; i++) {
|
|
70
|
-
const inBase = i * SplatParser.RowSizeBytes;
|
|
71
|
-
const inCenter = new Float32Array(inBuffer, inBase, 3);
|
|
72
|
-
const inScale = new Float32Array(inBuffer, inBase + SplatParser.CenterSizeBytes, 3);
|
|
73
|
-
const inColor = new Uint8Array(inBuffer, inBase + SplatParser.CenterSizeBytes + SplatParser.ScaleSizeBytes, 4);
|
|
74
|
-
const inRotation = new Uint8Array(inBuffer, inBase + SplatParser.CenterSizeBytes +
|
|
75
|
-
SplatParser.ScaleSizeBytes + SplatParser.ColorSizeBytes, 4);
|
|
76
|
-
|
|
77
|
-
const quat = new THREE.Quaternion((inRotation[1] - 128) / 128, (inRotation[2] - 128) / 128,
|
|
78
|
-
(inRotation[3] - 128) / 128, (inRotation[0] - 128) / 128);
|
|
79
|
-
quat.normalize();
|
|
80
|
-
|
|
81
|
-
splatArray.addSplatFromComonents(inCenter[0], inCenter[1], inCenter[2], inScale[0], inScale[1], inScale[2],
|
|
82
|
-
quat.w, quat.x, quat.y, quat.z, inColor[0], inColor[1], inColor[2], inColor[3]);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return splatArray;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'threepipe';
|
|
2
|
-
import {UncompressedSplatArray} from './UncompressedSplatArray.js';
|
|
3
|
-
import {SplatBuffer} from './SplatBuffer.js';
|
|
4
|
-
|
|
5
|
-
export class SplatPartitioner {
|
|
6
|
-
|
|
7
|
-
constructor (sectionCount, sectionFilters, groupingParameters, partitionGenerator) {
|
|
8
|
-
this.sectionCount = sectionCount;
|
|
9
|
-
this.sectionFilters = sectionFilters;
|
|
10
|
-
this.groupingParameters = groupingParameters;
|
|
11
|
-
this.partitionGenerator = partitionGenerator;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
partitionUncompressedSplatArray (splatArray) {
|
|
15
|
-
let groupingParameters;
|
|
16
|
-
let sectionCount;
|
|
17
|
-
let sectionFilters;
|
|
18
|
-
if (this.partitionGenerator) {
|
|
19
|
-
const results = this.partitionGenerator(splatArray);
|
|
20
|
-
groupingParameters = results.groupingParameters;
|
|
21
|
-
sectionCount = results.sectionCount;
|
|
22
|
-
sectionFilters = results.sectionFilters;
|
|
23
|
-
} else {
|
|
24
|
-
groupingParameters = this.groupingParameters;
|
|
25
|
-
sectionCount = this.sectionCount;
|
|
26
|
-
sectionFilters = this.sectionFilters;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const newArrays = [];
|
|
30
|
-
for (let s = 0; s < sectionCount; s++) {
|
|
31
|
-
const sectionSplats = new UncompressedSplatArray();
|
|
32
|
-
const sectionFilter = sectionFilters[s];
|
|
33
|
-
for (let i = 0; i < splatArray.splatCount; i++) {
|
|
34
|
-
if (sectionFilter(i)) {
|
|
35
|
-
sectionSplats.addSplatFromArray(splatArray, i);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
newArrays.push(sectionSplats);
|
|
39
|
-
}
|
|
40
|
-
return {
|
|
41
|
-
splatArrays: newArrays,
|
|
42
|
-
parameters: groupingParameters,
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
static getStandardPartitioner (partitionSize = 0, sceneCenter = new THREE.Vector3(),
|
|
47
|
-
blockSize = SplatBuffer.BucketBlockSize, bucketSize = SplatBuffer.BucketSize) {
|
|
48
|
-
const partitionGenerator = (splatArray) => {
|
|
49
|
-
|
|
50
|
-
if (partitionSize <= 0) partitionSize = splatArray.splatCount;
|
|
51
|
-
|
|
52
|
-
const centerA = new THREE.Vector3();
|
|
53
|
-
const centerB = new THREE.Vector3();
|
|
54
|
-
const clampDistance = 0.5;
|
|
55
|
-
const clampPoint = (point) => {
|
|
56
|
-
point.x = Math.floor(point.x / clampDistance) * clampDistance;
|
|
57
|
-
point.y = Math.floor(point.y / clampDistance) * clampDistance;
|
|
58
|
-
point.z = Math.floor(point.z / clampDistance) * clampDistance;
|
|
59
|
-
};
|
|
60
|
-
splatArray.splats.sort((a, b) => {
|
|
61
|
-
centerA.set(a[UncompressedSplatArray.OFFSET.X],
|
|
62
|
-
a[UncompressedSplatArray.OFFSET.Y],
|
|
63
|
-
a[UncompressedSplatArray.OFFSET.Z]).sub(sceneCenter);
|
|
64
|
-
clampPoint(centerA);
|
|
65
|
-
const centerADist = centerA.lengthSq();
|
|
66
|
-
centerB.set(b[UncompressedSplatArray.OFFSET.X],
|
|
67
|
-
b[UncompressedSplatArray.OFFSET.Y],
|
|
68
|
-
b[UncompressedSplatArray.OFFSET.Z]).sub(sceneCenter);
|
|
69
|
-
clampPoint(centerB);
|
|
70
|
-
const centerBDist = centerB.lengthSq();
|
|
71
|
-
if (centerADist > centerBDist) return 1;
|
|
72
|
-
else return -1;
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const sectionFilters = [];
|
|
76
|
-
const groupingParameters = [];
|
|
77
|
-
partitionSize = Math.min(splatArray.splatCount, partitionSize);
|
|
78
|
-
const patitionCount = Math.ceil(splatArray.splatCount / partitionSize);
|
|
79
|
-
let currentStartSplat = 0;
|
|
80
|
-
for (let i = 0; i < patitionCount; i++) {
|
|
81
|
-
let startSplat = currentStartSplat;
|
|
82
|
-
sectionFilters.push((splatIndex) => {
|
|
83
|
-
return splatIndex >= startSplat && splatIndex < startSplat + partitionSize;
|
|
84
|
-
});
|
|
85
|
-
groupingParameters.push({
|
|
86
|
-
'blocksSize': blockSize,
|
|
87
|
-
'bucketSize': bucketSize,
|
|
88
|
-
});
|
|
89
|
-
currentStartSplat += partitionSize;
|
|
90
|
-
}
|
|
91
|
-
return {
|
|
92
|
-
'sectionCount': sectionFilters.length,
|
|
93
|
-
sectionFilters,
|
|
94
|
-
groupingParameters,
|
|
95
|
-
};
|
|
96
|
-
};
|
|
97
|
-
return new SplatPartitioner(undefined, undefined, undefined, partitionGenerator);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
export class UncompressedSplatArray {
|
|
3
|
-
|
|
4
|
-
static OFFSET = {
|
|
5
|
-
X: 0,
|
|
6
|
-
Y: 1,
|
|
7
|
-
Z: 2,
|
|
8
|
-
SCALE0: 3,
|
|
9
|
-
SCALE1: 4,
|
|
10
|
-
SCALE2: 5,
|
|
11
|
-
ROTATION0: 6,
|
|
12
|
-
ROTATION1: 7,
|
|
13
|
-
ROTATION2: 8,
|
|
14
|
-
ROTATION3: 9,
|
|
15
|
-
FDC0: 10,
|
|
16
|
-
FDC1: 11,
|
|
17
|
-
FDC2: 12,
|
|
18
|
-
OPACITY: 13,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
constructor () {
|
|
22
|
-
this.splats = [];
|
|
23
|
-
this.splatCount = 0;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
addSplat (splat) {
|
|
27
|
-
this.splats.push(splat);
|
|
28
|
-
this.splatCount++;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
addDefaultSplat () {
|
|
32
|
-
const newSplat = [0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0];
|
|
33
|
-
this.addSplat(newSplat);
|
|
34
|
-
return newSplat;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
addSplatFromComonents (x, y, z, scale0, scale1, scale2, rot0, rot1, rot2, rot3, r, g, b, opacity) {
|
|
38
|
-
const newSplat = [x, y, z, scale0, scale1, scale2, rot0, rot1, rot2, rot3, r, g, b, opacity];
|
|
39
|
-
this.addSplat(newSplat);
|
|
40
|
-
return newSplat;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
addSplatFromArray (src, srcIndex) {
|
|
44
|
-
const srcSplat = src.splats[srcIndex];
|
|
45
|
-
this.addSplatFromComonents(srcSplat[0], srcSplat[1], srcSplat[2], srcSplat[3], srcSplat[4], srcSplat[5],
|
|
46
|
-
srcSplat[6], srcSplat[7], srcSplat[8], srcSplat[9],
|
|
47
|
-
srcSplat[10], srcSplat[11], srcSplat[12], srcSplat[13]);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { SceneFormat } from './SceneFormat.js';
|
|
2
|
-
|
|
3
|
-
export const sceneFormatFromPath = (path) => {
|
|
4
|
-
if (path.endsWith('.ply')) return SceneFormat.Ply;
|
|
5
|
-
else if (path.endsWith('.splat')) return SceneFormat.Splat;
|
|
6
|
-
else if (path.endsWith('.ksplat')) return SceneFormat.KSplat;
|
|
7
|
-
return null;
|
|
8
|
-
};
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import {SplatLoader as SplatLoaderJs} from '../loaders/SplatLoader.js'
|
|
2
|
-
import {ILoader, Loader} from 'threepipe'
|
|
3
|
-
import {GaussianSplatMesh} from '../../three-gaussian-splat'
|
|
4
|
-
|
|
5
|
-
export class SplatLoader extends Loader implements ILoader {
|
|
6
|
-
private _loader = new SplatLoaderJs()
|
|
7
|
-
load(url: string, onLoad?: (splat: any) => void, onProgress?: (event: ProgressEvent) => void, onError?: (event: ErrorEvent) => void) {
|
|
8
|
-
const onProgress1 = (percent: number, percentStr: string, status: number /* LoaderStatus*/)=>{
|
|
9
|
-
console.log('SplatLoader onProgress', {percent, percentStr, status})
|
|
10
|
-
onProgress && onProgress(new ProgressEvent('progress', {loaded: percent, total: 100}))
|
|
11
|
-
}
|
|
12
|
-
const streamBuiltSections = false
|
|
13
|
-
const onSectionBuilt = (streamSplatBuffer: any /* SplatBuffer */, loadComplete: boolean)=>{
|
|
14
|
-
console.log('SplatLoader streamSectionProgress', {streamSplatBuffer, loadComplete})
|
|
15
|
-
onLoad && onLoad(streamSplatBuffer)
|
|
16
|
-
}
|
|
17
|
-
const splatAlphaRemovalThreshold = 1
|
|
18
|
-
this._loader.loadFromURL(
|
|
19
|
-
url, onProgress1, streamBuiltSections, onSectionBuilt,
|
|
20
|
-
0, splatAlphaRemovalThreshold, false).then((buffer: any)=>{
|
|
21
|
-
console.log(buffer)
|
|
22
|
-
console.log('SplatLoader onLoad', buffer)
|
|
23
|
-
onLoad && onLoad(buffer)
|
|
24
|
-
}).catch((err: any)=>{
|
|
25
|
-
console.error(err)
|
|
26
|
-
onError && onError(new ErrorEvent('error', {error: err}))
|
|
27
|
-
})
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
public async loadAsync(url: string, onProgress?: (event: ProgressEvent) => void): Promise<GaussianSplatMesh> {
|
|
31
|
-
return new Promise((resolve, reject) => this.load(url, resolve, onProgress, reject))
|
|
32
|
-
}
|
|
33
|
-
}
|