Define basic data structure
This commit is contained in:
		@@ -2,7 +2,11 @@
 | 
				
			|||||||
	"name": "oktaeder",
 | 
						"name": "oktaeder",
 | 
				
			||||||
	"version": "0.1.0",
 | 
						"version": "0.1.0",
 | 
				
			||||||
	"description": "3D rendering library for WebGPU",
 | 
						"description": "3D rendering library for WebGPU",
 | 
				
			||||||
	"keywords": ["3d", "gltf", "wegbpu"],
 | 
						"keywords": [
 | 
				
			||||||
 | 
							"3d",
 | 
				
			||||||
 | 
							"gltf",
 | 
				
			||||||
 | 
							"wegbpu"
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
	"homepage": "https://github.com/iszn11/oktaeder",
 | 
						"homepage": "https://github.com/iszn11/oktaeder",
 | 
				
			||||||
	"bugs": {
 | 
						"bugs": {
 | 
				
			||||||
		"url": "https://github.com/iszn11/oktaeder/issues"
 | 
							"url": "https://github.com/iszn11/oktaeder/issues"
 | 
				
			||||||
@@ -20,6 +24,7 @@
 | 
				
			|||||||
		"tslib": "^2.6.1"
 | 
							"tslib": "^2.6.1"
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"devDependencies": {
 | 
						"devDependencies": {
 | 
				
			||||||
 | 
							"@webgpu/types": "^0.1.34",
 | 
				
			||||||
		"typescript": "5.1.6"
 | 
							"typescript": "5.1.6"
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"exports": {
 | 
						"exports": {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							@@ -10,12 +10,19 @@ dependencies:
 | 
				
			|||||||
    version: 2.6.1
 | 
					    version: 2.6.1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
devDependencies:
 | 
					devDependencies:
 | 
				
			||||||
 | 
					  '@webgpu/types':
 | 
				
			||||||
 | 
					    specifier: ^0.1.34
 | 
				
			||||||
 | 
					    version: 0.1.34
 | 
				
			||||||
  typescript:
 | 
					  typescript:
 | 
				
			||||||
    specifier: 5.1.6
 | 
					    specifier: 5.1.6
 | 
				
			||||||
    version: 5.1.6
 | 
					    version: 5.1.6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
packages:
 | 
					packages:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /@webgpu/types@0.1.34:
 | 
				
			||||||
 | 
					    resolution: {integrity: sha512-9mXtH+CC8q+Ku7Z+1XazNIte81FvfdXwR2lLRO7Ykzjd/hh1J1krJa0gtnkF1kvP11psUmKEPKo7iMTeEcUpNA==}
 | 
				
			||||||
 | 
					    dev: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /tslib@2.6.1:
 | 
					  /tslib@2.6.1:
 | 
				
			||||||
    resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==}
 | 
					    resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==}
 | 
				
			||||||
    dev: false
 | 
					    dev: false
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										115
									
								
								src/Camera.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								src/Camera.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,115 @@
 | 
				
			|||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public License,
 | 
				
			||||||
 | 
					 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 | 
				
			||||||
 | 
					 * obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Node } from "./Node";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type Camera = CameraOrthographic | CameraPerspective;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface CameraOrthographicProps {
 | 
				
			||||||
 | 
						readonly name?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly verticalSize: number;
 | 
				
			||||||
 | 
						readonly nearPlane: number;
 | 
				
			||||||
 | 
						readonly farPlane: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface CameraPerspectiveProps {
 | 
				
			||||||
 | 
						readonly name?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly verticalFovRad: number;
 | 
				
			||||||
 | 
						readonly nearPlane: number;
 | 
				
			||||||
 | 
						readonly farPlane: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class CameraOrthographic {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly type!: "CameraOrthographic";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_name: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_verticalSize: number;
 | 
				
			||||||
 | 
						_nearPlane: number;
 | 
				
			||||||
 | 
						_farPlane: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** backreference */
 | 
				
			||||||
 | 
						_node: Node | undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						constructor({
 | 
				
			||||||
 | 
							name = "",
 | 
				
			||||||
 | 
							verticalSize,
 | 
				
			||||||
 | 
							nearPlane,
 | 
				
			||||||
 | 
							farPlane,
 | 
				
			||||||
 | 
						}: CameraOrthographicProps) {
 | 
				
			||||||
 | 
							Object.defineProperty(this, "type", { value: "CameraOrthographic" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._name = name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._verticalSize = verticalSize;
 | 
				
			||||||
 | 
							this._nearPlane = nearPlane;
 | 
				
			||||||
 | 
							this._farPlane = farPlane;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._node = undefined;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						detach(): Camera {
 | 
				
			||||||
 | 
							if (this._node === undefined) {
 | 
				
			||||||
 | 
								return this;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._node._camera = undefined;
 | 
				
			||||||
 | 
							this._node = undefined;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class CameraPerspective {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly type!: "CameraPerspective";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_name: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_verticalFovRad: number;
 | 
				
			||||||
 | 
						_nearPlane: number;
 | 
				
			||||||
 | 
						_farPlane: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** backreference */
 | 
				
			||||||
 | 
						_node: Node | undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						constructor({
 | 
				
			||||||
 | 
							name = "",
 | 
				
			||||||
 | 
							verticalFovRad,
 | 
				
			||||||
 | 
							nearPlane,
 | 
				
			||||||
 | 
							farPlane,
 | 
				
			||||||
 | 
						}: CameraPerspectiveProps) {
 | 
				
			||||||
 | 
							Object.defineProperty(this, "type", { value: "CameraPerspective" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._name = name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._verticalFovRad = verticalFovRad;
 | 
				
			||||||
 | 
							this._nearPlane = nearPlane;
 | 
				
			||||||
 | 
							this._farPlane = farPlane;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._node = undefined;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						detach(): Camera {
 | 
				
			||||||
 | 
							if (this._node === undefined) {
 | 
				
			||||||
 | 
								return this;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._node._camera = undefined;
 | 
				
			||||||
 | 
							this._node = undefined;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isCameraOrthographic(value: unknown): value is CameraOrthographic {
 | 
				
			||||||
 | 
						return Boolean(value) && (value as CameraOrthographic).type === "CameraOrthographic";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isCameraPerspective(value: unknown): value is CameraPerspective {
 | 
				
			||||||
 | 
						return Boolean(value) && (value as CameraPerspective).type === "CameraPerspective";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										266
									
								
								src/Color.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										266
									
								
								src/Color.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,266 @@
 | 
				
			|||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public License,
 | 
				
			||||||
 | 
					 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 | 
				
			||||||
 | 
					 * obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Vector3Object } from "./Vector3";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Named colors
 | 
				
			||||||
 | 
					 * black       #000000   (0, 0, 0, 1)
 | 
				
			||||||
 | 
					 * silver      #C0C0C0   (192 / 255, 192 / 255, 192 / 255, 1)
 | 
				
			||||||
 | 
					 * gray        #808080   (128 / 255, 128 / 255, 128 / 255, 1)
 | 
				
			||||||
 | 
					 * white       #FFFFFF   (1, 1, 1, 1)
 | 
				
			||||||
 | 
					 * maroon      #800000   (128 / 255, 0, 0, 1)
 | 
				
			||||||
 | 
					 * red         #FF0000   (1, 0, 0, 1)
 | 
				
			||||||
 | 
					 * purple      #800080   (128 / 255, 0, 128 / 255, 1)
 | 
				
			||||||
 | 
					 * fuchsia     #FF00FF   (1, 0, 1, 1)
 | 
				
			||||||
 | 
					 * green       #008000   (0, 128 / 255, 0, 1)
 | 
				
			||||||
 | 
					 * lime        #00FF00   (0, 255, 0, 1)
 | 
				
			||||||
 | 
					 * olive       #808000   (128 / 255, 128 / 255, 0, 1)
 | 
				
			||||||
 | 
					 * yellow      #FFFF00   (1, 1, 0, 1)
 | 
				
			||||||
 | 
					 * navy        #000080   (0, 0, 128 / 255, 1)
 | 
				
			||||||
 | 
					 * blue        #0000FF   (0, 0, 1, 1)
 | 
				
			||||||
 | 
					 * teal        #008080   (0, 128 / 255, 128 / 255, 1)
 | 
				
			||||||
 | 
					 * aqua        #00FFFF   (0, 1, 1, 1)
 | 
				
			||||||
 | 
					 * orange      #FFA500   (1, 165 / 255, 0, 1)
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type ColorName =
 | 
				
			||||||
 | 
						| "black"
 | 
				
			||||||
 | 
						| "silver"
 | 
				
			||||||
 | 
						| "gray"
 | 
				
			||||||
 | 
						| "white"
 | 
				
			||||||
 | 
						| "maroon"
 | 
				
			||||||
 | 
						| "red"
 | 
				
			||||||
 | 
						| "purple"
 | 
				
			||||||
 | 
						| "fuchsia"
 | 
				
			||||||
 | 
						| "green"
 | 
				
			||||||
 | 
						| "lime"
 | 
				
			||||||
 | 
						| "olive"
 | 
				
			||||||
 | 
						| "yellow"
 | 
				
			||||||
 | 
						| "navy"
 | 
				
			||||||
 | 
						| "blue"
 | 
				
			||||||
 | 
						| "teal"
 | 
				
			||||||
 | 
						| "aqua"
 | 
				
			||||||
 | 
						| "orange"
 | 
				
			||||||
 | 
						;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface ColorObject {
 | 
				
			||||||
 | 
						readonly r: number;
 | 
				
			||||||
 | 
						readonly g: number;
 | 
				
			||||||
 | 
						readonly b: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type ColorTuple = readonly [r: number, g: number, b: number];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class Color {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly type!: "Color";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						r: number;
 | 
				
			||||||
 | 
						g: number;
 | 
				
			||||||
 | 
						b: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						constructor(r: number, g: number, b: number) {
 | 
				
			||||||
 | 
							Object.defineProperty(this, "type", { value: "Color" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this.r = r;
 | 
				
			||||||
 | 
							this.g = g;
 | 
				
			||||||
 | 
							this.b = b;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static fromObject(object: ColorObject): Color {
 | 
				
			||||||
 | 
							return new Color(object.r, object.g, object.b);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static fromTuple(tuple: ColorTuple): Color {
 | 
				
			||||||
 | 
							return new Color(...tuple);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static fromName(name: ColorName): Color {
 | 
				
			||||||
 | 
							switch (name) {
 | 
				
			||||||
 | 
								case "black": return new Color(0, 0, 0);
 | 
				
			||||||
 | 
								case "silver": return new Color(192 / 255, 192 / 255, 192 / 255);
 | 
				
			||||||
 | 
								case "gray": return new Color(128 / 255, 128 / 255, 128 / 255);
 | 
				
			||||||
 | 
								case "white": return new Color(1, 1, 1);
 | 
				
			||||||
 | 
								case "maroon": return new Color(128 / 255, 0, 0);
 | 
				
			||||||
 | 
								case "red": return new Color(1, 0, 0);
 | 
				
			||||||
 | 
								case "purple": return new Color(128 / 255, 0, 128 / 255);
 | 
				
			||||||
 | 
								case "fuchsia": return new Color(1, 0, 1);
 | 
				
			||||||
 | 
								case "green": return new Color(0, 128 / 255, 0);
 | 
				
			||||||
 | 
								case "lime": return new Color(0, 255, 0);
 | 
				
			||||||
 | 
								case "olive": return new Color(128 / 255, 128 / 255, 0);
 | 
				
			||||||
 | 
								case "yellow": return new Color(1, 1, 0);
 | 
				
			||||||
 | 
								case "navy": return new Color(0, 0, 128 / 255);
 | 
				
			||||||
 | 
								case "blue": return new Color(0, 0, 1);
 | 
				
			||||||
 | 
								case "teal": return new Color(0, 128 / 255, 128 / 255);
 | 
				
			||||||
 | 
								case "aqua": return new Color(0, 1, 1);
 | 
				
			||||||
 | 
								case "orange": return new Color(1, 165 / 255, 0);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static fromVector3(vector: Vector3Object): Color {
 | 
				
			||||||
 | 
							return new Color(vector.x, vector.y, vector.z);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static white(): Color {
 | 
				
			||||||
 | 
							return new Color(1, 1, 1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static black(): Color {
 | 
				
			||||||
 | 
							return new Color(0, 0, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set(r: number, g: number, b: number): Color {
 | 
				
			||||||
 | 
							this.r = r;
 | 
				
			||||||
 | 
							this.g = g;
 | 
				
			||||||
 | 
							this.b = b;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setObject(object: ColorObject): Color {
 | 
				
			||||||
 | 
							this.r = object.r;
 | 
				
			||||||
 | 
							this.g = object.g;
 | 
				
			||||||
 | 
							this.b = object.b;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setTuple(tuple: ColorTuple): Color {
 | 
				
			||||||
 | 
							this.r = tuple[0];
 | 
				
			||||||
 | 
							this.g = tuple[1];
 | 
				
			||||||
 | 
							this.b = tuple[2];
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setName(name: ColorName): Color {
 | 
				
			||||||
 | 
							switch (name) {
 | 
				
			||||||
 | 
								case "black":
 | 
				
			||||||
 | 
									this.r = 0;
 | 
				
			||||||
 | 
									this.g = 0;
 | 
				
			||||||
 | 
									this.b = 0;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "silver":
 | 
				
			||||||
 | 
									this.r = 192 / 255;
 | 
				
			||||||
 | 
									this.g = 192 / 255;
 | 
				
			||||||
 | 
									this.b = 192 / 255;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "gray":
 | 
				
			||||||
 | 
									this.r = 128 / 255;
 | 
				
			||||||
 | 
									this.g = 128 / 255;
 | 
				
			||||||
 | 
									this.b = 128 / 255;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "white":
 | 
				
			||||||
 | 
									this.r = 1;
 | 
				
			||||||
 | 
									this.g = 1;
 | 
				
			||||||
 | 
									this.b = 1;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "maroon":
 | 
				
			||||||
 | 
									this.r = 128 / 255;
 | 
				
			||||||
 | 
									this.g = 0;
 | 
				
			||||||
 | 
									this.b = 0;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "red":
 | 
				
			||||||
 | 
									this.r = 1;
 | 
				
			||||||
 | 
									this.g = 0;
 | 
				
			||||||
 | 
									this.b = 0;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "purple":
 | 
				
			||||||
 | 
									this.r = 128 / 255;
 | 
				
			||||||
 | 
									this.g = 0;
 | 
				
			||||||
 | 
									this.b = 128 / 255;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "fuchsia":
 | 
				
			||||||
 | 
									this.r = 1;
 | 
				
			||||||
 | 
									this.g = 0;
 | 
				
			||||||
 | 
									this.b = 1;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "green":
 | 
				
			||||||
 | 
									this.r = 0;
 | 
				
			||||||
 | 
									this.g = 128 / 255;
 | 
				
			||||||
 | 
									this.b = 0;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "lime":
 | 
				
			||||||
 | 
									this.r = 0;
 | 
				
			||||||
 | 
									this.g = 255;
 | 
				
			||||||
 | 
									this.b = 0;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "olive":
 | 
				
			||||||
 | 
									this.r = 128 / 255;
 | 
				
			||||||
 | 
									this.g = 128 / 255;
 | 
				
			||||||
 | 
									this.b = 0;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "yellow":
 | 
				
			||||||
 | 
									this.r = 1;
 | 
				
			||||||
 | 
									this.g = 1;
 | 
				
			||||||
 | 
									this.b = 0;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "navy":
 | 
				
			||||||
 | 
									this.r = 0;
 | 
				
			||||||
 | 
									this.g = 0;
 | 
				
			||||||
 | 
									this.b = 128 / 255;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "blue":
 | 
				
			||||||
 | 
									this.r = 0;
 | 
				
			||||||
 | 
									this.g = 0;
 | 
				
			||||||
 | 
									this.b = 1;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "teal":
 | 
				
			||||||
 | 
									this.r = 0;
 | 
				
			||||||
 | 
									this.g = 128 / 255;
 | 
				
			||||||
 | 
									this.b = 128 / 255;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "aqua":
 | 
				
			||||||
 | 
									this.r = 0;
 | 
				
			||||||
 | 
									this.g = 1;
 | 
				
			||||||
 | 
									this.b = 1;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case "orange":
 | 
				
			||||||
 | 
									this.r = 1;
 | 
				
			||||||
 | 
									this.g = 165 / 255;
 | 
				
			||||||
 | 
									this.b = 0;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setVector3(vector: Vector3Object): Color {
 | 
				
			||||||
 | 
							this.r = vector.x;
 | 
				
			||||||
 | 
							this.g = vector.y;
 | 
				
			||||||
 | 
							this.b = vector.z;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setWhite(): Color {
 | 
				
			||||||
 | 
							this.r = 1;
 | 
				
			||||||
 | 
							this.g = 1;
 | 
				
			||||||
 | 
							this.b = 1;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setBlack(): Color {
 | 
				
			||||||
 | 
							this.r = 0;
 | 
				
			||||||
 | 
							this.g = 0;
 | 
				
			||||||
 | 
							this.b = 0;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setR(r: number): Color {
 | 
				
			||||||
 | 
							this.r = r;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setG(g: number): Color {
 | 
				
			||||||
 | 
							this.g = g;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setB(b: number): Color {
 | 
				
			||||||
 | 
							this.b = b;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isColor(value: unknown): value is Color {
 | 
				
			||||||
 | 
						return Boolean(value) && (value as Color).type === "Color";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										49
									
								
								src/IndexBuffer.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/IndexBuffer.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public License,
 | 
				
			||||||
 | 
					 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 | 
				
			||||||
 | 
					 * obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const INDEX_SIZE = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class IndexBuffer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly type!: "IndexBuffer";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_device: GPUDevice;
 | 
				
			||||||
 | 
						_buffer: GPUBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						constructor(device: GPUDevice, indexCount: number) {
 | 
				
			||||||
 | 
							Object.defineProperty(this, "type", { value: "IndexBuffer" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._device = device;
 | 
				
			||||||
 | 
							this._buffer = device.createBuffer({
 | 
				
			||||||
 | 
								usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.INDEX,
 | 
				
			||||||
 | 
								size: indexCount * INDEX_SIZE,
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dispose(): IndexBuffer {
 | 
				
			||||||
 | 
							this._buffer.destroy();
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						get vertexCount(): number {
 | 
				
			||||||
 | 
							return this._buffer.size / INDEX_SIZE | 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeArray(offset: number, indices: readonly number[]): IndexBuffer {
 | 
				
			||||||
 | 
							const array = new Uint16Array(indices);
 | 
				
			||||||
 | 
							this._device.queue.writeBuffer(this._buffer, offset * INDEX_SIZE | 0, array);
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeTypedArray(offset: number, indices: Uint16Array): IndexBuffer {
 | 
				
			||||||
 | 
							this._device.queue.writeBuffer(this._buffer, offset * INDEX_SIZE | 0, indices);
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isIndexBuffer(value: unknown): value is IndexBuffer {
 | 
				
			||||||
 | 
						return Boolean(value) && (value as IndexBuffer).type === "IndexBuffer";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										76
									
								
								src/Material.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/Material.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
				
			|||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public License,
 | 
				
			||||||
 | 
					 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 | 
				
			||||||
 | 
					 * obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Color, ColorObject } from "./Color";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface MaterialProps {
 | 
				
			||||||
 | 
						name?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						baseColor?: ColorObject;
 | 
				
			||||||
 | 
						metallic?: number;
 | 
				
			||||||
 | 
						roughness?: number;
 | 
				
			||||||
 | 
						emissive?: ColorObject;
 | 
				
			||||||
 | 
						partialCoverage?: number;
 | 
				
			||||||
 | 
						transmission?: ColorObject;
 | 
				
			||||||
 | 
						collimation?: number;
 | 
				
			||||||
 | 
						ior?: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						doubleSided?: boolean;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class Material {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly type!: "Material";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_name: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_baseColor: Color;
 | 
				
			||||||
 | 
						_metallic: number;
 | 
				
			||||||
 | 
						_roughness: number;
 | 
				
			||||||
 | 
						_emissive: Color;
 | 
				
			||||||
 | 
						_partialCoverage: number;
 | 
				
			||||||
 | 
						_transmission: Color;
 | 
				
			||||||
 | 
						_collimation: number;
 | 
				
			||||||
 | 
						_ior: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_doubleSided: boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						constructor({
 | 
				
			||||||
 | 
							name = "",
 | 
				
			||||||
 | 
							baseColor,
 | 
				
			||||||
 | 
							metallic = 1,
 | 
				
			||||||
 | 
							roughness = 1,
 | 
				
			||||||
 | 
							emissive,
 | 
				
			||||||
 | 
							partialCoverage = 1,
 | 
				
			||||||
 | 
							transmission,
 | 
				
			||||||
 | 
							collimation = 1,
 | 
				
			||||||
 | 
							ior = 1.45,
 | 
				
			||||||
 | 
							doubleSided = false,
 | 
				
			||||||
 | 
						}: MaterialProps) {
 | 
				
			||||||
 | 
							Object.defineProperty(this, "type", { value: "Material" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._name = name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._baseColor = baseColor !== undefined ? Color.fromObject(baseColor) : Color.white();
 | 
				
			||||||
 | 
							this._metallic = metallic;
 | 
				
			||||||
 | 
							this._roughness = roughness;
 | 
				
			||||||
 | 
							this._emissive = emissive !== undefined ? Color.fromObject(emissive) : Color.black();
 | 
				
			||||||
 | 
							this._partialCoverage = partialCoverage;
 | 
				
			||||||
 | 
							this._transmission = transmission !== undefined ? Color.fromObject(transmission) : Color.black();
 | 
				
			||||||
 | 
							this._collimation = collimation;
 | 
				
			||||||
 | 
							this._ior = ior;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._doubleSided = doubleSided;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						get isTransparent(): boolean {
 | 
				
			||||||
 | 
							return this._partialCoverage < 1 || this._transmission.r > 0 || this._transmission.g > 0 || this._transmission.b > 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isMaterial(value: unknown): value is Material {
 | 
				
			||||||
 | 
						return Boolean(value) && (value as Material).type === "Material";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										246
									
								
								src/Matrix4x4.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										246
									
								
								src/Matrix4x4.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,246 @@
 | 
				
			|||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public License,
 | 
				
			||||||
 | 
					 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 | 
				
			||||||
 | 
					 * obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { QuaternionObject } from "./Quaternion";
 | 
				
			||||||
 | 
					import { Vector3Object } from "./Vector3";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface Matrix4x4Object {
 | 
				
			||||||
 | 
						readonly ix: number;
 | 
				
			||||||
 | 
						readonly iy: number;
 | 
				
			||||||
 | 
						readonly iz: number;
 | 
				
			||||||
 | 
						readonly iw: number;
 | 
				
			||||||
 | 
						readonly jx: number;
 | 
				
			||||||
 | 
						readonly jy: number;
 | 
				
			||||||
 | 
						readonly jz: number;
 | 
				
			||||||
 | 
						readonly jw: number;
 | 
				
			||||||
 | 
						readonly kx: number;
 | 
				
			||||||
 | 
						readonly ky: number;
 | 
				
			||||||
 | 
						readonly kz: number;
 | 
				
			||||||
 | 
						readonly kw: number;
 | 
				
			||||||
 | 
						readonly tx: number;
 | 
				
			||||||
 | 
						readonly ty: number;
 | 
				
			||||||
 | 
						readonly tz: number;
 | 
				
			||||||
 | 
						readonly tw: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type Matrix4x4Tuple = readonly [
 | 
				
			||||||
 | 
						ix: number, iy: number, iz: number, iw: number,
 | 
				
			||||||
 | 
						jx: number, jy: number, jz: number, jw: number,
 | 
				
			||||||
 | 
						kx: number, ky: number, kz: number, kw: number,
 | 
				
			||||||
 | 
						tx: number, ty: number, tz: number, tw: number,
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class Matrix4x4 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly type!: "Matrix4x4";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ix: number;
 | 
				
			||||||
 | 
						iy: number;
 | 
				
			||||||
 | 
						iz: number;
 | 
				
			||||||
 | 
						iw: number;
 | 
				
			||||||
 | 
						jx: number;
 | 
				
			||||||
 | 
						jy: number;
 | 
				
			||||||
 | 
						jz: number;
 | 
				
			||||||
 | 
						jw: number;
 | 
				
			||||||
 | 
						kx: number;
 | 
				
			||||||
 | 
						ky: number;
 | 
				
			||||||
 | 
						kz: number;
 | 
				
			||||||
 | 
						kw: number;
 | 
				
			||||||
 | 
						tx: number;
 | 
				
			||||||
 | 
						ty: number;
 | 
				
			||||||
 | 
						tz: number;
 | 
				
			||||||
 | 
						tw: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						constructor(
 | 
				
			||||||
 | 
							ix: number, iy: number, iz: number, iw: number,
 | 
				
			||||||
 | 
							jx: number, jy: number, jz: number, jw: number,
 | 
				
			||||||
 | 
							kx: number, ky: number, kz: number, kw: number,
 | 
				
			||||||
 | 
							tx: number, ty: number, tz: number, tw: number
 | 
				
			||||||
 | 
						) {
 | 
				
			||||||
 | 
							Object.defineProperty(this, "type", { value: "Matrix4x4" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this.ix = ix;
 | 
				
			||||||
 | 
							this.iy = iy;
 | 
				
			||||||
 | 
							this.iz = iz;
 | 
				
			||||||
 | 
							this.iw = iw;
 | 
				
			||||||
 | 
							this.jx = jx;
 | 
				
			||||||
 | 
							this.jy = jy;
 | 
				
			||||||
 | 
							this.jz = jz;
 | 
				
			||||||
 | 
							this.jw = jw;
 | 
				
			||||||
 | 
							this.kx = kx;
 | 
				
			||||||
 | 
							this.ky = ky;
 | 
				
			||||||
 | 
							this.kz = kz;
 | 
				
			||||||
 | 
							this.kw = kw;
 | 
				
			||||||
 | 
							this.tx = tx;
 | 
				
			||||||
 | 
							this.ty = ty;
 | 
				
			||||||
 | 
							this.tz = tz;
 | 
				
			||||||
 | 
							this.tw = tw;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static fromObject(object: Matrix4x4Object): Matrix4x4 {
 | 
				
			||||||
 | 
							return new Matrix4x4(
 | 
				
			||||||
 | 
								object.ix, object.iy, object.iz, object.iw,
 | 
				
			||||||
 | 
								object.jx, object.jy, object.jz, object.jw,
 | 
				
			||||||
 | 
								object.kx, object.ky, object.kz, object.kw,
 | 
				
			||||||
 | 
								object.tx, object.ty, object.tz, object.tw,
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static fromTuple(tuple: Matrix4x4Tuple): Matrix4x4 {
 | 
				
			||||||
 | 
							return new Matrix4x4(...tuple);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static fromTranslation(translation: Vector3Object): Matrix4x4 {
 | 
				
			||||||
 | 
							return new Matrix4x4(
 | 
				
			||||||
 | 
								1, 0, 0, 0,
 | 
				
			||||||
 | 
								0, 1, 0, 0,
 | 
				
			||||||
 | 
								0, 0, 1, 0,
 | 
				
			||||||
 | 
								translation.x, translation.y, translation.z, 1,
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static fromQuaternion(quaternion: QuaternionObject): Matrix4x4 {
 | 
				
			||||||
 | 
							const xx = quaternion.x * quaternion.x;
 | 
				
			||||||
 | 
							const xy = quaternion.x * quaternion.y;
 | 
				
			||||||
 | 
							const xz = quaternion.x * quaternion.z;
 | 
				
			||||||
 | 
							const xw = quaternion.x * quaternion.w;
 | 
				
			||||||
 | 
							const yy = quaternion.y * quaternion.y;
 | 
				
			||||||
 | 
							const yz = quaternion.y * quaternion.z;
 | 
				
			||||||
 | 
							const yw = quaternion.y * quaternion.w;
 | 
				
			||||||
 | 
							const zz = quaternion.z * quaternion.z;
 | 
				
			||||||
 | 
							const zw = quaternion.z * quaternion.w;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return new Matrix4x4(
 | 
				
			||||||
 | 
								1 - 2 * (yy + zz), 2 * (xy + zw), 2 * (xz - yw), 0,
 | 
				
			||||||
 | 
								2 * (xy - zw), 1 - 2 * (xx + zz), 2 * (yz + xw), 0,
 | 
				
			||||||
 | 
								2 * (xz + yw), 2 * (yz - xw), 1 - 2 * (xx + yy), 0,
 | 
				
			||||||
 | 
								0, 0, 0, 1,
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static fromScale(scale: Vector3Object): Matrix4x4 {
 | 
				
			||||||
 | 
							return new Matrix4x4(
 | 
				
			||||||
 | 
								scale.x, 0, 0, 0,
 | 
				
			||||||
 | 
								0, scale.y, 0, 0,
 | 
				
			||||||
 | 
								0, 0, scale.z, 0,
 | 
				
			||||||
 | 
								0, 0, 0, 1
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setObject(object: Matrix4x4Object): Matrix4x4 {
 | 
				
			||||||
 | 
							this.ix = object.ix;
 | 
				
			||||||
 | 
							this.iy = object.iy;
 | 
				
			||||||
 | 
							this.iz = object.iz;
 | 
				
			||||||
 | 
							this.iw = object.iw;
 | 
				
			||||||
 | 
							this.jx = object.jx;
 | 
				
			||||||
 | 
							this.jy = object.jy;
 | 
				
			||||||
 | 
							this.jz = object.jz;
 | 
				
			||||||
 | 
							this.jw = object.jw;
 | 
				
			||||||
 | 
							this.kx = object.kx;
 | 
				
			||||||
 | 
							this.ky = object.ky;
 | 
				
			||||||
 | 
							this.kz = object.kz;
 | 
				
			||||||
 | 
							this.kw = object.kw;
 | 
				
			||||||
 | 
							this.tx = object.tx;
 | 
				
			||||||
 | 
							this.ty = object.ty;
 | 
				
			||||||
 | 
							this.tz = object.tz;
 | 
				
			||||||
 | 
							this.tw = object.tw;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setTuple(tuple: Matrix4x4Tuple): Matrix4x4 {
 | 
				
			||||||
 | 
							this.ix = tuple[0];
 | 
				
			||||||
 | 
							this.iy = tuple[1];
 | 
				
			||||||
 | 
							this.iz = tuple[2];
 | 
				
			||||||
 | 
							this.iw = tuple[3];
 | 
				
			||||||
 | 
							this.jx = tuple[4];
 | 
				
			||||||
 | 
							this.jy = tuple[5];
 | 
				
			||||||
 | 
							this.jz = tuple[6];
 | 
				
			||||||
 | 
							this.jw = tuple[7];
 | 
				
			||||||
 | 
							this.kx = tuple[8];
 | 
				
			||||||
 | 
							this.ky = tuple[9];
 | 
				
			||||||
 | 
							this.kz = tuple[10];
 | 
				
			||||||
 | 
							this.kw = tuple[11];
 | 
				
			||||||
 | 
							this.tx = tuple[12];
 | 
				
			||||||
 | 
							this.ty = tuple[13];
 | 
				
			||||||
 | 
							this.tz = tuple[14];
 | 
				
			||||||
 | 
							this.tw = tuple[15];
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setTranslation(translation: Vector3Object): Matrix4x4 {
 | 
				
			||||||
 | 
							this.ix = 1;
 | 
				
			||||||
 | 
							this.iy = 0;
 | 
				
			||||||
 | 
							this.iz = 0;
 | 
				
			||||||
 | 
							this.iw = 0;
 | 
				
			||||||
 | 
							this.jx = 0;
 | 
				
			||||||
 | 
							this.jy = 1;
 | 
				
			||||||
 | 
							this.jz = 0;
 | 
				
			||||||
 | 
							this.jw = 0;
 | 
				
			||||||
 | 
							this.kx = 0;
 | 
				
			||||||
 | 
							this.ky = 0;
 | 
				
			||||||
 | 
							this.kz = 1;
 | 
				
			||||||
 | 
							this.kw = 0;
 | 
				
			||||||
 | 
							this.tx = translation.x;
 | 
				
			||||||
 | 
							this.ty = translation.y;
 | 
				
			||||||
 | 
							this.tz = translation.z;
 | 
				
			||||||
 | 
							this.tw = 1;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setQuaternion(quaternion: QuaternionObject): Matrix4x4 {
 | 
				
			||||||
 | 
							const xx = quaternion.x * quaternion.x;
 | 
				
			||||||
 | 
							const xy = quaternion.x * quaternion.y;
 | 
				
			||||||
 | 
							const xz = quaternion.x * quaternion.z;
 | 
				
			||||||
 | 
							const xw = quaternion.x * quaternion.w;
 | 
				
			||||||
 | 
							const yy = quaternion.y * quaternion.y;
 | 
				
			||||||
 | 
							const yz = quaternion.y * quaternion.z;
 | 
				
			||||||
 | 
							const yw = quaternion.y * quaternion.w;
 | 
				
			||||||
 | 
							const zz = quaternion.z * quaternion.z;
 | 
				
			||||||
 | 
							const zw = quaternion.z * quaternion.w;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this.ix = 1 - 2 * (yy + zz);
 | 
				
			||||||
 | 
							this.iy = 2 * (xy + zw);
 | 
				
			||||||
 | 
							this.iz = 2 * (xz - yw);
 | 
				
			||||||
 | 
							this.iw = 0;
 | 
				
			||||||
 | 
							this.jx = 2 * (xy - zw);
 | 
				
			||||||
 | 
							this.jy = 1 - 2 * (xx + zz);
 | 
				
			||||||
 | 
							this.jz = 2 * (yz + xw);
 | 
				
			||||||
 | 
							this.jw = 0;
 | 
				
			||||||
 | 
							this.kx = 2 * (xz + yw);
 | 
				
			||||||
 | 
							this.ky = 2 * (yz - xw);
 | 
				
			||||||
 | 
							this.kz = 1 - 2 * (xx + yy);
 | 
				
			||||||
 | 
							this.kw = 0;
 | 
				
			||||||
 | 
							this.tx = 0;
 | 
				
			||||||
 | 
							this.ty = 0;
 | 
				
			||||||
 | 
							this.tz = 0;
 | 
				
			||||||
 | 
							this.tw = 1;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setScale(scale: Vector3Object): Matrix4x4 {
 | 
				
			||||||
 | 
							this.ix = scale.x;
 | 
				
			||||||
 | 
							this.iy = 0;
 | 
				
			||||||
 | 
							this.iz = 0;
 | 
				
			||||||
 | 
							this.iw = 0;
 | 
				
			||||||
 | 
							this.jx = 0;
 | 
				
			||||||
 | 
							this.jy = scale.y;
 | 
				
			||||||
 | 
							this.jz = 0;
 | 
				
			||||||
 | 
							this.jw = 0;
 | 
				
			||||||
 | 
							this.kx = 0;
 | 
				
			||||||
 | 
							this.ky = 0;
 | 
				
			||||||
 | 
							this.kz = scale.z;
 | 
				
			||||||
 | 
							this.kw = 0;
 | 
				
			||||||
 | 
							this.tx = 0;
 | 
				
			||||||
 | 
							this.ty = 0;
 | 
				
			||||||
 | 
							this.tz = 0;
 | 
				
			||||||
 | 
							this.tw = 1;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isMatrix4x4(value: unknown): value is Matrix4x4 {
 | 
				
			||||||
 | 
						return Boolean(value) && (value as Matrix4x4).type === "Matrix4x4";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										42
									
								
								src/Mesh.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/Mesh.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
				
			|||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public License,
 | 
				
			||||||
 | 
					 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 | 
				
			||||||
 | 
					 * obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { IndexBuffer } from "./IndexBuffer";
 | 
				
			||||||
 | 
					import { VertexBuffer } from "./VertexBuffer";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface MeshProps {
 | 
				
			||||||
 | 
						readonly name?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly vertexBuffer: VertexBuffer;
 | 
				
			||||||
 | 
						readonly indexBuffer: IndexBuffer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class Mesh {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly type!: "Mesh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_name: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_vertexBuffer: VertexBuffer;
 | 
				
			||||||
 | 
						_indexBuffer: IndexBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						constructor({
 | 
				
			||||||
 | 
							name = "",
 | 
				
			||||||
 | 
							vertexBuffer,
 | 
				
			||||||
 | 
							indexBuffer,
 | 
				
			||||||
 | 
						}: MeshProps) {
 | 
				
			||||||
 | 
							Object.defineProperty(this, "type", { value: "Mesh" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._name = name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._vertexBuffer = vertexBuffer;
 | 
				
			||||||
 | 
							this._indexBuffer = indexBuffer
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isMesh(value: unknown): value is Mesh {
 | 
				
			||||||
 | 
						return Boolean(value) && (value as Mesh).type === "Mesh";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										84
									
								
								src/Node.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								src/Node.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,84 @@
 | 
				
			|||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public License,
 | 
				
			||||||
 | 
					 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 | 
				
			||||||
 | 
					 * obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Camera } from "./Camera";
 | 
				
			||||||
 | 
					import { Mesh } from "./Mesh";
 | 
				
			||||||
 | 
					import { Quaternion, QuaternionObject } from "./Quaternion";
 | 
				
			||||||
 | 
					import { Vector3, Vector3Object } from "./Vector3";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface NodeProps {
 | 
				
			||||||
 | 
						readonly name?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly translation?: Vector3Object;
 | 
				
			||||||
 | 
						readonly rotation?: QuaternionObject;
 | 
				
			||||||
 | 
						readonly scale?: Vector3Object;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly camera?: Camera;
 | 
				
			||||||
 | 
						readonly mesh?: Mesh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly children?: Node[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class Node {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly type!: "Node";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_name: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_translation: Vector3;
 | 
				
			||||||
 | 
						_rotation: Quaternion;
 | 
				
			||||||
 | 
						_scale: Vector3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** unique */
 | 
				
			||||||
 | 
						_camera: Camera | undefined;
 | 
				
			||||||
 | 
						/** shared */
 | 
				
			||||||
 | 
						_mesh: Mesh | undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** unique */
 | 
				
			||||||
 | 
						_children: Node[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** backreference */
 | 
				
			||||||
 | 
						_parent: Node | undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						constructor({
 | 
				
			||||||
 | 
							name = "",
 | 
				
			||||||
 | 
							translation,
 | 
				
			||||||
 | 
							rotation,
 | 
				
			||||||
 | 
							scale,
 | 
				
			||||||
 | 
							camera,
 | 
				
			||||||
 | 
							mesh,
 | 
				
			||||||
 | 
							children = [],
 | 
				
			||||||
 | 
						}: NodeProps) {
 | 
				
			||||||
 | 
							Object.defineProperty(this, "type", { value: "Node" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._name = name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._translation = translation !== undefined ? Vector3.fromObject(translation) : Vector3.zero();
 | 
				
			||||||
 | 
							this._rotation = rotation !== undefined ? Quaternion.fromObject(rotation) : Quaternion.identity();
 | 
				
			||||||
 | 
							this._scale = scale !== undefined ? Vector3.fromObject(scale) : Vector3.one();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._camera = camera;
 | 
				
			||||||
 | 
							this._mesh = mesh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._children = children;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._parent = undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (this._camera !== undefined) {
 | 
				
			||||||
 | 
								this._camera._node = this;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (this._children !== undefined) {
 | 
				
			||||||
 | 
								for (const child of this._children) {
 | 
				
			||||||
 | 
									child._parent = this;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isNode(value: unknown): value is Node {
 | 
				
			||||||
 | 
						return Boolean(value) && (value as Node).type === "Node";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										73
									
								
								src/Quaternion.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								src/Quaternion.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
				
			|||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public License,
 | 
				
			||||||
 | 
					 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 | 
				
			||||||
 | 
					 * obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface QuaternionObject {
 | 
				
			||||||
 | 
						readonly x: number;
 | 
				
			||||||
 | 
						readonly y: number;
 | 
				
			||||||
 | 
						readonly z: number;
 | 
				
			||||||
 | 
						readonly w: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type QuaternionTuple = readonly [x: number, y: number, z: number, w: number];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class Quaternion {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly type!: "Quaternion";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						x: number;
 | 
				
			||||||
 | 
						y: number;
 | 
				
			||||||
 | 
						z: number;
 | 
				
			||||||
 | 
						w: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						constructor(x: number, y: number, z: number, w: number) {
 | 
				
			||||||
 | 
							Object.defineProperty(this, "type", { value: "Quaternion" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this.x = x;
 | 
				
			||||||
 | 
							this.y = y;
 | 
				
			||||||
 | 
							this.z = z;
 | 
				
			||||||
 | 
							this.w = w;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static fromObject(object: QuaternionObject): Quaternion {
 | 
				
			||||||
 | 
							return new Quaternion(object.x, object.y, object.z, object.w);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static fromTuple(tuple: QuaternionTuple): Quaternion {
 | 
				
			||||||
 | 
							return new Quaternion(...tuple);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static identity(): Quaternion {
 | 
				
			||||||
 | 
							return new Quaternion(0, 0, 0, 1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setObject(object: QuaternionObject): Quaternion {
 | 
				
			||||||
 | 
							this.x = object.x;
 | 
				
			||||||
 | 
							this.y = object.y;
 | 
				
			||||||
 | 
							this.z = object.z;
 | 
				
			||||||
 | 
							this.w = object.w;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setTuple(tuple: QuaternionTuple): Quaternion {
 | 
				
			||||||
 | 
							this.x = tuple[0];
 | 
				
			||||||
 | 
							this.y = tuple[1];
 | 
				
			||||||
 | 
							this.z = tuple[2];
 | 
				
			||||||
 | 
							this.w = tuple[3];
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setIdentity(): Quaternion {
 | 
				
			||||||
 | 
							this.x = 0;
 | 
				
			||||||
 | 
							this.y = 0;
 | 
				
			||||||
 | 
							this.z = 0;
 | 
				
			||||||
 | 
							this.w = 1;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isQuaternion(value: unknown): value is Quaternion {
 | 
				
			||||||
 | 
						return Boolean(value) && (value as Quaternion).type === "Quaternion";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										37
									
								
								src/Scene.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/Scene.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public License,
 | 
				
			||||||
 | 
					 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 | 
				
			||||||
 | 
					 * obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Node } from "./Node";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface SceneProps {
 | 
				
			||||||
 | 
						readonly name?: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly nodes?: Node[];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class Scene {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly type!: "Scene";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_name: string | undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_nodes: Node[];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						constructor({
 | 
				
			||||||
 | 
							name = "",
 | 
				
			||||||
 | 
							nodes = [],
 | 
				
			||||||
 | 
						}: SceneProps) {
 | 
				
			||||||
 | 
							Object.defineProperty(this, "type", { value: "Scene" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._name = name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._nodes = nodes;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isScene(value: unknown): value is Scene {
 | 
				
			||||||
 | 
						return Boolean(value) && (value as Scene).type === "Scene";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										72
									
								
								src/Texture2D.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/Texture2D.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
				
			|||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public License,
 | 
				
			||||||
 | 
					 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 | 
				
			||||||
 | 
					 * obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface Texture2DProps {
 | 
				
			||||||
 | 
						name?: string;
 | 
				
			||||||
 | 
						device: GPUDevice;
 | 
				
			||||||
 | 
						width: number;
 | 
				
			||||||
 | 
						height: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class Texture2D {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly type!: "Texture2D";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_name: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_device: GPUDevice;
 | 
				
			||||||
 | 
						_texture: GPUTexture;
 | 
				
			||||||
 | 
						_textureView: GPUTextureView;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						constructor({
 | 
				
			||||||
 | 
							name = "",
 | 
				
			||||||
 | 
							device,
 | 
				
			||||||
 | 
							width,
 | 
				
			||||||
 | 
							height,
 | 
				
			||||||
 | 
						}: Texture2DProps) {
 | 
				
			||||||
 | 
							Object.defineProperty(this, "type", { value: "Texture2D" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._name = name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._device = device;
 | 
				
			||||||
 | 
							this._texture = device.createTexture({
 | 
				
			||||||
 | 
								usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,
 | 
				
			||||||
 | 
								size: { width, height },
 | 
				
			||||||
 | 
								format: "rgba8unorm",
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
							this._textureView = this._texture.createView({
 | 
				
			||||||
 | 
								format: "rgba8unorm",
 | 
				
			||||||
 | 
								dimension: "2d",
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dispose(): Texture2D {
 | 
				
			||||||
 | 
							this._texture.destroy();
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						get width(): number {
 | 
				
			||||||
 | 
							return this._texture.width;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						get height(): number {
 | 
				
			||||||
 | 
							return this._texture.height;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeTypedArray(data: Uint8Array): Texture2D {
 | 
				
			||||||
 | 
							this._device.queue.writeTexture(
 | 
				
			||||||
 | 
								{ texture: this._texture },
 | 
				
			||||||
 | 
								data,
 | 
				
			||||||
 | 
								{ bytesPerRow: 4 * this._texture.width },
 | 
				
			||||||
 | 
								{ width: this._texture.width, height: this._texture.height },
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isTexture2D(value: unknown): value is Texture2D {
 | 
				
			||||||
 | 
						return Boolean(value) && (value as Texture2D).type === "Texture2D";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										100
									
								
								src/Vector3.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								src/Vector3.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,100 @@
 | 
				
			|||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public License,
 | 
				
			||||||
 | 
					 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 | 
				
			||||||
 | 
					 * obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface Vector3Object {
 | 
				
			||||||
 | 
						readonly x: number;
 | 
				
			||||||
 | 
						readonly y: number;
 | 
				
			||||||
 | 
						readonly z: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type Vector3Tuple = readonly [x: number, y: number, z: number];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class Vector3 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly type!: "Vector3";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						x: number;
 | 
				
			||||||
 | 
						y: number;
 | 
				
			||||||
 | 
						z: number;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						constructor(x: number, y: number, z: number) {
 | 
				
			||||||
 | 
							Object.defineProperty(this, "type", { value: "Vector3" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this.x = x;
 | 
				
			||||||
 | 
							this.y = y;
 | 
				
			||||||
 | 
							this.z = z;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static fromObject(object: Vector3Object): Vector3 {
 | 
				
			||||||
 | 
							return new Vector3(object.x, object.y, object.z);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static fromTuple(tuple: Vector3Tuple): Vector3 {
 | 
				
			||||||
 | 
							return new Vector3(...tuple);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static zero(): Vector3 {
 | 
				
			||||||
 | 
							return new Vector3(0, 0, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static one(): Vector3 {
 | 
				
			||||||
 | 
							return new Vector3(1, 1, 1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						set(x: number, y: number, z: number): Vector3 {
 | 
				
			||||||
 | 
							this.x = x;
 | 
				
			||||||
 | 
							this.y = y;
 | 
				
			||||||
 | 
							this.z = z;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setObject(object: Vector3Object): Vector3 {
 | 
				
			||||||
 | 
							this.x = object.x;
 | 
				
			||||||
 | 
							this.y = object.y;
 | 
				
			||||||
 | 
							this.z = object.z;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setTuple(tuple: Vector3Tuple): Vector3 {
 | 
				
			||||||
 | 
							this.x = tuple[0];
 | 
				
			||||||
 | 
							this.y = tuple[1];
 | 
				
			||||||
 | 
							this.z = tuple[2];
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setZero(): Vector3 {
 | 
				
			||||||
 | 
							this.x = 0;
 | 
				
			||||||
 | 
							this.y = 0;
 | 
				
			||||||
 | 
							this.z = 0;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setOne(): Vector3 {
 | 
				
			||||||
 | 
							this.x = 1;
 | 
				
			||||||
 | 
							this.y = 1;
 | 
				
			||||||
 | 
							this.z = 1;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setX(x: number): Vector3 {
 | 
				
			||||||
 | 
							this.x = x;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setY(y: number): Vector3 {
 | 
				
			||||||
 | 
							this.y = y;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						setZ(z: number): Vector3 {
 | 
				
			||||||
 | 
							this.z = z;
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isVector3(value: unknown): value is Vector3 {
 | 
				
			||||||
 | 
						return Boolean(value) && (value as Vector3).type === "Vector3";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										57
									
								
								src/VertexBuffer.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/VertexBuffer.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					/*!
 | 
				
			||||||
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public License,
 | 
				
			||||||
 | 
					 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 | 
				
			||||||
 | 
					 * obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { Vector3Object } from "./Vector3";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const VERTEX_SIZE = 12;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class VertexBuffer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readonly type!: "VertexBuffer";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_device: GPUDevice;
 | 
				
			||||||
 | 
						_buffer: GPUBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						constructor(device: GPUDevice, vertexCount: number) {
 | 
				
			||||||
 | 
							Object.defineProperty(this, "type", { value: "VertexBuffer" });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this._device = device;
 | 
				
			||||||
 | 
							this._buffer = device.createBuffer({
 | 
				
			||||||
 | 
								usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.VERTEX,
 | 
				
			||||||
 | 
								size: vertexCount * VERTEX_SIZE,
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dispose(): VertexBuffer {
 | 
				
			||||||
 | 
							this._buffer.destroy();
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						get vertexCount(): number {
 | 
				
			||||||
 | 
							return this._buffer.size / VERTEX_SIZE | 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeArray(offset: number, vertices: readonly Vector3Object[]): VertexBuffer {
 | 
				
			||||||
 | 
							const array = new Float32Array(vertices.length * 3);
 | 
				
			||||||
 | 
							for (let vi = 0, ptr = 0; vi < vertices.length; ++vi) {
 | 
				
			||||||
 | 
								const vertex = vertices[vi]!;
 | 
				
			||||||
 | 
								array[ptr++] = vertex.x;
 | 
				
			||||||
 | 
								array[ptr++] = vertex.y;
 | 
				
			||||||
 | 
								array[ptr++] = vertex.z;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							this._device.queue.writeBuffer(this._buffer, offset * VERTEX_SIZE | 0, array);
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						writeTypedArray(offset: number, vertices: Float32Array): VertexBuffer {
 | 
				
			||||||
 | 
							this._device.queue.writeBuffer(this._buffer, offset * VERTEX_SIZE | 0, vertices);
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function isVertexBuffer(value: unknown): value is VertexBuffer {
 | 
				
			||||||
 | 
						return Boolean(value) && (value as VertexBuffer).type === "VertexBuffer";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1 +1,18 @@
 | 
				
			|||||||
export {};
 | 
					/*!
 | 
				
			||||||
 | 
					 * This Source Code Form is subject to the terms of the Mozilla Public License,
 | 
				
			||||||
 | 
					 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
 | 
				
			||||||
 | 
					 * obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export * from "./Camera";
 | 
				
			||||||
 | 
					export * from "./Color";
 | 
				
			||||||
 | 
					export * from "./IndexBuffer";
 | 
				
			||||||
 | 
					export * from "./Material";
 | 
				
			||||||
 | 
					export * from "./Matrix4x4";
 | 
				
			||||||
 | 
					export * from "./Mesh";
 | 
				
			||||||
 | 
					export * from "./Node";
 | 
				
			||||||
 | 
					export * from "./Quaternion";
 | 
				
			||||||
 | 
					export * from "./Scene";
 | 
				
			||||||
 | 
					export * from "./Texture2D";
 | 
				
			||||||
 | 
					export * from "./Vector3";
 | 
				
			||||||
 | 
					export * from "./VertexBuffer";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		"target": "ES2022",
 | 
							"target": "ES2022",
 | 
				
			||||||
		"lib": ["ES2022", "DOM"],
 | 
							"lib": ["ES2022", "DOM"],
 | 
				
			||||||
 | 
							"typeRoots": ["./node_modules/@webgpu/types"],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		"sourceMap": true,
 | 
							"sourceMap": true,
 | 
				
			||||||
		"declaration": true,
 | 
							"declaration": true,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user