Skip to content

Commit

Permalink
Update viewer app (#388)
Browse files Browse the repository at this point in the history
  • Loading branch information
slimbuck authored Jan 27, 2025
1 parent 32dc2ba commit 8d76535
Show file tree
Hide file tree
Showing 8 changed files with 297 additions and 199 deletions.
20 changes: 20 additions & 0 deletions import-as-string.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { createFilter } from '@rollup/pluginutils';
export function importAsString(options) {
const { include, exclude, transform = content => content } = options;
const filter = createFilter(include, exclude);
return {
name: 'importAsString',
transform(code, id) {
if (filter(id)) {
const content = transform(code, id) //
.replaceAll('\\', '\\\\')
.replaceAll('`', '\\`');
return {
code: `export default \`${content}\`;`,
map: { mappings: '' },
};
}
},
};
}
export default importAsString;
4 changes: 4 additions & 0 deletions rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import path from 'path';
import copyAndWatch from './copy-and-watch.mjs';
import importAsString from './import-as-string.mjs';
import alias from '@rollup/plugin-alias';
import image from '@rollup/plugin-image';
import terser from '@rollup/plugin-terser';
Expand Down Expand Up @@ -82,6 +83,9 @@ const application = {
{ src: 'static/env/VertebraeHDRI_v1_512.png', dest: 'static/env' }
]
}),
importAsString({
include: ['src/templates/*']
}),
alias({ entries: aliasEntries }),
resolve(),
image({ dom: false }),
Expand Down
5 changes: 5 additions & 0 deletions src/declaration.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ declare module '*.scss' {
const value: any;
export default value;
}

declare module '*.template' {
const content: string;
export default content;
}
45 changes: 19 additions & 26 deletions src/splat-serialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import { SHRotation } from './sh-utils';
import { Splat } from './splat';
import { State } from './splat-state';
import { version } from '../package.json';
import { template as CssTemplate } from './templates/viewer-css';
import { template as HtmlTemplate } from './templates/viewer-html';
import { template as ScriptTemplate } from './templates/viewer-script';
import indexCss from './templates/index.css.template';
import indexHtml from './templates/index.html.template';
import indexJs from './templates/index.js.template';

// async function for writing data
type WriteFunc = (data: Uint8Array, finalWrite?: boolean) => void;
Expand Down Expand Up @@ -919,42 +919,35 @@ const serializeViewer = async (splats: Splat[], options: ViewerExportSettings, w
compressedData = data;
});

const htmlFilename = 'index.html';
const scriptFilename = 'index.js';
const cssFilename = 'index.css';
const settingsFilename = 'settings.json';
const sceneFilename = 'scene.compressed.ply';

const { viewerSettings } = options;

if (options.type === 'html') {
const pad = (text: string, spaces: number) => {
const whitespace = ' '.repeat(spaces);
return text.split('\n').map((line, i) => (i ? whitespace : '') + line).join('\n');
return text.split('\n').map(line => whitespace + line).join('\n');
};

const html = HtmlTemplate
.replace('{{style}}', `<style>${pad(CssTemplate, 12)}\n </style>`)
.replace('{{script}}', `<script type="module">${pad(ScriptTemplate, 12)}\n </script>`)
.replace('{{settingsURL}}', `data:application/json;base64,${encodeBase64(new TextEncoder().encode(JSON.stringify(viewerSettings)))}`)
.replace('{{contentURL}}', `data:application/ply;base64,${encodeBase64(compressedData)}`);
const style = '<link rel="stylesheet" href="./index.css">';
const script = '<script type="module" src="./index.js"></script>';
const settings = '"viewerSettings": "./settings.json"';
const content = '<pc-asset id="ply" type="gsplat" lazy src="./scene.compressed.ply"></pc-asset>';

const html = indexHtml
.replace(style, `<style>\n${pad(indexCss, 12)}\n </style>`)
.replace(script, `<script type="module">\n${pad(indexJs, 12)}\n </script>`)
.replace(settings, `"viewerSettings": "data:application/json;base64,${encodeBase64(new TextEncoder().encode(JSON.stringify(viewerSettings)))}"`)
.replace(content, `<pc-asset id="ply" type="gsplat" lazy src="data:application/ply;base64,${encodeBase64(compressedData)}"></pc-asset>`);

await write(new TextEncoder().encode(html), true);
} else {
const html = HtmlTemplate
.replace('{{style}}', `<link rel="stylesheet" href="./${cssFilename}">`)
.replace('{{script}}', `<script type="module" src="./${scriptFilename}"></script>`)
.replace('{{settingsURL}}', `./${settingsFilename}`)
.replace('{{contentURL}}', `./${sceneFilename}`);

/* global JSZip */
// @ts-ignore
const zip = new JSZip();
zip.file(htmlFilename, html);
zip.file(cssFilename, CssTemplate);
zip.file(scriptFilename, ScriptTemplate);
zip.file(settingsFilename, JSON.stringify(viewerSettings, null, 4));
zip.file(sceneFilename, compressedData);
zip.file('index.html', indexHtml);
zip.file('index.css', indexCss);
zip.file('index.js', indexJs);
zip.file('settings.json', JSON.stringify(viewerSettings, null, 4));
zip.file('scene.compressed.ply', compressedData);
const result = await zip.generateAsync({ type: 'uint8array' });
await write(result, true);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const template = /* css */ `
* {
margin: 0;
padding: 0;
Expand Down Expand Up @@ -94,6 +93,4 @@ body {
.buttonSvg {
display: block;
margin: auto;
}`;

export { template };
}
25 changes: 11 additions & 14 deletions src/templates/viewer-html.ts → src/templates/index.html.template
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
const template = /* html */ `
<!DOCTYPE html>
<html lang="en">
<head>
<title>SuperSplat Viewer</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
{{style}}
<base href="">
<link rel="stylesheet" href="./index.css">
<script type="importmap">
{
"imports": {
"playcanvas": "https://cdn.jsdelivr.net/npm/playcanvas@2.3.3/build/playcanvas.mjs",
"viewerSettings": "{{settingsURL}}"
"playcanvas": "https://cdn.jsdelivr.net/npm/playcanvas@2.4.2/build/playcanvas.mjs",
"viewerSettings": "./settings.json"
}
}
</script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@playcanvas/[email protected].11/dist/pwc.mjs"></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/@playcanvas/[email protected].13/dist/pwc.mjs"></script>
</head>
<body>
<pc-app antialias="false" depth="false" high-resolution="true" stencil="false">
<pc-asset id="camera-controls" src="https://cdn.jsdelivr.net/npm/playcanvas@2.3.1/scripts/esm/camera-controls.mjs" preload></pc-asset>
<pc-asset id="xr-controllers" src="https://cdn.jsdelivr.net/npm/playcanvas@2.3.1/scripts/esm/xr-controllers.mjs" preload></pc-asset>
<pc-asset id="xr-navigation" src="https://cdn.jsdelivr.net/npm/playcanvas@2.3.1/scripts/esm/xr-navigation.mjs" preload></pc-asset>
<pc-asset id="ply" type="gsplat" src="{{contentURL}}"></pc-asset>
<pc-asset src="https://cdn.jsdelivr.net/npm/playcanvas@2.4.2/scripts/esm/camera-controls.mjs"></pc-asset>
<pc-asset src="https://cdn.jsdelivr.net/npm/playcanvas@2.4.2/scripts/esm/xr-controllers.mjs"></pc-asset>
<pc-asset src="https://cdn.jsdelivr.net/npm/playcanvas@2.4.2/scripts/esm/xr-navigation.mjs"></pc-asset>
<pc-asset id="ply" type="gsplat" lazy src="./scene.compressed.ply"></pc-asset>
<pc-scene>
<!-- Camera (with XR support) -->
<pc-entity name="camera root">
<pc-entity name="camera">
<pc-camera nearClip="0.01" farClip="1000" horizontalFov="true" tonemap="none"></pc-camera>
<pc-camera near-clip="0.01" far-clip="1000" horizontal-fov="true" tonemap="none"></pc-camera>
<pc-scripts>
<pc-script name="cameraControls"></pc-script>
</pc-scripts>
Expand Down Expand Up @@ -112,9 +112,6 @@ const template = /* html */ `
</button>
</div>

{{script}}
<script type="module" src="./index.js"></script>
</body>
</html>
`;

export { template };
Loading

0 comments on commit 8d76535

Please sign in to comment.