blaze-2d
Version:
A fast and simple WebGL 2 2D game engine written in TypeScript
140 lines • 5.07 kB
JavaScript
import { vec2 } from "gl-matrix";
import Logger from "../logger";
import { applyRotation, applyTranslation } from "../utils/vectors";
import Shape from "./shape";
// vertices for a triangle
const baseVertices = {
tc: vec2.fromValues(0.5, 1),
bl: vec2.fromValues(0, 0),
br: vec2.fromValues(1, 0),
};
const indices = new Uint16Array([0, 1, 2]);
const uvs = new Float32Array([0, 0, 1, 0, 0.5, 1]);
/**
* Represents a triangle in 2D space with a width and height.
*/
export default class Triangle extends Shape {
/**
* Creates a new {@link Triangle} instance with dimensions, position and rotation.
*
* @param width The width of the triangle (x size)
* @param height The height of the triangle (y size)
* @param position The triangle's position in world space, default is [0, 0]
* @param rotation The triangle's rotation, default is 0.
*/
constructor(width, height, position, rotation) {
super();
if (position)
this.setPosition(position);
if (rotation)
this.setRotation(rotation);
this.setWidth(width);
this.setHeight(height);
}
/**
* Calculates the triangle's vertices relative to the provided origin in world space.
*
* @param origin The origin to calculate the vertices relative to, should be a world position
* @param rotation An optional world space rotation to apply to the vertices
* @param returnVecs Wether or not to return the vertices as vec2s or raw numbers
* @returns The triangle's vertices relative to the provided origin in world space
*/
getVerticesWorld(origin, rotation, returnVecs = false) {
const base = this.getBaseVertices();
const world = applyTranslation(base, origin);
const worldLocal = applyTranslation(world, this.getPosition());
const worldLocalRotated = rotation ? applyRotation(worldLocal, origin, rotation) : worldLocal;
// vector to get from tc vertex to bc
// worldLocalRotated[2] is tc
const tcbc = vec2.sub(vec2.create(), vec2.fromValues(worldLocalRotated[2][0], worldLocalRotated[0][1]), worldLocalRotated[2]);
// centre of the triangle after translations
// TODO: Could change centre calculation to Midpoint formula
const centre = vec2.scaleAndAdd(vec2.create(), worldLocalRotated[2], tcbc, 0.5);
const worldLocalRotatedLocalRot = applyRotation(worldLocalRotated, centre, this.getRotation());
// const worldLocalTransRot = worldLocalTranslation;
if (returnVecs)
return worldLocalRotatedLocalRot;
const final = [];
worldLocalRotatedLocalRot.forEach((v) => final.push(...v));
return final;
}
/**
* Calculates the base vertices of the triangle.
*
* These are the vertices for a triangle scaled to the width and height of the {@link Triangle} instance.
*
* @returns The triangles base vertices
*/
getBaseVertices() {
const base = [
baseVertices.bl,
vec2.multiply(vec2.create(), baseVertices.br, vec2.fromValues(this.width, 1)),
vec2.multiply(vec2.create(), baseVertices.tc, vec2.fromValues(this.width, this.height)),
];
const temp = vec2.create();
const offset = vec2.fromValues(this.width / 2, this.height / 2);
const centred = base.map((v) => {
vec2.sub(temp, v, offset);
return vec2.clone(temp);
});
return centred;
}
/**
* Gets the triangle's vertex indices for drawing using element arrays.
*
* @param offset An offset to apply to each index
* @returns The triangle's vertex indices with the given offset added to each index
*/
getIndices(offset = 0) {
return indices.map((i) => i + offset);
}
/**
* Calculates the triangles's UV coords to be used for texture rendering.
*
* @returns the triangle's UV coords
*/
getUVCoords() {
return uvs;
}
/**
* Sets the triangle's width.
*
* @throws When the the provided width is < 0
*
* @param width The triangle's new width
*/
setWidth(width) {
if (width < 0)
return void Logger.error("Triangle", "Width cannot be < 0.");
this.width = width;
}
/**
* Gets the triangle's width in world space units.
*
* @returns The triangle's width in world space
*/
getWidth() {
return this.width;
}
/**
* Sets the triangle's height.
*
* @throws When the the provided height is < 0
*
* @param height The triangle's new height
*/
setHeight(height) {
if (height < 0)
return void Logger.error("Triangle", "Height cannot be < 0.");
this.height = height;
}
/**
* Gets the triangle's height in world space units.
*
* @returns The triangle's height in world space
*/
getHeight() {
return this.height;
}
}
//# sourceMappingURL=triangle.js.map