Skip to content

Commit

Permalink
Transform panel (#143)
Browse files Browse the repository at this point in the history
  • Loading branch information
slimbuck authored Jul 23, 2024
1 parent b512033 commit 07c49a9
Show file tree
Hide file tree
Showing 9 changed files with 346 additions and 137 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.24.3",
"version": "0.25.0",
"author": "PlayCanvas<[email protected]>",
"homepage": "https://playcanvas.com/supersplat/editor",
"description": "3D Gaussian Splat Editor",
Expand Down
4 changes: 2 additions & 2 deletions src/controllers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ const worldDiff = new Vec3();
const dist = (x0: number, y0: number, x1: number, y1: number) => Math.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2);

class PointerController {
destroy: () => void;
update: (deltaTime: number) => void;
destroy: () => void;

constructor(camera: Camera, target: HTMLElement) {

Expand Down Expand Up @@ -154,7 +154,7 @@ class PointerController {
};

const keydown = (event: KeyboardEvent) => {
if (keys.hasOwnProperty(event.key)) {
if (keys.hasOwnProperty(event.key) && event.target === document.body) {
keys[event.key] = event.shiftKey ? 10 : (event.ctrlKey || event.metaKey || event.altKey ? 0.1 : 1);
event.preventDefault();
event.stopPropagation();
Expand Down
9 changes: 7 additions & 2 deletions src/splat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,8 @@ class Splat extends Element {

this.worldBoundDirty = true;
this.scene.boundDirty = true;

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

// get local space bound
Expand All @@ -387,10 +389,11 @@ class Splat extends Element {
localBound.halfExtents.set(0.5, 0.5, 0.5);
}

this.localBoundDirty = false;

// align the pivot point to the splat center
this.entity.getWorldTransform().transformPoint(localBound.center, vec);
this.setPivot(vec);

this.localBoundDirty = false;
}

return this.localBoundStorage;
Expand All @@ -416,6 +419,8 @@ class Splat extends Element {
mat.transformPoint(position, veca);
this.entity.setLocalPosition(-veca.x, -veca.y, -veca.z);
this.pivot.setLocalPosition(position);

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

get visible() {
Expand Down
14 changes: 12 additions & 2 deletions src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ body {
margin-right: 10px;
color: $text-secondary;

#transform-panel & { content: '\E111'; };
#camera-panel & { content: '\E212'; };
#show-panel & { content: '\E117'; };
#selection-panel & { content: '\E398'; };
Expand Down Expand Up @@ -328,6 +329,15 @@ body {
flex-direction: column;
}

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

.transform-panel-axis-label {
text-align: center;
}

#camera-panel > .pcui-panel-content {
display: flex;
flex-direction: column;
Expand All @@ -353,8 +363,8 @@ body {
width: 100px;
flex-shrink: 0;
flex-grow: 0;
line-height: 24px;
margin: 2px 6px 2px 6px;
line-height: 32px;
margin: 0px 6px 0px 6px;
}

.control-element {
Expand Down
4 changes: 4 additions & 0 deletions src/tools/transform-tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ class TransformTool {
this.update();
});

events.on('splat.moved', (splat: Splat) => {
this.update();
});

const updateGizmoSize = () => {
const canvas = document.getElementById('canvas');
if (canvas) {
Expand Down
142 changes: 14 additions & 128 deletions src/ui/control-panel.ts
Original file line number Diff line number Diff line change
@@ -1,135 +1,11 @@
import { BooleanInput, Button, Container, Element as PcuiElement, Label, NumericInput, Panel, RadioButton, SelectInput, SliderInput, TreeViewItem, VectorInput } from 'pcui';
import { BooleanInput, Button, Container, Label, NumericInput, Panel, RadioButton, SelectInput, SliderInput, VectorInput } from 'pcui';
import { Events } from '../events';
import { SplatItem, SplatList } from './splat-list';
import { TransformPanel } from './transform-panel';
import { Element, ElementType } from '../element';
import { Splat } from '../splat';
import { version as appVersion } from '../../package.json';

class SplatItem extends Container {
getSelected: () => boolean;
setSelected: (value: boolean) => void;
getVisible: () => boolean;
setVisible: (value: boolean) => void;
destroy: () => void;

constructor(name: string, args = {}) {
args = {
...args,
class: 'scene-panel-splat-item'
};

super(args);

const text = new Label({
class: 'scene-panel-splat-item-text',
text: name
});

const visible = new PcuiElement({
class: ['scene-panel-splat-item-visible', 'checked']
});

const remove = new PcuiElement({
class: 'scene-panel-splat-item-delete'
});

this.append(text);
this.append(visible);
this.append(remove);

this.getSelected = () => {
return this.class.contains('selected');
};

this.setSelected = (value: boolean) => {
if (value !== this.selected) {
if (value) {
this.class.add('selected');
this.emit('select', this);
} else {
this.class.remove('selected');
this.emit('unselect', this);
}
}
};

this.getVisible = () => {
return visible.class.contains('checked');
};

this.setVisible = (value: boolean) => {
if (value !== this.visible) {
if (value) {
visible.class.add('checked');
this.emit('visible', this);
} else {
visible.class.remove('checked');
this.emit('invisible', this);
}
}
};

const toggleVisible = (event: MouseEvent) => {
event.stopPropagation();
this.visible = !this.visible;
};

const handleRemove = (event: MouseEvent) => {
event.stopPropagation();
this.emit('removeClicked', this);
};

// handle clicks
visible.dom.addEventListener('click', toggleVisible, true);
remove.dom.addEventListener('click', handleRemove, true);

this.destroy = () => {
visible.dom.removeEventListener('click', toggleVisible, true);
remove.dom.removeEventListener('click', handleRemove, true);
}
}

get selected() {
return this.getSelected();
}

set selected(value) {
this.setSelected(value);
}

get visible() {
return this.getVisible();
}

set visible(value) {
this.setVisible(value);
}
}

class SplatList extends Container {
protected _onAppendChild(element: PcuiElement): void {
super._onAppendChild(element);

if (element instanceof SplatItem) {
element.on('click', () => {
this.emit('click', element);
});

element.on('removeClicked', () => {
this.emit('removeClicked', element);
});
}
}

protected _onRemoveChild(element: PcuiElement): void {
if (element instanceof SplatItem) {
element.unbind('click');
element.unbind('removeClicked');
}

super._onRemoveChild(element);
}
}

class ControlPanel extends Panel {
constructor(events: Events, remoteStorageMode: boolean, args = { }) {
args = {
Expand Down Expand Up @@ -176,7 +52,14 @@ class ControlPanel extends Panel {
splatList.append(item);
items.set(splat, item);

item.on('visible', () => splat.visible = true);
item.on('visible', () => {
splat.visible = true;

// also select it if there is no other selection
if (!events.invoke('selection')) {
events.fire('selection', splat);
}
});
item.on('invisible', () => splat.visible = false);
}
});
Expand Down Expand Up @@ -237,6 +120,8 @@ class ControlPanel extends Panel {
}
});

const transformPanel = new TransformPanel(events);

// camera panel
const cameraPanel = new Panel({
id: 'camera-panel',
Expand Down Expand Up @@ -578,6 +463,7 @@ class ControlPanel extends Panel {
id: 'control-panel-controls'
});

controlsContainer.append(transformPanel);
controlsContainer.append(cameraPanel)
controlsContainer.append(selectionPanel);
controlsContainer.append(showPanel);
Expand Down
Loading

0 comments on commit 07c49a9

Please sign in to comment.