mirror of
https://github.com/DaanVandenBosch/phantasmal-world.git
synced 2025-04-04 22:58:29 +08:00
Orbital camera rotation sort of works. Translation happens after rotation instead of the other way around.
This commit is contained in:
parent
8e54ac90fd
commit
b3055bc271
@ -22,3 +22,13 @@ export function deg_to_rad(deg: number): number {
|
||||
export function floor_mod(dividend: number, divisor: number): number {
|
||||
return ((dividend % divisor) + divisor) % divisor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes sure a value is between a minimum and maximum.
|
||||
*
|
||||
* @returns `min` if `value` is lower than `min`, `max` if `value` is greater than `max` and `value`
|
||||
* otherwise.
|
||||
*/
|
||||
export function clamp(value: number, min: number, max: number): number {
|
||||
return Math.max(min, Math.min(value, max));
|
||||
}
|
||||
|
@ -23,14 +23,21 @@ export class Vec3 {
|
||||
magnitude(): number {
|
||||
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
|
||||
}
|
||||
|
||||
normalize(): void {
|
||||
const inv_mag = 1 / this.magnitude();
|
||||
this.x *= inv_mag;
|
||||
this.y *= inv_mag;
|
||||
this.z *= inv_mag;
|
||||
}
|
||||
}
|
||||
|
||||
export function vec3_diff(v: Vec3, w: Vec3): Vec3 {
|
||||
return new Vec3(v.x - w.x, v.y - w.y, v.z - v.z);
|
||||
export function vec3_sub(v: Vec3, w: Vec3): Vec3 {
|
||||
return new Vec3(v.x - w.x, v.y - w.y, v.z - w.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the distance between points p and q. Equivalent to `vec3_diff(p, q).magnitude()`.
|
||||
* Computes the distance between points `p` and `q`. Equivalent to `vec3_diff(p, q).magnitude()`.
|
||||
*/
|
||||
export function vec3_dist(p: Vec3, q: Vec3): number {
|
||||
const x = p.x - q.x;
|
||||
@ -39,6 +46,33 @@ export function vec3_dist(p: Vec3, q: Vec3): number {
|
||||
return Math.sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the cross product of `p` and `q`.
|
||||
*/
|
||||
export function vec3_cross(p: Vec3, q: Vec3): Vec3 {
|
||||
return new Vec3(p.y * q.z - p.z * q.y, p.z * q.x - p.x * q.z, p.x * q.y - p.y * q.x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the dot product of `p` and `q`.
|
||||
*/
|
||||
export function vec3_dot(p: Vec3, q: Vec3): number {
|
||||
return p.x * q.x + p.y * q.y + p.z * q.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the cross product of `p` and `q` and stores it in `result`.
|
||||
*/
|
||||
export function vec3_cross_into(p: Vec3, q: Vec3, result: Vec3): void {
|
||||
const x = p.y * q.z - p.z * q.y;
|
||||
const y = p.z * q.x - p.x * q.z;
|
||||
const z = p.x * q.y - p.y * q.x;
|
||||
|
||||
result.x = x;
|
||||
result.y = y;
|
||||
result.z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores data in column-major order.
|
||||
*/
|
||||
@ -167,16 +201,16 @@ export class Mat3 {
|
||||
}
|
||||
}
|
||||
|
||||
export function mat3_product(a: Mat3, b: Mat3): Mat3 {
|
||||
export function mat3_multiply(a: Mat3, b: Mat3): Mat3 {
|
||||
const c = new Mat3(new Float32Array(9));
|
||||
mat3_product_into_array(c.data, a, b);
|
||||
return c;
|
||||
}
|
||||
|
||||
export function mat3_multiply(a: Mat3, b: Mat3): void {
|
||||
export function mat3_multiply_into(a: Mat3, b: Mat3, result: Mat3): void {
|
||||
const array = new Float32Array(9);
|
||||
mat3_product_into_array(array, a, b);
|
||||
a.data.set(array);
|
||||
result.data.set(array);
|
||||
}
|
||||
|
||||
function mat3_product_into_array(array: Float32Array, a: Mat3, b: Mat3): void {
|
||||
@ -190,15 +224,16 @@ function mat3_product_into_array(array: Float32Array, a: Mat3, b: Mat3): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the product of `m` and `v` and stores the result in `v`.
|
||||
* Computes the product of `m` and `v` and stores it in `result`.
|
||||
*/
|
||||
export function mat3_vec3_multiply(m: Mat3, v: Vec3): void {
|
||||
export function mat3_vec3_multiply_into(m: Mat3, v: Vec3, result: Vec3): void {
|
||||
const x = m.get(0, 0) * v.x + m.get(0, 1) * v.y + m.get(0, 2) * v.z;
|
||||
const y = m.get(1, 0) * v.x + m.get(1, 1) * v.y + m.get(1, 2) * v.z;
|
||||
const z = m.get(2, 0) * v.x + m.get(2, 1) * v.y + m.get(2, 2) * v.z;
|
||||
v.x = x;
|
||||
v.y = y;
|
||||
v.z = z;
|
||||
|
||||
result.x = x;
|
||||
result.y = y;
|
||||
result.z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -321,6 +356,38 @@ export class Mat4 {
|
||||
this.data[15] = m33;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transposes this matrix in-place.
|
||||
*/
|
||||
transpose(): void {
|
||||
let tmp: number;
|
||||
const m = this.data;
|
||||
|
||||
tmp = m[1];
|
||||
m[1] = m[4];
|
||||
m[4] = tmp;
|
||||
|
||||
tmp = m[2];
|
||||
m[2] = m[8];
|
||||
m[8] = tmp;
|
||||
|
||||
tmp = m[6];
|
||||
m[6] = m[9];
|
||||
m[9] = tmp;
|
||||
|
||||
tmp = m[3];
|
||||
m[3] = m[12];
|
||||
m[12] = tmp;
|
||||
|
||||
tmp = m[7];
|
||||
m[7] = m[13];
|
||||
m[13] = tmp;
|
||||
|
||||
tmp = m[11];
|
||||
m[11] = m[14];
|
||||
m[14] = tmp;
|
||||
}
|
||||
|
||||
clone(): Mat4 {
|
||||
return new Mat4(new Float32Array(this.data));
|
||||
}
|
||||
@ -341,19 +408,19 @@ export class Mat4 {
|
||||
}
|
||||
}
|
||||
|
||||
export function mat4_product(a: Mat4, b: Mat4): Mat4 {
|
||||
export function mat4_multiply(a: Mat4, b: Mat4): Mat4 {
|
||||
const c = new Mat4(new Float32Array(16));
|
||||
mat4_product_into_array(c.data, a, b);
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the product of `a` and `b` and stores the result in `a`.
|
||||
* Computes the product of `a` and `b` and stores it in `result`.
|
||||
*/
|
||||
export function mat4_multiply(a: Mat4, b: Mat4): void {
|
||||
export function mat4_multiply_into(a: Mat4, b: Mat4, result: Mat4): void {
|
||||
const array = new Float32Array(16);
|
||||
mat4_product_into_array(array, a, b);
|
||||
a.data.set(array);
|
||||
result.data.set(array);
|
||||
}
|
||||
|
||||
function mat4_product_into_array(array: Float32Array, a: Mat4, b: Mat4): void {
|
||||
@ -367,13 +434,13 @@ function mat4_product_into_array(array: Float32Array, a: Mat4, b: Mat4): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the product of `m` and `v` and stores the result in `v`. Assumes `m` is affine.
|
||||
* Computes the product of `m` and `v` and stores it in `result`. Assumes `m` is affine.
|
||||
*/
|
||||
export function mat4_vec3_multiply(m: Mat4, v: Vec3): void {
|
||||
export function mat4_vec3_multiply_into(m: Mat4, v: Vec3, result: Vec3): void {
|
||||
const x = m.get(0, 0) * v.x + m.get(0, 1) * v.y + m.get(0, 2) * v.z + m.get(0, 3);
|
||||
const y = m.get(1, 0) * v.x + m.get(1, 1) * v.y + m.get(1, 2) * v.z + m.get(1, 3);
|
||||
const z = m.get(2, 0) * v.x + m.get(2, 1) * v.y + m.get(2, 2) * v.z + m.get(2, 3);
|
||||
v.x = x;
|
||||
v.y = y;
|
||||
v.z = z;
|
||||
result.x = x;
|
||||
result.y = y;
|
||||
result.z = z;
|
||||
}
|
||||
|
@ -39,6 +39,12 @@ export class Quat {
|
||||
}
|
||||
|
||||
constructor(public w: number, public x: number, public y: number, public z: number) {}
|
||||
|
||||
conjugate(): void {
|
||||
this.x *= -1;
|
||||
this.y *= -1;
|
||||
this.z *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
export function quat_product(p: Quat, q: Quat): Quat {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Mat4, Vec3, vec3_dist } from "../math/linear_algebra";
|
||||
import { deg_to_rad } from "../math";
|
||||
import { Mat4, Vec3, vec3_cross, vec3_dot, vec3_sub } from "../math/linear_algebra";
|
||||
import { clamp, deg_to_rad } from "../math";
|
||||
|
||||
export enum Projection {
|
||||
Orthographic,
|
||||
@ -11,11 +11,13 @@ export class Camera {
|
||||
* Only applicable in perspective mode.
|
||||
*/
|
||||
private readonly fov = deg_to_rad(75);
|
||||
private readonly position: Vec3 = new Vec3(0, 0, 0);
|
||||
private readonly look_at: Vec3 = new Vec3(0, 0, 0);
|
||||
private x_rot: number = 0;
|
||||
private y_rot: number = 0;
|
||||
private z_rot: number = 0;
|
||||
private readonly target: Vec3 = new Vec3(0, 0, 0);
|
||||
|
||||
// Spherical coordinates.
|
||||
private radius = 0;
|
||||
private azimuth = 0;
|
||||
private polar = Math.PI / 2;
|
||||
|
||||
private _zoom: number = 1;
|
||||
|
||||
/**
|
||||
@ -90,22 +92,26 @@ export class Camera {
|
||||
|
||||
case Projection.Perspective:
|
||||
pan_factor =
|
||||
(3 *
|
||||
vec3_dist(this.position, this.look_at) *
|
||||
Math.tan(0.5 * this.effective_fov)) /
|
||||
this.viewport_width;
|
||||
(3 * this.radius * Math.tan(0.5 * this.effective_fov)) / this.viewport_width;
|
||||
break;
|
||||
}
|
||||
|
||||
x *= pan_factor;
|
||||
y *= pan_factor;
|
||||
|
||||
this.position.x += x;
|
||||
this.position.y += y;
|
||||
this.position.z += z;
|
||||
this.look_at.x += x;
|
||||
this.look_at.y += y;
|
||||
this.target.x += x;
|
||||
this.target.y += y;
|
||||
|
||||
this.radius += z;
|
||||
|
||||
this.update_matrix();
|
||||
return this;
|
||||
}
|
||||
|
||||
rotate(azimuth: number, polar: number): this {
|
||||
this.azimuth += azimuth;
|
||||
const max_pole_dist = Math.PI / 1800; // tenth of a degree.
|
||||
this.polar = clamp(this.polar + polar, max_pole_dist, Math.PI - max_pole_dist);
|
||||
this.update_matrix();
|
||||
return this;
|
||||
}
|
||||
@ -115,37 +121,48 @@ export class Camera {
|
||||
*/
|
||||
zoom(factor: number): this {
|
||||
this._zoom *= factor;
|
||||
this.position.x *= factor;
|
||||
this.position.y *= factor;
|
||||
this.position.z *= factor;
|
||||
this.look_at.x *= factor;
|
||||
this.look_at.y *= factor;
|
||||
this.look_at.z *= factor;
|
||||
this.target.x *= factor;
|
||||
this.target.y *= factor;
|
||||
this.target.z *= factor;
|
||||
this.update_matrix();
|
||||
return this;
|
||||
}
|
||||
|
||||
reset(): this {
|
||||
this.position.x = 0;
|
||||
this.position.y = 0;
|
||||
this.position.z = 0;
|
||||
this.look_at.x = 0;
|
||||
this.look_at.y = 0;
|
||||
this.look_at.z = 0;
|
||||
this.x_rot = 0;
|
||||
this.y_rot = 0;
|
||||
this.z_rot = 0;
|
||||
this.target.x = 0;
|
||||
this.target.y = 0;
|
||||
this.target.z = 0;
|
||||
this._zoom = 1;
|
||||
this.update_matrix();
|
||||
return this;
|
||||
}
|
||||
|
||||
private update_matrix(): void {
|
||||
this.view_matrix.data[12] = -this.position.x;
|
||||
this.view_matrix.data[13] = -this.position.y;
|
||||
this.view_matrix.data[14] = -this.position.z;
|
||||
this.view_matrix.data[0] = this._zoom;
|
||||
this.view_matrix.data[5] = this._zoom;
|
||||
this.view_matrix.data[10] = this._zoom;
|
||||
// Convert spherical coordinates to cartesian coordinates.
|
||||
const radius_sin_polar = this.radius * Math.sin(this.polar);
|
||||
const camera_pos = new Vec3(
|
||||
this.target.x + radius_sin_polar * Math.sin(this.azimuth),
|
||||
this.target.y + this.radius * Math.cos(this.polar),
|
||||
this.target.z + radius_sin_polar * Math.cos(this.azimuth),
|
||||
);
|
||||
|
||||
// Compute forward (z-axis), right (x-axis) and up (y-axis) vectors.
|
||||
const forward = vec3_sub(camera_pos, this.target);
|
||||
forward.normalize();
|
||||
|
||||
const right = vec3_cross(new Vec3(0, 1, 0), forward);
|
||||
right.normalize();
|
||||
|
||||
const up = vec3_cross(forward, right);
|
||||
|
||||
const zoom = this._zoom;
|
||||
|
||||
// prettier-ignore
|
||||
this.view_matrix.set_all(
|
||||
right.x * zoom, right.y, right.z, -vec3_dot( right, camera_pos),
|
||||
up.x, up.y* zoom, up.z, -vec3_dot( up, camera_pos),
|
||||
forward.x, forward.y, forward.z* zoom, -vec3_dot(forward, camera_pos),
|
||||
0, 0, 0, 1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -11,18 +11,21 @@ export abstract class GfxRenderer implements Renderer {
|
||||
*/
|
||||
private animation_frame?: number;
|
||||
|
||||
protected width: number = 800;
|
||||
protected height: number = 600;
|
||||
|
||||
abstract readonly gfx: Gfx;
|
||||
readonly scene = new Scene();
|
||||
readonly camera: Camera;
|
||||
readonly canvas_element: HTMLCanvasElement = document.createElement("canvas");
|
||||
|
||||
protected constructor(projection: Projection) {
|
||||
this.canvas_element.width = 800;
|
||||
this.canvas_element.height = 600;
|
||||
this.canvas_element.width = this.width;
|
||||
this.canvas_element.height = this.height;
|
||||
this.canvas_element.addEventListener("mousedown", this.mousedown);
|
||||
this.canvas_element.addEventListener("wheel", this.wheel, { passive: true });
|
||||
|
||||
this.camera = new Camera(this.canvas_element.width, this.canvas_element.height, projection);
|
||||
this.camera = new Camera(this.width, this.height, projection);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
@ -30,6 +33,8 @@ export abstract class GfxRenderer implements Renderer {
|
||||
}
|
||||
|
||||
set_size(width: number, height: number): void {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.camera.set_viewport(width, height);
|
||||
this.schedule_render();
|
||||
}
|
||||
@ -74,25 +79,30 @@ export abstract class GfxRenderer implements Renderer {
|
||||
}
|
||||
|
||||
private mousedown = (evt: MouseEvent): void => {
|
||||
if (evt.buttons === 1) {
|
||||
this.pointer_pos = new Vec2(evt.clientX, evt.clientY);
|
||||
this.pointer_pos = new Vec2(evt.clientX, evt.clientY);
|
||||
|
||||
window.addEventListener("mousemove", this.mousemove);
|
||||
window.addEventListener("mouseup", this.mouseup);
|
||||
}
|
||||
window.addEventListener("mousemove", this.mousemove);
|
||||
window.addEventListener("mouseup", this.mouseup);
|
||||
window.addEventListener("contextmenu", this.contextmenu);
|
||||
};
|
||||
|
||||
private mousemove = (evt: MouseEvent): void => {
|
||||
const new_pos = new Vec2(evt.clientX, evt.clientY);
|
||||
const diff = vec2_diff(new_pos, this.pointer_pos!);
|
||||
|
||||
if (evt.buttons === 1) {
|
||||
const new_pos = new Vec2(evt.clientX, evt.clientY);
|
||||
const diff = vec2_diff(new_pos, this.pointer_pos!);
|
||||
this.camera.pan(-diff.x, diff.y, 0);
|
||||
this.pointer_pos = new_pos;
|
||||
this.schedule_render();
|
||||
} else if (evt.buttons === 2) {
|
||||
this.camera.rotate(-diff.x / (20 * Math.PI), -diff.y / (20 * Math.PI));
|
||||
}
|
||||
|
||||
this.pointer_pos = new_pos;
|
||||
this.schedule_render();
|
||||
};
|
||||
|
||||
private mouseup = (): void => {
|
||||
private mouseup = (evt: MouseEvent): void => {
|
||||
evt.preventDefault();
|
||||
|
||||
this.pointer_pos = undefined;
|
||||
|
||||
window.removeEventListener("mousemove", this.mousemove);
|
||||
@ -120,4 +130,9 @@ export abstract class GfxRenderer implements Renderer {
|
||||
|
||||
this.schedule_render();
|
||||
};
|
||||
|
||||
private contextmenu = (evt: Event): void => {
|
||||
evt.preventDefault();
|
||||
window.removeEventListener("contextmenu", this.contextmenu);
|
||||
};
|
||||
}
|
||||
|
@ -6,10 +6,10 @@ import { Mesh } from "../Mesh";
|
||||
import { VertexFormat } from "../VertexFormat";
|
||||
import { EulerOrder, Quat } from "../../math/quaternions";
|
||||
import {
|
||||
mat3_vec3_multiply,
|
||||
mat3_vec3_multiply_into,
|
||||
Mat4,
|
||||
mat4_product,
|
||||
mat4_vec3_multiply,
|
||||
mat4_multiply,
|
||||
mat4_vec3_multiply_into,
|
||||
Vec2,
|
||||
Vec3,
|
||||
} from "../../math/linear_algebra";
|
||||
@ -75,7 +75,7 @@ class MeshCreator {
|
||||
} = object.evaluation_flags;
|
||||
const { position, rotation, scale } = object;
|
||||
|
||||
const matrix = mat4_product(
|
||||
const matrix = mat4_multiply(
|
||||
parent_matrix,
|
||||
Mat4.compose(
|
||||
no_translate ? NO_TRANSLATION : vec3_to_math(position),
|
||||
@ -115,13 +115,13 @@ class MeshCreator {
|
||||
|
||||
const new_vertices = model.vertices.map(vertex => {
|
||||
const position = vec3_to_math(vertex.position);
|
||||
mat4_vec3_multiply(matrix, position);
|
||||
mat4_vec3_multiply_into(matrix, position, position);
|
||||
|
||||
let normal: Vec3 | undefined = undefined;
|
||||
|
||||
if (vertex.normal) {
|
||||
normal = vec3_to_math(vertex.normal);
|
||||
mat3_vec3_multiply(normal_matrix, normal);
|
||||
mat3_vec3_multiply_into(normal_matrix, normal, normal);
|
||||
}
|
||||
|
||||
return {
|
||||
@ -167,10 +167,10 @@ class MeshCreator {
|
||||
|
||||
for (const { position, normal } of model.vertices) {
|
||||
const p = vec3_to_math(position);
|
||||
mat4_vec3_multiply(matrix, p);
|
||||
mat4_vec3_multiply_into(matrix, p, p);
|
||||
|
||||
const n = normal ? vec3_to_math(normal) : new Vec3(0, 1, 0);
|
||||
mat3_vec3_multiply(normal_matrix, n);
|
||||
mat3_vec3_multiply_into(normal_matrix, n, n);
|
||||
|
||||
this.builder.vertex(p, n);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Mat4, mat4_product } from "../../math/linear_algebra";
|
||||
import { Mat4, mat4_multiply } from "../../math/linear_algebra";
|
||||
import { ShaderProgram } from "../ShaderProgram";
|
||||
import pos_norm_vert_shader_source from "./pos_norm.vert";
|
||||
import pos_norm_frag_shader_source from "./pos_norm.frag";
|
||||
@ -67,42 +67,42 @@ export class WebglRenderer extends GfxRenderer {
|
||||
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
this.render_node(this.scene.root_node, this.camera.view_matrix);
|
||||
// this.render_node(this.scene.root_node, this.camera.view_matrix);
|
||||
|
||||
// this.scene.traverse((node, parent_mat) => {
|
||||
// const mat = mat4_product(parent_mat, node.transform);
|
||||
//
|
||||
// if (node.mesh) {
|
||||
// const program = this.shader_programs[node.mesh.format];
|
||||
// program.bind();
|
||||
//
|
||||
// program.set_mat_projection_uniform(this.camera.projection_matrix);
|
||||
// program.set_mat_model_view_uniform(mat);
|
||||
// program.set_mat_normal_uniform(mat.normal_mat3());
|
||||
//
|
||||
// if (node.mesh.texture?.gfx_texture) {
|
||||
// gl.activeTexture(gl.TEXTURE0);
|
||||
// gl.bindTexture(gl.TEXTURE_2D, node.mesh.texture.gfx_texture as WebGLTexture);
|
||||
// program.set_texture_uniform(gl.TEXTURE0);
|
||||
// }
|
||||
//
|
||||
// const gfx_mesh = node.mesh.gfx_mesh as WebglMesh;
|
||||
// gl.bindVertexArray(gfx_mesh.vao);
|
||||
// gl.drawElements(gl.TRIANGLES, node.mesh.index_count, gl.UNSIGNED_SHORT, 0);
|
||||
// gl.bindVertexArray(null);
|
||||
//
|
||||
// gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
//
|
||||
// program.unbind();
|
||||
// }
|
||||
//
|
||||
// return mat;
|
||||
// }, this.camera.view_matrix);
|
||||
this.scene.traverse((node, parent_mat) => {
|
||||
const mat = mat4_multiply(parent_mat, node.transform);
|
||||
|
||||
if (node.mesh) {
|
||||
const program = this.shader_programs[node.mesh.format];
|
||||
program.bind();
|
||||
|
||||
program.set_mat_projection_uniform(this.camera.projection_matrix);
|
||||
program.set_mat_model_view_uniform(mat);
|
||||
program.set_mat_normal_uniform(mat.normal_mat3());
|
||||
|
||||
if (node.mesh.texture?.gfx_texture) {
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, node.mesh.texture.gfx_texture as WebGLTexture);
|
||||
program.set_texture_uniform(gl.TEXTURE0);
|
||||
}
|
||||
|
||||
const gfx_mesh = node.mesh.gfx_mesh as WebglMesh;
|
||||
gl.bindVertexArray(gfx_mesh.vao);
|
||||
gl.drawElements(gl.TRIANGLES, node.mesh.index_count, gl.UNSIGNED_SHORT, 0);
|
||||
gl.bindVertexArray(null);
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
|
||||
program.unbind();
|
||||
}
|
||||
|
||||
return mat;
|
||||
}, this.camera.view_matrix);
|
||||
}
|
||||
|
||||
private render_node(node: SceneNode, parent_mat: Mat4): void {
|
||||
const gl = this.gl;
|
||||
const mat = mat4_product(parent_mat, node.transform);
|
||||
const mat = mat4_multiply(parent_mat, node.transform);
|
||||
|
||||
if (node.mesh) {
|
||||
const program = this.shader_programs[node.mesh.format];
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { LogManager } from "../../Logger";
|
||||
import { vertex_format_size, VertexFormat } from "../VertexFormat";
|
||||
import { GfxRenderer } from "../GfxRenderer";
|
||||
import { mat4_product } from "../../math/linear_algebra";
|
||||
import { mat4_multiply } from "../../math/linear_algebra";
|
||||
import { WebgpuGfx, WebgpuMesh } from "./WebgpuGfx";
|
||||
import { ShaderLoader } from "./ShaderLoader";
|
||||
import { HttpClient } from "../../HttpClient";
|
||||
@ -23,8 +23,6 @@ export class WebgpuRenderer extends GfxRenderer {
|
||||
swap_chain: GPUSwapChain;
|
||||
pipeline: GPURenderPipeline;
|
||||
};
|
||||
private width = 800;
|
||||
private height = 600;
|
||||
private shader_loader: ShaderLoader;
|
||||
|
||||
get gfx(): WebgpuGfx {
|
||||
@ -145,9 +143,6 @@ export class WebgpuRenderer extends GfxRenderer {
|
||||
}
|
||||
|
||||
set_size(width: number, height: number): void {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
// There seems to be a bug in chrome's WebGPU implementation that requires you to set a
|
||||
// canvas element's width and height after it's added to the DOM.
|
||||
if (this.gpu) {
|
||||
@ -176,10 +171,13 @@ export class WebgpuRenderer extends GfxRenderer {
|
||||
|
||||
pass_encoder.setPipeline(pipeline);
|
||||
|
||||
const camera_project_mat = mat4_product(this.camera.projection_matrix, this.camera.view_matrix);
|
||||
const camera_project_mat = mat4_multiply(
|
||||
this.camera.projection_matrix,
|
||||
this.camera.view_matrix,
|
||||
);
|
||||
|
||||
this.scene.traverse((node, parent_mat) => {
|
||||
const mat = mat4_product(parent_mat, node.transform);
|
||||
const mat = mat4_multiply(parent_mat, node.transform);
|
||||
|
||||
if (node.mesh) {
|
||||
const gfx_mesh = node.mesh.gfx_mesh as WebgpuMesh;
|
||||
|
Loading…
Reference in New Issue
Block a user