177 lines
7.2 KiB
JavaScript
177 lines
7.2 KiB
JavaScript
import { Vec3, Mat4, Vec4 } from "./common.js";
|
|
import { DrawTag, Sprite } from "./graphics.js";
|
|
import { TileEdge } from "./world.js";
|
|
import * as Assets from "./assets.js";
|
|
// Attrib format
|
|
// position color uv
|
|
// (3) (4) (3) => 3 + 4 + 3 = 10 <=> vertexSize == 10
|
|
export class Rectangle {
|
|
attribs = ["a_position", "a_color", "a_tex"];
|
|
tags = [];
|
|
data = [];
|
|
vertexSize = 10;
|
|
sprites = Assets.assets.get("sprites");
|
|
constructor(tags, sprites, attribs) {
|
|
if (sprites !== undefined) {
|
|
this.sprites = sprites;
|
|
}
|
|
if (attribs !== undefined) {
|
|
this.attribs = attribs;
|
|
}
|
|
if (tags !== undefined) {
|
|
this.tags = tags;
|
|
}
|
|
}
|
|
commit(gfx) {
|
|
gfx.toRender.push(this);
|
|
}
|
|
draw(corners, fill) {
|
|
if (fill instanceof Sprite) {
|
|
let uvs = Assets.assets.get("sprites").getUVs(fill.id);
|
|
let data = [
|
|
corners[0].x, corners[0].y, corners[0].z, 0, 0, 0, 0, uvs[0].x, uvs[0].y, 1,
|
|
corners[1].x, corners[1].y, corners[1].z, 0, 0, 0, 0, uvs[1].x, uvs[1].y, 1,
|
|
corners[3].x, corners[3].y, corners[3].z, 0, 0, 0, 0, uvs[3].x, uvs[3].y, 1,
|
|
corners[2].x, corners[2].y, corners[2].z, 0, 0, 0, 0, uvs[2].x, uvs[2].y, 1,
|
|
corners[1].x, corners[1].y, corners[1].z, 0, 0, 0, 0, uvs[1].x, uvs[1].y, 1,
|
|
corners[3].x, corners[3].y, corners[3].z, 0, 0, 0, 0, uvs[3].x, uvs[3].y, 1,
|
|
];
|
|
for (let i = 0; i < data.length; ++i) {
|
|
this.data.push(data[i]);
|
|
}
|
|
}
|
|
else {
|
|
let color = fill;
|
|
let data = [
|
|
corners[0].x, corners[0].y, corners[0].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
|
corners[1].x, corners[1].y, corners[1].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
|
corners[3].x, corners[3].y, corners[3].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
|
corners[2].x, corners[2].y, corners[2].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
|
corners[1].x, corners[1].y, corners[1].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
|
corners[3].x, corners[3].y, corners[3].z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
|
];
|
|
for (let i = 0; i < data.length; ++i) {
|
|
this.data.push(data[i]);
|
|
}
|
|
}
|
|
}
|
|
drawExts(position, exts, fill) {
|
|
if (fill instanceof Sprite) {
|
|
let uvs = Assets.assets.get("sprites").getUVs(fill.id);
|
|
let data = [
|
|
position.x, position.y, position.z, 0, 0, 0, 0, uvs[0].x, uvs[0].y, 1,
|
|
position.x + exts.x, position.y, position.z, 0, 0, 0, 0, uvs[1].x, uvs[1].y, 1,
|
|
position.x, position.y + exts.y, position.z, 0, 0, 0, 0, uvs[3].x, uvs[3].y, 1,
|
|
position.x + exts.x, position.y + exts.y, position.z, 0, 0, 0, 0, uvs[2].x, uvs[2].y, 1,
|
|
position.x + exts.x, position.y, position.z, 0, 0, 0, 0, uvs[1].x, uvs[1].y, 1,
|
|
position.x, position.y + exts.y, position.z, 0, 0, 0, 0, uvs[3].x, uvs[3].y, 1,
|
|
];
|
|
for (let i = 0; i < data.length; ++i) {
|
|
this.data.push(data[i]);
|
|
}
|
|
}
|
|
else {
|
|
let color = fill;
|
|
let data = [
|
|
position.x, position.y, position.z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
|
position.x + exts.x, position.y, position.z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
|
position.x, position.y + exts.y, position.z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
|
position.x + exts.x, position.y + exts.y, position.z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
|
position.x + exts.x, position.y, position.z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
|
position.x, position.y + exts.y, position.z, color[0], color[1], color[2], color[3], 0, 0, 0,
|
|
];
|
|
for (let i = 0; i < data.length; ++i) {
|
|
this.data.push(data[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
export function drawIsometricCube(position, exts, r, fill, edge) {
|
|
let points = [
|
|
// Left Top
|
|
position,
|
|
//Top
|
|
new Vec3(position.x, position.y + exts.y, position.z),
|
|
//Mid
|
|
new Vec3(position.x + exts.x, position.y, position.z),
|
|
//Right Top
|
|
new Vec3(position.x + exts.x, position.y + exts.y, position.z),
|
|
//Bottom
|
|
new Vec3(position.x + 1.5 * exts.x, position.y - 0.5 * exts.y, position.z + 0.25 * exts.z),
|
|
new Vec3(position.x + 1.5 * exts.x, position.y + 0.5 * exts.y, position.z + 0.25 * exts.z),
|
|
new Vec3(position.x + 0.5 * exts.x, position.y - 0.5 * exts.y, position.z + 0.25 * exts.z),
|
|
];
|
|
// Top
|
|
r.draw([
|
|
points[0],
|
|
points[1],
|
|
points[3],
|
|
points[2],
|
|
], fill.top);
|
|
// Right Edge
|
|
if (edge == TileEdge.Right || edge == TileEdge.Both) {
|
|
r.draw([
|
|
points[3],
|
|
points[2],
|
|
points[4],
|
|
points[5],
|
|
], fill.right);
|
|
}
|
|
// Left Edge
|
|
if (edge == TileEdge.Left || edge == TileEdge.Both) {
|
|
r.draw([
|
|
points[0],
|
|
points[2],
|
|
points[4],
|
|
points[6],
|
|
], fill.left);
|
|
}
|
|
}
|
|
// TODO: Optimize the shit out of this function
|
|
export function drawIsometricGrid(gfx, camera, grid) {
|
|
let position = grid.position.copy();
|
|
let exts = new Vec3(grid.tileSize, grid.tileSize, 0);
|
|
let tileCoord = new Vec3(0, 0, 0);
|
|
let rect = new Rectangle([
|
|
DrawTag.ISO,
|
|
]);
|
|
let mt = Mat4.translate(camera.position.multScalarNew(-1.0));
|
|
let mi = Mat4.isometric();
|
|
let bias = 4 * grid.tileSize;
|
|
let bb = [
|
|
new Vec3(-bias, -bias, 0),
|
|
new Vec3(gfx.width() + bias, -bias, 0),
|
|
new Vec3(gfx.width() + bias, gfx.height() + bias, 0),
|
|
new Vec3(-bias, gfx.height() + bias, 0),
|
|
];
|
|
for (let i = 0; i < bb.length; ++i) {
|
|
bb[i] = mt.transformNew(bb[i].extend(1.0)).reduce();
|
|
}
|
|
for (let k = 0; k < grid.topHeight; ++k) {
|
|
for (let j = 0; j < grid.breadth; ++j) {
|
|
for (let i = 0; i < grid.width; ++i) {
|
|
tileCoord.x = i;
|
|
tileCoord.y = j;
|
|
tileCoord.z = k;
|
|
let tile = grid.getTile(tileCoord);
|
|
if (tile === null) {
|
|
position.x += grid.tileSize;
|
|
continue;
|
|
}
|
|
const ipos = mi.transformNew(new Vec4(position.x - grid.tileSize / 2 * k, position.y + grid.tileSize / 2 * k, 1.0, 1.0)).reduce();
|
|
if (ipos.x >= bb[2].x || ipos.x <= bb[0].x ||
|
|
ipos.y >= bb[2].y || ipos.y <= bb[0].y) {
|
|
position.x += grid.tileSize;
|
|
continue;
|
|
}
|
|
drawIsometricCube(new Vec3(position.x - grid.tileSize / 2 * k, position.y + grid.tileSize / 2 * k, position.z), exts, rect, tile.fill, tile.edge);
|
|
position.x += grid.tileSize;
|
|
}
|
|
position.y -= grid.tileSize;
|
|
position.x = grid.position.x;
|
|
}
|
|
position.y = grid.position.y;
|
|
}
|
|
rect.commit(gfx);
|
|
}
|