Testing things
This commit is contained in:
parent
a70e599c14
commit
b5c30a115d
|
|
@ -4,7 +4,7 @@
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "bunx --bun vite",
|
"dev": "bunx --bun vite --force",
|
||||||
"build": "tsc && vite build",
|
"build": "tsc && vite build",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import * as Three from 'three';
|
||||||
import * as CONST from '../consts';
|
import * as CONST from '../consts';
|
||||||
import { AABB } from '../physics/common';
|
import { AABB } from '../physics/common';
|
||||||
import Quadtree from '../physics/quadtree.class';
|
import Quadtree from '../physics/quadtree.class';
|
||||||
import { FreeList } from '../common';
|
import { FreeList, clamp } from '../common';
|
||||||
|
|
||||||
const _position = new Three.Vector3();
|
const _position = new Three.Vector3();
|
||||||
const _rotation = new Three.Quaternion();
|
const _rotation = new Three.Quaternion();
|
||||||
|
|
@ -23,6 +23,8 @@ export default class Asset
|
||||||
#rot: number;
|
#rot: number;
|
||||||
#scaleX: number;
|
#scaleX: number;
|
||||||
#scaleY: number;
|
#scaleY: number;
|
||||||
|
#shearX: number;
|
||||||
|
#shearY: number;
|
||||||
|
|
||||||
#index: number;
|
#index: number;
|
||||||
#quad?: number;
|
#quad?: number;
|
||||||
|
|
@ -33,14 +35,18 @@ export default class Asset
|
||||||
|
|
||||||
constructor(mat?: Three.Matrix4, layer?: number)
|
constructor(mat?: Three.Matrix4, layer?: number)
|
||||||
{
|
{
|
||||||
|
//TODO: Remake the value computation to include shear determination
|
||||||
this.mat = mat ?? new Three.Matrix4();
|
this.mat = mat ?? new Three.Matrix4();
|
||||||
this.mat.decompose(_position, _rotation, _scale);
|
this.mat.decompose(_position, _rotation, _scale);
|
||||||
|
|
||||||
this.#posX = _position.x;
|
this.#posX = _position.x;
|
||||||
this.#posY = _position.y;
|
this.#posY = _position.y;
|
||||||
this.#rot = _euler.setFromQuaternion(_rotation).z;
|
this.#rot = _euler.setFromQuaternion(_rotation).z;
|
||||||
this.#scaleX = _position.x;
|
this.#scaleX = _scale.x;
|
||||||
this.#scaleY = _position.y;
|
this.#scaleY = _scale.y;
|
||||||
|
|
||||||
|
this.#shearX = 1;
|
||||||
|
this.#shearY = 1;
|
||||||
|
|
||||||
this.#updateAABB();
|
this.#updateAABB();
|
||||||
this.layer = layer ?? 0;
|
this.layer = layer ?? 0;
|
||||||
|
|
@ -101,7 +107,7 @@ export default class Asset
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
update(quad: boolean = true): void
|
update(quad: boolean = true): Asset
|
||||||
{
|
{
|
||||||
this.#updateAABB();
|
this.#updateAABB();
|
||||||
Asset.instance.setMatrixAt(this.#index, this.mat);
|
Asset.instance.setMatrixAt(this.#index, this.mat);
|
||||||
|
|
@ -112,6 +118,8 @@ export default class Asset
|
||||||
this.#quad !== undefined && Asset.quadtree.remove(this.#quad);
|
this.#quad !== undefined && Asset.quadtree.remove(this.#quad);
|
||||||
this.#quad = Asset.quadtree.insert(this.#index, this.#aabb);
|
this.#quad = Asset.quadtree.insert(this.#index, this.#aabb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
moveTo(x: number, y: number): Asset
|
moveTo(x: number, y: number): Asset
|
||||||
{
|
{
|
||||||
|
|
@ -124,10 +132,10 @@ export default class Asset
|
||||||
}
|
}
|
||||||
rotateTo(rad: number): Asset
|
rotateTo(rad: number): Asset
|
||||||
{
|
{
|
||||||
this.#rot = rad;
|
this.#rot = rad % (Math.PI * 2);
|
||||||
|
|
||||||
const e = this.mat.elements;
|
const e = this.mat.elements;
|
||||||
const cos = Math.cos(rad), sin = Math.sin(rad);
|
const cos = Math.cos(rad), sin = Math.sin(rad), tanX = Math.tan(this.#shearX), tanY = Math.tan(this.#shearY);
|
||||||
|
|
||||||
e[0] = cos * this.#scaleX;
|
e[0] = cos * this.#scaleX;
|
||||||
e[1] = -sin * this.#scaleX;
|
e[1] = -sin * this.#scaleX;
|
||||||
|
|
@ -138,6 +146,9 @@ export default class Asset
|
||||||
}
|
}
|
||||||
scaleTo(x: number, y: number): Asset
|
scaleTo(x: number, y: number): Asset
|
||||||
{
|
{
|
||||||
|
x = clamp(x, 0.1, CONST.RESOLUTION_X);
|
||||||
|
y = clamp(y, 0.1, CONST.RESOLUTION_Y);
|
||||||
|
|
||||||
this.#scaleX = x;
|
this.#scaleX = x;
|
||||||
this.#scaleY = y;
|
this.#scaleY = y;
|
||||||
|
|
||||||
|
|
@ -145,10 +156,33 @@ export default class Asset
|
||||||
const cos = Math.cos(this.#rot), sin = Math.sin(this.#rot);
|
const cos = Math.cos(this.#rot), sin = Math.sin(this.#rot);
|
||||||
|
|
||||||
e[0] = cos * this.#scaleX;
|
e[0] = cos * this.#scaleX;
|
||||||
e[1] = -sin * this.#scaleX;
|
e[1] = -sin * this.#shearX;
|
||||||
e[4] = sin * this.#scaleY;
|
e[4] = sin * this.#shearY;
|
||||||
e[5] = cos * this.#scaleY;
|
e[5] = cos * this.#scaleY;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
matchAABB(aabb: AABB): Asset
|
||||||
|
{
|
||||||
|
this.#aabb = aabb;
|
||||||
|
|
||||||
|
this.#scaleX = aabb.x2 - aabb.x1;
|
||||||
|
this.#scaleY = aabb.y2 - aabb.y1;
|
||||||
|
|
||||||
|
this.#posX = aabb.x1 + this.#scaleX / 2;
|
||||||
|
this.#posY = aabb.y1 + this.#scaleY / 2;
|
||||||
|
|
||||||
|
const e = this.mat.elements;
|
||||||
|
const cos = Math.cos(this.#rot), sin = Math.sin(this.#rot);
|
||||||
|
|
||||||
|
e[0] = cos * this.#scaleX;
|
||||||
|
e[1] = -sin * this.#shearX;
|
||||||
|
e[4] = sin * this.#shearY;
|
||||||
|
e[5] = cos * this.#scaleY;
|
||||||
|
|
||||||
|
e[12] = this.#posX;
|
||||||
|
e[13] = this.#posY;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
17
src/main.ts
17
src/main.ts
|
|
@ -1,7 +1,7 @@
|
||||||
import * as THREE from 'three';
|
//import * as THREE from 'three';
|
||||||
import Renderer from './renderer/renderer.class';
|
import Renderer from './renderer/renderer.class';
|
||||||
import Asset from './assets/asset.class';
|
import Asset from './assets/asset.class';
|
||||||
import { RESOLUTION_X, RESOLUTION_Y } from './consts';
|
//import { RESOLUTION_X, RESOLUTION_Y } from './consts';
|
||||||
import Input from './renderer/input.class';
|
import Input from './renderer/input.class';
|
||||||
import { Random, clamp } from './common';
|
import { Random, clamp } from './common';
|
||||||
import Selector from './renderer/selector.class';
|
import Selector from './renderer/selector.class';
|
||||||
|
|
@ -18,13 +18,18 @@ Selector.init();
|
||||||
const r = new Random(0);
|
const r = new Random(0);
|
||||||
let dragMode = DragMode.pan, dragFrom: number | undefined;
|
let dragMode = DragMode.pan, dragFrom: number | undefined;
|
||||||
|
|
||||||
for(let i = 0; i < 10; i++)
|
/*for(let i = 0; i < 10; i++)
|
||||||
{
|
{
|
||||||
new Asset(new THREE.Matrix4(), 1).rotateTo(r.nextFloat(Math.PI * 2))
|
new Asset(new THREE.Matrix4(), 1).rotateTo(r.nextFloat(Math.PI * 2))
|
||||||
.scaleTo(r.nextFloat(10, 30), r.nextFloat(10, 30))
|
.scaleTo(r.nextFloat(10, 30), r.nextFloat(10, 30))
|
||||||
.moveTo(r.nextInt(-0.5 * RESOLUTION_X, 0.5 * RESOLUTION_X), r.nextInt(-0.5 * RESOLUTION_Y, 0.5 * RESOLUTION_Y))
|
.moveTo(r.nextInt(-0.5 * RESOLUTION_X, 0.5 * RESOLUTION_X), r.nextInt(-0.5 * RESOLUTION_Y, 0.5 * RESOLUTION_Y))
|
||||||
.update();
|
.update();
|
||||||
}
|
}*/
|
||||||
|
window.asset = new Asset().moveTo(0, 0).rotateTo(Math.PI / 3).scaleTo(20, 20).update();
|
||||||
|
new Asset().moveTo(40, 0).rotateTo(0).scaleTo(20, 20).update();
|
||||||
|
new Asset().moveTo(-40, 0).rotateTo(0).scaleTo(20, 20).update();
|
||||||
|
|
||||||
|
window.Selector = Selector;
|
||||||
|
|
||||||
Asset.instance.count = Asset.assets.length;
|
Asset.instance.count = Asset.assets.length;
|
||||||
|
|
||||||
|
|
@ -79,6 +84,10 @@ Input.onDrag((delta, start, end, _) => {
|
||||||
{
|
{
|
||||||
Selector.move(delta.x, delta.y);
|
Selector.move(delta.x, delta.y);
|
||||||
}
|
}
|
||||||
|
else if (dragMode === DragMode.rotate && Selector.selected)
|
||||||
|
{
|
||||||
|
Selector.rotate(delta.x, delta.y);
|
||||||
|
}
|
||||||
else if (dragMode === DragMode.scale && Selector.selected)
|
else if (dragMode === DragMode.scale && Selector.selected)
|
||||||
{
|
{
|
||||||
Selector.scale(dragFrom!, delta.x, delta.y);
|
Selector.scale(dragFrom!, delta.x, delta.y);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ export enum CursorType
|
||||||
leftright = "ew-resize",
|
leftright = "ew-resize",
|
||||||
nesw = "nesw-resize",
|
nesw = "nesw-resize",
|
||||||
nwse = "nwse-resize",
|
nwse = "nwse-resize",
|
||||||
|
//rotate = "url(public/rotate.png)"
|
||||||
|
rotate = "crosshair" //tmp
|
||||||
}
|
}
|
||||||
export default class Renderer
|
export default class Renderer
|
||||||
{
|
{
|
||||||
|
|
@ -38,7 +40,7 @@ export default class Renderer
|
||||||
this.camera = new Three.OrthographicCamera();
|
this.camera = new Three.OrthographicCamera();
|
||||||
this.camera.position.z = 500;
|
this.camera.position.z = 500;
|
||||||
|
|
||||||
this.#zoom = 1;
|
this.#zoom = 5;
|
||||||
|
|
||||||
const stats = this.#stats = new Stats();
|
const stats = this.#stats = new Stats();
|
||||||
stats.showPanel(0);
|
stats.showPanel(0);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import * as Three from "three";
|
import * as Three from "three";
|
||||||
import Asset from "../assets/asset.class";
|
import Asset from "../assets/asset.class";
|
||||||
import { Point, intersects, intersectsAsset, sqrtLen } from "../physics/common";
|
import { Point, intersects, sqrtLen } from "../physics/common";
|
||||||
import Renderer, { CursorType } from "./renderer.class";
|
import Renderer, { CursorType } from "./renderer.class";
|
||||||
import { QUAD } from '../consts';
|
import { QUAD } from '../consts';
|
||||||
import { DragMode } from "../main";
|
import { DragMode } from "../main";
|
||||||
|
|
@ -8,10 +8,10 @@ import { DragMode } from "../main";
|
||||||
const _vector = new Three.Vector3();
|
const _vector = new Three.Vector3();
|
||||||
|
|
||||||
const orientation = {
|
const orientation = {
|
||||||
0: { x: -1, y: -1 },
|
0: {neighborX: 2, neighborY: 1, opposite: 3},
|
||||||
1: { x: -1, y: 1 },
|
1: {neighborX: 3, neighborY: 0, opposite: 2},
|
||||||
2: { x: -1, y: 1 },
|
2: {neighborX: 0, neighborY: 3, opposite: 1},
|
||||||
3: { x: -1, y: 1 },
|
3: {neighborX: 1, neighborY: 2, opposite: 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class Selector
|
export default class Selector
|
||||||
|
|
@ -197,6 +197,10 @@ export default class Selector
|
||||||
minY = Selector.#selectionMesh.box.min.y,
|
minY = Selector.#selectionMesh.box.min.y,
|
||||||
maxX = Selector.#selectionMesh.box.max.x,
|
maxX = Selector.#selectionMesh.box.max.x,
|
||||||
maxY = Selector.#selectionMesh.box.max.y;
|
maxY = Selector.#selectionMesh.box.max.y;
|
||||||
|
|
||||||
|
const centerX = minX + (maxX - minX) / 2,
|
||||||
|
centerY = minY + (maxY - minY) / 2,
|
||||||
|
centerLen = sqrtLen(x, y, centerX, centerY);
|
||||||
|
|
||||||
if (sqrtLen(x, y, Selector.gizmoScale[0].position.x, Selector.gizmoScale[0].position.y) <= 500 / Renderer.zoom)
|
if (sqrtLen(x, y, Selector.gizmoScale[0].position.x, Selector.gizmoScale[0].position.y) <= 500 / Renderer.zoom)
|
||||||
{
|
{
|
||||||
|
|
@ -223,6 +227,11 @@ export default class Selector
|
||||||
Renderer.cursor(CursorType.move);
|
Renderer.cursor(CursorType.move);
|
||||||
return { mode: DragMode.move };
|
return { mode: DragMode.move };
|
||||||
}
|
}
|
||||||
|
else if (centerLen <= sqrtLen(centerX, centerY, maxX + (maxX - minX) / 2, centerY))
|
||||||
|
{
|
||||||
|
Renderer.cursor(CursorType.rotate);
|
||||||
|
return { mode: DragMode.rotate };
|
||||||
|
}
|
||||||
|
|
||||||
return { mode: DragMode.select };
|
return { mode: DragMode.select };
|
||||||
}
|
}
|
||||||
|
|
@ -241,25 +250,68 @@ export default class Selector
|
||||||
Selector.gizmoScale[2].position.add({ x: x, y: y, z: 0 });
|
Selector.gizmoScale[2].position.add({ x: x, y: y, z: 0 });
|
||||||
Selector.gizmoScale[3].position.add({ x: x, y: y, z: 0 });
|
Selector.gizmoScale[3].position.add({ x: x, y: y, z: 0 });
|
||||||
}
|
}
|
||||||
static scale(dragFrom: number, x: number, y: number): void
|
static rotate(x: number, y: number): void
|
||||||
{
|
{
|
||||||
console.log(dragFrom, x, y);
|
_vector.set(x, y, 0).normalize()
|
||||||
|
const rad = Math.atan2(-_vector.y, _vector.x);
|
||||||
//@ts-ignore
|
Selector.selection.forEach(e => e.rotateTo(e.rot + rad).update(false));
|
||||||
x *= orientation[dragFrom].x;
|
|
||||||
//@ts-ignore
|
|
||||||
y *= orientation[dragFrom].y;
|
|
||||||
|
|
||||||
Selector.selection.forEach(e => e.scaleTo(e.scaleX + x, e.scaleY + y).moveTo(e.posX - x / 2, e.posY - y / 2).update(false));
|
|
||||||
|
|
||||||
Selector.#selectionMesh.box.translate(_vector.set(-x / 2, -y / 2, 0));
|
|
||||||
|
|
||||||
Selector.gizmoScale[0].position.add({ x: -x / 2, y: -y / 2, z: 0 });
|
|
||||||
Selector.gizmoScale[1].position.add({ x: -x / 2, y: -y / 2, z: 0 });
|
|
||||||
Selector.gizmoScale[2].position.add({ x: -x / 2, y: -y / 2, z: 0 });
|
|
||||||
Selector.gizmoScale[3].position.add({ x: -x / 2, y: -y / 2, z: 0 });
|
|
||||||
|
|
||||||
Asset.instance.computeBoundingBox();
|
Asset.instance.computeBoundingBox();
|
||||||
Asset.instance.computeBoundingSphere();
|
Asset.instance.computeBoundingSphere();
|
||||||
}
|
}
|
||||||
}
|
static scale(dragFrom: number, x: number, y: number): void
|
||||||
|
{
|
||||||
|
//@ts-ignore
|
||||||
|
const o = orientation[dragFrom];
|
||||||
|
|
||||||
|
Selector.gizmoScale[dragFrom].position.add({ x: x, y: y, z: 0 });
|
||||||
|
Selector.gizmoScale[o.neighborX].position.add({ x: x, y: 0, z: 0 });
|
||||||
|
Selector.gizmoScale[o.neighborY].position.add({ x: 0, y: y, z: 0 });
|
||||||
|
|
||||||
|
Selector.selection.forEach(e => {
|
||||||
|
//DEBUG ONLY, IT IS NOT CORRECT
|
||||||
|
const aabb = { x1: Selector.gizmoScale[0].position.x, y1: Selector.gizmoScale[0].position.y, x2: Selector.gizmoScale[3].position.x, y2: Selector.gizmoScale[3].position.y }
|
||||||
|
e.matchAABB(aabb).update(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
Asset.instance.computeBoundingBox();
|
||||||
|
Asset.instance.computeBoundingSphere();
|
||||||
|
|
||||||
|
Selector.#selectionMesh.box.setFromPoints([Selector.gizmoScale[0].position, Selector.gizmoScale[3].position]);
|
||||||
|
Selector.#ghostMesh.box.setFromPoints([Selector.gizmoScale[0].position, Selector.gizmoScale[3].position]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
const o = orientation[dragFrom];
|
||||||
|
|
||||||
|
const sizeX = Selector.gizmoScale[3].position.x - Selector.gizmoScale[0].position.x,
|
||||||
|
sizeY = Selector.gizmoScale[3].position.y - Selector.gizmoScale[0].position.y;
|
||||||
|
|
||||||
|
const centerX = Selector.gizmoScale[0].position.x + sizeX / 2,
|
||||||
|
centerY = Selector.gizmoScale[0].position.y + sizeY / 2;
|
||||||
|
|
||||||
|
Selector.selection.forEach(e => {
|
||||||
|
const scaleX = (e.aabb.x2 - e.aabb.x1) / sizeX, scaleY = (e.aabb.y2 - e.aabb.y1) / sizeY;
|
||||||
|
const moveX = (e.posX - centerX) / sizeX, moveY = (e.posY - centerY) / sizeY;
|
||||||
|
|
||||||
|
const cos = Math.abs(Math.cos(e.rot)), sin = Math.abs(Math.sin(e.rot));
|
||||||
|
const localX = x * cos + y * -sin, localY = x * -sin + y * cos;
|
||||||
|
|
||||||
|
e.scaleTo(e.scaleX + localX * scaleX, e.scaleY + localY * scaleY).moveTo(e.posX + x / 2 + x * moveX, e.posY + y / 2 + y * moveY).update(false)
|
||||||
|
});
|
||||||
|
|
||||||
|
Asset.instance.computeBoundingBox();
|
||||||
|
Asset.instance.computeBoundingSphere();
|
||||||
|
|
||||||
|
Selector.gizmoScale[dragFrom].position.add({ x: x, y: y, z: 0 });
|
||||||
|
Selector.gizmoScale[o.neighborX].position.add({ x: x, y: 0, z: 0 });
|
||||||
|
Selector.gizmoScale[o.neighborY].position.add({ x: 0, y: y, z: 0 });
|
||||||
|
|
||||||
|
Selector.#selectionMesh.box.setFromPoints([Selector.gizmoScale[0].position, Selector.gizmoScale[3].position]);
|
||||||
|
Selector.#ghostMesh.box.setFromPoints([Selector.gizmoScale[0].position, Selector.gizmoScale[3].position]);
|
||||||
|
|
||||||
|
*/
|
||||||
Loading…
Reference in New Issue