Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update viewer app #388

Merged
merged 2 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}
44 changes: 19 additions & 25 deletions src/splat-serialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
import { SHRotation } from './sh-utils';
import { Splat } from './splat';
import { State } from './splat-state';
import { version } from '../package.json';

Check failure on line 13 in src/splat-serialize.ts

View workflow job for this annotation

GitHub Actions / Lint (18.x)

There should be no empty line within import group
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,12 +920,6 @@
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') {
Expand All @@ -933,28 +928,27 @@
return text.split('\n').map((line, i) => (i ? 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">`;

Check failure on line 931 in src/splat-serialize.ts

View workflow job for this annotation

GitHub Actions / Lint (18.x)

Strings must use singlequote
const script = `<script type="module" src="./index.js"></script>`;

Check failure on line 932 in src/splat-serialize.ts

View workflow job for this annotation

GitHub Actions / Lint (18.x)

Strings must use singlequote
const settings = `"viewerSettings": "./settings.json"`;

Check failure on line 933 in src/splat-serialize.ts

View workflow job for this annotation

GitHub Actions / Lint (18.x)

Strings must use singlequote
const content = `<pc-asset id="ply" type="gsplat" lazy src="./scene.compressed.ply"></pc-asset>`;

Check failure on line 934 in src/splat-serialize.ts

View workflow job for this annotation

GitHub Actions / Lint (18.x)

Strings must use singlequote

const html = indexHtml
.replace(style, `<style>${pad('\n' + indexCss, 12)}\n </style>`)

Check failure on line 937 in src/splat-serialize.ts

View workflow job for this annotation

GitHub Actions / Lint (18.x)

Unexpected string concatenation
.replace(script, `<script type="module">${pad('\n' + indexJs, 12)}\n </script>`)

Check failure on line 938 in src/splat-serialize.ts

View workflow job for this annotation

GitHub Actions / Lint (18.x)

Unexpected string concatenation
.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
Loading