157 lines
6.1 KiB
TypeScript
157 lines
6.1 KiB
TypeScript
import * as Three from 'three';
|
|
import * as CONST from '../consts';
|
|
import { AABB } from '../physics/common';
|
|
import Quadtree from '../physics/quadtree.class';
|
|
import { FreeList, clamp } from '../common';
|
|
|
|
const _mat = new Three.Matrix4();
|
|
|
|
export default class Asset
|
|
{
|
|
selected: boolean = false;
|
|
|
|
#layer: number;
|
|
#aabb: AABB;
|
|
|
|
#posX: number;
|
|
#posY: number;
|
|
#rot: number;
|
|
#scaleX: number;
|
|
#scaleY: number;
|
|
|
|
#sin: number;
|
|
#cos: number;
|
|
|
|
#index: number;
|
|
#quad?: number;
|
|
|
|
static instance: Three.InstancedMesh = new Three.InstancedMesh(CONST.QUAD, new Three.MeshBasicMaterial({ color: new Three.Color(0xffffff), side: Three.DoubleSide }), 1000000);
|
|
static quadtree: Quadtree = new Quadtree({ x1: -CONST.RESOLUTION_X / 2, x2: CONST.RESOLUTION_X / 2, y1: -CONST.RESOLUTION_Y / 2, y2: CONST.RESOLUTION_Y / 2 }, 6, 10);
|
|
static assets: FreeList<Asset> = new FreeList<Asset>();
|
|
|
|
constructor(posX?: number, posY?: number, scaleX?: number, scaleY?: number, rotation?: number, layer?: number)
|
|
{
|
|
this.#posX = posX ?? 0, this.#posY = posY ?? 0, this.#scaleX = scaleX ?? 0, this.#scaleY = scaleY ?? 0;
|
|
this.#rot = rotation ?? 0, this.#cos = Math.cos(this.#rot), this.#sin = Math.sin(this.#rot);
|
|
this.#layer = layer ?? 0;
|
|
|
|
this.#index = Asset.assets.insert(this);
|
|
|
|
console.log(this);
|
|
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 0, this.#cos * this.#scaleX);
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 1, this.#sin * this.#scaleX);
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 4, -this.#sin * this.#scaleY);
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 5, this.#cos * this.#scaleY);
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 12, this.#posX);
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 13, this.#posY);
|
|
Asset.instance.instanceMatrix.addUpdateRange(this.#index * 16, 16);
|
|
Asset.instance.instanceMatrix.needsUpdate = true;
|
|
|
|
this.#aabb = {
|
|
x1: -(this.#scaleX * Math.abs(this.#cos) + this.#scaleY * Math.abs(this.#sin)) / 2 + this.#posX,
|
|
x2: (this.#scaleX * Math.abs(this.#cos) + this.#scaleY * Math.abs(this.#sin)) / 2 + this.#posX,
|
|
y1: -(this.#scaleX * Math.abs(this.#sin) + this.#scaleY * Math.abs(this.#cos)) / 2 + this.#posY,
|
|
y2: (this.#scaleX * Math.abs(this.#sin) + this.#scaleY * Math.abs(this.#cos)) / 2 + this.#posY,
|
|
}
|
|
}
|
|
get aabb(): AABB {
|
|
return this.#aabb;
|
|
}
|
|
get layer(): number {
|
|
return this.#layer;
|
|
}
|
|
get posX(): number {
|
|
return this.#posX;
|
|
}
|
|
get posY(): number {
|
|
return this.#posY;
|
|
}
|
|
get rot(): number {
|
|
return this.#rot;
|
|
}
|
|
get scaleX(): number {
|
|
return this.#scaleX;
|
|
}
|
|
get scaleY(): number {
|
|
return this.#scaleY;
|
|
}
|
|
insert(): Asset
|
|
{
|
|
this.#quad = Asset.quadtree.insert(this.#index, this.#aabb);
|
|
|
|
return this;
|
|
}
|
|
remove(): Asset
|
|
{
|
|
this.#quad !== undefined && Asset.quadtree.remove(this.#quad);
|
|
Asset.assets.erase(this.#index);
|
|
Asset.instance.setMatrixAt(this.#index, _mat);
|
|
Asset.instance.instanceMatrix.addUpdateRange(this.#index * 16, 16);
|
|
Asset.instance.instanceMatrix.needsUpdate = true;
|
|
|
|
return this;
|
|
}
|
|
update(updateQuad: boolean = true): Asset
|
|
{
|
|
Asset.instance.instanceMatrix.needsUpdate = true;
|
|
|
|
if(updateQuad)
|
|
{
|
|
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
|
|
{
|
|
this.#aabb.x1 -= this.#posX - x;
|
|
this.#aabb.x2 -= this.#posX - x;
|
|
this.#aabb.y1 -= this.#posY - y;
|
|
this.#aabb.y2 -= this.#posY - y;
|
|
|
|
this.#posX = x, this.#posY = y;
|
|
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 12, x);
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 13, y);
|
|
|
|
return this;
|
|
}
|
|
rotateTo(rad: number): Asset
|
|
{
|
|
this.#rot = (rad + Math.PI) % (2*Math.PI) - Math.PI, this.#cos = Math.cos(this.#rot), this.#sin = Math.sin(this.#rot);
|
|
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 0, this.#cos * this.#scaleX);
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 1, this.#sin * this.#scaleX);
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 4, -this.#sin * this.#scaleY);
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 5, this.#cos * this.#scaleY);
|
|
|
|
this.#aabb.x1 = -(this.#scaleX * Math.abs(this.#cos) + this.#scaleY * Math.abs(this.#sin)) / 2 + this.#posX;
|
|
this.#aabb.x2 = (this.#scaleX * Math.abs(this.#cos) + this.#scaleY * Math.abs(this.#sin)) / 2 + this.#posX;
|
|
this.#aabb.y1 = -(this.#scaleX * Math.abs(this.#sin) + this.#scaleY * Math.abs(this.#cos)) / 2 + this.#posY;
|
|
this.#aabb.y2 = (this.#scaleX * Math.abs(this.#sin) + this.#scaleY * Math.abs(this.#cos)) / 2 + this.#posY;
|
|
|
|
return this;
|
|
}
|
|
matchAABB(aabb: AABB): Asset
|
|
{
|
|
const oldAABB = this.#aabb;
|
|
|
|
this.#aabb = aabb;
|
|
|
|
this.#posX = this.#aabb.x1 + (this.#aabb.x2 - this.#aabb.x1) / 2, this.#posY = this.#aabb.y1 + (this.#aabb.y2 - this.#aabb.y1) / 2;
|
|
this.#scaleX *= (this.#aabb.x2 - this.#aabb.x1) / (oldAABB.x2 - oldAABB.x1), this.#scaleY *= (this.#aabb.y2 - this.#aabb.y1) / (oldAABB.y2 - oldAABB.y1);
|
|
|
|
console.log(this.#posX, this.#posY, this.#scaleX, this.#scaleY);
|
|
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 0, this.#cos * this.#scaleX);
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 1, this.#sin * this.#scaleX);
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 4, -this.#sin * this.#scaleY);
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 5, this.#cos * this.#scaleY);
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 12, this.#posX);
|
|
Asset.instance.instanceMatrix.setComponent(this.#index, 13, this.#posY);
|
|
|
|
return this;
|
|
}
|
|
} |