Skip to content

Commit

Permalink
Merge pull request #161 from mkkellogg/dev
Browse files Browse the repository at this point in the history
Release v0.3.4: Upgraded PLY support
  • Loading branch information
mkkellogg authored Mar 17, 2024
2 parents a64c0c8 + 5772a68 commit e5846bd
Show file tree
Hide file tree
Showing 17 changed files with 1,081 additions and 411 deletions.
87 changes: 40 additions & 47 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,19 @@
}

.text-input {
border: #aaaaaa 1px solid;
border: hsl(0, 0%, 67%) 1px solid;
background-color: #ffffff;
padding: 4px;
border-radius: 3px;
}

.checkbox-input {
width: 17px;
height: 17px;
padding: 0px;
margin: 0;
}

.splat-panel {
margin-top: 10px;
margin-bottom: 10px;
Expand Down Expand Up @@ -193,6 +200,11 @@
margin-right: 3px;
}

.valid-value-label {
color:#888888;
font-size: 10pt;
}

@keyframes ply-load {
to{transform: rotate(1turn)}
}
Expand Down Expand Up @@ -254,37 +266,16 @@
import * as GaussianSplats3D from 'gaussian-splats-3d';
import * as THREE from 'three';

function convertPLYToSplatBuffer(plyBufferData, compressionLevel, alphaRemovalThreshold, sectionSize, sceneCenter, blockSize, bucketSize) {
const plyParser = new GaussianSplats3D.PlyParser(plyBufferData.data);
const splatArray = plyParser.parseToUncompressedSplatArray();
plyBufferData.data = null;
const splatBufferGenerator = GaussianSplats3D.SplatBufferGenerator.getStandardGenerator(alphaRemovalThreshold, compressionLevel, sectionSize, sceneCenter, blockSize, bucketSize);
return splatBufferGenerator.generateFromUncompressedSplatArray(splatArray);
}

function convertStandardSplatToSplatBuffer(bufferData, compressionLevel, alphaRemovalThreshold, sectionSize, sceneCenter, blockSize, bucketSize){
const splatArray = GaussianSplats3D.SplatParser.parseStandardSplatToUncompressedSplatArray(bufferData);
const splatBufferGenerator = GaussianSplats3D.SplatBufferGenerator.getStandardGenerator(alphaRemovalThreshold, compressionLevel, sectionSize, sceneCenter, blockSize, bucketSize);
return splatBufferGenerator.generateFromUncompressedSplatArray(splatArray);
}

function isPlyFile(fileName) {
return fileName.toLowerCase().trim().endsWith('.ply');
}

function fileBufferToSplatBuffer(fileBufferData, format, compressionLevel, alphaRemovalThreshold, sectionSize, sceneCenter, blockSize, bucketSize) {
let splatBuffer;
function fileBufferToSplatBuffer(fileBufferData, format, alphaRemovalThreshold, compressionLevel, sectionSize, sceneCenter, blockSize, bucketSize) {
if (format === GaussianSplats3D.SceneFormat.Ply) {
splatBuffer = convertPLYToSplatBuffer(fileBufferData, compressionLevel, alphaRemovalThreshold, sectionSize, sceneCenter, blockSize, bucketSize);
return GaussianSplats3D.PlyLoader.loadFromFileData(fileBufferData.data, alphaRemovalThreshold, compressionLevel, sectionSize, sceneCenter, blockSize, bucketSize);
} else {
if (format === GaussianSplats3D.SceneFormat.Splat) {
splatBuffer = convertStandardSplatToSplatBuffer(fileBufferData.data, compressionLevel, alphaRemovalThreshold, sectionSize, sceneCenter, blockSize, bucketSize);
return GaussianSplats3D.SplatLoader.loadFromFileData(fileBufferData.data, alphaRemovalThreshold, compressionLevel, sectionSize, sceneCenter, blockSize, bucketSize);
} else {
GaussianSplats3D.KSplatLoader.checkVersion(fileBufferData.data);
splatBuffer = new GaussianSplats3D.SplatBuffer(fileBufferData.data);
return GaussianSplats3D.KSplatLoader.loadFromFileData(fileBufferData.data);
}
}
return splatBuffer;
}

window.onCompressionLevelChange = function(arg) {
Expand Down Expand Up @@ -386,10 +377,12 @@
const fileData = {data: fileReader.result};
window.setTimeout(() => {
try {
const splatBuffer = fileBufferToSplatBuffer(fileData, format, compressionLevel,
alphaRemovalThreshold, sectionSize, sceneCenter, blockSize, bucketSize);
GaussianSplats3D.KSplatLoader.downloadFile(splatBuffer, 'converted_file.ksplat');
conversionDone();
const splatBufferPromise = fileBufferToSplatBuffer(fileData, format, alphaRemovalThreshold, compressionLevel,
sectionSize, sceneCenter, blockSize, bucketSize);
splatBufferPromise.then((splatBuffer) => {
GaussianSplats3D.KSplatLoader.downloadFile(splatBuffer, 'converted_file.ksplat');
conversionDone();
});
} catch (e) {
conversionDone(e);
}
Expand Down Expand Up @@ -540,15 +533,16 @@
const splatBufferOptions = {
'splatAlphaRemovalThreshold': alphaRemovalThreshold
};

const splatBuffer = fileBufferToSplatBuffer({data: splatBufferData}, format, 0, alphaRemovalThreshold);
document.getElementById("demo-content").style.display = 'none';
document.body.style.backgroundColor = "#000000";
history.pushState("ViewSplat", null);
const viewer = new GaussianSplats3D.Viewer(viewerOptions);
viewer.addSplatBuffers([splatBuffer], [splatBufferOptions])
.then(() => {
viewer.start();
const splatBufferPromise = fileBufferToSplatBuffer({data: splatBufferData}, format, alphaRemovalThreshold, 0);
splatBufferPromise.then((splatBuffer) => {
document.getElementById("demo-content").style.display = 'none';
document.body.style.backgroundColor = "#000000";
history.pushState("ViewSplat", null);
const viewer = new GaussianSplats3D.Viewer(viewerOptions);
viewer.addSplatBuffers([splatBuffer], [splatBufferOptions])
.then(() => {
viewer.start();
});
});
}

Expand Down Expand Up @@ -618,7 +612,7 @@
<br>
<div class="header-content-container">
<div class="content-row">
<div id ="view-panel" class="splat-panel" style="height:300px;">
<div id ="view-panel" class="splat-panel" style="height:310px;">
<br>
<div class="small-title">View a <span class="file-ext">.ply</span>, <span class="file-ext">.ksplat</span>, or <span class="file-ext-small">.splat</span> file</div>
<br>
Expand All @@ -635,13 +629,12 @@
<tr>
<td colspan="2" style="height: 10px;"></td>
</tr>
<tr>
<td>
Minimum alpha:&nbsp;
</td>
<td>
<input id="alphaRemovalThresholdView" type="text" class="text-input" style="width: 50px" value="1"></input>
<span style="color:#888888">(1 - 255)</span>
<span class="valid-value-label">(1 - 255)</span>
</td>
</tr>
<tr>
Expand Down Expand Up @@ -685,7 +678,7 @@
<span id="viewError" style="color: #ff0000"></span>
</div>

<div id ="conversion-panel" class="splat-panel" style="height:380px;">
<div id ="conversion-panel" class="splat-panel" style="height:390px;">
<br>
<span class="small-title">Convert a <span class="file-ext">.ply</span> or <span class="file-ext">.splat</span> to <span class="file-ext">.ksplat</span></span>
<br>
Expand All @@ -709,7 +702,7 @@
</td>
<td>
<input id="alphaRemovalThreshold" type="text" class="text-input" style="width: 50px" value="1"></input>
<span style="color:#888888">(1 - 255)</span>
<span class="valid-value-label">(1 - 255)</span>
</td>
</tr>
<tr>
Expand All @@ -726,7 +719,7 @@
</td>
<td>
<input id="compressionLevel" type="text" class="text-input" style="width: 50px" value="1" onChange="window.onCompressionLevelChange(this);"></input>
<span style="color:#888888">(0 or 1)</span>
<span class="valid-value-label">(0 or 1)</span>
</td>
</tr>
<tr id="advancedCompressionRow1">
Expand All @@ -740,7 +733,7 @@
</td>
<td>
<input id="blockSize" type="text" class="text-input" style="width: 50px" value="5.0"></input>
<span style="color:#888888">( >= 0.1 )</span>
<span class="valid-value-label">( >= 0.1 )</span>
</td>
</tr>
<tr id="advancedCompressionRow3">
Expand All @@ -749,7 +742,7 @@
</td>
<td>
<input id="bucketSize" type="text" class="text-input" style="width: 50px" value="256"></input>
<span style="color:#888888">(2 - 65536)</span>
<span class="valid-value-label">(2 - 65536)</span>
</td>
</tr>
</table>
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"type": "git",
"url": "https://github.com/mkkellogg/GaussianSplats3D"
},
"version": "0.3.3",
"version": "0.3.4",
"description": "Three.js-based 3D Gaussian splat viewer",
"module": "build/gaussian-splats-3d.module.js",
"main": "build/gaussian-splats-3d.umd.cjs",
Expand Down
12 changes: 6 additions & 6 deletions src/SplatMesh.js
Original file line number Diff line number Diff line change
Expand Up @@ -837,8 +837,8 @@ export class SplatMesh extends THREE.Mesh {
const covariance = this.splatDataTextures.baseData.covariances[i];
paddedCovariances[i] = covariance;
}
const covariancesTextureProps = this.renderer.properties.get(covariancesTexture);
if (!covariancesTextureProps.__webglTexture) {
const covariancesTextureProps = this.renderer ? this.renderer.properties.get(covariancesTexture) : null;
if (!covariancesTextureProps || !covariancesTextureProps.__webglTexture) {
covariancesTexture.needsUpdate = true;
} else {
const covaranceBytesPerElement = this.halfPrecisionCovariancesOnGPU ? 2 : 4;
Expand All @@ -851,8 +851,8 @@ export class SplatMesh extends THREE.Mesh {
const centerColorsTexture = centerColorsTextureDescriptor.texture;
updateCenterColorsPaddedData(this.lastBuildSplatCount, splatCount, this.splatDataTextures.baseData.centers,
this.splatDataTextures.baseData.colors, paddedCenterColors);
const centerColorsTextureProps = this.renderer.properties.get(centerColorsTexture);
if (!centerColorsTextureProps.__webglTexture) {
const centerColorsTextureProps = this.renderer ? this.renderer.properties.get(centerColorsTexture) : null;
if (!centerColorsTextureProps || !centerColorsTextureProps.__webglTexture) {
centerColorsTexture.needsUpdate = true;
} else {
this.updateDataTexture(paddedCenterColors, centerColorsTextureDescriptor, centerColorsTextureProps,
Expand All @@ -867,8 +867,8 @@ export class SplatMesh extends THREE.Mesh {
}

const paddedTransformIndexesTexture = transformIndexesTexDesc.texture;
const transformIndexesTextureProps = this.renderer.properties.get(paddedTransformIndexesTexture);
if (!transformIndexesTextureProps.__webglTexture) {
const transformIndexesTextureProps = this.renderer ? this.renderer.properties.get(paddedTransformIndexesTexture) : null;
if (!transformIndexesTextureProps || !transformIndexesTextureProps.__webglTexture) {
paddedTransformIndexesTexture.needsUpdate = true;
} else {
this.updateDataTexture(paddedTransformIndexes, transformIndexesTexDesc, transformIndexesTextureProps, 1, 1, 1);
Expand Down
16 changes: 7 additions & 9 deletions src/Viewer.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as THREE from 'three';
import { OrbitControls } from './OrbitControls.js';
import { PlyLoader } from './loaders/PlyLoader.js';
import { SplatLoader } from './loaders/SplatLoader.js';
import { KSplatLoader } from './loaders/KSplatLoader.js';
import { PlyLoader } from './loaders/ply/PlyLoader.js';
import { SplatLoader } from './loaders/splat/SplatLoader.js';
import { KSplatLoader } from './loaders/ksplat/KSplatLoader.js';
import { sceneFormatFromPath } from './loaders/Utils.js';
import { LoadingSpinner } from './ui/LoadingSpinner.js';
import { LoadingProgressBar } from './ui/LoadingProgressBar.js';
Expand Down Expand Up @@ -778,20 +778,18 @@ export class Viewer {
loadSplatSceneToSplatBuffer(path, splatAlphaRemovalThreshold = 1, onProgress = undefined,
streamBuiltSections = false, onSectionBuilt = undefined, format) {
if (format === SceneFormat.Splat) {
return new SplatLoader().loadFromURL(path, onProgress, streamBuiltSections, onSectionBuilt,
0, splatAlphaRemovalThreshold, false);
return SplatLoader.loadFromURL(path, onProgress, streamBuiltSections, onSectionBuilt, splatAlphaRemovalThreshold, 0, false);
} else if (format === SceneFormat.KSplat) {
return new KSplatLoader().loadFromURL(path, onProgress, streamBuiltSections,
onSectionBuilt, 0, splatAlphaRemovalThreshold);
return KSplatLoader.loadFromURL(path, onProgress, streamBuiltSections, onSectionBuilt);
} else if (format === SceneFormat.Ply) {
return new PlyLoader().loadFromURL(path, onProgress, 0, splatAlphaRemovalThreshold);
return PlyLoader.loadFromURL(path, onProgress, streamBuiltSections, onSectionBuilt, splatAlphaRemovalThreshold, 0);
}

return AbortablePromise.reject(new Error(`Viewer::loadSplatSceneToSplatBuffer -> File format not supported: ${path}`));
}

static isStreamable(format) {
return format === SceneFormat.Splat || format === SceneFormat.KSplat;
return format === SceneFormat.Splat || format === SceneFormat.KSplat || format === SceneFormat.Ply;
}

/**
Expand Down
12 changes: 7 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { PlyParser } from './loaders/PlyParser.js';
import { PlyLoader } from './loaders/PlyLoader.js';
import { SplatLoader } from './loaders/SplatLoader.js';
import { KSplatLoader } from './loaders/KSplatLoader.js';
import { PlyParser } from './loaders/ply/PlyParser.js';
import { CompressedPlyParser } from './loaders/ply/CompressedPlyParser.js';
import { PlyLoader } from './loaders/ply/PlyLoader.js';
import { SplatLoader } from './loaders/splat/SplatLoader.js';
import { KSplatLoader } from './loaders/ksplat/KSplatLoader.js';
import * as LoaderUtils from './loaders/Utils.js';
import { SplatBuffer } from './loaders/SplatBuffer.js';
import { SplatParser } from './loaders/SplatParser.js';
import { SplatParser } from './loaders/splat/SplatParser.js';
import { SplatPartitioner } from './loaders/SplatPartitioner.js';
import { SplatBufferGenerator } from './loaders/SplatBufferGenerator.js';
import { Viewer } from './Viewer.js';
Expand All @@ -17,6 +18,7 @@ import { RenderMode } from './RenderMode.js';

export {
PlyParser,
CompressedPlyParser,
PlyLoader,
SplatLoader,
KSplatLoader,
Expand Down
32 changes: 0 additions & 32 deletions src/loaders/PlyLoader.js

This file was deleted.

Loading

0 comments on commit e5846bd

Please sign in to comment.