Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gizmo cleanup and bug fixes #6323

Merged
merged 35 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
2648c55
WIP: reworking calcPoint code
kpal81xd Apr 22, 2024
78c1bb7
Merge branch 'main' into gizmo-refactor
kpal81xd Apr 24, 2024
d4d6679
fixed ray and plane intersection direction issue
kpal81xd Apr 24, 2024
edced0b
WIP calcPoint cleanup for gizmo
kpal81xd Apr 25, 2024
3646d3c
Merge branch 'main' into gizmo-refactor
kpal81xd Apr 29, 2024
cd65cfc
split up different point calculatoin into branches in calcPoint
kpal81xd Apr 29, 2024
135046a
removed unused point rotation code
kpal81xd Apr 29, 2024
9d572b2
extracted scale and rotation calcPoint into their own classes
kpal81xd Apr 29, 2024
e20ef57
removed excess tmp vector
kpal81xd Apr 29, 2024
27f7f4d
extracted out project to line code
kpal81xd Apr 29, 2024
437bbc7
updated normal calc code
kpal81xd Apr 30, 2024
7ce0f8c
cleaned up rotation facing calculation
kpal81xd Apr 30, 2024
6626206
updated lighting in example
kpal81xd Apr 30, 2024
276458a
updated facing epsilon to threshold
kpal81xd Apr 30, 2024
84f95f6
modified base class calcPoint
kpal81xd Apr 30, 2024
ba8b198
fixed gizmo local rotation when orthographic
kpal81xd Apr 30, 2024
e4517c4
removed unused variables in gizmo-transform and renamed internal prop…
kpal81xd Apr 30, 2024
37c8cb2
Merge branch 'main' into gizmo-refactor
kpal81xd Apr 30, 2024
31c4a0f
made sure to update mesh materials with new colorAlpha
kpal81xd Apr 30, 2024
89de99d
renamed calcPoint
kpal81xd Apr 30, 2024
f34e67a
reused same ray and plane objects for _screenToPoint
kpal81xd Apr 30, 2024
4dae3f1
removed extra variables created
kpal81xd Apr 30, 2024
398d8ff
added instruction keybinds and maintained coordspace when switching g…
kpal81xd Apr 30, 2024
ed2d246
Merge branch 'main' into gizmo-refactor
kpal81xd Apr 30, 2024
baa9661
extracted triangles directly from geometry
kpal81xd Apr 30, 2024
0579264
moved tris generation to inside geometry
kpal81xd Apr 30, 2024
a536d8c
Update src/extras/gizmo/rotate-gizmo.js
kpal81xd Apr 30, 2024
95c8974
Merge branch 'main' into gizmo-refactor
kpal81xd Apr 30, 2024
fb4aad3
cleaned up comments and variables
kpal81xd Apr 30, 2024
93a9627
space refactor
kpal81xd Apr 30, 2024
1381fb5
Merge branch 'main' into gizmo-refactor
kpal81xd Apr 30, 2024
27800e2
moved calculateTris back into tri data class
kpal81xd Apr 30, 2024
682ff15
fixed linting issue
kpal81xd Apr 30, 2024
7d7f717
fixed scale invariant for gizmo and set device maxPixelRatio
kpal81xd Apr 30, 2024
7daf52f
removed unused code
kpal81xd Apr 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 41 additions & 24 deletions examples/src/examples/misc/gizmos/example.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class GizmoHandler {
/**
* Object to reference each gizmo.
*
* @type {Record<string, pc.Gizmo>}
* @type {Record<string, pc.TransformGizmo>}
* @private
*/
_gizmos;
Expand Down Expand Up @@ -91,6 +91,7 @@ class GizmoHandler {
* @param {string} type - The transform gizmo type.
*/
_updateData(type) {
/** @type {any} */
const gizmo = this.gizmo;
this._skipSetFire = true;
data.set('gizmo', {
Expand Down Expand Up @@ -153,8 +154,10 @@ class GizmoHandler {
*/
switch(type) {
this.gizmo.detach();
const coordSpace = this.gizmo.coordSpace;
this._type = type ?? 'translate';
this.gizmo.attach(this._nodes);
this.gizmo.coordSpace = coordSpace;
this._updateData(type);
}

Expand All @@ -181,9 +184,11 @@ createOptions.componentSystems = [
pc.RenderComponentSystem,
pc.CameraComponentSystem,
pc.LightComponentSystem,
pc.ScriptComponentSystem
pc.ScriptComponentSystem,
pc.ScreenComponentSystem,
pc.ElementComponentSystem
];
createOptions.resourceHandlers = [pc.TextureHandler, pc.ContainerHandler, pc.ScriptHandler];
createOptions.resourceHandlers = [pc.TextureHandler, pc.ContainerHandler, pc.ScriptHandler, pc.FontHandler];

const app = new pc.AppBase(canvas);
app.init(createOptions);
Expand All @@ -198,7 +203,8 @@ window.addEventListener('resize', resize);

// load assets
const assets = {
script: new pc.Asset('script', 'script', { url: rootPath + '/static/scripts/camera/orbit-camera.js' })
script: new pc.Asset('script', 'script', { url: rootPath + '/static/scripts/camera/orbit-camera.js' }),
font: new pc.Asset('font', 'font', { url: rootPath + '/static/assets/fonts/courier.json' })
};
/**
* @param {pc.Asset[] | number[]} assetList - The asset list.
Expand All @@ -214,7 +220,6 @@ function loadAssets(assetList, assetRegistry) {
await loadAssets(Object.values(assets), app.assets);

app.start();

/**
* @param {pc.Color} color - The color.
* @returns {pc.Material} - The standard material.
Expand All @@ -226,6 +231,32 @@ function createColorMaterial(color) {
return material;
}

// scene settings
app.scene.ambientLight = new pc.Color(0.2, 0.2, 0.2);

// create screen
const screen = new pc.Entity('screen');
screen.addComponent('screen', {
referenceResolution: new pc.Vec2(1280, 720),
scaleBlend: 0.5,
scaleMode: pc.SCALEMODE_BLEND,
screenSpace: true
});
app.root.addChild(screen);

const instr = new pc.Entity('instructions');
instr.setLocalPosition(0, 200, 0);
instr.addComponent('element', {
pivot: new pc.Vec2(0.5, 0.5),
anchor: new pc.Vec4(0, 1, 1, 0.8),
margin: new pc.Vec4(0, 0, 0, 0),
fontAsset: assets.font.id,
fontSize: 18,
text: 'Translate (1), Rotate (2), Scale (3)\nWorld/Local (X)\nPerspective (P), Orthographic (O)',
type: pc.ELEMENTTYPE_TEXT
});
screen.addChild(instr);
kpal81xd marked this conversation as resolved.
Show resolved Hide resolved

// create entities
const box = new pc.Entity('box');
box.addComponent('render', {
Expand Down Expand Up @@ -279,27 +310,13 @@ camera.setPosition(1, 1, 1);
app.root.addChild(camera);
orbitCamera.distance = 14;

// create 3-point lighting
const backLight = new pc.Entity('light');
backLight.addComponent('light', {
intensity: 0.5
});
app.root.addChild(backLight);
backLight.setEulerAngles(-60, 0, 90);

const fillLight = new pc.Entity('light');
fillLight.addComponent('light', {
intensity: 0.5
});
app.root.addChild(fillLight);
fillLight.setEulerAngles(45, 0, 0);

const keyLight = new pc.Entity('light');
keyLight.addComponent('light', {
// create light entity
const light = new pc.Entity('light');
light.addComponent('light', {
intensity: 1
});
app.root.addChild(keyLight);
keyLight.setEulerAngles(0, 0, -60);
app.root.addChild(light);
light.setEulerAngles(0, 0, -60);

// create layers
const gizmoLayer = new pc.Layer({
Expand Down
73 changes: 41 additions & 32 deletions src/extras/gizmo/axis-shapes.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { BLEND_NORMAL } from '../../scene/constants.js';
import { createShaderFromCode } from '../../scene/shader-lib/utils.js';

import { COLOR_GRAY } from './default-colors.js';
import { MeshTriData } from './mesh-tri-data.js';
import { TriData } from './tri-data.js';
import { Mesh } from '../../scene/mesh.js';
import { BoxGeometry } from '../../scene/geometry/box-geometry.js';
import { CylinderGeometry } from '../../scene/geometry/cylinder-geometry.js';
Expand All @@ -21,16 +21,20 @@ import { TorusGeometry } from '../../scene/geometry/torus-geometry.js';
const SHADOW_DAMP_SCALE = 0.25;
const SHADOW_DAMP_OFFSET = 0.75;
const SHADOW_MESH_MAP = new Map();

const TORUS_RENDER_SEGMENTS = 80;
const TORUS_INTERSECT_SEGMENTS = 20;

const LIGHT_DIR = new Vec3(1, 2, 3);
const MESH_TEMPLATES = {

const GEOMETRIES = {
box: BoxGeometry,
cone: ConeGeometry,
cylinder: CylinderGeometry,
plane: PlaneGeometry,
torus: TorusGeometry
};

const SHADER = {
vert: /* glsl */`
attribute vec3 vertex_position;
Expand Down Expand Up @@ -68,12 +72,12 @@ const tmpV2 = new Vec3();
const tmpQ1 = new Quat();

function createShadowMesh(device, entity, type, color = Color.WHITE, templateOpts) {
const geomTemplate = MESH_TEMPLATES[type];
if (!geomTemplate) {
const Geometry = GEOMETRIES[type];
if (!Geometry) {
throw new Error('Invalid primitive type.');
}

const geom = new geomTemplate(templateOpts);
const geom = new Geometry(templateOpts);
geom.colors = [];

const wtm = entity.getWorldTransform().clone().invert();
Expand All @@ -83,7 +87,12 @@ function createShadowMesh(device, entity, type, color = Color.WHITE, templateOpt
const numVertices = geom.positions.length / 3;
const shadow = calculateShadow(tmpV1, numVertices, geom.normals);
for (let i = 0; i < shadow.length; i++) {
geom.colors.push(shadow[i] * color.r * 255, shadow[i] * color.g * 255, shadow[i] * color.b * 255, color.a * 255);
geom.colors.push(
shadow[i] * color.r * 0xFF,
shadow[i] * color.g * 0xFF,
shadow[i] * color.b * 0xFF,
color.a * 0xFF
);
}

const shadowMesh = Mesh.fromGeometry(device, geom);
Expand Down Expand Up @@ -145,7 +154,7 @@ class AxisShape {

entity;

meshTriDataList = [];
triData = [];

meshInstances = [];

Expand Down Expand Up @@ -256,9 +265,9 @@ class AxisArrow extends AxisShape {
constructor(device, options = {}) {
super(device, options);

this.meshTriDataList = [
new MeshTriData(Mesh.fromGeometry(this.device, new ConeGeometry())),
new MeshTriData(Mesh.fromGeometry(this.device, new CylinderGeometry()), 1)
this.triData = [
new TriData(new ConeGeometry()),
new TriData(new CylinderGeometry(), 1)
];

this._createArrow();
Expand Down Expand Up @@ -342,7 +351,7 @@ class AxisArrow extends AxisShape {
tmpV1.set(0, this._gap + this._arrowLength * 0.5 + this._lineLength, 0);
tmpQ1.set(0, 0, 0, 1);
tmpV2.set(this._arrowThickness, this._arrowLength, this._arrowThickness);
this.meshTriDataList[0].setTransform(tmpV1, tmpQ1, tmpV2);
this.triData[0].setTransform(tmpV1, tmpQ1, tmpV2);

this._head.setLocalPosition(0, this._gap + this._arrowLength * 0.5 + this._lineLength, 0);
this._head.setLocalScale(this._arrowThickness, this._arrowLength, this._arrowThickness);
Expand All @@ -353,7 +362,7 @@ class AxisArrow extends AxisShape {
tmpV1.set(0, this._gap + this._lineLength * 0.5, 0);
tmpQ1.set(0, 0, 0, 1);
tmpV2.set(this._lineThickness + this._tolerance, this._lineLength, this._lineThickness + this._tolerance);
this.meshTriDataList[1].setTransform(tmpV1, tmpQ1, tmpV2);
this.triData[1].setTransform(tmpV1, tmpQ1, tmpV2);

// render
this._line.setLocalPosition(0, this._gap + this._lineLength * 0.5, 0);
Expand All @@ -369,8 +378,8 @@ class AxisBoxCenter extends AxisShape {
constructor(device, options = {}) {
super(device, options);

this.meshTriDataList = [
new MeshTriData(Mesh.fromGeometry(this.device, new BoxGeometry()), 2)
this.triData = [
new TriData(new BoxGeometry(), 2)
];

this._createCenter();
Expand Down Expand Up @@ -422,9 +431,9 @@ class AxisBoxLine extends AxisShape {
constructor(device, options = {}) {
super(device, options);

this.meshTriDataList = [
new MeshTriData(Mesh.fromGeometry(this.device, new BoxGeometry())),
new MeshTriData(Mesh.fromGeometry(this.device, new CylinderGeometry()), 1)
this.triData = [
new TriData(new BoxGeometry()),
new TriData(new CylinderGeometry(), 1)
];

this._createBoxLine();
Expand Down Expand Up @@ -500,7 +509,7 @@ class AxisBoxLine extends AxisShape {
tmpV1.set(0, this._gap + this._boxSize * 0.5 + this._lineLength, 0);
tmpQ1.set(0, 0, 0, 1);
tmpV2.set(this._boxSize, this._boxSize, this._boxSize);
this.meshTriDataList[0].setTransform(tmpV1, tmpQ1, tmpV2);
this.triData[0].setTransform(tmpV1, tmpQ1, tmpV2);

// render
this._box.setLocalPosition(0, this._gap + this._boxSize * 0.5 + this._lineLength, 0);
Expand All @@ -512,7 +521,7 @@ class AxisBoxLine extends AxisShape {
tmpV1.set(0, this._gap + this._lineLength * 0.5, 0);
tmpQ1.set(0, 0, 0, 1);
tmpV2.set(this._lineThickness + this._tolerance, this._lineLength, this._lineThickness + this._tolerance);
this.meshTriDataList[1].setTransform(tmpV1, tmpQ1, tmpV2);
this.triData[1].setTransform(tmpV1, tmpQ1, tmpV2);

// render
this._line.setLocalPosition(0, this._gap + this._lineLength * 0.5, 0);
Expand All @@ -538,23 +547,23 @@ class AxisDisk extends AxisShape {
this._ringRadius = options.ringRadius ?? this._ringRadius;
this._sectorAngle = options.sectorAngle ?? this._sectorAngle;

this.meshTriDataList = [
new MeshTriData(this._createIntersectTorus())
this.triData = [
new TriData(this._createTorusGeometry())
];

this._createDisk();
}

_createIntersectTorus() {
return Mesh.fromGeometry(this.device, new TorusGeometry({
_createTorusGeometry() {
return new TorusGeometry({
tubeRadius: this._tubeRadius + this._tolerance,
ringRadius: this._ringRadius,
sectorAngle: this._sectorAngle,
segments: TORUS_INTERSECT_SEGMENTS
}));
});
}

_createRenderTorus(sectorAngle) {
_createTorusMesh(sectorAngle) {
const color = this._disabled ? this._disabledColor : this._defaultColor;
return createShadowMesh(this.device, this.entity, 'torus', color, {
tubeRadius: this._tubeRadius,
Expand All @@ -569,8 +578,8 @@ class AxisDisk extends AxisShape {

// arc/circle
this._addRenderMeshes(this.entity, [
this._createRenderTorus(this._sectorAngle),
this._createRenderTorus(360)
this._createTorusMesh(this._sectorAngle),
this._createTorusMesh(360)
]);
this.drag(false);
}
Expand Down Expand Up @@ -604,11 +613,11 @@ class AxisDisk extends AxisShape {

_updateTransform() {
// intersect
this.meshTriDataList[0].setTris(this._createIntersectTorus());
this.triData[0].fromGeometry(this._createTorusGeometry());

// render
this.meshInstances[0].mesh = this._createRenderTorus(this._sectorAngle);
this.meshInstances[1].mesh = this._createRenderTorus(360);
this.meshInstances[0].mesh = this._createTorusMesh(this._sectorAngle);
this.meshInstances[1].mesh = this._createTorusMesh(360);
}

drag(state) {
Expand Down Expand Up @@ -637,8 +646,8 @@ class AxisPlane extends AxisShape {
constructor(device, options = {}) {
super(device, options);

this.meshTriDataList = [
new MeshTriData(Mesh.fromGeometry(this.device, new PlaneGeometry()))
this.triData = [
new TriData(new PlaneGeometry())
];

this._createPlane();
Expand Down
27 changes: 11 additions & 16 deletions src/extras/gizmo/gizmo.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@
const tmpV1 = new Vec3();
const tmpM1 = new Mat4();
const tmpM2 = new Mat4();

const xstart = new Vec3();
const xdir = new Vec3();

const ray = new Ray();
const tmpR1 = new Ray();

// constants
const MIN_GIZMO_SCALE = 1e-4;
Expand Down Expand Up @@ -224,8 +220,7 @@

/**
* @typedef IntersectData
* @property {import('./mesh-tri-data.js').MeshTriData[]} meshTriDataList -
* The array of {@link MeshTriData}
* @property {import('./tri-data.js').TriData[]} triData - The array of {@link TriData}
* @property {import('../../scene/graph-node.js').GraphNode} parent - The mesh parent node.
* @property {import('../../scene/mesh-instance.js').MeshInstance[]} meshInstances -
* array of mesh instances for rendering
Expand All @@ -241,7 +236,8 @@
* Creates a new Gizmo object.
*
* @param {import('../../framework/app-base.js').AppBase} app - The application instance.
* @param {import('../../framework/components/camera/component.js').CameraComponent} camera - The camera component.
* @param {import('../../framework/components/camera/component.js').CameraComponent} camera -

Check failure on line 239 in src/extras/gizmo/gizmo.js

View workflow job for this annotation

GitHub Actions / Lint

Trailing spaces not allowed
* The camera component.
* @param {import('../../scene/layer.js').Layer} layer - The render layer.
* @example
* const gizmo = new pc.Gizmo(app, camera, layer);
Expand Down Expand Up @@ -385,19 +381,18 @@

const selection = [];
for (let i = 0; i < this.intersectData.length; i++) {
const { meshTriDataList, parent, meshInstances } = this.intersectData[i];
const { triData, parent, meshInstances } = this.intersectData[i];
const wtm = parent.getWorldTransform().clone();
for (let j = 0; j < meshTriDataList.length; j++) {
const { tris, ptm, priority } = meshTriDataList[j];
for (let j = 0; j < triData.length; j++) {
const { tris, ptm, priority } = triData[j];
tmpM1.copy(wtm).mul(ptm);
tmpM2.copy(tmpM1).invert();
tmpM2.transformPoint(start, xstart);
tmpM2.transformVector(dir, xdir);
xdir.normalize();
tmpM2.transformPoint(start, tmpR1.origin);
tmpM2.transformVector(dir, tmpR1.direction);
tmpR1.direction.normalize();

for (let k = 0; k < tris.length; k++) {
ray.set(xstart, xdir);
if (tris[k].intersectsRay(ray, tmpV1)) {
if (tris[k].intersectsRay(tmpR1, tmpV1)) {
selection.push({
dist: tmpM1.transformPoint(tmpV1).sub(start).length(),
meshInstances: meshInstances,
Expand Down
Loading
Loading