Compare commits

..

No commits in common. "859cf6aaec9941333e10e9fa18ccc01fd52f9ddd" and "37a91de848d873fbb8e264a9f8dcf6f3f4c13c0d" have entirely different histories.

18 changed files with 189 additions and 481 deletions

View File

@ -5,7 +5,6 @@ export const Colors = {
Green: [0, 1, 0, 1], Green: [0, 1, 0, 1],
Blue: [0, 0, 1, 1], Blue: [0, 0, 1, 1],
Brown: [0.341, 0.337, 0.204, 1], Brown: [0.341, 0.337, 0.204, 1],
Gray: [0.66, 0.66, 0.66, 1],
}; };
export class Assets { export class Assets {
assets = new Map(); assets = new Map();

View File

@ -8,7 +8,6 @@ export const Colors = {
Green : [0, 1, 0, 1] as Color, Green : [0, 1, 0, 1] as Color,
Blue : [0, 0, 1, 1] as Color, Blue : [0, 0, 1, 1] as Color,
Brown : [0.341, 0.337, 0.204, 1] as Color, Brown : [0.341, 0.337, 0.204, 1] as Color,
Gray : [0.66, 0.66, 0.66, 1] as Color,
} }
export type Asset = Texture | Spritesheet; export type Asset = Texture | Spritesheet;

View File

@ -1,24 +1,15 @@
export function initializeContext(canvasId) { function initializeContext(canvasId) {
const canvas = document.getElementById(canvasId); const canvas = document.getElementById(canvasId);
const ctx = canvas.getContext("webgl2", { antialias: false }); const ctx = canvas.getContext("webgl2", { antialias: false });
return ctx; return ctx;
} }
export class Vec2 { class Vec2 {
x; x;
y; y;
constructor(x, y) { constructor(x, y) {
this.x = x; this.x = x;
this.y = y; this.y = y;
} }
from(scalar) {
return new Vec2(scalar, scalar);
}
static ZERO() {
return new Vec2(0, 0);
}
static ID() {
return new Vec2(1, 1);
}
copy() { copy() {
return new Vec2(this.x, this.y); return new Vec2(this.x, this.y);
} }
@ -93,7 +84,7 @@ export class Vec2 {
return new Vec2(x, y); return new Vec2(x, y);
} }
} }
export class Vec3 { class Vec3 {
x; x;
y; y;
z; z;
@ -102,27 +93,6 @@ export class Vec3 {
this.y = y; this.y = y;
this.z = z; this.z = z;
} }
from(scalar) {
return new Vec3(scalar, scalar, scalar);
}
addScalar(scalar) {
this.x += scalar;
this.y += scalar;
this.z += scalar;
}
addScalarNew(scalar) {
let vec = this.copy();
vec.x += scalar;
vec.y += scalar;
vec.z += scalar;
return vec;
}
static ZERO() {
return new Vec3(0, 0, 0);
}
static ID() {
return new Vec3(1, 1, 1);
}
copy() { copy() {
return new Vec3(this.x, this.y, this.z); return new Vec3(this.x, this.y, this.z);
} }
@ -194,7 +164,7 @@ export class Vec3 {
return [this.x, this.y, this.z]; return [this.x, this.y, this.z];
} }
} }
export class Vec4 { class Vec4 {
x; x;
y; y;
z; z;
@ -205,15 +175,6 @@ export class Vec4 {
this.z = z; this.z = z;
this.w = w; this.w = w;
} }
from(scalar) {
return new Vec4(scalar, scalar, scalar, scalar);
}
static ZERO() {
return new Vec4(0, 0, 0, 0);
}
static ID() {
return new Vec4(1, 1, 1, 1);
}
copy() { copy() {
return new Vec4(this.x, this.y, this.z, this.w); return new Vec4(this.x, this.y, this.z, this.w);
} }
@ -231,20 +192,6 @@ export class Vec4 {
vec.w += other.w; vec.w += other.w;
return vec; return vec;
} }
addScalar(scalar) {
this.x += scalar;
this.y += scalar;
this.z += scalar;
this.w += scalar;
}
addScalarNew(scalar) {
let vec = this.copy();
vec.x += scalar;
vec.y += scalar;
vec.z += scalar;
vec.w += scalar;
return vec;
}
sub(other) { sub(other) {
this.x -= other.x; this.x -= other.x;
this.y -= other.y; this.y -= other.y;
@ -306,7 +253,7 @@ export class Vec4 {
throw new Error("Can't extend Vec4"); throw new Error("Can't extend Vec4");
} }
} }
export class Mat4 { class Mat4 {
data; data;
constructor(i) { constructor(i) {
if (i instanceof Float32Array) { if (i instanceof Float32Array) {
@ -350,8 +297,8 @@ export class Mat4 {
} }
static isometric_inverse() { static isometric_inverse() {
return new Mat4(new Float32Array([ return new Mat4(new Float32Array([
0.5, -0.5, 0, 0,
0.5, 0.5, 0, 0, 0.5, 0.5, 0, 0,
-0.5, 0.5, 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 1, 0, 0, 0, 1,
])); ]));
@ -423,10 +370,10 @@ export class Mat4 {
this.data[i * 4 + col] = data[i]; this.data[i * 4 + col] = data[i];
} }
transform(v) { transform(v) {
let x = v.x * this.x(0) + v.y * this.y(0) + v.z * this.z(0) + v.w * this.w(0); let x = v.x * this.x(0) + v.y * this.x(1) + v.z * this.x(2) + v.w * this.x(3);
let y = v.x * this.x(1) + v.y * this.y(1) + v.z * this.z(1) + v.w * this.w(1); let y = v.x * this.y(0) + v.y * this.y(1) + v.z * this.y(2) + v.w * this.y(3);
let z = v.x * this.x(2) + v.y * this.y(2) + v.z * this.z(2) + v.w * this.w(2); let z = v.x * this.z(0) + v.y * this.z(1) + v.z * this.z(2) + v.w * this.z(3);
let w = v.x * this.x(3) + v.y * this.y(3) + v.z * this.z(3) + v.w * this.w(3); let w = v.x * this.w(0) + v.y * this.w(1) + v.z * this.w(2) + v.w * this.w(3);
v.x = x; v.x = x;
v.y = y; v.y = y;
v.z = z; v.z = z;
@ -434,10 +381,10 @@ export class Mat4 {
} }
transformNew(v) { transformNew(v) {
let vec = v.copy(); let vec = v.copy();
let x = v.x * this.x(0) + v.y * this.y(0) + v.z * this.z(0) + v.w * this.w(0); let x = v.x * this.x(0) + v.y * this.x(1) + v.z * this.x(2) + v.w * this.x(3);
let y = v.x * this.x(1) + v.y * this.y(1) + v.z * this.z(1) + v.w * this.w(1); let y = v.x * this.y(0) + v.y * this.y(1) + v.z * this.y(2) + v.w * this.y(3);
let z = v.x * this.x(2) + v.y * this.y(2) + v.z * this.z(2) + v.w * this.w(2); let z = v.x * this.z(0) + v.y * this.z(1) + v.z * this.z(2) + v.w * this.z(3);
let w = v.x * this.x(3) + v.y * this.y(3) + v.z * this.z(3) + v.w * this.w(3); let w = v.x * this.w(0) + v.y * this.w(1) + v.z * this.w(2) + v.w * this.w(3);
vec.x = x; vec.x = x;
vec.y = y; vec.y = y;
vec.z = z; vec.z = z;
@ -462,3 +409,4 @@ export class Mat4 {
} }
} }
} }
export { initializeContext, Mat4, Vec2, Vec3, Vec4 };

View File

@ -1,4 +1,4 @@
export function initializeContext(canvasId: string): WebGL2RenderingContext | null { function initializeContext(canvasId: string): WebGL2RenderingContext | null {
const canvas = document.getElementById(canvasId) as HTMLCanvasElement; const canvas = document.getElementById(canvasId) as HTMLCanvasElement;
const ctx = canvas.getContext("webgl2", {antialias: false}); const ctx = canvas.getContext("webgl2", {antialias: false});
@ -9,14 +9,9 @@ export function initializeContext(canvasId: string): WebGL2RenderingContext | nu
interface Vector<P, T, N> { interface Vector<P, T, N> {
copy(): T; copy(): T;
from(scalar: number): T;
add(other: T): void; add(other: T): void;
addNew(other: T): T; addNew(other: T): T;
addScalar(scalar: number): void;
addScalarNew(scalar: number): T;
sub(other: T): void; sub(other: T): void;
subNew(other: T): T; subNew(other: T): T;
@ -28,10 +23,9 @@ interface Vector<P, T, N> {
reduce(): P; reduce(): P;
extend(value: number): N; extend(value: number): N;
} }
export class Vec2 implements Vector<void, Vec2, Vec3> { class Vec2 implements Vector<void, Vec2, Vec3> {
x: number; x: number;
y: number; y: number;
@ -40,18 +34,6 @@ export class Vec2 implements Vector<void, Vec2, Vec3> {
this.y = y; this.y = y;
} }
from(scalar: number): Vec2 {
return new Vec2(scalar, scalar);
}
static ZERO(): Vec2 {
return new Vec2(0, 0);
}
static ID(): Vec2 {
return new Vec2(1, 1);
}
copy(): Vec2 { copy(): Vec2 {
return new Vec2(this.x, this.y); return new Vec2(this.x, this.y);
} }
@ -152,7 +134,7 @@ export class Vec2 implements Vector<void, Vec2, Vec3> {
} }
} }
export class Vec3 implements Vector<Vec2, Vec3, Vec4> { class Vec3 implements Vector<Vec2, Vec3, Vec4> {
x: number; x: number;
y: number; y: number;
z: number; z: number;
@ -163,34 +145,6 @@ export class Vec3 implements Vector<Vec2, Vec3, Vec4> {
this.z = z; this.z = z;
} }
from(scalar: number): Vec3 {
return new Vec3(scalar, scalar, scalar);
}
addScalar(scalar: number): void {
this.x += scalar;
this.y += scalar;
this.z += scalar;
}
addScalarNew(scalar: number): Vec3 {
let vec = this.copy();
vec.x += scalar;
vec.y += scalar;
vec.z += scalar;
return vec;
}
static ZERO(): Vec3 {
return new Vec3(0, 0, 0);
}
static ID(): Vec3 {
return new Vec3(1, 1, 1);
}
copy(): Vec3 { copy(): Vec3 {
return new Vec3(this.x, this.y, this.z); return new Vec3(this.x, this.y, this.z);
} }
@ -286,7 +240,7 @@ export class Vec3 implements Vector<Vec2, Vec3, Vec4> {
} }
} }
export class Vec4 implements Vector<Vec3, Vec4, void> { class Vec4 implements Vector<Vec3, Vec4, void> {
x: number; x: number;
y: number; y: number;
z: number; z: number;
@ -299,18 +253,6 @@ export class Vec4 implements Vector<Vec3, Vec4, void> {
this.w = w; this.w = w;
} }
from(scalar: number): Vec4 {
return new Vec4(scalar, scalar, scalar, scalar);
}
static ZERO(): Vec4 {
return new Vec4(0, 0, 0, 0);
}
static ID(): Vec4 {
return new Vec4(1, 1, 1, 1);
}
copy(): Vec4 { copy(): Vec4 {
return new Vec4(this.x, this.y, this.z, this.w); return new Vec4(this.x, this.y, this.z, this.w);
} }
@ -333,24 +275,6 @@ export class Vec4 implements Vector<Vec3, Vec4, void> {
return vec; return vec;
} }
addScalar(scalar: number): void {
this.x += scalar;
this.y += scalar;
this.z += scalar;
this.w += scalar;
}
addScalarNew(scalar: number): Vec4 {
let vec = this.copy();
vec.x += scalar;
vec.y += scalar;
vec.z += scalar;
vec.w += scalar;
return vec;
}
sub(other: Vec4) { sub(other: Vec4) {
this.x -= other.x; this.x -= other.x;
this.y -= other.y; this.y -= other.y;
@ -432,14 +356,14 @@ export class Vec4 implements Vector<Vec3, Vec4, void> {
type Mat4Init = number | Float32Array; type Mat4Init = number | Float32Array;
export type Mat4Row = 0 | 1 | 2 | 3 type Mat4Row = 0 | 1 | 2 | 3
export type Mat4Col = Mat4Row type Mat4Col = Mat4Row
export type Mat4X = Mat4Row type Mat4X = Mat4Row
export type Mat4Y = Mat4Row type Mat4Y = Mat4Row
export type Mat4Z = Mat4Row type Mat4Z = Mat4Row
export type Mat4W = Mat4Row type Mat4W = Mat4Row
export class Mat4 { class Mat4 {
data: Float32Array; data: Float32Array;
constructor(i: Mat4Init) { constructor(i: Mat4Init) {
@ -490,8 +414,8 @@ export class Mat4 {
static isometric_inverse(): Mat4 { static isometric_inverse(): Mat4 {
return new Mat4(new Float32Array([ return new Mat4(new Float32Array([
0.5, -0.5, 0, 0,
0.5, 0.5, 0, 0, 0.5, 0.5, 0, 0,
-0.5, 0.5, 0, 0,
0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 1, 0, 0, 0, 1,
])); ]));
@ -579,10 +503,10 @@ export class Mat4 {
} }
transform(v: Vec4) { transform(v: Vec4) {
let x = v.x * this.x(0) + v.y * this.y(0) + v.z * this.z(0) + v.w * this.w(0); let x = v.x * this.x(0) + v.y * this.x(1) + v.z * this.x(2) + v.w * this.x(3);
let y = v.x * this.x(1) + v.y * this.y(1) + v.z * this.z(1) + v.w * this.w(1); let y = v.x * this.y(0) + v.y * this.y(1) + v.z * this.y(2) + v.w * this.y(3);
let z = v.x * this.x(2) + v.y * this.y(2) + v.z * this.z(2) + v.w * this.w(2); let z = v.x * this.z(0) + v.y * this.z(1) + v.z * this.z(2) + v.w * this.z(3);
let w = v.x * this.x(3) + v.y * this.y(3) + v.z * this.z(3) + v.w * this.w(3); let w = v.x * this.w(0) + v.y * this.w(1) + v.z * this.w(2) + v.w * this.w(3);
v.x = x; v.x = x;
v.y = y; v.y = y;
@ -593,10 +517,10 @@ export class Mat4 {
transformNew(v: Vec4): Vec4 { transformNew(v: Vec4): Vec4 {
let vec = v.copy(); let vec = v.copy();
let x = v.x * this.x(0) + v.y * this.y(0) + v.z * this.z(0) + v.w * this.w(0); let x = v.x * this.x(0) + v.y * this.x(1) + v.z * this.x(2) + v.w * this.x(3);
let y = v.x * this.x(1) + v.y * this.y(1) + v.z * this.z(1) + v.w * this.w(1); let y = v.x * this.y(0) + v.y * this.y(1) + v.z * this.y(2) + v.w * this.y(3);
let z = v.x * this.x(2) + v.y * this.y(2) + v.z * this.z(2) + v.w * this.w(2); let z = v.x * this.z(0) + v.y * this.z(1) + v.z * this.z(2) + v.w * this.z(3);
let w = v.x * this.x(3) + v.y * this.y(3) + v.z * this.z(3) + v.w * this.w(3); let w = v.x * this.w(0) + v.y * this.w(1) + v.z * this.w(2) + v.w * this.w(3);
vec.x = x; vec.x = x;
vec.y = y; vec.y = y;
@ -627,3 +551,5 @@ export class Mat4 {
} }
} }
} }
export { initializeContext, Mat4, Vec2, Vec3, Vec4 };

View File

@ -1,4 +1,4 @@
import { Vec3, Mat4, Vec4 } from "./common.js"; import { Vec3 } from "./common.js";
import { DrawTag, Sprite } from "./graphics.js"; import { DrawTag, Sprite } from "./graphics.js";
import { TileEdge } from "./world.js"; import { TileEdge } from "./world.js";
import * as Assets from "./assets.js"; import * as Assets from "./assets.js";
@ -28,61 +28,49 @@ export class Rectangle {
draw(corners, fill) { draw(corners, fill) {
if (fill instanceof Sprite) { if (fill instanceof Sprite) {
let uvs = Assets.assets.get("sprites").getUVs(fill.id); let uvs = Assets.assets.get("sprites").getUVs(fill.id);
let data = [ this.data.push([
corners[0].x, corners[0].y, corners[0].z, 0, 0, 0, 0, uvs[0].x, uvs[0].y, 1, 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[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[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[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[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[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 { else {
let color = fill; let color = fill;
let data = [ this.data.push([
corners[0].x, corners[0].y, corners[0].z, color[0], color[1], color[2], color[3], 0, 0, 0, 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[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[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[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[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[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) { drawExts(position, exts, fill) {
if (fill instanceof Sprite) { if (fill instanceof Sprite) {
let uvs = Assets.assets.get("sprites").getUVs(fill.id); let uvs = Assets.assets.get("sprites").getUVs(fill.id);
let data = [ this.data.push([
position.x, position.y, position.z, 0, 0, 0, 0, uvs[0].x, uvs[0].y, 1, 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 + 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, 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 + 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 + 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, 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 { else {
let color = fill; let color = fill;
let data = [ this.data.push([
position.x, position.y, position.z, color[0], color[1], color[2], color[3], 0, 0, 0, position.x, position.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
position.x + exts.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,
position.x, position.y + exts.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,
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 + exts.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
position.x + exts.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,
position.x, position.y + exts.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,
]; ]);
for (let i = 0; i < data.length; ++i) {
this.data.push(data[i]);
}
} }
} }
} }
@ -127,49 +115,29 @@ export function drawIsometricCube(position, exts, r, fill, edge) {
], fill.left); ], fill.left);
} }
} }
// TODO: Optimize the shit out of this function export function drawIsometricGrid(gfx, grid) {
export function drawIsometricGrid(gfx, camera, grid) { let position = { ...grid.position };
let position = grid.position.copy();
let exts = new Vec3(grid.tileSize, grid.tileSize, 0); let exts = new Vec3(grid.tileSize, grid.tileSize, 0);
let tileCoord = new Vec3(0, 0, 0); let tileCoord = new Vec3(0, 0, 0);
let rect = new Rectangle([ let rect = new Rectangle([
DrawTag.ISO, DrawTag.ISO,
]); ]);
let mt = Mat4.translate(camera.position.multScalarNew(-1.0)); // TODO: Optimize this
let ms = Mat4.scale(new Vec3(1 / camera.scale, 1 / camera.scale, 0)); // 1. Grid based occlusion culling
let mc = Mat4.translate(new Vec3((gfx.ctx.canvas.width / 2 - camera.position.x), (gfx.ctx.canvas.height / 2 - camera.position.y), 1.0)); // 2. frustum culling
let mr = Mat4.translate(new Vec3(-(gfx.ctx.canvas.width / 2 - camera.position.x), -(gfx.ctx.canvas.height / 2 - camera.position.y), 1.0)); for (let k = 0; k < grid.height; ++k) {
let mi = Mat4.isometric(); for (let j = 0; j < grid.length; ++j) {
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();
bb[i] = mr.transformNew(bb[i].extend(1.0)).reduce();
bb[i] = ms.transformNew(bb[i].extend(1.0)).reduce();
bb[i] = mc.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) { for (let i = 0; i < grid.width; ++i) {
tileCoord.x = i; tileCoord.x = i;
tileCoord.y = j; tileCoord.y = j;
tileCoord.z = k; tileCoord.z = k;
// getTile is sus (it uses a lot of time in the profiler) (i don't know why, it is a pretty simple function)
// (Prolly cuz i call it a lot) (Maybe change grid to use spatial hashmap?)
let tile = grid.getTile(tileCoord); let tile = grid.getTile(tileCoord);
if (tile === null) { if (tile === null) {
position.x += grid.tileSize; position.x += grid.tileSize;
continue; 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); 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.x += grid.tileSize;
} }

View File

@ -1,8 +1,7 @@
import { Vec3, Vec2, Mat4, Vec4 } from "./common.js" import { Vec3, Vec2 } from "./common.js"
import { Graphics, Drawable, DrawTag, Sprite, Spritesheet, Camera } from "./graphics.js"; import { Graphics, Drawable, DrawTag, Sprite, Spritesheet } from "./graphics.js";
import { TileEdge, TileFill, TileFillament, Grid } from "./world.js"; import { TileEdge, TileFill, TileFillament, Grid } from "./world.js";
import * as Assets from "./assets.js"; import * as Assets from "./assets.js";
import {Input} from "./input.js";
// Attrib format // Attrib format
// position color uv // position color uv
@ -12,7 +11,7 @@ export class Rectangle implements Drawable {
attribs: string[] = ["a_position", "a_color", "a_tex"]; attribs: string[] = ["a_position", "a_color", "a_tex"];
tags: Array<DrawTag> = []; tags: Array<DrawTag> = [];
data: number[] = []; data: number[][] = [];
vertexSize: number = 10; vertexSize: number = 10;
sprites: Spritesheet = Assets.assets.get("sprites") as Spritesheet; sprites: Spritesheet = Assets.assets.get("sprites") as Spritesheet;
@ -39,7 +38,7 @@ export class Rectangle implements Drawable {
if (fill instanceof Sprite) { if (fill instanceof Sprite) {
let uvs = (Assets.assets.get("sprites") as Spritesheet).getUVs(fill.id); let uvs = (Assets.assets.get("sprites") as Spritesheet).getUVs(fill.id);
let data = [ this.data.push([
corners[0].x, corners[0].y, corners[0].z, 0, 0, 0, 0, uvs[0].x, uvs[0].y, 1, 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[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[3].x, corners[3].y, corners[3].z, 0, 0, 0, 0, uvs[3].x, uvs[3].y, 1,
@ -47,15 +46,11 @@ export class Rectangle implements Drawable {
corners[2].x, corners[2].y, corners[2].z, 0, 0, 0, 0, uvs[2].x, uvs[2].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[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[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 { } else {
let color = fill; let color = fill;
let data = [ this.data.push([
corners[0].x, corners[0].y, corners[0].z, color[0], color[1], color[2], color[3], 0, 0, 0, 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[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[3].x, corners[3].y, corners[3].z, color[0], color[1], color[2], color[3], 0, 0, 0,
@ -63,11 +58,7 @@ export class Rectangle implements Drawable {
corners[2].x, corners[2].y, corners[2].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[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[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]);
}
} }
} }
@ -75,7 +66,7 @@ export class Rectangle implements Drawable {
if (fill instanceof Sprite) { if (fill instanceof Sprite) {
let uvs = (Assets.assets.get("sprites") as Spritesheet).getUVs(fill.id); let uvs = (Assets.assets.get("sprites") as Spritesheet).getUVs(fill.id);
let data = [ this.data.push([
position.x, position.y, position.z, 0, 0, 0, 0, uvs[0].x, uvs[0].y, 1, 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 + 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, position.y + exts.y, position.z, 0, 0, 0, 0, uvs[3].x, uvs[3].y, 1,
@ -83,27 +74,19 @@ export class Rectangle implements Drawable {
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 + 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 + 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, 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 { } else {
let color = fill; let color = fill;
let data = [ this.data.push([
position.x, position.y, position.z, color[0], color[1], color[2], color[3], 0, 0, 0, position.x, position.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
position.x + exts.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,
position.x, position.y + exts.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,
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 + exts.y, position.z, color[0], color[1], color[2], color[3], 0, 0,
position.x + exts.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,
position.x, position.y + exts.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,
]; ]);
for (let i = 0; i < data.length; ++i) {
this.data.push(data[i]);
}
} }
} }
} }
@ -162,53 +145,26 @@ export function drawIsometricCube(position: Vec3, exts: Vec3, r: Rectangle, fill
} }
} }
// TODO: Optimize the shit out of this function export function drawIsometricGrid(gfx: Graphics, grid: Grid) {
export function drawIsometricGrid(gfx: Graphics, camera: Camera, grid: Grid) { let position = {...grid.position} as Vec3;
let position = grid.position.copy();
let exts = new Vec3(grid.tileSize, grid.tileSize, 0); let exts = new Vec3(grid.tileSize, grid.tileSize, 0);
let tileCoord = new Vec3(0, 0, 0); let tileCoord = new Vec3(0, 0, 0);
let rect = new Rectangle([ let rect = new Rectangle([
DrawTag.ISO, DrawTag.ISO,
]); ]);
let mt = Mat4.translate(camera.position.multScalarNew(-1.0)); // TODO: Optimize this
let ms = Mat4.scale(new Vec3(1 / camera.scale, 1 /camera.scale, 0)); // 1. Grid based occlusion culling
let mc = Mat4.translate( // 2. frustum culling
new Vec3( for (let k = 0; k < grid.height; ++k) {
(gfx.ctx.canvas.width / 2 - camera.position.x), for (let j = 0; j < grid.length; ++j) {
(gfx.ctx.canvas.height / 2 - camera.position.y),
1.0));
let mr = Mat4.translate(
new Vec3(
-(gfx.ctx.canvas.width / 2 - camera.position.x),
-(gfx.ctx.canvas.height / 2 - camera.position.y),
1.0));
let mi = Mat4.isometric();
let bias = 4*grid.tileSize;
let bb: [Vec3, Vec3, Vec3, Vec3] = [
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();
bb[i] = mr.transformNew(bb[i].extend(1.0)).reduce();
bb[i] = ms.transformNew(bb[i].extend(1.0)).reduce();
bb[i] = mc.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) { for (let i = 0; i < grid.width; ++i) {
tileCoord.x = i; tileCoord.x = i;
tileCoord.y = j; tileCoord.y = j;
tileCoord.z = k; tileCoord.z = k;
// getTile is sus (it uses a lot of time in the profiler) (i don't know why, it is a pretty simple function)
// (Prolly cuz i call it a lot) (Maybe change grid to use spatial hashmap?)
let tile = grid.getTile(tileCoord); let tile = grid.getTile(tileCoord);
if (tile === null) { if (tile === null) {
@ -216,15 +172,6 @@ export function drawIsometricGrid(gfx: Graphics, camera: Camera, grid: Grid) {
continue; 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( drawIsometricCube(
new Vec3(position.x - grid.tileSize / 2 * k, position.y + grid.tileSize / 2 * k, position.z), new Vec3(position.x - grid.tileSize / 2 * k, position.y + grid.tileSize / 2 * k, position.z),
exts, exts,
@ -240,5 +187,6 @@ export function drawIsometricGrid(gfx: Graphics, camera: Camera, grid: Grid) {
} }
position.y = grid.position.y; position.y = grid.position.y;
} }
rect.commit(gfx); rect.commit(gfx);
} }

View File

@ -52,12 +52,6 @@ export class Graphics {
vbo; vbo;
toRender = []; toRender = [];
texCount = 0; texCount = 0;
width() {
return this.ctx.canvas.width;
}
height() {
return this.ctx.canvas.height;
}
constructor(ctx, vs, fs) { constructor(ctx, vs, fs) {
this.ctx = ctx; this.ctx = ctx;
this.program = createProgram(ctx, vs, fs); this.program = createProgram(ctx, vs, fs);
@ -98,7 +92,7 @@ export class Graphics {
} }
draw() { draw() {
for (let o of this.toRender) { for (let o of this.toRender) {
const data = o.data; const data = o.data.flat();
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, this.vbo); this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, this.vbo);
this.ctx.bufferData(this.ctx.ARRAY_BUFFER, new Float32Array(data), this.ctx.STATIC_DRAW); this.ctx.bufferData(this.ctx.ARRAY_BUFFER, new Float32Array(data), this.ctx.STATIC_DRAW);
let aid = 0; let aid = 0;

View File

@ -60,7 +60,7 @@ export interface Drawable {
attribs: string[]; attribs: string[];
tags: Array<DrawTag>; tags: Array<DrawTag>;
data: number[]; data: number[][];
vertexSize: number; vertexSize: number;
sprites: Spritesheet | undefined; sprites: Spritesheet | undefined;
@ -77,14 +77,6 @@ export class Graphics {
toRender: Array<Drawable> = []; toRender: Array<Drawable> = [];
texCount: number = 0; texCount: number = 0;
width(): number {
return this.ctx.canvas.width;
}
height(): number {
return this.ctx.canvas.height;
}
constructor(ctx: WebGL2RenderingContext, vs: string, fs: string) { constructor(ctx: WebGL2RenderingContext, vs: string, fs: string) {
this.ctx = ctx; this.ctx = ctx;
this.program = createProgram(ctx, vs, fs); this.program = createProgram(ctx, vs, fs);
@ -139,7 +131,7 @@ export class Graphics {
draw() { draw() {
for (let o of this.toRender) { for (let o of this.toRender) {
const data = o.data; const data = o.data.flat();
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, this.vbo); this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, this.vbo);
this.ctx.bufferData(this.ctx.ARRAY_BUFFER, new Float32Array(data), this.ctx.STATIC_DRAW); this.ctx.bufferData(this.ctx.ARRAY_BUFFER, new Float32Array(data), this.ctx.STATIC_DRAW);

View File

@ -1,4 +1,3 @@
import { Vec2 } from "./common.js";
class KeyAction { class KeyAction {
key; key;
keyup; keyup;
@ -13,7 +12,6 @@ class KeyAction {
} }
export class Input { export class Input {
handlers = new Map(); handlers = new Map();
mousePosition = Vec2.ZERO();
constructor() { constructor() {
window.addEventListener("keyup", e => { window.addEventListener("keyup", e => {
this.handlers.forEach(ka => { this.handlers.forEach(ka => {
@ -29,10 +27,6 @@ export class Input {
} }
}); });
}); });
window.addEventListener("mousemove", (e) => {
this.mousePosition.x = e.x;
this.mousePosition.y = e.y;
});
} }
//TODO: add modifier key support //TODO: add modifier key support
addKeyAction(key, modifiers, data, keydown, keyup) { addKeyAction(key, modifiers, data, keydown, keyup) {

View File

@ -1,5 +1,3 @@
import { Vec2 } from "./common.js";
type Action = ((data: any) => void); type Action = ((data: any) => void);
class KeyAction { class KeyAction {
@ -17,7 +15,6 @@ class KeyAction {
export class Input { export class Input {
handlers: Map<string, KeyAction> = new Map(); handlers: Map<string, KeyAction> = new Map();
mousePosition: Vec2 = Vec2.ZERO();
constructor() { constructor() {
window.addEventListener("keyup", e => { window.addEventListener("keyup", e => {
this.handlers.forEach(ka => { this.handlers.forEach(ka => {
@ -33,11 +30,6 @@ export class Input {
} }
}); });
}); });
window.addEventListener("mousemove", (e) => {
this.mousePosition.x = e.x;
this.mousePosition.y = e.y;
})
} }
//TODO: add modifier key support //TODO: add modifier key support

View File

@ -1,4 +1,4 @@
import { initializeContext, Vec3, Mat4, Vec4 } from "./common.js"; import { initializeContext, Vec3, Mat4, Vec4, Vec2 } from "./common.js";
import { Graphics, fullscreenCanvas, Camera, Sprite } from "./graphics.js"; import { Graphics, fullscreenCanvas, Camera, Sprite } from "./graphics.js";
import * as drawing from "./draw.js"; import * as drawing from "./draw.js";
import * as wasm from "./wasm.js"; import * as wasm from "./wasm.js";
@ -80,7 +80,7 @@ function draw(gfx, camera, dt, grid) {
m = m.multNew(mt); m = m.multNew(mt);
m = m.multNew(mo); m = m.multNew(mo);
gfx.ctx.uniformMatrix4fv(gfx.getUniform("u_matrix"), false, m.splat()); gfx.ctx.uniformMatrix4fv(gfx.getUniform("u_matrix"), false, m.splat());
drawing.drawIsometricGrid(gfx, camera, grid); drawing.drawIsometricGrid(gfx, grid);
gfx.draw(); gfx.draw();
} }
function addDefaultKeybinds(input, camera) { function addDefaultKeybinds(input, camera) {
@ -134,27 +134,17 @@ function addDefaultKeybinds(input, camera) {
await Assets.assets.load(gfx); await Assets.assets.load(gfx);
let m = Mat4.isometric(); let m = Mat4.isometric();
let size = 100; let size = 100;
let grid = new Grid(m.transformNew(new Vec4(ctx.canvas.width / 4, ctx.canvas.height / 2, 0, 1)).reduce(), 32, size, size, 10); let grid = new Grid(m.transformNew(new Vec4(ctx.canvas.width / 4, ctx.canvas.height / 2, 0, 1)).reduce(), 24, size, size, 10);
grid.fillLayer(new Tile({
top: Assets.Colors.Gray,
right: Assets.Colors.Gray,
left: Assets.Colors.Gray,
}), 0);
grid.fillLayer(new Tile({
top: Assets.Colors.Gray,
right: Assets.Colors.Gray,
left: Assets.Colors.Gray,
}), 1);
grid.fillLayer(new Tile({ grid.fillLayer(new Tile({
top: Sprite.id(0), top: Sprite.id(0),
right: Assets.Colors.Brown, right: Assets.Colors.Brown,
left: Assets.Colors.Brown, left: Assets.Colors.Brown,
}), 2); }), 0);
for (let i = 0; i <= size / 2; i++) { tree(grid, new Vec2(5, 5));
tree(grid, new Vec3(Math.floor(Math.random() * size - 1), Math.floor(Math.random() * size - 1), 2)); //for (let i = 0; i < 10; i++) {
} // tree(grid, new Vec2(Math.floor(Math.random() * size - 1), Math.floor(Math.random() * size - 1)));
const input = new Input(); //}
addDefaultKeybinds(input, camera); //grid.setTile(new Tile(Assets.AssetToTileFill("log"), TileEdge.Both), new Vec3(0, 29, 1));
let prevTimestamp = 0; let prevTimestamp = 0;
const frame = (timestamp) => { const frame = (timestamp) => {
const deltaTime = (timestamp - prevTimestamp) / 1000; const deltaTime = (timestamp - prevTimestamp) / 1000;
@ -167,5 +157,7 @@ function addDefaultKeybinds(input, camera) {
prevTimestamp = timestamp; prevTimestamp = timestamp;
window.requestAnimationFrame(frame); window.requestAnimationFrame(frame);
}); });
const input = new Input();
addDefaultKeybinds(input, camera);
const wasmgl = new wasm.WASMGL(await wasm.loadWasmModule("./src/wasm/module.wasm")); const wasmgl = new wasm.WASMGL(await wasm.loadWasmModule("./src/wasm/module.wasm"));
})(); })();

View File

@ -1,5 +1,5 @@
import { initializeContext, Vec3, Mat4, Vec4, Vec2 } from "./common.js"; import { initializeContext, Vec3, Mat4, Vec4, Vec2 } from "./common.js";
import { Graphics, fullscreenCanvas, Camera, Sprite, DrawTag } from "./graphics.js"; import { Graphics, fullscreenCanvas, Camera, Sprite } from "./graphics.js";
import * as drawing from "./draw.js"; import * as drawing from "./draw.js";
import * as wasm from "./wasm.js"; import * as wasm from "./wasm.js";
import { Input } from "./input.js"; import { Input } from "./input.js";
@ -107,8 +107,7 @@ function draw(gfx: Graphics, camera: Camera, dt: number, grid: Grid) {
m.splat() m.splat()
); );
drawing.drawIsometricGrid(gfx, camera, grid); drawing.drawIsometricGrid(gfx, grid);
gfx.draw(); gfx.draw();
} }
@ -187,32 +186,18 @@ function addDefaultKeybinds(input: Input, camera: Camera) {
let m = Mat4.isometric(); let m = Mat4.isometric();
let size = 100; let size = 100;
let grid = new Grid(m.transformNew(new Vec4(ctx.canvas.width / 4, ctx.canvas.height / 2, 0, 1)).reduce(), 32, size, size, 10); let grid = new Grid(m.transformNew(new Vec4(ctx.canvas.width / 4, ctx.canvas.height / 2, 0, 1)).reduce(), 24, size, size, 10);
grid.fillLayer(new Tile({
top: Assets.Colors.Gray,
right: Assets.Colors.Gray,
left: Assets.Colors.Gray,
}), 0);
grid.fillLayer(new Tile({
top: Assets.Colors.Gray,
right: Assets.Colors.Gray,
left: Assets.Colors.Gray,
}), 1);
grid.fillLayer(new Tile({ grid.fillLayer(new Tile({
top: Sprite.id(0), top: Sprite.id(0),
right: Assets.Colors.Brown, right: Assets.Colors.Brown,
left: Assets.Colors.Brown, left: Assets.Colors.Brown,
}), 2); }), 0);
tree(grid, new Vec2(5, 5));
//for (let i = 0; i < 10; i++) {
// tree(grid, new Vec2(Math.floor(Math.random() * size - 1), Math.floor(Math.random() * size - 1)));
//}
for (let i = 0; i <= size / 2; i++) { //grid.setTile(new Tile(Assets.AssetToTileFill("log"), TileEdge.Both), new Vec3(0, 29, 1));
tree(grid, new Vec3(Math.floor(Math.random() * size - 1), Math.floor(Math.random() * size - 1), 2));
}
const input = new Input();
addDefaultKeybinds(input, camera);
let prevTimestamp = 0; let prevTimestamp = 0;
const frame = (timestamp: number) => { const frame = (timestamp: number) => {
@ -230,5 +215,8 @@ function addDefaultKeybinds(input: Input, camera: Camera) {
window.requestAnimationFrame(frame); window.requestAnimationFrame(frame);
}); });
const input = new Input();
addDefaultKeybinds(input, camera);
const wasmgl: wasm.WASMGL = new wasm.WASMGL(await wasm.loadWasmModule("./src/wasm/module.wasm")); const wasmgl: wasm.WASMGL = new wasm.WASMGL(await wasm.loadWasmModule("./src/wasm/module.wasm"));
})(); })();

View File

@ -1,3 +1,11 @@
export class WASMGLvalue {
ptr;
size;
constructor(ptr, size) {
this.ptr = ptr;
this.size = size;
}
}
export async function loadWasmModule(path) { export async function loadWasmModule(path) {
return WebAssembly.instantiateStreaming(fetch(path)); return WebAssembly.instantiateStreaming(fetch(path));
} }
@ -26,18 +34,4 @@ export class WASMGL {
}); });
return ptr; return ptr;
} }
push(data) {
let ptr = this.alloc(data.length);
data.forEach((v, i) => {
this.mem[ptr + i] = v;
});
return ptr;
}
get(ptr, length) {
let a = new Array(length);
for (let i = 0; i < length; ++i) {
a[i] = this.mem[ptr + i];
}
return a;
}
} }

View File

@ -1,3 +1,13 @@
export class WASMGLvalue {
ptr: number;
size: number;
constructor(ptr: number, size: number) {
this.ptr = ptr;
this.size = size;
}
}
export interface WASMGLEnvironment { export interface WASMGLEnvironment {
exports: any, exports: any,
mem: Float32Array, mem: Float32Array,
@ -48,24 +58,4 @@ export class WASMGL {
return ptr; return ptr;
} }
push(data: number[]): number {
let ptr = this.alloc(data.length);
data.forEach((v, i) => {
this.mem[ptr + i] = v;
});
return ptr;
}
get(ptr: number, length: number): Array<number> {
let a = new Array(length);
for (let i = 0; i < length; ++i) {
a[i] = this.mem[ptr + i];
}
return a;
}
} }

View File

@ -33,42 +33,36 @@ export class Grid {
tiles3d; tiles3d;
tileSize; tileSize;
width; width;
breadth; length;
height; height;
topHeight; constructor(position, tileSize, width, length, height) {
constructor(position, tileSize, width, breadth, height) {
this.tiles3d = new Array(height); this.tiles3d = new Array(height);
this.position = position; this.position = position;
this.tileSize = tileSize; this.tileSize = tileSize;
this.width = width; this.width = width;
this.breadth = breadth; this.length = length;
this.height = height; this.height = height;
this.topHeight = 0; let layer = new Array(width * length);
let layer = new Array(width * breadth);
for (let i = 0; i < this.height; ++i) for (let i = 0; i < this.height; ++i)
this.tiles3d[i] = { ...layer }; this.tiles3d[i] = { ...layer };
} }
fillLayer(tile, z) { fillLayer(tile, z) {
if (z + 1 > this.topHeight)
this.topHeight = z + 1;
for (let i = 0; i < this.width; ++i) { for (let i = 0; i < this.width; ++i) {
for (let j = 0; j < this.breadth; ++j) { for (let j = 0; j < this.length; ++j) {
this.tiles3d[z][i + j * this.width] = { ...tile }; this.tiles3d[z][i + j * this.width] = { ...tile };
} }
} }
for (let i = 0; i < this.width; ++i) { for (let i = 0; i < this.width; ++i) {
this.tiles3d[z][this.breadth * i - 1] = { ...tile, edge: TileEdge.Right }; this.tiles3d[z][this.length * i - 1] = { ...tile, edge: TileEdge.Right };
} }
for (let i = 0; i < this.breadth - 1; ++i) { for (let i = 0; i < this.length - 1; ++i) {
this.tiles3d[z][this.width * (this.breadth - 1) + i] = { ...tile, edge: TileEdge.Left }; this.tiles3d[z][this.width * (this.length - 1) + i] = { ...tile, edge: TileEdge.Left };
} }
this.tiles3d[z][this.width * this.breadth - 1] = { ...tile, edge: TileEdge.Both }; this.tiles3d[z][this.width * this.length - 1] = { ...tile, edge: TileEdge.Both };
} }
setTile(tile, coord) { setTile(tile, coord) {
let index = coord.x + coord.y * this.width; let index = coord.x + coord.y * this.width;
this.tiles3d[coord.z][index] = { ...tile }; this.tiles3d[coord.z][index] = { ...tile };
if (coord.z + 1 > this.topHeight)
this.topHeight = coord.z + 1;
} }
getTile(coord) { getTile(coord) {
let index = coord.x + coord.y * this.width; let index = coord.x + coord.y * this.width;
@ -81,18 +75,18 @@ export class Grid {
export function tree(grid, position) { export function tree(grid, position) {
let log = Sprite.tile(2); let log = Sprite.tile(2);
let leaves = Sprite.tile(1); let leaves = Sprite.tile(1);
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, position.z + 1)); grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 1));
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, position.z + 2)); grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 2));
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, position.z + 3)); grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 3));
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, position.z + 4)); grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 4));
grid.setTile(new Tile(log, TileEdge.None), new Vec3(position.x, position.y, position.z + 4)); grid.setTile(new Tile(log, TileEdge.None), new Vec3(position.x, position.y, 4));
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, position.z + 4)); grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, 4));
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, position.z + 5)); grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, 5));
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y, position.z + 5)); grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y, 5));
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, position.z + 4)); grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, 4));
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, position.z + 5)); grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, 5));
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y + 1, position.z + 4)); grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 4));
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y + 1, position.z + 5)); grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 5));
} }
export function bush(grid, position) { export function bush(grid, position) {
let leaves = Sprite.tile(1); let leaves = Sprite.tile(1);

View File

@ -47,56 +47,46 @@ export class Grid {
tileSize: number; tileSize: number;
width: number; width: number;
breadth: number; length: number;
height: number; height: number;
topHeight: number; constructor(position: Vec3, tileSize: number, width: number, length: number, height: number) {
constructor(position: Vec3, tileSize: number, width: number, breadth: number, height: number) {
this.tiles3d = new Array<Tile[]>(height); this.tiles3d = new Array<Tile[]>(height);
this.position = position; this.position = position;
this.tileSize = tileSize; this.tileSize = tileSize;
this.width = width; this.width = width;
this.breadth = breadth; this.length = length;
this.height = height; this.height = height;
this.topHeight = 0; let layer = new Array(width * length);
let layer = new Array(width * breadth);
for (let i = 0; i < this.height; ++i) for (let i = 0; i < this.height; ++i)
this.tiles3d[i] = {...layer}; this.tiles3d[i] = {...layer};
} }
fillLayer(tile: Tile, z: number) { fillLayer(tile: Tile, z: number) {
if (z + 1 > this.topHeight)
this.topHeight = z + 1;
for (let i = 0; i < this.width; ++i) { for (let i = 0; i < this.width; ++i) {
for (let j = 0; j < this.breadth; ++j) { for (let j = 0; j < this.length; ++j) {
this.tiles3d[z][i + j * this.width] = {...tile}; this.tiles3d[z][i + j * this.width] = {...tile};
} }
} }
for (let i = 0; i < this.width; ++i) { for (let i = 0; i < this.width; ++i) {
this.tiles3d[z][this.breadth * i - 1] = {...tile, edge: TileEdge.Right}; this.tiles3d[z][this.length * i - 1] = {...tile, edge: TileEdge.Right};
} }
for (let i = 0; i < this.breadth - 1; ++i) { for (let i = 0; i < this.length - 1; ++i) {
this.tiles3d[z][this.width * (this.breadth - 1) + i] = {...tile, edge: TileEdge.Left}; this.tiles3d[z][this.width * (this.length - 1) + i] = {...tile, edge: TileEdge.Left};
} }
this.tiles3d[z][this.width * this.breadth - 1] = {...tile, edge: TileEdge.Both}; this.tiles3d[z][this.width * this.length - 1] = {...tile, edge: TileEdge.Both};
} }
setTile(tile: Tile, coord: Vec3) { setTile(tile: Tile, coord: Vec3) {
let index = coord.x + coord.y * this.width; let index = coord.x + coord.y * this.width;
this.tiles3d[coord.z][index] = {...tile}; this.tiles3d[coord.z][index] = {...tile};
if (coord.z + 1 > this.topHeight)
this.topHeight = coord.z + 1;
} }
getTile(coord: Vec3): Tile | null { getTile(coord: Vec3): Tile | null {
@ -109,22 +99,22 @@ export class Grid {
} }
} }
export function tree(grid: Grid, position: Vec3) { export function tree(grid: Grid, position: Vec2) {
let log = Sprite.tile(2); let log = Sprite.tile(2);
let leaves = Sprite.tile(1); let leaves = Sprite.tile(1);
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, position.z + 1)); grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 1));
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, position.z + 2)); grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 2));
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, position.z + 3)); grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 3));
grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, position.z + 4)); grid.setTile(new Tile(log, TileEdge.Both), new Vec3(position.x, position.y, 4));
grid.setTile(new Tile(log, TileEdge.None), new Vec3(position.x, position.y, position.z + 4)); grid.setTile(new Tile(log, TileEdge.None), new Vec3(position.x, position.y, 4));
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, position.z + 4)); grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, 4));
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, position.z + 5)); grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y + 1, 5));
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y, position.z + 5)); grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x, position.y, 5));
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, position.z + 4)); grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, 4));
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, position.z + 5)); grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y, 5));
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y + 1, position.z + 4)); grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 4));
grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y + 1, position.z + 5)); grid.setTile(new Tile(leaves, TileEdge.Both), new Vec3(position.x + 1, position.y + 1, 5));
} }
export function bush(grid: Grid, position: Vec2) { export function bush(grid: Grid, position: Vec2) {

View File

@ -1,20 +1,20 @@
#include "wasmgl.h" #include "wasmgl.h"
void doubel(WASMGLvalue(data)) void doubel(WASMGLvalue(0))
{ {
for (int i = 0; i < size_data; ++i) for (int i = 0; i < size_0; ++i)
WASMGLset(ptr_data + i, WASMGLmemory[ptr_data + i] * 2.0); WASMGLset(ptr_0 + i, WASMGLmemory[ptr_0 + i] * 2.0);
} }
void uppercase(WASMGLvalue(data)) { void uppercase(WASMGLvalue(0)) {
int val = 0; int val = 0;
for (int i = 0; i < size_data; ++i) for (int i = 0; i < size_0; ++i)
{ {
val = WASMGLmemory[ptr_data + i] - 32; val = WASMGLmemory[ptr_0 + i] - 32;
if (val < 65 || val > 122) val = WASMGLmemory[ptr_data + i]; if (val < 65 || val > 122) val = WASMGLmemory[ptr_0 + i];
WASMGLset(ptr_data + i, val); WASMGLset(ptr_0 + i, val);
} }
} }

View File

@ -17,7 +17,7 @@ extern float WASMGLmemory[WASMGLmemory_size];
typedef unsigned int WASMGLptr; typedef unsigned int WASMGLptr;
typedef unsigned int WASMGLsize; typedef unsigned int WASMGLsize;
#define WASMGLvalue(name) WASMGLptr ptr_##name, WASMGLsize size_##name #define WASMGLvalue(n) WASMGLptr ptr_##n, WASMGLsize size_##n
WASMGLptr WASMGLmalloc(WASMGLsize size); WASMGLptr WASMGLmalloc(WASMGLsize size);
void WASMGLset(WASMGLptr ptr, int value); void WASMGLset(WASMGLptr ptr, int value);