Testing things

This commit is contained in:
Peaceultime 2024-06-17 17:58:44 +02:00
parent a70e599c14
commit b5c30a115d
5 changed files with 133 additions and 36 deletions

View File

@ -4,7 +4,7 @@
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "bunx --bun vite",
"dev": "bunx --bun vite --force",
"build": "tsc && vite build",
"preview": "vite preview"
},

View File

@ -2,7 +2,7 @@ import * as Three from 'three';
import * as CONST from '../consts';
import { AABB } from '../physics/common';
import Quadtree from '../physics/quadtree.class';
import { FreeList } from '../common';
import { FreeList, clamp } from '../common';
const _position = new Three.Vector3();
const _rotation = new Three.Quaternion();
@ -23,6 +23,8 @@ export default class Asset
#rot: number;
#scaleX: number;
#scaleY: number;
#shearX: number;
#shearY: number;
#index: number;
#quad?: number;
@ -33,14 +35,18 @@ export default class Asset
constructor(mat?: Three.Matrix4, layer?: number)
{
//TODO: Remake the value computation to include shear determination
this.mat = mat ?? new Three.Matrix4();
this.mat.decompose(_position, _rotation, _scale);
this.#posX = _position.x;
this.#posY = _position.y;
this.#rot = _euler.setFromQuaternion(_rotation).z;
this.#scaleX = _position.x;
this.#scaleY = _position.y;
this.#scaleX = _scale.x;
this.#scaleY = _scale.y;
this.#shearX = 1;
this.#shearY = 1;
this.#updateAABB();
this.layer = layer ?? 0;
@ -101,7 +107,7 @@ export default class Asset
return this;
}
update(quad: boolean = true): void
update(quad: boolean = true): Asset
{
this.#updateAABB();
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 = Asset.quadtree.insert(this.#index, this.#aabb);
}
return this;
}
moveTo(x: number, y: number): Asset
{
@ -124,10 +132,10 @@ export default class Asset
}
rotateTo(rad: number): Asset
{
this.#rot = rad;
this.#rot = rad % (Math.PI * 2);
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[1] = -sin * this.#scaleX;
@ -138,6 +146,9 @@ export default class 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.#scaleY = y;
@ -145,10 +156,33 @@ export default class Asset
const cos = Math.cos(this.#rot), sin = Math.sin(this.#rot);
e[0] = cos * this.#scaleX;
e[1] = -sin * this.#scaleX;
e[4] = sin * this.#scaleY;
e[1] = -sin * this.#shearX;
e[4] = sin * this.#shearY;
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;
}
}

View File

@ -1,7 +1,7 @@
import * as THREE from 'three';
//import * as THREE from 'three';
import Renderer from './renderer/renderer.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 { Random, clamp } from './common';
import Selector from './renderer/selector.class';
@ -18,13 +18,18 @@ Selector.init();
const r = new Random(0);
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))
.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))
.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;
@ -79,6 +84,10 @@ Input.onDrag((delta, start, end, _) => {
{
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)
{
Selector.scale(dragFrom!, delta.x, delta.y);

View File

@ -14,6 +14,8 @@ export enum CursorType
leftright = "ew-resize",
nesw = "nesw-resize",
nwse = "nwse-resize",
//rotate = "url(public/rotate.png)"
rotate = "crosshair" //tmp
}
export default class Renderer
{
@ -38,7 +40,7 @@ export default class Renderer
this.camera = new Three.OrthographicCamera();
this.camera.position.z = 500;
this.#zoom = 1;
this.#zoom = 5;
const stats = this.#stats = new Stats();
stats.showPanel(0);

View File

@ -1,6 +1,6 @@
import * as Three from "three";
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 { QUAD } from '../consts';
import { DragMode } from "../main";
@ -8,10 +8,10 @@ import { DragMode } from "../main";
const _vector = new Three.Vector3();
const orientation = {
0: { x: -1, y: -1 },
1: { x: -1, y: 1 },
2: { x: -1, y: 1 },
3: { x: -1, y: 1 },
0: {neighborX: 2, neighborY: 1, opposite: 3},
1: {neighborX: 3, neighborY: 0, opposite: 2},
2: {neighborX: 0, neighborY: 3, opposite: 1},
3: {neighborX: 1, neighborY: 2, opposite: 0}
};
export default class Selector
@ -198,6 +198,10 @@ export default class Selector
maxX = Selector.#selectionMesh.box.max.x,
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)
{
Renderer.cursor(CursorType.nesw);
@ -223,6 +227,11 @@ export default class Selector
Renderer.cursor(CursorType.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 };
}
@ -241,25 +250,68 @@ export default class Selector
Selector.gizmoScale[2].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);
//@ts-ignore
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 });
_vector.set(x, y, 0).normalize()
const rad = Math.atan2(-_vector.y, _vector.x);
Selector.selection.forEach(e => e.rotateTo(e.rot + rad).update(false));
Asset.instance.computeBoundingBox();
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]);
*/