Skip to content

Commit

Permalink
optimize Camera.update() method and update version to 0.3.2,#21
Browse files Browse the repository at this point in the history
  • Loading branch information
iSpring committed Nov 30, 2016
1 parent 0ce8a06 commit cbd9c52
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 28 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "webglobe",
"version": "0.3.1",
"version": "0.3.2",
"description": "A WebGL virtual globe and map engine.",
"main": "require.js",
"scripts": {
Expand Down
61 changes: 40 additions & 21 deletions src/world/Camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,20 @@ class Camera extends Object3D {
private readonly baseTheoryDistanceFromCamera2EarthSurface = 1.23 * Kernel.EARTH_RADIUS;
private readonly maxPitch = 40;

private level: number = -1; //当前渲染等级

private animationLevel: number = -1;//非整数,表示缩放动画过程中的level

//旋转的时候,绕着视线与地球交点进行旋转
//定义抬头时,旋转角为正值
private isZeroPitch: boolean = true;//表示当前Camera视线有没有发生倾斜

private level: number = -1; //当前渲染等级
private realLevel: number = -2;//可能是正数,可能是非整数,非整数表示缩放动画过程中的level

private lastRealLevel: number = -3;//上次render()时所用到的this.realLevel
private lastMatrix: Matrix;//上次render()时的this.matrix
private lastFov: number = -1;
private lastAspect: number = -1;
private lastNear: number = -1;
private lastFar: number = -1;

private viewMatrix: Matrix;//视点矩阵,即Camera模型矩阵的逆矩阵
private projMatrix: Matrix;//当Matrix变化的时候,需要重新计算this.far
private projViewMatrix: Matrix;//获取投影矩阵与视点矩阵的乘积
Expand All @@ -36,18 +42,15 @@ class Camera extends Object3D {

private animating: boolean = false;

Enum: any = {
EARTH_FULL_OVERSPREAD_SCREEN: "EARTH_FULL_OVERSPREAD_SCREEN", //Canvas内全部被地球充满
EARTH_NOT_FULL_OVERSPREAD_SCREEN: "EARTH_NOT_FULL_OVERSPREAD_SCREEN" //Canvas没有全部被地球充满
};

//this.near一旦初始化之后就不应该再修改
//this.far可以动态计算
//this.aspect在Viewport改变后重新计算
//this.fov可以调整以实现缩放效果
constructor(private fov = 45, private aspect = 1, private near = 1, private far = 100) {
super();
this.initFov = this.fov;
this.lastMatrix = new Matrix();
this.lastMatrix.setUniqueValue(0);
this.projMatrix = new Matrix();
this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, this.far);
this._initCameraPosition();
Expand Down Expand Up @@ -121,11 +124,27 @@ class Camera extends Object3D {
return far;
}

//更新各种矩阵,保守起见,可以在每帧绘制之前调用
//理论上只在用户交互的时候调用就可以
update(): void {
this._normalUpdate();
this._updateProjViewMatrixForDraw();
//更新各种矩阵,理论上只在用户交互的时候调用就可以
update(force: boolean = false): void {
if(force || this._isNeedUpdate()){
this._normalUpdate();
this._updateProjViewMatrixForDraw();
}
this.lastFov = this.fov;
this.lastAspect = this.aspect;
this.lastNear = this.near;
this.lastFar = this.far;
this.lastRealLevel = this.realLevel;
this.lastMatrix.setMatrixByOther(this.matrix);
}

private _isNeedUpdate(): boolean{
return (this.fov !== this.lastFov) ||
(this.aspect !== this.lastAspect) ||
(this.near !== this.lastNear) ||
(this.far !== this.lastFar) ||
(this.realLevel !== this.lastRealLevel) ||
(!this.matrix.equals(this.lastMatrix));
}

getProjViewMatrixForDraw(): Matrix {
Expand Down Expand Up @@ -168,9 +187,8 @@ class Camera extends Object3D {

//返回更新后的fov值,如果返回结果 < 0,说明无需更新fov
private _updatePositionAndFov(cameraMatrix: Matrix): number {
//是否满足near值,和fov没有关系,和position有关
//但是改变position的话,fov也要相应变动以满足对应的缩放效果
const currentLevel = this.animating ? this.animationLevel : this.level;
//是否满足near值,和fov没有关系,和position有关,但是改变position的话,fov也要相应变动以满足对应的缩放效果
const currentLevel = this.animating ? this.realLevel : this.level;

//safeLevel不是整数
var safeLevel = this._getSafeThresholdLevelForNear();
Expand Down Expand Up @@ -260,8 +278,9 @@ class Camera extends Object3D {
return;
}
var isLevelChanged = this._updatePositionByLevel(level, this.matrix);
//不要在this._setLevel()方法中更新this.level,因为这会影响animateToLevel()方法
//不要在this._updatePositionByLevel()方法中更新this.level,因为这会影响animateToLevel()方法
this.level = level;
this.realLevel = level;
Kernel.globe.refresh();
}

Expand Down Expand Up @@ -431,7 +450,7 @@ class Camera extends Object3D {
var deltaZ = (newPosition.z - oldPosition.z) / count;
var deltaLevel = (newLevel - this.level) / count;
var start: number = -1;
this.animationLevel = this.level;
this.realLevel = this.level;
this.animating = true;

var callback = (timestap: number) => {
Expand All @@ -441,10 +460,10 @@ class Camera extends Object3D {
var a = timestap - start;
if (a >= span) {
this.animating = false;
this.animationLevel = -1;
this.realLevel = newLevel;
this.setLevel(newLevel);
} else {
this.animationLevel += deltaLevel;
this.realLevel += deltaLevel;
var p = this.getPosition();
this.setPosition(p.x + deltaX, p.y + deltaY, p.z + deltaZ);
requestAnimationFrame(callback);
Expand Down
24 changes: 19 additions & 5 deletions src/world/math/Matrix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ class Matrix{
this.setElements(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44);
}

equals(matrix: Matrix): boolean{
if(this === matrix){
return true;
}
return this.elements.every((ele: number, index: number) => {
return ele === matrix.elements[index];
});
}

setElements(m11: number, m12: number, m13: number, m14: number,
m21: number, m22: number, m23: number, m24: number,
m31: number, m32: number, m33: number, m34: number,
Expand Down Expand Up @@ -185,9 +194,6 @@ class Matrix{
}

setMatrixByOther(otherMatrix: Matrix): void {
if (!(otherMatrix instanceof Matrix)) {
throw "invalid otherMatrix";
}
for (var i = 0; i < otherMatrix.elements.length; i++) {
this.elements[i] = otherMatrix.elements[i];
}
Expand All @@ -201,7 +207,14 @@ class Matrix{
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
0, 0, 0, 1
);
}

setUniqueValue(value: number){
this.elements.forEach((ele, index) => {
this.elements[index] = value;
});
}

/**
Expand Down Expand Up @@ -231,7 +244,8 @@ class Matrix{
this.elements[0], this.elements[4], this.elements[8], this.elements[12],
this.elements[1], this.elements[5], this.elements[9], this.elements[13],
this.elements[2], this.elements[6], this.elements[10], this.elements[14],
this.elements[3], this.elements[7], this.elements[11], this.elements[15]);
this.elements[3], this.elements[7], this.elements[11], this.elements[15]
);
}

multiplyMatrix(otherMatrix: Matrix): Matrix {
Expand Down
4 changes: 3 additions & 1 deletion versions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,6 @@
但是实际传递给shader用于绘图的是projViewMatrixForDraw。Camera.getPickCartesianCoordInEarthByCanvas()方法也是基于projViewMatrixForDraw系列矩阵的。
该版本提高了深度值的精度,基本解决了z值精度问题。在update()方法中会计算projViewMatrixForDraw系列矩阵。

0.3.1 使得Globe.animateToLevel()可以在0.3.0的版本上运行,解决办法是引入了camera.animationLevel,其值是非整数。
0.3.1 使得Globe.animateToLevel()可以在0.3.0的版本上运行,解决办法是引入了camera.animationLevel,其值是非整数。

0.3.2 优化了Camera.update()方法,只有发生用户交互的情况下才实际进行计算。

0 comments on commit cbd9c52

Please sign in to comment.