Camera projection, upload lights and global uniforms, issue draw calls
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
* obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Node } from ".";
|
||||
import { Matrix4x4, Node } from ".";
|
||||
|
||||
export type Camera = OrthographicCamera | PerspectiveCamera;
|
||||
|
||||
@@ -30,7 +30,7 @@ export class OrthographicCamera {
|
||||
|
||||
_name: string;
|
||||
|
||||
_verticalSize: number;
|
||||
_halfVerticalSize: number;
|
||||
_nearPlane: number;
|
||||
_farPlane: number;
|
||||
|
||||
@@ -45,7 +45,7 @@ export class OrthographicCamera {
|
||||
}: OrthographicCameraProps) {
|
||||
this._name = name;
|
||||
|
||||
this._verticalSize = verticalSize;
|
||||
this._halfVerticalSize = verticalSize;
|
||||
this._nearPlane = nearPlane;
|
||||
this._farPlane = farPlane;
|
||||
|
||||
@@ -55,8 +55,8 @@ export class OrthographicCamera {
|
||||
set name(value: string) { this._name = value; }
|
||||
get name(): string { return this._name; }
|
||||
|
||||
set verticalSize(value: number) { this._verticalSize = value; }
|
||||
get verticalSize(): number { return this._verticalSize; }
|
||||
set halfVerticalSize(value: number) { this._halfVerticalSize = value; }
|
||||
get halfVerticalSize(): number { return this._halfVerticalSize; }
|
||||
|
||||
set nearPlane(value: number) { this._nearPlane = value; }
|
||||
get nearPlane(): number { return this._nearPlane; }
|
||||
@@ -87,6 +87,16 @@ export class OrthographicCamera {
|
||||
this._node = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
computeProjectionMatrix(aspectRatio: number, res: Matrix4x4): Matrix4x4 {
|
||||
const halfHorizontalSize = this._halfVerticalSize / aspectRatio;
|
||||
return res.set(
|
||||
1 / halfHorizontalSize, 0, 0, 0,
|
||||
0, 1 / this._halfVerticalSize, 0, 0,
|
||||
0, 0, 1 / (this._nearPlane - this._farPlane), 0,
|
||||
0, 0, this._farPlane / (this._farPlane - this._nearPlane), 1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export class PerspectiveCamera {
|
||||
@@ -149,6 +159,25 @@ export class PerspectiveCamera {
|
||||
this._node = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
computeProjectionMatrix(aspectRatio: number, res: Matrix4x4): Matrix4x4 {
|
||||
const halfVerticalCotangent = 1 / Math.tan(0.5 * this._verticalFovRad);
|
||||
if (this._farPlane === Infinity) {
|
||||
return res.set(
|
||||
halfVerticalCotangent / aspectRatio, 0, 0, 0,
|
||||
0, halfVerticalCotangent, 0, 0,
|
||||
0, 0, 0, 1,
|
||||
0, 0, this._nearPlane, 0,
|
||||
);
|
||||
} else {
|
||||
return res.set(
|
||||
halfVerticalCotangent / aspectRatio, 0, 0, 0,
|
||||
0, halfVerticalCotangent, 0, 0,
|
||||
0, 0, this._nearPlane / (this._nearPlane - this._farPlane), 1,
|
||||
0, 0, this._nearPlane * this._farPlane / (this._farPlane - this._nearPlane), 0,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(OrthographicCamera.prototype, "type", { value: "OrthographicCamera" });
|
||||
|
@@ -155,6 +155,31 @@ export class Matrix4x4 {
|
||||
);
|
||||
}
|
||||
|
||||
set(
|
||||
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,
|
||||
): 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;
|
||||
return this;
|
||||
}
|
||||
|
||||
setObject(object: Matrix4x4Object): Matrix4x4 {
|
||||
this.ix = object.ix;
|
||||
this.iy = object.iy;
|
||||
@@ -507,6 +532,40 @@ export class Matrix4x4 {
|
||||
return this;
|
||||
}
|
||||
|
||||
inverseAffine(): Matrix4x4 {
|
||||
const ix = this.ix;
|
||||
const iy = this.iy;
|
||||
const iz = this.iz;
|
||||
const jx = this.jx;
|
||||
const jy = this.jy;
|
||||
const jz = this.jz;
|
||||
const kx = this.kx;
|
||||
const ky = this.ky;
|
||||
const kz = this.kz;
|
||||
const tx = this.tx;
|
||||
const ty = this.ty;
|
||||
const tz = this.tz;
|
||||
|
||||
const det = ix * jy * kz + iy * jz * kx + iz * jx * ky
|
||||
- ix * jz * ky - iy * jx * kz - iz * jy * kx;
|
||||
const invDet = 1 / det;
|
||||
|
||||
this.ix = invDet * (jy * kz - jz * ky);
|
||||
this.iy = invDet * (iz * ky - iy * kz);
|
||||
this.iz = invDet * (iy * jz - iz * jy);
|
||||
this.jx = invDet * (jz * kx - jx * kz);
|
||||
this.jy = invDet * (ix * kz - iz * kx);
|
||||
this.jz = invDet * (iz * jx - ix * jz);
|
||||
this.kx = invDet * (jx * ky - jy * kx);
|
||||
this.ky = invDet * (iy * kx - ix * ky);
|
||||
this.kz = invDet * (ix * jy - iy * jx);
|
||||
this.tx = -(this.ix * tx + this.jx * ty + this.kx * tz);
|
||||
this.ty = -(this.iy * tx + this.jy * ty + this.ky * tz);
|
||||
this.tz = -(this.iz * tx + this.jz * ty + this.kz * tz);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
inverseTransposeAffine(): Matrix4x4 {
|
||||
const ix = this.ix;
|
||||
const iy = this.iy;
|
||||
|
@@ -4,12 +4,14 @@
|
||||
* obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
import { Node } from ".";
|
||||
import { Color, ColorObject, Node } from ".";
|
||||
|
||||
export interface SceneProps {
|
||||
readonly name?: string;
|
||||
|
||||
readonly nodes?: Node[];
|
||||
|
||||
readonly ambientLight?: ColorObject;
|
||||
}
|
||||
|
||||
export class Scene {
|
||||
@@ -20,17 +22,31 @@ export class Scene {
|
||||
|
||||
_nodes: Node[];
|
||||
|
||||
_ambientLight: Color;
|
||||
|
||||
constructor({
|
||||
name = "",
|
||||
nodes = [],
|
||||
ambientLight,
|
||||
}: SceneProps) {
|
||||
this._name = name;
|
||||
|
||||
this._nodes = nodes;
|
||||
|
||||
this._ambientLight = ambientLight !== undefined ? Color.fromObject(ambientLight) : Color.black();
|
||||
}
|
||||
|
||||
set name(value: string) { this._name = value; }
|
||||
get name(): string { return this._name; }
|
||||
|
||||
setAmbientLight(value: ColorObject): Scene {
|
||||
this._ambientLight.setObject(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
getAmbientLight(res: Color): Color {
|
||||
return res.setObject(this._ambientLight);
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(Scene.prototype, "type", { value: "Scene" });
|
||||
|
@@ -78,6 +78,13 @@ export class Vector2 {
|
||||
this.y = y;
|
||||
return this;
|
||||
}
|
||||
|
||||
normalize(): Vector2 {
|
||||
const l = Math.sqrt(this.x * this.x + this.y * this.y);
|
||||
this.x /= l;
|
||||
this.y /= l;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(Vector2.prototype, "type", { value: "Vector2" });
|
||||
|
@@ -91,6 +91,14 @@ export class Vector3 {
|
||||
this.z = z;
|
||||
return this;
|
||||
}
|
||||
|
||||
normalize(): Vector3 {
|
||||
const l = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
|
||||
this.x /= l;
|
||||
this.y /= l;
|
||||
this.z /= l;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(Vector3.prototype, "type", { value: "Vector3" });
|
||||
|
@@ -104,6 +104,15 @@ export class Vector4 {
|
||||
this.w = w;
|
||||
return this;
|
||||
}
|
||||
|
||||
normalize(): Vector4 {
|
||||
const l = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
|
||||
this.x /= l;
|
||||
this.y /= l;
|
||||
this.z /= l;
|
||||
this.w /= l;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(Vector4.prototype, "type", { value: "Vector4" });
|
||||
|
Reference in New Issue
Block a user