3D game
This commit is contained in:
+18
-21
@@ -1,20 +1,17 @@
|
|||||||
import { Component } from "$/common/ecs/mod.ts";
|
import { Component } from "$/common/ecs/mod.ts";
|
||||||
|
|
||||||
export class Camera extends Component {
|
export class Camera extends Component {
|
||||||
active = true;
|
x = 0;
|
||||||
x: number;
|
y = 0;
|
||||||
y: number;
|
z = 3;
|
||||||
zoom: number;
|
|
||||||
rotation = 0;
|
|
||||||
offset_x = 0;
|
|
||||||
offset_y = 0;
|
|
||||||
|
|
||||||
constructor(x = 0, y = 0, zoom = 1) {
|
pitch = 0;
|
||||||
super();
|
yaw = 0;
|
||||||
this.x = x;
|
roll = 0;
|
||||||
this.y = y;
|
|
||||||
this.zoom = zoom;
|
fov = Math.PI / 3;
|
||||||
}
|
near = 0.1;
|
||||||
|
far = 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function screen_to_world(
|
export function screen_to_world(
|
||||||
@@ -24,10 +21,10 @@ export function screen_to_world(
|
|||||||
screen_width: number,
|
screen_width: number,
|
||||||
screen_height: number,
|
screen_height: number,
|
||||||
) {
|
) {
|
||||||
return {
|
// return {
|
||||||
x: (screen_x - screen_width / 2) / camera.zoom + camera.x,
|
// x: (screen_x - screen_width / 2) / camera.zoom + camera.x,
|
||||||
y: (screen_y - screen_height / 2) / camera.zoom + camera.y,
|
// y: (screen_y - screen_height / 2) / camera.zoom + camera.y,
|
||||||
};
|
// };
|
||||||
}
|
}
|
||||||
|
|
||||||
export function world_to_screen(
|
export function world_to_screen(
|
||||||
@@ -37,8 +34,8 @@ export function world_to_screen(
|
|||||||
screen_width: number,
|
screen_width: number,
|
||||||
screen_height: number,
|
screen_height: number,
|
||||||
) {
|
) {
|
||||||
return {
|
// return {
|
||||||
x: (world_x - camera.x) / camera.zoom + screen_width / 2,
|
// x: (world_x - camera.x) / camera.zoom + screen_width / 2,
|
||||||
y: (world_y - camera.y) / camera.zoom + screen_height / 2,
|
// y: (world_y - camera.y) / camera.zoom + screen_height / 2,
|
||||||
};
|
// };
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { Texture } from "../renderer/mod.ts";
|
|||||||
export interface Tile<T = unknown> {
|
export interface Tile<T = unknown> {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
|
z: number;
|
||||||
id: string;
|
id: string;
|
||||||
data?: T;
|
data?: T;
|
||||||
tickable?: boolean;
|
tickable?: boolean;
|
||||||
|
|||||||
@@ -2,11 +2,11 @@ import { Component } from "$/common/ecs/mod.ts";
|
|||||||
import { KeyCode } from "$/client/input_manager.ts";
|
import { KeyCode } from "$/client/input_manager.ts";
|
||||||
|
|
||||||
export class PlayerControls extends Component {
|
export class PlayerControls extends Component {
|
||||||
move_speed: number = 100;
|
move_speed: number = 5;
|
||||||
|
|
||||||
// Keys
|
// Keys
|
||||||
move_up: KeyCode = "KeyW";
|
move_forward: KeyCode = "KeyW";
|
||||||
move_down: KeyCode = "KeyS";
|
move_backwards: KeyCode = "KeyS";
|
||||||
move_left: KeyCode = "KeyA";
|
move_left: KeyCode = "KeyA";
|
||||||
move_right: KeyCode = "KeyD";
|
move_right: KeyCode = "KeyD";
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ export function start_game(world: ClientWorld) {
|
|||||||
world.dimension = new Dimension([]);
|
world.dimension = new Dimension([]);
|
||||||
dimension.add(world.dimension);
|
dimension.add(world.dimension);
|
||||||
world.add_entity(dimension);
|
world.add_entity(dimension);
|
||||||
generate(dimension.get(Dimension)!, 100, 100);
|
generate(dimension.get(Dimension)!, 20, 20);
|
||||||
|
|
||||||
create_player(world);
|
create_player(world);
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,13 @@ export function generate(dimension: Dimension, width: number, height: number, se
|
|||||||
|
|
||||||
const scale = 0.05;
|
const scale = 0.05;
|
||||||
|
|
||||||
for (let y = 0; y < height; y++) {
|
for (let z = 0; z < height; z++) {
|
||||||
for (let x = 0; x < width; x++) {
|
for (let x = 0; x < width; x++) {
|
||||||
// multi-octave terrain
|
// multi-octave terrain
|
||||||
const nx = x * scale;
|
const nx = x * scale;
|
||||||
const ny = y * scale;
|
const nz = z * scale;
|
||||||
|
|
||||||
let h = height_noise(nx, ny) * 1 + height_noise(nx * 2, ny * 2) * 0.5 + height_noise(nx * 4, ny * 4) * 0.25;
|
let h = height_noise(nx, nz) * 1 + height_noise(nx * 2, nz * 2) * 0.5 + height_noise(nx * 4, nz * 4) * 0.25;
|
||||||
|
|
||||||
h /= 1.75; // normalize
|
h /= 1.75; // normalize
|
||||||
|
|
||||||
@@ -28,10 +28,10 @@ export function generate(dimension: Dimension, width: number, height: number, se
|
|||||||
id = "bworld:grass";
|
id = "bworld:grass";
|
||||||
}
|
}
|
||||||
|
|
||||||
dimension.tiles.push({ x, y, id });
|
dimension.tiles.push({ x, z, id, y: 0 });
|
||||||
|
|
||||||
// tree placement
|
// tree placement
|
||||||
if (id === "bworld:grass") {
|
/*if (id === "bworld:grass") {
|
||||||
const t = tree_noise(x * 0.12, y * 0.12);
|
const t = tree_noise(x * 0.12, y * 0.12);
|
||||||
|
|
||||||
if (t > 0.65) {
|
if (t > 0.65) {
|
||||||
@@ -41,7 +41,7 @@ export function generate(dimension: Dimension, width: number, height: number, se
|
|||||||
id: "bworld:tree",
|
id: "bworld:tree",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+93
-13
@@ -1,3 +1,5 @@
|
|||||||
|
import { canvas } from "./renderer/core.ts";
|
||||||
|
|
||||||
export type KeyCode =
|
export type KeyCode =
|
||||||
// letters
|
// letters
|
||||||
| "KeyA"
|
| "KeyA"
|
||||||
@@ -89,9 +91,16 @@ export class InputManager {
|
|||||||
|
|
||||||
static typed_characters = new Set<string>();
|
static typed_characters = new Set<string>();
|
||||||
|
|
||||||
|
static pointer_lock_flag = false;
|
||||||
|
static mouse_grab_timer = 0;
|
||||||
|
static mouse_ungrab_timer = 0;
|
||||||
|
static mouse_ungrab_timeout = -1;
|
||||||
|
static pointer_lock_waiting = false;
|
||||||
|
|
||||||
static initialize(canvas: HTMLCanvasElement) {
|
static initialize(canvas: HTMLCanvasElement) {
|
||||||
self.addEventListener("keydown", (e) => {
|
self.addEventListener("keydown", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
if (!this.keys_down.has(e.code)) {
|
if (!this.keys_down.has(e.code)) {
|
||||||
this.keys_pressed.add(e.code);
|
this.keys_pressed.add(e.code);
|
||||||
}
|
}
|
||||||
@@ -103,12 +112,18 @@ export class InputManager {
|
|||||||
|
|
||||||
self.addEventListener("keyup", (e) => {
|
self.addEventListener("keyup", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
this.keys_down.delete(e.code);
|
this.keys_down.delete(e.code);
|
||||||
this.keys_released.add(e.code);
|
this.keys_released.add(e.code);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.addEventListener("mousedown", (e) => {
|
self.addEventListener("mousedown", (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
if (!document.hasFocus() && document.pointerLockElement !== canvas) {
|
||||||
|
this.set_mouse_grabbed(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!this.mouse_buttons_down.has(e.button)) {
|
if (!this.mouse_buttons_down.has(e.button)) {
|
||||||
this.mouse_buttons_pressed.add(e.button);
|
this.mouse_buttons_pressed.add(e.button);
|
||||||
}
|
}
|
||||||
@@ -121,22 +136,44 @@ export class InputManager {
|
|||||||
this.mouse_buttons_released.add(e.button);
|
this.mouse_buttons_released.add(e.button);
|
||||||
});
|
});
|
||||||
|
|
||||||
self.addEventListener("mousemove", (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
const rect = canvas.getBoundingClientRect();
|
|
||||||
const new_x = e.clientX - rect.left;
|
|
||||||
const new_y = e.clientY - rect.top;
|
|
||||||
|
|
||||||
this.mouse_delta_x += new_x - this.mouse_x;
|
|
||||||
this.mouse_delta_y += new_y - this.mouse_y;
|
|
||||||
|
|
||||||
this.mouse_x = new_x;
|
|
||||||
this.mouse_y = new_y;
|
|
||||||
});
|
|
||||||
|
|
||||||
self.addEventListener("wheel", (e) => {
|
self.addEventListener("wheel", (e) => {
|
||||||
this.wheel_delta += e.deltaY;
|
this.wheel_delta += e.deltaY;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.addEventListener("mousemove", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (document.pointerLockElement) {
|
||||||
|
this.mouse_delta_x += e.movementX;
|
||||||
|
this.mouse_delta_y += e.movementY;
|
||||||
|
} else {
|
||||||
|
const rect = canvas.getBoundingClientRect();
|
||||||
|
const new_x = e.clientX - rect.left;
|
||||||
|
const new_y = e.clientY - rect.top;
|
||||||
|
|
||||||
|
this.mouse_delta_x += new_x - this.mouse_x;
|
||||||
|
this.mouse_delta_y += new_y - this.mouse_y;
|
||||||
|
|
||||||
|
this.mouse_x = new_x;
|
||||||
|
this.mouse_y = new_y;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("pointerlockchange", () => {
|
||||||
|
self.setTimeout(() => {
|
||||||
|
const grab = document.pointerLockElement === canvas;
|
||||||
|
if (!grab) {
|
||||||
|
if (this.pointer_lock_flag) {
|
||||||
|
this.mouse_ungrab_timer = performance.now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.pointer_lock_flag = grab;
|
||||||
|
}, 60);
|
||||||
|
this.pointer_lock_waiting = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener("pointerlockerror", () => {
|
||||||
|
this.pointer_lock_waiting = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static is_key_down(code: KeyCode): boolean {
|
static is_key_down(code: KeyCode): boolean {
|
||||||
@@ -197,4 +234,47 @@ export class InputManager {
|
|||||||
this.typed_characters.clear();
|
this.typed_characters.clear();
|
||||||
this.mouse_buttons_consumed.clear();
|
this.mouse_buttons_consumed.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static async set_mouse_grabbed(grab: boolean) {
|
||||||
|
this.pointer_lock_flag = grab;
|
||||||
|
const t = performance.now();
|
||||||
|
this.mouse_grab_timer = t;
|
||||||
|
if (grab) {
|
||||||
|
this.mouse_x = -1;
|
||||||
|
this.mouse_y = -1;
|
||||||
|
this.pointer_lock_waiting = true;
|
||||||
|
try {
|
||||||
|
await canvas.requestPointerLock();
|
||||||
|
} catch (_) { /* */ }
|
||||||
|
if (this.mouse_ungrab_timeout !== -1) {
|
||||||
|
self.clearTimeout(this.mouse_ungrab_timeout);
|
||||||
|
}
|
||||||
|
this.mouse_ungrab_timeout = -1;
|
||||||
|
if (t - this.mouse_ungrab_timer < 3000) {
|
||||||
|
this.mouse_ungrab_timeout = self.setTimeout(async () => {
|
||||||
|
try {
|
||||||
|
await canvas.requestPointerLock();
|
||||||
|
} catch (_) { /* */ }
|
||||||
|
}, 3100 - (t - this.mouse_ungrab_timer));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this.mouse_ungrab_timeout !== -1) self.clearTimeout(this.mouse_ungrab_timeout);
|
||||||
|
this.mouse_ungrab_timeout = -1;
|
||||||
|
if (!this.pointer_lock_waiting) {
|
||||||
|
document.exitPointerLock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static is_mouse_grabbed() {
|
||||||
|
return document.hasFocus() && document.pointerLockElement === canvas;
|
||||||
|
}
|
||||||
|
|
||||||
|
static toggle_fullscreen() {
|
||||||
|
if (!document.fullscreenElement) {
|
||||||
|
canvas.requestFullscreen();
|
||||||
|
} else {
|
||||||
|
document.exitFullscreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-24
@@ -4,9 +4,7 @@ import { Component, Entity } from "$/common/ecs/mod.ts";
|
|||||||
import { Camera } from "$/client/components/camera.ts";
|
import { Camera } from "$/client/components/camera.ts";
|
||||||
import { ItemStack, PlayerInventory } from "./inventory.ts";
|
import { ItemStack, PlayerInventory } from "./inventory.ts";
|
||||||
import { PlayerControls } from "$/client/components/player_controls.ts";
|
import { PlayerControls } from "$/client/components/player_controls.ts";
|
||||||
import { AnimatedSprite, Sprite } from "$/client/components/sprite.ts";
|
|
||||||
import { ClientWorld } from "./client_world.ts";
|
import { ClientWorld } from "./client_world.ts";
|
||||||
import { AssetManager } from "./assets.ts";
|
|
||||||
import { GuiScreen } from "./gui/gui_screen.ts";
|
import { GuiScreen } from "./gui/gui_screen.ts";
|
||||||
|
|
||||||
export class PlayerComponent extends Component {
|
export class PlayerComponent extends Component {
|
||||||
@@ -23,26 +21,8 @@ export class PlayerComponent extends Component {
|
|||||||
|
|
||||||
export function create_player(world: ClientWorld) {
|
export function create_player(world: ClientWorld) {
|
||||||
const player = new Entity("player");
|
const player = new Entity("player");
|
||||||
player.add(new Position(1440, 700));
|
player.add(new Position(0, 0));
|
||||||
player.add(new Velocity(0, 0));
|
player.add(new Velocity(0, 0));
|
||||||
player.add(
|
|
||||||
new AnimatedSprite("bworld:player", 72, 72, {
|
|
||||||
"idle": {
|
|
||||||
source_x: [0, 24],
|
|
||||||
source_y: [0, 0],
|
|
||||||
source_width: 24,
|
|
||||||
source_height: 24,
|
|
||||||
duration: 60,
|
|
||||||
},
|
|
||||||
"running": {
|
|
||||||
source_x: [0, 24, 48, 72, 96, 120, 144, 168],
|
|
||||||
source_y: [24, 24, 24, 24, 24, 24, 24, 24],
|
|
||||||
source_width: 24,
|
|
||||||
source_height: 24,
|
|
||||||
duration: 20,
|
|
||||||
},
|
|
||||||
}, "idle"),
|
|
||||||
);
|
|
||||||
player.add(new PlayerControls());
|
player.add(new PlayerControls());
|
||||||
|
|
||||||
player.add(new PlayerComponent());
|
player.add(new PlayerComponent());
|
||||||
@@ -58,14 +38,12 @@ export function create_player(world: ClientWorld) {
|
|||||||
// player_inventory.container.add_item(new ItemStack("bworld:pumpkin_seeds", 64));
|
// player_inventory.container.add_item(new ItemStack("bworld:pumpkin_seeds", 64));
|
||||||
// player_inventory.container.add_item(new ItemStack("bworld:carrot_seeds", 64));
|
// player_inventory.container.add_item(new ItemStack("bworld:carrot_seeds", 64));
|
||||||
player_inventory.container.add_item(new ItemStack("bworld:furnace", 1));
|
player_inventory.container.add_item(new ItemStack("bworld:furnace", 1));
|
||||||
player.add(new Camera(-100, -100));
|
player.add(new Camera());
|
||||||
|
|
||||||
world.add_entity(player);
|
world.add_entity(player);
|
||||||
|
|
||||||
const player_hand = new Entity("playerhand");
|
const player_hand = new Entity("playerhand");
|
||||||
player_hand.add(new Position(0, 0));
|
player_hand.add(new Position(0, 0));
|
||||||
// empty sprite
|
|
||||||
player_hand.add(new Sprite(AssetManager.instance.get("bworld:textures"), 0, 0));
|
|
||||||
world.add_entity(player_hand);
|
world.add_entity(player_hand);
|
||||||
|
|
||||||
world.add_tag("player", [player, player_hand]);
|
world.add_tag("player", [player, player_hand]);
|
||||||
|
|||||||
+123
-303
@@ -1,33 +1,21 @@
|
|||||||
import { Camera } from "../components/camera.ts";
|
import { Camera } from "../components/camera.ts";
|
||||||
import { mat4_mul, mat4_perspective, mat4_view } from "./math.ts";
|
import { mat4 } from "gl-matrix";
|
||||||
|
|
||||||
|
export let gl: WebGLRenderingContext;
|
||||||
|
export let canvas: HTMLCanvasElement;
|
||||||
|
|
||||||
const MAX_SPRITES = 10000;
|
const MAX_SPRITES = 10000;
|
||||||
const VERTS_PER_SPRITE = 6;
|
const VERTS_PER_SPRITE = 6;
|
||||||
const FLOATS_PER_VERT = 9;
|
const FLOATS_PER_VERT = 9;
|
||||||
|
|
||||||
export let gl: WebGLRenderingContext;
|
|
||||||
export let canvas: HTMLCanvasElement;
|
|
||||||
let program: WebGLProgram;
|
let program: WebGLProgram;
|
||||||
let buffer: WebGLBuffer;
|
let buffer: WebGLBuffer;
|
||||||
|
|
||||||
// const default_camera = new Camera();
|
|
||||||
// let camera: Camera = default_camera;
|
|
||||||
//
|
|
||||||
// let camera_pos_loc: WebGLUniformLocation | null;
|
|
||||||
// let camera_zoom_loc: WebGLUniformLocation | null;
|
|
||||||
// let camera_rot_loc: WebGLUniformLocation | null;
|
|
||||||
// let camera_offset_loc: WebGLUniformLocation | null;
|
|
||||||
|
|
||||||
export const projection = new Float32Array(16);
|
|
||||||
export const view = new Float32Array(16);
|
|
||||||
export const mvp_matrix = new Float32Array(16);
|
|
||||||
|
|
||||||
const vertex_data = new Float32Array(MAX_SPRITES * VERTS_PER_SPRITE * FLOATS_PER_VERT);
|
const vertex_data = new Float32Array(MAX_SPRITES * VERTS_PER_SPRITE * FLOATS_PER_VERT);
|
||||||
let vert_index = 0;
|
let vert_index = 0;
|
||||||
|
|
||||||
let pos_loc: GLint;
|
let pos_loc: GLint;
|
||||||
let uv_loc: GLint;
|
let uv_loc: GLint;
|
||||||
let resolution_loc: WebGLUniformLocation | null;
|
|
||||||
let texture_loc: WebGLUniformLocation | null;
|
let texture_loc: WebGLUniformLocation | null;
|
||||||
let mvp_loc: WebGLUniformLocation | null;
|
let mvp_loc: WebGLUniformLocation | null;
|
||||||
let col_diffuse_loc: WebGLUniformLocation | null;
|
let col_diffuse_loc: WebGLUniformLocation | null;
|
||||||
@@ -35,22 +23,14 @@ let col_diffuse_loc: WebGLUniformLocation | null;
|
|||||||
let current_texture: WebGLTexture | null = null;
|
let current_texture: WebGLTexture | null = null;
|
||||||
export let white_tex: WebGLTexture | null = null;
|
export let white_tex: WebGLTexture | null = null;
|
||||||
|
|
||||||
export const camera = {
|
|
||||||
x: 3,
|
|
||||||
y: 3,
|
|
||||||
z: 3,
|
|
||||||
|
|
||||||
pitch: 0,
|
|
||||||
yaw: 0,
|
|
||||||
roll: 0,
|
|
||||||
|
|
||||||
fov: Math.PI / 3,
|
|
||||||
near: 0.1,
|
|
||||||
far: 1000,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mode3d = false;
|
let mode3d = false;
|
||||||
let active_camera = camera;
|
|
||||||
|
let camera: Camera | undefined;
|
||||||
|
|
||||||
|
const ortho = mat4.create();
|
||||||
|
const proj = mat4.create();
|
||||||
|
const view = mat4.create();
|
||||||
|
const mvp = mat4.create();
|
||||||
|
|
||||||
const vertex_src = `#version 300 es
|
const vertex_src = `#version 300 es
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
@@ -121,15 +101,13 @@ export function init_window(canvas_element: HTMLCanvasElement) {
|
|||||||
gl.enable(gl.BLEND);
|
gl.enable(gl.BLEND);
|
||||||
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
gl.disable(gl.CULL_FACE);
|
|
||||||
|
|
||||||
create_white_texture();
|
create_white_texture();
|
||||||
|
|
||||||
update_mvp(canvas.width, canvas.height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function begin_drawing() {
|
export function begin_drawing() {
|
||||||
update_2d_mvp();
|
update_2d_mvp();
|
||||||
|
gl.depthFunc(gl.LEQUAL);
|
||||||
|
gl.clearDepth(1.0);
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||||
vert_index = 0;
|
vert_index = 0;
|
||||||
}
|
}
|
||||||
@@ -138,49 +116,35 @@ export function end_drawing() {
|
|||||||
flush_batch();
|
flush_batch();
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ortho_matrix = new Float32Array(16);
|
function update_2d_mvp() {
|
||||||
|
|
||||||
export function update_2d_mvp() {
|
|
||||||
const w = canvas.width;
|
const w = canvas.width;
|
||||||
const h = canvas.height;
|
const h = canvas.height;
|
||||||
const l = 0, r = w, t = 0, b = h, n = -1, f = 1;
|
|
||||||
|
|
||||||
ortho_matrix[0] = 2 / (r - l);
|
const l = 0;
|
||||||
ortho_matrix[1] = 0;
|
const r = w;
|
||||||
ortho_matrix[2] = 0;
|
const t = 0;
|
||||||
ortho_matrix[3] = 0;
|
const b = h;
|
||||||
|
const n = -1;
|
||||||
|
const f = 1;
|
||||||
|
|
||||||
ortho_matrix[4] = 0;
|
mat4.ortho(ortho, l, r, b, t, n, f);
|
||||||
ortho_matrix[5] = 2 / (t - b);
|
|
||||||
ortho_matrix[6] = 0;
|
|
||||||
ortho_matrix[7] = 0;
|
|
||||||
|
|
||||||
ortho_matrix[8] = 0;
|
|
||||||
ortho_matrix[9] = 0;
|
|
||||||
ortho_matrix[10] = -2 / (f - n);
|
|
||||||
ortho_matrix[11] = 0;
|
|
||||||
|
|
||||||
ortho_matrix[12] = -(r + l) / (r - l);
|
|
||||||
ortho_matrix[13] = -(t + b) / (t - b);
|
|
||||||
ortho_matrix[14] = -(f + n) / (f - n);
|
|
||||||
ortho_matrix[15] = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function begin_mode_2d(new_camera: Camera) {
|
//export function begin_mode_2d(new_camera: Camera) {
|
||||||
mode3d = false;
|
// mode3d = false;
|
||||||
|
//
|
||||||
|
// gl.disable(gl.DEPTH_TEST);
|
||||||
|
//
|
||||||
|
// vert_index = 0;
|
||||||
|
//
|
||||||
|
// update_2d_mvp();
|
||||||
|
// gl.uniformMatrix4fv(mvp_loc, false, ortho_matrix);
|
||||||
|
//}
|
||||||
|
|
||||||
gl.disable(gl.DEPTH_TEST);
|
// export function end_mode_2d() {
|
||||||
|
// flush_batch();
|
||||||
vert_index = 0;
|
// // camera = default_camera;
|
||||||
|
// }
|
||||||
update_2d_mvp();
|
|
||||||
gl.uniformMatrix4fv(mvp_loc, false, ortho_matrix);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function end_mode_2d() {
|
|
||||||
flush_batch();
|
|
||||||
// camera = default_camera;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function begin_clip(x: number, y: number, width: number, height: number) {
|
export function begin_clip(x: number, y: number, width: number, height: number) {
|
||||||
gl.enable(gl.SCISSOR_TEST);
|
gl.enable(gl.SCISSOR_TEST);
|
||||||
@@ -194,6 +158,28 @@ export function end_clip() {
|
|||||||
gl.disable(gl.SCISSOR_TEST);
|
gl.disable(gl.SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function begin_mode_3d(new_camera: Camera) {
|
||||||
|
flush_batch();
|
||||||
|
|
||||||
|
mode3d = true;
|
||||||
|
camera = new_camera;
|
||||||
|
|
||||||
|
gl.enable(gl.DEPTH_TEST);
|
||||||
|
|
||||||
|
update_camera();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function end_mode_3d() {
|
||||||
|
if (!mode3d) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flush_batch();
|
||||||
|
|
||||||
|
mode3d = false;
|
||||||
|
gl.disable(gl.DEPTH_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
export function clear_background(r: number, g: number, b: number, a = 1) {
|
export function clear_background(r: number, g: number, b: number, a = 1) {
|
||||||
gl.clearColor(r, g, b, a);
|
gl.clearColor(r, g, b, a);
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||||
@@ -208,9 +194,9 @@ export function flush_batch() {
|
|||||||
gl.bufferData(gl.ARRAY_BUFFER, vertex_data.subarray(0, vert_index), gl.STREAM_DRAW);
|
gl.bufferData(gl.ARRAY_BUFFER, vertex_data.subarray(0, vert_index), gl.STREAM_DRAW);
|
||||||
|
|
||||||
if (mode3d) {
|
if (mode3d) {
|
||||||
gl.uniformMatrix4fv(mvp_loc, false, mvp_matrix);
|
gl.uniformMatrix4fv(mvp_loc, false, mvp);
|
||||||
} else {
|
} else {
|
||||||
gl.uniformMatrix4fv(mvp_loc, false, ortho_matrix);
|
gl.uniformMatrix4fv(mvp_loc, false, ortho);
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.uniform4f(col_diffuse_loc, 1, 1, 1, 1);
|
gl.uniform4f(col_diffuse_loc, 1, 1, 1, 1);
|
||||||
@@ -224,6 +210,44 @@ export function flush_batch() {
|
|||||||
vert_index = 0;
|
vert_index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function resize_canvas() {
|
||||||
|
const width = self.innerWidth;
|
||||||
|
const height = self.innerHeight;
|
||||||
|
|
||||||
|
if (canvas.width !== width || canvas.height !== height) {
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
canvas.style.width = canvas.width + "px";
|
||||||
|
canvas.style.height = canvas.height + "px";
|
||||||
|
|
||||||
|
gl.viewport(0, 0, width, height);
|
||||||
|
|
||||||
|
gl.useProgram(program);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get_current_texture(): WebGLTexture | null {
|
||||||
|
return current_texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function set_current_texture(texture: WebGLTexture) {
|
||||||
|
current_texture = texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function push_vertex(px: number, py: number, pz: number, u: number, vv: number, r = 1, g = 1, b = 1, a = 1) {
|
||||||
|
let i = vert_index;
|
||||||
|
vertex_data[i++] = px;
|
||||||
|
vertex_data[i++] = py;
|
||||||
|
vertex_data[i++] = pz;
|
||||||
|
vertex_data[i++] = u;
|
||||||
|
vertex_data[i++] = vv;
|
||||||
|
vertex_data[i++] = r;
|
||||||
|
vertex_data[i++] = g;
|
||||||
|
vertex_data[i++] = b;
|
||||||
|
vertex_data[i++] = a;
|
||||||
|
vert_index = i;
|
||||||
|
}
|
||||||
|
|
||||||
export function push_quad(
|
export function push_quad(
|
||||||
dx: number,
|
dx: number,
|
||||||
dy: number,
|
dy: number,
|
||||||
@@ -241,97 +265,41 @@ export function push_quad(
|
|||||||
const x2 = dx + dw;
|
const x2 = dx + dw;
|
||||||
const y2 = dy + dh;
|
const y2 = dy + dh;
|
||||||
|
|
||||||
let i = vert_index;
|
|
||||||
|
|
||||||
// triangle 1
|
// triangle 1
|
||||||
vertex_data[i++] = dx;
|
push_vertex(dx, dy, 0, u0, v0, r, g, b, a);
|
||||||
vertex_data[i++] = dy;
|
push_vertex(x2, dy, 0, u1, v0, r, g, b, a);
|
||||||
vertex_data[i++] = 0;
|
push_vertex(dx, y2, 0, u0, v1, r, g, b, a);
|
||||||
vertex_data[i++] = u0;
|
|
||||||
vertex_data[i++] = v0;
|
|
||||||
vertex_data[i++] = r;
|
|
||||||
vertex_data[i++] = g;
|
|
||||||
vertex_data[i++] = b;
|
|
||||||
vertex_data[i++] = a;
|
|
||||||
|
|
||||||
vertex_data[i++] = x2;
|
|
||||||
vertex_data[i++] = dy;
|
|
||||||
vertex_data[i++] = 0;
|
|
||||||
vertex_data[i++] = u1;
|
|
||||||
vertex_data[i++] = v0;
|
|
||||||
vertex_data[i++] = r;
|
|
||||||
vertex_data[i++] = g;
|
|
||||||
vertex_data[i++] = b;
|
|
||||||
vertex_data[i++] = a;
|
|
||||||
|
|
||||||
vertex_data[i++] = dx;
|
|
||||||
vertex_data[i++] = y2;
|
|
||||||
vertex_data[i++] = 0;
|
|
||||||
vertex_data[i++] = u0;
|
|
||||||
vertex_data[i++] = v1;
|
|
||||||
vertex_data[i++] = r;
|
|
||||||
vertex_data[i++] = g;
|
|
||||||
vertex_data[i++] = b;
|
|
||||||
vertex_data[i++] = a;
|
|
||||||
|
|
||||||
// triangle 2
|
// triangle 2
|
||||||
vertex_data[i++] = x2;
|
push_vertex(x2, dy, 0, u1, v0, r, g, b, a);
|
||||||
vertex_data[i++] = dy;
|
push_vertex(x2, y2, 0, u1, v1, r, g, b, a);
|
||||||
vertex_data[i++] = 0;
|
push_vertex(dx, y2, 0, u0, v1, r, g, b, a);
|
||||||
vertex_data[i++] = u1;
|
|
||||||
vertex_data[i++] = v0;
|
|
||||||
vertex_data[i++] = r;
|
|
||||||
vertex_data[i++] = g;
|
|
||||||
vertex_data[i++] = b;
|
|
||||||
vertex_data[i++] = a;
|
|
||||||
|
|
||||||
vertex_data[i++] = x2;
|
|
||||||
vertex_data[i++] = y2;
|
|
||||||
vertex_data[i++] = 0;
|
|
||||||
vertex_data[i++] = u1;
|
|
||||||
vertex_data[i++] = v1;
|
|
||||||
vertex_data[i++] = r;
|
|
||||||
vertex_data[i++] = g;
|
|
||||||
vertex_data[i++] = b;
|
|
||||||
vertex_data[i++] = a;
|
|
||||||
|
|
||||||
vertex_data[i++] = dx;
|
|
||||||
vertex_data[i++] = y2;
|
|
||||||
vertex_data[i++] = 0;
|
|
||||||
vertex_data[i++] = u0;
|
|
||||||
vertex_data[i++] = v1;
|
|
||||||
vertex_data[i++] = r;
|
|
||||||
vertex_data[i++] = g;
|
|
||||||
vertex_data[i++] = b;
|
|
||||||
vertex_data[i++] = a;
|
|
||||||
|
|
||||||
vert_index = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resize_canvas() {
|
// internal
|
||||||
const width = self.innerWidth;
|
|
||||||
const height = self.innerHeight;
|
|
||||||
|
|
||||||
if (canvas.width !== width || canvas.height !== height) {
|
function update_camera() {
|
||||||
canvas.width = width;
|
if (!camera) {
|
||||||
canvas.height = height;
|
return;
|
||||||
canvas.style.width = canvas.width + "px";
|
|
||||||
canvas.style.height = canvas.height + "px";
|
|
||||||
|
|
||||||
gl.viewport(0, 0, width, height);
|
|
||||||
|
|
||||||
gl.useProgram(program);
|
|
||||||
// gl.uniform2f(resolution_loc, width, height);
|
|
||||||
update_mvp(canvas.width, canvas.height);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export function get_current_texture(): WebGLTexture | null {
|
mat4.perspective(
|
||||||
return current_texture;
|
proj,
|
||||||
}
|
camera.fov,
|
||||||
|
canvas.width / canvas.height,
|
||||||
|
camera.near,
|
||||||
|
camera.far,
|
||||||
|
);
|
||||||
|
|
||||||
export function set_current_texture(texture: WebGLTexture) {
|
mat4.identity(view);
|
||||||
current_texture = texture;
|
|
||||||
|
mat4.rotateZ(view, view, -camera.roll);
|
||||||
|
mat4.rotateX(view, view, -camera.pitch);
|
||||||
|
mat4.rotateY(view, view, -camera.yaw);
|
||||||
|
|
||||||
|
mat4.translate(view, view, [-camera.x, -camera.y, -camera.z]);
|
||||||
|
|
||||||
|
mat4.multiply(mvp, proj, view);
|
||||||
}
|
}
|
||||||
|
|
||||||
function compile_shader(type: number, src: string) {
|
function compile_shader(type: number, src: string) {
|
||||||
@@ -378,151 +346,3 @@ function create_white_texture() {
|
|||||||
|
|
||||||
white_tex = tex;
|
white_tex = tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_mvp(width: number, height: number) {
|
|
||||||
const l = 0;
|
|
||||||
const r = width;
|
|
||||||
const b = height;
|
|
||||||
const t = 0;
|
|
||||||
const n = -1;
|
|
||||||
const f = 1;
|
|
||||||
|
|
||||||
mvp_matrix[0] = 2 / (r - l);
|
|
||||||
mvp_matrix[1] = 0;
|
|
||||||
mvp_matrix[2] = 0;
|
|
||||||
mvp_matrix[3] = 0;
|
|
||||||
|
|
||||||
mvp_matrix[4] = 0;
|
|
||||||
mvp_matrix[5] = 2 / (t - b);
|
|
||||||
mvp_matrix[6] = 0;
|
|
||||||
mvp_matrix[7] = 0;
|
|
||||||
|
|
||||||
mvp_matrix[8] = 0;
|
|
||||||
mvp_matrix[9] = 0;
|
|
||||||
mvp_matrix[10] = -2 / (f - n);
|
|
||||||
mvp_matrix[11] = 0;
|
|
||||||
|
|
||||||
mvp_matrix[12] = -(r + l) / (r - l);
|
|
||||||
mvp_matrix[13] = -(t + b) / (t - b);
|
|
||||||
mvp_matrix[14] = -(f + n) / (f - n);
|
|
||||||
mvp_matrix[15] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function push_cube(
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
z: number,
|
|
||||||
w: number,
|
|
||||||
h: number,
|
|
||||||
d: number,
|
|
||||||
r = 1,
|
|
||||||
g = 1,
|
|
||||||
b = 1,
|
|
||||||
a = 1,
|
|
||||||
) {
|
|
||||||
set_current_texture(white_tex!);
|
|
||||||
|
|
||||||
const x2 = x + w;
|
|
||||||
const y2 = y + h;
|
|
||||||
const z2 = z + d;
|
|
||||||
|
|
||||||
const u0 = 0, v0 = 0;
|
|
||||||
const u1 = 1, v1 = 1;
|
|
||||||
|
|
||||||
let i = vert_index;
|
|
||||||
|
|
||||||
function v(px: number, py: number, pz: number, u: number, vv: number) {
|
|
||||||
vertex_data[i++] = px;
|
|
||||||
vertex_data[i++] = py;
|
|
||||||
vertex_data[i++] = pz;
|
|
||||||
vertex_data[i++] = u;
|
|
||||||
vertex_data[i++] = vv;
|
|
||||||
vertex_data[i++] = r;
|
|
||||||
vertex_data[i++] = g;
|
|
||||||
vertex_data[i++] = b;
|
|
||||||
vertex_data[i++] = a;
|
|
||||||
}
|
|
||||||
|
|
||||||
v(x, y, z2, u0, v0);
|
|
||||||
v(x2, y, z2, u1, v0);
|
|
||||||
v(x, y2, z2, u0, v1);
|
|
||||||
v(x2, y, z2, u1, v0);
|
|
||||||
v(x2, y2, z2, u1, v1);
|
|
||||||
v(x, y2, z2, u0, v1);
|
|
||||||
|
|
||||||
v(x2, y, z, u0, v0);
|
|
||||||
v(x, y, z, u1, v0);
|
|
||||||
v(x2, y2, z, u0, v1);
|
|
||||||
v(x, y, z, u1, v0);
|
|
||||||
v(x, y2, z, u1, v1);
|
|
||||||
v(x2, y2, z, u0, v1);
|
|
||||||
|
|
||||||
v(x, y, z, u0, v0);
|
|
||||||
v(x, y, z2, u1, v0);
|
|
||||||
v(x, y2, z, u0, v1);
|
|
||||||
v(x, y, z2, u1, v0);
|
|
||||||
v(x, y2, z2, u1, v1);
|
|
||||||
v(x, y2, z, u0, v1);
|
|
||||||
|
|
||||||
v(x2, y, z2, u0, v0);
|
|
||||||
v(x2, y, z, u1, v0);
|
|
||||||
v(x2, y2, z2, u0, v1);
|
|
||||||
v(x2, y, z, u1, v0);
|
|
||||||
v(x2, y2, z, u1, v1);
|
|
||||||
v(x2, y2, z2, u0, v1);
|
|
||||||
|
|
||||||
v(x, y2, z2, u0, v0);
|
|
||||||
v(x2, y2, z2, u1, v0);
|
|
||||||
v(x, y2, z, u0, v1);
|
|
||||||
v(x2, y2, z2, u1, v0);
|
|
||||||
v(x2, y2, z, u1, v1);
|
|
||||||
v(x, y2, z, u0, v1);
|
|
||||||
|
|
||||||
v(x, y, z, u0, v0);
|
|
||||||
v(x2, y, z, u1, v0);
|
|
||||||
v(x, y, z2, u0, v1);
|
|
||||||
v(x2, y, z, u1, v0);
|
|
||||||
v(x2, y, z2, u1, v1);
|
|
||||||
v(x, y, z2, u0, v1);
|
|
||||||
|
|
||||||
vert_index = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function begin_mode_3d() {
|
|
||||||
flush_batch();
|
|
||||||
|
|
||||||
mode3d = true;
|
|
||||||
active_camera = camera;
|
|
||||||
|
|
||||||
gl.enable(gl.DEPTH_TEST);
|
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
vert_index = 0;
|
|
||||||
|
|
||||||
update_camera();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function end_mode_3d() {
|
|
||||||
if (!mode3d) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
flush_batch();
|
|
||||||
|
|
||||||
mode3d = false;
|
|
||||||
gl.disable(gl.DEPTH_TEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function update_camera() {
|
|
||||||
mat4_perspective(
|
|
||||||
projection,
|
|
||||||
camera.fov,
|
|
||||||
canvas.width / canvas.height,
|
|
||||||
camera.near,
|
|
||||||
camera.far,
|
|
||||||
);
|
|
||||||
|
|
||||||
mat4_view(view);
|
|
||||||
|
|
||||||
mat4_mul(mvp_matrix, projection, view);
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
import { camera } from "./core.ts";
|
|
||||||
|
|
||||||
export function mat4_perspective(out: Float32Array, fov: number, aspect: number, near: number, far: number) {
|
|
||||||
const f = 1 / Math.tan(fov / 2);
|
|
||||||
|
|
||||||
out[0] = f / aspect;
|
|
||||||
out[1] = 0;
|
|
||||||
out[2] = 0;
|
|
||||||
out[3] = 0;
|
|
||||||
|
|
||||||
out[4] = 0;
|
|
||||||
out[5] = f;
|
|
||||||
out[6] = 0;
|
|
||||||
out[7] = 0;
|
|
||||||
|
|
||||||
out[8] = 0;
|
|
||||||
out[9] = 0;
|
|
||||||
out[10] = -(far + near) / (far - near);
|
|
||||||
out[11] = -1;
|
|
||||||
|
|
||||||
out[12] = 0;
|
|
||||||
out[13] = 0;
|
|
||||||
out[14] = -(2 * far * near) / (far - near);
|
|
||||||
out[15] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mat4_view(out: Float32Array) {
|
|
||||||
const cx = camera.x;
|
|
||||||
const cy = camera.y;
|
|
||||||
const cz = camera.z;
|
|
||||||
|
|
||||||
const yaw = camera.yaw;
|
|
||||||
const pitch = camera.pitch;
|
|
||||||
|
|
||||||
const cosY = Math.cos(yaw);
|
|
||||||
const sinY = Math.sin(yaw);
|
|
||||||
const cosP = Math.cos(pitch);
|
|
||||||
const sinP = Math.sin(pitch);
|
|
||||||
|
|
||||||
const fx = cosP * sinY;
|
|
||||||
const fy = sinP;
|
|
||||||
const fz = cosP * cosY;
|
|
||||||
|
|
||||||
const rx = cosY;
|
|
||||||
const rz = -sinY;
|
|
||||||
|
|
||||||
const ux = -sinP * sinY;
|
|
||||||
const uy = cosP;
|
|
||||||
const uz = -sinP * cosY;
|
|
||||||
|
|
||||||
out[0] = rx;
|
|
||||||
out[1] = ux;
|
|
||||||
out[2] = -fx;
|
|
||||||
out[3] = 0;
|
|
||||||
|
|
||||||
out[4] = 0;
|
|
||||||
out[5] = uy;
|
|
||||||
out[6] = -fy;
|
|
||||||
out[7] = 0;
|
|
||||||
|
|
||||||
out[8] = rz;
|
|
||||||
out[9] = uz;
|
|
||||||
out[10] = -fz;
|
|
||||||
out[11] = 0;
|
|
||||||
|
|
||||||
out[12] = -(rx * cx + rz * cz);
|
|
||||||
out[13] = -(ux * cx + uy * cy + uz * cz);
|
|
||||||
out[14] = fx * cx + fy * cy + fz * cz;
|
|
||||||
out[15] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mat4_mul(out: Float32Array, a: Float32Array, b: Float32Array) {
|
|
||||||
for (let i = 0; i < 4; i++) {
|
|
||||||
const ai0 = a[i];
|
|
||||||
const ai1 = a[i + 4];
|
|
||||||
const ai2 = a[i + 8];
|
|
||||||
const ai3 = a[i + 12];
|
|
||||||
|
|
||||||
out[i] = ai0 * b[0] + ai1 * b[1] + ai2 * b[2] + ai3 * b[3];
|
|
||||||
out[i + 4] = ai0 * b[4] + ai1 * b[5] + ai2 * b[6] + ai3 * b[7];
|
|
||||||
out[i + 8] = ai0 * b[8] + ai1 * b[9] + ai2 * b[10] + ai3 * b[11];
|
|
||||||
out[i + 12] = ai0 * b[12] + ai1 * b[13] + ai2 * b[14] + ai3 * b[15];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,4 +2,5 @@ export * from "./core.ts";
|
|||||||
export * from "./shapes.ts";
|
export * from "./shapes.ts";
|
||||||
export * from "./textures.ts";
|
export * from "./textures.ts";
|
||||||
export * from "./text.ts";
|
export * from "./text.ts";
|
||||||
|
export * from "./models.ts";
|
||||||
export * from "./types.ts";
|
export * from "./types.ts";
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import { flush_batch, get_current_texture, push_vertex, set_current_texture } from "./core.ts";
|
||||||
|
import { Texture } from "./types.ts";
|
||||||
|
|
||||||
|
export function push_cube(
|
||||||
|
texture: Texture,
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
z: number,
|
||||||
|
w: number,
|
||||||
|
h: number,
|
||||||
|
d: number,
|
||||||
|
sx: number,
|
||||||
|
sy: number,
|
||||||
|
sw: number,
|
||||||
|
sh: number,
|
||||||
|
r = 1,
|
||||||
|
g = 1,
|
||||||
|
b = 1,
|
||||||
|
a = 1,
|
||||||
|
) {
|
||||||
|
if (get_current_texture() !== texture.tex) {
|
||||||
|
flush_batch();
|
||||||
|
set_current_texture(texture.tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
const x2 = x + w;
|
||||||
|
const y2 = y + h;
|
||||||
|
const z2 = z + d;
|
||||||
|
|
||||||
|
const u0 = sx / texture.width;
|
||||||
|
const v0 = sy / texture.height;
|
||||||
|
const u1 = (sx + sw) / texture.width;
|
||||||
|
const v1 = (sy + sh) / texture.height;
|
||||||
|
|
||||||
|
push_vertex(x, y, z2, u0, v0, r, g, b, a);
|
||||||
|
push_vertex(x2, y, z2, u1, v0, r, g, b, a);
|
||||||
|
push_vertex(x, y2, z2, u0, v1, r, g, b, a);
|
||||||
|
push_vertex(x2, y, z2, u1, v0, r, g, b, a);
|
||||||
|
push_vertex(x2, y2, z2, u1, v1, r, g, b, a);
|
||||||
|
push_vertex(x, y2, z2, u0, v1, r, g, b, a);
|
||||||
|
|
||||||
|
push_vertex(x2, y, z, u0, v0, r, g, b, a);
|
||||||
|
push_vertex(x, y, z, u1, v0, r, g, b, a);
|
||||||
|
push_vertex(x2, y2, z, u0, v1, r, g, b, a);
|
||||||
|
push_vertex(x, y, z, u1, v0, r, g, b, a);
|
||||||
|
push_vertex(x, y2, z, u1, v1, r, g, b, a);
|
||||||
|
push_vertex(x2, y2, z, u0, v1, r, g, b, a);
|
||||||
|
|
||||||
|
push_vertex(x, y, z, u0, v0, r, g, b, a);
|
||||||
|
push_vertex(x, y, z2, u1, v0, r, g, b, a);
|
||||||
|
push_vertex(x, y2, z, u0, v1, r, g, b, a);
|
||||||
|
push_vertex(x, y, z2, u1, v0, r, g, b, a);
|
||||||
|
push_vertex(x, y2, z2, u1, v1, r, g, b, a);
|
||||||
|
push_vertex(x, y2, z, u0, v1, r, g, b, a);
|
||||||
|
|
||||||
|
push_vertex(x2, y, z2, u0, v0, r, g, b, a);
|
||||||
|
push_vertex(x2, y, z, u1, v0, r, g, b, a);
|
||||||
|
push_vertex(x2, y2, z2, u0, v1, r, g, b, a);
|
||||||
|
push_vertex(x2, y, z, u1, v0, r, g, b, a);
|
||||||
|
push_vertex(x2, y2, z, u1, v1, r, g, b, a);
|
||||||
|
push_vertex(x2, y2, z2, u0, v1, r, g, b, a);
|
||||||
|
|
||||||
|
push_vertex(x, y2, z2, u0, v0, r, g, b, a);
|
||||||
|
push_vertex(x2, y2, z2, u1, v0, r, g, b, a);
|
||||||
|
push_vertex(x, y2, z, u0, v1, r, g, b, a);
|
||||||
|
push_vertex(x2, y2, z2, u1, v0, r, g, b, a);
|
||||||
|
push_vertex(x2, y2, z, u1, v1, r, g, b, a);
|
||||||
|
push_vertex(x, y2, z, u0, v1, r, g, b, a);
|
||||||
|
|
||||||
|
push_vertex(x, y, z, u0, v0, r, g, b, a);
|
||||||
|
push_vertex(x2, y, z, u1, v0, r, g, b, a);
|
||||||
|
push_vertex(x, y, z2, u0, v1, r, g, b, a);
|
||||||
|
push_vertex(x2, y, z, u1, v0, r, g, b, a);
|
||||||
|
push_vertex(x2, y, z2, u1, v1, r, g, b, a);
|
||||||
|
push_vertex(x, y, z2, u0, v1, r, g, b, a);
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ import { distance_point_rectangle } from "../../common/utils.ts";
|
|||||||
|
|
||||||
export class DimensionLogicSystem extends System {
|
export class DimensionLogicSystem extends System {
|
||||||
update(world: ClientWorld, delta: number): void {
|
update(world: ClientWorld, delta: number): void {
|
||||||
const dimension_entity = world.get_entities().values().find((ent) => ent.get(Dimension));
|
/*const dimension_entity = world.get_entities().values().find((ent) => ent.get(Dimension));
|
||||||
const dimension = dimension_entity!.get(Dimension)!;
|
const dimension = dimension_entity!.get(Dimension)!;
|
||||||
|
|
||||||
dimension.second_timer += delta;
|
dimension.second_timer += delta;
|
||||||
@@ -72,7 +72,7 @@ export class DimensionLogicSystem extends System {
|
|||||||
tile_info.on_click(world, tile);
|
tile_info.on_click(world, tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
handle_second(world: ClientWorld, dimension: Dimension) {
|
handle_second(world: ClientWorld, dimension: Dimension) {
|
||||||
const tickables = dimension.tiles.filter((t) => t.tickable);
|
const tickables = dimension.tiles.filter((t) => t.tickable);
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import { System } from "$/common/ecs/mod.ts";
|
import { System } from "$/common/ecs/mod.ts";
|
||||||
import { Velocity } from "$/common/components/velocity.ts";
|
import { Velocity } from "$/common/components/velocity.ts";
|
||||||
import { InputManager } from "../input_manager.ts";
|
import { InputManager } from "../input_manager.ts";
|
||||||
import { AnimatedSprite } from "../components/sprite.ts";
|
|
||||||
import { ClientWorld } from "../client_world.ts";
|
import { ClientWorld } from "../client_world.ts";
|
||||||
import { PlayerControls } from "../components/player_controls.ts";
|
import { PlayerControls } from "../components/player_controls.ts";
|
||||||
import { Camera } from "../components/camera.ts";
|
import { Camera } from "../components/camera.ts";
|
||||||
import { Position } from "../../common/components/position.ts";
|
import { Position } from "../../common/components/position.ts";
|
||||||
import { canvas } from "../renderer/mod.ts";
|
|
||||||
import { PlayerComponent } from "../player.ts";
|
import { PlayerComponent } from "../player.ts";
|
||||||
import { GuiPlayerInventory } from "../gui/gui_player_inventory.ts";
|
import { GuiPlayerInventory } from "../gui/gui_player_inventory.ts";
|
||||||
|
|
||||||
@@ -20,40 +18,51 @@ export class PlayerControlsSystem extends System {
|
|||||||
const velocity = player.get(Velocity)!;
|
const velocity = player.get(Velocity)!;
|
||||||
const controls = player.get(PlayerControls)!;
|
const controls = player.get(PlayerControls)!;
|
||||||
const player_component = player.get(PlayerComponent)!;
|
const player_component = player.get(PlayerComponent)!;
|
||||||
|
const position = player.get(Position)!;
|
||||||
|
const camera = player.get(Camera)!;
|
||||||
|
|
||||||
|
let input_x = 0;
|
||||||
|
let input_z = 0;
|
||||||
|
|
||||||
if (InputManager.is_key_down(controls.move_left)) {
|
if (InputManager.is_key_down(controls.move_left)) {
|
||||||
velocity.vx = -controls.move_speed;
|
input_x -= 1;
|
||||||
} else if (InputManager.is_key_down(controls.move_right)) {
|
}
|
||||||
velocity.vx = controls.move_speed;
|
if (InputManager.is_key_down(controls.move_right)) {
|
||||||
} else {
|
input_x += 1;
|
||||||
velocity.vx = 0;
|
}
|
||||||
|
if (InputManager.is_key_down(controls.move_forward)) {
|
||||||
|
input_z -= 1;
|
||||||
|
}
|
||||||
|
if (InputManager.is_key_down(controls.move_backwards)) {
|
||||||
|
input_z += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InputManager.is_key_down(controls.move_up)) {
|
const size = Math.hypot(input_x, input_z);
|
||||||
velocity.vy = -controls.move_speed;
|
if (size > 0) {
|
||||||
} else if (InputManager.is_key_down(controls.move_down)) {
|
input_x /= size;
|
||||||
velocity.vy = controls.move_speed;
|
input_z /= size;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sin = Math.sin(camera.yaw);
|
||||||
|
const cos = Math.cos(camera.yaw);
|
||||||
|
|
||||||
|
const forwardX = sin;
|
||||||
|
const forwardZ = cos;
|
||||||
|
|
||||||
|
const rightX = cos;
|
||||||
|
const rightZ = -sin;
|
||||||
|
|
||||||
|
velocity.vx = (forwardX * input_z + rightX * input_x) * controls.move_speed;
|
||||||
|
velocity.vz = (forwardZ * input_z + rightZ * input_x) * controls.move_speed;
|
||||||
|
|
||||||
|
if (InputManager.is_key_down("Space")) {
|
||||||
|
velocity.vy += controls.move_speed / 10;
|
||||||
|
} else if (InputManager.is_key_down("ShiftLeft")) {
|
||||||
|
velocity.vy -= controls.move_speed / 10;
|
||||||
} else {
|
} else {
|
||||||
velocity.vy = 0;
|
velocity.vy = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const animated_sprite = player.get(AnimatedSprite)!;
|
|
||||||
|
|
||||||
if (
|
|
||||||
InputManager.is_key_down(controls.move_up) || InputManager.is_key_down(controls.move_down) ||
|
|
||||||
InputManager.is_key_down(controls.move_left) || InputManager.is_key_down(controls.move_right)
|
|
||||||
) {
|
|
||||||
animated_sprite.set_state("running");
|
|
||||||
} else {
|
|
||||||
animated_sprite.set_state("idle");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (InputManager.is_key_down(controls.move_left)) {
|
|
||||||
animated_sprite.flip_x = false;
|
|
||||||
} else if (InputManager.is_key_down(controls.move_right)) {
|
|
||||||
animated_sprite.flip_x = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (InputManager.is_key_pressed(controls.open_inventory)) {
|
if (InputManager.is_key_pressed(controls.open_inventory)) {
|
||||||
if (player_component.screens.length === 0) {
|
if (player_component.screens.length === 0) {
|
||||||
player_component.screens.push(new GuiPlayerInventory(player_component.player_inventory));
|
player_component.screens.push(new GuiPlayerInventory(player_component.player_inventory));
|
||||||
@@ -66,13 +75,24 @@ export class PlayerControlsSystem extends System {
|
|||||||
world.debugging = !world.debugging;
|
world.debugging = !world.debugging;
|
||||||
}
|
}
|
||||||
|
|
||||||
const position = player.get(Position)!;
|
if (InputManager.is_key_pressed("F11")) {
|
||||||
const camera = player.get(Camera)!;
|
InputManager.toggle_fullscreen();
|
||||||
|
}
|
||||||
|
|
||||||
camera.x = Math.round(position.x);
|
camera.x = position.x;
|
||||||
camera.y = Math.round(position.y);
|
camera.y = position.y + 1.79;
|
||||||
camera.offset_x = Math.floor(canvas.width / 2);
|
camera.z = position.z;
|
||||||
camera.offset_y = Math.floor(canvas.height / 2);
|
|
||||||
|
if (InputManager.is_mouse_grabbed()) {
|
||||||
|
const mouse_delta = InputManager.get_mouse_delta();
|
||||||
|
camera.yaw += -mouse_delta.x * 0.001;
|
||||||
|
camera.pitch += -mouse_delta.y * 0.001;
|
||||||
|
|
||||||
|
const limit = Math.PI / 2 - 0.01;
|
||||||
|
camera.pitch = Math.max(-limit, Math.min(limit, camera.pitch));
|
||||||
|
}
|
||||||
|
|
||||||
|
InputManager.set_mouse_grabbed(player_component.screens.length === 0);
|
||||||
|
|
||||||
if (player_component.screens.length === 0) {
|
if (player_component.screens.length === 0) {
|
||||||
const player_inventory = player_component.player_inventory;
|
const player_inventory = player_component.player_inventory;
|
||||||
|
|||||||
@@ -8,9 +8,8 @@ import { Camera } from "$/client/components/camera.ts";
|
|||||||
import { render_animated_sprite, render_sprite } from "./rendering/sprites.ts";
|
import { render_animated_sprite, render_sprite } from "./rendering/sprites.ts";
|
||||||
import { render_dimension } from "./rendering/dimension.ts";
|
import { render_dimension } from "./rendering/dimension.ts";
|
||||||
import { render_player_hotbar } from "./rendering/player.ts";
|
import { render_player_hotbar } from "./rendering/player.ts";
|
||||||
import { begin_mode_2d, end_mode_2d } from "../renderer/mod.ts";
|
|
||||||
import { PlayerComponent } from "../player.ts";
|
import { PlayerComponent } from "../player.ts";
|
||||||
import { begin_mode_3d, end_mode_3d, push_cube } from "../renderer/core.ts";
|
import { begin_mode_3d, end_mode_3d } from "../renderer/core.ts";
|
||||||
|
|
||||||
export class RenderSystem extends System {
|
export class RenderSystem extends System {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -18,83 +17,42 @@ export class RenderSystem extends System {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update(world: World, _delta: number): void {
|
update(world: World, _delta: number): void {
|
||||||
/*const camera_entity = world.get_entities().values().find((e) => e.get(Camera)?.active);
|
const camera_entity = world.get_entities().values().find((e) => e.get(Camera));
|
||||||
const camera = camera_entity?.get(Camera);
|
const camera = camera_entity?.get(Camera);
|
||||||
|
|
||||||
if (!camera) {
|
if (!camera) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
begin_mode_2d(camera);
|
begin_mode_3d(camera);
|
||||||
|
|
||||||
for (const entity of world.get_entities()) {
|
for (const entity of world.get_entities()) {
|
||||||
const position = entity.get(Position);
|
|
||||||
const sprite = entity.get(Sprite);
|
|
||||||
|
|
||||||
if (sprite && position) {
|
|
||||||
render_sprite(sprite, position, camera);
|
|
||||||
}
|
|
||||||
|
|
||||||
const animated_sprite = entity.get(AnimatedSprite);
|
|
||||||
|
|
||||||
if (animated_sprite && position) {
|
|
||||||
render_animated_sprite(animated_sprite, position, camera);
|
|
||||||
}
|
|
||||||
|
|
||||||
const dimension = entity.get(Dimension);
|
const dimension = entity.get(Dimension);
|
||||||
|
|
||||||
if (dimension) {
|
if (dimension) {
|
||||||
render_dimension(dimension, camera);
|
render_dimension(dimension /*, camera*/);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end_mode_2d();
|
end_mode_3d();
|
||||||
|
|
||||||
for (const entity of world.get_entities()) {
|
for (const entity of world.get_entities()) {
|
||||||
const player_component = entity.get(PlayerComponent);
|
const position = entity.get(Position);
|
||||||
|
|
||||||
|
const sprite = entity.get(Sprite);
|
||||||
|
if (position && sprite) {
|
||||||
|
render_sprite(sprite, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
const animated_sprite = entity.get(AnimatedSprite);
|
||||||
|
if (position && animated_sprite) {
|
||||||
|
render_animated_sprite(animated_sprite, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
const player_component = entity.get(PlayerComponent);
|
||||||
if (player_component) {
|
if (player_component) {
|
||||||
render_player_hotbar(player_component.player_inventory);
|
render_player_hotbar(player_component.player_inventory);
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
|
||||||
begin_mode_3d();
|
|
||||||
push_cube(
|
|
||||||
-0.5,
|
|
||||||
-0.5,
|
|
||||||
-0.5,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
push_cube(
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
0.5,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
push_cube(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
1,
|
|
||||||
);
|
|
||||||
end_mode_3d();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,11 @@
|
|||||||
import { get_sprite_region } from "$/common/utils.ts";
|
import { get_sprite_region } from "$/common/utils.ts";
|
||||||
import { Dimension } from "$/client/components/dimension.ts";
|
import { Dimension } from "$/client/components/dimension.ts";
|
||||||
import { TEXTURE_SIZE, TILE_SIZE } from "$/common/constants.ts";
|
import { TEXTURE_SIZE } from "$/common/constants.ts";
|
||||||
import { Camera, world_to_screen } from "$/client/components/camera.ts";
|
|
||||||
import { canvas, draw_texture_region } from "$/client/renderer/mod.ts";
|
|
||||||
import { EverythingRegistry, TileRegistry } from "$/common/everything_registry.ts";
|
import { EverythingRegistry, TileRegistry } from "$/common/everything_registry.ts";
|
||||||
|
import { push_cube } from "$/client/renderer/mod.ts";
|
||||||
|
|
||||||
export function render_dimension(dimension: Dimension, camera: Camera) {
|
export function render_dimension(dimension: Dimension /*, camera: Camera*/) {
|
||||||
for (const tile of dimension.tiles) {
|
for (const tile of dimension.tiles) {
|
||||||
const x = tile.x * TILE_SIZE;
|
|
||||||
const y = tile.y * TILE_SIZE;
|
|
||||||
|
|
||||||
const screen_position = world_to_screen(x, y, camera, canvas.width, canvas.height);
|
|
||||||
if (
|
|
||||||
screen_position.x + TILE_SIZE < 0 || screen_position.x > canvas.width ||
|
|
||||||
screen_position.y + TILE_SIZE < 0 || screen_position.y > canvas.height
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let texture_id = tile.id;
|
let texture_id = tile.id;
|
||||||
const tile_info = EverythingRegistry.get<TileRegistry>("tiles", tile.id);
|
const tile_info = EverythingRegistry.get<TileRegistry>("tiles", tile.id);
|
||||||
if (tile_info?.texture_id) {
|
if (tile_info?.texture_id) {
|
||||||
@@ -30,16 +18,18 @@ export function render_dimension(dimension: Dimension, camera: Camera) {
|
|||||||
|
|
||||||
const region = get_sprite_region(texture_id);
|
const region = get_sprite_region(texture_id);
|
||||||
|
|
||||||
draw_texture_region(
|
push_cube(
|
||||||
dimension.image,
|
dimension.image,
|
||||||
|
tile.x,
|
||||||
|
tile.y,
|
||||||
|
tile.z,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
region.x * TEXTURE_SIZE,
|
region.x * TEXTURE_SIZE,
|
||||||
region.y * TEXTURE_SIZE,
|
region.y * TEXTURE_SIZE,
|
||||||
TEXTURE_SIZE,
|
TEXTURE_SIZE,
|
||||||
TEXTURE_SIZE,
|
TEXTURE_SIZE,
|
||||||
x,
|
|
||||||
y,
|
|
||||||
TILE_SIZE,
|
|
||||||
TILE_SIZE,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
import { Position } from "$/common/components/position.ts";
|
import { Position } from "$/common/components/position.ts";
|
||||||
import { AnimatedSprite, Sprite } from "$/client/components/sprite.ts";
|
import { AnimatedSprite, Sprite } from "$/client/components/sprite.ts";
|
||||||
import { draw_texture_region } from "$/client/renderer/mod.ts";
|
import { draw_texture_region } from "$/client/renderer/mod.ts";
|
||||||
import { Camera } from "$/client/components/camera.ts";
|
|
||||||
|
|
||||||
// TODO: camera scale
|
export function render_sprite(sprite: Sprite, position: Position) {
|
||||||
// TODO: only render if inside screen
|
|
||||||
|
|
||||||
export function render_sprite(sprite: Sprite, position: Position, _camera: Camera) {
|
|
||||||
draw_texture_region(
|
draw_texture_region(
|
||||||
sprite.image,
|
sprite.image,
|
||||||
sprite.source_x,
|
sprite.source_x,
|
||||||
@@ -25,7 +21,6 @@ export function render_sprite(sprite: Sprite, position: Position, _camera: Camer
|
|||||||
export function render_animated_sprite(
|
export function render_animated_sprite(
|
||||||
animated_sprite: AnimatedSprite,
|
animated_sprite: AnimatedSprite,
|
||||||
position: Position,
|
position: Position,
|
||||||
_camera: Camera,
|
|
||||||
) {
|
) {
|
||||||
const current_animation = animated_sprite.states[animated_sprite.current_state];
|
const current_animation = animated_sprite.states[animated_sprite.current_state];
|
||||||
if (!current_animation) {
|
if (!current_animation) {
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ import { Component } from "$/common/ecs/component.ts";
|
|||||||
export class Position extends Component {
|
export class Position extends Component {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
|
z: number;
|
||||||
|
|
||||||
constructor(x: number, y: number) {
|
constructor(x: number, y: number, z = 0) {
|
||||||
super();
|
super();
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ import { Component } from "$/common/ecs/component.ts";
|
|||||||
export class Velocity extends Component {
|
export class Velocity extends Component {
|
||||||
vx: number;
|
vx: number;
|
||||||
vy: number;
|
vy: number;
|
||||||
|
vz: number;
|
||||||
|
|
||||||
constructor(vx: number, vy: number) {
|
constructor(vx: number, vy: number, vz = 0) {
|
||||||
super();
|
super();
|
||||||
this.vx = vx;
|
this.vx = vx;
|
||||||
this.vy = vy;
|
this.vy = vy;
|
||||||
|
this.vz = vz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ export class MovementSystem extends System {
|
|||||||
if (position && velocity) {
|
if (position && velocity) {
|
||||||
position.x += velocity.vx * delta;
|
position.x += velocity.vx * delta;
|
||||||
position.y += velocity.vy * delta;
|
position.y += velocity.vy * delta;
|
||||||
position.x = Math.round(position.x);
|
position.z += velocity.vz * delta;
|
||||||
position.y = Math.round(position.y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"@gfx/canvas-wasm": "jsr:@gfx/canvas-wasm@^0.4.2",
|
"@gfx/canvas-wasm": "jsr:@gfx/canvas-wasm@^0.4.2",
|
||||||
"@paulaboks/rng": "jsr:@paulaboks/rng@^0.0.2",
|
"@paulaboks/rng": "jsr:@paulaboks/rng@^0.0.2",
|
||||||
"@std/fs": "jsr:@std/fs@^1.0.23",
|
"@std/fs": "jsr:@std/fs@^1.0.23",
|
||||||
|
"gl-matrix": "npm:gl-matrix@^3.4.4",
|
||||||
"marked": "npm:marked@^17.0.3"
|
"marked": "npm:marked@^17.0.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
"jsr:@std/fs@^1.0.23": "1.0.23",
|
"jsr:@std/fs@^1.0.23": "1.0.23",
|
||||||
"jsr:@std/internal@^1.0.12": "1.0.12",
|
"jsr:@std/internal@^1.0.12": "1.0.12",
|
||||||
"jsr:@std/path@^1.1.4": "1.1.4",
|
"jsr:@std/path@^1.1.4": "1.1.4",
|
||||||
|
"npm:gl-matrix@^3.4.4": "3.4.4",
|
||||||
"npm:marked@^17.0.3": "17.0.3"
|
"npm:marked@^17.0.3": "17.0.3"
|
||||||
},
|
},
|
||||||
"jsr": {
|
"jsr": {
|
||||||
@@ -40,6 +41,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"npm": {
|
"npm": {
|
||||||
|
"gl-matrix@3.4.4": {
|
||||||
|
"integrity": "sha512-latSnyDNt/8zYUB6VIJ6PCh2jBjJX6gnDsoCZ7LyW7GkqrD51EWwa9qCoGixj8YqBtETQK/xY7OmpTF8xz1DdQ=="
|
||||||
|
},
|
||||||
"marked@17.0.3": {
|
"marked@17.0.3": {
|
||||||
"integrity": "sha512-jt1v2ObpyOKR8p4XaUJVk3YWRJ5n+i4+rjQopxvV32rSndTJXvIzuUdWWIy/1pFQMkQmvTXawzDNqOH/CUmx6A==",
|
"integrity": "sha512-jt1v2ObpyOKR8p4XaUJVk3YWRJ5n+i4+rjQopxvV32rSndTJXvIzuUdWWIy/1pFQMkQmvTXawzDNqOH/CUmx6A==",
|
||||||
"bin": true
|
"bin": true
|
||||||
@@ -50,6 +54,7 @@
|
|||||||
"jsr:@gfx/canvas-wasm@~0.4.2",
|
"jsr:@gfx/canvas-wasm@~0.4.2",
|
||||||
"jsr:@paulaboks/rng@^0.0.2",
|
"jsr:@paulaboks/rng@^0.0.2",
|
||||||
"jsr:@std/fs@^1.0.23",
|
"jsr:@std/fs@^1.0.23",
|
||||||
|
"npm:gl-matrix@^3.4.4",
|
||||||
"npm:marked@^17.0.3"
|
"npm:marked@^17.0.3"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user