Browse Source

完成WebGLMatrixStack

master
blobt 3 years ago
parent
commit
f28b30b6e6
  1. 6
      src/render/common.ts
  2. 21
      src/render/core/Camera.ts
  3. 488
      src/render/webgl/WebGLMatrixStack.ts

6
src/render/common.ts

@ -41,4 +41,10 @@ export enum EPlaneLoc {
export enum ECameraType {
FPSCAMERA,
FLYCAMERA
}
export enum EMatrixMode {
MODELVIEW,
PROJECTION,
TEXTURE
}

21
src/render/core/Camera.ts

@ -497,4 +497,25 @@ export class Camera {
}
}
/**
*
* @param target
* @param up
*/
public lookAt(target: vec3, up: vec3 = vec3.up): void {
this._viewMatrix = mat4.lookAt(this._position, target, up);
this._xAxis.x = this._viewMatrix.values[0];
this._yAxis.x = this._viewMatrix.values[1];
this._zAxis.x = this._viewMatrix.values[2];
this._xAxis.y = this._viewMatrix.values[4];
this._yAxis.y = this._viewMatrix.values[5];
this._zAxis.y = this._viewMatrix.values[6];
//TODO这里有点问题
this._xAxis.z = this._viewMatrix.values[8];
this._yAxis.z = this._viewMatrix.values[9];
this._zAxis.z = this._viewMatrix.values[10];
}
}

488
src/render/webgl/WebGLMatrixStack.ts

@ -0,0 +1,488 @@
import { vec3, mat4, Util } from "../math"
import { EMatrixMode } from "../common";
export class GLMatrixStack {
/**
* @var
* model view matrix stack
*/
private _mvStack: mat4[];
/**
* @var
* projection matrix stack
*/
private _projStack: mat4[];
/**
* @var
*/
private _texStack: mat4[];
/**
* @var
*/
public matrixMode: EMatrixMode;
public constructor() {
this._mvStack = [];
this._mvStack.push(new mat4());
this._projStack = [];
this._projStack.push(new mat4());
this._texStack = [];
this._texStack.push(new mat4());
this.matrixMode = EMatrixMode.MODELVIEW;
}
/**
* model view矩阵
*/
public get modelViewMatrix(): mat4 {
if (this._mvStack.length <= 0) {
throw new Error("model view matrix stack empty!");
}
return this._mvStack[this._mvStack.length - 1];
}
/**
* projection
*/
public get projectionMatrix(): mat4 {
if (this._projStack.length <= 0) {
throw new Error("projection matrix stack empty!");
}
return this._projStack[this._mvStack.length - 1];
}
/**
* projection
*/
public get textureMatrix(): mat4 {
if (this._texStack.length <= 0) {
throw new Error("texture matrix stack empty!");
}
return this._texStack[this._mvStack.length - 1];
}
/**
*
*/
public get modelViewProjectionMatrix(): mat4 {
let ret: mat4 = new mat4();
this.projectionMatrix.copy(ret);
ret.multiply(this.modelViewMatrix);
return ret;
}
/**
*
*/
public get normalMatrix(): mat4 {
let ret: mat4 = new mat4();
this.modelViewMatrix.copy(ret);
this.modelViewMatrix.inverse(ret);
ret.transpose();
return ret;
}
/**
*
* @returns
*/
public pushMatrix(): GLMatrixStack {
switch (this.matrixMode) {
case EMatrixMode.MODELVIEW:
let mv: mat4 = new mat4();
this.modelViewMatrix.copy(mv);
this._mvStack.push(mv);
break;
case EMatrixMode.PROJECTION:
let proj = new mat4();
this.projectionMatrix.copy(proj);
this._projStack.push(proj);
break;
case EMatrixMode.TEXTURE:
let tex: mat4 = new mat4();
this.textureMatrix.copy(tex);
this._texStack.push(tex);
break;
}
return this;
}
/**
*
* @returns
*/
public popMatrix(): GLMatrixStack {
switch (this.matrixMode) {
case EMatrixMode.MODELVIEW:
this._mvStack.pop();
break;
case EMatrixMode.PROJECTION:
this._projStack.pop();
break;
case EMatrixMode.TEXTURE:
this._texStack.pop();
break;
}
return this;
}
/**
*
* @param mat
* @returns
*/
public loadIdentity(): GLMatrixStack {
switch (this.matrixMode) {
case EMatrixMode.MODELVIEW:
this.modelViewMatrix.setIdentity();
break;
case EMatrixMode.PROJECTION:
this.projectionMatrix.setIdentity();
break;
case EMatrixMode.TEXTURE:
this.textureMatrix.setIdentity();
break;
}
return this;
}
/**
*
* @param mat
* @returns
*/
public loadMatrix(mat: mat4): GLMatrixStack {
switch (this.matrixMode) {
case EMatrixMode.MODELVIEW:
mat.copy(this.modelViewMatrix);
break;
case EMatrixMode.PROJECTION:
mat.copy(this.projectionMatrix);
break;
case EMatrixMode.TEXTURE:
mat.copy(this.textureMatrix);
break;
}
return this;
}
/**
*
* @param fov
* @param aspect
* @param near
* @param far
* @param isRadians
* @returns
*/
public perspective(fov: number, aspect: number, near: number, far: number, isRadians: boolean = false): GLMatrixStack {
this.matrixMode = EMatrixMode.PROJECTION;
if (isRadians == false) {
fov = Util.toRadian(fov);
}
let mat: mat4 = mat4.perspective(fov, aspect, near, far);
this.loadMatrix(mat);
this.matrixMode = EMatrixMode.MODELVIEW;
// 是否要调用loadIdentity方法???
this.loadIdentity();
return this;
}
/**
*
* @param left
* @param right
* @param bottom
* @param top
* @param near
* @param far
* @returns
*/
public frustum(left: number, right: number, bottom: number, top: number, near: number, far: number): GLMatrixStack {
this.matrixMode = EMatrixMode.PROJECTION;
let mat: mat4 = mat4.frustum(left, right, bottom, top, near, far);
this.matrixMode = EMatrixMode.MODELVIEW;
// 是否要调用loadIdentity方法???
this.loadIdentity();
return this;
}
/**
*
* @param left
* @param right
* @param bottom
* @param top
* @param near
* @param far
* @returns
*/
public ortho(left: number, right: number, bottom: number, top: number, near: number, far: number): GLMatrixStack {
this.matrixMode = EMatrixMode.PROJECTION;
let mat: mat4 = mat4.orthographic(left, right, bottom, top, near, far);
this.loadMatrix(mat);
this.matrixMode = EMatrixMode.MODELVIEW;
// 是否要调用loadIdentity方法???
this.loadIdentity();
return this;
}
/**
* lookat矩阵
* @param pos
* @param target
* @param up
* @returns
*/
public lookAt(pos: vec3, target: vec3, up: vec3 = vec3.up): GLMatrixStack {
this.matrixMode = EMatrixMode.MODELVIEW;
let mat: mat4 = mat4.lookAt(pos, target, up);
this.loadMatrix(mat);
return this;
}
/**
*
* @param pos
* @param xAxis
* @param yAxis
* @param zAxis
* @returns
*/
public makeView(pos: vec3, xAxis: vec3, yAxis: vec3, zAxis: vec3): GLMatrixStack {
zAxis.normalize();
vec3.cross(zAxis, xAxis, yAxis);
yAxis.normalize();
vec3.cross(yAxis, zAxis, xAxis);
xAxis.normalize();
let x: number = -vec3.dot(xAxis, pos);
let y: number = -vec3.dot(yAxis, pos);
let z: number = -vec3.dot(zAxis, pos);
let mat: mat4 = this._mvStack[this._mvStack.length - 1];
mat.values[0] = xAxis.x;
mat.values[1] = yAxis.x;
mat.values[2] = zAxis.x;
mat.values[3] = 0.0;
mat.values[4] = xAxis.y;
mat.values[5] = yAxis.y;
mat.values[6] = zAxis.y;
mat.values[7] = 0.0;
mat.values[8] = xAxis.z;
mat.values[9] = yAxis.z;
mat.values[10] = zAxis.z;
mat.values[11] = 0.0;
mat.values[12] = x;
mat.values[13] = y;
mat.values[14] = z;
mat.values[15] = 1.0;
return this;
}
/**
*
* @param mat
* @returns
*/
public multMatrix(mat: mat4): GLMatrixStack {
switch (this.matrixMode) {
case EMatrixMode.MODELVIEW:
this.modelViewMatrix.multiply(mat);
break;
case EMatrixMode.PROJECTION:
this.projectionMatrix.multiply(mat);
break;
case EMatrixMode.TEXTURE:
this.textureMatrix.multiply(mat);
break;
}
return this;
}
/**
*
* @param pos
* @returns
*/
public translate(pos: vec3): GLMatrixStack {
switch (this.matrixMode) {
case EMatrixMode.MODELVIEW:
this.modelViewMatrix.translate(pos);
break;
case EMatrixMode.PROJECTION:
this.projectionMatrix.translate(pos);
break;
case EMatrixMode.TEXTURE:
this.textureMatrix.translate(pos);
break;
}
return this;
}
/**
*
* @param angle
* @param axis
* @param isRadians
* @returns
*/
public rotate(angle: number, axis: vec3, isRadians: boolean = false): GLMatrixStack {
if (isRadians === false) {
angle = Util.toRadian(angle);
}
switch (this.matrixMode) {
case EMatrixMode.MODELVIEW:
this.modelViewMatrix.rotate(angle, axis);
break;
case EMatrixMode.PROJECTION:
this.projectionMatrix.rotate(angle, axis);
break;
case EMatrixMode.TEXTURE:
this.textureMatrix.rotate(angle, axis);
break;
}
return this;
}
/**
*
* @param s
* @returns
*/
public scale(s: vec3): GLMatrixStack {
switch (this.matrixMode) {
case EMatrixMode.MODELVIEW:
this.modelViewMatrix.scale(s);
break;
case EMatrixMode.PROJECTION:
this.projectionMatrix.scale(s);
break;
case EMatrixMode.TEXTURE:
this.textureMatrix.scale(s);
break;
}
return this;
}
}
export class GLWordMatrixStack {
/**
* @var
*/
private _worldMatrixStack: mat4[];
public constructor() {
this._worldMatrixStack = [];
this._worldMatrixStack.push(new mat4());
}
/**
*
*/
public get modelViewMatrix(): mat4 {
if (this._worldMatrixStack.length <= 0) {
throw new Error("model matrix stack is empty!");
}
return this._worldMatrixStack[this._worldMatrixStack.length - 1];
}
/**
*
* @returns
*/
public pushMatrix(): GLWordMatrixStack {
let mv: mat4 = new mat4();
this.modelViewMatrix.copy(mv);
this._worldMatrixStack.push(mv);
return this;
}
/**
*
* @returns
*/
public popMatrix(): GLWordMatrixStack {
this._worldMatrixStack.pop();
return this;
}
/**
*
* @returns
*/
public loadIdentity(): GLWordMatrixStack {
this.modelViewMatrix.setIdentity();
return this;
}
/**
*
* @param mat
* @returns
*/
public loadMatrix(mat: mat4): GLWordMatrixStack {
mat.copy(this.modelViewMatrix);
return this;
}
/**
*
* @param mat
* @returns
*/
public multMatrix(mat: mat4): GLWordMatrixStack {
this.modelViewMatrix.multiply(mat);
return this;
}
/**
*
* @param pos
* @returns
*/
public translate(pos: vec3): GLWordMatrixStack {
this.modelViewMatrix.translate(pos);
return this;
}
/**
*
* @param angle
* @param axis
* @param isRadians
* @returns
*/
public rotate(angle: number, axis: vec3, isRadians: boolean = false): GLWordMatrixStack {
if (isRadians === false) {
angle = Util.toRadian(angle);
}
this.modelViewMatrix.rotate(angle, axis);
return this;
}
/**
*
* @param s
* @returns
*/
public scale(s: vec3): GLWordMatrixStack {
this.modelViewMatrix.scale(s);
return this;
}
}
Loading…
Cancel
Save