Skip to content

Commit 309d4e0

Browse files
authored
GSplat double click and sogs support (#320)
1 parent 70fe97c commit 309d4e0

7 files changed

Lines changed: 1109 additions & 474 deletions

File tree

package-lock.json

Lines changed: 968 additions & 289 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,32 +26,32 @@
2626
"@playcanvas/observer": "^1.6.6",
2727
"@playcanvas/pcui": "^5.2.0",
2828
"@rollup/plugin-alias": "^5.1.1",
29-
"@rollup/plugin-commonjs": "^28.0.2",
29+
"@rollup/plugin-commonjs": "^28.0.3",
3030
"@rollup/plugin-image": "^3.0.3",
3131
"@rollup/plugin-json": "^6.1.0",
32-
"@rollup/plugin-node-resolve": "^16.0.0",
32+
"@rollup/plugin-node-resolve": "^16.0.1",
3333
"@rollup/plugin-replace": "^6.0.2",
3434
"@rollup/plugin-terser": "^0.4.4",
3535
"@rollup/plugin-typescript": "^12.1.2",
3636
"@types/react": "^18.3.13",
3737
"@types/react-dom": "^18.3.1",
38-
"@typescript-eslint/eslint-plugin": "^8.25.0",
39-
"@typescript-eslint/parser": "^8.25.0",
38+
"@typescript-eslint/eslint-plugin": "^8.30.1",
39+
"@typescript-eslint/parser": "^8.30.1",
4040
"concurrently": "^9.1.2",
4141
"cross-env": "^7.0.3",
42-
"eslint": "^9.21.0",
43-
"eslint-import-resolver-typescript": "^3.8.3",
42+
"eslint": "^9.24.0",
43+
"eslint-import-resolver-typescript": "^4.3.2",
4444
"globals": "^16.0.0",
45-
"playcanvas": "^2.5.1",
45+
"playcanvas": "^2.7.1",
4646
"qrious": "^4.0.2",
4747
"react": "^18.3.1",
4848
"react-dom": "^18.3.1",
4949
"react-visibility-sensor": "^5.1.1",
50-
"rollup": "^4.34.8",
50+
"rollup": "^4.40.0",
5151
"rollup-plugin-sass": "^1.15.2",
5252
"serve": "^14.2.4",
5353
"tslib": "^2.8.1",
54-
"typescript": "^5.7.3"
54+
"typescript": "^5.8.3"
5555
},
5656
"scripts": {
5757
"build": "rollup -c",

src/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,6 @@ const loadOptions = (observer: Observer, name: string, skyboxUrls: Map<string, s
204204
}
205205
};
206206

207-
208207
// print out versions of dependent packages
209208
console.log(`Model Viewer v${modelViewerVersion} | PCUI v${pcuiVersion} (${pcuiRevision}) | PlayCanvas Engine v${engineVersion} (${engineRevision})`);
210209

src/multiframe.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
Shader,
1919
Texture,
2020
Vec3,
21+
GraphicsDevice,
2122
WebglGraphicsDevice
2223
} from 'playcanvas';
2324

@@ -43,16 +44,16 @@ void main(void) {
4344
}
4445
`;
4546

46-
const supportsFloat16 = (device: WebglGraphicsDevice): boolean => {
47+
const supportsFloat16 = (device: GraphicsDevice): boolean => {
4748
return device.textureHalfFloatRenderable;
4849
};
4950

50-
const supportsFloat32 = (device: WebglGraphicsDevice): boolean => {
51+
const supportsFloat32 = (device: GraphicsDevice): boolean => {
5152
return device.textureFloatRenderable;
5253
};
5354

5455
// lighting source should be stored HDR
55-
const choosePixelFormat = (device: WebglGraphicsDevice): number => {
56+
const choosePixelFormat = (device: GraphicsDevice): number => {
5657
return supportsFloat16(device) ? PIXELFORMAT_RGBA16F :
5758
supportsFloat32(device) ? PIXELFORMAT_RGBA32F :
5859
PIXELFORMAT_RGBA8;
@@ -68,7 +69,7 @@ const noBlend = new BlendState(false);
6869

6970
// generate multiframe, supersampled AA
7071
class Multiframe {
71-
device: WebglGraphicsDevice;
72+
device: GraphicsDevice;
7273

7374
camera: CameraComponent;
7475

@@ -100,7 +101,7 @@ class Multiframe {
100101

101102
blend = 1.0;
102103

103-
constructor(device: WebglGraphicsDevice, camera: CameraComponent, samples?: Vec3[]) {
104+
constructor(device: GraphicsDevice, camera: CameraComponent, samples?: Vec3[]) {
104105
this.device = device;
105106
this.camera = camera;
106107
this.samples = samples || Multiframe.generateSamples(5, false, 2, 0);
@@ -249,10 +250,11 @@ class Multiframe {
249250
private activateBackbuffer() {
250251
const device = this.device;
251252
if (!device.isWebGPU) {
252-
device.setRenderTarget(null);
253-
device.updateBegin();
254-
device.setViewport(0, 0, device.width, device.height);
255-
device.setScissor(0, 0, device.width, device.height);
253+
const glDevice = device as WebglGraphicsDevice;
254+
glDevice.setRenderTarget(null);
255+
glDevice.updateBegin();
256+
glDevice.setViewport(0, 0, device.width, device.height);
257+
glDevice.setScissor(0, 0, device.width, device.height);
256258
}
257259
}
258260

src/picker.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { AppBase, Entity, Picker as PickerPC, Vec3, Vec4 } from 'playcanvas';
2+
3+
const float32 = new Float32Array(1);
4+
const uint8 = new Uint8Array(float32.buffer);
5+
const two = new Vec4(2, 2, 2, 1);
6+
const one = new Vec4(1, 1, 1, 0);
7+
8+
class Picker {
9+
app: AppBase;
10+
11+
camera: Entity;
12+
13+
picker: PickerPC | null;
14+
15+
constructor(app: AppBase, camera: Entity) {
16+
this.app = app;
17+
this.camera = camera;
18+
this.picker = null;
19+
}
20+
21+
async pick(x: number, y: number) {
22+
const { app, camera } = this;
23+
const { graphicsDevice } = app;
24+
const { canvas } = graphicsDevice;
25+
const width = canvas.clientWidth;
26+
const height = canvas.clientHeight;
27+
28+
y = height - y - 1;
29+
30+
// construct picker on demand
31+
if (!this.picker) {
32+
this.picker = new PickerPC(this.app, width, height);
33+
}
34+
35+
// render scene, read depth
36+
const { picker } = this;
37+
picker.resize(width, height);
38+
picker.prepare(camera.camera, app.scene, [app.scene.layers.getLayerByName('World')]);
39+
const pixels = await picker.renderTarget.colorBuffer.read(x, y, 1, 1, {
40+
renderTarget: picker.renderTarget
41+
});
42+
43+
for (let i = 0; i < 4; ++i) {
44+
uint8[i] = pixels[i];
45+
}
46+
const depth = float32[0];
47+
48+
// 255, 255, 255, 255 === NaN
49+
if (!isFinite(depth)) {
50+
return null;
51+
}
52+
53+
// clip space
54+
const pos = new Vec4(x / width, y / height, depth, 1).mul(two).sub(one);
55+
56+
// homogeneous view space
57+
camera.camera.projectionMatrix.clone().invert().transformVec4(pos, pos);
58+
59+
// perform perspective divide
60+
pos.mulScalar(1.0 / pos.w);
61+
62+
// view to world space
63+
const pos3 = new Vec3(pos.x, pos.y, pos.z);
64+
camera.getWorldTransform().transformPoint(pos3, pos3);
65+
66+
return pos3;
67+
}
68+
}
69+
70+
export { Picker };

src/read-depth.ts

Lines changed: 0 additions & 135 deletions
This file was deleted.

0 commit comments

Comments
 (0)