Skip to content

Commit

Permalink
Support scene scale (#31)
Browse files Browse the repository at this point in the history
* add scene scale

* output scaled

* v0.10.3
  • Loading branch information
slimbuck committed Nov 14, 2023
1 parent 4271900 commit 7fcaa62
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 28 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": "super-splat",
"version": "0.10.2",
"version": "0.10.3",
"author": "PlayCanvas<support@playcanvas.com>",
"homepage": "https://playcanvas.com",
"description": "All the splat things",
Expand Down
28 changes: 13 additions & 15 deletions src/camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ class Camera extends Element {
focalPointTween = new TweenValue({x: 0, y: 0.5, z: 0});
azimElevTween = new TweenValue({azim: 30, elev: -15});
distanceTween = new TweenValue({distance: 2});
sceneRadius = 0;

minElev = -90;
maxElev = 90;
Expand Down Expand Up @@ -344,24 +343,23 @@ class Camera extends Element {
}
}

focus() {
let focalPoint: Vec3;
this.scene.elements.forEach((element: any) => {
if (!focalPoint && element.type === ElementType.splat) {
focalPoint = element.focalPoint && element.focalPoint();
}
});

focus(options?: { sceneRadius?: number, distance?: number, focalPoint?: Vec3}) {
const config = this.scene.config;

const bound = this.scene.bound;
const radius = bound.halfExtents.length();
const distance = radius / Math.sin(config.camera.fov * math.DEG_TO_RAD * 0.5);
let focalPoint: Vec3 = options?.focalPoint;
if (!focalPoint) {
this.scene.elements.forEach((element: any) => {
if (!focalPoint && element.type === ElementType.splat) {
focalPoint = element.focalPoint && element.focalPoint();
}
});
}

this.setDistance(1.0, 0);
this.setFocalPoint(focalPoint ?? bound.center, 0);
const sceneRadius = options?.sceneRadius ?? this.scene.bound.halfExtents.length();
const distance = sceneRadius / Math.sin(config.camera.fov * math.DEG_TO_RAD * 0.5);

this.sceneRadius = radius;
this.setDistance(options?.distance ?? 1.0, 0);
this.setFocalPoint(focalPoint ?? this.scene.bound.center, 0);
this.focusDistance = 1.1 * distance;
}

Expand Down
46 changes: 38 additions & 8 deletions src/editor-ops.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ const convertPly = (splatData: SplatData, modelMat: Mat4) => {
const quat = new Quat();
quat.setFromMat4(mat);

const scale = new Vec3();
mat.getScale(scale);

const v = new Vec3();
const q = new Quat();

Expand All @@ -198,6 +201,10 @@ const convertPly = (splatData: SplatData, modelMat: Mat4) => {
const r1_off = props.indexOf('rot_1') * 4;
const r2_off = props.indexOf('rot_2') * 4;
const r3_off = props.indexOf('rot_3') * 4;
const scale0_off = props.indexOf('scale_0') * 4;
const scale1_off = props.indexOf('scale_1') * 4;
const scale2_off = props.indexOf('scale_2') * 4;

for (let i = 0; i < numSplats; ++i) {
const off = header.byteLength + i * props.length * 4;
const x = dataView.getFloat32(off + x_off, true);
Expand All @@ -207,6 +214,9 @@ const convertPly = (splatData: SplatData, modelMat: Mat4) => {
const rot_1 = dataView.getFloat32(off + r1_off, true);
const rot_2 = dataView.getFloat32(off + r2_off, true);
const rot_3 = dataView.getFloat32(off + r3_off, true);
const scale_0 = dataView.getFloat32(off + scale0_off, true);
const scale_1 = dataView.getFloat32(off + scale1_off, true);
const scale_2 = dataView.getFloat32(off + scale2_off, true);

v.set(x, y, z);
mat.transformPoint(v, v);
Expand All @@ -219,6 +229,10 @@ const convertPly = (splatData: SplatData, modelMat: Mat4) => {
dataView.setFloat32(off + r1_off, q.x, true);
dataView.setFloat32(off + r2_off, q.y, true);
dataView.setFloat32(off + r3_off, q.z, true);

dataView.setFloat32(off + scale0_off, Math.log(Math.exp(scale_0) * scale.x), true);
dataView.setFloat32(off + scale1_off, Math.log(Math.exp(scale_1) * scale.x), true);
dataView.setFloat32(off + scale2_off, Math.log(Math.exp(scale_2) * scale.x), true);
}

return result;
Expand Down Expand Up @@ -263,6 +277,9 @@ const convertSplat = (splatData: SplatData, modelMat: Mat4) => {
const v = new Vec3();
const q = new Quat();

const scale = new Vec3();
mat.getScale(scale);

const clamp = (x: number) => Math.max(0, Math.min(255, x));
let idx = 0;

Expand All @@ -277,9 +294,9 @@ const convertSplat = (splatData: SplatData, modelMat: Mat4) => {
dataView.setFloat32(off + 4, v.y, true);
dataView.setFloat32(off + 8, v.z, true);

dataView.setFloat32(off + 12, Math.exp(scale_0[i]), true);
dataView.setFloat32(off + 16, Math.exp(scale_1[i]), true);
dataView.setFloat32(off + 20, Math.exp(scale_2[i]), true);
dataView.setFloat32(off + 12, Math.exp(scale_0[i]) * scale.x, true);
dataView.setFloat32(off + 16, Math.exp(scale_1[i]) * scale.x, true);
dataView.setFloat32(off + 20, Math.exp(scale_2[i]) * scale.x, true);

const SH_C0 = 0.28209479177387814;
dataView.setUint8(off + 24, clamp((0.5 + SH_C0 * f_dc_0[i]) * 255));
Expand Down Expand Up @@ -463,10 +480,14 @@ const registerEvents = (scene: Scene, editorUI: EditorUI) => {
splatData.calcAabb(aabb, selectedSplats ? selectionPred : opacityPred);
splatData.calcFocalPoint(vec, selectedSplats ? selectionPred : opacityPred);

splatDef.element.entity.getWorldTransform().transformPoint(vec, vec);
const worldTransform = splatDef.element.entity.getWorldTransform();
worldTransform.transformPoint(vec, vec);
worldTransform.getScale(vec2);

scene.camera.setFocalPoint(vec);
scene.camera.setDistance(aabb.halfExtents.length() / scene.bound.halfExtents.length());
scene.camera.focus({
focalPoint: vec,
distance: aabb.halfExtents.length() * vec2.x / scene.bound.halfExtents.length()
});
}
});

Expand Down Expand Up @@ -670,8 +691,9 @@ const registerEvents = (scene: Scene, editorUI: EditorUI) => {
mat.transformVec4(vec4, vec4);
vec4.x = vec4.x / vec4.w * 0.5 + 0.5;
vec4.y = -vec4.y / vec4.w * 0.5 + 0.5;
vec4.z = vec4.z / vec4.w * 0.5 + 0.5;

if (vec4.x < 0 || vec4.x > 1 || vec4.y < 0 || vec4.y > 1) {
if (vec4.x < 0 || vec4.x > 1 || vec4.y < 0 || vec4.y > 1 || vec4.z < 0 || vec4.z > 1) {
return false;
}

Expand All @@ -696,14 +718,22 @@ const registerEvents = (scene: Scene, editorUI: EditorUI) => {
scene.updateBound();
});

events.on('sceneOrientation', (value: number[]) => {
events.on('sceneRotation', (value: number[]) => {
splatDefs.forEach((splatDef) => {
splatDef.element.entity.setLocalEulerAngles(value[0], value[1], value[2]);
});

scene.updateBound();
});

events.on('sceneScale', (value: number) => {
splatDefs.forEach((splatDef) => {
splatDef.element.entity.setLocalScale(value, value, value);
});

scene.updateBound();
});

events.on('deleteSelection', () => {
splatDefs.forEach((splatDef) => {
const splatData = splatDef.data;
Expand Down
5 changes: 5 additions & 0 deletions src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ body {
}
}

.pcui-vector-input {
margin-left: 6px;
margin-right: 6px;
}

/* scrollbar styling */
::-webkit-scrollbar {
width: 8px;
Expand Down
28 changes: 26 additions & 2 deletions src/ui/control-panel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ class ControlPanel extends Container {
position.append(positionLabel);
position.append(positionVector);

// orientation
// rotation
const rotation = new Container({
class: 'control-parent'
});
Expand All @@ -597,9 +597,29 @@ class ControlPanel extends Container {
rotation.append(rotationLabel);
rotation.append(rotationVector);

// scale
const scale = new Container({
class: 'control-parent'
});

const scaleLabel = new Label({
class: 'control-label',
text: 'Scale'
});

const scaleInput = new NumericInput({
class: 'control-element-expand',
precision: 4,
value: 1
});

scale.append(scaleLabel);
scale.append(scaleInput);

scenePanel.append(origin);
scenePanel.append(position);
scenePanel.append(rotation);
scenePanel.append(scale);

// import
const importPanel = new Panel({
Expand Down Expand Up @@ -822,7 +842,11 @@ class ControlPanel extends Container {
});

rotationVector.on('change', () => {
this.events.fire('sceneOrientation', rotationVector.value);
this.events.fire('sceneRotation', rotationVector.value);
});

scaleInput.on('change', () => {
this.events.fire('sceneScale', scaleInput.value);
});

deleteSelectionButton.on('click', () => {
Expand Down

0 comments on commit 7fcaa62

Please sign in to comment.