Skip to content

Commit

Permalink
Add transform gizmos (#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
slimbuck authored Jan 31, 2024
1 parent 92a1638 commit e590e1e
Show file tree
Hide file tree
Showing 35 changed files with 1,144 additions and 3,052 deletions.
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "super-splat",
"version": "0.13.0",
"version": "0.14.0",
"author": "PlayCanvas<support@playcanvas.com>",
"homepage": "https://playcanvas.com/super-splat",
"description": "All the splat things",
Expand Down Expand Up @@ -67,7 +67,7 @@
"cross-env": "^7.0.3",
"eslint": "^8.43.0",
"jest": "^29.5.0",
"playcanvas": "^1.67.3",
"playcanvas": "^1.68.0",
"rollup": "^3.25.1",
"rollup-plugin-sass": "^1.12.21",
"rollup-plugin-visualizer": "^5.9.2",
Expand Down
14 changes: 0 additions & 14 deletions rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ const pipeline = (input) => {
{src: 'src/manifest.json'},
{src: 'static/images', dest: 'static'},
{src: 'static/icons', dest: 'static'},
{src: 'static/lib/draco_decoder.wasm', dest: 'static/lib'},
{src: 'static/env/VertebraeHDRI_v1_512.png', dest: 'static/env'}
]
}),
Expand Down Expand Up @@ -89,18 +88,5 @@ const pipeline = (input) => {
};

export default [
{
input: 'static/lib/draco_decoder.js',
output: {
file: 'dist/static/lib/draco_decoder.js'
},
plugins: [
terser({
mangle: {
reserved: ['DracoDecoderModule']
}
})
]
},
pipeline('src/index.ts'),
];
86 changes: 55 additions & 31 deletions src/asset-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,40 +36,64 @@ class AssetLoader {
return new Promise<Model|Splat>((resolve, reject) => {
const isPly = loadRequest.filename?.endsWith('.ply');

const containerAsset = new Asset(
loadRequest.filename || loadRequest.url,
'container',
{
url: loadRequest.url,
filename: loadRequest.filename,
contents: loadRequest.contents
},
isPly ? {
elementFilter: this.loadAllData ? (() => true) : null
} : null,
{
image: {
postprocess: (gltfImage: any, textureAsset: Asset) => {
textureAsset.resource.anisotropy = loadRequest.maxAnisotropy || this.defaultAnisotropy;
if (isPly) {
const asset = new Asset(
loadRequest.filename || loadRequest.url,
'gsplat',
{
url: loadRequest.url,
filename: loadRequest.filename,
contents: loadRequest.contents
},
{ elementFilter: this.loadAllData ? (() => true) : null }
);
asset.on('load', () => {
stopSpinner();
resolve(new Splat(asset));
});
asset.on('error', (err: string) => {
stopSpinner();
reject(err);
});

registry.add(asset);
registry.load(asset);
} else {
const containerAsset = new Asset(
loadRequest.filename || loadRequest.url,
'container',
{
url: loadRequest.url,
filename: loadRequest.filename,
contents: loadRequest.contents
},
isPly ? {
elementFilter: this.loadAllData ? (() => true) : null
} : null,
{
image: {
postprocess: (gltfImage: any, textureAsset: Asset) => {
textureAsset.resource.anisotropy = loadRequest.maxAnisotropy || this.defaultAnisotropy;
}
}
} as any
);
containerAsset.on('load', () => {
stopSpinner();
if (isPly) {
resolve(new Splat(containerAsset));
} else {
resolve(new Model(containerAsset));
}
} as any
);
containerAsset.on('load', () => {
stopSpinner();
if (isPly) {
resolve(new Splat(containerAsset));
} else {
resolve(new Model(containerAsset));
}
});
containerAsset.on('error', (err: string) => {
stopSpinner();
reject(err);
});
});
containerAsset.on('error', (err: string) => {
stopSpinner();
reject(err);
});

registry.add(containerAsset);
registry.load(containerAsset);
registry.add(containerAsset);
registry.load(containerAsset);
}
});
}

Expand Down
6 changes: 5 additions & 1 deletion src/camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,11 @@ class Camera extends Element {

add() {
this.scene.cameraRoot.addChild(this.entity);
this.entity.camera.layers = this.entity.camera.layers.concat([this.scene.shadowLayer.id]);
this.entity.camera.layers = this.entity.camera.layers.concat([
this.scene.shadowLayer.id,
this.scene.debugLayer.id,
this.scene.gizmoLayer.id
]);

if (this.scene.config.camera.debug_render) {
this.entity.camera.setShaderPass(`debug_${this.scene.config.camera.debug_render}`);
Expand Down
98 changes: 90 additions & 8 deletions src/debug.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,97 @@
class Debug {
static exec(func: () => void) {
func();
import {
BLEND_NONE,
SEMANTIC_COLOR,
SEMANTIC_POSITION,
createShaderFromCode,
GraphNode,
Material,
Mesh,
MeshInstance,
Shader,
} from 'playcanvas';
import { Element, ElementType } from './element';

const vertexShader = `
attribute vec3 vertex_position;
attribute vec4 vertex_color;
varying vec4 vColor;
varying vec2 vZW;
uniform mat4 matrix_model;
uniform mat4 matrix_viewProjection;
void main(void) {
gl_Position = matrix_viewProjection * matrix_model * vec4(vertex_position, 1.0);
// store z/w for later use in fragment shader
vColor = vertex_color;
vZW = gl_Position.zw;
// disable depth clipping
gl_Position.z = 0.0;
}`;

const fragmentShader = `
precision highp float;
varying vec4 vColor;
varying vec2 vZW;
void main(void) {
gl_FragColor = vColor;
// clamp depth in Z to [0, 1] range
gl_FragDepth = max(0.0, min(1.0, (vZW.x / vZW.y + 1.0) * 0.5));
}`;

class Debug extends Element {
shader: Shader;
material: Material;
instance: MeshInstance;

constructor() {
super(ElementType.debug);
}

destroy() {
this.shader.destroy();
this.material.destroy();
}

static time(label: string) {
console.time(label);
add() {
const app = this.scene.app;
const device = app.graphicsDevice;

this.shader = createShaderFromCode(device, vertexShader, fragmentShader, 'debug-lines', {
vertex_position: SEMANTIC_POSITION,
vertex_color: SEMANTIC_COLOR
});

this.material = new Material();
this.material.shader = this.shader;
this.material.blendType = BLEND_NONE;
this.material.update();
}

remove() {

}

set mesh(mesh: Mesh) {
if (this.instance) {
this.scene.debugLayer.removeMeshInstances([this.instance], true);
}

this.instance = new MeshInstance(mesh, this.material, new GraphNode());
this.instance.cull = false;
// this.instance.visible = true;
this.scene.debugLayer.addMeshInstances([this.instance], true);
}

static timeEnd(label: string) {
console.timeEnd(label);
get mesh() {
return this.instance?.mesh;
}
}

export {Debug};
export { Debug };
28 changes: 28 additions & 0 deletions src/edit-history.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Events } from './events';

interface EditOp {
name: string;
do(): void;
Expand All @@ -8,6 +10,25 @@ interface EditOp {
class EditHistory {
history: EditOp[] = [];
cursor = 0;
events: Events;

constructor(events: Events) {
this.events = events;

events.on('edit:undo', () => {
if (this.canUndo()) {
this.undo();
events.fire('edit:changed');
}
});

events.on('edit:redo', () => {
if (this.canRedo()) {
this.redo();
events.fire('edit:changed');
}
});
}

add(editOp: EditOp) {
while (this.cursor < this.history.length) {
Expand All @@ -27,10 +48,17 @@ class EditHistory {

undo() {
this.history[--this.cursor].undo();
this.fireEvents();
}

redo() {
this.history[this.cursor++].do();
this.fireEvents();
}

fireEvents() {
this.events.fire('edit:canUndo', this.canUndo());
this.events.fire('edit:canRedo', this.canRedo());
}
}

Expand Down
Loading

0 comments on commit e590e1e

Please sign in to comment.