Skip to content

Commit

Permalink
Add data panel (#127)
Browse files Browse the repository at this point in the history
  • Loading branch information
slimbuck authored Jul 10, 2024
1 parent 8696e64 commit 18fbe5a
Show file tree
Hide file tree
Showing 16 changed files with 876 additions and 129 deletions.
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
@@ -1,6 +1,6 @@
{
"name": "supersplat",
"version": "0.21.0",
"version": "0.22.0",
"author": "PlayCanvas<[email protected]>",
"homepage": "https://playcanvas.com/supersplat/editor",
"description": "3D Gaussian Splat Editor",
Expand Down
10 changes: 6 additions & 4 deletions rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@ if (process.env.BUILD_TYPE === 'prod') {
process.env.BUILD_TYPE = 'release';
}

// debug, profile, release
const HREF = process.env.BASE_HREF || '';

// debug, profile, release
const BUILD_TYPE = process.env.BUILD_TYPE || 'release';
const ENGINE_DIR = process.env.ENGINE_PATH || './node_modules/playcanvas';
const PCUI_DIR = path.resolve(process.env.PCUI_PATH || 'node_modules/@playcanvas/pcui');

const ENGINE_NAME = BUILD_TYPE === 'debug' ? 'playcanvas.dbg/src/index.js' : 'playcanvas/src/index.js';
const ENGINE_DIR = process.env.ENGINE_PATH || './node_modules/playcanvas';
const ENGINE_NAME = (BUILD_TYPE === 'debug') ? 'playcanvas.dbg/src/index.js' : 'playcanvas/src/index.js';
const ENGINE_PATH = path.resolve(ENGINE_DIR, 'build', ENGINE_NAME);

const PCUI_DIR = path.resolve(process.env.PCUI_PATH || 'node_modules/@playcanvas/pcui');

const aliasEntries = {
playcanvas: ENGINE_PATH,
pcui: PCUI_DIR
Expand Down
2 changes: 1 addition & 1 deletion src/camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ class Camera extends Element {
autoResolve: false
});
this.entity.camera.renderTarget = renderTarget;
this.entity.camera.camera.horizontalFov = width < height;
this.entity.camera.camera.horizontalFov = width > height;

// create pick mode render target
this.pickModeColorBuffer = createTexture(width, height, pixelFormat);
Expand Down
42 changes: 2 additions & 40 deletions src/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,49 +187,11 @@ const registerEditorEvents = (events: Events, editHistory: EditHistory, scene: S
});
});

events.on('select.bySize', (op: string, value: number) => {
events.on('select.pred', (op, pred: (i: number) => boolean) => {
selectedSplats().forEach((splat) => {
const splatData = splat.splatData;
const state = splatData.getProp('state') as Uint8Array;
const scale_0 = splatData.getProp('scale_0');
const scale_1 = splatData.getProp('scale_1');
const scale_2 = splatData.getProp('scale_2');

// calculate min and max size
let first = true;
let scaleMin;
let scaleMax;
for (let i = 0; i < splatData.numSplats; ++i) {
if (state[i] & State.deleted) continue;
if (first) {
first = false;
scaleMin = Math.min(scale_0[i], scale_1[i], scale_2[i]);
scaleMax = Math.max(scale_0[i], scale_1[i], scale_2[i]);
} else {
scaleMin = Math.min(scaleMin, scale_0[i], scale_1[i], scale_2[i]);
scaleMax = Math.max(scaleMax, scale_0[i], scale_1[i], scale_2[i]);
}
}

const maxScale = Math.log(Math.exp(scaleMin) + value * (Math.exp(scaleMax) - Math.exp(scaleMin)));

processSelection(state, op, (i) => scale_0[i] > maxScale || scale_1[i] > maxScale || scale_2[i] > maxScale);

splat.updateState();
});
});

events.on('select.byOpacity', (op: string, value: number) => {
selectedSplats().forEach((splat) => {
const splatData = splat.splatData;
const state = splatData.getProp('state') as Uint8Array;
const opacity = splatData.getProp('opacity') as Float32Array;

processSelection(state, op, (i) => {
const t = Math.exp(opacity[i]);
return ((1 / (1 + t)) < value);
});

processSelection(state, op, pred);
splat.updateState();
});
});
Expand Down
1 change: 1 addition & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ const initShortcuts = (events: Events) => {
shortcuts.register(['Z', 'z'], { event: 'edit.undo', ctrl: true });
shortcuts.register(['Z', 'z'], { event: 'edit.redo', ctrl: true, shift: true });
shortcuts.register(['M', 'm'], { event: 'camera.toggleMode' });
shortcuts.register(['D', 'd'], { event: 'dataPanel.toggle' });

// keep tabs on splat size changes
let splatSizeSave = 2;
Expand Down
6 changes: 3 additions & 3 deletions src/scene-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const sceneConfig = {
camera: {
pixelScale: 1,
multisample: false,
fov: 36,
fov: 50,
dollyZoom: true,
exposure: 1.0,
toneMapping: 'linear',
Expand All @@ -40,8 +40,8 @@ const sceneConfig = {
maxPolarAngle: 2.8,
minZoom: 0.001,
maxZoom: 2.0,
initialAzim: 0,
initialElev: -27,
initialAzim: -45,
initialElev: -10,
initialZoom: 1.0,
autoRotate: false,
autoRotateSpeed: -2.0,
Expand Down
8 changes: 8 additions & 0 deletions src/splat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,29 @@ flat varying highp uint vertexId;
#endif
vec4 discardVec = vec4(0.0, 0.0, 2.0, 1.0);
void main(void)
{
// calculate splat uv
if (!calcSplatUV()) {
gl_Position = discardVec;
return;
}
// read data
readData();
vec4 pos;
if (!evalSplat(pos)) {
gl_Position = discardVec;
return;
}
gl_Position = pos;
texCoord = vertex_position.xy;
color = getColor();
#ifndef DITHER_NONE
id = float(splatId);
#endif
Expand Down Expand Up @@ -212,6 +218,8 @@ class Splat extends Element {
}

this.scene.forceRender = true;

this.scene.events.fire('splat.stateChanged', this);
}

get worldTransform() {
Expand Down
117 changes: 115 additions & 2 deletions src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,89 @@ body {
border-right: 1px solid $bcg-darker;
}

#main-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
border: 0;
padding: 0;
margin: 0;
flex-grow: 1;
}

#canvas-container {
width: 100%;
background-color: #666666;
display: flex;
border: 0;
padding: 0;
margin: 0;
flex-grow: 1;
}

#data-panel {
width: 100%;
height: 320px;
}

#sep-container {
background-color: $bcg-darker;
}

#sep-container > span {
color: white;
}

#data-controls-container {
width: 256px;
flex-grow: 0;
flex-shrink: 0;
overflow-y: auto;
// display: flex;
// flex-direction: column;
}

#data-controls {
width: 100%;
}

#histogram-container {
flex-grow: 1;
flex-shrink: 1;
}

#histogram-canvas {

}

#histogram-svg {
pointer-events: none;
position: absolute;
width: 100%;
height: 100%;
top: 0;
right: 0;
bottom: 0;
left: 0;
}

#histogram-rect {
// fill: rgba()
}

#data-panel-popup-container {
position: absolute;
left: 50px;
top: 50px;
pointer-events: none;
}

#data-panel-popup-label {
background-color: $bcg-dark;
color: $text-primary;
}

#coord-space-toggle.active {
background-color: $bcg-dark !important;
color: #f60;
Expand All @@ -52,6 +135,17 @@ body {
border-right: 1px solid #20292b;
display: flex;
flex-direction: column;
flex-grow: 0;
flex-shrink: 0;
}

#control-panel-controls {
display: flex;
flex-direction: column;
flex-grow: 1;
flex-shrink: 1;

overflow-y: auto;
}

.pcui-panel-header-title::before {
Expand All @@ -69,6 +163,10 @@ body {
#keyboard-panel & { content: '\E136'};
}

#scene-panel {
flex-shrink: 0;
}

#scene-panel-splat-list-container {
// padding: 10px;
overflow: scroll;
Expand Down Expand Up @@ -233,15 +331,29 @@ body {
text-shadow: 0 0 4px black;
}

.control-panel > .pcui-panel-header {
#control-panel > .pcui-panel-header {
background-color: $bcg-dark;
}

.control-panel > .pcui-panel-content {
#control-panel > .pcui-panel-content {
display: flex;
flex-direction: column;
}

#camera-panel > .pcui-panel-content {
display: flex;
flex-direction: column;
}

#modify-panel > .pcui-panel-content {
display: flex;
flex-direction: column;
}

.control-panel {
flex-shrink: 0;
}

.control-parent {
width: 100%;
display: flex;
Expand All @@ -254,6 +366,7 @@ body {
flex-shrink: 0;
flex-grow: 0;
line-height: 24px;
margin: 2px 6px 2px 6px;
}

.control-element {
Expand Down
66 changes: 66 additions & 0 deletions src/ui/color.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

const rgb2hsv = (rgb: { r: number, g: number, b: number }) => {
const r = rgb.r;
const g = rgb.g;
const b = rgb.b;
const v = Math.max(r, g, b);
const diff = v - Math.min(r, g, b);

const diffc = (c: number) => {
return (v - c) / 6 / diff + 1 / 2;
};

let h, s;

if (diff === 0) {
h = s = 0;
} else {
s = diff / v;
const rr = diffc(r);
const gg = diffc(g);
const bb = diffc(b);

if (r === v) {
h = bb - gg;
} else if (g === v) {
h = (1 / 3) + rr - bb;
} else if (b === v) {
h = (2 / 3) + gg - rr;
}
if (h < 0) {
h += 1;
} else if (h > 1) {
h -= 1;
}
}

return { h, s, v };
};

const hsv2rgb = (hsv: { h: number, s: number, v: number }) => {
const h = hsv.h;
const s = hsv.s;
const v = hsv.v;

const i = Math.floor(h * 6);
const f = h * 6 - i;
const p = v * (1 - s);
const q = v * (1 - f * s);
const t = v * (1 - (1 - f) * s);

let r, g, b;

switch (i % 6) {
case 0: r = v; g = t; b = p; break;
case 1: r = q; g = v; b = p; break;
case 2: r = p; g = v; b = t; break;
case 3: r = p; g = q; b = v; break;
case 4: r = t; g = p; b = v; break;
case 5: r = v; g = p; b = q; break;
}

return { r, g, b };
};

export { rgb2hsv, hsv2rgb };

Loading

0 comments on commit 18fbe5a

Please sign in to comment.