Skip to content

Commit

Permalink
Initial Preview
Browse files Browse the repository at this point in the history
  • Loading branch information
simonbethke committed Oct 17, 2024
1 parent a528004 commit e987945
Show file tree
Hide file tree
Showing 8 changed files with 317 additions and 3 deletions.
38 changes: 37 additions & 1 deletion src/edit-ops.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,40 @@ class ResetOp extends StateOp {
}
}

interface EntityColorAdjustment {
brightness: number
temperature: number
tint: number
}

class EntityColorAdjustmentOp {
name = 'entityColorAdjustment';

splat: Splat;
oldAdj: EntityColorAdjustment;
newAdj: EntityColorAdjustment;

constructor(options: { splat: Splat, oldAdj: EntityColorAdjustment, newAdj: EntityColorAdjustment }) {
this.splat = options.splat;
this.oldAdj = options.oldAdj;
this.newAdj = options.newAdj;
}

do() {
this.splat.colorAdjustment = this.newAdj;
}

undo() {
this.splat.colorAdjustment = this.oldAdj;
}

destroy() {
this.splat = null;
this.oldAdj = null;
this.oldAdj = null;
}
}

// op for modifying a splat transform
class EntityTransformOp {
name = 'entityTransform';
Expand Down Expand Up @@ -348,5 +382,7 @@ export {
EntityTransformOp,
SplatsTransformOp,
PlacePivotOp,
MultiOp
MultiOp,
EntityColorAdjustment,
EntityColorAdjustmentOp
};
4 changes: 4 additions & 0 deletions src/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ const registerEditorEvents = (events: Events, editHistory: EditHistory, scene: S
scene.forceRender = true;
});

events.on('splat.color', () => {
scene.forceRender = true;
});

events.on('camera.bound', () => {
scene.forceRender = true;
});
Expand Down
4 changes: 3 additions & 1 deletion src/shaders/splat-shader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ uniform sampler2D splatState;
uniform highp usampler2D splatTransform; // per-splat index into transform palette
uniform sampler2D transformPalette; // palette of transform matrices
uniform vec4 colorAdjustment; // rgba factors to be applied to SH0
varying mediump vec2 texCoord;
varying mediump vec4 color;
flat varying highp uint vertexState;
Expand Down Expand Up @@ -66,7 +68,7 @@ void main(void)
vec4 v1v2 = calcV1V2(splat_cam.xyz, covA, covB, transpose(mat3(model_view)));
// get color
color = texelFetch(splatColor, splatUV, 0);
color = texelFetch(splatColor, splatUV, 0) * colorAdjustment;
// calculate scale based on alpha
// float scale = min(1.0, sqrt(-log(1.0 / 255.0 / color.a)) / 2.0);
Expand Down
26 changes: 25 additions & 1 deletion src/splat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { Serializer } from "./serializer";
import { State } from './splat-state';
import { vertexShader, fragmentShader } from './shaders/splat-shader';
import { TransformPalette } from './transform-palette';
import { EntityColorAdjustment } from './edit-ops';

const vec = new Vec3();
const veca = new Vec3();
Expand Down Expand Up @@ -55,6 +56,11 @@ class Splat extends Element {
localBoundDirty = true;
worldBoundDirty = true;
_visible = true;
_colorAdjustment: EntityColorAdjustment = {
brightness: 1,
temperature: 0,
tint: 0
};
transformPalette: TransformPalette;

selectionAlpha = 1;
Expand Down Expand Up @@ -120,10 +126,18 @@ class Splat extends Element {
// @ts-ignore
instance.createMaterial(getMaterialOptions(instance.splat.hasSH ? bands : 0));

const material = instance.material;
const material = instance.material;
const {brightness, temperature, tint} = this._colorAdjustment;

material.setParameter('splatState', this.stateTexture);
material.setParameter('splatTransform', this.transformTexture);
material.setParameter('transformPalette', this.transformPalette.texture);
material.setParameter('colorAdjustment', [
(1.0 + temperature + tint) * brightness,
(1.0 - Math.abs(temperature / 2) - tint) * brightness,
(1.0 - temperature + tint / 2) * brightness,
1
]);
material.update();
};

Expand Down Expand Up @@ -391,6 +405,16 @@ class Splat extends Element {
this.scene.events.fire('splat.visibility', this);
}
}

set colorAdjustment(adj: EntityColorAdjustment){
this._colorAdjustment = adj;
this.rebuildMaterial(this.scene.events.invoke('view.bands'));
this.scene.events.fire('splat.color', this);
}

get colorAdjustment() {
return this._colorAdjustment;
}
}

export { Splat };
62 changes: 62 additions & 0 deletions src/ui/color-panel.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

#color-panel {
display: flex;
flex-direction: column;

background-color: $bcg-primary;

padding: 0px 6px 12px 6px;
}

.color-row{
height: 32px;
line-height: 32px;
width: 100%;
display: flex;
flex-direction: row;
flex-grow: 1;
align-items: center;
}

.color-label{
width: 70px;
flex-shrink: 0;
flex-grow: 0;
margin: 0px;
}

.color-expand {
flex-grow: 1;
}

$height: 22px;

#color-panel > div > div.pcui-vector-input {
margin: 0px;
gap: 10px;
height: $height;
}

#color-panel > div > div.pcui-numeric-input {
margin: 0px;
height: $height;
line-height: $height;

& > input {
padding: 0px;
margin: 0px 0px 0px 4px;
height: $height;
}
}

#color-panel > div > div > div.pcui-numeric-input {
margin: 0px;
height: $height;
line-height: $height;

& > input {
padding: 0px;
margin: 0px 0px 0px 4px;
height: $height;
}
}
162 changes: 162 additions & 0 deletions src/ui/color-panel.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
import { Container, ContainerArgs, Label, NumericInput } from 'pcui';
import { Events } from '../events';
import { Splat } from '../splat';
import { EntityColorAdjustmentOp } from '../edit-ops';
import { localize } from './localization';

class ColorPanel extends Container {
constructor(events: Events, args: ContainerArgs = {}) {
args = {
...args,
id: 'color-panel'
};

super(args);

const brightness = new Container({
class: 'color-row'
});

const brightnessLabel = new Label({
class: 'color-label',
text: localize('color.brightness')
});

const brightnessInput = new NumericInput({
class: 'color-expand',
precision: 2,
value: 1.0,
min: 0.0,
max: 10.0,
enabled: false
});

brightness.append(brightnessLabel);
brightness.append(brightnessInput);

const temperature = new Container({
class: 'color-row'
});

const temperatureLabel = new Label({
class: 'color-label',
text: localize('color.temperature')
});

const temperatureInput = new NumericInput({
class: 'color-expand',
precision: 2,
value: 0,
min: -0.5,
max: 0.5,
enabled: false
});

temperature.append(temperatureLabel);
temperature.append(temperatureInput);

const tint = new Container({
class: 'color-row'
});

const tintLabel = new Label({
class: 'color-label',
text: localize('color.tint')
});

const tintInput = new NumericInput({
class: 'color-expand',
precision: 2,
value: 0,
max: 0.5,
min: -0.5,
enabled: false
});

tint.append(tintLabel);
tint.append(tintInput);

this.append(brightness);
this.append(temperature);
this.append(tint);

let selection: Splat | null = null;

let uiUpdating = false;

const updateUI = () => {
uiUpdating = true;
brightnessInput.value = selection.colorAdjustment.brightness;
temperatureInput.value = selection.colorAdjustment.temperature;
tintInput.value = selection.colorAdjustment.tint;
uiUpdating = false;
};

events.on('selection.changed', (splat) => {
selection = splat;

if (selection) {
// enable inputs
updateUI();
temperatureInput.enabled = tintInput.enabled = brightnessInput.enabled = true;
} else {
// disable inputs
temperatureInput.enabled = tintInput.enabled = brightnessInput.enabled = false;
}
});

let op: EntityColorAdjustmentOp | null = null;

const createOp = () => {
op = new EntityColorAdjustmentOp({
splat: selection,
oldAdj: selection.colorAdjustment,
newAdj: selection.colorAdjustment
});
};

const updateOp = () => {
op.newAdj = {
brightness: brightnessInput.value,
temperature: temperatureInput.value,
tint: tintInput.value
};

op.do();
};

const submitOp = () => {
events.fire('edit.add', op);
op = null;
};

const change = () => {
if (!uiUpdating) {
if (op) {
updateOp();
} else {
createOp();
updateOp();
submitOp();
}
}
};

const mousedown = () => {
createOp();
};

const mouseup = () => {
updateOp();
submitOp();
};

[brightnessInput, temperatureInput, tintInput].forEach((input) => {
input.on('change', change);
input.on('slider:mousedown', mousedown);
input.on('slider:mouseup', mouseup);
});
}
}

export { ColorPanel };
4 changes: 4 additions & 0 deletions src/ui/localization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ const localizeInit = () => {
"position": "Position",
"rotation": "Rotation",
"scale": "Scale",
"color": "COLOR",
"color.brightness": "Brightness",
"color.temperature": "Temperature",
"color.tint": "Tint",

// Options panel
"options": "VIEW OPTIONS",
Expand Down
Loading

0 comments on commit e987945

Please sign in to comment.