-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
splat.mjs
111 lines (92 loc) · 3.6 KB
/
splat.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import * as pc from 'playcanvas';
/**
* @typedef {import('../../options.mjs').ExampleOptions} ExampleOptions
* @param {import('../../options.mjs').ExampleOptions} options - The example options.
* @returns {Promise<pc.AppBase>} The example application.
*/
async function example({ canvas, deviceType, assetPath, scriptsPath, glslangPath, twgslPath, pcx, files }) {
const gfxOptions = {
deviceTypes: [deviceType],
glslangUrl: glslangPath + 'glslang.js',
twgslUrl: twgslPath + 'twgsl.js',
// disable antialiasing as gaussian splats do not benefit from it and it's expensive
antialias: false
};
const device = await pc.createGraphicsDevice(canvas, gfxOptions);
const createOptions = new pc.AppOptions();
createOptions.graphicsDevice = device;
createOptions.mouse = new pc.Mouse(document.body);
createOptions.touch = new pc.TouchDevice(document.body);
createOptions.componentSystems = [
pc.RenderComponentSystem,
pc.CameraComponentSystem,
pc.LightComponentSystem,
pc.ScriptComponentSystem
];
createOptions.resourceHandlers = [
// @ts-ignore
pc.TextureHandler,
// @ts-ignore
pc.ContainerHandler,
// @ts-ignore
pc.ScriptHandler
];
const app = new pc.AppBase(canvas);
app.init(createOptions);
pcx.registerPlyParser(app);
// Set the canvas to fill the window and automatically change resolution to be the same as the canvas size
app.setCanvasFillMode(pc.FILLMODE_FILL_WINDOW);
app.setCanvasResolution(pc.RESOLUTION_AUTO);
// Ensure canvas is resized when window changes size
const resize = () => app.resizeCanvas();
window.addEventListener('resize', resize);
app.on('destroy', () => {
window.removeEventListener('resize', resize);
});
const assets = {
biker: new pc.Asset('splat', 'container', { url: assetPath + 'splats/biker.ply' }),
orbit: new pc.Asset('script', 'script', { url: scriptsPath + 'camera/orbit-camera.js' })
};
const assetListLoader = new pc.AssetListLoader(Object.values(assets), app.assets);
assetListLoader.load(() => {
app.start();
app.scene.toneMapping = pc.TONEMAP_ACES;
// Create an Entity with a camera component
const camera = new pc.Entity();
camera.addComponent("camera", {
clearColor: new pc.Color(0.2, 0.2, 0.2)
});
camera.setLocalPosition(2, 1, 1);
const createSplatInstance = (resource, px, py, pz, scale, vertex, fragment) => {
const splat = resource.instantiateRenderEntity({
cameraEntity: camera,
debugRender: false,
fragment: fragment,
vertex: vertex
});
splat.setLocalPosition(px, py, pz);
splat.setLocalScale(scale, scale, scale);
app.root.addChild(splat);
return splat;
};
const biker = createSplatInstance(assets.biker.resource, -1.5, 0.05, 0, 0.7);
// add orbit camera script with a mouse and a touch support
camera.addComponent("script");
camera.script.create("orbitCamera", {
attributes: {
inertiaFactor: 0.2,
focusEntity: biker,
distanceMax: 60,
frameOnStart: false
}
});
camera.script.create("orbitCameraInputMouse");
camera.script.create("orbitCameraInputTouch");
app.root.addChild(camera);
});
return app;
}
export class SplatExample {
static CATEGORY = 'Loaders';
static example = example;
}