Big update
This commit is contained in:
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
45
.idea/workspace.xml
generated
45
.idea/workspace.xml
generated
@@ -1,7 +1,26 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="dc704aa3-69bc-4c4e-bfa3-31f248741e3c" name="Default Changelist" comment="" />
|
<list default="true" id="dc704aa3-69bc-4c4e-bfa3-31f248741e3c" name="Default Changelist" comment="">
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/Camera.ts" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/Cone.ts" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/MatrixFour.ts" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/src/TransformableGeometry.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/build/bundle.js" beforeDir="false" afterPath="$PROJECT_DIR$/build/bundle.js" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/App.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/App.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/BasicColor.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/BasicColor.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/Matrix4.ts" beforeDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/Point2D.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/Point2D.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/Point3D.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/Point3D.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/PointVec.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/PointVec.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/Triangle2D.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/Triangle2D.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/TrsMatrix.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/TrsMatrix.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/fragmentShader.glsl" beforeDir="false" afterPath="$PROJECT_DIR$/src/fragmentShader.glsl" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/types.d.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/types.d.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/utils.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils.ts" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/src/vertexShader.glsl" beforeDir="false" afterPath="$PROJECT_DIR$/src/vertexShader.glsl" afterDir="false" />
|
||||||
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
@@ -18,6 +37,9 @@
|
|||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
<component name="Git.Settings">
|
||||||
|
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||||
|
</component>
|
||||||
<component name="ProjectId" id="1dJrR6XMWeePLne62dJk97OPzOb" />
|
<component name="ProjectId" id="1dJrR6XMWeePLne62dJk97OPzOb" />
|
||||||
<component name="ProjectViewState">
|
<component name="ProjectViewState">
|
||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
<option name="hideEmptyMiddlePackages" value="true" />
|
||||||
@@ -69,6 +91,8 @@
|
|||||||
<workItem from="1592157594053" duration="10162000" />
|
<workItem from="1592157594053" duration="10162000" />
|
||||||
<workItem from="1592213404810" duration="33877000" />
|
<workItem from="1592213404810" duration="33877000" />
|
||||||
<workItem from="1592384389528" duration="612000" />
|
<workItem from="1592384389528" duration="612000" />
|
||||||
|
<workItem from="1593163095834" duration="18917000" />
|
||||||
|
<workItem from="1593248452910" duration="13264000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
@@ -88,13 +112,20 @@
|
|||||||
<screen x="0" y="540" width="1080" height="1380" />
|
<screen x="0" y="540" width="1080" height="1380" />
|
||||||
</state>
|
</state>
|
||||||
<state x="0" y="721" key="SettingsEditor/1080.513.1920.1080/0.540.1080.1380@0.540.1080.1380" timestamp="1592157574185" />
|
<state x="0" y="721" key="SettingsEditor/1080.513.1920.1080/0.540.1080.1380@0.540.1080.1380" timestamp="1592157574185" />
|
||||||
<state x="204" y="456" width="672" height="677" key="run.anything.popup" timestamp="1592164107251">
|
<state x="608" y="250" width="704" height="578" key="find.popup" timestamp="1593260457178">
|
||||||
<screen x="0" y="540" width="1080" height="1380" />
|
|
||||||
</state>
|
|
||||||
<state x="204" y="456" width="672" height="677" key="run.anything.popup/1080.513.1920.1080/0.540.1080.1380@0.540.1080.1380" timestamp="1592164107251" />
|
|
||||||
<state x="992" y="237" width="672" height="678" key="search.everywhere.popup" timestamp="1592225020545">
|
|
||||||
<screen x="0" y="27" width="1920" height="1053" />
|
<screen x="0" y="27" width="1920" height="1053" />
|
||||||
</state>
|
</state>
|
||||||
<state x="992" y="237" width="672" height="678" key="search.everywhere.popup/1920.0.1920.1080/0.27.1920.1053@0.27.1920.1053" timestamp="1592225020545" />
|
<state x="608" y="250" width="704" height="578" key="find.popup/1920.0.1920.1080/0.27.1920.1053@0.27.1920.1053" timestamp="1593260457178" />
|
||||||
|
<state x="363" y="-37" width="1195" height="517" key="run.anything.popup" timestamp="1593262773357">
|
||||||
|
<screen x="0" y="27" width="1920" height="1053" />
|
||||||
|
</state>
|
||||||
|
<state x="204" y="456" width="672" height="677" key="run.anything.popup/1080.513.1920.1080/0.540.1080.1380@0.540.1080.1380" timestamp="1592164107251" />
|
||||||
|
<state x="363" y="-37" width="1195" height="517" key="run.anything.popup/1920.0.1920.1080/0.27.1920.1053@0.27.1920.1053" timestamp="1593262773357" />
|
||||||
|
<state x="2283" y="-66" width="1195" height="531" key="run.anything.popup/1920.0.1920.1080/0.27.1920.1053@1920.0.1920.1080" timestamp="1593189438638" />
|
||||||
|
<state x="2912" y="215" width="672" height="696" key="search.everywhere.popup" timestamp="1593184656351">
|
||||||
|
<screen x="1920" y="0" width="1920" height="1080" />
|
||||||
|
</state>
|
||||||
|
<state x="992" y="237" width="672" height="678" key="search.everywhere.popup/1920.0.1920.1080/0.27.1920.1053@0.27.1920.1053" timestamp="1593175537121" />
|
||||||
|
<state x="2912" y="215" width="672" height="696" key="search.everywhere.popup/1920.0.1920.1080/0.27.1920.1053@1920.0.1920.1080" timestamp="1593184656351" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
File diff suppressed because one or more lines are too long
144
src/App.ts
144
src/App.ts
@@ -1,12 +1,14 @@
|
|||||||
import vs_src from "./vertexShader.glsl";
|
import vs_src from "./vertexShader.glsl";
|
||||||
import fs_src from "./fragmentShader.glsl";
|
import fs_src from "./fragmentShader.glsl";
|
||||||
import Matrix4 from "./Matrix4";
|
import {Color, Colored, Geometry, Transformable} from "./types";
|
||||||
import {perspMat} from "./utils";
|
import MatrixFour from "./MatrixFour";
|
||||||
import Triangle2D from "./Triangle2D";
|
import Triangle2D from "./Triangle2D";
|
||||||
import TrsMatrix from "./TrsMatrix";
|
|
||||||
import Point2D from "./Point2D";
|
|
||||||
import BasicColor from "./BasicColor";
|
import BasicColor from "./BasicColor";
|
||||||
import {ProgramLinkingError, ShaderCompilationError} from "./Errors";
|
import {ProgramLinkingError, ShaderCompilationError} from "./Errors";
|
||||||
|
import Cone from "./Cone";
|
||||||
|
import TrsMatrix from "./TrsMatrix";
|
||||||
|
import Camera from "./Camera";
|
||||||
|
import Point3D from "./Point3D";
|
||||||
|
|
||||||
export enum ExitCode {
|
export enum ExitCode {
|
||||||
ERROR,
|
ERROR,
|
||||||
@@ -15,29 +17,37 @@ export enum ExitCode {
|
|||||||
WEBGL_ERROR
|
WEBGL_ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Updatable {
|
||||||
|
update(delta: number): void;
|
||||||
|
}
|
||||||
|
type Object = Transformable & Geometry & Colored & Updatable;
|
||||||
|
|
||||||
class WebGlApp {
|
class WebGlApp {
|
||||||
private gl: WebGLRenderingContext;
|
private gl: WebGLRenderingContext;
|
||||||
private stage: HTMLCanvasElement;
|
private stage: HTMLCanvasElement;
|
||||||
private perspMat: Matrix4;
|
private normalBuffer?: WebGLBuffer;
|
||||||
|
private pointBuffer?: WebGLBuffer;
|
||||||
|
private elementBuffer?: WebGLBuffer;
|
||||||
private currentProgram: WebGLProgram | null;
|
private currentProgram: WebGLProgram | null;
|
||||||
private positionAttributeLocation: number = 0;
|
private a_position: number = 0;
|
||||||
|
private a_normal: number = 0;
|
||||||
private u_colorLoc: number = 0;
|
private u_colorLoc: number = 0;
|
||||||
private u_trsMatrixLoc: number = 0;
|
private u_trsMatrixLoc: number = 0;
|
||||||
private maxTris: number = 1000;
|
private objects: Object[] = [];
|
||||||
private tris: Triangle2D[] = [];
|
private camera: Camera = new Camera();
|
||||||
private sinceLastTri: number = 0;
|
private running: boolean = true;
|
||||||
private onShutdownCallback: (exitCode: ExitCode) => any = () => {};
|
private onShutdownCallback: (exitCode: ExitCode) => any = () => {};
|
||||||
constructor(gl: WebGLRenderingContext, canvas: HTMLCanvasElement) {
|
constructor(gl: WebGLRenderingContext, canvas: HTMLCanvasElement) {
|
||||||
this.gl = gl;
|
this.gl = gl;
|
||||||
this.stage = canvas;
|
this.stage = canvas;
|
||||||
this.currentProgram = this.createDefaultProgram();
|
this.currentProgram = this.createDefaultProgram();
|
||||||
this.perspMat = perspMat(90, this.stage.width / this.stage.height, 1.0, 2000.0);
|
|
||||||
this.setupGl();
|
this.setupGl();
|
||||||
}
|
}
|
||||||
|
|
||||||
private setupGl(): void {
|
private setupGl(): void {
|
||||||
this.gl.enable(this.gl.DEPTH_TEST);
|
this.gl.enable(this.gl.DEPTH_TEST);
|
||||||
this.gl.enable(this.gl.CULL_FACE);
|
//this.gl.enable(this.gl.CULL_FACE);
|
||||||
|
//this.gl.frontFace(this.gl.CCW);
|
||||||
}
|
}
|
||||||
|
|
||||||
onShutdown(callback: (exitCode: ExitCode) => any): void {
|
onShutdown(callback: (exitCode: ExitCode) => any): void {
|
||||||
@@ -45,6 +55,7 @@ class WebGlApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private shutdown(exitCode: ExitCode) {
|
private shutdown(exitCode: ExitCode) {
|
||||||
|
this.running = false;
|
||||||
this.onShutdownCallback(exitCode);
|
this.onShutdownCallback(exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,13 +63,14 @@ class WebGlApp {
|
|||||||
const program = this.createProgram(
|
const program = this.createProgram(
|
||||||
this.createShaderFromString(this.gl.VERTEX_SHADER, vs_src),
|
this.createShaderFromString(this.gl.VERTEX_SHADER, vs_src),
|
||||||
this.createShaderFromString(this.gl.FRAGMENT_SHADER, fs_src));
|
this.createShaderFromString(this.gl.FRAGMENT_SHADER, fs_src));
|
||||||
this.positionAttributeLocation = this.gl.getAttribLocation(program, "a_position");
|
this.a_position = this.gl.getAttribLocation(program, "a_position");
|
||||||
|
this.a_normal = this.gl.getAttribLocation(program, "a_normal");
|
||||||
this.u_colorLoc = this.gl.getUniformLocation(program, "u_color") as number;
|
this.u_colorLoc = this.gl.getUniformLocation(program, "u_color") as number;
|
||||||
this.u_trsMatrixLoc = this.gl.getUniformLocation(program, "u_trsMatrix") as number;
|
this.u_trsMatrixLoc = this.gl.getUniformLocation(program, "u_trsMatrix") as number;
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
private createProgram(vertexShader: WebGLShader, fragmentShader: WebGLShader) {
|
private createProgram(vertexShader: WebGLShader, fragmentShader: WebGLShader): WebGLProgram {
|
||||||
const program: WebGLProgram = this.gl.createProgram() as WebGLProgram;
|
const program: WebGLProgram = this.gl.createProgram() as WebGLProgram;
|
||||||
this.gl.attachShader(program, vertexShader);
|
this.gl.attachShader(program, vertexShader);
|
||||||
this.gl.attachShader(program, fragmentShader);
|
this.gl.attachShader(program, fragmentShader);
|
||||||
@@ -89,12 +101,27 @@ class WebGlApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderTriangle(triangle: Triangle2D) {
|
private renderObject(object: Object) {
|
||||||
this.gl.bufferData(this.gl.ARRAY_BUFFER, triangle.pointBuffer(), this.gl.STATIC_DRAW);
|
this.gl.enableVertexAttribArray(this.a_position);
|
||||||
this.gl.uniform4fv(this.u_colorLoc, triangle.colorVec());
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.pointBuffer!);
|
||||||
|
this.gl.bufferData(this.gl.ARRAY_BUFFER, object.pointBuffer(), this.gl.STATIC_DRAW);
|
||||||
|
this.gl.vertexAttribPointer(
|
||||||
|
this.a_position, 3, this.gl.FLOAT, false, 0, 0);
|
||||||
|
|
||||||
|
this.gl.enableVertexAttribArray(this.a_normal);
|
||||||
|
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.normalBuffer!);
|
||||||
|
this.gl.bufferData(this.gl.ARRAY_BUFFER, object.normalBuffer(), this.gl.STATIC_DRAW);
|
||||||
|
this.gl.vertexAttribPointer(
|
||||||
|
this.a_normal, 3, this.gl.FLOAT, false, 0, 0);
|
||||||
|
|
||||||
|
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.elementBuffer!);
|
||||||
|
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, object.elementBuffer(), this.gl.STATIC_DRAW);
|
||||||
|
|
||||||
|
this.gl.uniform4fv(this.u_colorLoc, object.getColor().vec());
|
||||||
this.gl.uniformMatrix4fv(this.u_trsMatrixLoc, false,
|
this.gl.uniformMatrix4fv(this.u_trsMatrixLoc, false,
|
||||||
triangle.getTrsMatrix().buffer());
|
this.useCamera(object.getTrsMatrix()).buffer());
|
||||||
this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
|
|
||||||
|
this.gl.drawElements(this.gl.TRIANGLES, object.elementBuffer().length, this.gl.UNSIGNED_SHORT, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private initViewport(): void {
|
private initViewport(): void {
|
||||||
@@ -105,70 +132,53 @@ class WebGlApp {
|
|||||||
|
|
||||||
private useDefaultProgram(): void {
|
private useDefaultProgram(): void {
|
||||||
this.gl.useProgram(this.currentProgram);
|
this.gl.useProgram(this.currentProgram);
|
||||||
const positionBuffer = this.gl.createBuffer();
|
this.pointBuffer = this.gl.createBuffer()!;
|
||||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, positionBuffer);
|
this.elementBuffer = this.gl.createBuffer()!;
|
||||||
this.gl.enableVertexAttribArray(this.positionAttributeLocation);
|
this.normalBuffer = this.gl.createBuffer()!;
|
||||||
this.gl.vertexAttribPointer(
|
|
||||||
this.positionAttributeLocation, 3, this.gl.FLOAT, false, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private createRandomTriangle(): Triangle2D {
|
private useCamera(inputTrs: TrsMatrix): MatrixFour {
|
||||||
return new Triangle2D(
|
const projectionMatrix = MatrixFour.Perspective(
|
||||||
this.rand2DClipspacePoint(),
|
Math.PI,
|
||||||
this.rand2DClipspacePoint(),
|
this.stage.clientWidth / this.stage.clientHeight,
|
||||||
this.rand2DClipspacePoint(),
|
1,
|
||||||
this.randTrsMat(),
|
2000);
|
||||||
this.randBasicColor()
|
const viewProjectionMatrix = projectionMatrix.times(this.camera.viewMat());
|
||||||
)
|
return viewProjectionMatrix.times(inputTrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
private randTrsMat(): TrsMatrix {
|
private mainLoop(delta: number): void {
|
||||||
return new TrsMatrix()
|
for (const object of this.objects) {
|
||||||
.translateBy(this.randClipspaceInt() / 2, this.randClipspaceInt() / 2, this.randClipspaceInt() / 2)
|
object.update(delta);
|
||||||
.rotateBy(this.randAngle(), this.randAngle(), this.randAngle())
|
|
||||||
}
|
}
|
||||||
|
for (const object of this.objects) {
|
||||||
private rand2DClipspacePoint(): Point2D {
|
this.renderObject(object);
|
||||||
return new Point2D(this.randClipspaceInt() / 2, this.randClipspaceInt() / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
private randBasicColor(): BasicColor {
|
|
||||||
return new BasicColor(Math.random(), Math.random(), Math.random());
|
|
||||||
}
|
|
||||||
|
|
||||||
private randAngle(): number {
|
|
||||||
return Math.random() * Math.PI / 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
private randClipspaceInt(): number {
|
|
||||||
return Math.random() * 2 - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private animateRandomTrisPopin(delta: number): void {
|
|
||||||
if (this.maxTris >= this.tris.length) {
|
|
||||||
this.sinceLastTri += delta;
|
|
||||||
if (this.sinceLastTri > 100) {
|
|
||||||
this.tris.push(this.createRandomTriangle());
|
|
||||||
this.sinceLastTri = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const tri of this.tris) {
|
|
||||||
this.renderTriangle(tri);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private animate(then: number): void {
|
private frame(then: number): void {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const delta = now - then;
|
const delta = now - then;
|
||||||
this.animateRandomTrisPopin(delta);
|
this.mainLoop(delta);
|
||||||
window.requestAnimationFrame(() => this.animate(now));
|
if (this.running) {
|
||||||
|
window.requestAnimationFrame(() => this.frame(now));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private setupScene(): void {
|
||||||
|
const cone = new Cone(4, 100);
|
||||||
|
cone.setColor(new BasicColor(1.0, 0, 0, 1.0));
|
||||||
|
cone.scaleBy(100);
|
||||||
|
this.objects.push(cone);
|
||||||
|
this.camera.translateBy(100, 100, 100);
|
||||||
|
console.log(this.useCamera(cone.getTrsMatrix()));
|
||||||
}
|
}
|
||||||
|
|
||||||
run() {
|
run() {
|
||||||
this.initViewport();
|
this.initViewport();
|
||||||
this.useDefaultProgram();
|
this.useDefaultProgram();
|
||||||
window.requestAnimationFrame(() => this.animate(Date.now()));
|
this.setupScene();
|
||||||
//this.shutdown(ExitCode.QUIT);
|
window.requestAnimationFrame(() => this.frame(Date.now()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
|
import {VectorSizeError} from "./Errors";
|
||||||
|
import {Color, Vector} from "./types";
|
||||||
|
|
||||||
class BasicColor implements Vector, Color {
|
class BasicColor implements Vector, Color {
|
||||||
private rep: Float32Array;
|
private readonly rep: Float32Array;
|
||||||
constructor(r: number, g: number, b: number, a?: number) {
|
constructor();
|
||||||
this.rep = new Float32Array([r, g, b, a ?? 1.0]);
|
constructor(r: number, g: number, b: number, a?: number);
|
||||||
|
constructor(...args: any[]) {
|
||||||
|
this.rep = new Float32Array([args[0] ?? 0.5, args[1] ?? 0.5, args[2] ?? 0.5, args[3] ?? 1.0]);
|
||||||
}
|
}
|
||||||
static fromVec(vec: Float32Array): Color {
|
static fromVec(vec: ArrayLike<number>): Color {
|
||||||
if (vec.length === 4) {
|
if (vec.length === 4) {
|
||||||
return new BasicColor(vec[0], vec[1], vec[2], vec[3]);
|
return new BasicColor(vec[0], vec[1], vec[2], vec[3]);
|
||||||
}
|
}
|
||||||
|
|||||||
66
src/Camera.ts
Normal file
66
src/Camera.ts
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import TrsMatrix from "./TrsMatrix";
|
||||||
|
import Point3D from "./Point3D";
|
||||||
|
import {Transformable} from "./types";
|
||||||
|
import MatrixFour from "./MatrixFour";
|
||||||
|
|
||||||
|
class Camera implements Transformable {
|
||||||
|
private trs: TrsMatrix;
|
||||||
|
constructor();
|
||||||
|
constructor(position: Point3D, lookAt: Point3D, up: Point3D);
|
||||||
|
constructor(radius: number, rotX: number, rotY: number, rotZ: number);
|
||||||
|
constructor(...args: any[]) {
|
||||||
|
this.trs = new TrsMatrix();
|
||||||
|
if (args[0] !== undefined) {
|
||||||
|
if (args[0] instanceof Point3D) {
|
||||||
|
this.trs.setPosition(args[0]);
|
||||||
|
this.lookAt(args[1], args[2]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.rotateBy(args[1], args[2], args[3]);
|
||||||
|
this.translateBy(0, 0, args[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
translateBy(tX: number, tY: number, tZ: number): Camera {
|
||||||
|
this.trs.translateBy(tX, tY, tZ);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotateBy(degX: number, degY: number, degZ: number): Camera {
|
||||||
|
this.trs.rotateBy(degX, degY, degZ);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
scaleBy(sX: number, sY: number, sZ: number): Camera {
|
||||||
|
this.trs.scaleBy(sX, sY, sZ);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTrsMatrix(): TrsMatrix {
|
||||||
|
return this.trs;
|
||||||
|
}
|
||||||
|
|
||||||
|
position(): Point3D {
|
||||||
|
return this.trs.position();
|
||||||
|
};
|
||||||
|
|
||||||
|
lookAt(other: Point3D, up: Point3D) {
|
||||||
|
const selfPosition = this.position();
|
||||||
|
const zAxis = selfPosition.minus(other).normalised();
|
||||||
|
const xAxis = up.cross(zAxis).normalised();
|
||||||
|
const yAxis = zAxis.cross(xAxis).normalised();
|
||||||
|
this.trs.setSlice([
|
||||||
|
xAxis.x(), xAxis.y(), xAxis.z(), 0,
|
||||||
|
yAxis.x(), yAxis.y(), yAxis.z(), 0,
|
||||||
|
zAxis.x(), zAxis.y(), zAxis.z(), 0,
|
||||||
|
selfPosition.x(), selfPosition.y(), selfPosition.z(), 1,
|
||||||
|
], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
viewMat(): MatrixFour {
|
||||||
|
return this.trs.inverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Camera;
|
||||||
106
src/Cone.ts
Normal file
106
src/Cone.ts
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
import TrsMatrix from "./TrsMatrix";
|
||||||
|
import BasicColor from "./BasicColor";
|
||||||
|
import TransformableGeometry from "./TransformableGeometry";
|
||||||
|
import {triNormal} from "./utils";
|
||||||
|
import Point3D from "./Point3D";
|
||||||
|
import {Color, Colored, GeometryParams, Transformable} from "./types";
|
||||||
|
import {Updatable} from "./App";
|
||||||
|
|
||||||
|
class Cone extends TransformableGeometry implements Transformable, Colored, Updatable {
|
||||||
|
private color: Color;
|
||||||
|
private height?: number;
|
||||||
|
private basePoints?: number;
|
||||||
|
private static DEFAULT_BASE_POINTS: number = 10;
|
||||||
|
private static DEFAULT_HEIGHT: number = 1;
|
||||||
|
constructor(geometry: GeometryParams, trsMatrix?: TrsMatrix, color?: Color);
|
||||||
|
constructor(height?: number, basePoints?: number, trsMatrix?: TrsMatrix, color?: Color | ArrayLike<number>);
|
||||||
|
constructor(...args: any[]) {
|
||||||
|
let color;
|
||||||
|
if (typeof args[0] !== "number") {
|
||||||
|
super(args[0], args[1]);
|
||||||
|
color = args[2];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super(Cone.generateGeometry(args[0], args[1]), args[2]);
|
||||||
|
this.height = args[0] ?? Cone.DEFAULT_HEIGHT;
|
||||||
|
this.basePoints = args[1] ?? Cone.DEFAULT_BASE_POINTS;
|
||||||
|
color = args[4] ?? new BasicColor();
|
||||||
|
}
|
||||||
|
if (color.hasOwnProperty("length")) {
|
||||||
|
this.color = BasicColor.fromVec(color as ArrayLike<number>);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.color = color as Color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static generateGeometry(height: number, basePoints: number): GeometryParams {
|
||||||
|
basePoints = Math.abs(Math.ceil(basePoints));
|
||||||
|
const basePointsAngle = 2 * Math.PI / basePoints;
|
||||||
|
const pointBuffer = [
|
||||||
|
0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.0, height,
|
||||||
|
0.0, 1.0, 0.0
|
||||||
|
];
|
||||||
|
const normalBuffer = [];
|
||||||
|
const elementBuffer = [];
|
||||||
|
for (let i = 1; i < basePoints; i++) {
|
||||||
|
pointBuffer.push(
|
||||||
|
Math.sin(basePointsAngle * i),
|
||||||
|
Math.cos(basePointsAngle * i),
|
||||||
|
0.0
|
||||||
|
);
|
||||||
|
elementBuffer.push(0, 2 + i, 1 + i);
|
||||||
|
normalBuffer.push(
|
||||||
|
0.0, 0.0, -1.0,
|
||||||
|
0.0, 0.0, -1.0,
|
||||||
|
0.0, 0.0, -1.0,
|
||||||
|
);
|
||||||
|
elementBuffer.push(1, 1 + i, 2 + i);
|
||||||
|
normalBuffer.push(
|
||||||
|
...triNormal(
|
||||||
|
new Point3D(pointBuffer.slice(1, 4)),
|
||||||
|
new Point3D(pointBuffer.slice(1 + i, 4 + i)),
|
||||||
|
new Point3D(pointBuffer.slice(2 + i, 5 + i)),
|
||||||
|
).vec()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
elementBuffer.push(0, 2, 1 + basePoints);
|
||||||
|
elementBuffer.push(1, 1 + basePoints, 2);
|
||||||
|
return {
|
||||||
|
pointBuffer: new Float32Array(pointBuffer),
|
||||||
|
normalBuffer: new Float32Array(normalBuffer),
|
||||||
|
elementBuffer: new Uint16Array(elementBuffer)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
update(delta: number): void {
|
||||||
|
const secs = delta / 1000.0;
|
||||||
|
this.rotateBy(0, 0.05 * secs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
setHeight(height: number) {
|
||||||
|
this.changeHeight(height - (this.height ?? 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
changeHeight(deltaHeight: number) {
|
||||||
|
this.height = this.height ?? Cone.DEFAULT_HEIGHT + deltaHeight;
|
||||||
|
this.geometry = Cone.generateGeometry(this.height, this.basePoints ?? Cone.DEFAULT_BASE_POINTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
setBasePoints(basePoints: number) {
|
||||||
|
this.height = basePoints;
|
||||||
|
this.geometry = Cone.generateGeometry(this.height, this.basePoints ?? Cone.DEFAULT_BASE_POINTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
setColor(color: Color) {
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
getColor(): Color {
|
||||||
|
return this.color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default Cone;
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
import {identityMatrix} from "./utils";
|
|
||||||
|
|
||||||
class Matrix4 {
|
|
||||||
protected readonly matrix: Float32Array;
|
|
||||||
constructor(matrix: Float32Array | ArrayLike<number>);
|
|
||||||
constructor(...args: any[]) {
|
|
||||||
if (args[0].length === 16) {
|
|
||||||
if (!(args[0] instanceof Float32Array)) {
|
|
||||||
args[0] = new Float32Array(args[0]);
|
|
||||||
}
|
|
||||||
this.matrix = args[0];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new VectorSizeError(16, args[0].length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
times(other: Matrix4) {
|
|
||||||
const result = new Matrix4(Array<number>(16));
|
|
||||||
const a = this.matrix;
|
|
||||||
const b = other.matrix;
|
|
||||||
const c = result.matrix;
|
|
||||||
c[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12];
|
|
||||||
c[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13];
|
|
||||||
c[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14];
|
|
||||||
c[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15];
|
|
||||||
c[4] = a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12];
|
|
||||||
c[5] = a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13];
|
|
||||||
c[6] = a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14];
|
|
||||||
c[7] = a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15];
|
|
||||||
c[8] = a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12];
|
|
||||||
c[9] = a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13];
|
|
||||||
c[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14];
|
|
||||||
c[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15];
|
|
||||||
c[12] = a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12];
|
|
||||||
c[13] = a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13];
|
|
||||||
c[14] = a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14];
|
|
||||||
c[15] = a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15];
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
buffer(): Float32Array {
|
|
||||||
return this.matrix.slice();
|
|
||||||
}
|
|
||||||
set(m: number, n: number, val: number): void {
|
|
||||||
this.matrix[m * 4 + n] = val;
|
|
||||||
}
|
|
||||||
setRel(m: number, n: number, val: number): void {
|
|
||||||
this.matrix[m * 4 + n] += val;
|
|
||||||
}
|
|
||||||
static Identity(): Matrix4 {
|
|
||||||
return new Matrix4(identityMatrix(4));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Matrix4;
|
|
||||||
155
src/MatrixFour.ts
Normal file
155
src/MatrixFour.ts
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
import {identityMatrix} from "./utils";
|
||||||
|
import {VectorSizeError} from "./Errors";
|
||||||
|
|
||||||
|
class MatrixFour {
|
||||||
|
protected matrix: Float32Array;
|
||||||
|
constructor();
|
||||||
|
constructor(matrix: Float32Array | ArrayLike<number>);
|
||||||
|
constructor(...args: any[]) {
|
||||||
|
if (args[0]) {
|
||||||
|
if (args[0].length === 16) {
|
||||||
|
if (!(args[0] instanceof Float32Array)) {
|
||||||
|
args[0] = new Float32Array(args[0]);
|
||||||
|
}
|
||||||
|
this.matrix = args[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new VectorSizeError(16, args[0].length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.matrix = identityMatrix(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
times(other: MatrixFour) {
|
||||||
|
const result = new MatrixFour(Array<number>(16));
|
||||||
|
const a = this.matrix;
|
||||||
|
const b = other.matrix;
|
||||||
|
const c = result.matrix;
|
||||||
|
c[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12];
|
||||||
|
c[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13];
|
||||||
|
c[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14];
|
||||||
|
c[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15];
|
||||||
|
c[4] = a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12];
|
||||||
|
c[5] = a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13];
|
||||||
|
c[6] = a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14];
|
||||||
|
c[7] = a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15];
|
||||||
|
c[8] = a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12];
|
||||||
|
c[9] = a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13];
|
||||||
|
c[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14];
|
||||||
|
c[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15];
|
||||||
|
c[12] = a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12];
|
||||||
|
c[13] = a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13];
|
||||||
|
c[14] = a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14];
|
||||||
|
c[15] = a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer(start?: number, stop?: number): Float32Array {
|
||||||
|
return this.matrix.slice(start, stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
set(m: number, n: number, val: number): void {
|
||||||
|
this.matrix[m * 4 + n] = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
setSlice(vals: number[], offset: number): void {
|
||||||
|
this.matrix.set(vals, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
setRel(m: number, n: number, val: number): void {
|
||||||
|
this.matrix[m * 4 + n] += val;
|
||||||
|
}
|
||||||
|
|
||||||
|
inverse(): MatrixFour {
|
||||||
|
const m = this.matrix;
|
||||||
|
const m00 = m[0];
|
||||||
|
const m01 = m[1];
|
||||||
|
const m02 = m[2];
|
||||||
|
const m03 = m[3];
|
||||||
|
const m10 = m[4];
|
||||||
|
const m11 = m[5];
|
||||||
|
const m12 = m[6];
|
||||||
|
const m13 = m[7];
|
||||||
|
const m20 = m[8];
|
||||||
|
const m21 = m[9];
|
||||||
|
const m22 = m[10];
|
||||||
|
const m23 = m[11];
|
||||||
|
const m30 = m[12];
|
||||||
|
const m31 = m[13];
|
||||||
|
const m32 = m[14];
|
||||||
|
const m33 = m[15];
|
||||||
|
const tmp_0 = m22 * m33;
|
||||||
|
const tmp_1 = m32 * m23;
|
||||||
|
const tmp_2 = m12 * m33;
|
||||||
|
const tmp_3 = m32 * m13;
|
||||||
|
const tmp_4 = m12 * m23;
|
||||||
|
const tmp_5 = m22 * m13;
|
||||||
|
const tmp_6 = m02 * m33;
|
||||||
|
const tmp_7 = m32 * m03;
|
||||||
|
const tmp_8 = m02 * m23;
|
||||||
|
const tmp_9 = m22 * m03;
|
||||||
|
const tmp_10 = m02 * m13;
|
||||||
|
const tmp_11 = m12 * m03;
|
||||||
|
const tmp_12 = m20 * m31;
|
||||||
|
const tmp_13 = m30 * m21;
|
||||||
|
const tmp_14 = m10 * m31;
|
||||||
|
const tmp_15 = m30 * m11;
|
||||||
|
const tmp_16 = m10 * m21;
|
||||||
|
const tmp_17 = m20 * m11;
|
||||||
|
const tmp_18 = m00 * m31;
|
||||||
|
const tmp_19 = m30 * m01;
|
||||||
|
const tmp_20 = m00 * m21;
|
||||||
|
const tmp_21 = m20 * m01;
|
||||||
|
const tmp_22 = m00 * m11;
|
||||||
|
const tmp_23 = m10 * m01;
|
||||||
|
|
||||||
|
const t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) - (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31);
|
||||||
|
const t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) - (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31);
|
||||||
|
const t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) - (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31);
|
||||||
|
const t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) - (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21);
|
||||||
|
|
||||||
|
const d = 1.0 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3);
|
||||||
|
|
||||||
|
const result = new MatrixFour([
|
||||||
|
d * t0,
|
||||||
|
d * t1,
|
||||||
|
d * t2,
|
||||||
|
d * t3,
|
||||||
|
|
||||||
|
d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) - (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30)),
|
||||||
|
d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) - (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30)),
|
||||||
|
d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) - (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30)),
|
||||||
|
d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) - (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20)),
|
||||||
|
|
||||||
|
d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) - (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33)),
|
||||||
|
d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) - (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33)),
|
||||||
|
d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) - (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33)),
|
||||||
|
d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) - (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23)),
|
||||||
|
|
||||||
|
d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) - (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22)),
|
||||||
|
d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) - (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02)),
|
||||||
|
d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) - (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12)),
|
||||||
|
d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) - (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02))
|
||||||
|
]);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Perspective(fov: number, aspect: number, near: number, far: number): MatrixFour {
|
||||||
|
const f = Math.tan(Math.PI / 2 - fov / 2);
|
||||||
|
const rangeInv = 1.0 / (near - far);
|
||||||
|
return new MatrixFour(new Float32Array([
|
||||||
|
f / aspect, 0, 0, 0,
|
||||||
|
0, f, 0, 0,
|
||||||
|
0, 0, (near + far) * rangeInv, -1,
|
||||||
|
0, 0, near * far * rangeInv * 2, 0
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static Identity(): MatrixFour {
|
||||||
|
return new MatrixFour(identityMatrix(4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MatrixFour;
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import PointVec from "./PointVec";
|
import PointVec from "./PointVec";
|
||||||
|
import {VectorSizeError} from "./Errors";
|
||||||
|
|
||||||
class Point2D extends PointVec {
|
class Point2D extends PointVec {
|
||||||
constructor(vec: Float32Array | ArrayLike<number>);
|
constructor(vec: Float32Array | ArrayLike<number>);
|
||||||
|
|||||||
@@ -1,32 +1,102 @@
|
|||||||
import PointVec from "./PointVec";
|
import PointVec from "./PointVec";
|
||||||
|
import {VectorSizeError} from "./Errors";
|
||||||
|
|
||||||
class Point3D extends PointVec {
|
class Point3D extends PointVec {
|
||||||
|
private len: number;
|
||||||
|
private lengthCacheDirty: boolean;
|
||||||
constructor(vec: Float32Array | ArrayLike<number>);
|
constructor(vec: Float32Array | ArrayLike<number>);
|
||||||
constructor(x: number, y: number, z: number);
|
constructor(x: number, y: number, z: number);
|
||||||
constructor(first: any, second?: any, third?: any) {
|
constructor(...args: any[]) {
|
||||||
super(first, second, third);
|
if (typeof args[0] === "number") {
|
||||||
|
super(args[0], args[1], args[2]);
|
||||||
}
|
}
|
||||||
xOrd(): number {
|
else {
|
||||||
|
if (args[0].length !== 3) {
|
||||||
|
throw new VectorSizeError(3, args[0].length);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
super(args[0][0], args[0][1], args[0][2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.len = 0;
|
||||||
|
this.lengthCacheDirty = true;
|
||||||
|
}
|
||||||
|
x(): number {
|
||||||
return this.rep[0];
|
return this.rep[0];
|
||||||
}
|
}
|
||||||
yOrd(): number {
|
y(): number {
|
||||||
return this.rep[1];
|
return this.rep[1];
|
||||||
}
|
}
|
||||||
zOrd(): number {
|
z(): number {
|
||||||
return this.rep[2];
|
return this.rep[2];
|
||||||
}
|
}
|
||||||
setX(x: number): void {
|
setX(x: number): void {
|
||||||
this.rep[0] = x;
|
this.rep[0] = x;
|
||||||
|
this.lengthCacheDirty = false;
|
||||||
}
|
}
|
||||||
setY(y: number): void {
|
setY(y: number): void {
|
||||||
this.rep[1] = y;
|
this.rep[1] = y;
|
||||||
|
this.lengthCacheDirty = false;
|
||||||
}
|
}
|
||||||
setZ(z: number): void {
|
setZ(z: number): void {
|
||||||
this.rep[2] = z;
|
this.rep[2] = z;
|
||||||
|
this.lengthCacheDirty = false;
|
||||||
|
}
|
||||||
|
set(point: Point3D): void {
|
||||||
|
this.setX(point.x());
|
||||||
|
this.setY(point.y());
|
||||||
|
this.setZ(point.z());
|
||||||
}
|
}
|
||||||
vec(): Float32Array {
|
vec(): Float32Array {
|
||||||
return this.rep.slice();
|
return this.rep.slice();
|
||||||
}
|
}
|
||||||
|
cross(other: Point3D): Point3D {
|
||||||
|
return new Point3D(
|
||||||
|
this.y() * other.z() - this.z() * other.y(),
|
||||||
|
this.z() * other.x() - this.x() * other.z(),
|
||||||
|
this.x() * other.y() - this.y() * other.x(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
dot(other: Point3D): number {
|
||||||
|
return this.x() * other.x() + this.y() * other.y() + this.z() * other.z();
|
||||||
|
}
|
||||||
|
minus(other: Point3D): Point3D {
|
||||||
|
return new Point3D(
|
||||||
|
this.x() - other.x(),
|
||||||
|
this.y() - other.y(),
|
||||||
|
this.z() - other.z(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
plus(other: Point3D): Point3D {
|
||||||
|
return new Point3D(
|
||||||
|
this.x() + other.x(),
|
||||||
|
this.y() + other.y(),
|
||||||
|
this.z() + other.z(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
normalised(): Point3D {
|
||||||
|
const len = this.length();
|
||||||
|
if (len > 0.00001) {
|
||||||
|
return this.scaled(1 / len);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return Point3D.Zeros();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scaled(scalar: number) {
|
||||||
|
return new Point3D(
|
||||||
|
this.x() * scalar,
|
||||||
|
this.y() * scalar,
|
||||||
|
this.z() * scalar,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
length(): number {
|
||||||
|
if (this.lengthCacheDirty) {
|
||||||
|
this.len = Math.sqrt(this.dot(this));
|
||||||
|
this.lengthCacheDirty = false;
|
||||||
|
}
|
||||||
|
return this.len;
|
||||||
|
}
|
||||||
static Zeros(): Point3D {
|
static Zeros(): Point3D {
|
||||||
return new Point3D(0.0, 0.0, 0.0);
|
return new Point3D(0.0, 0.0, 0.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,12 @@
|
|||||||
|
import {Vector} from "./types";
|
||||||
|
|
||||||
abstract class PointVec implements Vector {
|
abstract class PointVec implements Vector {
|
||||||
protected rep: Float32Array;
|
protected rep: Float32Array;
|
||||||
protected constructor(vec: Float32Array | ArrayLike<number>);
|
protected constructor(first: number, second: number, third: number) {
|
||||||
protected constructor(x: number, y: number, z: number);
|
|
||||||
protected constructor(first: number | Float32Array | ArrayLike<number>, second?: number, third?: number) {
|
|
||||||
if (typeof first === "number") {
|
|
||||||
if (typeof second !== "number" || typeof third !== "number"){
|
|
||||||
throw new TypeError("Incorrect constructor call for Point3D");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.rep = new Float32Array(3);
|
this.rep = new Float32Array(3);
|
||||||
this.rep[0] = first;
|
this.rep[0] = first;
|
||||||
this.rep[1] = <number>second;
|
this.rep[1] = second;
|
||||||
this.rep[2] = <number>third;
|
this.rep[2] = third;
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.rep = new Float32Array(first[2]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
abstract vec(): Float32Array;
|
abstract vec(): Float32Array;
|
||||||
}
|
}
|
||||||
|
|||||||
76
src/TransformableGeometry.ts
Normal file
76
src/TransformableGeometry.ts
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import TrsMatrix from "./TrsMatrix";
|
||||||
|
import {VectorSizeError} from "./Errors";
|
||||||
|
import {Geometry, GeometryParams, Transformable} from "./types";
|
||||||
|
import Point3D from "./Point3D";
|
||||||
|
|
||||||
|
class TransformableGeometry implements Transformable, Geometry {
|
||||||
|
protected geometry: GeometryParams;
|
||||||
|
protected readonly trsMatrix: TrsMatrix;
|
||||||
|
constructor(geometry: {
|
||||||
|
pointBuffer: Float32Array,
|
||||||
|
normalBuffer: Float32Array,
|
||||||
|
elementBuffer?: ArrayLike<number>,
|
||||||
|
}, trsMatrix?: TrsMatrix) {
|
||||||
|
let elBuffer;
|
||||||
|
if (geometry.elementBuffer) {
|
||||||
|
elBuffer = new Uint16Array(geometry.elementBuffer);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (geometry.pointBuffer.length % 3 !== 0) {
|
||||||
|
throw new VectorSizeError("Multiple of 3 (no vertexOrder supplied)",
|
||||||
|
geometry.pointBuffer.length);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
elBuffer = new Uint16Array(Array(geometry.pointBuffer.length / 3).keys());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.geometry = {
|
||||||
|
pointBuffer: geometry.pointBuffer,
|
||||||
|
normalBuffer: geometry.normalBuffer,
|
||||||
|
elementBuffer: elBuffer,
|
||||||
|
};
|
||||||
|
this.trsMatrix = trsMatrix ?? new TrsMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
getTrsMatrix(): TrsMatrix {
|
||||||
|
return this.trsMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
pointBuffer(): Float32Array {
|
||||||
|
return this.geometry.pointBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
normalBuffer(): Float32Array {
|
||||||
|
return this.geometry.normalBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
elementBuffer(): Uint16Array {
|
||||||
|
return this.geometry.elementBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
position(): Point3D {
|
||||||
|
return this.trsMatrix.position();
|
||||||
|
}
|
||||||
|
|
||||||
|
translateBy(tX: number, tY: number, tZ: number): this {
|
||||||
|
this.trsMatrix.translateBy(tX, tY, tZ);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
rotateBy(degX: number, degY: number, degZ: number): this {
|
||||||
|
this.trsMatrix.rotateBy(degX, degY, degZ);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
scaleBy(xOrAll: number, sY?: number, sZ?: number): this {
|
||||||
|
if (sY && sZ) {
|
||||||
|
this.trsMatrix.scaleBy(xOrAll, sY, sZ);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.trsMatrix.scaleBy(xOrAll);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TransformableGeometry;
|
||||||
@@ -1,39 +1,56 @@
|
|||||||
import TrsMatrix from "./TrsMatrix";
|
import TrsMatrix from "./TrsMatrix";
|
||||||
import Point2D from "./Point2D";
|
import Point2D from "./Point2D";
|
||||||
|
import BasicColor from "./BasicColor";
|
||||||
|
import {VectorSizeError} from "./Errors";
|
||||||
|
import TransformableGeometry from "./TransformableGeometry";
|
||||||
|
import {triNormal} from "./utils";
|
||||||
|
import Point3D from "./Point3D";
|
||||||
|
import {Color, Colored, Transformable} from "./types";
|
||||||
|
|
||||||
class Triangle2D implements Transformable{
|
class Triangle2D extends TransformableGeometry implements Transformable, Colored {
|
||||||
private geometryRep: Float32Array;
|
|
||||||
private color: Color;
|
private color: Color;
|
||||||
private readonly trsMatrix: TrsMatrix;
|
constructor(pointBuffer: Float32Array, trsMatrix?: TrsMatrix, color?: Color);
|
||||||
constructor(vec: Float32Array, trsMatrix?: TrsMatrix, color?: Color);
|
constructor(p1: Point2D, p2: Point2D, p3: Point2D, trsMatrix?: TrsMatrix, color?: Color | ArrayLike<any>);
|
||||||
constructor(p1: Point2D, p2: Point2D, p3: Point2D, trsMatrix?: TrsMatrix, color?: Color);
|
|
||||||
constructor(...args: any[]) {
|
constructor(...args: any[]) {
|
||||||
|
let trsMatrix: TrsMatrix, pointBuff: Float32Array, color: Color | ArrayLike<number>;
|
||||||
if (args[0] instanceof Float32Array) {
|
if (args[0] instanceof Float32Array) {
|
||||||
if (args[0].length !== 6 && args[0].length !== 8) {
|
if (args[0].length !== 6 && args[0].length !== 8) {
|
||||||
throw new VectorSizeError("6 or 9", args[0].length)
|
throw new VectorSizeError("6 or 9", args[0].length)
|
||||||
}
|
}
|
||||||
else if (args[0].length === 6) {
|
else if (args[0].length === 6) {
|
||||||
this.geometryRep = new Float32Array([
|
pointBuff = new Float32Array([
|
||||||
...args[0].slice(0, 2), 0.0,
|
...args[0].slice(0, 2), 0.0,
|
||||||
...args[0].slice(2, 4), 0.0,
|
...args[0].slice(2, 4), 0.0,
|
||||||
...args[0].slice(4, 6), 0.0
|
...args[0].slice(4, 6), 0.0
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.geometryRep = args[0];
|
pointBuff = args[0];
|
||||||
}
|
}
|
||||||
this.trsMatrix = args[1] ?? new TrsMatrix();
|
trsMatrix = args[1] ?? new TrsMatrix();
|
||||||
this.color = args[2] ?? new BasicColor(0, 0, 0, 1.0);
|
color = args[2] ?? new BasicColor();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.geometryRep = new Float32Array([...args[0].vec(), ...args[1].vec(), ...args[2].vec()]);
|
pointBuff = new Float32Array([...args[0].vec(), ...args[1].vec(), ...args[2].vec()]);
|
||||||
this.trsMatrix = args[3] ?? new TrsMatrix();
|
trsMatrix = args[3] ?? new TrsMatrix();
|
||||||
this.color = args[4] ?? new BasicColor(0, 0, 0, 1.0);
|
color = args[4] ?? new BasicColor();
|
||||||
}
|
}
|
||||||
|
super({
|
||||||
|
pointBuffer: pointBuff,
|
||||||
|
normalBuffer: new Float32Array(
|
||||||
|
triNormal(
|
||||||
|
new Point3D(pointBuff.slice(0, 3)),
|
||||||
|
new Point3D(pointBuff.slice(3, 6)),
|
||||||
|
new Point3D(pointBuff.slice(6, 9))
|
||||||
|
).vec()
|
||||||
|
),
|
||||||
|
}, trsMatrix);
|
||||||
|
if (color.hasOwnProperty("length")) {
|
||||||
|
this.color = BasicColor.fromVec(color as ArrayLike<number>);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.color = color as Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
colorVec(): Float32Array {
|
|
||||||
return this.color.vec();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setColor(color: Color) {
|
setColor(color: Color) {
|
||||||
@@ -44,18 +61,14 @@ class Triangle2D implements Transformable{
|
|||||||
return this.color;
|
return this.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTrsMatrix(): TrsMatrix {
|
|
||||||
return this.trsMatrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
private mapPointTo(point: Point2D | ArrayLike<number>, x: number) {
|
private mapPointTo(point: Point2D | ArrayLike<number>, x: number) {
|
||||||
if (point instanceof Point2D) {
|
if (point instanceof Point2D) {
|
||||||
this.geometryRep[x] = point.xOrd();
|
this.geometry.pointBuffer[x] = point.xOrd();
|
||||||
this.geometryRep[x + 1] = point.yOrd();
|
this.geometry.pointBuffer[x + 1] = point.yOrd();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.geometryRep[x] = point[0];
|
this.geometry.pointBuffer[x] = point[0];
|
||||||
this.geometryRep[x + 1] = point[1];
|
this.geometry.pointBuffer[x + 1] = point[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,34 +85,6 @@ class Triangle2D implements Transformable{
|
|||||||
this.mapPointTo(p3, 6);
|
this.mapPointTo(p3, 6);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePointsFromVec(vec: Float32Array) {
|
|
||||||
if (vec.length === 6) {
|
|
||||||
this.geometryRep = vec;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new VectorSizeError(6, vec.length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pointBuffer(): Float32Array {
|
|
||||||
return this.geometryRep;
|
|
||||||
}
|
|
||||||
|
|
||||||
translateBy(tX: number, tY: number, tZ: number): Triangle2D {
|
|
||||||
this.trsMatrix.translateBy(tX, tY, tZ);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
rotateBy(degX: number, degY: number, degZ: number): Triangle2D {
|
|
||||||
this.trsMatrix.rotateBy(degX, degY, degZ);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
scaleBy(sX: number, sY: number, sZ: number): Triangle2D {
|
|
||||||
this.trsMatrix.scaleBy(sX, sY, sZ);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Triangle2D;
|
export default Triangle2D;
|
||||||
@@ -1,34 +1,44 @@
|
|||||||
import Matrix4 from "./Matrix4";
|
import MatrixFour from "./MatrixFour";
|
||||||
|
import Point3D from "./Point3D";
|
||||||
|
|
||||||
class TrsMatrix implements Transformable {
|
class TrsMatrix extends MatrixFour {
|
||||||
protected trs: Matrix4 = Matrix4.Identity();
|
|
||||||
constructor();
|
constructor();
|
||||||
constructor(translation: Matrix4, rotX: Matrix4, rotY: Matrix4, rotZ: Matrix4, scale: Matrix4);
|
constructor(translation: MatrixFour, rotX: MatrixFour, rotY: MatrixFour, rotZ: MatrixFour, scale: MatrixFour);
|
||||||
constructor(mat: TrsMatrix);
|
constructor(mat: TrsMatrix);
|
||||||
constructor(...args: any[]) {
|
constructor(...args: any[]) {
|
||||||
|
super();
|
||||||
if (args[0]) {
|
if (args[0]) {
|
||||||
if (args[0] instanceof TrsMatrix) {
|
if (args[0] instanceof TrsMatrix) {
|
||||||
this.trs = new Matrix4(args[0].buffer());
|
this.matrix = args[0].buffer();
|
||||||
} else {
|
} else {
|
||||||
this.trs = args[0].times(args[1]).times(args[2]).times(args[3]).times(args[4])
|
this.matrix = args[0].times(args[1]).times(args[2]).times(args[3]).times(args[4])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
toMatrix4(): Matrix4 {
|
|
||||||
return this.trs;
|
position(): Point3D {
|
||||||
|
return new Point3D(this.buffer(12, 15));
|
||||||
}
|
}
|
||||||
buffer(): Float32Array {
|
|
||||||
return this.trs.buffer();
|
setPosition(xOrPoint: number | Point3D, y?: number, z?: number): void {
|
||||||
|
if (xOrPoint instanceof Point3D) {
|
||||||
|
this.setSlice([xOrPoint.x(), xOrPoint.y(), xOrPoint.z()], 12);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
this.setSlice([xOrPoint, y ?? 0, z ?? 0], 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
translateBy(tX: number, tY: number, tZ: number): TrsMatrix {
|
translateBy(tX: number, tY: number, tZ: number): TrsMatrix {
|
||||||
this.trs = this.trs.times(new Matrix4([
|
this.matrix = this.times(new MatrixFour([
|
||||||
1, 0, 0, 0,
|
1, 0, 0, 0,
|
||||||
0, 1, 0, 0,
|
0, 1, 0, 0,
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
tX, tY, tZ, 1,
|
tX, tY, tZ, 1,
|
||||||
]));
|
])).buffer();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
rotateBy(degX: number, degY: number, degZ: number): TrsMatrix {
|
rotateBy(degX: number, degY: number, degZ: number): TrsMatrix {
|
||||||
const sx = Math.sin(degX);
|
const sx = Math.sin(degX);
|
||||||
const cx = Math.cos(degX);
|
const cx = Math.cos(degX);
|
||||||
@@ -36,34 +46,39 @@ class TrsMatrix implements Transformable {
|
|||||||
const cy = Math.cos(degY);
|
const cy = Math.cos(degY);
|
||||||
const sz = Math.sin(degZ);
|
const sz = Math.sin(degZ);
|
||||||
const cz = Math.cos(degZ);
|
const cz = Math.cos(degZ);
|
||||||
this.trs = this.trs
|
this.matrix = this
|
||||||
.times(new Matrix4([
|
.times(new MatrixFour([
|
||||||
1, 0, 0, 0,
|
1, 0, 0, 0,
|
||||||
0, cx, sx, 0,
|
0, cx, sx, 0,
|
||||||
0, -sx, cx, 0,
|
0, -sx, cx, 0,
|
||||||
0, 0, 0, 1,
|
0, 0, 0, 1,
|
||||||
]))
|
]))
|
||||||
.times(new Matrix4([
|
.times(new MatrixFour([
|
||||||
cy, 0, -sy, 0,
|
cy, 0, -sy, 0,
|
||||||
0, 1, 0, 0,
|
0, 1, 0, 0,
|
||||||
sy, 0, cy, 0,
|
sy, 0, cy, 0,
|
||||||
0, 0, 0, 1,
|
0, 0, 0, 1,
|
||||||
]))
|
]))
|
||||||
.times(new Matrix4([
|
.times(new MatrixFour([
|
||||||
cz, sz, 0, 0,
|
cz, sz, 0, 0,
|
||||||
-sz, cz, 0, 0,
|
-sz, cz, 0, 0,
|
||||||
0, 0, 1, 0,
|
0, 0, 1, 0,
|
||||||
0, 0, 0, 1,
|
0, 0, 0, 1,
|
||||||
]));
|
])).buffer();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
scaleBy(sX: number, sY: number, sZ: number): TrsMatrix {
|
|
||||||
this.trs = this.trs.times(new Matrix4([
|
scaleBy(xOrAll: number, sY?: number, sZ?: number): TrsMatrix {
|
||||||
sX, 0, 0, 0,
|
if (sY === undefined || sZ === undefined) {
|
||||||
|
sY = xOrAll;
|
||||||
|
sZ = xOrAll;
|
||||||
|
}
|
||||||
|
this.matrix = this.times(new MatrixFour([
|
||||||
|
xOrAll, 0, 0, 0,
|
||||||
0, sY, 0, 0,
|
0, sY, 0, 0,
|
||||||
0, 0, sZ, 0,
|
0, 0, sZ, 0,
|
||||||
0, 0, 0, 1,
|
0, 0, 0, 1,
|
||||||
]));
|
])).buffer();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|
||||||
uniform vec4 u_color;
|
uniform vec4 u_color;
|
||||||
|
|
||||||
varying float v_depth;
|
varying float v_depth;
|
||||||
|
varying vec3 v_light;
|
||||||
|
varying vec3 v_normal;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_FragColor = vec4(exp(v_depth), exp(v_depth), exp(v_depth), 1.0);
|
vec3 normal = normalize(v_normal);
|
||||||
|
float light = dot(normal, v_light);
|
||||||
|
gl_FragColor = u_color * (1.0 + light - light);
|
||||||
}
|
}
|
||||||
28
src/types.d.ts
vendored
28
src/types.d.ts
vendored
@@ -1,3 +1,6 @@
|
|||||||
|
import TrsMatrix from "./TrsMatrix";
|
||||||
|
import Point3D from "./Point3D";
|
||||||
|
|
||||||
declare module '*.glsl' {
|
declare module '*.glsl' {
|
||||||
const value: string;
|
const value: string;
|
||||||
export = value;
|
export = value;
|
||||||
@@ -8,9 +11,16 @@ declare interface Vector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare interface Transformable {
|
declare interface Transformable {
|
||||||
translateBy(tX: number, tY: number, tZ: number): any;
|
translateBy(tX: number, tY: number, tZ: number): Transformable;
|
||||||
rotateBy(degX: number, degY: number, degZ: number): any;
|
rotateBy(degX: number, degY: number, degZ: number): Transformable;
|
||||||
scaleBy(sX: number, sY: number, sZ: number): any;
|
scaleBy(sX: number, sY: number, sZ: number): Transformable;
|
||||||
|
getTrsMatrix(): TrsMatrix;
|
||||||
|
position(): Point3D;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare interface Colored {
|
||||||
|
setColor(color: Color);
|
||||||
|
getColor(): Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare interface Color extends Vector {
|
declare interface Color extends Vector {
|
||||||
@@ -19,3 +29,15 @@ declare interface Color extends Vector {
|
|||||||
blue(): number;
|
blue(): number;
|
||||||
alpha(): number;
|
alpha(): number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare interface GeometryParams {
|
||||||
|
pointBuffer: Float32Array;
|
||||||
|
normalBuffer: Float32Array;
|
||||||
|
elementBuffer: Uint16Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare interface Geometry {
|
||||||
|
pointBuffer(): Float32Array;
|
||||||
|
normalBuffer(): Float32Array;
|
||||||
|
elementBuffer(): Uint16Array;
|
||||||
|
}
|
||||||
19
src/utils.ts
19
src/utils.ts
@@ -1,4 +1,9 @@
|
|||||||
import Matrix4 from "./Matrix4";
|
import MatrixFour from "./MatrixFour";
|
||||||
|
import Triangle2D from "./Triangle2D";
|
||||||
|
import TrsMatrix from "./TrsMatrix";
|
||||||
|
import Point2D from "./Point2D";
|
||||||
|
import BasicColor from "./BasicColor";
|
||||||
|
import Point3D from "./Point3D";
|
||||||
|
|
||||||
export function identityMatrix(size: number): Float32Array {
|
export function identityMatrix(size: number): Float32Array {
|
||||||
const mat = Array<number>(size*size).fill(0);
|
const mat = Array<number>(size*size).fill(0);
|
||||||
@@ -8,14 +13,6 @@ export function identityMatrix(size: number): Float32Array {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function perspMat(fovDeg: number, aspect: number, near: number, far: number): Matrix4 {
|
export function triNormal(p1: Point3D, p2: Point3D, p3: Point3D): Point3D {
|
||||||
const f = Math.tan(Math.PI * 0.5 - 0.5 * fovDeg);
|
return p2.minus(p1).cross(p3.minus(p1));
|
||||||
const rangeInv = 1.0 / (near - far);
|
|
||||||
|
|
||||||
return new Matrix4([
|
|
||||||
f / aspect, 0, 0, 0,
|
|
||||||
0, f, 0, 0,
|
|
||||||
0, 0, (near + far) * rangeInv, -1,
|
|
||||||
0, 0, near * far * rangeInv * 2, 0
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,14 @@
|
|||||||
attribute vec4 a_position;
|
attribute vec4 a_position;
|
||||||
|
attribute vec4 a_normal;
|
||||||
uniform mat4 u_trsMatrix;
|
uniform mat4 u_trsMatrix;
|
||||||
|
|
||||||
|
varying vec3 v_light;
|
||||||
varying float v_depth;
|
varying float v_depth;
|
||||||
|
varying vec3 v_normal;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
v_light = vec3(0.0, 0.0, 1.0);
|
||||||
|
v_normal = (u_trsMatrix * a_normal).xyz;
|
||||||
vec4 pos = u_trsMatrix * a_position;
|
vec4 pos = u_trsMatrix * a_position;
|
||||||
v_depth = pos.z;
|
v_depth = pos.z;
|
||||||
gl_Position = pos;
|
gl_Position = pos;
|
||||||
|
|||||||
Reference in New Issue
Block a user