Skip to content

Commit

Permalink
Gizmo example update (#6622)
Browse files Browse the repository at this point in the history
* separated out grid code

* split out selector and disabled deselection on orbiting

* added type for observer set callback

* fixed example page
  • Loading branch information
kpal81xd authored and marklundin committed May 31, 2024
1 parent 9fcc31f commit f73bd44
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 37 deletions.
2 changes: 2 additions & 0 deletions examples/iframe/example.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
body {
margin: 0;
overflow-y: hidden;
background-color: #000;
}

#application-canvas {
width: 100%;
height: 100%;
Expand Down
55 changes: 18 additions & 37 deletions examples/src/examples/misc/gizmos.example.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ if (!(canvas instanceof HTMLCanvasElement)) {

// class for handling gizmo
const { GizmoHandler } = await localImport('gizmo-handler.mjs');
const { Grid } = await localImport('grid.mjs');
const { Selector } = await localImport('selector.mjs');

const gfxOptions = {
deviceTypes: [deviceType],
Expand Down Expand Up @@ -162,14 +164,14 @@ const setType = (/** @type {string} */ value) => {

// call method from top context (same as controls)
// @ts-ignore
window.top.setType(value);
window.top.setType?.(value);
};
const setProj = (/** @type {number} */ value) => {
data.set('camera.proj', value + 1);

// call method from top context (same as controls)
// @ts-ignore
window.top.setProj(value);
window.top.setProj?.(value);
};

// key event handlers
Expand Down Expand Up @@ -209,7 +211,7 @@ window.addEventListener('keypress', keypress);

// gizmo and camera set handler
const tmpC = new pc.Color();
data.on('*:set', (/** @type {string} */ path, value) => {
data.on('*:set', (/** @type {string} */ path, /** @type {any} */ value) => {
const pathArray = path.split('.');

switch (pathArray[0]) {
Expand Down Expand Up @@ -246,55 +248,34 @@ data.on('*:set', (/** @type {string} */ path, value) => {
}
});

// picker
const picker = new pc.Picker(app, canvas.clientWidth, canvas.clientHeight);
const worldLayer = layers.getLayerByName('World');
const pickerLayers = [worldLayer];

const onPointerDown = (/** @type {PointerEvent} */ e) => {
// selector
const selector = new Selector(app, camera.camera, [layers.getLayerByName('World')]);
selector.on('select', (/** @type {pc.GraphNode} */ node, /** @type {boolean} */ clear) => {
if (gizmoHandler.ignorePicker) {
return;
}

if (picker) {
picker.resize(canvas.clientWidth, canvas.clientHeight);
picker.prepare(camera.camera, app.scene, pickerLayers);
}

picker.getSelectionAsync(e.clientX - 1, e.clientY - 1, 2, 2).then((selection) => {
if (!selection[0]) {
gizmoHandler.clear();
return;
}

gizmoHandler.add(selection[0].node, !e.ctrlKey && !e.metaKey);
});
};
window.addEventListener('pointerdown', onPointerDown);
gizmoHandler.add(node, clear);
});
selector.on('deselect', () => {
gizmoHandler.clear();
});

// grid
const gridColor = new pc.Color(1, 1, 1, 0.5);
const gridHalfSize = 4;
/**
* @type {pc.Vec3[]}
*/
const gridLines = [];
for (let i = 0; i < gridHalfSize * 2 + 1; i++) {
gridLines.push(new pc.Vec3(-gridHalfSize, 0, i - gridHalfSize), new pc.Vec3(gridHalfSize, 0, i - gridHalfSize));
gridLines.push(new pc.Vec3(i - gridHalfSize, 0, -gridHalfSize), new pc.Vec3(i - gridHalfSize, 0, gridHalfSize));
}
app.on('update', () => {
app.drawLines(gridLines, gridColor);
const grid = new Grid();

app.on('update', (/** @type {number} */ dt) => {
grid.draw(app);
});

app.on('destroy', () => {
gizmoHandler.destroy();
selector.destroy();

window.removeEventListener('resize', resize);
window.removeEventListener('keydown', keydown);
window.removeEventListener('keyup', keyup);
window.removeEventListener('keypress', keypress);
window.removeEventListener('pointerdown', onPointerDown);
});

export { app };
77 changes: 77 additions & 0 deletions examples/src/examples/misc/gizmos.grid.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import * as pc from 'playcanvas';

class Grid {
/**
* @type {pc.Vec3[]}
* @private
*/
_lines = [];

/**
* @type {pc.Color}
* @private
*/
_color = new pc.Color(1, 1, 1, 0.5);

/**
* @type {pc.Vec2}
* @private
*/
_halfExtents = new pc.Vec2(4, 4);

constructor() {
this._setLines();
}

set halfExtents(value) {
this._halfExtents.copy(value);
this._setLines();
}

get halfExtents() {
return this._halfExtents;
}

set color(value) {
this._color.copy(value);
}

get color() {
return this._color;
}

/**
* @private
*/
_setLines() {
this._lines = [
new pc.Vec3(-this._halfExtents.x, 0, 0),
new pc.Vec3(this._halfExtents.x, 0, 0),
new pc.Vec3(0, 0, -this._halfExtents.y),
new pc.Vec3(0, 0, this._halfExtents.y)
];
for (let i = -this._halfExtents.x; i <= this._halfExtents.x; i++) {
if (i === 0) {
continue;
}
this._lines.push(new pc.Vec3(i, 0, -this._halfExtents.y));
this._lines.push(new pc.Vec3(i, 0, this._halfExtents.y));
}
for (let i = -this._halfExtents.y; i <= this._halfExtents.y; i++) {
if (i === 0) {
continue;
}
this._lines.push(new pc.Vec3(-this._halfExtents.x, 0, i));
this._lines.push(new pc.Vec3(this._halfExtents.x, 0, i));
}
}

/**
* @param {pc.AppBase} app - The app.
*/
draw(app) {
app.drawLines(this._lines, this._color);
}
}

export { Grid };
93 changes: 93 additions & 0 deletions examples/src/examples/misc/gizmos.selector.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import * as pc from 'playcanvas';

class Selector extends pc.EventHandler {
/**
* @type {pc.CameraComponent}
* @private
*/
_camera;

/**
* @type {pc.Scene}
* @private
*/
_scene;

/**
* @type {pc.Picker}
* @private
*/
_picker;

/**
* @type {pc.Layer[]}
* @private
*/
_layers;

/**
* @type {pc.Vec2}
* @private
*/
_start = new pc.Vec2();

/**
* @param {pc.AppBase} app - The app.
* @param {pc.CameraComponent} camera - The camera to pick from.
* @param {pc.Layer[]} [layers] - The layers to pick from.
*/
constructor(app, camera, layers = []) {
super();
this._camera = camera;
this._scene = app.scene;
const device = app.graphicsDevice;
this._picker = new pc.Picker(app, device.canvas.width, device.canvas.height);
this._layers = layers;

this._onPointerDown = this._onPointerDown.bind(this);
this._onPointerUp = this._onPointerUp.bind(this);

window.addEventListener('pointerdown', this._onPointerDown);
window.addEventListener('pointerup', this._onPointerUp);
}

/**
* @param {MouseEvent} e - The event.
* @private
*/
_onPointerDown(e) {
this._start.set(e.clientX, e.clientY);
}

/**
* @param {MouseEvent} e - The event.
* @private
*/
_onPointerUp(e) {
if (e.clientX !== this._start.x || e.clientY !== this._start.y) {
return;
}

if (this._picker) {
const device = this._picker.device;
this._picker.resize(device.canvas.width, device.canvas.height);
this._picker.prepare(this._camera, this._scene, this._layers);
}

const selection = this._picker.getSelection(e.clientX, e.clientY, 2, 2);

if (!selection[0]) {
this.fire('deselect');
return;
}

this.fire('select', selection[0].node, !e.ctrlKey && !e.metaKey);
}

destroy() {
window.removeEventListener('pointerdown', this._onPointerDown);
window.removeEventListener('pointerup', this._onPointerUp);
}
}

export { Selector };

0 comments on commit f73bd44

Please sign in to comment.