From cac595f9c6e555d8be9017c3a513ac47bb4e24aa Mon Sep 17 00:00:00 2001
From: Sun Qun <1039219852@qq.com>
Date: Thu, 20 Oct 2016 12:17:10 +0800
Subject: [PATCH 001/109] Update README.md
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index ae4c0f7..b0ef2f8 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ Demo: https://ispring.github.io/WebGlobe/index.html
**如果觉得不错,欢迎Star和Fork!**
## Setup dev environment
- 1. 项目有两个主要的分支:develop分支和master分支,develop是主分支,开发的代码都提交到该分支;master分支用于release,当develop分支中的代码比较稳定切有重要更新的时候,会将develop分支的代码merge到master分支,然后通过master分支进行发布新版本。
+ 1. 项目有两个主要的分支:develop分支和master分支,develop是主分支,开发的代码都提交到该分支;master分支用于release,当develop分支中的代码比较稳定且有重要更新的时候,会将develop分支的代码merge到master分支,然后通过master分支进行发布新版本。
2. 项目采用TypeScript编写,编译成JavaScript运行,推荐使用[Visual Studio Code](http://code.visualstudio.com/)作为编辑器。
@@ -29,7 +29,7 @@ Demo: https://ispring.github.io/WebGlobe/index.html
- clear用于清除编译打包的结果
- compile用于将TypeScript版本的模块编译成JavaScript版本的AMD模块
- bundle用于将TypeScript版本的模块打包成一个JavaScript压缩文件
- - build用于执行以上所有的task
+ - build用于执行以上所有的task,且是默认的task
6. 通过index-src.html可以加载AMD格式的源码,方便调试;通过index-bundle.html可以加载打打包压缩后的JavaScript文件,减少了文件体积和网络请求数量,用于生产环境。
From 6d06931995f4f580ba1ea208f977ba5847f42a12 Mon Sep 17 00:00:00 2001
From: Sun Qun <1039219852@qq.com>
Date: Thu, 20 Oct 2016 20:46:36 +0800
Subject: [PATCH 002/109] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index b0ef2f8..36d7513 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ Demo: https://ispring.github.io/WebGlobe/index.html
- clear用于清除编译打包的结果
- compile用于将TypeScript版本的模块编译成JavaScript版本的AMD模块
- bundle用于将TypeScript版本的模块打包成一个JavaScript压缩文件
- - build用于执行以上所有的task,且是默认的task
+ - build用于执行以上所有的task,且是默认的task
6. 通过index-src.html可以加载AMD格式的源码,方便调试;通过index-bundle.html可以加载打打包压缩后的JavaScript文件,减少了文件体积和网络请求数量,用于生产环境。
From c50c5e3304b08003acad6761af9106ca61bb28ae Mon Sep 17 00:00:00 2001
From: Sun Qun <1039219852@qq.com>
Date: Thu, 20 Oct 2016 20:47:54 +0800
Subject: [PATCH 003/109] Update README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 36d7513..92dac3f 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ Demo: https://ispring.github.io/WebGlobe/index.html
- clear用于清除编译打包的结果
- compile用于将TypeScript版本的模块编译成JavaScript版本的AMD模块
- bundle用于将TypeScript版本的模块打包成一个JavaScript压缩文件
- - build用于执行以上所有的task,且是默认的task
+ - build用于执行以上所有的task,且是默认的task
6. 通过index-src.html可以加载AMD格式的源码,方便调试;通过index-bundle.html可以加载打打包压缩后的JavaScript文件,减少了文件体积和网络请求数量,用于生产环境。
From 1b1432d50351c9715008dabe8a739ba92fe162b4 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Fri, 21 Oct 2016 12:44:25 +0800
Subject: [PATCH 004/109] add folder math and layers
---
main.js | 5 +--
src/world/Elevation.ts | 2 +-
src/world/Event.ts | 8 ++---
src/world/Globe.ts | 10 +++---
src/world/Object3D.ts | 6 ++--
src/world/Object3DComponents.ts | 4 +--
src/world/PerspectiveCamera.ts | 16 ++++-----
src/world/Scene.ts | 2 +-
src/world/Tile.ts | 2 +-
src/world/TileGrid.ts | 2 +-
src/world/Vertice.ts | 37 --------------------
src/world/{ => layers}/ArcGISTiledLayer.ts | 4 +--
src/world/{ => layers}/AutonaviTiledLayer.ts | 4 +--
src/world/{ => layers}/BingTiledLayer.ts | 4 +--
src/world/{ => layers}/BlendTiledLayer.ts | 2 +-
src/world/{ => layers}/GoogleTiledLayer.ts | 2 +-
src/world/{ => layers}/NokiaTiledLayer.ts | 2 +-
src/world/{ => layers}/OsmTiledLayer.ts | 2 +-
src/world/{ => layers}/SosoTiledLayer.ts | 2 +-
src/world/{ => layers}/SubTiledLayer.ts | 16 ++++-----
src/world/{ => layers}/TiandituTiledLayer.ts | 2 +-
src/world/{ => layers}/TiledLayer.ts | 6 ++--
src/world/{ => math}/Line.ts | 4 +--
src/world/{ => math}/Math.ts | 6 ++--
src/world/{ => math}/Matrix.ts | 2 +-
src/world/{ => math}/Plan.ts | 2 +-
src/world/{ => math}/Ray.ts | 4 +--
src/world/{ => math}/Vector.ts | 2 +-
src/world/math/Vertice.ts | 19 ++++++++++
29 files changed, 81 insertions(+), 98 deletions(-)
delete mode 100644 src/world/Vertice.ts
rename src/world/{ => layers}/ArcGISTiledLayer.ts (74%)
rename src/world/{ => layers}/AutonaviTiledLayer.ts (78%)
rename src/world/{ => layers}/BingTiledLayer.ts (91%)
rename src/world/{ => layers}/BlendTiledLayer.ts (87%)
rename src/world/{ => layers}/GoogleTiledLayer.ts (82%)
rename src/world/{ => layers}/NokiaTiledLayer.ts (89%)
rename src/world/{ => layers}/OsmTiledLayer.ts (83%)
rename src/world/{ => layers}/SosoTiledLayer.ts (90%)
rename src/world/{ => layers}/SubTiledLayer.ts (93%)
rename src/world/{ => layers}/TiandituTiledLayer.ts (81%)
rename src/world/{ => layers}/TiledLayer.ts (89%)
rename src/world/{ => math}/Line.ts (92%)
rename src/world/{ => math}/Math.ts (99%)
rename src/world/{ => math}/Matrix.ts (99%)
rename src/world/{ => math}/Plan.ts (80%)
rename src/world/{ => math}/Ray.ts (94%)
rename src/world/{ => math}/Vector.ts (98%)
create mode 100644 src/world/math/Vertice.ts
diff --git a/main.js b/main.js
index 71ad393..156c5d5 100644
--- a/main.js
+++ b/main.js
@@ -1,5 +1,6 @@
window.onload = function() {
- require(["world/Globe", "world/BingTiledLayer", "world/NokiaTiledLayer", "world/OsmTiledLayer", "world/SosoTiledLayer", "world/TiandituTiledLayer", "world/GoogleTiledLayer"],
+ require(["world/Globe", "world/layers/BingTiledLayer", "world/layers/NokiaTiledLayer", "world/layers/OsmTiledLayer",
+ "world/layers/SosoTiledLayer", "world/layers/TiandituTiledLayer", "world/layers/GoogleTiledLayer"],
function(Globe, BingTiledLayer, NokiaTiledLayer, OsmTiledLayer, SosoTiledLayer, TiandituTiledLayer, GoogleTiledLayer) {
function startWebGL() {
@@ -41,7 +42,7 @@
}
}
-
+
startWebGL();
});
};
\ No newline at end of file
diff --git a/src/world/Elevation.ts b/src/world/Elevation.ts
index eae4745..2756bf1 100644
--- a/src/world/Elevation.ts
+++ b/src/world/Elevation.ts
@@ -1,7 +1,7 @@
///
import Kernel = require('./Kernel');
import Utils = require('./Utils');
-import MathUtils = require('./Math');
+import MathUtils = require('./math/Math');
import TileGrid = require('./TileGrid');
const Elevation = {
diff --git a/src/world/Event.ts b/src/world/Event.ts
index 4a302b1..f336fab 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -1,7 +1,7 @@
///
import Kernel = require("./Kernel");
-import MathUtils = require("./Math");
-import Vector = require("./Vector");
+import MathUtils = require("./math/Math");
+import Vector = require("./math/Vector");
import PerspectiveCamera = require("./PerspectiveCamera");
type MouseMoveListener = (e: MouseEvent) => {};
@@ -96,7 +96,7 @@ const EventModule = {
if(oldLon === newLon && oldLat === newLat){
return;
}
- var p1 = MathUtils.geographicToCartesianCoord(oldLon, oldLat);
+ var p1 = MathUtils.geographicToCartesianCoord(oldLon, oldLat);
var v1 = Vector.fromVertice(p1);
v1.normalize();
var p2 = MathUtils.geographicToCartesianCoord(newLon, newLat);
@@ -158,7 +158,7 @@ const EventModule = {
if(newLevel >= 0){
//globe.setLevel(newLevel);
globe.animateToLevel(newLevel);
- }
+ }
},
onKeyDown(event: KeyboardEvent) {
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index 7d98204..3e4488a 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -5,8 +5,8 @@ import ShaderContent = require("./ShaderContent");
import Renderer = require("./Renderer");
import PerspectiveCamera = require("./PerspectiveCamera");
import Scene = require("./Scene");
-import TiledLayer = require("./TiledLayer");
-import SubTiledLayer = require("./SubTiledLayer");
+import TiledLayer = require("./layers/TiledLayer");
+import SubTiledLayer = require("./layers/SubTiledLayer");
import Tile = require("./Tile");
import ImageUtils = require("./Image");
import EventUtils = require("./Event");
@@ -84,12 +84,12 @@ class Globe {
if (!Utils.isNonNegativeInteger(level)) {
throw "invalid level:" + level;
}
-
+
level = level > this.MAX_LEVEL ? this.MAX_LEVEL : level; //超过最大的渲染级别就不渲染
if (level != this.CURRENT_LEVEL) {
if (this.camera instanceof PerspectiveCamera) {
//要先执行camera.setLevel,然后再刷新
- this.camera.setLevel(level);
+ this.camera.setLevel(level);
this.refresh();
}
}
@@ -102,7 +102,7 @@ class Globe {
animateToLevel(level: number){
if(!this.isAnimating()){
this.camera.animateToLevel(level);
- }
+ }
}
/**
diff --git a/src/world/Object3D.ts b/src/world/Object3D.ts
index 1d02bd8..b7ff2c1 100644
--- a/src/world/Object3D.ts
+++ b/src/world/Object3D.ts
@@ -1,8 +1,8 @@
///
import Kernel = require('./Kernel');
-import Matrix = require('./Matrix');
-import Vertice = require('./Vertice');
-import Vector = require('./Vector');
+import Matrix = require('./math/Matrix');
+import Vertice = require('./math/Vertice');
+import Vector = require('./math/Vector');
import TextureMaterial = require('./TextureMaterial');
class Object3D {
diff --git a/src/world/Object3DComponents.ts b/src/world/Object3DComponents.ts
index 39424b1..b52fe4a 100644
--- a/src/world/Object3DComponents.ts
+++ b/src/world/Object3DComponents.ts
@@ -1,7 +1,7 @@
///
import Kernel = require('./Kernel');
-import Vector = require('./Vector');
-import Matrix = require('./Matrix');
+import Vector = require('./math/Vector');
+import Matrix = require('./math/Matrix');
import Object3D = require('./Object3D');
import PerspectiveCamera = require('./PerspectiveCamera');
diff --git a/src/world/PerspectiveCamera.ts b/src/world/PerspectiveCamera.ts
index 2d90c33..09bfbeb 100644
--- a/src/world/PerspectiveCamera.ts
+++ b/src/world/PerspectiveCamera.ts
@@ -1,13 +1,13 @@
///
import Kernel = require('./Kernel');
import Utils = require('./Utils');
-import MathUtils = require('./Math');
-import Vertice = require('./Vertice');
-import Vector = require('./Vector');
-import Line = require('./Line');
-import Plan = require('./Plan');
+import MathUtils = require('./math/Math');
+import Vertice = require('./math/Vertice');
+import Vector = require('./math/Vector');
+import Line = require('./math/Line');
+import Plan = require('./math/Plan');
import TileGrid = require('./TileGrid');
-import Matrix = require('./Matrix');
+import Matrix = require('./math/Matrix');
import Object3D = require('./Object3D');
import Globe = require('./Globe');//just used for TypeScript validate type
@@ -308,7 +308,7 @@ class PerspectiveCamera extends Object3D {
var a = timestap - start;
if(a >= span){
this.matrix = newMat;
- this.animating = false;
+ this.animating = false;
cb();
}else{
var p = this.getPosition();
@@ -365,7 +365,7 @@ class PerspectiveCamera extends Object3D {
dir.setLength(deltaLength);
var pNew = Vector.verticePlusVector(pOld, dir);
this.setPosition(pNew.x, pNew.y, pNew.z);
- }
+ }
}
//判断世界坐标系中的点是否在Canvas中可见
diff --git a/src/world/Scene.ts b/src/world/Scene.ts
index d2c1053..ad1d7d5 100644
--- a/src/world/Scene.ts
+++ b/src/world/Scene.ts
@@ -1,6 +1,6 @@
///
import Object3DComponents = require('./Object3DComponents');
-import TiledLayer = require("./TiledLayer");
+import TiledLayer = require("./layers/TiledLayer");
class Scene extends Object3DComponents{
tiledLayer: TiledLayer;
diff --git a/src/world/Tile.ts b/src/world/Tile.ts
index 0284d03..eabf42f 100644
--- a/src/world/Tile.ts
+++ b/src/world/Tile.ts
@@ -3,7 +3,7 @@ import Kernel = require('./Kernel');
import Object3D = require('./Object3D');
import Enum = require('./Enum');
import Elevation = require('./Elevation');
-import MathUtils = require('./Math');
+import MathUtils = require('./math/Math');
import TileMaterial = require('./TileMaterial');
class Tile extends Object3D {
diff --git a/src/world/TileGrid.ts b/src/world/TileGrid.ts
index 843c976..3f09444 100644
--- a/src/world/TileGrid.ts
+++ b/src/world/TileGrid.ts
@@ -1,7 +1,7 @@
///
import Kernel = require('./Kernel');
import Utils = require('./Utils');
-import MathUtils = require('./Math');
+import MathUtils = require('./math/Math');
class TileGrid {
static LEFT_TOP = "LEFT_TOP";
diff --git a/src/world/Vertice.ts b/src/world/Vertice.ts
deleted file mode 100644
index c1b6cf7..0000000
--- a/src/world/Vertice.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-///
-
-class Vertice{
- constructor(public x = 0, public y = 0, public z = 0){}
-
- // minus(otherVertice: Vertice) : Vector {
- // var x = this.x - otherVertice.x;
- // var y = this.y - otherVertice.y;
- // var z = this.z - otherVertice.z;
- // return new Vector(x, y, z);
- // }
-
- // plus(otherVector: Vector) : Vertice {
- // var x = this.x + otherVector.x;
- // var y = this.y + otherVector.y;
- // var z = this.z + otherVector.z;
- // return new Vertice(x, y, z);
- // }
-
- // getVector(): Vector {
- // return new Vector(this.x, this.y, this.z);
- // }
-
- getArray(): number[] {
- return [this.x, this.y, this.z];
- }
-
- clone(): Vertice {
- return new Vertice(this.x, this.y, this.z);
- }
-
- getOpposite(): Vertice {
- return new Vertice(-this.x, -this.y, -this.z);
- }
-}
-
-export = Vertice;
\ No newline at end of file
diff --git a/src/world/ArcGISTiledLayer.ts b/src/world/layers/ArcGISTiledLayer.ts
similarity index 74%
rename from src/world/ArcGISTiledLayer.ts
rename to src/world/layers/ArcGISTiledLayer.ts
index c410716..a83ddcd 100644
--- a/src/world/ArcGISTiledLayer.ts
+++ b/src/world/layers/ArcGISTiledLayer.ts
@@ -1,5 +1,5 @@
-///
-import Kernel = require("./Kernel");
+///
+import Kernel = require("../Kernel");
import TiledLayer = require("./TiledLayer");
class ArcGISTiledLayer extends TiledLayer{
diff --git a/src/world/AutonaviTiledLayer.ts b/src/world/layers/AutonaviTiledLayer.ts
similarity index 78%
rename from src/world/AutonaviTiledLayer.ts
rename to src/world/layers/AutonaviTiledLayer.ts
index dbb797f..12f2b1e 100644
--- a/src/world/AutonaviTiledLayer.ts
+++ b/src/world/layers/AutonaviTiledLayer.ts
@@ -1,5 +1,5 @@
-///
-import Kernel = require('./Kernel');
+///
+import Kernel = require('../Kernel');
import TiledLayer = require('./TiledLayer');
class AutonaviTiledLayer extends TiledLayer{
diff --git a/src/world/BingTiledLayer.ts b/src/world/layers/BingTiledLayer.ts
similarity index 91%
rename from src/world/BingTiledLayer.ts
rename to src/world/layers/BingTiledLayer.ts
index d024f8a..e928a5c 100644
--- a/src/world/BingTiledLayer.ts
+++ b/src/world/layers/BingTiledLayer.ts
@@ -1,5 +1,5 @@
-///
-import MathUtils = require('./Math');
+///
+import MathUtils = require('../math/Math');
import TiledLayer = require('./TiledLayer');
//Bing地图
diff --git a/src/world/BlendTiledLayer.ts b/src/world/layers/BlendTiledLayer.ts
similarity index 87%
rename from src/world/BlendTiledLayer.ts
rename to src/world/layers/BlendTiledLayer.ts
index fab27d8..8121243 100644
--- a/src/world/BlendTiledLayer.ts
+++ b/src/world/layers/BlendTiledLayer.ts
@@ -1,4 +1,4 @@
-///
+///
import TiledLayer = require("./TiledLayer");
import NokiaTiledLayer = require("./NokiaTiledLayer");
import GoogleTiledLayer = require("./GoogleTiledLayer");
diff --git a/src/world/GoogleTiledLayer.ts b/src/world/layers/GoogleTiledLayer.ts
similarity index 82%
rename from src/world/GoogleTiledLayer.ts
rename to src/world/layers/GoogleTiledLayer.ts
index 19d09d3..0bb800b 100644
--- a/src/world/GoogleTiledLayer.ts
+++ b/src/world/layers/GoogleTiledLayer.ts
@@ -1,4 +1,4 @@
-///
+///
import TiledLayer = require('./TiledLayer');
class GoogleTiledLayer extends TiledLayer{
diff --git a/src/world/NokiaTiledLayer.ts b/src/world/layers/NokiaTiledLayer.ts
similarity index 89%
rename from src/world/NokiaTiledLayer.ts
rename to src/world/layers/NokiaTiledLayer.ts
index b5bd3cd..a594c55 100644
--- a/src/world/NokiaTiledLayer.ts
+++ b/src/world/layers/NokiaTiledLayer.ts
@@ -1,4 +1,4 @@
-///
+///
import TiledLayer = require('./TiledLayer');
class NokiaTiledLayer extends TiledLayer{
diff --git a/src/world/OsmTiledLayer.ts b/src/world/layers/OsmTiledLayer.ts
similarity index 83%
rename from src/world/OsmTiledLayer.ts
rename to src/world/layers/OsmTiledLayer.ts
index 44d9b85..474dcce 100644
--- a/src/world/OsmTiledLayer.ts
+++ b/src/world/layers/OsmTiledLayer.ts
@@ -1,4 +1,4 @@
-///
+///
import TiledLayer = require('./TiledLayer');
class OsmTiledLayer extends TiledLayer {
diff --git a/src/world/SosoTiledLayer.ts b/src/world/layers/SosoTiledLayer.ts
similarity index 90%
rename from src/world/SosoTiledLayer.ts
rename to src/world/layers/SosoTiledLayer.ts
index 952fbf1..a27eee9 100644
--- a/src/world/SosoTiledLayer.ts
+++ b/src/world/layers/SosoTiledLayer.ts
@@ -1,4 +1,4 @@
-///
+///
import TiledLayer = require('./TiledLayer');
class SosoTiledLayer extends TiledLayer {
diff --git a/src/world/SubTiledLayer.ts b/src/world/layers/SubTiledLayer.ts
similarity index 93%
rename from src/world/SubTiledLayer.ts
rename to src/world/layers/SubTiledLayer.ts
index c9ca3fa..06d424c 100644
--- a/src/world/SubTiledLayer.ts
+++ b/src/world/layers/SubTiledLayer.ts
@@ -1,11 +1,11 @@
-///
-import Kernel = require('./Kernel');
-import Utils = require('./Utils');
-import MathUtils = require('./Math');
-import TileGrid = require('./TileGrid');
-import Object3DComponents = require('./Object3DComponents');
-import Tile = require('./Tile');
-import Elevation = require('./Elevation');
+///
+import Kernel = require('../Kernel');
+import Utils = require('../Utils');
+import MathUtils = require('../math/Math');
+import TileGrid = require('../TileGrid');
+import Object3DComponents = require('../Object3DComponents');
+import Tile = require('../Tile');
+import Elevation = require('../Elevation');
class SubTiledLayer extends Object3DComponents {
level: number = -1;
diff --git a/src/world/TiandituTiledLayer.ts b/src/world/layers/TiandituTiledLayer.ts
similarity index 81%
rename from src/world/TiandituTiledLayer.ts
rename to src/world/layers/TiandituTiledLayer.ts
index 65f6f94..113e9b1 100644
--- a/src/world/TiandituTiledLayer.ts
+++ b/src/world/layers/TiandituTiledLayer.ts
@@ -1,4 +1,4 @@
-///
+///
import TiledLayer = require('./TiledLayer');
class TiandituTiledLayer extends TiledLayer {
diff --git a/src/world/TiledLayer.ts b/src/world/layers/TiledLayer.ts
similarity index 89%
rename from src/world/TiledLayer.ts
rename to src/world/layers/TiledLayer.ts
index 598f676..cc09fc6 100644
--- a/src/world/TiledLayer.ts
+++ b/src/world/layers/TiledLayer.ts
@@ -1,6 +1,6 @@
-///
-import Kernel = require('./Kernel');
-import Object3DComponents = require('./Object3DComponents');
+///
+import Kernel = require('../Kernel');
+import Object3DComponents = require('../Object3DComponents');
import SubTiledLayer = require('./SubTiledLayer');
abstract class TiledLayer extends Object3DComponents {
diff --git a/src/world/Line.ts b/src/world/math/Line.ts
similarity index 92%
rename from src/world/Line.ts
rename to src/world/math/Line.ts
index 5862957..d40e763 100644
--- a/src/world/Line.ts
+++ b/src/world/math/Line.ts
@@ -1,4 +1,4 @@
-///
+///
import Vertice = require('./Vertice');
import Vector = require('./Vector');
@@ -16,7 +16,7 @@ class Line{
this.vertice = position.clone();
return this;
}
-
+
setVector(direction: Vector): Line {
this.vector = direction.clone();
this.vector.normalize();
diff --git a/src/world/Math.ts b/src/world/math/Math.ts
similarity index 99%
rename from src/world/Math.ts
rename to src/world/math/Math.ts
index f15c81f..734d7ee 100644
--- a/src/world/Math.ts
+++ b/src/world/math/Math.ts
@@ -1,6 +1,6 @@
-///
-import Kernel = require('./Kernel');
-import Utils = require('./Utils');
+///
+import Kernel = require('../Kernel');
+import Utils = require('../Utils');
import Vertice = require('./Vertice');
import Vector = require('./Vector');
import Line = require('./Line');
diff --git a/src/world/Matrix.ts b/src/world/math/Matrix.ts
similarity index 99%
rename from src/world/Matrix.ts
rename to src/world/math/Matrix.ts
index 6acce9f..7b87858 100644
--- a/src/world/Matrix.ts
+++ b/src/world/math/Matrix.ts
@@ -1,4 +1,4 @@
-///
+///
import Vertice = require('./Vertice');
import Vector = require('./Vector');
diff --git a/src/world/Plan.ts b/src/world/math/Plan.ts
similarity index 80%
rename from src/world/Plan.ts
rename to src/world/math/Plan.ts
index 51f6b8c..2aa9369 100644
--- a/src/world/Plan.ts
+++ b/src/world/math/Plan.ts
@@ -1,4 +1,4 @@
-///
+///
class Plan{
constructor(public A: number, public B: number, public C: number, public D: number){
}
diff --git a/src/world/Ray.ts b/src/world/math/Ray.ts
similarity index 94%
rename from src/world/Ray.ts
rename to src/world/math/Ray.ts
index e79c12f..3191149 100644
--- a/src/world/Ray.ts
+++ b/src/world/math/Ray.ts
@@ -1,4 +1,4 @@
-///
+///
import Vertice = require('./Vertice');
import Vector = require('./Vector');
@@ -32,7 +32,7 @@ class Ray{
var rayCopy = new Ray(this.vertice, this.vector);
return rayCopy;
}
-
+
rotateVertice(vertice: Vertice): Vertice {
return null;
}
diff --git a/src/world/Vector.ts b/src/world/math/Vector.ts
similarity index 98%
rename from src/world/Vector.ts
rename to src/world/math/Vector.ts
index 6c366a6..fb2687d 100644
--- a/src/world/Vector.ts
+++ b/src/world/math/Vector.ts
@@ -1,4 +1,4 @@
-///
+///
import Vertice = require('./Vertice');
class Vector{
diff --git a/src/world/math/Vertice.ts b/src/world/math/Vertice.ts
new file mode 100644
index 0000000..3c8317c
--- /dev/null
+++ b/src/world/math/Vertice.ts
@@ -0,0 +1,19 @@
+///
+
+class Vertice{
+ constructor(public x = 0, public y = 0, public z = 0){}
+
+ getArray(): number[] {
+ return [this.x, this.y, this.z];
+ }
+
+ clone(): Vertice {
+ return new Vertice(this.x, this.y, this.z);
+ }
+
+ getOpposite(): Vertice {
+ return new Vertice(-this.x, -this.y, -this.z);
+ }
+}
+
+export = Vertice;
\ No newline at end of file
From 8737f1ae838adb55cad1f62d80cb53065b5726d6 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Fri, 21 Oct 2016 13:43:33 +0800
Subject: [PATCH 005/109] add new ts files
---
src/world/VertexBufferObject.ts | 40 ++++++++
src/world/geometries/Box.ts | 146 ++++++++++++++++++++++++++++
src/world/geometries/Geometry.ts | 161 +++++++++++++++++++++++++++++++
src/world/geometries/Triangle.ts | 13 +++
src/world/geometries/Vertice.ts | 18 ++++
5 files changed, 378 insertions(+)
create mode 100644 src/world/VertexBufferObject.ts
create mode 100644 src/world/geometries/Box.ts
create mode 100644 src/world/geometries/Geometry.ts
create mode 100644 src/world/geometries/Triangle.ts
create mode 100644 src/world/geometries/Vertice.ts
diff --git a/src/world/VertexBufferObject.ts b/src/world/VertexBufferObject.ts
new file mode 100644
index 0000000..49e9155
--- /dev/null
+++ b/src/world/VertexBufferObject.ts
@@ -0,0 +1,40 @@
+///
+import Kernel = require("./Kernel");
+
+class VertexBufferObject{
+ buffer: WebGLBuffer;
+
+ constructor(public target: number){
+ //target: ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER
+ this.buffer = Kernel.gl.createBuffer();
+ }
+
+ bind(){
+ Kernel.gl.bindBuffer(this.target, this.buffer);
+ }
+
+ unbind(){
+ Kernel.gl.bindBuffer(this.target, null);
+ }
+
+ bufferData(data: number[], usage: number, hasBinded: boolean = false){
+ if(!hasBinded){
+ this.bind();
+ }
+
+ if(this.target === Kernel.gl.ARRAY_BUFFER){
+ Kernel.gl.bufferData(Kernel.gl.ARRAY_BUFFER, new Float32Array(data), usage);
+ }else if(this.target === Kernel.gl.ELEMENT_ARRAY_BUFFER){
+ Kernel.gl.bufferData(Kernel.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(data), usage);
+ }
+ }
+
+ destroy(){
+ if(Kernel.gl.isBuffer(this.buffer)){
+ Kernel.gl.deleteBuffer(this.buffer);
+ }
+ this.buffer = null;
+ }
+}
+
+export = VertexBufferObject;
\ No newline at end of file
diff --git a/src/world/geometries/Box.ts b/src/world/geometries/Box.ts
new file mode 100644
index 0000000..21e8300
--- /dev/null
+++ b/src/world/geometries/Box.ts
@@ -0,0 +1,146 @@
+///
+
+import Vertice = require("./Vertice");
+import Triangle = require("./Triangle");
+import Geometry = require("./Geometry");
+
+class Box extends Geometry {
+ constructor(public length: number, public width: number, public height: number) {
+ super();
+ }
+
+ buildTriangles() {
+ this.vertices = [];
+ this.triangles = [];
+
+ var halfLength = this.length / 2;
+ var halfHeight = this.height / 2;
+ var halfWidth = this.width / 2;
+
+ /*
+ B1---- B3
+ / | / |
+ F1----F3 |
+ | B2- |--B4
+ |/ | /
+ F2----F4
+ */
+
+ //前面四个顶点
+ var vF1 = [-halfLength, halfHeight, halfWidth]; //前面左上角点 F1,索引0
+ var vF2 = [-halfLength, -halfHeight, halfWidth]; //前面左下角点 F2,索引1
+ var vF3 = [halfLength, halfHeight, halfWidth]; //前面右上角点 F3,索引2
+ var vF4 = [halfLength, -halfHeight, halfWidth]; //前面右下角点 F4,索引3
+
+ //后面四个顶点
+ var vB1 = [-halfLength, halfHeight, -halfWidth]; //后面左上角点 B1,索引4
+ var vB2 = [-halfLength, -halfHeight, -halfWidth]; //后面左下角点 B2,索引5
+ var vB3 = [halfLength, halfHeight, -halfWidth]; //后面右上角点 B3,索引6
+ var vB4 = [halfLength, -halfHeight, -halfWidth]; //后面右下角点 B4,索引7
+
+ /*对于一个面从外面向里面看的绘制顺序
+ * 0 2
+ *
+ * 1 3*/
+ //0,1,2; 2,1,3
+
+ var index = 0;
+
+ //加入前面四个顶点,索引号:0,1,2,3
+ var pzResult = this._buildPlane(index, vF1, vF2, vF3, vF4, [0, 0, 1]);
+ this.vertices = this.vertices.concat(pzResult.vertices);
+ this.triangles = this.triangles.concat(pzResult.triangles);
+ index += 4;
+
+ //加入右面四个顶点,索引号:4,5,6,7
+ var pxResult = this._buildPlane(index, vF3, vF4, vB3, vB4, [1, 0, 0]);
+ this.vertices = this.vertices.concat(pxResult.vertices);
+ this.triangles = this.triangles.concat(pxResult.triangles);
+ index += 4;
+
+ //加入后面四个顶点,索引号:8,9,10,11
+ var nzResult = this._buildPlane(index, vB3, vB4, vB1, vB2, [0, 0, -1]);
+ this.vertices = this.vertices.concat(nzResult.vertices);
+ this.triangles = this.triangles.concat(nzResult.triangles);
+ index += 4;
+
+ //加入左面四个顶点,索引号:12,13,14,15
+ var nxResult = this._buildPlane(index, vB1, vB2, vF1, vF2, [-1, 0, 0]);
+ this.vertices = this.vertices.concat(nxResult.vertices);
+ this.triangles = this.triangles.concat(nxResult.triangles);
+ index += 4;
+
+ //加入上面的四个顶点,索引号:16,17,18,19
+ var pyResult = this._buildPlane(index, vB1, vF1, vB3, vF3, [0, 1, 0]);
+ this.vertices = this.vertices.concat(pyResult.vertices);
+ this.triangles = this.triangles.concat(pyResult.triangles);
+ index += 4;
+
+
+ //加入下面四个顶点,索引号:20,21,22,23
+ var nyResult = this._buildPlane(index, vF2, vB2, vF4, vB4, [0, -1, 0]);
+ this.vertices = this.vertices.concat(nyResult.vertices);
+ this.triangles = this.triangles.concat(nyResult.triangles);
+ }
+
+ _buildPlane(startIndex: number, pLT: number[], pLB: number[], pRT: number[], pRB: number[], nortal: number[]) {
+ /*对于一个面从外面向里面看的绘制顺序
+ * 0 2
+ *
+ * 1 3*/
+ //0,1,2; 2,1,3
+
+ var result = {
+ vertices: [],
+ triangles: []
+ };
+
+ //vertices
+
+ var v0 = new Vertice({
+ i: startIndex,
+ p: pLT,
+ uv: [0, 0],
+ n: nortal,
+ c: null
+ });
+
+ var v1 = new Vertice({
+ i: startIndex + 1,
+ p: pLB,
+ uv: [0, 1],
+ n: nortal,
+ c: null
+ });
+
+ var v2 = new Vertice({
+ i: startIndex + 2,
+ p: pRT,
+ uv: [1, 0],
+ n: nortal,
+ c: null
+ });
+
+ var v3 = new Vertice({
+ i: startIndex + 3,
+ p: pRB,
+ uv: [1, 1],
+ n: nortal,
+ c: null
+ });
+
+ result.vertices = [v0, v1, v2, v3];
+
+ //triangles
+
+ var tri0 = new Triangle(v0, v1, v2);
+
+ var tri1 = new Triangle(v2, v1, v3);
+
+ result.triangles = [tri0, tri1];
+
+ return result;
+ }
+}
+
+export = Box;
\ No newline at end of file
diff --git a/src/world/geometries/Geometry.ts b/src/world/geometries/Geometry.ts
new file mode 100644
index 0000000..22a1940
--- /dev/null
+++ b/src/world/geometries/Geometry.ts
@@ -0,0 +1,161 @@
+///
+import Kernel = require("../Kernel");
+import Vertice = require("./Vertice");
+import Triangle = require("./Triangle");
+import VertexBufferObject = require("../VertexBufferObject");
+
+class Geometry {
+ vertices: Vertice[];
+ triangles: Triangle[];
+ vbo: any;
+ ibo: any;
+ nbo: any;
+ uvbo: any;
+ cbo: any;
+
+ constructor() {
+ this.buildTriangles();
+ }
+
+ //set vertices and triangles
+ buildTriangles(){
+ this.vertices = [];
+ this.triangles = [];
+ }
+
+ calculateVBO(force:boolean = false) {
+ if (!this.vbo || force) {
+ var vboData:number[] = [], vertex:Vertice;
+
+ for (var i = 0, length = this.vertices.length; i < length; i++) {
+ vertex = this.vertices[i];
+ vboData.push(vertex.p[0]);
+ vboData.push(vertex.p[1]);
+ vboData.push(vertex.p[2]);
+ }
+
+ if (!this.vbo) {
+ this.vbo = new VertexBufferObject(Kernel.gl.ARRAY_BUFFER);
+ }
+ this.vbo.bind();
+ this.vbo.bufferData(vboData, Kernel.gl.STATIC_DRAW, true);
+ this.vbo.unbind();
+ }
+ return this.vbo;
+ }
+
+ calculateIBO(force:boolean = false) {
+ if (!this.ibo || force) {
+ var iboData:number[] = [], triangle:Triangle;
+
+ for (var i = 0, length = this.triangles.length; i < length; i++) {
+ triangle = this.triangles[i];
+ iboData.push(triangle.v1.i);
+ iboData.push(triangle.v2.i);
+ iboData.push(triangle.v3.i);
+ }
+
+ if (!this.ibo) {
+ this.ibo = new VertexBufferObject(Kernel.gl.ELEMENT_ARRAY_BUFFER);
+ }
+ this.ibo.bind();
+ this.ibo.bufferData(iboData, Kernel.gl.STATIC_DRAW, true);
+ this.ibo.unbind();
+ }
+ return this.ibo;
+ }
+
+ calculateNBO(force:boolean = false) {
+ if (!this.nbo || force) {
+ var nboData:number[] = [], vertex:Vertice;
+
+ for (var i = 0, length = this.vertices.length; i < length; i++) {
+ vertex = this.vertices[i];
+ nboData.push(vertex.n[0]);
+ nboData.push(vertex.n[1]);
+ nboData.push(vertex.n[2]);
+ }
+
+ if (!this.nbo) {
+ this.nbo = new VertexBufferObject(Kernel.gl.ARRAY_BUFFER);
+ }
+ this.nbo.bind();
+ this.nbo.bufferData(nboData, Kernel.gl.STATIC_DRAW, true);
+ this.nbo.unbind();
+ }
+ return this.nbo;
+ }
+
+ calculateUVBO(force:boolean = false) {
+ if (!this.uvbo || force) {
+ var uvboData:number[] = [], vertex:Vertice;
+
+ for (var i = 0, length = this.vertices.length; i < length; i++) {
+ vertex = this.vertices[i];
+ uvboData.push(vertex.uv[0]);
+ uvboData.push(vertex.uv[1]);
+ }
+
+ if (!this.uvbo) {
+ this.uvbo = new VertexBufferObject(Kernel.gl.ARRAY_BUFFER);
+ }
+ this.uvbo.bind();
+ this.uvbo.bufferData(uvboData, Kernel.gl.STATIC_DRAW, true);
+ this.uvbo.unbind();
+ }
+ return this.uvbo;
+ }
+
+ calculateCBO(force:boolean = false) {
+ if (!this.cbo || force) {
+ var cboData:number[] = [], vertex:Vertice;
+
+ for (var i = 0, length = this.vertices.length; i < length; i++) {
+ vertex = this.vertices[i];
+ cboData.push(vertex.c[0]);
+ cboData.push(vertex.c[1]);
+ cboData.push(vertex.c[2]);
+ }
+
+ if (!this.cbo) {
+ this.cbo = new VertexBufferObject(Kernel.gl.ARRAY_BUFFER);
+ }
+ this.cbo.bind();
+ this.cbo.bufferData(cboData, Kernel.gl.STATIC_DRAW, true);
+ this.cbo.unbind();
+ }
+ return this.cbo;
+ }
+
+ destroy() {
+ if (this.vbo) {
+ Kernel.gl.deleteBuffer(this.vbo);
+ }
+ if (this.ibo) {
+ Kernel.gl.deleteBuffer(this.ibo);
+ }
+ if (this.nbo) {
+ Kernel.gl.deleteBuffer(this.nbo);
+ }
+ if (this.cbo) {
+ Kernel.gl.deleteBuffer(this.cbo);
+ }
+ if (this.uvbo) {
+ Kernel.gl.deleteBuffer(this.uvbo);
+ }
+
+ this.vbo = null;
+ this.ibo = null;
+ this.nbo = null;
+ this.cbo = null;
+ this.uvbo = null;
+ this.vertices = [];
+ this.triangles = [];
+ }
+}
+
+//world.geometries._Geometry.prototype = new world._Object3D();
+
+//world.geometries._Geometry.prototype.constructor = world.geometries._Geometry;
+
+export = Geometry;
\ No newline at end of file
diff --git a/src/world/geometries/Triangle.ts b/src/world/geometries/Triangle.ts
new file mode 100644
index 0000000..dd0ef14
--- /dev/null
+++ b/src/world/geometries/Triangle.ts
@@ -0,0 +1,13 @@
+///
+import Vertice = require("./Vertice");
+
+class Triangle{
+
+ constructor(public v1: Vertice, public v2: Vertice, public v3: Vertice){}
+
+ setColor(c: number[]){
+ this.v1.c = this.v2.c = this.v3.c = c;
+ }
+}
+
+export = Triangle;
\ No newline at end of file
diff --git a/src/world/geometries/Vertice.ts b/src/world/geometries/Vertice.ts
new file mode 100644
index 0000000..430f13a
--- /dev/null
+++ b/src/world/geometries/Vertice.ts
@@ -0,0 +1,18 @@
+///
+class Vertice{
+ p:number[];
+ n:number[];
+ uv:number[];
+ c:number[];
+ i:number;
+
+ constructor(args:any){
+ this.p = args.p;//[x,y,z]
+ this.n = args.n;//[x,y,z]
+ this.uv = args.uv;//[s,t]
+ this.c = args.c;//[r,g,b]
+ this.i = args.i;//index
+ }
+}
+
+export = Vertice;
\ No newline at end of file
From b982aa159469c4594a09db8d96540ec23b91bb8f Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Sat, 22 Oct 2016 18:57:52 +0800
Subject: [PATCH 006/109] update new ts files
---
src/world/graphics/Graphic.ts | 66 +++++++++++++
src/world/graphics/MeshGraphic.ts | 104 +++++++++++++++++++++
src/world/materials/Material.ts | 8 ++
src/world/materials/MeshColorMaterial.ts | 55 +++++++++++
src/world/materials/MeshTextureMaterial.ts | 89 ++++++++++++++++++
src/world/math/Math.ts | 4 +
6 files changed, 326 insertions(+)
create mode 100644 src/world/graphics/Graphic.ts
create mode 100644 src/world/graphics/MeshGraphic.ts
create mode 100644 src/world/materials/Material.ts
create mode 100644 src/world/materials/MeshColorMaterial.ts
create mode 100644 src/world/materials/MeshTextureMaterial.ts
diff --git a/src/world/graphics/Graphic.ts b/src/world/graphics/Graphic.ts
new file mode 100644
index 0000000..1622d86
--- /dev/null
+++ b/src/world/graphics/Graphic.ts
@@ -0,0 +1,66 @@
+///
+
+import Kernel = require("../Kernel");
+import Geometry = require("../geometries/Geometry");
+import Material = require("../materials/Material");
+
+interface GraphicOptions{
+ geometry: Geometry;
+ material: Material;
+ parent: any;
+ visible?: boolean;
+}
+
+class Graphic{
+ id:number;
+ ready: boolean = false;
+ visible: boolean = true;
+ parent: any;
+
+ constructor(public geometry: Geometry, public material: Material){
+ this.id = ++Kernel.idCounter;
+ this.parent = null;
+ }
+
+ setVisible(visible: boolean){
+ this.visible = visible;
+ }
+
+ getProgramType() {
+ return this.material.getType();
+ }
+
+ //need to be override
+ createProgram(): any{
+ return null;
+ }
+
+ // onBeforeDraw(){}
+
+ // _draw(program, camera, scene){
+ // if(!program || !this.visible || !this.isReady || !this.material.isReady){
+ // return;
+ // }
+
+ // this.onBeforeDraw(program, camera, scene);
+ // this.draw(program, camera, scene);
+ // this.onAfterDraw(program, camera, scene);
+ // }
+
+ // //need to be override
+ // draw(){}
+
+ // onAfterDraw(){}
+
+ destroy(){
+ this.parent = null;
+ //释放显卡中的资源
+ this.geometry.destroy();
+ this.material.destroy();
+ this.geometry = null;
+ this.material = null;
+ this.ready = false;
+ }
+}
+
+export = Graphic;
\ No newline at end of file
diff --git a/src/world/graphics/MeshGraphic.ts b/src/world/graphics/MeshGraphic.ts
new file mode 100644
index 0000000..10408fa
--- /dev/null
+++ b/src/world/graphics/MeshGraphic.ts
@@ -0,0 +1,104 @@
+///
+
+import Kernel = require("../Kernel");
+import Graphic = require("./Graphic");
+import Geometry = require("../geometries/Geometry");
+import MeshTextureMaterial = require("../materials/MeshTextureMaterial");
+
+const vs =
+ `
+'attribute vec3 aPosition;',
+'attribute vec2 aUV;',
+'varying vec2 vUV;',
+'uniform mat4 uPMVMatrix;',
+
+'void main()',
+'{',
+ 'gl_Position = uPMVMatrix * vec4(aPosition,1.0);',
+ 'vUV = aUV;',
+'}'
+`;
+
+const fs =
+ `
+'precision mediump float;',
+ 'varying vec2 vUV;',
+ 'uniform sampler2D uSampler;',
+
+ 'void main()',
+ '{',
+ 'gl_FragColor = texture2D(uSampler, vec2(vUV.s, vUV.t));',
+ '}'
+`;
+
+class MeshGraphic extends Graphic {
+ constructor(public geometry: Geometry, public material: MeshTextureMaterial){
+ super(geometry, material);
+ this.geometry.calculateVBO();
+ this.geometry.calculateIBO();
+ this._init4TextureMaterial();
+ this.ready = true;
+ }
+
+ _init4TextureMaterial() {
+ this.geometry.calculateUVBO();
+ }
+
+ _drawTextureMaterial(program) {
+ //set aUV
+ var locUV = program.getAttribLocation('aUV');
+ program.enableVertexAttribArray('aUV');
+ this.geometry.uvbo.bind();
+ Kernel.gl.vertexAttribPointer(locUV, 2, Kernel.gl.FLOAT, false, 0, 0);
+
+ //set uSampler
+ var locSampler = program.getUniformLocation('uSampler');
+ Kernel.gl.activeTexture(Kernel.gl.TEXTURE0);
+ //world.Cache.activeTexture(gl.TEXTURE0);
+ Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, this.material.texture);
+ Kernel.gl.uniform1i(locSampler, 0);
+ }
+
+ // createProgram(scene) {
+ // var program = null;
+ // var programType = this.getProgramType(scene);
+ // var args = {
+ // type: programType,
+ // definesObject: null,
+ // vsSource: vs,
+ // fsSource: fs
+ // };
+ // program = new world.Program(args);
+
+ // return program;
+ // }
+
+ // draw(program, camera, scene) {
+ // //aPosition
+ // var locPosition = program.getAttribLocation('aPosition');
+ // program.enableVertexAttribArray('aPosition');
+ // this.geometry.vbo.bind();
+ // Kernel.gl.vertexAttribPointer(locPosition, 3, Kernel.gl.FLOAT, false, 0, 0);
+
+ // //uPMVMatrix
+ // var pmvMatrix = camera.projViewMatrix.multiplyMatrix(this.geometry.matrix);
+ // var locPMVMatrix = program.getUniformLocation('uPMVMatrix');
+ // Kernel.gl.uniformMatrix4fv(locPMVMatrix, false, pmvMatrix.elements);
+
+ // this._drawTextureMaterial(program);
+
+ // //设置索引,但不用往shader中赋值
+ // this.geometry.ibo.bind();
+
+ // //绘图
+ // var count = this.geometry.triangles.length * 3;
+ // Kernel.gl.drawElements(Kernel.gl.TRIANGLES, count, Kernel.gl.UNSIGNED_SHORT, 0);
+
+ // //释放当前绑定对象
+ // Kernel.gl.bindBuffer(Kernel.gl.ARRAY_BUFFER, null);
+ // Kernel.gl.bindBuffer(Kernel.gl.ELEMENT_ARRAY_BUFFER, null);
+ // Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, null);
+ // }
+}
+
+export = MeshGraphic;
\ No newline at end of file
diff --git a/src/world/materials/Material.ts b/src/world/materials/Material.ts
new file mode 100644
index 0000000..103d922
--- /dev/null
+++ b/src/world/materials/Material.ts
@@ -0,0 +1,8 @@
+///
+abstract class Material{
+ abstract isReady(): boolean
+ abstract getType(): string
+ abstract destroy(): void
+}
+
+export = Material;
\ No newline at end of file
diff --git a/src/world/materials/MeshColorMaterial.ts b/src/world/materials/MeshColorMaterial.ts
new file mode 100644
index 0000000..671b97c
--- /dev/null
+++ b/src/world/materials/MeshColorMaterial.ts
@@ -0,0 +1,55 @@
+///
+import Material = require("./Material");
+
+class MeshColorMaterial extends Material {
+ type: string = "";
+ ready: boolean = false;
+ singleColor: number[];
+ triangleColors: number[][];
+ verticeColors: number[][];
+
+ constructor() {
+ super();
+ this.reset();
+ }
+
+ isReady(){
+ return this.ready;
+ }
+
+ getType(){
+ return "MeshColorMaterial";
+ }
+
+ reset() {
+ this.type = '';
+ this.singleColor = null;
+ this.triangleColors = [];
+ this.verticeColors = [];
+ this.ready = false;
+ }
+
+ setSingleColor(color: number[]) {
+ this.type = 'single';
+ this.singleColor = color;
+ this.ready = true;
+ }
+
+ setTriangleColor(colors: number[][]) {
+ this.type = 'triangle';
+ this.triangleColors = colors;
+ this.ready = true;
+ };
+
+ setVerticeColor(colors: number[][]) {
+ this.type = 'vertice';
+ this.verticeColors = colors;
+ this.ready = true;
+ }
+
+ destroy() {
+ this.reset();
+ }
+}
+
+export = MeshColorMaterial;
\ No newline at end of file
diff --git a/src/world/materials/MeshTextureMaterial.ts b/src/world/materials/MeshTextureMaterial.ts
new file mode 100644
index 0000000..2719bff
--- /dev/null
+++ b/src/world/materials/MeshTextureMaterial.ts
@@ -0,0 +1,89 @@
+///
+import Kernel = require("../Kernel");
+import MathUtils = require("../math/Math");
+import Material = require("./Material");
+
+class MeshTextureMaterial extends Material {
+ texture: WebGLTexture;
+ image: HTMLImageElement;
+ url: string;
+ ready: boolean = false;
+ isDelete: boolean = false;
+
+ constructor(args: any) {
+ super();
+ if (args.image instanceof Image && args.image.width > 0 && args.image.height > 0) {
+ this.setImage(args.image);
+ } else if (typeof args.url === "string") {
+ this.setImageUrl(args.url);
+ } else {
+ throw 'Invalid parameter';
+ }
+ }
+
+ getType(){
+ return "MeshTextureMaterial";
+ }
+
+ isReady(){
+ return this.ready;
+ }
+
+ setImage(image: HTMLImageElement) {
+ if (image.width > 0 && image.height > 0) {
+ this.image = image;
+ this._onLoad();
+ }
+ }
+
+ setImageUrl(url: string) {
+ this.image = new Image();
+ this.image.crossOrigin = 'anonymous';//很重要,因为图片是跨域获得的,所以一定要加上此句代码
+ this.image.onload = this._onLoad.bind(this);
+ this.image.src = url;
+ }
+
+ //图片加载完成时触发
+ _onLoad() {
+ //要考虑纹理已经被移除掉了图片才进入onLoad这种情况
+ if (this.isDelete) {
+ return;
+ }
+
+ Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, this.texture);
+ //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true);
+
+ Kernel.gl.texImage2D(Kernel.gl.TEXTURE_2D, 0, Kernel.gl.RGBA, Kernel.gl.RGBA, Kernel.gl.UNSIGNED_BYTE, this.image);
+
+ var isMipMap = this.image.width === this.image.height && MathUtils.isPowerOfTwo(this.image.width);
+
+ if (isMipMap) {
+ //使用MipMap
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);//LINEAR_MIPMAP_LINEAR
+ Kernel.gl.generateMipmap(Kernel.gl.TEXTURE_2D);
+ } else {
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR);//gl.NEAREST
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR);//gl.NEAREST
+ }
+
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
+
+ Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, null);
+
+ this.ready = true;
+ }
+
+ //释放显卡中的texture资源
+ destroy() {
+ if (Kernel.gl.isTexture(this.texture)) {
+ Kernel.gl.deleteTexture(this.texture);
+ }
+ this.texture = null;
+ this.isDelete = true;
+ this.ready = false;
+ }
+}
+
+export = MeshTextureMaterial;
\ No newline at end of file
diff --git a/src/world/math/Math.ts b/src/world/math/Math.ts
index 734d7ee..b9603e7 100644
--- a/src/world/math/Math.ts
+++ b/src/world/math/Math.ts
@@ -25,6 +25,10 @@ const MathUtils = {
return Math.abs(value) < 0.000001;
},
+ isPowerOfTwo(value: number) {
+ return ( value & ( value - 1 ) ) === 0 && value !== 0;
+ },
+
/**
* 将其他进制的数字转换为10进制
* @param numSys 要准换的进制
From f01348ab887b1edbdf432622ac6033c1fcee05e2 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Tue, 25 Oct 2016 13:40:56 +0800
Subject: [PATCH 007/109] update ts files
---
src/world/Object3D.ts | 147 +--------------------------
src/world/Object3DComponents.ts | 9 +-
src/world/PerspectiveCamera.ts | 2 +-
src/world/Program.ts | 162 ++++++++++++++++++++++++++++++
src/world/ProgramUtils.ts | 31 ++++++
src/world/geometries/Geometry.ts | 28 +++---
src/world/graphics/Graphic.ts | 29 ++----
src/world/graphics/MeshGraphic.ts | 74 ++++++--------
8 files changed, 258 insertions(+), 224 deletions(-)
create mode 100644 src/world/Program.ts
create mode 100644 src/world/ProgramUtils.ts
diff --git a/src/world/Object3D.ts b/src/world/Object3D.ts
index b7ff2c1..2b818e2 100644
--- a/src/world/Object3D.ts
+++ b/src/world/Object3D.ts
@@ -6,153 +6,10 @@ import Vector = require('./math/Vector');
import TextureMaterial = require('./TextureMaterial');
class Object3D {
- id: number;
matrix: Matrix;
- parent: any;
- vertices: number[];
- vertexBuffer: WebGLBuffer;
- indices: number[];
- indexBuffer: WebGLBuffer;
- textureCoords: number[];
- textureCoordBuffer: WebGLBuffer;
- material: TextureMaterial;
- visible: boolean;
-
- constructor(args?: any) {
- this.id = ++Kernel.idCounter;
+
+ constructor() {
this.matrix = new Matrix();
- this.parent = null;
- this.vertices = [];
- this.vertexBuffer = null;
- this.indices = [];
- this.indexBuffer = null;
- this.textureCoords = [];
- this.textureCoordBuffer = null;
- this.material = null;
- this.visible = true;
- if (args && args.material) {
- this.material = args.material;
- }
- this.createVerticeData(args);
- }
-
- /**
- * 根据传入的参数生成vertices和indices,然后通过调用setBuffers初始化buffer
- * @param params 传入的参数
- */
- createVerticeData(params: any): void {
- /*var infos = {
- vertices:vertices,
- indices:indices
- };
- this.setBuffers(infos);*/
- }
-
- /**
- * 设置buffer,由createVerticeData函数调用
- * @param infos 包含vertices和indices信息,由createVerticeData传入参数
- */
- setBuffers(infos: any): void {
- if (infos) {
- this.vertices = infos.vertices || [];
- this.indices = infos.indices || [];
- this.textureCoords = infos.textureCoords || [];
- if (this.vertices.length > 0 && this.indices.length > 0) {
- if (!(Kernel.gl.isBuffer(this.vertexBuffer))) {
- this.vertexBuffer = Kernel.gl.createBuffer();
- }
- Kernel.gl.bindBuffer(Kernel.gl.ARRAY_BUFFER, this.vertexBuffer);
- Kernel.gl.bufferData(Kernel.gl.ARRAY_BUFFER, new Float32Array(this.vertices), Kernel.gl.STATIC_DRAW);
-
- if (!(Kernel.gl.isBuffer(this.indexBuffer))) {
- this.indexBuffer = Kernel.gl.createBuffer();
- }
- Kernel.gl.bindBuffer(Kernel.gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
- Kernel.gl.bufferData(Kernel.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.indices), Kernel.gl.STATIC_DRAW);
- }
-
- //使用纹理
- if (this.material instanceof TextureMaterial) {
- if (this.textureCoords.length > 0) { //提供了纹理坐标
- if (!(Kernel.gl.isBuffer(this.textureCoordBuffer))) {
- this.textureCoordBuffer = Kernel.gl.createBuffer();
- }
- Kernel.gl.bindBuffer(Kernel.gl.ARRAY_BUFFER, this.textureCoordBuffer);
- Kernel.gl.bufferData(Kernel.gl.ARRAY_BUFFER, new Float32Array(this.textureCoords), Kernel.gl.STATIC_DRAW);
- }
- }
- }
- Kernel.gl.bindBuffer(Kernel.gl.ARRAY_BUFFER, null);
- Kernel.gl.bindBuffer(Kernel.gl.ELEMENT_ARRAY_BUFFER, null);
- }
-
- setShaderMatrix(camera: any): void {
- // if (!(camera instanceof PerspectiveCamera)) {
- // throw "invalid camera : not World.PerspectiveCamera";
- // }
- camera.viewMatrix = (camera.viewMatrix instanceof Matrix) ? camera.viewMatrix : camera.getViewMatrix();
- var mvMatrix = camera.viewMatrix.multiplyMatrix(this.matrix);
- Kernel.gl.uniformMatrix4fv(Kernel.gl.shaderProgram.uMVMatrix, false, mvMatrix.elements);
- Kernel.gl.uniformMatrix4fv(Kernel.gl.shaderProgram.uPMatrix, false, camera.projMatrix.elements);
- }
-
- draw(camera: any): void {
- // if (!(camera instanceof PerspectiveCamera)) {
- // throw "invalid camera : not World.PerspectiveCamera";
- // }
- if (this.visible) {
- if (this.material instanceof TextureMaterial && this.material.loaded) {
- Kernel.gl.enableVertexAttribArray(Kernel.gl.shaderProgram.aTextureCoord);
- Kernel.gl.bindBuffer(Kernel.gl.ARRAY_BUFFER, this.textureCoordBuffer);
- Kernel.gl.vertexAttribPointer(Kernel.gl.shaderProgram.aTextureCoord, 2, Kernel.gl.FLOAT, false, 0, 0);
-
- Kernel.gl.activeTexture(Kernel.gl.TEXTURE0);
- Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, this.material.texture);
- Kernel.gl.uniform1i(Kernel.gl.shaderProgram.uSampler, 0);
-
- this.setShaderMatrix(camera);
-
- //往shader中对vertex赋值
- Kernel.gl.enableVertexAttribArray(Kernel.gl.shaderProgram.aVertexPosition);
- Kernel.gl.bindBuffer(Kernel.gl.ARRAY_BUFFER, this.vertexBuffer);
- Kernel.gl.vertexAttribPointer(Kernel.gl.shaderProgram.aVertexPosition, 3, Kernel.gl.FLOAT, false, 0, 0);
-
- //设置索引,但不用往shader中赋值
- Kernel.gl.bindBuffer(Kernel.gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
- //绘图
- Kernel.gl.drawElements(Kernel.gl.TRIANGLES, this.indices.length, Kernel.gl.UNSIGNED_SHORT, 0);
-
- Kernel.gl.bindBuffer(Kernel.gl.ARRAY_BUFFER, null);
- Kernel.gl.bindBuffer(Kernel.gl.ELEMENT_ARRAY_BUFFER, null);
- Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, null);
- }
- }
- }
-
- //释放显存中的buffer资源
- releaseBuffers(): void {
- //释放显卡中的资源
- if (Kernel.gl.isBuffer(this.vertexBuffer)) {
- Kernel.gl.deleteBuffer(this.vertexBuffer);
- }
- if (Kernel.gl.isBuffer(this.indexBuffer)) {
- Kernel.gl.deleteBuffer(this.indexBuffer);
- }
- if (Kernel.gl.isBuffer(this.textureCoordBuffer)) {
- Kernel.gl.deleteBuffer(this.textureCoordBuffer);
- }
- this.vertexBuffer = null;
- this.indexBuffer = null;
- this.textureCoordBuffer = null;
- }
-
- destroy(): void {
- this.parent = null;
- this.releaseBuffers();
- if (this.material instanceof TextureMaterial) {
- this.material.releaseTexture();
- this.material = null;
- }
}
//需要子类重写
diff --git a/src/world/Object3DComponents.ts b/src/world/Object3DComponents.ts
index b52fe4a..7470212 100644
--- a/src/world/Object3DComponents.ts
+++ b/src/world/Object3DComponents.ts
@@ -3,9 +3,10 @@ import Kernel = require('./Kernel');
import Vector = require('./math/Vector');
import Matrix = require('./math/Matrix');
import Object3D = require('./Object3D');
+import Graphic = require('./graphics/Graphic');
import PerspectiveCamera = require('./PerspectiveCamera');
-type ChildType = Object3D | Object3DComponents;
+// type ChildType = Object3D | Object3DComponents;
//三维对象集合
class Object3DComponents {
@@ -13,7 +14,7 @@ class Object3DComponents {
matrix: Matrix;
visible: boolean;
parent: any;
- children: ChildType[];
+ children: Graphic[];
constructor() {
this.id = ++Kernel.idCounter;
@@ -23,7 +24,7 @@ class Object3DComponents {
this.children = [];
}
- add(obj: ChildType) {
+ add(obj: Graphic) {
if (this.findObjById(obj.id) !== null) {
console.debug("obj已经存在于Object3DComponents中,无法将其再次加入!");
return;
@@ -33,7 +34,7 @@ class Object3DComponents {
}
}
- remove(obj: ChildType) {
+ remove(obj: Graphic) {
if (obj) {
var result = this.findObjById(obj.id);
if (result === null) {
diff --git a/src/world/PerspectiveCamera.ts b/src/world/PerspectiveCamera.ts
index 09bfbeb..1e92d06 100644
--- a/src/world/PerspectiveCamera.ts
+++ b/src/world/PerspectiveCamera.ts
@@ -22,7 +22,7 @@ class PerspectiveCamera extends Object3D {
private animating: boolean = false;
constructor(public fov = 90, public aspect = 1, public near = 1, public far = 1) {
- super(null);
+ super();
this.pitch = 90;
this.projMatrix = new Matrix();
this.setPerspectiveMatrix(this.fov, this.aspect, this.near, this.far);
diff --git a/src/world/Program.ts b/src/world/Program.ts
new file mode 100644
index 0000000..e5ef5a5
--- /dev/null
+++ b/src/world/Program.ts
@@ -0,0 +1,162 @@
+///
+
+import Kernel = require("./Kernel");
+
+class Program{
+ ready: boolean = false;
+ activeInfosObject:any;
+ program: WebGLProgram;
+ static currentProgram:Program;
+
+ constructor(public type:string, public vs:string, public fs:string){
+ //{name,type,size,loc,isAttribute, isEnabled} the default value of isEnabled is undefined
+ //Note: if attribute, loc is number; if uniform, loc is WebGLUniformLocation
+ this.activeInfosObject = {};
+ this._init();
+ }
+
+ use(){
+ if(this.ready && Program.currentProgram !== this){
+ Kernel.gl.useProgram(this.program);
+ Program.currentProgram = this;
+ }
+ }
+
+ updateActiveAttribInfos(){
+ var count = Kernel.gl.getProgramParameter(this.program, Kernel.gl.ACTIVE_ATTRIBUTES);
+
+ for(var i = 0, activeInfo; i < count; i++){
+ activeInfo = Kernel.gl.getActiveAttrib(this.program, i);
+ activeInfo.loc = Kernel.gl.getAttribLocation(this.program, activeInfo.name);
+ activeInfo.isAttribute = true;
+ this.activeInfosObject[activeInfo.name] = activeInfo;
+ }
+ }
+
+ updateActiveUniformInfos(){
+ var count = Kernel.gl.getProgramParameter(this.program, Kernel.gl.ACTIVE_UNIFORMS);
+
+ for(var i = 0, activeInfo; i < count; i++){
+ activeInfo = Kernel.gl.getActiveUniform(this.program, i);
+ activeInfo.loc = Kernel.gl.getUniformLocation(this.program, activeInfo.name);
+ activeInfo.isAttribute = false;
+ this.activeInfosObject[activeInfo.name] = activeInfo;
+ }
+ }
+
+ getLocation(name){
+ //loc = gl.getAttribLocation(this.program, name);
+ //loc = gl.getUniformLocation(this.program, name);
+ var loc = -1;
+ var activeInfo = this.activeInfosObject[name];
+ if(activeInfo){
+ loc = activeInfo.loc;
+ }
+ return loc;
+ }
+
+ getAttribLocation(name){
+ var loc = -1;
+ var activeInfo = this.activeInfosObject[name];
+ if(activeInfo && activeInfo.isAttribute){
+ loc = activeInfo.loc;
+ }
+ return loc;
+ }
+
+ //return WebGLUniformLocation, not a number
+ getUniformLocation(name){
+ var loc = null;
+ var activeInfo = this.activeInfosObject[name];
+ if(activeInfo && !activeInfo.isAttribute){
+ loc = activeInfo.loc;
+ }
+ return loc;
+ }
+
+ //VertexAttributeState
+ getVertexAttrib(){
+ /*VERTEX_ATTRIB_ARRAY_ENABLED
+ VERTEX_ATTRIB_ARRAY_SIZE
+ VERTEX_ATTRIB_ARRAY_STRIDE
+ VERTEX_ATTRIB_ARRAY_TYPE
+ VERTEX_ATTRIB_ARRAY_NORMALIZED
+ VERTEX_ATTRIB_ARRAY_BUFFER_BINDING
+ CURRENT_VERTEX_ATTRIB*/
+ }
+
+ //Return the uniform value at the passed location in the passed program.
+ //The type returned is dependent on the uniform type.
+ getUniform(name){
+ var result = null;
+ var loc = this.getUniformLocation(name);
+ if(loc){
+ result = Kernel.gl.getUniform(this.program, loc);
+ }
+ return result;
+ }
+
+ enableVertexAttribArray(name){
+ var activeInfo = this.activeInfosObject[name];
+ if(activeInfo && activeInfo.isAttribute && activeInfo.isEnabled !== true){
+ var loc = activeInfo.loc;
+ Kernel.gl.enableVertexAttribArray(loc);
+ activeInfo.isEnabled = true;
+ }
+ }
+
+ disableVertexAttribArray(name){
+ var activeInfo = this.activeInfosObject[name];
+ if(activeInfo && activeInfo.isAttribute && activeInfo.isEnabled !== false){
+ var loc = activeInfo.loc;
+ Kernel.gl.disableVertexAttribArray(loc);
+ activeInfo.isEnabled = false;
+ }
+ }
+
+ _init(){
+ var vs = this._getShader(Kernel.gl.VERTEX_SHADER, this.vs);
+ if(!vs){
+ return;
+ }
+
+ var fs = this._getShader(Kernel.gl.FRAGMENT_SHADER, this.fs);
+ if(!fs){
+ return;
+ }
+
+ this.program = Kernel.gl.createProgram();
+ Kernel.gl.attachShader(this.program, vs);
+ Kernel.gl.attachShader(this.program, fs);
+ Kernel.gl.linkProgram(this.program);
+
+ if (!Kernel.gl.getProgramParameter(this.program, Kernel.gl.LINK_STATUS)) {
+ console.error("Could not link program!");
+ Kernel.gl.deleteProgram(this.program);
+ Kernel.gl.deleteShader(vs);
+ Kernel.gl.deleteShader(fs);
+ this.program = null;
+ return;
+ }
+
+ this.updateActiveAttribInfos();
+ this.updateActiveUniformInfos();
+ this.ready = true;
+ }
+
+ _getShader(shaderType, shaderText){
+ var shader = Kernel.gl.createShader(shaderType);
+ Kernel.gl.shaderSource(shader, shaderText);
+ Kernel.gl.compileShader(shader);
+
+ if(!Kernel.gl.getShaderParameter(shader, Kernel.gl.COMPILE_STATUS)){
+ console.error("create shader failed", Kernel.gl.getShaderInfoLog(shader));
+ Kernel.gl.deleteShader(shader);
+ return null;
+ }
+
+ return shader;
+ }
+}
+
+export = Program;
\ No newline at end of file
diff --git a/src/world/ProgramUtils.ts b/src/world/ProgramUtils.ts
new file mode 100644
index 0000000..ed95f5e
--- /dev/null
+++ b/src/world/ProgramUtils.ts
@@ -0,0 +1,31 @@
+///
+
+import Program = require("./Program");
+import Graphic = require("./graphics/Graphic");
+
+const programs:Program[] = [];
+
+const ProgramUtils = {
+
+ getProgram(graphic){
+ var program:Program = null;
+
+ var programType = graphic.getProgramType();
+
+ programs.some(function(item){
+ if(item.type === graphic.type){
+ program = item;
+ return true;
+ }else{
+ return false;
+ }
+ });
+
+ if(!program){
+ program = graphic.createProgram();
+ this.programs.push(program);
+ }
+
+ return program;
+ }
+};
\ No newline at end of file
diff --git a/src/world/geometries/Geometry.ts b/src/world/geometries/Geometry.ts
index 22a1940..8a37f21 100644
--- a/src/world/geometries/Geometry.ts
+++ b/src/world/geometries/Geometry.ts
@@ -2,18 +2,20 @@
import Kernel = require("../Kernel");
import Vertice = require("./Vertice");
import Triangle = require("./Triangle");
+import Object3D = require("../Object3D");
import VertexBufferObject = require("../VertexBufferObject");
-class Geometry {
+class Geometry extends Object3D {
vertices: Vertice[];
triangles: Triangle[];
- vbo: any;
- ibo: any;
- nbo: any;
- uvbo: any;
- cbo: any;
+ vbo: VertexBufferObject;
+ ibo: VertexBufferObject;
+ nbo: VertexBufferObject;
+ uvbo: VertexBufferObject;
+ cbo: VertexBufferObject;
constructor() {
+ super();
this.buildTriangles();
}
@@ -129,19 +131,19 @@ class Geometry {
destroy() {
if (this.vbo) {
- Kernel.gl.deleteBuffer(this.vbo);
+ this.vbo.destroy();
}
if (this.ibo) {
- Kernel.gl.deleteBuffer(this.ibo);
+ this.ibo.destroy();
}
if (this.nbo) {
- Kernel.gl.deleteBuffer(this.nbo);
+ this.nbo.destroy();
}
if (this.cbo) {
- Kernel.gl.deleteBuffer(this.cbo);
+ this.cbo.destroy();
}
if (this.uvbo) {
- Kernel.gl.deleteBuffer(this.uvbo);
+ this.uvbo.destroy();
}
this.vbo = null;
@@ -154,8 +156,4 @@ class Geometry {
}
}
-//world.geometries._Geometry.prototype = new world._Object3D();
-
-//world.geometries._Geometry.prototype.constructor = world.geometries._Geometry;
-
export = Geometry;
\ No newline at end of file
diff --git a/src/world/graphics/Graphic.ts b/src/world/graphics/Graphic.ts
index 1622d86..6f1ed93 100644
--- a/src/world/graphics/Graphic.ts
+++ b/src/world/graphics/Graphic.ts
@@ -3,6 +3,8 @@
import Kernel = require("../Kernel");
import Geometry = require("../geometries/Geometry");
import Material = require("../materials/Material");
+import Program = require("../Program");
+import PerspectiveCamera = require("../PerspectiveCamera");
interface GraphicOptions{
geometry: Geometry;
@@ -11,7 +13,7 @@ interface GraphicOptions{
visible?: boolean;
}
-class Graphic{
+abstract class Graphic{
id:number;
ready: boolean = false;
visible: boolean = true;
@@ -30,27 +32,18 @@ class Graphic{
return this.material.getType();
}
- //need to be override
- createProgram(): any{
- return null;
+ isDrawable(): boolean{
+ if(!this.visible || !this.material.isReady() || !this.ready){
+ return false;
+ }
+ return true;
}
- // onBeforeDraw(){}
-
- // _draw(program, camera, scene){
- // if(!program || !this.visible || !this.isReady || !this.material.isReady){
- // return;
- // }
-
- // this.onBeforeDraw(program, camera, scene);
- // this.draw(program, camera, scene);
- // this.onAfterDraw(program, camera, scene);
- // }
+ //need to be override
+ abstract createProgram(): Program
// //need to be override
- // draw(){}
-
- // onAfterDraw(){}
+ abstract draw(program: Program, camera: PerspectiveCamera)
destroy(){
this.parent = null;
diff --git a/src/world/graphics/MeshGraphic.ts b/src/world/graphics/MeshGraphic.ts
index 10408fa..cf2bbd3 100644
--- a/src/world/graphics/MeshGraphic.ts
+++ b/src/world/graphics/MeshGraphic.ts
@@ -1,9 +1,11 @@
///
import Kernel = require("../Kernel");
+import Program = require("../Program");
import Graphic = require("./Graphic");
import Geometry = require("../geometries/Geometry");
import MeshTextureMaterial = require("../materials/MeshTextureMaterial");
+import PerspectiveCamera = require("../PerspectiveCamera");
const vs =
`
@@ -40,11 +42,15 @@ class MeshGraphic extends Graphic {
this.ready = true;
}
+ createProgram(): Program{
+ return new Program(this.getProgramType(), vs, fs);
+ }
+
_init4TextureMaterial() {
this.geometry.calculateUVBO();
}
- _drawTextureMaterial(program) {
+ _drawTextureMaterial(program: any) {
//set aUV
var locUV = program.getAttribLocation('aUV');
program.enableVertexAttribArray('aUV');
@@ -59,46 +65,32 @@ class MeshGraphic extends Graphic {
Kernel.gl.uniform1i(locSampler, 0);
}
- // createProgram(scene) {
- // var program = null;
- // var programType = this.getProgramType(scene);
- // var args = {
- // type: programType,
- // definesObject: null,
- // vsSource: vs,
- // fsSource: fs
- // };
- // program = new world.Program(args);
-
- // return program;
- // }
-
- // draw(program, camera, scene) {
- // //aPosition
- // var locPosition = program.getAttribLocation('aPosition');
- // program.enableVertexAttribArray('aPosition');
- // this.geometry.vbo.bind();
- // Kernel.gl.vertexAttribPointer(locPosition, 3, Kernel.gl.FLOAT, false, 0, 0);
-
- // //uPMVMatrix
- // var pmvMatrix = camera.projViewMatrix.multiplyMatrix(this.geometry.matrix);
- // var locPMVMatrix = program.getUniformLocation('uPMVMatrix');
- // Kernel.gl.uniformMatrix4fv(locPMVMatrix, false, pmvMatrix.elements);
-
- // this._drawTextureMaterial(program);
-
- // //设置索引,但不用往shader中赋值
- // this.geometry.ibo.bind();
-
- // //绘图
- // var count = this.geometry.triangles.length * 3;
- // Kernel.gl.drawElements(Kernel.gl.TRIANGLES, count, Kernel.gl.UNSIGNED_SHORT, 0);
-
- // //释放当前绑定对象
- // Kernel.gl.bindBuffer(Kernel.gl.ARRAY_BUFFER, null);
- // Kernel.gl.bindBuffer(Kernel.gl.ELEMENT_ARRAY_BUFFER, null);
- // Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, null);
- // }
+ draw(program: Program, camera: PerspectiveCamera) {
+ //aPosition
+ var locPosition = program.getAttribLocation('aPosition');
+ program.enableVertexAttribArray('aPosition');
+ this.geometry.vbo.bind();
+ Kernel.gl.vertexAttribPointer(locPosition, 3, Kernel.gl.FLOAT, false, 0, 0);
+
+ //uPMVMatrix
+ var pmvMatrix = camera.projViewMatrix.multiplyMatrix(this.geometry.matrix);
+ var locPMVMatrix = program.getUniformLocation('uPMVMatrix');
+ Kernel.gl.uniformMatrix4fv(locPMVMatrix, false, pmvMatrix.elements);
+
+ this._drawTextureMaterial(program);
+
+ //设置索引,但不用往shader中赋值
+ this.geometry.ibo.bind();
+
+ //绘图
+ var count = this.geometry.triangles.length * 3;
+ Kernel.gl.drawElements(Kernel.gl.TRIANGLES, count, Kernel.gl.UNSIGNED_SHORT, 0);
+
+ //释放当前绑定对象
+ Kernel.gl.bindBuffer(Kernel.gl.ARRAY_BUFFER, null);
+ Kernel.gl.bindBuffer(Kernel.gl.ELEMENT_ARRAY_BUFFER, null);
+ Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, null);
+ }
}
export = MeshGraphic;
\ No newline at end of file
From 4864f82b48b4a8dac83197e35f8b680e2a71053b Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Wed, 26 Oct 2016 12:41:38 +0800
Subject: [PATCH 008/109] update refactor
---
src/world/GraphicGroup.ts | 76 +++++++++++++++++++++++++++++++
src/world/ProgramUtils.ts | 10 ++--
src/world/graphics/Graphic.ts | 16 +++++--
src/world/graphics/MeshGraphic.ts | 10 ++--
4 files changed, 99 insertions(+), 13 deletions(-)
create mode 100644 src/world/GraphicGroup.ts
diff --git a/src/world/GraphicGroup.ts b/src/world/GraphicGroup.ts
new file mode 100644
index 0000000..0417d68
--- /dev/null
+++ b/src/world/GraphicGroup.ts
@@ -0,0 +1,76 @@
+///
+import Kernel = require("./Kernel");
+import Graphic = require("./graphics/Graphic");
+import PerspectiveCamera = require("./PerspectiveCamera");
+
+type Drawable = Graphic | GraphicGroup;
+
+class GraphicGroup{
+ id: number;
+ parent: GraphicGroup;
+ children: Drawable[];
+ visible: boolean = true;
+
+ constructor(){
+ this.id = ++Kernel.idCounter;
+ this.children = [];
+ }
+
+ add(g: Drawable){
+ this.children.push(g);
+ g.parent = this;
+ }
+
+ remove(g: Drawable){
+ var findResult = this.findGraphicById(g.id);
+ if(findResult){
+ g.destroy();
+ this.children.splice(findResult.index, 1);
+ g = null;
+ }
+ }
+
+ clear(){
+ var i = 0, length = this.children.length, g:Drawable = null;
+ for(; i < length; i++){
+ g = this.children[i];
+ g.destroy();
+ }
+ this.children = [];
+ }
+
+ destroy(){
+ this.parent = null;
+ this.clear();
+ }
+
+ findGraphicById(graphicId: number){
+ var i = 0, length = this.children.length, g:Drawable = null;
+ for(; i < length; i++){
+ g = this.children[i];
+ if(g.id === graphicId){
+ return {
+ index: i,
+ graphic: g
+ };
+ }
+ }
+ return null;
+ }
+
+ isDrawable(){
+ return this.visible;
+ }
+
+ draw(camera: PerspectiveCamera){
+ if(this.isDrawable()){
+ this.children.forEach(function(g: Drawable){
+ if(g.isDrawable()){
+ g.draw(camera);
+ }
+ });
+ }
+ }
+}
+
+export = GraphicGroup;
\ No newline at end of file
diff --git a/src/world/ProgramUtils.ts b/src/world/ProgramUtils.ts
index ed95f5e..a93f62b 100644
--- a/src/world/ProgramUtils.ts
+++ b/src/world/ProgramUtils.ts
@@ -1,4 +1,4 @@
-///
+///
import Program = require("./Program");
import Graphic = require("./graphics/Graphic");
@@ -7,13 +7,13 @@ const programs:Program[] = [];
const ProgramUtils = {
- getProgram(graphic){
+ getProgram(graphic: Graphic){
var program:Program = null;
var programType = graphic.getProgramType();
programs.some(function(item){
- if(item.type === graphic.type){
+ if(item.type === graphic.getProgramType()){
program = item;
return true;
}else{
@@ -28,4 +28,6 @@ const ProgramUtils = {
return program;
}
-};
\ No newline at end of file
+};
+
+export = ProgramUtils;
\ No newline at end of file
diff --git a/src/world/graphics/Graphic.ts b/src/world/graphics/Graphic.ts
index 6f1ed93..657bb4d 100644
--- a/src/world/graphics/Graphic.ts
+++ b/src/world/graphics/Graphic.ts
@@ -4,6 +4,7 @@ import Kernel = require("../Kernel");
import Geometry = require("../geometries/Geometry");
import Material = require("../materials/Material");
import Program = require("../Program");
+import ProgramUtils = require("../ProgramUtils");
import PerspectiveCamera = require("../PerspectiveCamera");
interface GraphicOptions{
@@ -18,16 +19,20 @@ abstract class Graphic{
ready: boolean = false;
visible: boolean = true;
parent: any;
+ program: Program;
constructor(public geometry: Geometry, public material: Material){
this.id = ++Kernel.idCounter;
this.parent = null;
+ this.program = ProgramUtils.getProgram(this);
}
setVisible(visible: boolean){
this.visible = visible;
}
+ abstract createProgram(): Program
+
getProgramType() {
return this.material.getType();
}
@@ -39,11 +44,14 @@ abstract class Graphic{
return true;
}
- //need to be override
- abstract createProgram(): Program
+ draw(camera: PerspectiveCamera){
+ if(this.isDrawable()){
+ this.program.use();
+ this.onDraw(camera);
+ }
+ }
- // //need to be override
- abstract draw(program: Program, camera: PerspectiveCamera)
+ abstract onDraw(camera: PerspectiveCamera)
destroy(){
this.parent = null;
diff --git a/src/world/graphics/MeshGraphic.ts b/src/world/graphics/MeshGraphic.ts
index cf2bbd3..b917025 100644
--- a/src/world/graphics/MeshGraphic.ts
+++ b/src/world/graphics/MeshGraphic.ts
@@ -65,19 +65,19 @@ class MeshGraphic extends Graphic {
Kernel.gl.uniform1i(locSampler, 0);
}
- draw(program: Program, camera: PerspectiveCamera) {
+ onDraw(camera: PerspectiveCamera) {
//aPosition
- var locPosition = program.getAttribLocation('aPosition');
- program.enableVertexAttribArray('aPosition');
+ var locPosition = this.program.getAttribLocation('aPosition');
+ this.program.enableVertexAttribArray('aPosition');
this.geometry.vbo.bind();
Kernel.gl.vertexAttribPointer(locPosition, 3, Kernel.gl.FLOAT, false, 0, 0);
//uPMVMatrix
var pmvMatrix = camera.projViewMatrix.multiplyMatrix(this.geometry.matrix);
- var locPMVMatrix = program.getUniformLocation('uPMVMatrix');
+ var locPMVMatrix = this.program.getUniformLocation('uPMVMatrix');
Kernel.gl.uniformMatrix4fv(locPMVMatrix, false, pmvMatrix.elements);
- this._drawTextureMaterial(program);
+ this._drawTextureMaterial(this.program);
//设置索引,但不用往shader中赋值
this.geometry.ibo.bind();
From 1de06440134ab8ccadbdd29300a50da053b18339 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Wed, 26 Oct 2016 12:49:15 +0800
Subject: [PATCH 009/109] update ts files
---
src/world/PerspectiveCamera.ts | 1 +
src/world/Program.ts | 22 +++++++++++-----------
src/world/graphics/Graphic.ts | 2 +-
3 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/src/world/PerspectiveCamera.ts b/src/world/PerspectiveCamera.ts
index 1e92d06..858e646 100644
--- a/src/world/PerspectiveCamera.ts
+++ b/src/world/PerspectiveCamera.ts
@@ -15,6 +15,7 @@ class PerspectiveCamera extends Object3D {
pitch: number;
viewMatrix: Matrix;
projMatrix: Matrix;
+ projViewMatrix: Matrix;
Enum: any = {
EARTH_FULL_OVERSPREAD_SCREEN: "EARTH_FULL_OVERSPREAD_SCREEN", //Canvas内全部被地球充满
EARTH_NOT_FULL_OVERSPREAD_SCREEN: "EARTH_NOT_FULL_OVERSPREAD_SCREEN" //Canvas没有全部被地球充满
diff --git a/src/world/Program.ts b/src/world/Program.ts
index e5ef5a5..831b59e 100644
--- a/src/world/Program.ts
+++ b/src/world/Program.ts
@@ -25,7 +25,7 @@ class Program{
updateActiveAttribInfos(){
var count = Kernel.gl.getProgramParameter(this.program, Kernel.gl.ACTIVE_ATTRIBUTES);
- for(var i = 0, activeInfo; i < count; i++){
+ for(var i = 0, activeInfo: any; i < count; i++){
activeInfo = Kernel.gl.getActiveAttrib(this.program, i);
activeInfo.loc = Kernel.gl.getAttribLocation(this.program, activeInfo.name);
activeInfo.isAttribute = true;
@@ -36,7 +36,7 @@ class Program{
updateActiveUniformInfos(){
var count = Kernel.gl.getProgramParameter(this.program, Kernel.gl.ACTIVE_UNIFORMS);
- for(var i = 0, activeInfo; i < count; i++){
+ for(var i = 0, activeInfo: any; i < count; i++){
activeInfo = Kernel.gl.getActiveUniform(this.program, i);
activeInfo.loc = Kernel.gl.getUniformLocation(this.program, activeInfo.name);
activeInfo.isAttribute = false;
@@ -44,7 +44,7 @@ class Program{
}
}
- getLocation(name){
+ getLocation(name: string){
//loc = gl.getAttribLocation(this.program, name);
//loc = gl.getUniformLocation(this.program, name);
var loc = -1;
@@ -55,7 +55,7 @@ class Program{
return loc;
}
- getAttribLocation(name){
+ getAttribLocation(name: string){
var loc = -1;
var activeInfo = this.activeInfosObject[name];
if(activeInfo && activeInfo.isAttribute){
@@ -65,8 +65,8 @@ class Program{
}
//return WebGLUniformLocation, not a number
- getUniformLocation(name){
- var loc = null;
+ getUniformLocation(name: string){
+ var loc: WebGLUniformLocation;
var activeInfo = this.activeInfosObject[name];
if(activeInfo && !activeInfo.isAttribute){
loc = activeInfo.loc;
@@ -87,8 +87,8 @@ class Program{
//Return the uniform value at the passed location in the passed program.
//The type returned is dependent on the uniform type.
- getUniform(name){
- var result = null;
+ getUniform(name:string){
+ var result: any;
var loc = this.getUniformLocation(name);
if(loc){
result = Kernel.gl.getUniform(this.program, loc);
@@ -96,7 +96,7 @@ class Program{
return result;
}
- enableVertexAttribArray(name){
+ enableVertexAttribArray(name:string){
var activeInfo = this.activeInfosObject[name];
if(activeInfo && activeInfo.isAttribute && activeInfo.isEnabled !== true){
var loc = activeInfo.loc;
@@ -105,7 +105,7 @@ class Program{
}
}
- disableVertexAttribArray(name){
+ disableVertexAttribArray(name:string){
var activeInfo = this.activeInfosObject[name];
if(activeInfo && activeInfo.isAttribute && activeInfo.isEnabled !== false){
var loc = activeInfo.loc;
@@ -144,7 +144,7 @@ class Program{
this.ready = true;
}
- _getShader(shaderType, shaderText){
+ _getShader(shaderType:number, shaderText:string){
var shader = Kernel.gl.createShader(shaderType);
Kernel.gl.shaderSource(shader, shaderText);
Kernel.gl.compileShader(shader);
diff --git a/src/world/graphics/Graphic.ts b/src/world/graphics/Graphic.ts
index 657bb4d..eaf1e35 100644
--- a/src/world/graphics/Graphic.ts
+++ b/src/world/graphics/Graphic.ts
@@ -51,7 +51,7 @@ abstract class Graphic{
}
}
- abstract onDraw(camera: PerspectiveCamera)
+ abstract onDraw(camera: PerspectiveCamera):void
destroy(){
this.parent = null;
From 0fa4e4911f4776db0cc171b97f2d8bee9789c50c Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Wed, 26 Oct 2016 13:27:34 +0800
Subject: [PATCH 010/109] update refactor
---
src/world/Tile.ts | 55 ++++++++++++++--------
src/world/graphics/MeshGraphic.ts | 6 +--
src/world/materials/MeshTextureMaterial.ts | 3 +-
3 files changed, 37 insertions(+), 27 deletions(-)
diff --git a/src/world/Tile.ts b/src/world/Tile.ts
index eabf42f..80036c9 100644
--- a/src/world/Tile.ts
+++ b/src/world/Tile.ts
@@ -1,17 +1,19 @@
///
import Kernel = require('./Kernel');
-import Object3D = require('./Object3D');
import Enum = require('./Enum');
import Elevation = require('./Elevation');
import MathUtils = require('./math/Math');
+import MeshGraphic = require('./graphics/MeshGraphic');
import TileMaterial = require('./TileMaterial');
+import Geometry = require("./geometries/Geometry");
-class Tile extends Object3D {
- level: number = 0;
- row: number = 0;
- column: number = 0;
- url: string;
- subTiledLayer: any;
+class TileGeometry extends Geometry{
+ buildTriangles(){
+
+ }
+}
+
+class TileInfo{
//type如果是GLOBE_TILE,表示其buffer已经设置为一般形式
//type如果是TERRAIN_TILE,表示其buffer已经设置为高程形式
//type如果是UNKNOWN,表示buffer没设置
@@ -28,19 +30,7 @@ class Tile extends Object3D {
segment: number = 1;
elevationInfo: any = null;
- //args中包含level、row、column、url即可
- constructor(args: any) {
- super(null);
- this.createVerticeData(args);
- }
-
- createVerticeData(args: any) {
- if (!args) {
- return;
- }
- this.setTileInfo(args);
- this.checkTerrain();
- }
+ constructor(public level: number, public row: number, public column: number, public url: string){}
// 根据传入的切片的层级以及行列号信息设置切片的经纬度范围 以及设置其纹理
setTileInfo(args: any) {
@@ -68,6 +58,31 @@ class Tile extends Object3D {
};
this.material = new TileMaterial(matArgs);
}
+}
+
+class Tile extends MeshGraphic {
+ subTiledLayer: any;
+
+
+ //args中包含level、row、column、url即可
+ constructor(public geometry: Geometry, public material: MeshTextureMaterial) {
+ super(geometry, material);
+ // this.createVerticeData(args);
+ }
+
+ static getTile(){
+
+ }
+
+ createVerticeData(args: any) {
+ if (!args) {
+ return;
+ }
+ this.setTileInfo(args);
+ this.checkTerrain();
+ }
+
+
/**
* 判断是否满足现实Terrain的条件,若满足则转换为三维地形
diff --git a/src/world/graphics/MeshGraphic.ts b/src/world/graphics/MeshGraphic.ts
index b917025..f9efd0c 100644
--- a/src/world/graphics/MeshGraphic.ts
+++ b/src/world/graphics/MeshGraphic.ts
@@ -38,7 +38,7 @@ class MeshGraphic extends Graphic {
super(geometry, material);
this.geometry.calculateVBO();
this.geometry.calculateIBO();
- this._init4TextureMaterial();
+ this.geometry.calculateUVBO();
this.ready = true;
}
@@ -46,10 +46,6 @@ class MeshGraphic extends Graphic {
return new Program(this.getProgramType(), vs, fs);
}
- _init4TextureMaterial() {
- this.geometry.calculateUVBO();
- }
-
_drawTextureMaterial(program: any) {
//set aUV
var locUV = program.getAttribLocation('aUV');
diff --git a/src/world/materials/MeshTextureMaterial.ts b/src/world/materials/MeshTextureMaterial.ts
index 2719bff..456e325 100644
--- a/src/world/materials/MeshTextureMaterial.ts
+++ b/src/world/materials/MeshTextureMaterial.ts
@@ -16,8 +16,6 @@ class MeshTextureMaterial extends Material {
this.setImage(args.image);
} else if (typeof args.url === "string") {
this.setImageUrl(args.url);
- } else {
- throw 'Invalid parameter';
}
}
@@ -39,6 +37,7 @@ class MeshTextureMaterial extends Material {
setImageUrl(url: string) {
this.image = new Image();
this.image.crossOrigin = 'anonymous';//很重要,因为图片是跨域获得的,所以一定要加上此句代码
+ this.ready = false;
this.image.onload = this._onLoad.bind(this);
this.image.src = url;
}
From 0be901a5e799f0d2ae484d3fc016f468d14b4ac7 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Wed, 26 Oct 2016 18:05:29 +0800
Subject: [PATCH 011/109] update refactor
---
src/world/TextureMaterial.ts | 6 +-
src/world/Tile.ts | 245 -------------------------------
src/world/geometries/Box.ts | 7 +-
src/world/geometries/Geometry.ts | 5 -
src/world/graphics/Tile.ts | 226 ++++++++++++++++++++++++++++
5 files changed, 233 insertions(+), 256 deletions(-)
delete mode 100644 src/world/Tile.ts
create mode 100644 src/world/graphics/Tile.ts
diff --git a/src/world/TextureMaterial.ts b/src/world/TextureMaterial.ts
index c571314..308108e 100644
--- a/src/world/TextureMaterial.ts
+++ b/src/world/TextureMaterial.ts
@@ -24,14 +24,14 @@ class TextureMaterial {
this.image = image;
this.onLoad();
}
- };
-
+ }
+
setImageUrl(url: string): void {
this.image = new Image();
this.image.crossOrigin = 'anonymous'; //很重要,因为图片是跨域获得的,所以一定要加上此句代码
this.image.onload = this.onLoad.bind(this);
this.image.src = url;
- };
+ }
//图片加载完成时触发
onLoad(): void {
diff --git a/src/world/Tile.ts b/src/world/Tile.ts
deleted file mode 100644
index 80036c9..0000000
--- a/src/world/Tile.ts
+++ /dev/null
@@ -1,245 +0,0 @@
-///
-import Kernel = require('./Kernel');
-import Enum = require('./Enum');
-import Elevation = require('./Elevation');
-import MathUtils = require('./math/Math');
-import MeshGraphic = require('./graphics/MeshGraphic');
-import TileMaterial = require('./TileMaterial');
-import Geometry = require("./geometries/Geometry");
-
-class TileGeometry extends Geometry{
- buildTriangles(){
-
- }
-}
-
-class TileInfo{
- //type如果是GLOBE_TILE,表示其buffer已经设置为一般形式
- //type如果是TERRAIN_TILE,表示其buffer已经设置为高程形式
- //type如果是UNKNOWN,表示buffer没设置
- type: number = Enum.UNKNOWN;
- elevationLevel: number = 0;//高程level
- minLon: number = null;
- minLat: number = null;
- maxLon: number = null;
- maxLat: number = null;
- minX: number = null;
- minY: number = null;
- maxX: number = null;
- maxY: number = null;
- segment: number = 1;
- elevationInfo: any = null;
-
- constructor(public level: number, public row: number, public column: number, public url: string){}
-
- // 根据传入的切片的层级以及行列号信息设置切片的经纬度范围 以及设置其纹理
- setTileInfo(args: any) {
- this.level = args.level;
- this.row = args.row;
- this.column = args.column;
- this.url = args.url;
- this.elevationLevel = Elevation.getAncestorElevationLevel(this.level);
- //经纬度范围
- var Egeo = MathUtils.getTileGeographicEnvelopByGrid(this.level, this.row, this.column);
- this.minLon = Egeo.minLon;
- this.minLat = Egeo.minLat;
- this.maxLon = Egeo.maxLon;
- this.maxLat = Egeo.maxLat;
- var minCoord = MathUtils.degreeGeographicToWebMercator(this.minLon, this.minLat);
- var maxCoord = MathUtils.degreeGeographicToWebMercator(this.maxLon, this.maxLat);
- //投影坐标范围
- this.minX = minCoord[0];
- this.minY = minCoord[1];
- this.maxX = maxCoord[0];
- this.maxY = maxCoord[1];
- var matArgs = {
- level: this.level,
- url: this.url
- };
- this.material = new TileMaterial(matArgs);
- }
-}
-
-class Tile extends MeshGraphic {
- subTiledLayer: any;
-
-
- //args中包含level、row、column、url即可
- constructor(public geometry: Geometry, public material: MeshTextureMaterial) {
- super(geometry, material);
- // this.createVerticeData(args);
- }
-
- static getTile(){
-
- }
-
- createVerticeData(args: any) {
- if (!args) {
- return;
- }
- this.setTileInfo(args);
- this.checkTerrain();
- }
-
-
-
- /**
- * 判断是否满足现实Terrain的条件,若满足则转换为三维地形
- * 条件:
- * 1.当前显示的是GlobeTile
- * 2.该切片的level大于TERRAIN_LEVEL
- * 3.pich不为90
- * 4.当前切片的高程数据存在
- * 5.如果bForce为true,则表示强制显示为三维,不考虑level
- */
- checkTerrain(bForce: boolean = false) {
- var globe = Kernel.globe;
- var a = bForce === true ? true : this.level >= Kernel.TERRAIN_LEVEL;
- var shouldShowTerrain = this.type != Enum.TERRAIN_TILE && a && globe && globe.camera && globe.camera.pitch != 90;
- if (shouldShowTerrain) {
- //应该以TerrainTile显示
- if (!this.elevationInfo) {
- this.elevationInfo = Elevation.getExactElevation(this.level, this.row, this.column);
-
- // if(this.level - this.elevationLevel == 1){
- // //当该level与其elevationLevel只相差一级时,可以使用推倒的高程数据
- // this.elevationInfo = Elevation.getElevation(this.level,this.row,this.column);
- // if(this.elevationInfo){
- // console.log("Tile("+this.level+","+this.row+","+this.column+");sourceLevel:"+this.elevationInfo.sourceLevel+";elevationLevel:"+this.elevationLevel);
- // }
- // }
- // else{
- // //否则使用准确的高程数据
- // this.elevationInfo = Elevation.getExactElevation(this.level,this.row,this.column);
- // }
- }
- var canShowTerrain = this.elevationInfo ? true : false;
- if (canShowTerrain) {
- //能够显示为TerrainTile
- this.handleTerrainTile();
- } else {
- //不能够显示为TerrainTile
- this.visible = false;
- //this.handleGlobeTile();
- }
- } else {
- if (this.type == Enum.UNKNOWN) {
- //初始type为UNKNOWN,还未初始化buffer,应该显示为GlobeTile
- this.handleGlobeTile();
- }
- }
- }
-
- //处理球面的切片
- handleGlobeTile() {
- this.type = Enum.GLOBE_TILE;
- if (this.level < Kernel.BASE_LEVEL) {
- var changeLevel = Kernel.BASE_LEVEL - this.level;
- this.segment = Math.pow(2, changeLevel);
- } else {
- this.segment = 1;
- }
- this.handleTile();
- }
-
- //处理地形的切片
- handleTerrainTile() {
- this.type = Enum.TERRAIN_TILE;
- this.segment = 10;
- this.handleTile();
- };
-
- //如果是GlobeTile,那么elevations为null
- //如果是TerrainTile,那么elevations是一个一维数组,大小是(segment+1)*(segment+1)
- handleTile() {
- this.visible = true;
- var vertices:number[] = [];
- var indices:number[] = [];
- var textureCoords:number[] = [];
-
- var deltaX = (this.maxX - this.minX) / this.segment;
- var deltaY = (this.maxY - this.minY) / this.segment;
- var deltaTextureCoord = 1.0 / this.segment;
- var changeElevation = this.type == Enum.TERRAIN_TILE && this.elevationInfo;
- //level不同设置的半径也不同
- var levelDeltaR = 0; //this.level * 100;
- //对WebMercator投影进行等间距划分格网
- var mercatorXs:number[] = []; //存储从最小的x到最大x的分割值
- var mercatorYs:number[] = []; //存储从最大的y到最小的y的分割值
- var textureSs:number[] = []; //存储从0到1的s的分割值
- var textureTs:number[] = []; //存储从1到0的t的分割值
- var i:number, j:number;
-
- for (i = 0; i <= this.segment; i++) {
- mercatorXs.push(this.minX + i * deltaX);
- mercatorYs.push(this.maxY - i * deltaY);
- var b = i * deltaTextureCoord;
- textureSs.push(b);
- textureTs.push(1 - b);
- }
- //从左上到右下遍历填充vertices和textureCoords:从最上面一行开始自左向右遍历一行,然后再以相同的方式遍历下面一行
- for (i = 0; i <= this.segment; i++) {
- for (j = 0; j <= this.segment; j++) {
- var merX = mercatorXs[j];
- var merY = mercatorYs[i];
- var ele = changeElevation ? this.elevationInfo.elevations[(this.segment + 1) * i + j] : 0;
- var lonlat = MathUtils.webMercatorToDegreeGeographic(merX, merY);
- var p = MathUtils.geographicToCartesianCoord(lonlat[0], lonlat[1], Kernel.EARTH_RADIUS + ele + levelDeltaR).getArray();
- vertices = vertices.concat(p); //顶点坐标
- textureCoords = textureCoords.concat(textureSs[j], textureTs[i]); //纹理坐标
- }
- }
-
- //从左上到右下填充indices
- //添加的点的顺序:左上->左下->右下->右上
- //0 1 2; 2 3 0;
- /*对于一个面从外面向里面看的绘制顺序
- * 0 3
- *
- * 1 2*/
- for (i = 0; i < this.segment; i++) {
- for (j = 0; j < this.segment; j++) {
- var idx0 = (this.segment + 1) * i + j;
- var idx1 = (this.segment + 1) * (i + 1) + j;
- var idx2 = idx1 + 1;
- var idx3 = idx0 + 1;
- indices = indices.concat(idx0, idx1, idx2); // 0 1 2
- indices = indices.concat(idx2, idx3, idx0); // 2 3 0
- }
- }
-
- // if(changeElevation){
- // //添加坐标原点的数据
- // var originVertice = [0,0,0];
- // var originTexture = [0,0];
- // vertices = vertices.concat(originVertice);
- // textureCoords = textureCoords.concat(originTexture);
- //
- // var idxOrigin = (this.segment+1)*(this.segment+1);
- // var idxLeftTop = 0;
- // var idxRightTop = this.segment;
- // var idxRightBottom = (this.segment+1)*(this.segment+1)-1;
- // var idxLeftBottom = idxRightBottom - this.segment;
- // indices = indices.concat(idxLeftTop,idxOrigin,idxLeftBottom);
- // indices = indices.concat(idxRightTop,idxOrigin,idxLeftTop);
- // indices = indices.concat(idxRightBottom,idxOrigin,idxRightTop);
- // indices = indices.concat(idxLeftBottom,idxOrigin,idxRightBottom);
- // }
-
- var infos = {
- vertices: vertices,
- indices: indices,
- textureCoords: textureCoords
- };
- this.setBuffers(infos);
- }
-
- //重写Object3D的destroy方法
- destroy() {
- super.destroy();
- this.subTiledLayer = null;
- }
-}
-
-export = Tile;
\ No newline at end of file
diff --git a/src/world/geometries/Box.ts b/src/world/geometries/Box.ts
index 21e8300..184b50e 100644
--- a/src/world/geometries/Box.ts
+++ b/src/world/geometries/Box.ts
@@ -7,6 +7,7 @@ import Geometry = require("./Geometry");
class Box extends Geometry {
constructor(public length: number, public width: number, public height: number) {
super();
+ this.buildTriangles();
}
buildTriangles() {
@@ -22,9 +23,9 @@ class Box extends Geometry {
/ | / |
F1----F3 |
| B2- |--B4
- |/ | /
- F2----F4
- */
+ |/ | /
+ F2----F4
+ */
//前面四个顶点
var vF1 = [-halfLength, halfHeight, halfWidth]; //前面左上角点 F1,索引0
diff --git a/src/world/geometries/Geometry.ts b/src/world/geometries/Geometry.ts
index 8a37f21..efdf4f5 100644
--- a/src/world/geometries/Geometry.ts
+++ b/src/world/geometries/Geometry.ts
@@ -14,11 +14,6 @@ class Geometry extends Object3D {
uvbo: VertexBufferObject;
cbo: VertexBufferObject;
- constructor() {
- super();
- this.buildTriangles();
- }
-
//set vertices and triangles
buildTriangles(){
this.vertices = [];
diff --git a/src/world/graphics/Tile.ts b/src/world/graphics/Tile.ts
new file mode 100644
index 0000000..5def207
--- /dev/null
+++ b/src/world/graphics/Tile.ts
@@ -0,0 +1,226 @@
+///
+import Kernel = require('../Kernel');
+import Enum = require('../Enum');
+import Elevation = require('../Elevation');
+import MathUtils = require('../math/Math');
+import MeshGraphic = require('../graphics/MeshGraphic');
+import MeshTextureMaterial = require('../materials/MeshTextureMaterial');
+import Geometry = require("../geometries/Geometry");
+import Vertice = require("../geometries/Vertice");
+import Triangle = require("../geometries/Triangle");
+
+class TileGeometry extends Geometry{
+ constructor(public tileInfo: TileInfo){
+ super();
+ }
+
+ buildTriangles(){
+
+ }
+}
+
+class TileInfo{
+ //type如果是GLOBE_TILE,表示其buffer已经设置为一般形式
+ //type如果是TERRAIN_TILE,表示其buffer已经设置为高程形式
+ //type如果是UNKNOWN,表示buffer没设置
+ type: number = Enum.UNKNOWN;
+ elevationLevel: number = 0;//高程level
+ minLon: number = null;
+ minLat: number = null;
+ maxLon: number = null;
+ maxLat: number = null;
+ minX: number = null;
+ minY: number = null;
+ maxX: number = null;
+ maxY: number = null;
+ segment: number = 1;
+ elevationInfo: any = null;
+ geometry: TileGeometry;
+ material: MeshTextureMaterial;
+
+ constructor(public level: number, public row: number, public column: number, public url: string){
+ this._setTileInfo();
+ this._createGeometry();
+ this._createMaterial();
+ }
+
+ // 根据传入的切片的层级以及行列号信息设置切片的经纬度范围 以及设置其纹理
+ _setTileInfo() {
+ this.elevationLevel = Elevation.getAncestorElevationLevel(this.level);
+ //经纬度范围
+ var Egeo = MathUtils.getTileGeographicEnvelopByGrid(this.level, this.row, this.column);
+ this.minLon = Egeo.minLon;
+ this.minLat = Egeo.minLat;
+ this.maxLon = Egeo.maxLon;
+ this.maxLat = Egeo.maxLat;
+ var minCoord = MathUtils.degreeGeographicToWebMercator(this.minLon, this.minLat);
+ var maxCoord = MathUtils.degreeGeographicToWebMercator(this.maxLon, this.maxLat);
+ //投影坐标范围
+ this.minX = minCoord[0];
+ this.minY = minCoord[1];
+ this.maxX = maxCoord[0];
+ this.maxY = maxCoord[1];
+ }
+
+ _createGeometry(){
+ this.geometry = null;
+ }
+
+ _createMaterial(){
+ var matArgs = {
+ level: this.level,
+ url: this.url
+ };
+ this.material = new MeshTextureMaterial(matArgs);
+ }
+}
+
+class Tile extends MeshGraphic {
+ subTiledLayer: any;
+
+ private constructor(public geometry: TileGeometry, public material: MeshTextureMaterial, public tileInfo: TileInfo) {
+ super(geometry, material);
+ }
+
+ static getTile(level: number, row: number, column: number, url: string){
+ var tileInfo = new TileInfo(level, row, column, url);
+ return new Tile(tileInfo.geometry, tileInfo.material, tileInfo);
+ }
+
+ // createVerticeData(args: any) {
+ // if (!args) {
+ // return;
+ // }
+ // this.setTileInfo(args);
+ // this.checkTerrain();
+ // }
+
+ /**
+ * 判断是否满足现实Terrain的条件,若满足则转换为三维地形
+ * 条件:
+ * 1.当前显示的是GlobeTile
+ * 2.该切片的level大于TERRAIN_LEVEL
+ * 3.pich不为90
+ * 4.当前切片的高程数据存在
+ * 5.如果bForce为true,则表示强制显示为三维,不考虑level
+ */
+ checkTerrain(bForce: boolean = false) {
+ // var globe = Kernel.globe;
+ // var a = bForce === true ? true : this.tileInfo.level >= Kernel.TERRAIN_LEVEL;
+ // var shouldShowTerrain = this.tileInfo.type != Enum.TERRAIN_TILE && a && globe && globe.camera && globe.camera.pitch != 90;
+ // if (shouldShowTerrain) {
+ // //应该以TerrainTile显示
+ // if (!this.tileInfo.elevationInfo) {
+ // this.tileInfo.elevationInfo = Elevation.getExactElevation(this.tileInfo.level, this.tileInfo.row, this.tileInfo.column);
+ // }
+ // var canShowTerrain = this.tileInfo.elevationInfo ? true : false;
+ // if (canShowTerrain) {
+ // //能够显示为TerrainTile
+ // this.handleTerrainTile();
+ // } else {
+ // //不能够显示为TerrainTile
+ // this.visible = false;
+ // //this.handleGlobeTile();
+ // }
+ // } else {
+ // if (this.tileInfo.type == Enum.UNKNOWN) {
+ // //初始type为UNKNOWN,还未初始化buffer,应该显示为GlobeTile
+ // this.handleGlobeTile();
+ // }
+ // }
+ }
+
+ //处理球面的切片
+ handleGlobeTile() {
+ this.tileInfo.type = Enum.GLOBE_TILE;
+ if (this.tileInfo.level < Kernel.BASE_LEVEL) {
+ var changeLevel = Kernel.BASE_LEVEL - this.tileInfo.level;
+ this.tileInfo.segment = Math.pow(2, changeLevel);
+ } else {
+ this.tileInfo.segment = 1;
+ }
+ this.handleTile();
+ }
+
+ //处理地形的切片
+ handleTerrainTile() {
+ this.tileInfo.type = Enum.TERRAIN_TILE;
+ this.tileInfo.segment = 10;
+ this.handleTile();
+ };
+
+ //如果是GlobeTile,那么elevations为null
+ //如果是TerrainTile,那么elevations是一个一维数组,大小是(segment+1)*(segment+1)
+ handleTile() {
+ this.visible = true;
+ var vertices:number[] = [];
+ var indices:number[] = [];
+ var textureCoords:number[] = [];
+
+ var deltaX = (this.tileInfo.maxX - this.tileInfo.minX) / this.tileInfo.segment;
+ var deltaY = (this.tileInfo.maxY - this.tileInfo.minY) / this.tileInfo.segment;
+ var deltaTextureCoord = 1.0 / this.tileInfo.segment;
+ var changeElevation = this.tileInfo.type == Enum.TERRAIN_TILE && this.tileInfo.elevationInfo;
+ //level不同设置的半径也不同
+ var levelDeltaR = 0; //this.level * 100;
+ //对WebMercator投影进行等间距划分格网
+ var mercatorXs:number[] = []; //存储从最小的x到最大x的分割值
+ var mercatorYs:number[] = []; //存储从最大的y到最小的y的分割值
+ var textureSs:number[] = []; //存储从0到1的s的分割值
+ var textureTs:number[] = []; //存储从1到0的t的分割值
+ var i:number, j:number;
+
+ for (i = 0; i <= this.tileInfo.segment; i++) {
+ mercatorXs.push(this.tileInfo.minX + i * deltaX);
+ mercatorYs.push(this.tileInfo.maxY - i * deltaY);
+ var b = i * deltaTextureCoord;
+ textureSs.push(b);
+ textureTs.push(1 - b);
+ }
+ //从左上到右下遍历填充vertices和textureCoords:从最上面一行开始自左向右遍历一行,然后再以相同的方式遍历下面一行
+ for (i = 0; i <= this.tileInfo.segment; i++) {
+ for (j = 0; j <= this.tileInfo.segment; j++) {
+ var merX = mercatorXs[j];
+ var merY = mercatorYs[i];
+ var ele = changeElevation ? this.tileInfo.elevationInfo.elevations[(this.tileInfo.segment + 1) * i + j] : 0;
+ var lonlat = MathUtils.webMercatorToDegreeGeographic(merX, merY);
+ var p = MathUtils.geographicToCartesianCoord(lonlat[0], lonlat[1], Kernel.EARTH_RADIUS + ele + levelDeltaR).getArray();
+ vertices = vertices.concat(p); //顶点坐标
+ textureCoords = textureCoords.concat(textureSs[j], textureTs[i]); //纹理坐标
+ }
+ }
+
+ //从左上到右下填充indices
+ //添加的点的顺序:左上->左下->右下->右上
+ //0 1 2; 2 3 0;
+ /*对于一个面从外面向里面看的绘制顺序
+ * 0 3
+ *
+ * 1 2*/
+ for (i = 0; i < this.tileInfo.segment; i++) {
+ for (j = 0; j < this.tileInfo.segment; j++) {
+ var idx0 = (this.tileInfo.segment + 1) * i + j;
+ var idx1 = (this.tileInfo.segment + 1) * (i + 1) + j;
+ var idx2 = idx1 + 1;
+ var idx3 = idx0 + 1;
+ indices = indices.concat(idx0, idx1, idx2); // 0 1 2
+ indices = indices.concat(idx2, idx3, idx0); // 2 3 0
+ }
+ }
+
+ var infos = {
+ vertices: vertices,
+ indices: indices,
+ textureCoords: textureCoords
+ };
+ // this.setBuffers(infos);
+ }
+
+ //重写Object3D的destroy方法
+ destroy() {
+ super.destroy();
+ this.subTiledLayer = null;
+ }
+}
+
+export = Tile;
\ No newline at end of file
From fd2ddd91d1832c50584cf8183896654fcdfe256e Mon Sep 17 00:00:00 2001
From: iSpring
Date: Wed, 26 Oct 2016 21:37:15 +0800
Subject: [PATCH 012/109] update refactor
---
src/world/graphics/Graphic.ts | 11 +-
src/world/graphics/Tile.ts | 214 +++++++++++++++++++---------------
2 files changed, 122 insertions(+), 103 deletions(-)
diff --git a/src/world/graphics/Graphic.ts b/src/world/graphics/Graphic.ts
index eaf1e35..392349f 100644
--- a/src/world/graphics/Graphic.ts
+++ b/src/world/graphics/Graphic.ts
@@ -16,7 +16,6 @@ interface GraphicOptions{
abstract class Graphic{
id:number;
- ready: boolean = false;
visible: boolean = true;
parent: any;
program: Program;
@@ -37,11 +36,12 @@ abstract class Graphic{
return this.material.getType();
}
+ isReady(): boolean{
+ return this.geometry && this.material && this.material.isReady();
+ }
+
isDrawable(): boolean{
- if(!this.visible || !this.material.isReady() || !this.ready){
- return false;
- }
- return true;
+ return this.visible && this.isReady();
}
draw(camera: PerspectiveCamera){
@@ -60,7 +60,6 @@ abstract class Graphic{
this.material.destroy();
this.geometry = null;
this.material = null;
- this.ready = false;
}
}
diff --git a/src/world/graphics/Tile.ts b/src/world/graphics/Tile.ts
index 5def207..328e547 100644
--- a/src/world/graphics/Tile.ts
+++ b/src/world/graphics/Tile.ts
@@ -9,17 +9,17 @@ import Geometry = require("../geometries/Geometry");
import Vertice = require("../geometries/Vertice");
import Triangle = require("../geometries/Triangle");
-class TileGeometry extends Geometry{
- constructor(public tileInfo: TileInfo){
+class TileGeometry extends Geometry {
+ constructor(public vertices: Vertice[], public triangles: Triangle[]) {
super();
}
- buildTriangles(){
+ // buildTriangles() {
- }
+ // }
}
-class TileInfo{
+class TileInfo {
//type如果是GLOBE_TILE,表示其buffer已经设置为一般形式
//type如果是TERRAIN_TILE,表示其buffer已经设置为高程形式
//type如果是UNKNOWN,表示buffer没设置
@@ -37,9 +37,11 @@ class TileInfo{
elevationInfo: any = null;
geometry: TileGeometry;
material: MeshTextureMaterial;
+ visible: boolean;
- constructor(public level: number, public row: number, public column: number, public url: string){
+ constructor(public level: number, public row: number, public column: number, public url: string) {
this._setTileInfo();
+ this._checkTerrain();
this._createGeometry();
this._createMaterial();
}
@@ -47,6 +49,7 @@ class TileInfo{
// 根据传入的切片的层级以及行列号信息设置切片的经纬度范围 以及设置其纹理
_setTileInfo() {
this.elevationLevel = Elevation.getAncestorElevationLevel(this.level);
+
//经纬度范围
var Egeo = MathUtils.getTileGeographicEnvelopByGrid(this.level, this.row, this.column);
this.minLon = Egeo.minLon;
@@ -55,6 +58,7 @@ class TileInfo{
this.maxLat = Egeo.maxLat;
var minCoord = MathUtils.degreeGeographicToWebMercator(this.minLon, this.minLat);
var maxCoord = MathUtils.degreeGeographicToWebMercator(this.maxLon, this.maxLat);
+
//投影坐标范围
this.minX = minCoord[0];
this.minY = minCoord[1];
@@ -62,38 +66,17 @@ class TileInfo{
this.maxY = maxCoord[1];
}
- _createGeometry(){
+ _createGeometry() {
this.geometry = null;
}
- _createMaterial(){
+ _createMaterial() {
var matArgs = {
level: this.level,
url: this.url
};
this.material = new MeshTextureMaterial(matArgs);
}
-}
-
-class Tile extends MeshGraphic {
- subTiledLayer: any;
-
- private constructor(public geometry: TileGeometry, public material: MeshTextureMaterial, public tileInfo: TileInfo) {
- super(geometry, material);
- }
-
- static getTile(level: number, row: number, column: number, url: string){
- var tileInfo = new TileInfo(level, row, column, url);
- return new Tile(tileInfo.geometry, tileInfo.material, tileInfo);
- }
-
- // createVerticeData(args: any) {
- // if (!args) {
- // return;
- // }
- // this.setTileInfo(args);
- // this.checkTerrain();
- // }
/**
* 判断是否满足现实Terrain的条件,若满足则转换为三维地形
@@ -104,91 +87,103 @@ class Tile extends MeshGraphic {
* 4.当前切片的高程数据存在
* 5.如果bForce为true,则表示强制显示为三维,不考虑level
*/
- checkTerrain(bForce: boolean = false) {
- // var globe = Kernel.globe;
- // var a = bForce === true ? true : this.tileInfo.level >= Kernel.TERRAIN_LEVEL;
- // var shouldShowTerrain = this.tileInfo.type != Enum.TERRAIN_TILE && a && globe && globe.camera && globe.camera.pitch != 90;
- // if (shouldShowTerrain) {
- // //应该以TerrainTile显示
- // if (!this.tileInfo.elevationInfo) {
- // this.tileInfo.elevationInfo = Elevation.getExactElevation(this.tileInfo.level, this.tileInfo.row, this.tileInfo.column);
- // }
- // var canShowTerrain = this.tileInfo.elevationInfo ? true : false;
- // if (canShowTerrain) {
- // //能够显示为TerrainTile
- // this.handleTerrainTile();
- // } else {
- // //不能够显示为TerrainTile
- // this.visible = false;
- // //this.handleGlobeTile();
- // }
- // } else {
- // if (this.tileInfo.type == Enum.UNKNOWN) {
- // //初始type为UNKNOWN,还未初始化buffer,应该显示为GlobeTile
- // this.handleGlobeTile();
- // }
- // }
+ _checkTerrain(bForce: boolean = false) {
+ var globe = Kernel.globe;
+ var a = bForce === true ? true : this.level >= Kernel.TERRAIN_LEVEL;
+ var shouldShowTerrain = this.type != Enum.TERRAIN_TILE && a && globe && globe.camera && globe.camera.pitch != 90;
+ if (shouldShowTerrain) {
+ //应该以TerrainTile显示
+ if (!this.elevationInfo) {
+ this.elevationInfo = Elevation.getExactElevation(this.level, this.row, this.column);
+ }
+ var canShowTerrain = this.elevationInfo ? true : false;
+ if (canShowTerrain) {
+ //能够显示为TerrainTile
+ this._handleTerrainTile();
+ } else {
+ //不能够显示为TerrainTile
+ this.visible = false;
+ //this.handleGlobeTile();
+ }
+ } else {
+ if (this.type == Enum.UNKNOWN) {
+ //初始type为UNKNOWN,还未初始化buffer,应该显示为GlobeTile
+ this._handleGlobeTile();
+ }
+ }
}
//处理球面的切片
- handleGlobeTile() {
- this.tileInfo.type = Enum.GLOBE_TILE;
- if (this.tileInfo.level < Kernel.BASE_LEVEL) {
- var changeLevel = Kernel.BASE_LEVEL - this.tileInfo.level;
- this.tileInfo.segment = Math.pow(2, changeLevel);
+ _handleGlobeTile() {
+ this.type = Enum.GLOBE_TILE;
+ if (this.level < Kernel.BASE_LEVEL) {
+ var changeLevel = Kernel.BASE_LEVEL - this.level;
+ this.segment = Math.pow(2, changeLevel);
} else {
- this.tileInfo.segment = 1;
+ this.segment = 1;
}
- this.handleTile();
+ this._handleTile();
}
//处理地形的切片
- handleTerrainTile() {
- this.tileInfo.type = Enum.TERRAIN_TILE;
- this.tileInfo.segment = 10;
- this.handleTile();
- };
+ _handleTerrainTile() {
+ this.type = Enum.TERRAIN_TILE;
+ this.segment = 10;
+ this._handleTile();
+ }
//如果是GlobeTile,那么elevations为null
//如果是TerrainTile,那么elevations是一个一维数组,大小是(segment+1)*(segment+1)
- handleTile() {
+ _handleTile() {
this.visible = true;
- var vertices:number[] = [];
- var indices:number[] = [];
- var textureCoords:number[] = [];
-
- var deltaX = (this.tileInfo.maxX - this.tileInfo.minX) / this.tileInfo.segment;
- var deltaY = (this.tileInfo.maxY - this.tileInfo.minY) / this.tileInfo.segment;
- var deltaTextureCoord = 1.0 / this.tileInfo.segment;
- var changeElevation = this.tileInfo.type == Enum.TERRAIN_TILE && this.tileInfo.elevationInfo;
+ var verticeArray: Vertice[] = [];
+ var triangleArray: Triangle[] = [];
+ var vertices: number[] = [];
+ var indices: number[] = [];
+ var textureCoords: number[] = [];
+
+ var deltaX = (this.maxX - this.minX) / this.segment;
+ var deltaY = (this.maxY - this.minY) / this.segment;
+ var deltaTextureCoord = 1.0 / this.segment;
+ var changeElevation = this.type === Enum.TERRAIN_TILE && this.elevationInfo;
//level不同设置的半径也不同
var levelDeltaR = 0; //this.level * 100;
//对WebMercator投影进行等间距划分格网
- var mercatorXs:number[] = []; //存储从最小的x到最大x的分割值
- var mercatorYs:number[] = []; //存储从最大的y到最小的y的分割值
- var textureSs:number[] = []; //存储从0到1的s的分割值
- var textureTs:number[] = []; //存储从1到0的t的分割值
- var i:number, j:number;
-
- for (i = 0; i <= this.tileInfo.segment; i++) {
- mercatorXs.push(this.tileInfo.minX + i * deltaX);
- mercatorYs.push(this.tileInfo.maxY - i * deltaY);
+ var mercatorXs: number[] = []; //存储从最小的x到最大x的分割值
+ var mercatorYs: number[] = []; //存储从最大的y到最小的y的分割值
+ var textureSs: number[] = []; //存储从0到1的s的分割值
+ var textureTs: number[] = []; //存储从1到0的t的分割值
+ var i: number, j: number;
+
+ for (i = 0; i <= this.segment; i++) {
+ mercatorXs.push(this.minX + i * deltaX);
+ mercatorYs.push(this.maxY - i * deltaY);
var b = i * deltaTextureCoord;
textureSs.push(b);
textureTs.push(1 - b);
}
- //从左上到右下遍历填充vertices和textureCoords:从最上面一行开始自左向右遍历一行,然后再以相同的方式遍历下面一行
- for (i = 0; i <= this.tileInfo.segment; i++) {
- for (j = 0; j <= this.tileInfo.segment; j++) {
+
+ //从左上到右下遍历填充vertices和textureCoords
+ //从最上面一行开始自左向右遍历一行,然后再以相同的方式遍历下面一行
+ var index = 0;
+ for (i = 0; i <= this.segment; i++) {
+ for (j = 0; j <= this.segment; j++) {
var merX = mercatorXs[j];
var merY = mercatorYs[i];
- var ele = changeElevation ? this.tileInfo.elevationInfo.elevations[(this.tileInfo.segment + 1) * i + j] : 0;
+ var ele = changeElevation ? this.elevationInfo.elevations[(this.segment + 1) * i + j] : 0;
var lonlat = MathUtils.webMercatorToDegreeGeographic(merX, merY);
var p = MathUtils.geographicToCartesianCoord(lonlat[0], lonlat[1], Kernel.EARTH_RADIUS + ele + levelDeltaR).getArray();
vertices = vertices.concat(p); //顶点坐标
textureCoords = textureCoords.concat(textureSs[j], textureTs[i]); //纹理坐标
+ var v = new Vertice({
+ p: p,
+ i: index,
+ uv: [textureSs[j], textureTs[i]]
+ });
+ verticeArray.push(v);
+ index++;
}
- }
+ }
//从左上到右下填充indices
//添加的点的顺序:左上->左下->右下->右上
@@ -197,23 +192,48 @@ class Tile extends MeshGraphic {
* 0 3
*
* 1 2*/
- for (i = 0; i < this.tileInfo.segment; i++) {
- for (j = 0; j < this.tileInfo.segment; j++) {
- var idx0 = (this.tileInfo.segment + 1) * i + j;
- var idx1 = (this.tileInfo.segment + 1) * (i + 1) + j;
+ for (i = 0; i < this.segment; i++) {
+ for (j = 0; j < this.segment; j++) {
+ var idx0 = (this.segment + 1) * i + j;
+ var idx1 = (this.segment + 1) * (i + 1) + j;
var idx2 = idx1 + 1;
var idx3 = idx0 + 1;
indices = indices.concat(idx0, idx1, idx2); // 0 1 2
indices = indices.concat(idx2, idx3, idx0); // 2 3 0
+ var v0: Vertice = verticeArray[idx0];
+ var v1: Vertice = verticeArray[idx1];
+ var v2: Vertice = verticeArray[idx2];
+ var v3: Vertice = verticeArray[idx3];
+ var triangle1 = new Triangle(v0, v1, v2);
+ var triangle2 = new Triangle(v2, v3, v0);
+ triangleArray.concat(triangle1, triangle2);
}
}
- var infos = {
- vertices: vertices,
- indices: indices,
- textureCoords: textureCoords
- };
+ // var infos = {
+ // vertices: vertices,
+ // indices: indices,
+ // textureCoords: textureCoords
+ // };
// this.setBuffers(infos);
+ this.geometry = new TileGeometry(verticeArray, triangleArray);
+ }
+}
+
+class Tile extends MeshGraphic {
+ subTiledLayer: any;
+
+ constructor(public geometry: TileGeometry, public material: MeshTextureMaterial, public tileInfo: TileInfo) {
+ super(geometry, material);
+ }
+
+ static getTile(level: number, row: number, column: number, url: string) {
+ var tileInfo = new TileInfo(level, row, column, url);
+ return new Tile(tileInfo.geometry, tileInfo.material, tileInfo);
+ }
+
+ isDrawable(){
+ return this.tileInfo.visible && super.isDrawable();
}
//重写Object3D的destroy方法
From ecb14350899b475cf2515f98c29e34ca49099957 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Wed, 26 Oct 2016 22:37:41 +0800
Subject: [PATCH 013/109] update refactor
---
src/world/TileMaterial.ts | 30 -------
src/world/geometries/TileGeometry.ts | 13 +++
src/world/graphics/MeshGraphic.ts | 9 +-
src/world/graphics/Tile.ts | 12 +--
src/world/layers/SubTiledLayer.ts | 41 ++++------
src/world/materials/MeshTextureMaterial.ts | 82 ++++++++++++++-----
src/world/materials/TileMaterial.ts | 24 ++++++
.../__TextureMaterial.ts} | 0
8 files changed, 122 insertions(+), 89 deletions(-)
delete mode 100644 src/world/TileMaterial.ts
create mode 100644 src/world/geometries/TileGeometry.ts
create mode 100644 src/world/materials/TileMaterial.ts
rename src/world/{TextureMaterial.ts => materials/__TextureMaterial.ts} (100%)
diff --git a/src/world/TileMaterial.ts b/src/world/TileMaterial.ts
deleted file mode 100644
index f56afa1..0000000
--- a/src/world/TileMaterial.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-///
-import TextureMaterial= require('./TextureMaterial');
-import ImageUtils = require('./Image');
-
-class TileMaterial extends TextureMaterial{
- level: number;
-
- constructor(args?: any){
- super(args);
- if (args) {
- if (!args.image && typeof args.url === "string") {
- var tileImage = ImageUtils.get(args.url);
- if (tileImage) {
- args.image = tileImage;
- delete args.url;
- }
- }
- this.level = typeof args.level == "number" && args.level >= 0 ? args.level : 20;
- }
- }
-
- onLoad() {
- if (this.level <= ImageUtils.MAX_LEVEL) {
- ImageUtils.add(this.image.src, this.image);
- }
- super.onLoad();
- }
-}
-
-export = TileMaterial;
\ No newline at end of file
diff --git a/src/world/geometries/TileGeometry.ts b/src/world/geometries/TileGeometry.ts
new file mode 100644
index 0000000..e9f1c3e
--- /dev/null
+++ b/src/world/geometries/TileGeometry.ts
@@ -0,0 +1,13 @@
+///
+
+import Vertice = require("./Vertice");
+import Triangle = require("./Triangle");
+import Geometry = require("./Geometry");
+
+class TileGeometry extends Geometry {
+ constructor(public vertices: Vertice[], public triangles: Triangle[]) {
+ super();
+ }
+}
+
+export = TileGeometry;
\ No newline at end of file
diff --git a/src/world/graphics/MeshGraphic.ts b/src/world/graphics/MeshGraphic.ts
index f9efd0c..61c6925 100644
--- a/src/world/graphics/MeshGraphic.ts
+++ b/src/world/graphics/MeshGraphic.ts
@@ -39,7 +39,14 @@ class MeshGraphic extends Graphic {
this.geometry.calculateVBO();
this.geometry.calculateIBO();
this.geometry.calculateUVBO();
- this.ready = true;
+ }
+
+ isGeometryReady():boolean{
+ return !!this.geometry.vbo && !!this.geometry.ibo && !!this.geometry.uvbo;
+ }
+
+ isReady():boolean{
+ return this.isGeometryReady() && super.isReady();
}
createProgram(): Program{
diff --git a/src/world/graphics/Tile.ts b/src/world/graphics/Tile.ts
index 328e547..0a681ef 100644
--- a/src/world/graphics/Tile.ts
+++ b/src/world/graphics/Tile.ts
@@ -5,20 +5,10 @@ import Elevation = require('../Elevation');
import MathUtils = require('../math/Math');
import MeshGraphic = require('../graphics/MeshGraphic');
import MeshTextureMaterial = require('../materials/MeshTextureMaterial');
-import Geometry = require("../geometries/Geometry");
+import TileGeometry = require("../geometries/TileGeometry");
import Vertice = require("../geometries/Vertice");
import Triangle = require("../geometries/Triangle");
-class TileGeometry extends Geometry {
- constructor(public vertices: Vertice[], public triangles: Triangle[]) {
- super();
- }
-
- // buildTriangles() {
-
- // }
-}
-
class TileInfo {
//type如果是GLOBE_TILE,表示其buffer已经设置为一般形式
//type如果是TERRAIN_TILE,表示其buffer已经设置为高程形式
diff --git a/src/world/layers/SubTiledLayer.ts b/src/world/layers/SubTiledLayer.ts
index 06d424c..cb48b8b 100644
--- a/src/world/layers/SubTiledLayer.ts
+++ b/src/world/layers/SubTiledLayer.ts
@@ -3,11 +3,11 @@ import Kernel = require('../Kernel');
import Utils = require('../Utils');
import MathUtils = require('../math/Math');
import TileGrid = require('../TileGrid');
-import Object3DComponents = require('../Object3DComponents');
-import Tile = require('../Tile');
+import GraphicGroup = require('../GraphicGroup');
+import Tile = require('../graphics/Tile');
import Elevation = require('../Elevation');
-class SubTiledLayer extends Object3DComponents {
+class SubTiledLayer extends GraphicGroup {
level: number = -1;
//该级要请求的高程数据的层级,7[8,9,10];10[11,12,13];13[14,15,16];16[17,18,19]
elevationLevel = -1;
@@ -33,21 +33,12 @@ class SubTiledLayer extends Object3DComponents {
//重写Object3DComponents的add方法
add(tile: Tile) {
- if (tile.level === this.level) {
+ if (tile.tileInfo.level === this.level) {
super.add(tile);
tile.subTiledLayer = this;
}
}
- //调用其父的getImageUrl
- // getImageUrl(level: number, row: number, column: number) {
- // var url = "";
- // if (this.tiledLayer) {
- // url = this.tiledLayer.getImageUrl(level, row, column);
- // }
- // return url;
- // }
-
//重写Object3DComponents的destroy方法
destroy() {
super.destroy();
@@ -59,7 +50,7 @@ class SubTiledLayer extends Object3DComponents {
var length = this.children.length;
for (var i = 0; i < length; i++) {
var tile = this.children[i];
- if (tile.level === level && tile.row === row && tile.column === column) {
+ if (tile.tileInfo.level === level && tile.tileInfo.row === row && tile.tileInfo.column === column) {
return tile;
}
}
@@ -91,7 +82,7 @@ class SubTiledLayer extends Object3DComponents {
var i:number, tile:Tile;
for (i = 0; i < this.children.length; i++) {
tile = this.children[i];
- var checkResult = checkTileExist(visibleTileGrids, tile.level, tile.row, tile.column);
+ var checkResult = checkTileExist(visibleTileGrids, tile.tileInfo.level, tile.tileInfo.row, tile.tileInfo.column);
var isExist = checkResult.isExist;
if (isExist) {
visibleTileGrids.splice(checkResult.index, 1); //已处理
@@ -121,7 +112,7 @@ class SubTiledLayer extends Object3DComponents {
url: ""
};
args.url = this.tiledLayer.getImageUrl(args.level, args.row, args.column);
- tile = new Tile(args);
+ tile = Tile.getTile(args.level, args.row, args.column, args.url);
this.add(tile);
}
}
@@ -129,15 +120,15 @@ class SubTiledLayer extends Object3DComponents {
//如果bForce为true,则表示强制显示为三维,不考虑level
checkTerrain(bForce:boolean = false) {
- var globe = Kernel.globe;
- var show3d = bForce === true ? true : this.level >= Kernel.TERRAIN_LEVEL;
- if (show3d && globe && globe.camera && globe.camera.pitch < Kernel.TERRAIN_PITCH) {
- var tiles = this.children;
- for (var i = 0; i < tiles.length; i++) {
- var tile = tiles[i];
- tile.checkTerrain(bForce);
- }
- }
+ // var globe = Kernel.globe;
+ // var show3d = bForce === true ? true : this.level >= Kernel.TERRAIN_LEVEL;
+ // if (show3d && globe && globe.camera && globe.camera.pitch < Kernel.TERRAIN_PITCH) {
+ // var tiles = this.children;
+ // for (var i = 0; i < tiles.length; i++) {
+ // var tile = tiles[i];
+ // tile.checkTerrain(bForce);
+ // }
+ // }
}
//根据当前子图层下的tiles获取其对应的祖先高程切片的TileGrid //getAncestorElevationTileGrids
diff --git a/src/world/materials/MeshTextureMaterial.ts b/src/world/materials/MeshTextureMaterial.ts
index 456e325..be62153 100644
--- a/src/world/materials/MeshTextureMaterial.ts
+++ b/src/world/materials/MeshTextureMaterial.ts
@@ -2,20 +2,21 @@
import Kernel = require("../Kernel");
import MathUtils = require("../math/Math");
import Material = require("./Material");
+import ImageUtils = require('../Image');
+
+type ImageType = HTMLImageElement | string;
class MeshTextureMaterial extends Material {
texture: WebGLTexture;
image: HTMLImageElement;
url: string;
- ready: boolean = false;
- isDelete: boolean = false;
+ private ready:boolean = false;
+ private deleted: boolean = false;
- constructor(args: any) {
+ constructor(imageOrUrl?: ImageType) {
super();
- if (args.image instanceof Image && args.image.width > 0 && args.image.height > 0) {
- this.setImage(args.image);
- } else if (typeof args.url === "string") {
- this.setImageUrl(args.url);
+ if(imageOrUrl){
+ this.setImageOrUrl(imageOrUrl);
}
}
@@ -23,34 +24,52 @@ class MeshTextureMaterial extends Material {
return "MeshTextureMaterial";
}
- isReady(){
+ isReady(): boolean{
return this.ready;
}
+ setImageOrUrl(imageOrUrl?: ImageType){
+ if(!imageOrUrl){
+ return;
+ }
+ if (imageOrUrl instanceof Image && imageOrUrl.width > 0 && imageOrUrl.height > 0) {
+ this.setImage(imageOrUrl);
+ } else if (typeof imageOrUrl === "string") {
+ this.setImageUrl(imageOrUrl);
+ }
+ }
+
setImage(image: HTMLImageElement) {
if (image.width > 0 && image.height > 0) {
+ this.ready = false;
this.image = image;
- this._onLoad();
+ this.onLoad();
}
}
setImageUrl(url: string) {
- this.image = new Image();
- this.image.crossOrigin = 'anonymous';//很重要,因为图片是跨域获得的,所以一定要加上此句代码
- this.ready = false;
- this.image.onload = this._onLoad.bind(this);
- this.image.src = url;
+ var tileImage = ImageUtils.get(url);
+ if(tileImage){
+ this.setImage(tileImage);
+ }else{
+ this.ready = false;
+ this.image = new Image();
+ //很重要,因为图片是跨域获得的,所以一定要加上此句代码
+ this.image.crossOrigin = 'anonymous';
+ this.image.onload = this.onLoad.bind(this);
+ this.image.src = url;
+ }
}
//图片加载完成时触发
- _onLoad() {
+ onLoad() {
//要考虑纹理已经被移除掉了图片才进入onLoad这种情况
- if (this.isDelete) {
+ if (this.deleted) {
return;
}
Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, this.texture);
- //gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true);
+ Kernel.gl.pixelStorei(Kernel.gl.UNPACK_FLIP_Y_WEBGL, +true);
Kernel.gl.texImage2D(Kernel.gl.TEXTURE_2D, 0, Kernel.gl.RGBA, Kernel.gl.RGBA, Kernel.gl.UNSIGNED_BYTE, this.image);
@@ -60,28 +79,47 @@ class MeshTextureMaterial extends Material {
//使用MipMap
Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);
Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);//LINEAR_MIPMAP_LINEAR
+
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
+
Kernel.gl.generateMipmap(Kernel.gl.TEXTURE_2D);
} else {
Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR);//gl.NEAREST
Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR);//gl.NEAREST
- }
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
+ }
Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, null);
this.ready = true;
}
+ // test(){
+ // Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, this.texture);
+ // Kernel.gl.pixelStorei(Kernel.gl.UNPACK_FLIP_Y_WEBGL, +true);
+
+ // Kernel.gl.texImage2D(Kernel.gl.TEXTURE_2D, 0, Kernel.gl.RGBA, Kernel.gl.RGBA, Kernel.gl.UNSIGNED_BYTE, this.image);
+ // //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
+ // //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
+ // //使用MipMap
+ // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);
+ // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR); //LINEAR_MIPMAP_NEAREST LINEAR_MIPMAP_LINEAR
+ // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
+ // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
+ // Kernel.gl.generateMipmap(Kernel.gl.TEXTURE_2D);
+ // Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, null);
+ // }
+
//释放显卡中的texture资源
destroy() {
if (Kernel.gl.isTexture(this.texture)) {
Kernel.gl.deleteTexture(this.texture);
}
this.texture = null;
- this.isDelete = true;
- this.ready = false;
+ this.deleted = true;
}
}
diff --git a/src/world/materials/TileMaterial.ts b/src/world/materials/TileMaterial.ts
new file mode 100644
index 0000000..d67fe46
--- /dev/null
+++ b/src/world/materials/TileMaterial.ts
@@ -0,0 +1,24 @@
+///
+import MeshTextureMaterial= require('./MeshTextureMaterial');
+import ImageUtils = require('../Image');
+
+type ImageType = HTMLImageElement | string;
+
+class TileMaterial extends MeshTextureMaterial{
+ level: number;
+
+ constructor(level: number, imageOrUrl: ImageType){
+ super();
+ this.level = level >= 0 ? level : 20;
+ this.setImageOrUrl(imageOrUrl);
+ }
+
+ onLoad() {
+ if (this.level <= ImageUtils.MAX_LEVEL) {
+ ImageUtils.add(this.image.src, this.image);
+ }
+ super.onLoad();
+ }
+}
+
+export = TileMaterial;
\ No newline at end of file
diff --git a/src/world/TextureMaterial.ts b/src/world/materials/__TextureMaterial.ts
similarity index 100%
rename from src/world/TextureMaterial.ts
rename to src/world/materials/__TextureMaterial.ts
From 66a4e8b668b39f6b0a21fb50acc73c7e66df5b40 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Wed, 26 Oct 2016 23:29:42 +0800
Subject: [PATCH 014/109] update refactor
---
src/world/Globe.ts | 12 +-
src/world/Object3D.ts | 1 -
src/world/Object3DComponents.ts | 140 --------------------
src/world/ProgramUtils.ts | 2 +-
src/world/Renderer.ts | 142 ++++++++++-----------
src/world/Scene.ts | 4 +-
src/world/geometries/TileGeometry.ts | 2 +-
src/world/graphics/MeshGraphic.ts | 40 +++---
src/world/graphics/Tile.ts | 23 +---
src/world/layers/SubTiledLayer.ts | 4 +-
src/world/layers/TiledLayer.ts | 4 +-
src/world/materials/MeshTextureMaterial.ts | 3 +-
src/world/materials/TileMaterial.ts | 2 +-
src/world/materials/__TextureMaterial.ts | 4 +-
14 files changed, 113 insertions(+), 270 deletions(-)
delete mode 100644 src/world/Object3DComponents.ts
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index 3e4488a..39ea305 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -1,13 +1,13 @@
///
import Kernel = require("./Kernel");
import Utils = require("./Utils");
-import ShaderContent = require("./ShaderContent");
+// import ShaderContent = require("./ShaderContent");
import Renderer = require("./Renderer");
import PerspectiveCamera = require("./PerspectiveCamera");
import Scene = require("./Scene");
import TiledLayer = require("./layers/TiledLayer");
import SubTiledLayer = require("./layers/SubTiledLayer");
-import Tile = require("./Tile");
+import Tile = require("./graphics/Tile");
import ImageUtils = require("./Image");
import EventUtils = require("./Event");
@@ -25,9 +25,9 @@ class Globe {
args = args || {};
Kernel.globe = this;
- var vs_content = ShaderContent.SIMPLE_SHADER.VS_CONTENT;
- var fs_content = ShaderContent.SIMPLE_SHADER.FS_CONTENT;
- this.renderer = Kernel.renderer = new Renderer(canvas, vs_content, fs_content);
+ // var vs_content = ShaderContent.SIMPLE_SHADER.VS_CONTENT;
+ // var fs_content = ShaderContent.SIMPLE_SHADER.FS_CONTENT;
+ this.renderer = Kernel.renderer = new Renderer(canvas);
this.scene = new Scene();
var radio = canvas.width / canvas.height;
this.camera = new PerspectiveCamera(30, radio, 1.0, 20000000.0);
@@ -72,7 +72,7 @@ class Globe {
url: ""
};
args.url = this.tiledLayer.getImageUrl(args.level, args.row, args.column);
- var tile = new Tile(args);
+ var tile = Tile.getTile(args.level, args.row, args.column, args.url);
subLayer1.add(tile);
}
}
diff --git a/src/world/Object3D.ts b/src/world/Object3D.ts
index 2b818e2..9f64aa8 100644
--- a/src/world/Object3D.ts
+++ b/src/world/Object3D.ts
@@ -3,7 +3,6 @@ import Kernel = require('./Kernel');
import Matrix = require('./math/Matrix');
import Vertice = require('./math/Vertice');
import Vector = require('./math/Vector');
-import TextureMaterial = require('./TextureMaterial');
class Object3D {
matrix: Matrix;
diff --git a/src/world/Object3DComponents.ts b/src/world/Object3DComponents.ts
deleted file mode 100644
index 7470212..0000000
--- a/src/world/Object3DComponents.ts
+++ /dev/null
@@ -1,140 +0,0 @@
-///
-import Kernel = require('./Kernel');
-import Vector = require('./math/Vector');
-import Matrix = require('./math/Matrix');
-import Object3D = require('./Object3D');
-import Graphic = require('./graphics/Graphic');
-import PerspectiveCamera = require('./PerspectiveCamera');
-
-// type ChildType = Object3D | Object3DComponents;
-
-//三维对象集合
-class Object3DComponents {
- id: number;
- matrix: Matrix;
- visible: boolean;
- parent: any;
- children: Graphic[];
-
- constructor() {
- this.id = ++Kernel.idCounter;
- this.matrix = new Matrix();
- this.visible = true;
- this.parent = null;
- this.children = [];
- }
-
- add(obj: Graphic) {
- if (this.findObjById(obj.id) !== null) {
- console.debug("obj已经存在于Object3DComponents中,无法将其再次加入!");
- return;
- } else {
- this.children.push(obj);
- obj.parent = this;
- }
- }
-
- remove(obj: Graphic) {
- if (obj) {
- var result = this.findObjById(obj.id);
- if (result === null) {
- console.debug("obj不存在于Object3DComponents中,所以无法将其从中删除!");
- return false;
- }
- obj.destroy();
- this.children.splice(result.index, 1);
- obj = null;
- return true;
- } else {
- return false;
- }
- }
-
- //销毁所有的子节点
- clear() {
- for (var i = 0; i < this.children.length; i++) {
- var obj = this.children[i];
- obj.destroy();
- }
- this.children = [];
- }
-
- //销毁自身及其子节点
- destroy() {
- this.parent = null;
- this.clear();
- }
-
- findObjById(objId: number): any {
- for (var i = 0; i < this.children.length; i++) {
- var obj = this.children[i];
- if (obj.id == objId) {
- (obj).index = i;
- return obj;
- }
- }
- return null;
- }
-
- draw(camera: PerspectiveCamera) {
- for (var i = 0; i < this.children.length; i++) {
- var obj = this.children[i];
- if (obj) {
- if (obj.visible) {
- (obj).draw(camera);
- }
- }
- }
- }
-
- worldTranslate(x: number, y: number, z: number) {
- this.matrix.worldTranslate(x, y, z);
- }
-
- localTranslate(x: number, y: number, z: number) {
- this.matrix.localTranslate(x, y, z);
- }
-
- worldScale(scaleX: number, scaleY: number, scaleZ: number) {
- this.matrix.worldScale(scaleX, scaleY, scaleZ);
- }
-
- localScale(scaleX: number, scaleY: number, scaleZ: number) {
- this.matrix.localScale(scaleX, scaleY, scaleZ);
- }
-
- worldRotateX(radian: number) {
- this.matrix.worldRotateX(radian);
- }
-
- worldRotateY(radian: number) {
- this.matrix.worldRotateY(radian);
- }
-
- worldRotateZ(radian: number) {
- this.matrix.worldRotateZ(radian);
- }
-
- worldRotateByVector(radian: number, vector: Vector) {
- this.matrix.worldRotateByVector(radian, vector);
- }
-
- localRotateX(radian: number) {
- this.matrix.localRotateX(radian);
- }
-
- localRotateY(radian: number) {
- this.matrix.localRotateY(radian);
- }
-
- localRotateZ(radian: number) {
- this.matrix.localRotateZ(radian);
- }
-
- //localVector指的是相对于模型坐标系中的向量
- localRotateByVector(radian: number, localVector: Vector) {
- this.matrix.localRotateByVector(radian, localVector);
- }
-}
-
-export = Object3DComponents;
\ No newline at end of file
diff --git a/src/world/ProgramUtils.ts b/src/world/ProgramUtils.ts
index a93f62b..5c74fd4 100644
--- a/src/world/ProgramUtils.ts
+++ b/src/world/ProgramUtils.ts
@@ -23,7 +23,7 @@ const ProgramUtils = {
if(!program){
program = graphic.createProgram();
- this.programs.push(program);
+ programs.push(program);
}
return program;
diff --git a/src/world/Renderer.ts b/src/world/Renderer.ts
index 317b9fb..9c6e599 100644
--- a/src/world/Renderer.ts
+++ b/src/world/Renderer.ts
@@ -10,13 +10,7 @@ class Renderer {
camera: PerspectiveCamera = null;
bAutoRefresh: boolean = false;
- constructor(canvas: HTMLCanvasElement, vertexShaderText: string, fragmentShaderText: string) {
- if (!(vertexShaderText !== "")) {
- throw "invalid vertexShaderText";
- }
- if (!(fragmentShaderText !== "")) {
- throw "invalid fragmentShaderText";
- }
+ constructor(canvas: HTMLCanvasElement) {
//之所以在此处设置Kernel.renderer是因为要在tick函数中使用
Kernel.renderer = this;
@@ -40,71 +34,71 @@ class Renderer {
} catch (e) { }
}
- function getShader(gl: WebGLRenderingContextExtension, shaderType: string, shaderText: string) {
- if (!shaderText) {
- return null;
- }
-
- var shader: WebGLShader = null;
- if (shaderType == "VERTEX_SHADER") {
- shader = gl.createShader(gl.VERTEX_SHADER);
- } else if (shaderType == "FRAGMENT_SHADER") {
- shader = gl.createShader(gl.FRAGMENT_SHADER);
- } else {
- return null;
- }
-
- gl.shaderSource(shader, shaderText);
- gl.compileShader(shader);
-
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- alert(gl.getShaderInfoLog(shader));
- console.error(gl.getShaderInfoLog(shader));
- gl.deleteShader(shader);
- return null;
- }
-
- return shader;
- }
-
- function initShaders(vertexShaderText: string, fragmentShaderText: string) {
- var vertexShader = getShader(Kernel.gl, "VERTEX_SHADER", vertexShaderText);
- var fragmentShader = getShader(Kernel.gl, "FRAGMENT_SHADER", fragmentShaderText);
-
- var shaderProgram = gl.createProgram();
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
-
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- console.error("Could not link program!");
- gl.deleteProgram(shaderProgram);
- gl.deleteShader(vertexShader);
- gl.deleteShader(fragmentShader);
- return;
- }
-
- gl.useProgram(shaderProgram);
- gl.shaderProgram = shaderProgram as WebGLProgramExtension;
- gl.shaderProgram.aVertexPosition = gl.getAttribLocation(gl.shaderProgram, "aVertexPosition");
- gl.shaderProgram.aTextureCoord = gl.getAttribLocation(gl.shaderProgram, "aTextureCoord");
- gl.shaderProgram.uMVMatrix = gl.getUniformLocation(gl.shaderProgram, "uMVMatrix");
- gl.shaderProgram.uPMatrix = gl.getUniformLocation(gl.shaderProgram, "uPMatrix");
- gl.shaderProgram.uSampler = gl.getUniformLocation(gl.shaderProgram, "uSampler"); //纹理采样器
- gl.shaderProgram.uOffScreen = gl.getUniformLocation(gl.shaderProgram, "uOffScreen"); //是否离屏渲染
-
- //设置默认非离屏渲染
- gl.uniform1i(gl.shaderProgram.uOffScreen, 1);
-
- //设置默认值
- var squareArray = [1, 0, 0, 0,
- 0, 1, 0, 0,
- 0, 0, 1, 0,
- 0, 0, 0, 1
- ];
- var squareMatrix = new Float32Array(squareArray); //ArrayBuffer
- gl.uniformMatrix4fv(gl.shaderProgram.uMVMatrix, false, squareMatrix);
- }
+ // function getShader(gl: WebGLRenderingContextExtension, shaderType: string, shaderText: string) {
+ // if (!shaderText) {
+ // return null;
+ // }
+
+ // var shader: WebGLShader = null;
+ // if (shaderType == "VERTEX_SHADER") {
+ // shader = gl.createShader(gl.VERTEX_SHADER);
+ // } else if (shaderType == "FRAGMENT_SHADER") {
+ // shader = gl.createShader(gl.FRAGMENT_SHADER);
+ // } else {
+ // return null;
+ // }
+
+ // gl.shaderSource(shader, shaderText);
+ // gl.compileShader(shader);
+
+ // if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
+ // alert(gl.getShaderInfoLog(shader));
+ // console.error(gl.getShaderInfoLog(shader));
+ // gl.deleteShader(shader);
+ // return null;
+ // }
+
+ // return shader;
+ // }
+
+ // function initShaders(vertexShaderText: string, fragmentShaderText: string) {
+ // var vertexShader = getShader(Kernel.gl, "VERTEX_SHADER", vertexShaderText);
+ // var fragmentShader = getShader(Kernel.gl, "FRAGMENT_SHADER", fragmentShaderText);
+
+ // var shaderProgram = gl.createProgram();
+ // gl.attachShader(shaderProgram, vertexShader);
+ // gl.attachShader(shaderProgram, fragmentShader);
+ // gl.linkProgram(shaderProgram);
+
+ // if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
+ // console.error("Could not link program!");
+ // gl.deleteProgram(shaderProgram);
+ // gl.deleteShader(vertexShader);
+ // gl.deleteShader(fragmentShader);
+ // return;
+ // }
+
+ // gl.useProgram(shaderProgram);
+ // gl.shaderProgram = shaderProgram as WebGLProgramExtension;
+ // gl.shaderProgram.aVertexPosition = gl.getAttribLocation(gl.shaderProgram, "aVertexPosition");
+ // gl.shaderProgram.aTextureCoord = gl.getAttribLocation(gl.shaderProgram, "aTextureCoord");
+ // gl.shaderProgram.uMVMatrix = gl.getUniformLocation(gl.shaderProgram, "uMVMatrix");
+ // gl.shaderProgram.uPMatrix = gl.getUniformLocation(gl.shaderProgram, "uPMatrix");
+ // gl.shaderProgram.uSampler = gl.getUniformLocation(gl.shaderProgram, "uSampler"); //纹理采样器
+ // gl.shaderProgram.uOffScreen = gl.getUniformLocation(gl.shaderProgram, "uOffScreen"); //是否离屏渲染
+
+ // //设置默认非离屏渲染
+ // gl.uniform1i(gl.shaderProgram.uOffScreen, 1);
+
+ // //设置默认值
+ // var squareArray = [1, 0, 0, 0,
+ // 0, 1, 0, 0,
+ // 0, 0, 1, 0,
+ // 0, 0, 0, 1
+ // ];
+ // var squareMatrix = new Float32Array(squareArray); //ArrayBuffer
+ // gl.uniformMatrix4fv(gl.shaderProgram.uMVMatrix, false, squareMatrix);
+ // }
initWebGL(canvas);
@@ -114,7 +108,7 @@ class Renderer {
return;
}
- initShaders(vertexShaderText, fragmentShaderText);
+ //initShaders(vertexShaderText, fragmentShaderText);
gl.clearColor(255, 255, 255, 1.0);
//gl.enable(gl.DEPTH_TEST);
@@ -132,7 +126,9 @@ class Renderer {
Kernel.gl.viewport(0, 0, Kernel.canvas.width, Kernel.canvas.height);
Kernel.gl.clear(Kernel.gl.COLOR_BUFFER_BIT | Kernel.gl.DEPTH_BUFFER_BIT);
camera.viewMatrix = null;
+ //update viewMatrix and projViewMatrix of camera
camera.viewMatrix = camera.getViewMatrix();
+ camera.projViewMatrix = camera.projMatrix.multiplyMatrix(camera.viewMatrix);
scene.draw(camera);
}
diff --git a/src/world/Scene.ts b/src/world/Scene.ts
index ad1d7d5..f7be677 100644
--- a/src/world/Scene.ts
+++ b/src/world/Scene.ts
@@ -1,8 +1,8 @@
///
-import Object3DComponents = require('./Object3DComponents');
+import GraphicGroup = require('./GraphicGroup');
import TiledLayer = require("./layers/TiledLayer");
-class Scene extends Object3DComponents{
+class Scene extends GraphicGroup{
tiledLayer: TiledLayer;
}
diff --git a/src/world/geometries/TileGeometry.ts b/src/world/geometries/TileGeometry.ts
index e9f1c3e..19ba3cf 100644
--- a/src/world/geometries/TileGeometry.ts
+++ b/src/world/geometries/TileGeometry.ts
@@ -1,4 +1,4 @@
-///
+///
import Vertice = require("./Vertice");
import Triangle = require("./Triangle");
diff --git a/src/world/graphics/MeshGraphic.ts b/src/world/graphics/MeshGraphic.ts
index 61c6925..bac0102 100644
--- a/src/world/graphics/MeshGraphic.ts
+++ b/src/world/graphics/MeshGraphic.ts
@@ -8,29 +8,29 @@ import MeshTextureMaterial = require("../materials/MeshTextureMaterial");
import PerspectiveCamera = require("../PerspectiveCamera");
const vs =
- `
-'attribute vec3 aPosition;',
-'attribute vec2 aUV;',
-'varying vec2 vUV;',
-'uniform mat4 uPMVMatrix;',
-
-'void main()',
-'{',
- 'gl_Position = uPMVMatrix * vec4(aPosition,1.0);',
- 'vUV = aUV;',
-'}'
+`
+attribute vec3 aPosition;
+attribute vec2 aUV;
+varying vec2 vUV;
+uniform mat4 uPMVMatrix;
+
+void main()
+{
+ gl_Position = uPMVMatrix * vec4(aPosition,1.0);
+ vUV = aUV;
+}
`;
const fs =
- `
-'precision mediump float;',
- 'varying vec2 vUV;',
- 'uniform sampler2D uSampler;',
-
- 'void main()',
- '{',
- 'gl_FragColor = texture2D(uSampler, vec2(vUV.s, vUV.t));',
- '}'
+`
+precision mediump float;
+varying vec2 vUV;
+uniform sampler2D uSampler;
+
+void main()
+{
+ gl_FragColor = texture2D(uSampler, vec2(vUV.s, vUV.t));
+}
`;
class MeshGraphic extends Graphic {
diff --git a/src/world/graphics/Tile.ts b/src/world/graphics/Tile.ts
index 0a681ef..ee60b25 100644
--- a/src/world/graphics/Tile.ts
+++ b/src/world/graphics/Tile.ts
@@ -1,10 +1,10 @@
-///
+///
import Kernel = require('../Kernel');
import Enum = require('../Enum');
import Elevation = require('../Elevation');
import MathUtils = require('../math/Math');
import MeshGraphic = require('../graphics/MeshGraphic');
-import MeshTextureMaterial = require('../materials/MeshTextureMaterial');
+import TileMaterial = require('../materials/TileMaterial');
import TileGeometry = require("../geometries/TileGeometry");
import Vertice = require("../geometries/Vertice");
import Triangle = require("../geometries/Triangle");
@@ -26,14 +26,13 @@ class TileInfo {
segment: number = 1;
elevationInfo: any = null;
geometry: TileGeometry;
- material: MeshTextureMaterial;
+ material: TileMaterial;
visible: boolean;
constructor(public level: number, public row: number, public column: number, public url: string) {
this._setTileInfo();
this._checkTerrain();
- this._createGeometry();
- this._createMaterial();
+ this.material = new TileMaterial(this.level, this.url);
}
// 根据传入的切片的层级以及行列号信息设置切片的经纬度范围 以及设置其纹理
@@ -56,18 +55,6 @@ class TileInfo {
this.maxY = maxCoord[1];
}
- _createGeometry() {
- this.geometry = null;
- }
-
- _createMaterial() {
- var matArgs = {
- level: this.level,
- url: this.url
- };
- this.material = new MeshTextureMaterial(matArgs);
- }
-
/**
* 判断是否满足现实Terrain的条件,若满足则转换为三维地形
* 条件:
@@ -213,7 +200,7 @@ class TileInfo {
class Tile extends MeshGraphic {
subTiledLayer: any;
- constructor(public geometry: TileGeometry, public material: MeshTextureMaterial, public tileInfo: TileInfo) {
+ constructor(public geometry: TileGeometry, public material: TileMaterial, public tileInfo: TileInfo) {
super(geometry, material);
}
diff --git a/src/world/layers/SubTiledLayer.ts b/src/world/layers/SubTiledLayer.ts
index cb48b8b..03b694a 100644
--- a/src/world/layers/SubTiledLayer.ts
+++ b/src/world/layers/SubTiledLayer.ts
@@ -140,7 +140,7 @@ class SubTiledLayer extends GraphicGroup {
var i:number, name:any;
for (i = 0; i < tiles.length; i++) {
var tile = tiles[i];
- var tileGrid = TileGrid.getTileGridAncestor(this.elevationLevel, tile.level, tile.row, tile.column);
+ var tileGrid = TileGrid.getTileGridAncestor(this.elevationLevel, tile.tileInfo.level, tile.tileInfo.row, tile.tileInfo.column);
name = tileGrid.level + "_" + tileGrid.row + "_" + tileGrid.column;
if (result.indexOf(name) < 0) {
result.push(name);
@@ -165,7 +165,7 @@ class SubTiledLayer extends GraphicGroup {
for (var i = 0; i < this.children.length; i++) {
var tile = this.children[i];
if (tile) {
- var isTileLoaded = tile.material.loaded;
+ var isTileLoaded = tile.material.isReady();
if (!isTileLoaded) {
return false;
}
diff --git a/src/world/layers/TiledLayer.ts b/src/world/layers/TiledLayer.ts
index cc09fc6..e4ef093 100644
--- a/src/world/layers/TiledLayer.ts
+++ b/src/world/layers/TiledLayer.ts
@@ -1,9 +1,9 @@
///
import Kernel = require('../Kernel');
-import Object3DComponents = require('../Object3DComponents');
+import GraphicGroup = require('../GraphicGroup');
import SubTiledLayer = require('./SubTiledLayer');
-abstract class TiledLayer extends Object3DComponents {
+abstract class TiledLayer extends GraphicGroup {
//重写
add(subTiledLayer: SubTiledLayer) {
super.add(subTiledLayer);
diff --git a/src/world/materials/MeshTextureMaterial.ts b/src/world/materials/MeshTextureMaterial.ts
index be62153..5207bcf 100644
--- a/src/world/materials/MeshTextureMaterial.ts
+++ b/src/world/materials/MeshTextureMaterial.ts
@@ -15,6 +15,7 @@ class MeshTextureMaterial extends Material {
constructor(imageOrUrl?: ImageType) {
super();
+ this.texture = Kernel.gl.createTexture();
if(imageOrUrl){
this.setImageOrUrl(imageOrUrl);
}
@@ -73,7 +74,7 @@ class MeshTextureMaterial extends Material {
Kernel.gl.texImage2D(Kernel.gl.TEXTURE_2D, 0, Kernel.gl.RGBA, Kernel.gl.RGBA, Kernel.gl.UNSIGNED_BYTE, this.image);
- var isMipMap = this.image.width === this.image.height && MathUtils.isPowerOfTwo(this.image.width);
+ var isMipMap = false;//this.image.width === this.image.height && MathUtils.isPowerOfTwo(this.image.width);
if (isMipMap) {
//使用MipMap
diff --git a/src/world/materials/TileMaterial.ts b/src/world/materials/TileMaterial.ts
index d67fe46..11579e3 100644
--- a/src/world/materials/TileMaterial.ts
+++ b/src/world/materials/TileMaterial.ts
@@ -1,4 +1,4 @@
-///
+///
import MeshTextureMaterial= require('./MeshTextureMaterial');
import ImageUtils = require('../Image');
diff --git a/src/world/materials/__TextureMaterial.ts b/src/world/materials/__TextureMaterial.ts
index 308108e..8b410c5 100644
--- a/src/world/materials/__TextureMaterial.ts
+++ b/src/world/materials/__TextureMaterial.ts
@@ -1,5 +1,5 @@
-///
-import Kernel = require('./Kernel');
+///
+import Kernel = require('../Kernel');
class TextureMaterial {
texture: WebGLTexture = null;
From 19bc21d8a8555d9f1afd15e7912a68f3cef0e523 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Wed, 26 Oct 2016 23:50:30 +0800
Subject: [PATCH 015/109] update
---
src/world/graphics/Tile.ts | 2 +-
src/world/materials/MeshTextureMaterial.ts | 37 +++++++-----
src/world/materials/__TextureMaterial.ts | 68 ----------------------
3 files changed, 23 insertions(+), 84 deletions(-)
delete mode 100644 src/world/materials/__TextureMaterial.ts
diff --git a/src/world/graphics/Tile.ts b/src/world/graphics/Tile.ts
index ee60b25..c2c4ae3 100644
--- a/src/world/graphics/Tile.ts
+++ b/src/world/graphics/Tile.ts
@@ -183,7 +183,7 @@ class TileInfo {
var v3: Vertice = verticeArray[idx3];
var triangle1 = new Triangle(v0, v1, v2);
var triangle2 = new Triangle(v2, v3, v0);
- triangleArray.concat(triangle1, triangle2);
+ triangleArray.push(triangle1, triangle2);
}
}
diff --git a/src/world/materials/MeshTextureMaterial.ts b/src/world/materials/MeshTextureMaterial.ts
index 5207bcf..2c922ee 100644
--- a/src/world/materials/MeshTextureMaterial.ts
+++ b/src/world/materials/MeshTextureMaterial.ts
@@ -74,24 +74,31 @@ class MeshTextureMaterial extends Material {
Kernel.gl.texImage2D(Kernel.gl.TEXTURE_2D, 0, Kernel.gl.RGBA, Kernel.gl.RGBA, Kernel.gl.UNSIGNED_BYTE, this.image);
- var isMipMap = false;//this.image.width === this.image.height && MathUtils.isPowerOfTwo(this.image.width);
+ // var isMipMap = this.image.width === this.image.height && MathUtils.isPowerOfTwo(this.image.width);
- if (isMipMap) {
- //使用MipMap
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);//LINEAR_MIPMAP_LINEAR
+ // if (isMipMap) {
+ // //使用MipMap
+ // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);
+ // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);//LINEAR_MIPMAP_LINEAR
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
+ // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
+ // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
- Kernel.gl.generateMipmap(Kernel.gl.TEXTURE_2D);
- } else {
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR);//gl.NEAREST
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR);//gl.NEAREST
-
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
- }
+ // Kernel.gl.generateMipmap(Kernel.gl.TEXTURE_2D);
+ // } else {
+ // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR);//gl.NEAREST
+ // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR);//gl.NEAREST
+
+ // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
+ // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
+ // }
+
+ //使用MipMap
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR); //LINEAR_MIPMAP_NEAREST LINEAR_MIPMAP_LINEAR
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
+ Kernel.gl.generateMipmap(Kernel.gl.TEXTURE_2D);
Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, null);
diff --git a/src/world/materials/__TextureMaterial.ts b/src/world/materials/__TextureMaterial.ts
deleted file mode 100644
index 8b410c5..0000000
--- a/src/world/materials/__TextureMaterial.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-///
-import Kernel = require('../Kernel');
-
-class TextureMaterial {
- texture: WebGLTexture = null;
- image: HTMLImageElement = null;
- loaded: boolean = false;
- delete: boolean = false;
-
- constructor(args: any) {
- this.texture = Kernel.gl.createTexture();
- this.image = null;
- this.loaded = false;
- this.delete = false;
- if (args.image instanceof Image && args.image.width > 0 && args.image.height > 0) {
- this.setImage(args.image);
- } else if (typeof args.url == "string") {
- this.setImageUrl(args.url);
- }
- }
-
- setImage(image: HTMLImageElement): void {
- if (image.width > 0 && image.height > 0) {
- this.image = image;
- this.onLoad();
- }
- }
-
- setImageUrl(url: string): void {
- this.image = new Image();
- this.image.crossOrigin = 'anonymous'; //很重要,因为图片是跨域获得的,所以一定要加上此句代码
- this.image.onload = this.onLoad.bind(this);
- this.image.src = url;
- }
-
- //图片加载完成时触发
- onLoad(): void {
- //要考虑纹理已经被移除掉了图片才进入onLoad这种情况
- if (this.delete) {
- return;
- }
-
- Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, this.texture);
- Kernel.gl.pixelStorei(Kernel.gl.UNPACK_FLIP_Y_WEBGL, +true);
-
- Kernel.gl.texImage2D(Kernel.gl.TEXTURE_2D, 0, Kernel.gl.RGBA, Kernel.gl.RGBA, Kernel.gl.UNSIGNED_BYTE, this.image);
- //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- //使用MipMap
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR); //LINEAR_MIPMAP_NEAREST LINEAR_MIPMAP_LINEAR
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
- Kernel.gl.generateMipmap(Kernel.gl.TEXTURE_2D);
- Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, null);
- this.loaded = true;
- };
-
- //释放显卡中的texture资源
- releaseTexture(): void {
- if (Kernel.gl.isTexture(this.texture)) {
- Kernel.gl.deleteTexture(this.texture);
- this.delete = true;
- }
- };
-}
-
-export = TextureMaterial;
\ No newline at end of file
From 3c54187e2a200a040c88899754d211b50419eafb Mon Sep 17 00:00:00 2001
From: iSpring
Date: Thu, 27 Oct 2016 21:00:01 +0800
Subject: [PATCH 016/109] remove ShaderContent.ts
---
src/world/Renderer.ts | 68 ----------------------
src/world/ShaderContent.ts | 48 ---------------
src/world/materials/MeshTextureMaterial.ts | 57 +++++-------------
3 files changed, 16 insertions(+), 157 deletions(-)
delete mode 100644 src/world/ShaderContent.ts
diff --git a/src/world/Renderer.ts b/src/world/Renderer.ts
index 9c6e599..bd18198 100644
--- a/src/world/Renderer.ts
+++ b/src/world/Renderer.ts
@@ -34,72 +34,6 @@ class Renderer {
} catch (e) { }
}
- // function getShader(gl: WebGLRenderingContextExtension, shaderType: string, shaderText: string) {
- // if (!shaderText) {
- // return null;
- // }
-
- // var shader: WebGLShader = null;
- // if (shaderType == "VERTEX_SHADER") {
- // shader = gl.createShader(gl.VERTEX_SHADER);
- // } else if (shaderType == "FRAGMENT_SHADER") {
- // shader = gl.createShader(gl.FRAGMENT_SHADER);
- // } else {
- // return null;
- // }
-
- // gl.shaderSource(shader, shaderText);
- // gl.compileShader(shader);
-
- // if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- // alert(gl.getShaderInfoLog(shader));
- // console.error(gl.getShaderInfoLog(shader));
- // gl.deleteShader(shader);
- // return null;
- // }
-
- // return shader;
- // }
-
- // function initShaders(vertexShaderText: string, fragmentShaderText: string) {
- // var vertexShader = getShader(Kernel.gl, "VERTEX_SHADER", vertexShaderText);
- // var fragmentShader = getShader(Kernel.gl, "FRAGMENT_SHADER", fragmentShaderText);
-
- // var shaderProgram = gl.createProgram();
- // gl.attachShader(shaderProgram, vertexShader);
- // gl.attachShader(shaderProgram, fragmentShader);
- // gl.linkProgram(shaderProgram);
-
- // if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- // console.error("Could not link program!");
- // gl.deleteProgram(shaderProgram);
- // gl.deleteShader(vertexShader);
- // gl.deleteShader(fragmentShader);
- // return;
- // }
-
- // gl.useProgram(shaderProgram);
- // gl.shaderProgram = shaderProgram as WebGLProgramExtension;
- // gl.shaderProgram.aVertexPosition = gl.getAttribLocation(gl.shaderProgram, "aVertexPosition");
- // gl.shaderProgram.aTextureCoord = gl.getAttribLocation(gl.shaderProgram, "aTextureCoord");
- // gl.shaderProgram.uMVMatrix = gl.getUniformLocation(gl.shaderProgram, "uMVMatrix");
- // gl.shaderProgram.uPMatrix = gl.getUniformLocation(gl.shaderProgram, "uPMatrix");
- // gl.shaderProgram.uSampler = gl.getUniformLocation(gl.shaderProgram, "uSampler"); //纹理采样器
- // gl.shaderProgram.uOffScreen = gl.getUniformLocation(gl.shaderProgram, "uOffScreen"); //是否离屏渲染
-
- // //设置默认非离屏渲染
- // gl.uniform1i(gl.shaderProgram.uOffScreen, 1);
-
- // //设置默认值
- // var squareArray = [1, 0, 0, 0,
- // 0, 1, 0, 0,
- // 0, 0, 1, 0,
- // 0, 0, 0, 1
- // ];
- // var squareMatrix = new Float32Array(squareArray); //ArrayBuffer
- // gl.uniformMatrix4fv(gl.shaderProgram.uMVMatrix, false, squareMatrix);
- // }
-
initWebGL(canvas);
if (!gl) {
@@ -108,8 +42,6 @@ class Renderer {
return;
}
- //initShaders(vertexShaderText, fragmentShaderText);
-
gl.clearColor(255, 255, 255, 1.0);
//gl.enable(gl.DEPTH_TEST);
gl.disable(gl.DEPTH_TEST); //此处禁用深度测试是为了解决两个不同层级的切片在拖动时一起渲染会导致屏闪的问题
diff --git a/src/world/ShaderContent.ts b/src/world/ShaderContent.ts
deleted file mode 100644
index 60eb293..0000000
--- a/src/world/ShaderContent.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-///
-
-const vsShader =
-`
-attribute vec3 aVertexPosition;
-attribute vec2 aTextureCoord;
-varying vec2 vTextureCoord;
-
-uniform mat4 uMVMatrix;
-uniform mat4 uPMatrix;
-
-void main()
-{
- gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition,1.0);
- vTextureCoord = aTextureCoord;
-}
-`;
-
-const fsShader =
-`
-#ifdef GL_ES
-precision highp float;
-#endif
-
-uniform bool uUseTexture;
-uniform float uShininess;
-uniform vec3 uLightDirection;
-
-uniform vec4 uLightAmbient;
-uniform vec4 uLightDiffuse;
-uniform vec4 uLightSpecular;
-
-varying vec2 vTextureCoord;
-uniform sampler2D uSampler;
-
-void main()
-{
- gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
-}
-`;
-
-
-export = {
- SIMPLE_SHADER: {
- VS_CONTENT: vsShader,
- FS_CONTENT: fsShader
- }
-};
\ No newline at end of file
diff --git a/src/world/materials/MeshTextureMaterial.ts b/src/world/materials/MeshTextureMaterial.ts
index 2c922ee..c02ec5a 100644
--- a/src/world/materials/MeshTextureMaterial.ts
+++ b/src/world/materials/MeshTextureMaterial.ts
@@ -74,53 +74,28 @@ class MeshTextureMaterial extends Material {
Kernel.gl.texImage2D(Kernel.gl.TEXTURE_2D, 0, Kernel.gl.RGBA, Kernel.gl.RGBA, Kernel.gl.UNSIGNED_BYTE, this.image);
- // var isMipMap = this.image.width === this.image.height && MathUtils.isPowerOfTwo(this.image.width);
-
- // if (isMipMap) {
- // //使用MipMap
- // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);
- // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);//LINEAR_MIPMAP_LINEAR
-
- // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
- // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
-
- // Kernel.gl.generateMipmap(Kernel.gl.TEXTURE_2D);
- // } else {
- // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR);//gl.NEAREST
- // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR);//gl.NEAREST
-
- // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
- // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
- // }
-
- //使用MipMap
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR); //LINEAR_MIPMAP_NEAREST LINEAR_MIPMAP_LINEAR
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
- Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
- Kernel.gl.generateMipmap(Kernel.gl.TEXTURE_2D);
+ var isMipMap = this.image.width === this.image.height && MathUtils.isPowerOfTwo(this.image.width);
+
+ if (isMipMap) {
+ //使用MipMap
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR); //LINEAR_MIPMAP_NEAREST LINEAR_MIPMAP_LINEAR
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
+ Kernel.gl.generateMipmap(Kernel.gl.TEXTURE_2D);
+ } else {
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR);//gl.NEAREST
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR);//gl.NEAREST
+
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
+ Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
+ }
Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, null);
this.ready = true;
}
- // test(){
- // Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, this.texture);
- // Kernel.gl.pixelStorei(Kernel.gl.UNPACK_FLIP_Y_WEBGL, +true);
-
- // Kernel.gl.texImage2D(Kernel.gl.TEXTURE_2D, 0, Kernel.gl.RGBA, Kernel.gl.RGBA, Kernel.gl.UNSIGNED_BYTE, this.image);
- // //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- // //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- // //使用MipMap
- // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MIN_FILTER, Kernel.gl.LINEAR_MIPMAP_NEAREST);
- // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_MAG_FILTER, Kernel.gl.LINEAR); //LINEAR_MIPMAP_NEAREST LINEAR_MIPMAP_LINEAR
- // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_S, Kernel.gl.CLAMP_TO_EDGE);
- // Kernel.gl.texParameteri(Kernel.gl.TEXTURE_2D, Kernel.gl.TEXTURE_WRAP_T, Kernel.gl.CLAMP_TO_EDGE);
- // Kernel.gl.generateMipmap(Kernel.gl.TEXTURE_2D);
- // Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, null);
- // }
-
//释放显卡中的texture资源
destroy() {
if (Kernel.gl.isTexture(this.texture)) {
From 844ad0b8af8d1a3f284dbf5fb9e0ff6fe687625e Mon Sep 17 00:00:00 2001
From: iSpring
Date: Thu, 27 Oct 2016 22:30:37 +0800
Subject: [PATCH 017/109] fix the blank issue when zoom into level 14,#9
---
src/world/Event.ts | 10 ++++------
src/world/GraphicGroup.ts | 5 ++++-
src/world/math/Matrix.ts | 38 ++++++++++++++++++++++----------------
src/world/math/Vector.ts | 15 +++++++++++++++
4 files changed, 45 insertions(+), 23 deletions(-)
diff --git a/src/world/Event.ts b/src/world/Event.ts
index f336fab..359d451 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -56,7 +56,7 @@ const EventModule = {
var pickResult = Kernel.globe.camera.getPickCartesianCoordInEarthByCanvas(this.previousX, this.previousY);
if (pickResult.length > 0) {
this.dragGeo = MathUtils.cartesianCoordToGeographic(pickResult[0]);
- console.log("单击点三维坐标:(" + pickResult[0].x + "," + pickResult[0].y + "," + pickResult[0].z + ");经纬度坐标:[" + this.dragGeo[0] + "," + this.dragGeo[1] + "]");
+ //console.log("单击点三维坐标:(" + pickResult[0].x + "," + pickResult[0].y + "," + pickResult[0].z + ");经纬度坐标:[" + this.dragGeo[0] + "," + this.dragGeo[1] + "]");
}
this.canvas.addEventListener("mousemove", this.onMouseMoveListener, false);
}
@@ -98,12 +98,10 @@ const EventModule = {
}
var p1 = MathUtils.geographicToCartesianCoord(oldLon, oldLat);
var v1 = Vector.fromVertice(p1);
- v1.normalize();
var p2 = MathUtils.geographicToCartesianCoord(newLon, newLat);
var v2 = Vector.fromVertice(p2);
- v2.normalize();
var rotateVector = v1.cross(v2);
- var rotateRadian = -Math.acos(v1.dot(v2));
+ var rotateRadian = -Vector.getRadianOfTwoVectors(v1, v2);
var camera: PerspectiveCamera = Kernel.globe.camera;
camera.worldRotateByVector(rotateRadian, rotateVector);
},
@@ -156,8 +154,8 @@ const EventModule = {
}
var newLevel = globe.CURRENT_LEVEL + deltaLevel;
if(newLevel >= 0){
- //globe.setLevel(newLevel);
- globe.animateToLevel(newLevel);
+ globe.setLevel(newLevel);
+ //globe.animateToLevel(newLevel);
}
},
diff --git a/src/world/GraphicGroup.ts b/src/world/GraphicGroup.ts
index 0417d68..c2cc456 100644
--- a/src/world/GraphicGroup.ts
+++ b/src/world/GraphicGroup.ts
@@ -21,13 +21,16 @@ class GraphicGroup{
g.parent = this;
}
- remove(g: Drawable){
+ remove(g: Drawable): boolean{
+ var result = false;
var findResult = this.findGraphicById(g.id);
if(findResult){
g.destroy();
this.children.splice(findResult.index, 1);
g = null;
+ result = true;
}
+ return result;
}
clear(){
diff --git a/src/world/math/Matrix.ts b/src/world/math/Matrix.ts
index 7b87858..63d8274 100644
--- a/src/world/math/Matrix.ts
+++ b/src/world/math/Matrix.ts
@@ -132,21 +132,21 @@ class Matrix{
var result: Matrix = new Matrix();
var b = result.elements;
var c = a[0],
- d = a[1],
- e = a[2],
- g = a[3],
- f = a[4],
- h = a[5],
- i = a[6],
- j = a[7],
- k = a[8],
- l = a[9],
- n = a[10],
- o = a[11],
- m = a[12],
- p = a[13],
- r = a[14],
- s = a[15];
+ d = a[1],
+ e = a[2],
+ g = a[3],
+ f = a[4],
+ h = a[5],
+ i = a[6],
+ j = a[7],
+ k = a[8],
+ l = a[9],
+ n = a[10],
+ o = a[11],
+ m = a[12],
+ p = a[13],
+ r = a[14],
+ s = a[15];
var A = c * h - d * f;
var B = c * i - e * f;
var t = c * j - g * f;
@@ -163,7 +163,7 @@ class Matrix{
if (!q) {
console.log("can't get inverse matrix");
return null
- };
+ }
q = 1 / q;
b[0] = (h * E - i * D + j * C) * q;
b[1] = (-d * E + e * D - g * C) * q;
@@ -275,6 +275,12 @@ class Matrix{
return [m11, m21, m31, m41];
}
+ hasNaN():boolean{
+ return this.elements.some(function(v){
+ return isNaN(v);
+ });
+ }
+
divide(a: number) {
if (a === 0) {
throw "invalid a:a is 0";
diff --git a/src/world/math/Vector.ts b/src/world/math/Vector.ts
index fb2687d..3bae7bf 100644
--- a/src/world/math/Vector.ts
+++ b/src/world/math/Vector.ts
@@ -16,6 +16,21 @@ class Vector{
return new Vertice(vertice.x + vector.x, vertice.y + vector.y, vertice.z + vector.z);
}
+ static getRadianOfTwoVectors(vector1: Vector, vector2: Vector): number{
+ var v1 = vector1.clone().normalize();
+ var v2 = vector2.clone().normalize();
+ var dotValue = v1.dot(v2);
+ //dotValue的值应该在[-1,1],但是由于JavaScript精度问题,导致计算的值有可能超出该范围,例如1.0000000000000002
+ if(dotValue < -1){
+ dotValue = -1;
+ }
+ if(dotValue > 1){
+ dotValue = 1;
+ }
+ var radian = Math.acos(dotValue);
+ return radian;
+ }
+
getVertice(): Vertice {
return new Vertice(this.x, this.y, this.z);
}
From 0375947e4eb8ad126ebefa4ced92162e9486a46d Mon Sep 17 00:00:00 2001
From: iSpring
Date: Thu, 27 Oct 2016 22:31:14 +0800
Subject: [PATCH 018/109] update
---
index-bundle.html | 2 +-
index-src.html | 2 +-
src/world/Event.ts | 4 ++--
src/world/PerspectiveCamera.ts | 6 +++---
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/index-bundle.html b/index-bundle.html
index 7e5daab..ce0ce02 100644
--- a/index-bundle.html
+++ b/index-bundle.html
@@ -13,8 +13,8 @@
-
-
+
+
## WebGlobe
WebGlobe是基于HTML5原生WebGL实现的轻量级Google Earth三维地图引擎,支持诺基亚地图、微软Bing地图、腾讯地图、天地图、OpenStreetMap等。
@@ -18,19 +18,20 @@ Demo: https://ispring.github.io/WebGlobe/index.html
## Setup dev environment
1. 项目有两个主要的分支:develop分支和master分支,develop是主分支,开发的代码都提交到该分支;master分支用于release,当develop分支中的代码比较稳定且有重要更新的时候,会将develop分支的代码merge到master分支,然后通过master分支进行发布新版本。
-
+
2. 项目采用TypeScript编写,编译成JavaScript运行,推荐使用[Visual Studio Code](http://code.visualstudio.com/)作为编辑器。
-
- 3. 通过npm install -g typescript gulp-cli安装全局模块typescript和gulp。
-
+
+ 3. 通过npm install -g typescript安装全局模块typescript。
+
4. 在项目的根目录下执行npm install,安装所需模块。
-
- 5. 通过gulp进行编译打包,gulpfile中定义了多个task:
- - clear用于清除编译打包的结果
- - compile用于将TypeScript版本的模块编译成JavaScript版本的AMD模块
- - bundle用于将TypeScript版本的模块打包成一个JavaScript压缩文件
- - build用于执行以上所有的task,且是默认的task
-
+
+ 5. 使用gulp进行编译打包,gulpfile中定义了多个task,并在package.json中定义了对应的npm scripts:
+ - npm run clear 用于清除编译打包的结果
+ - npm run compile 用于将TypeScript版本的模块编译成JavaScript版本的AMD模块
+ - npm run bundle 用于将TypeScript版本的模块打包成一个JavaScript压缩文件
+ - npm run build 用于执行以上所有的task
+ - npm start 用于执行build
+
6. 通过index-src.html可以加载AMD格式的源码,方便调试;通过index-bundle.html可以加载打打包压缩后的JavaScript文件,减少了文件体积和网络请求数量,用于生产环境。
diff --git a/package.json b/package.json
index 2f2d695..cfb2469 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,11 @@
"description": "A WebGL virtual globe and map engine.",
"main": "require.js",
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
+ "clear": "gulp clear",
+ "compile": "gulp compile",
+ "bundle": "gulp bundle",
+ "build": "gulp build",
+ "start": "npm run build"
},
"repository": {
"type": "git",
diff --git a/src/world/geometries/Geometry.ts b/src/world/geometries/Geometry.ts
new file mode 100644
index 0000000..f843a29
--- /dev/null
+++ b/src/world/geometries/Geometry.ts
@@ -0,0 +1,7 @@
+///
+
+interface Geometry{
+ destroy():void
+}
+
+export = Geometry;
\ No newline at end of file
diff --git a/src/world/graphics/MeshGraphic.ts b/src/world/graphics/MeshGraphic.ts
index bac0102..d9ced79 100644
--- a/src/world/graphics/MeshGraphic.ts
+++ b/src/world/graphics/MeshGraphic.ts
@@ -3,7 +3,7 @@
import Kernel = require("../Kernel");
import Program = require("../Program");
import Graphic = require("./Graphic");
-import Geometry = require("../geometries/Geometry");
+import Mesh = require("../geometries/Mesh");
import MeshTextureMaterial = require("../materials/MeshTextureMaterial");
import PerspectiveCamera = require("../PerspectiveCamera");
@@ -34,7 +34,7 @@ void main()
`;
class MeshGraphic extends Graphic {
- constructor(public geometry: Geometry, public material: MeshTextureMaterial){
+ constructor(public geometry: Mesh, public material: MeshTextureMaterial){
super(geometry, material);
this.geometry.calculateVBO();
this.geometry.calculateIBO();
diff --git a/versions.txt b/versions.txt
index 4851f98..ddff7c5 100644
--- a/versions.txt
+++ b/versions.txt
@@ -90,4 +90,6 @@
0.2.1 修复了在leve 15及以上的情况下,拖动地图导致地图空白的问题,见issue#9
-0.2.2 删除高程相关代码
\ No newline at end of file
+0.2.2 删除高程相关代码
+
+0.2.3 将world/geometries/Geomtry重命名为world/geometries/Mesh,并在package.json中添加了多个npm scripts,对应gulp中定义的tasks
\ No newline at end of file
From e12922d15be1c89f0401ccc3de329050bb4df545 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Thu, 17 Nov 2016 18:34:28 +0800
Subject: [PATCH 027/109] update version
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index cfb2469..11b1239 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "webglobe",
- "version": "0.2.1",
+ "version": "0.2.3",
"description": "A WebGL virtual globe and map engine.",
"main": "require.js",
"scripts": {
From 352809084d3438bbbaff87dbaf733bbb862b7d14 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Thu, 17 Nov 2016 21:08:15 +0800
Subject: [PATCH 028/109] update console.log() of SubTiledLayer
---
src/world/layers/SubTiledLayer.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/world/layers/SubTiledLayer.ts b/src/world/layers/SubTiledLayer.ts
index a4fe7ed..3c4b8e8 100644
--- a/src/world/layers/SubTiledLayer.ts
+++ b/src/world/layers/SubTiledLayer.ts
@@ -94,7 +94,7 @@ class SubTiledLayer extends GraphicGroup {
var b = this.remove(tilesNeedDelete[0]);
tilesNeedDelete.splice(0, 1);
if (!b) {
- console.debug("LINE:2191,subTiledLayer.remove(tilesNeedDelete[0])失败");
+ console.debug("subTiledLayer.remove(tilesNeedDelete[0])失败");
}
}
From d6700029287ac49fc8afe091f7601113f31beb4d Mon Sep 17 00:00:00 2001
From: iSpring
Date: Thu, 17 Nov 2016 22:19:12 +0800
Subject: [PATCH 029/109] rename world/geometries/Vertice to
world/geometries/MeshVertice
---
src/world/geometries/Box.ts | 2 +-
src/world/geometries/Mesh.ts | 2 +-
src/world/geometries/{Vertice.ts => MeshVertice.ts} | 6 +++---
src/world/geometries/TileGeometry.ts | 2 +-
src/world/geometries/Triangle.ts | 2 +-
src/world/graphics/Marker.ts | 13 +++++++++++++
src/world/graphics/Tile.ts | 2 +-
7 files changed, 21 insertions(+), 8 deletions(-)
rename src/world/geometries/{Vertice.ts => MeshVertice.ts} (70%)
create mode 100644 src/world/graphics/Marker.ts
diff --git a/src/world/geometries/Box.ts b/src/world/geometries/Box.ts
index 324d155..02bbd2b 100644
--- a/src/world/geometries/Box.ts
+++ b/src/world/geometries/Box.ts
@@ -1,6 +1,6 @@
///
-import Vertice = require("./Vertice");
+import Vertice = require("./MeshVertice");
import Triangle = require("./Triangle");
import Mesh = require("./Mesh");
diff --git a/src/world/geometries/Mesh.ts b/src/world/geometries/Mesh.ts
index 09693be..0c0dd4a 100644
--- a/src/world/geometries/Mesh.ts
+++ b/src/world/geometries/Mesh.ts
@@ -1,6 +1,6 @@
///
import Kernel = require("../Kernel");
-import Vertice = require("./Vertice");
+import Vertice = require("./MeshVertice");
import Triangle = require("./Triangle");
import Object3D = require("../Object3D");
import VertexBufferObject = require("../VertexBufferObject");
diff --git a/src/world/geometries/Vertice.ts b/src/world/geometries/MeshVertice.ts
similarity index 70%
rename from src/world/geometries/Vertice.ts
rename to src/world/geometries/MeshVertice.ts
index 430f13a..e368413 100644
--- a/src/world/geometries/Vertice.ts
+++ b/src/world/geometries/MeshVertice.ts
@@ -1,5 +1,5 @@
-///
-class Vertice{
+///
+class MeshVertice{
p:number[];
n:number[];
uv:number[];
@@ -15,4 +15,4 @@ class Vertice{
}
}
-export = Vertice;
\ No newline at end of file
+export = MeshVertice;
\ No newline at end of file
diff --git a/src/world/geometries/TileGeometry.ts b/src/world/geometries/TileGeometry.ts
index 3626b48..37f3961 100644
--- a/src/world/geometries/TileGeometry.ts
+++ b/src/world/geometries/TileGeometry.ts
@@ -1,6 +1,6 @@
///
-import Vertice = require("./Vertice");
+import Vertice = require("./MeshVertice");
import Triangle = require("./Triangle");
import Mesh = require("./Mesh");
diff --git a/src/world/geometries/Triangle.ts b/src/world/geometries/Triangle.ts
index dd0ef14..3d04629 100644
--- a/src/world/geometries/Triangle.ts
+++ b/src/world/geometries/Triangle.ts
@@ -1,5 +1,5 @@
///
-import Vertice = require("./Vertice");
+import Vertice = require("./MeshVertice");
class Triangle{
diff --git a/src/world/graphics/Marker.ts b/src/world/graphics/Marker.ts
new file mode 100644
index 0000000..78b438f
--- /dev/null
+++ b/src/world/graphics/Marker.ts
@@ -0,0 +1,13 @@
+///
+
+import Graphic = require('./Graphic');
+
+class Marker {
+ constructor(){
+
+ }
+}
+
+//extends Graphic
+
+export = Marker;
\ No newline at end of file
diff --git a/src/world/graphics/Tile.ts b/src/world/graphics/Tile.ts
index 83fe0ed..d25d797 100644
--- a/src/world/graphics/Tile.ts
+++ b/src/world/graphics/Tile.ts
@@ -5,7 +5,7 @@ import MathUtils = require('../math/Math');
import MeshGraphic = require('../graphics/MeshGraphic');
import TileMaterial = require('../materials/TileMaterial');
import TileGeometry = require("../geometries/TileGeometry");
-import Vertice = require("../geometries/Vertice");
+import Vertice = require("../geometries/MeshVertice");
import Triangle = require("../geometries/Triangle");
class TileInfo {
From f66a11204bbff929125e82ecb339fb9e6b735fa2 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Fri, 18 Nov 2016 00:14:02 +0800
Subject: [PATCH 030/109] add Poi
---
index-bundle.html | 6 ++--
index-src.html | 6 ++--
main.js | 9 +++--
src/world/geometries/Marker.ts | 21 +++++++++++
src/world/graphics/Marker.ts | 13 -------
src/world/graphics/Poi.ts | 57 ++++++++++++++++++++++++++++++
src/world/layers/PoiLayer.ts | 24 +++++++++++++
src/world/materials/PoiMaterial.ts | 20 +++++++++++
8 files changed, 135 insertions(+), 21 deletions(-)
create mode 100644 src/world/geometries/Marker.ts
delete mode 100644 src/world/graphics/Marker.ts
create mode 100644 src/world/graphics/Poi.ts
create mode 100644 src/world/layers/PoiLayer.ts
create mode 100644 src/world/materials/PoiMaterial.ts
diff --git a/index-bundle.html b/index-bundle.html
index ce0ce02..3691819 100644
--- a/index-bundle.html
+++ b/index-bundle.html
@@ -12,9 +12,9 @@
-
-
-
+
+
+
diff --git a/index-src.html b/index-src.html
index 9e7f8cd..d6765c4 100644
--- a/index-src.html
+++ b/index-src.html
@@ -20,9 +20,9 @@
-
-
-
+
+
+
diff --git a/main.js b/main.js
index 156c5d5..a0aac74 100644
--- a/main.js
+++ b/main.js
@@ -1,7 +1,9 @@
window.onload = function() {
require(["world/Globe", "world/layers/BingTiledLayer", "world/layers/NokiaTiledLayer", "world/layers/OsmTiledLayer",
- "world/layers/SosoTiledLayer", "world/layers/TiandituTiledLayer", "world/layers/GoogleTiledLayer"],
- function(Globe, BingTiledLayer, NokiaTiledLayer, OsmTiledLayer, SosoTiledLayer, TiandituTiledLayer, GoogleTiledLayer) {
+ "world/layers/SosoTiledLayer", "world/layers/TiandituTiledLayer", "world/layers/GoogleTiledLayer",
+ "world/layers/PoiLayer"],
+ function(Globe, BingTiledLayer, NokiaTiledLayer, OsmTiledLayer, SosoTiledLayer, TiandituTiledLayer, GoogleTiledLayer,
+ PoiLayer) {
function startWebGL() {
var canvas = document.getElementById("canvasId");
@@ -9,6 +11,9 @@
var mapSelector = document.getElementById("mapSelector");
mapSelector.onchange = changeTiledLayer;
changeTiledLayer();
+
+ var poiLayer = new PoiLayer();
+ window.globe.scene.add(poiLayer);
}
function changeTiledLayer() {
diff --git a/src/world/geometries/Marker.ts b/src/world/geometries/Marker.ts
new file mode 100644
index 0000000..4f13c19
--- /dev/null
+++ b/src/world/geometries/Marker.ts
@@ -0,0 +1,21 @@
+///
+
+import Kernel = require("../Kernel");
+import Geometry = require('./Geometry');
+import VertexBufferObject = require("../VertexBufferObject");
+
+class Marker implements Geometry{
+
+ vbo: VertexBufferObject;
+
+ constructor(public x: number, public y: number, public z: number){
+ this.vbo = new VertexBufferObject(Kernel.gl.ARRAY_BUFFER);
+ this.vbo.bind();
+ this.vbo.bufferData([x,y,z], Kernel.gl.STATIC_DRAW, true);
+ this.vbo.unbind();
+ }
+
+ destroy(){}
+}
+
+export = Marker;
\ No newline at end of file
diff --git a/src/world/graphics/Marker.ts b/src/world/graphics/Marker.ts
deleted file mode 100644
index 78b438f..0000000
--- a/src/world/graphics/Marker.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-///
-
-import Graphic = require('./Graphic');
-
-class Marker {
- constructor(){
-
- }
-}
-
-//extends Graphic
-
-export = Marker;
\ No newline at end of file
diff --git a/src/world/graphics/Poi.ts b/src/world/graphics/Poi.ts
new file mode 100644
index 0000000..b4d1a65
--- /dev/null
+++ b/src/world/graphics/Poi.ts
@@ -0,0 +1,57 @@
+///
+
+import Kernel = require("../Kernel");
+import Graphic = require('./Graphic');
+import Marker = require('../geometries/Marker');
+import PoiMaterial = require('../materials/PoiMaterial');
+import Program = require("../Program");
+import PerspectiveCamera = require("../PerspectiveCamera");
+
+const vs =
+`
+attribute vec3 aPosition;
+uniform mat4 uPMVMatrix;
+
+void main(void) {
+ gl_Position = uPMVMatrix * vec4(aPosition, 1.0);
+ gl_PointSize = 10.0;
+}
+`;
+
+const fs =
+`
+precision mediump float;
+
+void main()
+{
+ gl_FragColor = vec4(1.0, 1.0, 0.0, 0.5);
+}
+`;
+
+class Poi extends Graphic {
+ constructor(public geometry: Marker, public material: PoiMaterial){
+ super(geometry, material);
+ }
+
+ createProgram(){
+ return new Program(this.getProgramType(), vs, fs);
+ }
+
+ onDraw(camera: PerspectiveCamera){
+ //aPosition
+ var locPosition = this.program.getAttribLocation('aPosition');
+ this.program.enableVertexAttribArray('aPosition');
+ this.geometry.vbo.bind();
+ Kernel.gl.vertexAttribPointer(locPosition, 3, Kernel.gl.FLOAT, false, 0, 0);
+
+ //uPMVMatrix
+ var pmvMatrix = camera.projViewMatrix;//.multiplyMatrix(this.geometry.matrix);
+ var locPMVMatrix = this.program.getUniformLocation('uPMVMatrix');
+ Kernel.gl.uniformMatrix4fv(locPMVMatrix, false, pmvMatrix.elements);
+
+ //绘图,1表示1个点
+ Kernel.gl.drawArrays(Kernel.gl.POINTS, 0, 1);
+ }
+}
+
+export = Poi;
\ No newline at end of file
diff --git a/src/world/layers/PoiLayer.ts b/src/world/layers/PoiLayer.ts
new file mode 100644
index 0000000..ce38c13
--- /dev/null
+++ b/src/world/layers/PoiLayer.ts
@@ -0,0 +1,24 @@
+///
+import Kernel = require('../Kernel');
+import Utils = require('../Utils');
+import MathUtils = require('../math/Math');
+import GraphicGroup = require('../GraphicGroup');
+import Poi = require('../graphics/Poi');
+import Marker = require('../geometries/Marker');
+import PoiMaterial = require('../materials/PoiMaterial');
+
+class PoiLayer extends GraphicGroup{
+ constructor(){
+ super();
+ //Kernel.EARTH_RADIUS + 100
+ //14198820
+ var p = MathUtils.geographicToCartesianCoord(0, 0, Kernel.EARTH_RADIUS + 100);
+ var marker = new Marker(p.x, p.y, p.z);
+ //var marker = new Marker(0, 0, 14198820-100);
+ var material = new PoiMaterial();
+ var poi = new Poi(marker, material);
+ this.add(poi);
+ }
+}
+
+export = PoiLayer;
\ No newline at end of file
diff --git a/src/world/materials/PoiMaterial.ts b/src/world/materials/PoiMaterial.ts
new file mode 100644
index 0000000..4e430cf
--- /dev/null
+++ b/src/world/materials/PoiMaterial.ts
@@ -0,0 +1,20 @@
+///
+
+import Material = require("./Material");
+
+class PoiMaterial implements Material{
+
+ isReady(){
+ return true;
+ }
+
+ getType(){
+ return "PoiMaterial";
+ }
+
+ destroy(){
+
+ }
+}
+
+export = PoiMaterial;
\ No newline at end of file
From ce7e92e99c74df86519cff2a4317ec44505f38da Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Fri, 18 Nov 2016 12:06:36 +0800
Subject: [PATCH 031/109] update
---
src/world/Globe.ts | 8 ++++----
src/world/PerspectiveCamera.ts | 11 +++++++++++
src/world/Renderer.ts | 15 +++++++--------
src/world/layers/SubTiledLayer.ts | 28 ++++++++++++++--------------
src/world/layers/TiledLayer.ts | 9 +++++++++
5 files changed, 45 insertions(+), 26 deletions(-)
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index 2baddda..25fb695 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -30,8 +30,8 @@ class Globe {
this.scene = new Scene();
var radio = canvas.width / canvas.height;
this.camera = new PerspectiveCamera(30, radio, 1.0, 20000000.0);
- this.renderer.bindScene(this.scene);
- this.renderer.bindCamera(this.camera);
+ this.renderer.setScene(this.scene);
+ this.renderer.setCamera(this.camera);
this.setLevel(0);
this.renderer.setIfAutoRefresh(true);
EventUtils.initLayout();
@@ -103,7 +103,7 @@ class Globe {
level = level > this.MAX_LEVEL ? this.MAX_LEVEL : level; //超过最大的渲染级别就不渲染
if(level !== this.CURRENT_LEVEL){
this.camera.animateToLevel(level);
- }
+ }
}
}
@@ -170,7 +170,7 @@ class Globe {
levelsTileGrids.splice(0, 1);
}
}
-
+
}
export = Globe;
\ No newline at end of file
diff --git a/src/world/PerspectiveCamera.ts b/src/world/PerspectiveCamera.ts
index d55d6b7..5609021 100644
--- a/src/world/PerspectiveCamera.ts
+++ b/src/world/PerspectiveCamera.ts
@@ -107,6 +107,17 @@ class PerspectiveCamera extends Object3D {
return this.matrix.getInverseMatrix();
}
+ updateViewMatrix(): Matrix{
+ this.viewMatrix = this.getViewMatrix();
+ return this.viewMatrix;
+ }
+
+ updateProjViewMatrix(): Matrix{
+ this.updateViewMatrix();
+ this.projViewMatrix = this.projMatrix.multiplyMatrix(this.viewMatrix);
+ return this.projViewMatrix;
+ }
+
look(cameraPnt: Vertice, targetPnt: Vertice, upDirection: Vector = new Vector(0, 1, 0)): void {
var cameraPntCopy = cameraPnt.clone();
var targetPntCopy = targetPnt.clone();
diff --git a/src/world/Renderer.ts b/src/world/Renderer.ts
index bd18198..3446071 100644
--- a/src/world/Renderer.ts
+++ b/src/world/Renderer.ts
@@ -13,7 +13,7 @@ class Renderer {
constructor(canvas: HTMLCanvasElement) {
//之所以在此处设置Kernel.renderer是因为要在tick函数中使用
Kernel.renderer = this;
-
+
EventUtils.bindEvents(canvas);
var gl: WebGLRenderingContextExtension;
@@ -43,12 +43,12 @@ class Renderer {
}
gl.clearColor(255, 255, 255, 1.0);
- //gl.enable(gl.DEPTH_TEST);
- gl.disable(gl.DEPTH_TEST); //此处禁用深度测试是为了解决两个不同层级的切片在拖动时一起渲染会导致屏闪的问题
+ gl.enable(gl.DEPTH_TEST);
+ //gl.disable(gl.DEPTH_TEST); //此处禁用深度测试是为了解决两个不同层级的切片在拖动时一起渲染会导致屏闪的问题
gl.depthFunc(gl.LEQUAL);
gl.enable(gl.CULL_FACE); //一定要启用裁剪,否则显示不出立体感
- gl.frontFace(gl.CCW);
+ gl.frontFace(gl.CCW);//指定逆时针方向为正面
gl.cullFace(gl.BACK); //裁剪掉背面
//gl.enable(gl.TEXTURE_2D);//WebGL: INVALID_ENUM: enable: invalid capability
@@ -59,16 +59,15 @@ class Renderer {
Kernel.gl.clear(Kernel.gl.COLOR_BUFFER_BIT | Kernel.gl.DEPTH_BUFFER_BIT);
camera.viewMatrix = null;
//update viewMatrix and projViewMatrix of camera
- camera.viewMatrix = camera.getViewMatrix();
- camera.projViewMatrix = camera.projMatrix.multiplyMatrix(camera.viewMatrix);
+ camera.updateProjViewMatrix();
scene.draw(camera);
}
- bindScene(scene: Scene) {
+ setScene(scene: Scene) {
this.scene = scene;
}
- bindCamera(camera: PerspectiveCamera) {
+ setCamera(camera: PerspectiveCamera) {
this.camera = camera;
}
diff --git a/src/world/layers/SubTiledLayer.ts b/src/world/layers/SubTiledLayer.ts
index 3c4b8e8..d5a9d6b 100644
--- a/src/world/layers/SubTiledLayer.ts
+++ b/src/world/layers/SubTiledLayer.ts
@@ -15,20 +15,20 @@ class SubTiledLayer extends GraphicGroup {
this.level = args.level;
}
- //重写draw方法
- draw(camera: any) {
- /*if (this.level >= Kernel.TERRAIN_LEVEL && Kernel.globe && Kernel.globe.camera.pitch <= Kernel.TERRAIN_PITCH) {
- Kernel.gl.clear(Kernel.gl.DEPTH_BUFFER_BIT);
- Kernel.gl.clearDepth(1);
- Kernel.gl.enable(Kernel.gl.DEPTH_TEST);
- } else {
- Kernel.gl.disable(Kernel.gl.DEPTH_TEST);
- }*/
- Kernel.gl.disable(Kernel.gl.DEPTH_TEST);
- super.draw(camera);
- }
+ //重写GraphicGroup的draw方法
+ // draw(camera: any) {
+ // /*if (this.level >= Kernel.TERRAIN_LEVEL && Kernel.globe && Kernel.globe.camera.pitch <= Kernel.TERRAIN_PITCH) {
+ // Kernel.gl.clear(Kernel.gl.DEPTH_BUFFER_BIT);
+ // Kernel.gl.clearDepth(1);
+ // Kernel.gl.enable(Kernel.gl.DEPTH_TEST);
+ // } else {
+ // Kernel.gl.disable(Kernel.gl.DEPTH_TEST);
+ // }*/
+ // Kernel.gl.disable(Kernel.gl.DEPTH_TEST);//此处禁用深度测试是为了解决两个不同层级的切片在拖动时一起渲染会导致屏闪的问题
+ // super.draw(camera);
+ // }
- //重写Object3DComponents的add方法
+ //重写GraphicGroup的add方法
add(tile: Tile) {
if (tile.tileInfo.level === this.level) {
super.add(tile);
@@ -36,7 +36,7 @@ class SubTiledLayer extends GraphicGroup {
}
}
- //重写Object3DComponents的destroy方法
+ //重写GraphicGroup的destroy方法
destroy() {
super.destroy();
this.tiledLayer = null;
diff --git a/src/world/layers/TiledLayer.ts b/src/world/layers/TiledLayer.ts
index e4ef093..d68af50 100644
--- a/src/world/layers/TiledLayer.ts
+++ b/src/world/layers/TiledLayer.ts
@@ -2,8 +2,17 @@
import Kernel = require('../Kernel');
import GraphicGroup = require('../GraphicGroup');
import SubTiledLayer = require('./SubTiledLayer');
+import PerspectiveCamera = require('../PerspectiveCamera');
abstract class TiledLayer extends GraphicGroup {
+
+ //重写
+ draw(camera: PerspectiveCamera){
+ Kernel.gl.disable(Kernel.gl.DEPTH_TEST);//此处禁用深度测试是为了解决两个不同层级的切片在拖动时一起渲染会导致屏闪的问题
+ super.draw(camera);
+ Kernel.gl.enable(Kernel.gl.DEPTH_TEST);//恢复深度测试
+ }
+
//重写
add(subTiledLayer: SubTiledLayer) {
super.add(subTiledLayer);
From c7a30fc7c8b9a7056c5309eecec6786b826d90bc Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Fri, 18 Nov 2016 14:48:42 +0800
Subject: [PATCH 032/109] update
---
main.js | 1 +
src/world/Globe.ts | 5 +----
src/world/GraphicGroup.ts | 8 ++++++--
src/world/Renderer.ts | 7 ++++++-
src/world/graphics/Poi.ts | 4 +++-
src/world/layers/PoiLayer.ts | 10 +++++++---
6 files changed, 24 insertions(+), 11 deletions(-)
diff --git a/main.js b/main.js
index a0aac74..62e9a21 100644
--- a/main.js
+++ b/main.js
@@ -8,6 +8,7 @@
function startWebGL() {
var canvas = document.getElementById("canvasId");
window.globe = new Globe(canvas);
+
var mapSelector = document.getElementById("mapSelector");
mapSelector.onchange = changeTiledLayer;
changeTiledLayer();
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index 25fb695..edd26f9 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -23,9 +23,6 @@ class Globe {
constructor(canvas: HTMLCanvasElement, args: any) {
args = args || {};
Kernel.globe = this;
-
- // var vs_content = ShaderContent.SIMPLE_SHADER.VS_CONTENT;
- // var fs_content = ShaderContent.SIMPLE_SHADER.FS_CONTENT;
this.renderer = Kernel.renderer = new Renderer(canvas);
this.scene = new Scene();
var radio = canvas.width / canvas.height;
@@ -49,7 +46,7 @@ class Globe {
this.scene.tiledLayer = null;
}
this.tiledLayer = tiledLayer;
- this.scene.add(this.tiledLayer);
+ this.scene.add(this.tiledLayer, true);
//添加第0级的子图层
var subLayer0 = new SubTiledLayer({
level: 0
diff --git a/src/world/GraphicGroup.ts b/src/world/GraphicGroup.ts
index c2cc456..f7b6f64 100644
--- a/src/world/GraphicGroup.ts
+++ b/src/world/GraphicGroup.ts
@@ -16,8 +16,12 @@ class GraphicGroup{
this.children = [];
}
- add(g: Drawable){
- this.children.push(g);
+ add(g: Drawable, first: boolean = false){
+ if(first){
+ this.children.unshift(g);
+ }else{
+ this.children.push(g);
+ }
g.parent = this;
}
diff --git a/src/world/Renderer.ts b/src/world/Renderer.ts
index 3446071..9f73279 100644
--- a/src/world/Renderer.ts
+++ b/src/world/Renderer.ts
@@ -42,10 +42,12 @@ class Renderer {
return;
}
+ Kernel.gl.clear(Kernel.gl.COLOR_BUFFER_BIT | Kernel.gl.DEPTH_BUFFER_BIT);
gl.clearColor(255, 255, 255, 1.0);
+
gl.enable(gl.DEPTH_TEST);
- //gl.disable(gl.DEPTH_TEST); //此处禁用深度测试是为了解决两个不同层级的切片在拖动时一起渲染会导致屏闪的问题
gl.depthFunc(gl.LEQUAL);
+ gl.depthMask(true);
gl.enable(gl.CULL_FACE); //一定要启用裁剪,否则显示不出立体感
gl.frontFace(gl.CCW);//指定逆时针方向为正面
@@ -57,6 +59,9 @@ class Renderer {
render(scene: Scene, camera: PerspectiveCamera) {
Kernel.gl.viewport(0, 0, Kernel.canvas.width, Kernel.canvas.height);
Kernel.gl.clear(Kernel.gl.COLOR_BUFFER_BIT | Kernel.gl.DEPTH_BUFFER_BIT);
+ Kernel.gl.enable(Kernel.gl.DEPTH_TEST);
+ Kernel.gl.depthFunc(Kernel.gl.LEQUAL);
+ Kernel.gl.depthMask(true);
camera.viewMatrix = null;
//update viewMatrix and projViewMatrix of camera
camera.updateProjViewMatrix();
diff --git a/src/world/graphics/Poi.ts b/src/world/graphics/Poi.ts
index b4d1a65..ddcca34 100644
--- a/src/world/graphics/Poi.ts
+++ b/src/world/graphics/Poi.ts
@@ -11,7 +11,7 @@ const vs =
`
attribute vec3 aPosition;
uniform mat4 uPMVMatrix;
-
+
void main(void) {
gl_Position = uPMVMatrix * vec4(aPosition, 1.0);
gl_PointSize = 10.0;
@@ -28,6 +28,8 @@ void main()
}
`;
+//gl_FragColor = vec4(1.0, 1.0, 0.0, 0.5);
+
class Poi extends Graphic {
constructor(public geometry: Marker, public material: PoiMaterial){
super(geometry, material);
diff --git a/src/world/layers/PoiLayer.ts b/src/world/layers/PoiLayer.ts
index ce38c13..ca22020 100644
--- a/src/world/layers/PoiLayer.ts
+++ b/src/world/layers/PoiLayer.ts
@@ -6,19 +6,23 @@ import GraphicGroup = require('../GraphicGroup');
import Poi = require('../graphics/Poi');
import Marker = require('../geometries/Marker');
import PoiMaterial = require('../materials/PoiMaterial');
+import PerspectiveCamera = require('../PerspectiveCamera');
class PoiLayer extends GraphicGroup{
constructor(){
super();
- //Kernel.EARTH_RADIUS + 100
- //14198820
- var p = MathUtils.geographicToCartesianCoord(0, 0, Kernel.EARTH_RADIUS + 100);
+ var p = MathUtils.geographicToCartesianCoord(0, 0, Kernel.EARTH_RADIUS + 1000000);
var marker = new Marker(p.x, p.y, p.z);
//var marker = new Marker(0, 0, 14198820-100);
var material = new PoiMaterial();
var poi = new Poi(marker, material);
this.add(poi);
}
+
+ draw(camera: PerspectiveCamera){
+ Kernel.gl.enable(Kernel.gl.DEPTH_TEST);
+ super.draw(camera);
+ }
}
export = PoiLayer;
\ No newline at end of file
From c5f528e9b67b5f5e55bd0d41103c0376c2215e00 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Fri, 18 Nov 2016 16:32:17 +0800
Subject: [PATCH 033/109] update PerspectiveCamera
---
src/world/PerspectiveCamera.ts | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/src/world/PerspectiveCamera.ts b/src/world/PerspectiveCamera.ts
index 5609021..4517526 100644
--- a/src/world/PerspectiveCamera.ts
+++ b/src/world/PerspectiveCamera.ts
@@ -30,28 +30,29 @@ class PerspectiveCamera extends Object3D {
}
setPerspectiveMatrix(fov: number = 90, aspect: number = 1, near: number = 1, far: number = 1): void {
+ //https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/mat4.js#L1788
this.fov = fov;
this.aspect = aspect;
this.near = near;
this.far = far;
- var mat = [1, 0, 0, 0,
+ var mat = [
+ 1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
];
var halfFov = this.fov * Math.PI / 180 / 2;
- var a = 1 / Math.tan(halfFov);
- var b = this.far - this.near;
+ var f = 1 / Math.tan(halfFov);
+ var nf = 1 / (this.near - this.far);
- mat[0] = a / this.aspect;
- mat[5] = a;
- mat[10] = -(this.far + this.near) / b;
+ mat[0] = f / this.aspect;
+ mat[5] = f;
+ mat[10] = (this.far + this.near) * nf;
mat[11] = -1;
- mat[14] = -2 * this.near * this.far / b;
+ mat[14] = 2 * this.near * this.far * nf;
mat[15] = 0;
- //by comparision with matrixProjection.exe and glMatrix,
- //the 11th element is always -1
+ //by comparision with matrixProjection.exe and glMatrix, the 11th element is always -1
this.projMatrix.setElements(
mat[0], mat[1], mat[2], mat[3],
mat[4], mat[5], mat[6], mat[7],
From 6142eb50d12b38ee7e34c6090890c3992b6112f0 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Fri, 18 Nov 2016 17:31:25 +0800
Subject: [PATCH 034/109] update
---
src/world/math/Math.ts | 22 ++++++++--------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/src/world/math/Math.ts b/src/world/math/Math.ts
index b9603e7..be778ef 100644
--- a/src/world/math/Math.ts
+++ b/src/world/math/Math.ts
@@ -331,7 +331,7 @@ const MathUtils = {
* @return {*}
*/
getLengthFromCamera2EarthSurface(level: number): number{
- return 7820683/Math.pow(2,level);
+ return 7820683 / Math.pow(2, level);
},
/**将经纬度转换为笛卡尔空间直角坐标系中的x、y、z
@@ -372,8 +372,7 @@ const MathUtils = {
var sin2 = y/Kernel.EARTH_RADIUS;
if(sin2 > 1){
sin2 = 2;
- }
- else if(sin2 < -1){
+ }else if(sin2 < -1){
sin2 = -1;
}
var radianLat = Math.asin(sin2);
@@ -381,31 +380,26 @@ const MathUtils = {
var sin1 = x / (Kernel.EARTH_RADIUS * cos2);
if(sin1 > 1){
sin1 = 1;
- }
- else if(sin1 < -1){
+ }else if(sin1 < -1){
sin1 = -1;
}
var cos1 = z / (Kernel.EARTH_RADIUS * cos2);
if(cos1 > 1){
cos1 = 1;
- }
- else if(cos1 < -1){
+ }else if(cos1 < -1){
cos1 = -1;
}
var radianLog = Math.asin(sin1);
if(sin1 >= 0){//经度在[0,π]
if(cos1 >= 0){//经度在[0,π/2]之间
radianLog = radianLog;
- }
- else{//经度在[π/2,π]之间
+ }else{//经度在[π/2,π]之间
radianLog = Math.PI - radianLog;
}
- }
- else{//经度在[-π,0]之间
- if(cos1 >= 0){//经度在[-π/2,0]之间
+ }else{//经度在[-π,0]之间
+ if(cos1 >= 0){//经度在[-π/2,0]之间
radianLog = radianLog;
- }
- else{//经度在[-π,-π/2]之间
+ }else{//经度在[-π,-π/2]之间
radianLog = -radianLog - Math.PI;
}
}
From 56ad2007289881c963fc4e6dbbea1d66e30c2699 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Sun, 20 Nov 2016 23:56:45 +0800
Subject: [PATCH 035/109] update
---
src/world/Renderer.ts | 1 +
src/world/graphics/Poi.ts | 4 +---
src/world/layers/PoiLayer.ts | 2 +-
src/world/layers/SubTiledLayer.ts | 13 -------------
4 files changed, 3 insertions(+), 17 deletions(-)
diff --git a/src/world/Renderer.ts b/src/world/Renderer.ts
index 9f73279..9d9bd99 100644
--- a/src/world/Renderer.ts
+++ b/src/world/Renderer.ts
@@ -27,6 +27,7 @@ class Renderer {
}) as WebGLRenderingContextExtension;
if (gl) {
Kernel.gl = gl;
+ (window).gl = gl;
Kernel.canvas = canvas;
break;
}
diff --git a/src/world/graphics/Poi.ts b/src/world/graphics/Poi.ts
index ddcca34..955e95a 100644
--- a/src/world/graphics/Poi.ts
+++ b/src/world/graphics/Poi.ts
@@ -24,12 +24,10 @@ precision mediump float;
void main()
{
- gl_FragColor = vec4(1.0, 1.0, 0.0, 0.5);
+ gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;
-//gl_FragColor = vec4(1.0, 1.0, 0.0, 0.5);
-
class Poi extends Graphic {
constructor(public geometry: Marker, public material: PoiMaterial){
super(geometry, material);
diff --git a/src/world/layers/PoiLayer.ts b/src/world/layers/PoiLayer.ts
index ca22020..11f2aab 100644
--- a/src/world/layers/PoiLayer.ts
+++ b/src/world/layers/PoiLayer.ts
@@ -11,7 +11,7 @@ import PerspectiveCamera = require('../PerspectiveCamera');
class PoiLayer extends GraphicGroup{
constructor(){
super();
- var p = MathUtils.geographicToCartesianCoord(0, 0, Kernel.EARTH_RADIUS + 1000000);
+ var p = MathUtils.geographicToCartesianCoord(180, 0, Kernel.EARTH_RADIUS + 1000000);
var marker = new Marker(p.x, p.y, p.z);
//var marker = new Marker(0, 0, 14198820-100);
var material = new PoiMaterial();
diff --git a/src/world/layers/SubTiledLayer.ts b/src/world/layers/SubTiledLayer.ts
index d5a9d6b..91c4ba9 100644
--- a/src/world/layers/SubTiledLayer.ts
+++ b/src/world/layers/SubTiledLayer.ts
@@ -15,19 +15,6 @@ class SubTiledLayer extends GraphicGroup {
this.level = args.level;
}
- //重写GraphicGroup的draw方法
- // draw(camera: any) {
- // /*if (this.level >= Kernel.TERRAIN_LEVEL && Kernel.globe && Kernel.globe.camera.pitch <= Kernel.TERRAIN_PITCH) {
- // Kernel.gl.clear(Kernel.gl.DEPTH_BUFFER_BIT);
- // Kernel.gl.clearDepth(1);
- // Kernel.gl.enable(Kernel.gl.DEPTH_TEST);
- // } else {
- // Kernel.gl.disable(Kernel.gl.DEPTH_TEST);
- // }*/
- // Kernel.gl.disable(Kernel.gl.DEPTH_TEST);//此处禁用深度测试是为了解决两个不同层级的切片在拖动时一起渲染会导致屏闪的问题
- // super.draw(camera);
- // }
-
//重写GraphicGroup的add方法
add(tile: Tile) {
if (tile.tileInfo.level === this.level) {
From ee9cd69fe0d6e67c7f60ca25b7f2dab7468ad86d Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Mon, 21 Nov 2016 14:27:14 +0800
Subject: [PATCH 036/109] decrease EARTH_RADIUS and MAX_PROJECTED_COORD to fix
the depth test issue,#10
---
src/world/Globe.ts | 2 +-
src/world/Kernel.ts | 4 ++--
src/world/graphics/Tile.ts | 6 +++---
src/world/layers/PoiLayer.ts | 19 ++++++++++++++-----
src/world/layers/TiledLayer.ts | 6 ++++--
src/world/math/Math.ts | 3 ++-
6 files changed, 26 insertions(+), 14 deletions(-)
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index edd26f9..abb363d 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -26,7 +26,7 @@ class Globe {
this.renderer = Kernel.renderer = new Renderer(canvas);
this.scene = new Scene();
var radio = canvas.width / canvas.height;
- this.camera = new PerspectiveCamera(30, radio, 1.0, 20000000.0);
+ this.camera = new PerspectiveCamera(30, radio, 1, Kernel.EARTH_RADIUS * 2);
this.renderer.setScene(this.scene);
this.renderer.setCamera(this.camera);
this.setLevel(0);
diff --git a/src/world/Kernel.ts b/src/world/Kernel.ts
index e408947..12d4aea 100644
--- a/src/world/Kernel.ts
+++ b/src/world/Kernel.ts
@@ -10,8 +10,8 @@ const Kernel = {
globe: null,
idCounter: 0, //Object3D对象的唯一标识
BASE_LEVEL: 6, //渲染的基准层级
- EARTH_RADIUS: 6378137,
- MAX_PROJECTED_COORD: 20037508.3427892,
+ EARTH_RADIUS: 637.8137,//6378137
+ MAX_PROJECTED_COORD: 2003.75083427892,//20037508.3427892
proxy: ""
};
diff --git a/src/world/graphics/Tile.ts b/src/world/graphics/Tile.ts
index d25d797..cde99c5 100644
--- a/src/world/graphics/Tile.ts
+++ b/src/world/graphics/Tile.ts
@@ -46,7 +46,7 @@ class TileInfo {
this.maxLat = Egeo.maxLat;
var minCoord = MathUtils.degreeGeographicToWebMercator(this.minLon, this.minLat);
var maxCoord = MathUtils.degreeGeographicToWebMercator(this.maxLon, this.maxLat);
-
+
//投影坐标范围
this.minX = minCoord[0];
this.minY = minCoord[1];
@@ -81,7 +81,7 @@ class TileInfo {
var deltaTextureCoord = 1.0 / this.segment;
var changeElevation = this.type === Enum.TERRAIN_TILE && this.elevationInfo;
//level不同设置的半径也不同
- var levelDeltaR = 0; //this.level * 100;
+ var levelDeltaR = 0;//this.level * 2;
//对WebMercator投影进行等间距划分格网
var mercatorXs: number[] = []; //存储从最小的x到最大x的分割值
var mercatorYs: number[] = []; //存储从最大的y到最小的y的分割值
@@ -117,7 +117,7 @@ class TileInfo {
verticeArray.push(v);
index++;
}
- }
+ }
//从左上到右下填充indices
//添加的点的顺序:左上->左下->右下->右上
diff --git a/src/world/layers/PoiLayer.ts b/src/world/layers/PoiLayer.ts
index 11f2aab..d655362 100644
--- a/src/world/layers/PoiLayer.ts
+++ b/src/world/layers/PoiLayer.ts
@@ -7,11 +7,20 @@ import Poi = require('../graphics/Poi');
import Marker = require('../geometries/Marker');
import PoiMaterial = require('../materials/PoiMaterial');
import PerspectiveCamera = require('../PerspectiveCamera');
+import Box = require('../geometries/Box');
+import MeshTextureMaterial = require('../materials/MeshTextureMaterial');
+import MeshGraphic = require('../graphics/MeshGraphic');
class PoiLayer extends GraphicGroup{
constructor(){
super();
- var p = MathUtils.geographicToCartesianCoord(180, 0, Kernel.EARTH_RADIUS + 1000000);
+ // var d = Kernel.EARTH_RADIUS * 2;
+ // var box = new Box(d, d, d);
+ // var material2 = new MeshTextureMaterial("http://gallery.esri.com/WebGlobe/images/test.png");
+ // var boxGraphic = new MeshGraphic(box, material2);
+ // this.add(boxGraphic);
+
+ var p = MathUtils.geographicToCartesianCoord(0, 0, Kernel.EARTH_RADIUS * 1.2);
var marker = new Marker(p.x, p.y, p.z);
//var marker = new Marker(0, 0, 14198820-100);
var material = new PoiMaterial();
@@ -19,10 +28,10 @@ class PoiLayer extends GraphicGroup{
this.add(poi);
}
- draw(camera: PerspectiveCamera){
- Kernel.gl.enable(Kernel.gl.DEPTH_TEST);
- super.draw(camera);
- }
+ // draw(camera: PerspectiveCamera){
+ // Kernel.gl.enable(Kernel.gl.DEPTH_TEST);
+ // super.draw(camera);
+ // }
}
export = PoiLayer;
\ No newline at end of file
diff --git a/src/world/layers/TiledLayer.ts b/src/world/layers/TiledLayer.ts
index d68af50..2892845 100644
--- a/src/world/layers/TiledLayer.ts
+++ b/src/world/layers/TiledLayer.ts
@@ -8,9 +8,11 @@ abstract class TiledLayer extends GraphicGroup {
//重写
draw(camera: PerspectiveCamera){
- Kernel.gl.disable(Kernel.gl.DEPTH_TEST);//此处禁用深度测试是为了解决两个不同层级的切片在拖动时一起渲染会导致屏闪的问题
+ //此处将深度测试设置为ALWAYS是为了解决两个不同层级的切片在拖动时一起渲染会导致屏闪的问题
+ Kernel.gl.depthFunc(Kernel.gl.ALWAYS);
super.draw(camera);
- Kernel.gl.enable(Kernel.gl.DEPTH_TEST);//恢复深度测试
+ //将深度测试恢复成LEQUAL
+ Kernel.gl.depthFunc(Kernel.gl.LEQUAL);
}
//重写
diff --git a/src/world/math/Math.ts b/src/world/math/Math.ts
index be778ef..76f419d 100644
--- a/src/world/math/Math.ts
+++ b/src/world/math/Math.ts
@@ -331,7 +331,8 @@ const MathUtils = {
* @return {*}
*/
getLengthFromCamera2EarthSurface(level: number): number{
- return 7820683 / Math.pow(2, level);
+ //7820683
+ return 1.2261704318988444 * Kernel.EARTH_RADIUS / Math.pow(2, level);
},
/**将经纬度转换为笛卡尔空间直角坐标系中的x、y、z
From baa08021846432255153e097a81e24a5e204691f Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Mon, 21 Nov 2016 15:57:33 +0800
Subject: [PATCH 037/109] increase EARTH_RADIUS and MAX_PROJECTED_COORD to let
level14 visible,#10
---
src/world/Kernel.ts | 4 ++--
src/world/math/Math.ts | 3 ++-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/world/Kernel.ts b/src/world/Kernel.ts
index 12d4aea..6a0484c 100644
--- a/src/world/Kernel.ts
+++ b/src/world/Kernel.ts
@@ -10,8 +10,8 @@ const Kernel = {
globe: null,
idCounter: 0, //Object3D对象的唯一标识
BASE_LEVEL: 6, //渲染的基准层级
- EARTH_RADIUS: 637.8137,//6378137
- MAX_PROJECTED_COORD: 2003.75083427892,//20037508.3427892
+ EARTH_RADIUS: 637.8137*26,//6378137
+ MAX_PROJECTED_COORD: 2003.75083427892*26,//20037508.3427892
proxy: ""
};
diff --git a/src/world/math/Math.ts b/src/world/math/Math.ts
index 76f419d..56c5e6f 100644
--- a/src/world/math/Math.ts
+++ b/src/world/math/Math.ts
@@ -332,7 +332,8 @@ const MathUtils = {
*/
getLengthFromCamera2EarthSurface(level: number): number{
//7820683
- return 1.2261704318988444 * Kernel.EARTH_RADIUS / Math.pow(2, level);
+ //1.2261704318988444 * Kernel.EARTH_RADIUS / Math.pow(2, level);
+ return Kernel.EARTH_RADIUS / Math.pow(2, level);
},
/**将经纬度转换为笛卡尔空间直角坐标系中的x、y、z
From 07a5d873222c7c48013b29f0a229c7cf4dd9737b Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Mon, 21 Nov 2016 17:18:00 +0800
Subject: [PATCH 038/109] fix the depth test issue,#10
---
package.json | 2 +-
src/world/Kernel.ts | 7 +++++--
src/world/math/Math.ts | 2 +-
versions.txt | 4 +++-
4 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/package.json b/package.json
index 11b1239..01c3981 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "webglobe",
- "version": "0.2.3",
+ "version": "0.2.4",
"description": "A WebGL virtual globe and map engine.",
"main": "require.js",
"scripts": {
diff --git a/src/world/Kernel.ts b/src/world/Kernel.ts
index 6a0484c..e3ad69d 100644
--- a/src/world/Kernel.ts
+++ b/src/world/Kernel.ts
@@ -3,6 +3,9 @@ import {WebGLRenderingContextExtension} from './Definitions';
import Globe = require("./Globe");
import Renderer = require("./Renderer");
+const radius = 14000;//6378137
+const maxProjectedCoord = Math.PI * radius;
+
const Kernel = {
gl: null,
canvas: null,
@@ -10,8 +13,8 @@ const Kernel = {
globe: null,
idCounter: 0, //Object3D对象的唯一标识
BASE_LEVEL: 6, //渲染的基准层级
- EARTH_RADIUS: 637.8137*26,//6378137
- MAX_PROJECTED_COORD: 2003.75083427892*26,//20037508.3427892
+ EARTH_RADIUS: radius,
+ MAX_PROJECTED_COORD: maxProjectedCoord,
proxy: ""
};
diff --git a/src/world/math/Math.ts b/src/world/math/Math.ts
index 56c5e6f..c6b909c 100644
--- a/src/world/math/Math.ts
+++ b/src/world/math/Math.ts
@@ -333,7 +333,7 @@ const MathUtils = {
getLengthFromCamera2EarthSurface(level: number): number{
//7820683
//1.2261704318988444 * Kernel.EARTH_RADIUS / Math.pow(2, level);
- return Kernel.EARTH_RADIUS / Math.pow(2, level);
+ return 1.23 * Kernel.EARTH_RADIUS / Math.pow(2, level);
},
/**将经纬度转换为笛卡尔空间直角坐标系中的x、y、z
diff --git a/versions.txt b/versions.txt
index ddff7c5..80869e4 100644
--- a/versions.txt
+++ b/versions.txt
@@ -92,4 +92,6 @@
0.2.2 删除高程相关代码
-0.2.3 将world/geometries/Geomtry重命名为world/geometries/Mesh,并在package.json中添加了多个npm scripts,对应gulp中定义的tasks
\ No newline at end of file
+0.2.3 将world/geometries/Geomtry重命名为world/geometries/Mesh,并在package.json中添加了多个npm scripts,对应gulp中定义的tasks
+
+0.2.4 之前EARTH_RADIUS的值为6378137,特别大,导致了深度值计算有问题,从而使得深度测试不能正常进行。将EARTH_RADIUS改成14000,使得深度测试可以正常进行。并加入了Poi和PoiLayer这两个类。
\ No newline at end of file
From 95c7af2c0d67f65fceec80b6edf4b1760494d13a Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Mon, 21 Nov 2016 18:47:47 +0800
Subject: [PATCH 039/109] basically make Poi display marker with texture,#12
---
src/world/Renderer.ts | 2 +-
src/world/graphics/MeshGraphic.ts | 24 +++++++------
src/world/graphics/Poi.ts | 32 +++++++++++++----
src/world/images/poi.png | Bin 0 -> 336 bytes
src/world/layers/PoiLayer.ts | 16 ++-------
src/world/materials/MeshTextureMaterial.ts | 38 ++++++++++++---------
src/world/materials/PoiMaterial.ts | 16 ++++-----
src/world/math/Math.ts | 2 --
8 files changed, 71 insertions(+), 59 deletions(-)
create mode 100644 src/world/images/poi.png
diff --git a/src/world/Renderer.ts b/src/world/Renderer.ts
index 9d9bd99..9b57df6 100644
--- a/src/world/Renderer.ts
+++ b/src/world/Renderer.ts
@@ -48,7 +48,7 @@ class Renderer {
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
- gl.depthMask(true);
+ gl.depthMask(true);//允许写入深度
gl.enable(gl.CULL_FACE); //一定要启用裁剪,否则显示不出立体感
gl.frontFace(gl.CCW);//指定逆时针方向为正面
diff --git a/src/world/graphics/MeshGraphic.ts b/src/world/graphics/MeshGraphic.ts
index d9ced79..b94b888 100644
--- a/src/world/graphics/MeshGraphic.ts
+++ b/src/world/graphics/MeshGraphic.ts
@@ -54,31 +54,35 @@ class MeshGraphic extends Graphic {
}
_drawTextureMaterial(program: any) {
+ var gl = Kernel.gl;
+
//set aUV
var locUV = program.getAttribLocation('aUV');
program.enableVertexAttribArray('aUV');
this.geometry.uvbo.bind();
- Kernel.gl.vertexAttribPointer(locUV, 2, Kernel.gl.FLOAT, false, 0, 0);
+ gl.vertexAttribPointer(locUV, 2, gl.FLOAT, false, 0, 0);
//set uSampler
var locSampler = program.getUniformLocation('uSampler');
- Kernel.gl.activeTexture(Kernel.gl.TEXTURE0);
+ gl.activeTexture(gl.TEXTURE0);
//world.Cache.activeTexture(gl.TEXTURE0);
- Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, this.material.texture);
- Kernel.gl.uniform1i(locSampler, 0);
+ gl.bindTexture(gl.TEXTURE_2D, this.material.texture);
+ gl.uniform1i(locSampler, 0);
}
onDraw(camera: PerspectiveCamera) {
+ var gl = Kernel.gl;
+
//aPosition
var locPosition = this.program.getAttribLocation('aPosition');
this.program.enableVertexAttribArray('aPosition');
this.geometry.vbo.bind();
- Kernel.gl.vertexAttribPointer(locPosition, 3, Kernel.gl.FLOAT, false, 0, 0);
+ gl.vertexAttribPointer(locPosition, 3, gl.FLOAT, false, 0, 0);
//uPMVMatrix
var pmvMatrix = camera.projViewMatrix.multiplyMatrix(this.geometry.matrix);
var locPMVMatrix = this.program.getUniformLocation('uPMVMatrix');
- Kernel.gl.uniformMatrix4fv(locPMVMatrix, false, pmvMatrix.elements);
+ gl.uniformMatrix4fv(locPMVMatrix, false, pmvMatrix.elements);
this._drawTextureMaterial(this.program);
@@ -87,12 +91,12 @@ class MeshGraphic extends Graphic {
//绘图
var count = this.geometry.triangles.length * 3;
- Kernel.gl.drawElements(Kernel.gl.TRIANGLES, count, Kernel.gl.UNSIGNED_SHORT, 0);
+ gl.drawElements(gl.TRIANGLES, count, gl.UNSIGNED_SHORT, 0);
//释放当前绑定对象
- Kernel.gl.bindBuffer(Kernel.gl.ARRAY_BUFFER, null);
- Kernel.gl.bindBuffer(Kernel.gl.ELEMENT_ARRAY_BUFFER, null);
- Kernel.gl.bindTexture(Kernel.gl.TEXTURE_2D, null);
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+ gl.bindTexture(gl.TEXTURE_2D, null);
}
}
diff --git a/src/world/graphics/Poi.ts b/src/world/graphics/Poi.ts
index 955e95a..e694076 100644
--- a/src/world/graphics/Poi.ts
+++ b/src/world/graphics/Poi.ts
@@ -11,20 +11,22 @@ const vs =
`
attribute vec3 aPosition;
uniform mat4 uPMVMatrix;
+uniform float uSize;
void main(void) {
gl_Position = uPMVMatrix * vec4(aPosition, 1.0);
- gl_PointSize = 10.0;
+ gl_PointSize = uSize;
}
`;
const fs =
`
precision mediump float;
+uniform sampler2D uSampler;
void main()
{
- gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+ gl_FragColor = texture2D(uSampler, gl_PointCoord);
}
`;
@@ -38,19 +40,37 @@ class Poi extends Graphic {
}
onDraw(camera: PerspectiveCamera){
+ var gl = Kernel.gl;
+
//aPosition
var locPosition = this.program.getAttribLocation('aPosition');
this.program.enableVertexAttribArray('aPosition');
this.geometry.vbo.bind();
- Kernel.gl.vertexAttribPointer(locPosition, 3, Kernel.gl.FLOAT, false, 0, 0);
+ gl.vertexAttribPointer(locPosition, 3, gl.FLOAT, false, 0, 0);
//uPMVMatrix
- var pmvMatrix = camera.projViewMatrix;//.multiplyMatrix(this.geometry.matrix);
+ var pmvMatrix = camera.projViewMatrix;
var locPMVMatrix = this.program.getUniformLocation('uPMVMatrix');
- Kernel.gl.uniformMatrix4fv(locPMVMatrix, false, pmvMatrix.elements);
+ gl.uniformMatrix4fv(locPMVMatrix, false, pmvMatrix.elements);
+
+ //uSize
+ var locSize = this.program.getUniformLocation('uSize');
+ gl.uniform1f(locSize, this.material.size);
+
+ //set uSampler
+ var locSampler = this.program.getUniformLocation('uSampler');
+ gl.activeTexture(gl.TEXTURE0);
+ //world.Cache.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, this.material.texture);
+ gl.uniform1i(locSampler, 0);
//绘图,1表示1个点
- Kernel.gl.drawArrays(Kernel.gl.POINTS, 0, 1);
+ gl.drawArrays(gl.POINTS, 0, 1);
+
+ //释放当前绑定对象
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+ gl.bindTexture(gl.TEXTURE_2D, null);
}
}
diff --git a/src/world/images/poi.png b/src/world/images/poi.png
new file mode 100644
index 0000000000000000000000000000000000000000..dc00c817391fb51fd4a0769d87c63cca8ffa5b61
GIT binary patch
literal 336
zcmV-W0k8gvP)owzhkfva$9o_19cD&|e=3xFLm>64pcih+pL{~OJw)?ite|J+%Hfgh3ktVG
zbOztJ>D$mVW4F}d(Gwj9S0mi(bDVYO$hKw*dS>i6<9I<#dq%Nm;j}YDswt7awxMUn
zjx&xI#0xqSwJ+>9Bx08q_Nq4Y%-C_p@q$`!gvjwbcF!l+Dar-bFH&XfIJ49}T-<#i
zoHwzpSqN)Wh4PDxohvUXUmsvI^NFpase+!FtAF9J@`zwYD(J;3w2?MJ#Hv(knIM02
i!!UfplP6D})>uECV*Fl>dLzmJ0000
-import Material = require("./Material");
+import MeshTextureMaterial = require("./MeshTextureMaterial");
-class PoiMaterial implements Material{
-
- isReady(){
- return true;
+type ImageType = string | HTMLImageElement;
+
+class PoiMaterial extends MeshTextureMaterial{
+
+ constructor(imageOrUrl?: ImageType, public size:number = 16){
+ super(imageOrUrl, true);
}
getType(){
return "PoiMaterial";
}
-
- destroy(){
-
- }
}
export = PoiMaterial;
\ No newline at end of file
diff --git a/src/world/math/Math.ts b/src/world/math/Math.ts
index c6b909c..2f21e1d 100644
--- a/src/world/math/Math.ts
+++ b/src/world/math/Math.ts
@@ -331,8 +331,6 @@ const MathUtils = {
* @return {*}
*/
getLengthFromCamera2EarthSurface(level: number): number{
- //7820683
- //1.2261704318988444 * Kernel.EARTH_RADIUS / Math.pow(2, level);
return 1.23 * Kernel.EARTH_RADIUS / Math.pow(2, level);
},
From 59b35c7a4edf895b5fe15f74f3bdca802df1a9be Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Mon, 21 Nov 2016 18:48:02 +0800
Subject: [PATCH 040/109] add comment
---
src/world/graphics/MeshGraphic.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/world/graphics/MeshGraphic.ts b/src/world/graphics/MeshGraphic.ts
index b94b888..88bde17 100644
--- a/src/world/graphics/MeshGraphic.ts
+++ b/src/world/graphics/MeshGraphic.ts
@@ -21,6 +21,7 @@ void main()
}
`;
+//http://stackoverflow.com/questions/3497068/textured-points-in-opengl-es-2-0
const fs =
`
precision mediump float;
From 205268c392f0f6a86502951089655a1996732fc1 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Mon, 21 Nov 2016 23:23:09 +0800
Subject: [PATCH 041/109] enable blend for poi,#12
---
src/world/graphics/MeshGraphic.ts | 1 -
src/world/graphics/Poi.ts | 7 ++++++-
src/world/images/pin.png | Bin 0 -> 2428 bytes
src/world/layers/PoiLayer.ts | 4 ++--
src/world/materials/PoiMaterial.ts | 2 +-
5 files changed, 9 insertions(+), 5 deletions(-)
create mode 100644 src/world/images/pin.png
diff --git a/src/world/graphics/MeshGraphic.ts b/src/world/graphics/MeshGraphic.ts
index 88bde17..b94b888 100644
--- a/src/world/graphics/MeshGraphic.ts
+++ b/src/world/graphics/MeshGraphic.ts
@@ -21,7 +21,6 @@ void main()
}
`;
-//http://stackoverflow.com/questions/3497068/textured-points-in-opengl-es-2-0
const fs =
`
precision mediump float;
diff --git a/src/world/graphics/Poi.ts b/src/world/graphics/Poi.ts
index e694076..f32066b 100644
--- a/src/world/graphics/Poi.ts
+++ b/src/world/graphics/Poi.ts
@@ -19,6 +19,7 @@ void main(void) {
}
`;
+//http://stackoverflow.com/questions/3497068/textured-points-in-opengl-es-2-0
const fs =
`
precision mediump float;
@@ -26,7 +27,7 @@ uniform sampler2D uSampler;
void main()
{
- gl_FragColor = texture2D(uSampler, gl_PointCoord);
+ gl_FragColor = texture2D(uSampler, vec2(gl_PointCoord.x, 1.0 - gl_PointCoord.y));
}
`;
@@ -42,6 +43,9 @@ class Poi extends Graphic {
onDraw(camera: PerspectiveCamera){
var gl = Kernel.gl;
+ gl.enable(gl.BLEND);
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+
//aPosition
var locPosition = this.program.getAttribLocation('aPosition');
this.program.enableVertexAttribArray('aPosition');
@@ -68,6 +72,7 @@ class Poi extends Graphic {
gl.drawArrays(gl.POINTS, 0, 1);
//释放当前绑定对象
+ gl.disable(gl.BLEND);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
gl.bindTexture(gl.TEXTURE_2D, null);
diff --git a/src/world/images/pin.png b/src/world/images/pin.png
new file mode 100644
index 0000000000000000000000000000000000000000..727591d3e4d91eae6349049cb393cd2d8ac83827
GIT binary patch
literal 2428
zcmV-?34`{DP);9F?VL}%$#5USU?sKfu7{#%t_9i-{<$6`F_tKoJONr
zivZBU8N;$-qLwQvUONwT({iA3K!QUBk_;kX^yQ%4Z-U>Pcg$YmbO0Ct&$$b{qZgt%
zf!fkL6d8J(oc-h(!W}S3`5_670Tu{6V9y$`(12^6I5wHn0l<}y1BwCL28b-ZE&VjJ
zy2Kr=w1
z3#{e>*a}uZ#mJcoGD^fDhPnb>{g=}RNL}?Sn1+G46@wKsVMHT-*QgPgJh20$#~D^T
zLq-FHK?JNG#o+p95}&SN))RmVG2yQJKr(W8KY1#_JHPW+L}JaTmI^2rvZ!@;!>d<|
zqsNZp+0LgSH^u5KtZ=Xapdd(MXIlL1HzeE(#y)V6Gp4nEWkp->WANaOS=L
zMsw>(%wF&fOdEeGKH2<^u(vN~t8?@NrBZQb=h(BWm_R32fl0sUhHjVu0I!k*D!
znwa`VAV`li_^Lr>K=+E73xsh$sjdN==hQRE?SDKlEr6&hk6(yJt6n
z`(8bc48QUyM0yn1tpfl!@FBDasd545Ty~|1#^NCnT@2-~)+G`V3YFh*g{q!kxNQ;SNa
zM{!HKom8kou<8<8^u?A`b0U?r6q6K%Vu_WAlCKCx!=o_2Pu24~g%fG&VXM8LLqD&A
z;6VTY5d#3;xMyg3IQXnZAUdQ<1~U^_F@nGpQKM5i^>Acso858#r7PN+V_zEGnh2$C
z$WlGzY|*B=T|q57fa-x=?Bw^tEoFkRmYd0-4MIqAC)~(z3d8apUV+!|24DRI;5o2H
zb^ri7wdy@GYW`eEtsPNACC)g@>1d57$F;?jrW>;CDz4V*S=KJDq*zc%IT3
zW5X~-$pvTfHf8cQYSl98g?*?OGVGKF$*W`s1GhGvK^dV%h;)m&Gyr|aD=52_VO1FR
z4+yD2DFv_sfLXe(W8#>$FqJg4x-xmjxCD}BM3g*2#jaDaT8CY?;Z}0&RC46iimFj7
z$iS;V45Ew>Qi4?orwBw7#{>tCvSI;-6hsHlyFG0w3llq1blH@#ls0{`A|bKVP^>yA
zR2-D5b-2|c4h8pWdFi{gOh8z>qKlHZWZ_lw?9~d?uuBLV&TnKi?nkE2
z5mGlHr`>_j_deHWJ~N_Oi=b==y!t-g=_hFNxnuYA?%X$FRBO`(x*iFwSWIe~#v6Nf
zQN;tQwu^c>3#YsvUNx`0N>&6;Whv>21wuDPBsE?MFi83EHa_*a0K-&(S&I<6>Tx(;
zz}WUNFe3Tm-c<79gk_xV`bwFmCC(i`8XG?xK(0`Mva|52Ie3*U0@ntOJin!7&HYf(
zh|1mg9|)}%RDJt|PCML+$IV6{1mewc7!x|E(G<6{+2Y!U64x0~y`|y%DuhJ3HASIf
zE|e-%uawZRixg?@fNbgaJs6u?QVG8)Zc3juRzjC0+vi-NNUmLlQYxs|%9`uc=K^?&h$Mh8c;)*i
z1Q;g6b?erlDcJ-+2%)$t8omk~XW;s)zIN{1<~47tr8_k0%ca;bOzE=>U7wj5LTVZX
zPF)R2m`~}Fb9nLmdGj%U-hAY8IWULhI&~Fz_NWV{Oj`6&Z$EV5i!WO}kM#BIyKe8k
zOz*yZ8JW)=kd;zi*p(7o$JPVC(Fj$zJ`4kdDjWj(f~En05CYfEz81IL`dv)F=t3|L
zofqYDdC{KTySuUn4qz~wU;o<$k3I+>C{Fw3RJ3(mCp7KbLeO+DS`@3A3d02?#CDJ%
z&5W^MEq@^Z0l@wD-H+DRR$Tw}>(P=*$*!(3VP9YWy~%j|@&B%WOYO;ID$7@_xXiYz
zAK7DX(!#DQg5HHQL09|5M
zlWMljl0S&lC|sB
zp>OBTe?I)sL*IM(<(I_`H{789xNsrzyWYnmeUktL06GCu1Q0_VbUZHu#HRu)Z~Nj;
zz|45*#g|~3rqCi0RVkP6oH6~vXWo7H9rS}@?g&hCMMYZdd_resnWhM^WLSO8WEQl8Rn{=@()mMw#6
zn&{~41T!bMba(gn_4fyZ+3cN9Em`t|>0Jj~EYib%Obk?;Ngxj7Fo)
zp6A72D?NY%?PN(TTo*alb-Q_5Tb0000
Date: Mon, 21 Nov 2016 23:59:02 +0800
Subject: [PATCH 042/109] update,#12
---
src/world/graphics/Poi.ts | 2 ++
src/world/layers/PoiLayer.ts | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/world/graphics/Poi.ts b/src/world/graphics/Poi.ts
index f32066b..1dde278 100644
--- a/src/world/graphics/Poi.ts
+++ b/src/world/graphics/Poi.ts
@@ -43,6 +43,7 @@ class Poi extends Graphic {
onDraw(camera: PerspectiveCamera){
var gl = Kernel.gl;
+ gl.disable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
@@ -72,6 +73,7 @@ class Poi extends Graphic {
gl.drawArrays(gl.POINTS, 0, 1);
//释放当前绑定对象
+ gl.enable(gl.DEPTH_TEST);
gl.disable(gl.BLEND);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
diff --git a/src/world/layers/PoiLayer.ts b/src/world/layers/PoiLayer.ts
index d42e4ae..821052a 100644
--- a/src/world/layers/PoiLayer.ts
+++ b/src/world/layers/PoiLayer.ts
@@ -13,7 +13,7 @@ class PoiLayer extends GraphicGroup{
constructor(){
super();
- var p = MathUtils.geographicToCartesianCoord(0, 0, Kernel.EARTH_RADIUS);
+ var p = MathUtils.geographicToCartesianCoord(116.408540, 39.902350, Kernel.EARTH_RADIUS);
var marker = new Marker(p.x, p.y, p.z);
var url = "/WebGlobe/src/world/images/poi.png";
var material = new PoiMaterial(url, 24);
From 46b03554fbd06f7e1fa54420007c091b6a8433f7 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Tue, 22 Nov 2016 00:13:23 +0800
Subject: [PATCH 043/109] upadte poi,#12
---
src/world/graphics/Poi.ts | 4 ++--
src/world/layers/PoiLayer.ts | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/world/graphics/Poi.ts b/src/world/graphics/Poi.ts
index 1dde278..8b741f9 100644
--- a/src/world/graphics/Poi.ts
+++ b/src/world/graphics/Poi.ts
@@ -43,7 +43,7 @@ class Poi extends Graphic {
onDraw(camera: PerspectiveCamera){
var gl = Kernel.gl;
- gl.disable(gl.DEPTH_TEST);
+ //gl.disable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
@@ -73,7 +73,7 @@ class Poi extends Graphic {
gl.drawArrays(gl.POINTS, 0, 1);
//释放当前绑定对象
- gl.enable(gl.DEPTH_TEST);
+ //gl.enable(gl.DEPTH_TEST);
gl.disable(gl.BLEND);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
diff --git a/src/world/layers/PoiLayer.ts b/src/world/layers/PoiLayer.ts
index 821052a..214b7d1 100644
--- a/src/world/layers/PoiLayer.ts
+++ b/src/world/layers/PoiLayer.ts
@@ -13,7 +13,7 @@ class PoiLayer extends GraphicGroup{
constructor(){
super();
- var p = MathUtils.geographicToCartesianCoord(116.408540, 39.902350, Kernel.EARTH_RADIUS);
+ var p = MathUtils.geographicToCartesianCoord(116.408540, 39.902350, Kernel.EARTH_RADIUS + 0.001);
var marker = new Marker(p.x, p.y, p.z);
var url = "/WebGlobe/src/world/images/poi.png";
var material = new PoiMaterial(url, 24);
From f71c63f670e3268e392a865754fa11bcc771aa22 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Fri, 25 Nov 2016 15:52:59 +0800
Subject: [PATCH 044/109] calculate camera.far after call camera._setLevel()
method
---
src/world/PerspectiveCamera.ts | 45 +++++++++++++++++++++++++---------
1 file changed, 33 insertions(+), 12 deletions(-)
diff --git a/src/world/PerspectiveCamera.ts b/src/world/PerspectiveCamera.ts
index 4517526..f5cdcb6 100644
--- a/src/world/PerspectiveCamera.ts
+++ b/src/world/PerspectiveCamera.ts
@@ -22,14 +22,14 @@ class PerspectiveCamera extends Object3D {
};
private animating: boolean = false;
- constructor(public fov = 90, public aspect = 1, public near = 1, public far = 1) {
+ constructor(public fov = 45, public aspect = 1, public near = 1, public far = 100) {
super();
this.pitch = 90;
this.projMatrix = new Matrix();
this.setPerspectiveMatrix(this.fov, this.aspect, this.near, this.far);
}
- setPerspectiveMatrix(fov: number = 90, aspect: number = 1, near: number = 1, far: number = 1): void {
+ setPerspectiveMatrix(fov: number = 45, aspect: number = 1, near: number = 1, far: number = 100): void {
//https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/mat4.js#L1788
this.fov = fov;
this.aspect = aspect;
@@ -68,6 +68,12 @@ class PerspectiveCamera extends Object3D {
return direction;
}
+ getDistance2EarthSurface(): number {
+ var position = this.getPosition();
+ var length2EarthSurface = Vector.fromVertice(position).getLength() - Kernel.EARTH_RADIUS;
+ return length2EarthSurface;
+ }
+
//获取投影矩阵与视点矩阵的乘积
getProjViewMatrix(): Matrix {
var viewMatrix = this.getViewMatrix();
@@ -294,19 +300,19 @@ class PerspectiveCamera extends Object3D {
}
animateToLevel(level: number): void {
- var newMat = this._animateToLevel(level);
- this._animateToMatrix(newMat, () => {
+ var newCamera = this._animateToLevel(level);
+ this._animateToCamera(newCamera, () => {
Kernel.globe.CURRENT_LEVEL = level;
});
}
- private _animateToMatrix(newMat: Matrix, cb: ()=>void){
+ private _animateToCamera(newCamera: PerspectiveCamera, cb: ()=>void){
if(this.isAnimating()){
return;
}
this.animating = true;
var oldPosition = this.getPosition();
- var newPosition = newMat.getPosition();
+ var newPosition = newCamera.matrix.getPosition();
var span = this.animationDuration;
var singleSpan = 1000 / 60;
var count = Math.floor(span / singleSpan);
@@ -320,7 +326,7 @@ class PerspectiveCamera extends Object3D {
}
var a = timestap - start;
if(a >= span){
- this.matrix = newMat;
+ (Object).assign(this, newCamera.toJson());
this.animating = false;
cb();
}else{
@@ -332,24 +338,34 @@ class PerspectiveCamera extends Object3D {
requestAnimationFrame(callback);
}
- private _animateToLevel(level: number): Matrix{
+ private _animateToLevel(level: number): PerspectiveCamera{
if (!(Utils.isNonNegativeInteger(level))) {
throw "invalid level:" + level;
}
var camera = this._clone();
//don't call setLevel method because it will update CURRENT_LEVEL
camera._setLevel(level);
- return camera.matrix;
+ return camera;
}
private _clone(): PerspectiveCamera{
var camera: PerspectiveCamera = new PerspectiveCamera();
- camera.pitch = this.pitch;
- camera.matrix = this.matrix.clone();
- camera.projMatrix = this.projMatrix.clone();
+ (Object).assign(camera, this.toJson());
return camera;
}
+ toJson(): any {
+ return {
+ pitch: this.pitch,
+ near: this.near,
+ far: this.far,
+ fov: this.fov,
+ aspect: this.aspect,
+ matrix: this.matrix.clone(),
+ projMatrix: this.projMatrix.clone()
+ };
+ }
+
setLevel(level: number): void{
this._setLevel(level);
//don't update CURRENT_LEVEL in _setLevel method because it will affect animateToLevel method
@@ -379,6 +395,11 @@ class PerspectiveCamera extends Object3D {
var pNew = Vector.verticePlusVector(pOld, dir);
this.setPosition(pNew.x, pNew.y, pNew.z);
}
+ //重新计算far,保持far在满足正常需求情况下的最小值
+ //far值:视点与地球切面的距离
+ var length2EarthOrigin = Vector.fromVertice(this.getPosition()).getLength();
+ var far = Math.sqrt(length2EarthOrigin * length2EarthOrigin - Kernel.EARTH_RADIUS * Kernel.EARTH_RADIUS);
+ this.setFar(far * 1.05);
}
//判断世界坐标系中的点是否在Canvas中可见
From 8ea998dbd8d72004f70eacd218b664703565a50f Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Fri, 25 Nov 2016 15:53:53 +0800
Subject: [PATCH 045/109] add vscode settings.json
---
.vscode/settings.json | 3 +++
1 file changed, 3 insertions(+)
create mode 100644 .vscode/settings.json
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..ccdda08
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "typescript.check.workspaceVersion": false
+}
\ No newline at end of file
From b6e42a1c19a856694bf6bbecc1bb664e100f74cf Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Fri, 25 Nov 2016 18:07:42 +0800
Subject: [PATCH 046/109] update
---
src/world/PerspectiveCamera.ts | 59 ++++++++++++++++++++++------------
src/world/geometries/Marker.ts | 5 ++-
2 files changed, 42 insertions(+), 22 deletions(-)
diff --git a/src/world/PerspectiveCamera.ts b/src/world/PerspectiveCamera.ts
index f5cdcb6..70a7694 100644
--- a/src/world/PerspectiveCamera.ts
+++ b/src/world/PerspectiveCamera.ts
@@ -14,7 +14,7 @@ class PerspectiveCamera extends Object3D {
private animationDuration = 600;//层级变化的动画周期是600毫秒
pitch: number;
viewMatrix: Matrix;
- projMatrix: Matrix;
+ projMatrix: Matrix;//当Matrix变化的时候,需要重新计算this.far
projViewMatrix: Matrix;
Enum: any = {
EARTH_FULL_OVERSPREAD_SCREEN: "EARTH_FULL_OVERSPREAD_SCREEN", //Canvas内全部被地球充满
@@ -26,10 +26,15 @@ class PerspectiveCamera extends Object3D {
super();
this.pitch = 90;
this.projMatrix = new Matrix();
- this.setPerspectiveMatrix(this.fov, this.aspect, this.near, this.far);
+ this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, this.far);
}
- setPerspectiveMatrix(fov: number = 45, aspect: number = 1, near: number = 1, far: number = 100): void {
+ _setPerspectiveMatrix(fov: number = 45, aspect: number = 1, near: number = 1, far: number = 100): void {
+ this._rawSetPerspectiveMatrix(fov, aspect, near, far);
+ this._updateFar();
+ }
+
+ _rawSetPerspectiveMatrix(fov: number = 45, aspect: number = 1, near: number = 1, far: number = 100): void {
//https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/mat4.js#L1788
this.fov = fov;
this.aspect = aspect;
@@ -85,28 +90,37 @@ class PerspectiveCamera extends Object3D {
if (!(fov > 0)) {
throw "invalid fov:" + fov;
}
- this.setPerspectiveMatrix(fov, this.aspect, this.near, this.far);
+ this._setPerspectiveMatrix(fov, this.aspect, this.near, this.far);
}
setAspect(aspect: number): void {
if (!(aspect > 0)) {
throw "invalid aspect:" + aspect;
}
- this.setPerspectiveMatrix(this.fov, aspect, this.near, this.far);
+ this._setPerspectiveMatrix(this.fov, aspect, this.near, this.far);
}
setNear(near: number): void {
if (!(near > 0)) {
throw "invalid near:" + near;
}
- this.setPerspectiveMatrix(this.fov, this.aspect, near, this.far);
+ this._setPerspectiveMatrix(this.fov, this.aspect, near, this.far);
}
- setFar(far: number): void {
- if (!(far > 0)) {
- throw "invalid far:" + far;
- }
- this.setPerspectiveMatrix(this.fov, this.aspect, this.near, far);
+ // setFar(far: number): void {
+ // if (!(far > 0)) {
+ // throw "invalid far:" + far;
+ // }
+ // this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, far);
+ // }
+
+ _updateFar():void{
+ //重新计算far,保持far在满足正常需求情况下的最小值
+ //far值:视点与地球切面的距离
+ var length2EarthOrigin = Vector.fromVertice(this.getPosition()).getLength();
+ var far = Math.sqrt(length2EarthOrigin * length2EarthOrigin - Kernel.EARTH_RADIUS * Kernel.EARTH_RADIUS);
+ far *= 1.05;
+ this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, far);
}
getViewMatrix(): Matrix {
@@ -119,8 +133,14 @@ class PerspectiveCamera extends Object3D {
return this.viewMatrix;
}
+ updateProjMatrix(): Matrix{
+ this._updateFar();
+ return this.projMatrix;
+ }
+
updateProjViewMatrix(): Matrix{
this.updateViewMatrix();
+ this.updateProjMatrix();
this.projViewMatrix = this.projMatrix.multiplyMatrix(this.viewMatrix);
return this.projViewMatrix;
}
@@ -142,11 +162,13 @@ class PerspectiveCamera extends Object3D {
this.matrix.setColumnTrans(transX, transY, transZ); //此处相当于对Camera的模型矩阵(不是视点矩阵)设置偏移量
this.matrix.setLastRowDefault();
- var deltaX = cameraPntCopy.x - targetPntCopy.x;
- var deltaY = cameraPntCopy.y - targetPntCopy.y;
- var deltaZ = cameraPntCopy.z - targetPntCopy.z;
- var far = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
- this.setFar(far);
+ // var deltaX = cameraPntCopy.x - targetPntCopy.x;
+ // var deltaY = cameraPntCopy.y - targetPntCopy.y;
+ // var deltaZ = cameraPntCopy.z - targetPntCopy.z;
+ // var far = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
+ // this.setFar(far);
+
+ this._updateFar();
}
lookAt(targetPnt: Vertice, upDirection?: Vector): void {
@@ -395,11 +417,6 @@ class PerspectiveCamera extends Object3D {
var pNew = Vector.verticePlusVector(pOld, dir);
this.setPosition(pNew.x, pNew.y, pNew.z);
}
- //重新计算far,保持far在满足正常需求情况下的最小值
- //far值:视点与地球切面的距离
- var length2EarthOrigin = Vector.fromVertice(this.getPosition()).getLength();
- var far = Math.sqrt(length2EarthOrigin * length2EarthOrigin - Kernel.EARTH_RADIUS * Kernel.EARTH_RADIUS);
- this.setFar(far * 1.05);
}
//判断世界坐标系中的点是否在Canvas中可见
diff --git a/src/world/geometries/Marker.ts b/src/world/geometries/Marker.ts
index 4f13c19..c76a9c0 100644
--- a/src/world/geometries/Marker.ts
+++ b/src/world/geometries/Marker.ts
@@ -15,7 +15,10 @@ class Marker implements Geometry{
this.vbo.unbind();
}
- destroy(){}
+ destroy(){
+ this.vbo.destroy();
+ this.vbo = null;
+ }
}
export = Marker;
\ No newline at end of file
From 83b0fb6f3231da34a8ac74af37ed5e8b10523c27 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Fri, 25 Nov 2016 19:31:49 +0800
Subject: [PATCH 047/109] update depth
---
src/world/Event.ts | 4 +-
src/world/Globe.ts | 3 +-
src/world/Kernel.ts | 2 +-
src/world/PerspectiveCamera.ts | 33 ++++++----
src/world/Renderer.ts | 2 +-
src/world/math/Math.ts | 116 +++++++++++++++++----------------
6 files changed, 88 insertions(+), 72 deletions(-)
diff --git a/src/world/Event.ts b/src/world/Event.ts
index 6288c43..359d451 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -154,8 +154,8 @@ const EventModule = {
}
var newLevel = globe.CURRENT_LEVEL + deltaLevel;
if(newLevel >= 0){
- //globe.setLevel(newLevel);
- globe.animateToLevel(newLevel);
+ globe.setLevel(newLevel);
+ //globe.animateToLevel(newLevel);
}
},
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index abb363d..51dbb22 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -20,8 +20,7 @@ class Globe {
camera: PerspectiveCamera = null;
tiledLayer: TiledLayer = null;
- constructor(canvas: HTMLCanvasElement, args: any) {
- args = args || {};
+ constructor(canvas: HTMLCanvasElement) {
Kernel.globe = this;
this.renderer = Kernel.renderer = new Renderer(canvas);
this.scene = new Scene();
diff --git a/src/world/Kernel.ts b/src/world/Kernel.ts
index e3ad69d..e9eb22b 100644
--- a/src/world/Kernel.ts
+++ b/src/world/Kernel.ts
@@ -3,7 +3,7 @@ import {WebGLRenderingContextExtension} from './Definitions';
import Globe = require("./Globe");
import Renderer = require("./Renderer");
-const radius = 14000;//6378137
+const radius = 500;//6378137
const maxProjectedCoord = Math.PI * radius;
const Kernel = {
diff --git a/src/world/PerspectiveCamera.ts b/src/world/PerspectiveCamera.ts
index 70a7694..7740b50 100644
--- a/src/world/PerspectiveCamera.ts
+++ b/src/world/PerspectiveCamera.ts
@@ -162,12 +162,6 @@ class PerspectiveCamera extends Object3D {
this.matrix.setColumnTrans(transX, transY, transZ); //此处相当于对Camera的模型矩阵(不是视点矩阵)设置偏移量
this.matrix.setLastRowDefault();
- // var deltaX = cameraPntCopy.x - targetPntCopy.x;
- // var deltaY = cameraPntCopy.y - targetPntCopy.y;
- // var deltaZ = cameraPntCopy.z - targetPntCopy.z;
- // var far = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
- // this.setFar(far);
-
this._updateFar();
}
@@ -411,14 +405,31 @@ class PerspectiveCamera extends Object3D {
} else {
var length2SurfaceNow = MathUtils.getLengthFromCamera2EarthSurface(Kernel.globe.CURRENT_LEVEL);
var length2Surface = MathUtils.getLengthFromCamera2EarthSurface(level);
- var deltaLength = length2SurfaceNow - length2Surface;
- var dir = this.getLightDirection();
- dir.setLength(deltaLength);
- var pNew = Vector.verticePlusVector(pOld, dir);
- this.setPosition(pNew.x, pNew.y, pNew.z);
+ if(length2Surface > (this.near * 0.6)){
+ var deltaLength = length2SurfaceNow - length2Surface;
+ var dir = this.getLightDirection();
+ dir.setLength(deltaLength);
+ var pNew = Vector.verticePlusVector(pOld, dir);
+ this.setPosition(pNew.x, pNew.y, pNew.z);
+ }else{
+ var deltaLevel = level - Kernel.globe.CURRENT_LEVEL;
+ var newFov = this._zoomInByFov(this.fov, deltaLevel)
+ this.setFov(newFov);
+ }
}
}
+ private _zoomInByFov(fov1: number, deltaLevel: number): number{
+ var radianFov1 = MathUtils.degreeToRadian(fov1);
+ var halfRadianFov1 = radianFov1 / 2;
+ var tan1 = Math.tan(halfRadianFov1);
+ var tan2 = tan1 / Math.pow(2, deltaLevel);
+ var halfRadianFov2 = Math.atan(tan2);
+ var radianFov2 = halfRadianFov2 * 2;
+ var fov2 = MathUtils.radianToDegree(radianFov2);
+ return fov2;
+ }
+
//判断世界坐标系中的点是否在Canvas中可见
//options:projView、verticeInNDC
isWorldVerticeVisibleInCanvas(verticeInWorld: Vertice, options?: any): boolean {
diff --git a/src/world/Renderer.ts b/src/world/Renderer.ts
index 9b57df6..272a904 100644
--- a/src/world/Renderer.ts
+++ b/src/world/Renderer.ts
@@ -64,7 +64,7 @@ class Renderer {
Kernel.gl.depthFunc(Kernel.gl.LEQUAL);
Kernel.gl.depthMask(true);
camera.viewMatrix = null;
- //update viewMatrix and projViewMatrix of camera
+ //update viewMatrix, projMatrix and projViewMatrix of camera
camera.updateProjViewMatrix();
scene.draw(camera);
}
diff --git a/src/world/math/Math.ts b/src/world/math/Math.ts
index 2f21e1d..4e052ca 100644
--- a/src/world/math/Math.ts
+++ b/src/world/math/Math.ts
@@ -309,7 +309,7 @@ const MathUtils = {
}
var ndcX = 2 * canvasX / Kernel.canvas.width - 1;
var ndcY = 1 - 2 * canvasY / Kernel.canvas.height;
- return [ndcX,ndcY];
+ return [ndcX, ndcY];
},
//点变换: NDC->Canvas
@@ -322,7 +322,7 @@ const MathUtils = {
}
var canvasX = (1 + ndcX) * Kernel.canvas.width / 2.0;
var canvasY = (1 - ndcY) * Kernel.canvas.height / 2.0;
- return [canvasX,canvasY];
+ return [canvasX, canvasY];
},
/**
@@ -341,10 +341,10 @@ const MathUtils = {
* @p 笛卡尔坐标系中的坐标
*/
geographicToCartesianCoord(lon:number, lat: number, r: number = Kernel.EARTH_RADIUS): Vertice{
- if(!(lon >= -(180+0.001) && lon <= (180+0.001))){
+ if(!(lon >= -(180 + 0.001) && lon <= (180 + 0.001))){
throw "invalid lon";
}
- if(!(lat >= -(90+0.001) && lat <= (90+0.001))){
+ if(!(lat >= -(90 + 0.001) && lat <= (90 + 0.001))){
throw "invalid lat";
}
var radianLon = this.degreeToRadian(lon);
@@ -353,10 +353,10 @@ const MathUtils = {
var cos1 = Math.cos(radianLon);
var sin2 = Math.sin(radianLat);
var cos2 = Math.cos(radianLat);
- var x = r*sin1*cos2;
- var y = r*sin2;
- var z = r*cos1*cos2;
- return new Vertice(x,y,z);
+ var x = r * sin1 *cos2;
+ var y = r * sin2;
+ var z = r *cos1 * cos2;
+ return new Vertice(x, y, z);
},
/**
@@ -369,7 +369,7 @@ const MathUtils = {
var x = verticeCopy.x;
var y = verticeCopy.y;
var z = verticeCopy.z;
- var sin2 = y/Kernel.EARTH_RADIUS;
+ var sin2 = y / Kernel.EARTH_RADIUS;
if(sin2 > 1){
sin2 = 2;
}else if(sin2 < -1){
@@ -390,16 +390,22 @@ const MathUtils = {
cos1 = -1;
}
var radianLog = Math.asin(sin1);
- if(sin1 >= 0){//经度在[0,π]
- if(cos1 >= 0){//经度在[0,π/2]之间
+ if(sin1 >= 0){
+ //经度在[0,π]
+ if(cos1 >= 0){
+ //经度在[0, π/2]之间
radianLog = radianLog;
- }else{//经度在[π/2,π]之间
+ }else{
+ //经度在[π/2, π]之间
radianLog = Math.PI - radianLog;
}
- }else{//经度在[-π,0]之间
- if(cos1 >= 0){//经度在[-π/2,0]之间
+ }else{
+ //经度在[-π, 0]之间
+ if(cos1 >= 0){
+ //经度在[-π/2, 0]之间
radianLog = radianLog;
- }else{//经度在[-π,-π/2]之间
+ }else{
+ //经度在[-π,-π/2]之间
radianLog = -radianLog - Math.PI;
}
}
@@ -455,9 +461,9 @@ const MathUtils = {
throw "invalid y";
}
var a = y / Kernel.EARTH_RADIUS;
- var b = Math.pow(Math.E,a);
+ var b = Math.pow(Math.E, a);
var c = Math.atan(b);
- var radianLat = 2*c - Math.PI/2;
+ var radianLat = 2 * c - Math.PI/2;
return radianLat;
},
@@ -501,7 +507,7 @@ const MathUtils = {
* @return {*} 投影坐标x
*/
radianLogToWebMercatorX(radianLog: number): number{
- if(!(Utils.isNumber(radianLog) && radianLog <= (Math.PI+0.001) && radianLog >= -(Math.PI+0.001))){
+ if(!(Utils.isNumber(radianLog) && radianLog <= (Math.PI + 0.001) && radianLog >= -(Math.PI + 0.001))){
throw "invalid radianLog";
}
return Kernel.EARTH_RADIUS * radianLog;
@@ -513,7 +519,7 @@ const MathUtils = {
* @return {*} 投影坐标x
*/
degreeLogToWebMercatorX(degreeLog: number): number{
- if(!(Utils.isNumber(degreeLog) && degreeLog <= (180+0.001) && degreeLog >= -(180+0.001))){
+ if(!(Utils.isNumber(degreeLog) && degreeLog <= (180 + 0.001) && degreeLog >= -(180 + 0.001))){
throw "invalid degreeLog";
}
var radianLog = this.degreeToRadian(degreeLog);
@@ -526,10 +532,10 @@ const MathUtils = {
* @return {Number} 投影坐标y
*/
radianLatToWebMercatorY(radianLat: number): number{
- if(!(radianLat <= (Math.PI/2+0.001) && radianLat >= -(Math.PI/2+0.001))){
+ if(!(radianLat <= (Math.PI / 2 + 0.001) && radianLat >= -(Math.PI / 2 + 0.001))){
throw "invalid radianLat";
}
- var a = Math.PI/4 + radianLat/2;
+ var a = Math.PI / 4 + radianLat / 2;
var b = Math.tan(a);
var c = Math.log(b);
var y = Kernel.EARTH_RADIUS * c;
@@ -542,7 +548,7 @@ const MathUtils = {
* @return {Number} 投影坐标y
*/
degreeLatToWebMercatorY(degreeLat: number): number{
- if(!(degreeLat <= (90+0.001) && degreeLat >= -(90+0.001))){
+ if(!(degreeLat <= (90 + 0.001) && degreeLat >= -(90 + 0.001))){
throw "invalid degreeLat";
}
var radianLat = this.degreeToRadian(degreeLat);
@@ -558,7 +564,7 @@ const MathUtils = {
radianGeographicToWebMercator(radianLog: number, radianLat: number): number[]{
var x = this.radianLogToWebMercatorX(radianLog);
var y = this.radianLatToWebMercatorY(radianLat);
- return [x,y];
+ return [x, y];
},
/**
@@ -570,13 +576,13 @@ const MathUtils = {
degreeGeographicToWebMercator(degreeLog: number, degreeLat: number): number[]{
var x = this.degreeLogToWebMercatorX(degreeLog);
var y = this.degreeLatToWebMercatorY(degreeLat);
- return [x,y];
+ return [x, y];
},
//根据切片的level、row、column计算该切片所覆盖的投影区域的范围
getTileWebMercatorEnvelopeByGrid(level: number, row: number, column: number): any{
var k = Kernel.MAX_PROJECTED_COORD;
- var size = 2*k / Math.pow(2,level);
+ var size = 2 * k / Math.pow(2, level);
var minX = -k + column * size;
var maxX = minX + size;
var maxY = k - row * size;
@@ -592,14 +598,14 @@ const MathUtils = {
//根据切片的level、row、column计算该切片所覆盖的经纬度区域的范围,以经纬度表示返回结果
getTileGeographicEnvelopByGrid(level: number, row: number, column: number): any{
- var Eproj = this.getTileWebMercatorEnvelopeByGrid(level,row,column);
- var pMin = this.webMercatorToDegreeGeographic(Eproj.minX,Eproj.minY);
- var pMax = this.webMercatorToDegreeGeographic(Eproj.maxX,Eproj.maxY);
+ var Eproj = this.getTileWebMercatorEnvelopeByGrid(level, row, column);
+ var pMin = this.webMercatorToDegreeGeographic(Eproj.minX, Eproj.minY);
+ var pMax = this.webMercatorToDegreeGeographic(Eproj.maxX, Eproj.maxY);
var Egeo = {
- "minLon":pMin[0],
- "minLat":pMin[1],
- "maxLon":pMax[0],
- "maxLat":pMax[1]
+ "minLon": pMin[0],
+ "minLat": pMin[1],
+ "maxLon": pMax[0],
+ "maxLat": pMax[1]
};
return Egeo;
},
@@ -611,19 +617,19 @@ const MathUtils = {
var minLat = Egeo.minLat;
var maxLon = Egeo.maxLon;
var maxLat = Egeo.maxLat;
- var pLeftBottom = this.geographicToCartesianCoord(minLon,minLat);
- var pLeftTop = this.geographicToCartesianCoord(minLon,maxLat);
- var pRightTop = this.geographicToCartesianCoord(maxLon,maxLat);
- var pRightBottom = this.geographicToCartesianCoord(maxLon,minLat);
+ var pLeftBottom = this.geographicToCartesianCoord(minLon, minLat);
+ var pLeftTop = this.geographicToCartesianCoord(minLon, maxLat);
+ var pRightTop = this.geographicToCartesianCoord(maxLon, maxLat);
+ var pRightBottom = this.geographicToCartesianCoord(maxLon, minLat);
var Ecar = {
- "pLeftBottom":pLeftBottom,
- "pLeftTop":pLeftTop,
- "pRightTop":pRightTop,
- "pRightBottom":pRightBottom,
- "minLon":minLon,
- "minLat":minLat,
- "maxLon":maxLon,
- "maxLat":maxLat
+ "pLeftBottom": pLeftBottom,
+ "pLeftTop": pLeftTop,
+ "pRightTop": pRightTop,
+ "pRightBottom": pRightBottom,
+ "minLon": minLon,
+ "minLat": minLat,
+ "maxLon": maxLon,
+ "maxLat": maxLat
};
return Ecar;
},
@@ -636,20 +642,20 @@ const MathUtils = {
* @return {Array}
*/
getGeographicTileCenter(level: number, row: number, column: number): number[]{
- var Egeo = this.getTileGeographicEnvelopByGrid(level,row,column);
+ var Egeo = this.getTileGeographicEnvelopByGrid(level, row, column);
var minLon = Egeo.minLon;
var minLat = Egeo.minLat;
var maxLon = Egeo.maxLon;
var maxLat = Egeo.maxLat;
var centerLon = (minLon+maxLon)/2;//切片的经度中心
var centerLat = (minLat+maxLat)/2;//切片的纬度中心
- var lonlatTileCenter = [centerLon,centerLat];
+ var lonlatTileCenter = [centerLon, centerLat];
return lonlatTileCenter;
},
getCartesianTileCenter(level: number, row: number, column: number): Vertice{
- var lonLat = this.getGeographicTileCenter(level,row,column);
- var vertice = this.geographicToCartesianCoord(lonLat[0],lonLat[1]);
+ var lonLat = this.getGeographicTileCenter(level, row, column);
+ var vertice = this.geographicToCartesianCoord(lonLat[0], lonLat[1]);
return vertice;
},
@@ -660,15 +666,15 @@ const MathUtils = {
* @return {Array} 返回每个顶点的平均法向量的数组
*/
calculateNormals(vs: number[], ind: number[]): number[]{
- var x=0;
- var y=1;
- var z=2;
+ var x = 0;
+ var y = 1;
+ var z = 2;
var ns:number[] = [];
//对于每个vertex,初始化normal x, normal y, normal z
- for(var i=0;i
Date: Sat, 26 Nov 2016 13:00:05 +0800
Subject: [PATCH 048/109] update depth issue,#14
---
src/world/Event.ts | 6 +--
src/world/Globe.ts | 22 +++++-----
src/world/Kernel.ts | 1 +
src/world/PerspectiveCamera.ts | 73 +++++++++++++++++++++-------------
src/world/Renderer.ts | 2 +-
5 files changed, 64 insertions(+), 40 deletions(-)
diff --git a/src/world/Event.ts b/src/world/Event.ts
index 359d451..bde3f66 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -123,13 +123,13 @@ const EventModule = {
var absoluteX = event.layerX || event.offsetX;
var absoluteY = event.layerY || event.offsetY;
var pickResult = globe.camera.getPickCartesianCoordInEarthByCanvas(absoluteX, absoluteY);
- globe.setLevel(globe.CURRENT_LEVEL + 1);
+ globe.setLevel(globe.getLevel() + 1);
if (pickResult.length >= 1) {
var pickVertice = pickResult[0];
var lonlat = MathUtils.cartesianCoordToGeographic(pickVertice);
var lon = lonlat[0];
var lat = lonlat[1];
- globe.setLevel(globe.CURRENT_LEVEL + 1);
+ globe.setLevel(globe.getLevel() + 1);
this.moveLonLatToCanvas(lon, lat, absoluteX, absoluteY);
}
}
@@ -152,7 +152,7 @@ const EventModule = {
delta = event.detail;
deltaLevel = -parseInt((delta / 3));
}
- var newLevel = globe.CURRENT_LEVEL + deltaLevel;
+ var newLevel = globe.getLevel() + deltaLevel;
if(newLevel >= 0){
globe.setLevel(newLevel);
//globe.animateToLevel(newLevel);
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index 51dbb22..81da9ab 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -10,11 +10,10 @@ import Tile = require("./graphics/Tile");
import ImageUtils = require("./Image");
import EventUtils = require("./Event");
-class Globe {
- MAX_LEVEL: number = 14;//最大的渲染级别14
- CURRENT_LEVEL: number = -1; //当前渲染等级
+class Globe {
REFRESH_INTERVAL: number = 300; //Globe自动刷新时间间隔,以毫秒为单位
idTimeOut: any = null; //refresh自定刷新的timeOut的handle
+ level: number = -1; //当前渲染等级
renderer: Renderer = null;
scene: Scene = null;
camera: PerspectiveCamera = null;
@@ -31,7 +30,7 @@ class Globe {
this.setLevel(0);
this.renderer.setIfAutoRefresh(true);
EventUtils.initLayout();
- }
+ }
setTiledLayer(tiledLayer: TiledLayer) {
clearTimeout(this.idTimeOut);
@@ -75,13 +74,17 @@ class Globe {
this.tick();
}
+ getLevel(){
+ return this.level;
+ }
+
setLevel(level: number) {
if (!Utils.isNonNegativeInteger(level)) {
throw "invalid level:" + level;
}
- level = level > this.MAX_LEVEL ? this.MAX_LEVEL : level; //超过最大的渲染级别就不渲染
- if (level != this.CURRENT_LEVEL) {
+ level = level > Kernel.MAX_LEVEL ? Kernel.MAX_LEVEL : level; //超过最大的渲染级别就不渲染
+ if (level != this.getLevel()) {
if (this.camera instanceof PerspectiveCamera) {
//要先执行camera.setLevel,然后再刷新
this.camera.setLevel(level);
@@ -96,8 +99,8 @@ class Globe {
animateToLevel(level: number){
if(!this.isAnimating()){
- level = level > this.MAX_LEVEL ? this.MAX_LEVEL : level; //超过最大的渲染级别就不渲染
- if(level !== this.CURRENT_LEVEL){
+ level = level > Kernel.MAX_LEVEL ? Kernel.MAX_LEVEL : level; //超过最大的渲染级别就不渲染
+ if(level !== this.getLevel()){
this.camera.animateToLevel(level);
}
}
@@ -138,7 +141,8 @@ class Globe {
if (!this.tiledLayer || !this.scene || !this.camera) {
return;
}
- var level = this.CURRENT_LEVEL + 3;
+ this.camera.update();
+ var level = this.getLevel() + 3;
this.tiledLayer.updateSubLayerCount(level);
var projView = this.camera.getProjViewMatrix();
var options = {
diff --git a/src/world/Kernel.ts b/src/world/Kernel.ts
index e9eb22b..ec6c06f 100644
--- a/src/world/Kernel.ts
+++ b/src/world/Kernel.ts
@@ -13,6 +13,7 @@ const Kernel = {
globe: null,
idCounter: 0, //Object3D对象的唯一标识
BASE_LEVEL: 6, //渲染的基准层级
+ MAX_LEVEL: 14,//最大的渲染级别
EARTH_RADIUS: radius,
MAX_PROJECTED_COORD: maxProjectedCoord,
proxy: ""
diff --git a/src/world/PerspectiveCamera.ts b/src/world/PerspectiveCamera.ts
index 7740b50..d07707d 100644
--- a/src/world/PerspectiveCamera.ts
+++ b/src/world/PerspectiveCamera.ts
@@ -86,7 +86,7 @@ class PerspectiveCamera extends Object3D {
return projViewMatrix;
}
- setFov(fov: number): void {
+ _setFov(fov: number): void {
if (!(fov > 0)) {
throw "invalid fov:" + fov;
}
@@ -100,7 +100,7 @@ class PerspectiveCamera extends Object3D {
this._setPerspectiveMatrix(this.fov, aspect, this.near, this.far);
}
- setNear(near: number): void {
+ _setNear(near: number): void {
if (!(near > 0)) {
throw "invalid near:" + near;
}
@@ -145,6 +145,41 @@ class PerspectiveCamera extends Object3D {
return this.projViewMatrix;
}
+ private _setVirtualPosition(virtualPosisition: Vertice){
+
+ }
+
+ private _getVirtualPosition(): Vertice{
+ return null;
+ }
+
+ private _zoomInByFov(fov1: number, deltaLevel: number): number{
+ // if(length2Surface > (this.near * 0.6)){
+ // var deltaLength = length2SurfaceNow - length2Surface;
+ // var dir = this.getLightDirection();
+ // dir.setLength(deltaLength);
+ // var pNew = Vector.verticePlusVector(pOld, dir);
+ // this.setPosition(pNew.x, pNew.y, pNew.z);
+ // }else{
+ // var deltaLevel = level - Kernel.globe.CURRENT_LEVEL;
+ // var newFov = this._zoomInByFov(this.fov, deltaLevel)
+ // this._setFov(newFov);
+ // }
+
+ var radianFov1 = MathUtils.degreeToRadian(fov1);
+ var halfRadianFov1 = radianFov1 / 2;
+ var tan1 = Math.tan(halfRadianFov1);
+ var tan2 = tan1 / Math.pow(2, deltaLevel);
+ var halfRadianFov2 = Math.atan(tan2);
+ var radianFov2 = halfRadianFov2 * 2;
+ var fov2 = MathUtils.radianToDegree(radianFov2);
+ return fov2;
+ }
+
+ update():void{
+ this.updateProjViewMatrix();
+ }
+
look(cameraPnt: Vertice, targetPnt: Vertice, upDirection: Vector = new Vector(0, 1, 0)): void {
var cameraPntCopy = cameraPnt.clone();
var targetPntCopy = targetPnt.clone();
@@ -318,7 +353,7 @@ class PerspectiveCamera extends Object3D {
animateToLevel(level: number): void {
var newCamera = this._animateToLevel(level);
this._animateToCamera(newCamera, () => {
- Kernel.globe.CURRENT_LEVEL = level;
+ Kernel.globe.level = level;
});
}
@@ -385,7 +420,7 @@ class PerspectiveCamera extends Object3D {
setLevel(level: number): void{
this._setLevel(level);
//don't update CURRENT_LEVEL in _setLevel method because it will affect animateToLevel method
- Kernel.globe.CURRENT_LEVEL = level;
+ Kernel.globe.level = level;
}
//设置观察到的层级
@@ -393,6 +428,7 @@ class PerspectiveCamera extends Object3D {
if (!(Utils.isNonNegativeInteger(level))) {
throw "invalid level:" + level;
}
+ var globe = Kernel.globe;
var pOld = this.getPosition();
if (pOld.x === 0 && pOld.y === 0 && pOld.z === 0) {
//初始设置camera
@@ -403,33 +439,16 @@ class PerspectiveCamera extends Object3D {
var newPosition = vector.getVertice();
this.look(newPosition, origin);
} else {
- var length2SurfaceNow = MathUtils.getLengthFromCamera2EarthSurface(Kernel.globe.CURRENT_LEVEL);
+ var length2SurfaceNow = MathUtils.getLengthFromCamera2EarthSurface(globe.getLevel());
var length2Surface = MathUtils.getLengthFromCamera2EarthSurface(level);
- if(length2Surface > (this.near * 0.6)){
- var deltaLength = length2SurfaceNow - length2Surface;
- var dir = this.getLightDirection();
- dir.setLength(deltaLength);
- var pNew = Vector.verticePlusVector(pOld, dir);
- this.setPosition(pNew.x, pNew.y, pNew.z);
- }else{
- var deltaLevel = level - Kernel.globe.CURRENT_LEVEL;
- var newFov = this._zoomInByFov(this.fov, deltaLevel)
- this.setFov(newFov);
- }
+ var deltaLength = length2SurfaceNow - length2Surface;
+ var dir = this.getLightDirection();
+ dir.setLength(deltaLength);
+ var pNew = Vector.verticePlusVector(pOld, dir);
+ this.setPosition(pNew.x, pNew.y, pNew.z);
}
}
- private _zoomInByFov(fov1: number, deltaLevel: number): number{
- var radianFov1 = MathUtils.degreeToRadian(fov1);
- var halfRadianFov1 = radianFov1 / 2;
- var tan1 = Math.tan(halfRadianFov1);
- var tan2 = tan1 / Math.pow(2, deltaLevel);
- var halfRadianFov2 = Math.atan(tan2);
- var radianFov2 = halfRadianFov2 * 2;
- var fov2 = MathUtils.radianToDegree(radianFov2);
- return fov2;
- }
-
//判断世界坐标系中的点是否在Canvas中可见
//options:projView、verticeInNDC
isWorldVerticeVisibleInCanvas(verticeInWorld: Vertice, options?: any): boolean {
diff --git a/src/world/Renderer.ts b/src/world/Renderer.ts
index 272a904..281c3f4 100644
--- a/src/world/Renderer.ts
+++ b/src/world/Renderer.ts
@@ -65,7 +65,7 @@ class Renderer {
Kernel.gl.depthMask(true);
camera.viewMatrix = null;
//update viewMatrix, projMatrix and projViewMatrix of camera
- camera.updateProjViewMatrix();
+ camera.update();
scene.draw(camera);
}
From c1c9a3783e1b613fba3a61d2b2505f20cee7e014 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Sat, 26 Nov 2016 15:10:52 +0800
Subject: [PATCH 049/109] disable ALWAYS for depth test
---
src/world/Enum.ts | 4 ----
src/world/Globe.ts | 5 +++--
src/world/PerspectiveCamera.ts | 4 ++--
src/world/Renderer.ts | 2 +-
src/world/layers/PoiLayer.ts | 3 ++-
src/world/layers/TiledLayer.ts | 4 ++--
6 files changed, 10 insertions(+), 12 deletions(-)
diff --git a/src/world/Enum.ts b/src/world/Enum.ts
index 4e7f1a3..d79d72c 100644
--- a/src/world/Enum.ts
+++ b/src/world/Enum.ts
@@ -4,10 +4,6 @@ enum Enum {
FULL_IN,
FULL_OUT,
IN_OUT,
- NOKIA_TILED_MAP,
- Google_TILED_MAP,
- OSM_TILED_MAP,
- BLENDED_TILED_MAP,
GLOBE_TILE,
TERRAIN_TILE
}
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index 81da9ab..15c61a8 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -10,7 +10,7 @@ import Tile = require("./graphics/Tile");
import ImageUtils = require("./Image");
import EventUtils = require("./Event");
-class Globe {
+class Globe {
REFRESH_INTERVAL: number = 300; //Globe自动刷新时间间隔,以毫秒为单位
idTimeOut: any = null; //refresh自定刷新的timeOut的handle
level: number = -1; //当前渲染等级
@@ -30,7 +30,7 @@ class Globe {
this.setLevel(0);
this.renderer.setIfAutoRefresh(true);
EventUtils.initLayout();
- }
+ }
setTiledLayer(tiledLayer: TiledLayer) {
clearTimeout(this.idTimeOut);
@@ -141,6 +141,7 @@ class Globe {
if (!this.tiledLayer || !this.scene || !this.camera) {
return;
}
+ //先更新camera中的各种矩阵
this.camera.update();
var level = this.getLevel() + 3;
this.tiledLayer.updateSubLayerCount(level);
diff --git a/src/world/PerspectiveCamera.ts b/src/world/PerspectiveCamera.ts
index d07707d..fb7f830 100644
--- a/src/world/PerspectiveCamera.ts
+++ b/src/world/PerspectiveCamera.ts
@@ -165,7 +165,7 @@ class PerspectiveCamera extends Object3D {
// var newFov = this._zoomInByFov(this.fov, deltaLevel)
// this._setFov(newFov);
// }
-
+
var radianFov1 = MathUtils.degreeToRadian(fov1);
var halfRadianFov1 = radianFov1 / 2;
var tan1 = Math.tan(halfRadianFov1);
@@ -445,7 +445,7 @@ class PerspectiveCamera extends Object3D {
var dir = this.getLightDirection();
dir.setLength(deltaLength);
var pNew = Vector.verticePlusVector(pOld, dir);
- this.setPosition(pNew.x, pNew.y, pNew.z);
+ this.setPosition(pNew.x, pNew.y, pNew.z);
}
}
diff --git a/src/world/Renderer.ts b/src/world/Renderer.ts
index 281c3f4..8144331 100644
--- a/src/world/Renderer.ts
+++ b/src/world/Renderer.ts
@@ -64,7 +64,7 @@ class Renderer {
Kernel.gl.depthFunc(Kernel.gl.LEQUAL);
Kernel.gl.depthMask(true);
camera.viewMatrix = null;
- //update viewMatrix, projMatrix and projViewMatrix of camera
+ //update viewMatrix, projMatrix and projViewMatrix
camera.update();
scene.draw(camera);
}
diff --git a/src/world/layers/PoiLayer.ts b/src/world/layers/PoiLayer.ts
index 214b7d1..404f40e 100644
--- a/src/world/layers/PoiLayer.ts
+++ b/src/world/layers/PoiLayer.ts
@@ -13,7 +13,8 @@ class PoiLayer extends GraphicGroup{
constructor(){
super();
- var p = MathUtils.geographicToCartesianCoord(116.408540, 39.902350, Kernel.EARTH_RADIUS + 0.001);
+ //var p = MathUtils.geographicToCartesianCoord(116.408540, 39.902350, Kernel.EARTH_RADIUS + 0.001);
+ var p = MathUtils.geographicToCartesianCoord(0, 0, Kernel.EARTH_RADIUS * 1.2);
var marker = new Marker(p.x, p.y, p.z);
var url = "/WebGlobe/src/world/images/poi.png";
var material = new PoiMaterial(url, 24);
diff --git a/src/world/layers/TiledLayer.ts b/src/world/layers/TiledLayer.ts
index 2892845..5b03ccc 100644
--- a/src/world/layers/TiledLayer.ts
+++ b/src/world/layers/TiledLayer.ts
@@ -9,10 +9,10 @@ abstract class TiledLayer extends GraphicGroup {
//重写
draw(camera: PerspectiveCamera){
//此处将深度测试设置为ALWAYS是为了解决两个不同层级的切片在拖动时一起渲染会导致屏闪的问题
- Kernel.gl.depthFunc(Kernel.gl.ALWAYS);
+ //Kernel.gl.depthFunc(Kernel.gl.ALWAYS);
super.draw(camera);
//将深度测试恢复成LEQUAL
- Kernel.gl.depthFunc(Kernel.gl.LEQUAL);
+ //Kernel.gl.depthFunc(Kernel.gl.LEQUAL);
}
//重写
From 067221aff865b68f8986bdcdd66fd1674040f542 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Sat, 26 Nov 2016 15:14:52 +0800
Subject: [PATCH 050/109] rename PerspectiveCamera to Camera
---
src/world/{PerspectiveCamera.ts => Camera.ts} | 14 +++++++-------
src/world/Event.ts | 4 ++--
src/world/Globe.ts | 8 ++++----
src/world/GraphicGroup.ts | 4 ++--
src/world/Renderer.ts | 8 ++++----
src/world/graphics/Graphic.ts | 6 +++---
src/world/graphics/MeshGraphic.ts | 4 ++--
src/world/graphics/Poi.ts | 4 ++--
src/world/layers/PoiLayer.ts | 1 -
src/world/layers/TiledLayer.ts | 4 ++--
10 files changed, 28 insertions(+), 29 deletions(-)
rename src/world/{PerspectiveCamera.ts => Camera.ts} (98%)
diff --git a/src/world/PerspectiveCamera.ts b/src/world/Camera.ts
similarity index 98%
rename from src/world/PerspectiveCamera.ts
rename to src/world/Camera.ts
index fb7f830..b85fd5e 100644
--- a/src/world/PerspectiveCamera.ts
+++ b/src/world/Camera.ts
@@ -1,4 +1,4 @@
-///
+///
import Kernel = require('./Kernel');
import Utils = require('./Utils');
import MathUtils = require('./math/Math');
@@ -10,7 +10,7 @@ import TileGrid = require('./TileGrid');
import Matrix = require('./math/Matrix');
import Object3D = require('./Object3D');
-class PerspectiveCamera extends Object3D {
+class Camera extends Object3D {
private animationDuration = 600;//层级变化的动画周期是600毫秒
pitch: number;
viewMatrix: Matrix;
@@ -357,7 +357,7 @@ class PerspectiveCamera extends Object3D {
});
}
- private _animateToCamera(newCamera: PerspectiveCamera, cb: ()=>void){
+ private _animateToCamera(newCamera: Camera, cb: ()=>void){
if(this.isAnimating()){
return;
}
@@ -389,7 +389,7 @@ class PerspectiveCamera extends Object3D {
requestAnimationFrame(callback);
}
- private _animateToLevel(level: number): PerspectiveCamera{
+ private _animateToLevel(level: number): Camera{
if (!(Utils.isNonNegativeInteger(level))) {
throw "invalid level:" + level;
}
@@ -399,8 +399,8 @@ class PerspectiveCamera extends Object3D {
return camera;
}
- private _clone(): PerspectiveCamera{
- var camera: PerspectiveCamera = new PerspectiveCamera();
+ private _clone(): Camera{
+ var camera: Camera = new Camera();
(Object).assign(camera, this.toJson());
return camera;
}
@@ -793,4 +793,4 @@ class PerspectiveCamera extends Object3D {
}
}
-export = PerspectiveCamera;
\ No newline at end of file
+export = Camera;
\ No newline at end of file
diff --git a/src/world/Event.ts b/src/world/Event.ts
index bde3f66..1c7b9ec 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -2,7 +2,7 @@
import Kernel = require("./Kernel");
import MathUtils = require("./math/Math");
import Vector = require("./math/Vector");
-import PerspectiveCamera = require("./PerspectiveCamera");
+import Camera = require("./Camera");
type MouseMoveListener = (e: MouseEvent) => {};
@@ -102,7 +102,7 @@ const EventModule = {
var v2 = Vector.fromVertice(p2);
var rotateVector = v1.cross(v2);
var rotateRadian = -Vector.getRadianOfTwoVectors(v1, v2);
- var camera: PerspectiveCamera = Kernel.globe.camera;
+ var camera: Camera = Kernel.globe.camera;
camera.worldRotateByVector(rotateRadian, rotateVector);
},
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index 15c61a8..ea6a40a 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -2,7 +2,7 @@
import Kernel = require("./Kernel");
import Utils = require("./Utils");
import Renderer = require("./Renderer");
-import PerspectiveCamera = require("./PerspectiveCamera");
+import Camera = require("./Camera");
import Scene = require("./Scene");
import TiledLayer = require("./layers/TiledLayer");
import SubTiledLayer = require("./layers/SubTiledLayer");
@@ -16,7 +16,7 @@ class Globe {
level: number = -1; //当前渲染等级
renderer: Renderer = null;
scene: Scene = null;
- camera: PerspectiveCamera = null;
+ camera: Camera = null;
tiledLayer: TiledLayer = null;
constructor(canvas: HTMLCanvasElement) {
@@ -24,7 +24,7 @@ class Globe {
this.renderer = Kernel.renderer = new Renderer(canvas);
this.scene = new Scene();
var radio = canvas.width / canvas.height;
- this.camera = new PerspectiveCamera(30, radio, 1, Kernel.EARTH_RADIUS * 2);
+ this.camera = new Camera(30, radio, 1, Kernel.EARTH_RADIUS * 2);
this.renderer.setScene(this.scene);
this.renderer.setCamera(this.camera);
this.setLevel(0);
@@ -85,7 +85,7 @@ class Globe {
level = level > Kernel.MAX_LEVEL ? Kernel.MAX_LEVEL : level; //超过最大的渲染级别就不渲染
if (level != this.getLevel()) {
- if (this.camera instanceof PerspectiveCamera) {
+ if (this.camera instanceof Camera) {
//要先执行camera.setLevel,然后再刷新
this.camera.setLevel(level);
this.refresh();
diff --git a/src/world/GraphicGroup.ts b/src/world/GraphicGroup.ts
index f7b6f64..83bef4e 100644
--- a/src/world/GraphicGroup.ts
+++ b/src/world/GraphicGroup.ts
@@ -1,7 +1,7 @@
///
import Kernel = require("./Kernel");
import Graphic = require("./graphics/Graphic");
-import PerspectiveCamera = require("./PerspectiveCamera");
+import Camera = require("./Camera");
type Drawable = Graphic | GraphicGroup;
@@ -69,7 +69,7 @@ class GraphicGroup{
return this.visible;
}
- draw(camera: PerspectiveCamera){
+ draw(camera: Camera){
if(this.isDrawable()){
this.children.forEach(function(g: Drawable){
if(g.isDrawable()){
diff --git a/src/world/Renderer.ts b/src/world/Renderer.ts
index 8144331..378d7c2 100644
--- a/src/world/Renderer.ts
+++ b/src/world/Renderer.ts
@@ -2,12 +2,12 @@
import Kernel = require("./Kernel");
import EventUtils = require("./Event");
import Scene = require("./Scene");
-import PerspectiveCamera = require("./PerspectiveCamera");
+import Camera = require("./Camera");
import {WebGLRenderingContextExtension, WebGLProgramExtension} from "./Definitions";
class Renderer {
scene: Scene = null;
- camera: PerspectiveCamera = null;
+ camera: Camera = null;
bAutoRefresh: boolean = false;
constructor(canvas: HTMLCanvasElement) {
@@ -57,7 +57,7 @@ class Renderer {
//gl.enable(gl.TEXTURE_2D);//WebGL: INVALID_ENUM: enable: invalid capability
}
- render(scene: Scene, camera: PerspectiveCamera) {
+ render(scene: Scene, camera: Camera) {
Kernel.gl.viewport(0, 0, Kernel.canvas.width, Kernel.canvas.height);
Kernel.gl.clear(Kernel.gl.COLOR_BUFFER_BIT | Kernel.gl.DEPTH_BUFFER_BIT);
Kernel.gl.enable(Kernel.gl.DEPTH_TEST);
@@ -73,7 +73,7 @@ class Renderer {
this.scene = scene;
}
- setCamera(camera: PerspectiveCamera) {
+ setCamera(camera: Camera) {
this.camera = camera;
}
diff --git a/src/world/graphics/Graphic.ts b/src/world/graphics/Graphic.ts
index 392349f..af08ed8 100644
--- a/src/world/graphics/Graphic.ts
+++ b/src/world/graphics/Graphic.ts
@@ -5,7 +5,7 @@ import Geometry = require("../geometries/Geometry");
import Material = require("../materials/Material");
import Program = require("../Program");
import ProgramUtils = require("../ProgramUtils");
-import PerspectiveCamera = require("../PerspectiveCamera");
+import Camera = require("../Camera");
interface GraphicOptions{
geometry: Geometry;
@@ -44,14 +44,14 @@ abstract class Graphic{
return this.visible && this.isReady();
}
- draw(camera: PerspectiveCamera){
+ draw(camera: Camera){
if(this.isDrawable()){
this.program.use();
this.onDraw(camera);
}
}
- abstract onDraw(camera: PerspectiveCamera):void
+ abstract onDraw(camera: Camera):void
destroy(){
this.parent = null;
diff --git a/src/world/graphics/MeshGraphic.ts b/src/world/graphics/MeshGraphic.ts
index b94b888..0005ac1 100644
--- a/src/world/graphics/MeshGraphic.ts
+++ b/src/world/graphics/MeshGraphic.ts
@@ -5,7 +5,7 @@ import Program = require("../Program");
import Graphic = require("./Graphic");
import Mesh = require("../geometries/Mesh");
import MeshTextureMaterial = require("../materials/MeshTextureMaterial");
-import PerspectiveCamera = require("../PerspectiveCamera");
+import Camera = require("../Camera");
const vs =
`
@@ -70,7 +70,7 @@ class MeshGraphic extends Graphic {
gl.uniform1i(locSampler, 0);
}
- onDraw(camera: PerspectiveCamera) {
+ onDraw(camera: Camera) {
var gl = Kernel.gl;
//aPosition
diff --git a/src/world/graphics/Poi.ts b/src/world/graphics/Poi.ts
index 8b741f9..50c7f20 100644
--- a/src/world/graphics/Poi.ts
+++ b/src/world/graphics/Poi.ts
@@ -5,7 +5,7 @@ import Graphic = require('./Graphic');
import Marker = require('../geometries/Marker');
import PoiMaterial = require('../materials/PoiMaterial');
import Program = require("../Program");
-import PerspectiveCamera = require("../PerspectiveCamera");
+import Camera = require("../Camera");
const vs =
`
@@ -40,7 +40,7 @@ class Poi extends Graphic {
return new Program(this.getProgramType(), vs, fs);
}
- onDraw(camera: PerspectiveCamera){
+ onDraw(camera: Camera){
var gl = Kernel.gl;
//gl.disable(gl.DEPTH_TEST);
diff --git a/src/world/layers/PoiLayer.ts b/src/world/layers/PoiLayer.ts
index 404f40e..2744c60 100644
--- a/src/world/layers/PoiLayer.ts
+++ b/src/world/layers/PoiLayer.ts
@@ -6,7 +6,6 @@ import GraphicGroup = require('../GraphicGroup');
import Poi = require('../graphics/Poi');
import Marker = require('../geometries/Marker');
import PoiMaterial = require('../materials/PoiMaterial');
-import PerspectiveCamera = require('../PerspectiveCamera');
import MeshTextureMaterial = require('../materials/MeshTextureMaterial');
class PoiLayer extends GraphicGroup{
diff --git a/src/world/layers/TiledLayer.ts b/src/world/layers/TiledLayer.ts
index 5b03ccc..5dadd3a 100644
--- a/src/world/layers/TiledLayer.ts
+++ b/src/world/layers/TiledLayer.ts
@@ -2,12 +2,12 @@
import Kernel = require('../Kernel');
import GraphicGroup = require('../GraphicGroup');
import SubTiledLayer = require('./SubTiledLayer');
-import PerspectiveCamera = require('../PerspectiveCamera');
+import Camera = require('../Camera');
abstract class TiledLayer extends GraphicGroup {
//重写
- draw(camera: PerspectiveCamera){
+ draw(camera: Camera){
//此处将深度测试设置为ALWAYS是为了解决两个不同层级的切片在拖动时一起渲染会导致屏闪的问题
//Kernel.gl.depthFunc(Kernel.gl.ALWAYS);
super.draw(camera);
From 9234d1b084e316313c462c8dd0774f113adf7dd9 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Sat, 26 Nov 2016 18:34:04 +0800
Subject: [PATCH 051/109] update Camera,#14
---
src/world/Camera.ts | 352 +++++++++++++++++++++++------------------
src/world/Globe.ts | 16 +-
src/world/math/Math.ts | 9 --
3 files changed, 197 insertions(+), 180 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index b85fd5e..e1d10cf 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -11,7 +11,13 @@ import Matrix = require('./math/Matrix');
import Object3D = require('./Object3D');
class Camera extends Object3D {
- private animationDuration = 600;//层级变化的动画周期是600毫秒
+ private readonly animationDuration: number = 600;//层级变化的动画周期是600毫秒
+ private readonly nearFactor: number = 0.6;
+ private readonly baseTheoryDistanceFromCamera2EarthSurface = 1.23 * Kernel.EARTH_RADIUS;
+
+ deltaFovLevel: number = 0;
+ thresholdLevelForNear: number = -1;
+ level: number = -1; //当前渲染等级
pitch: number;
viewMatrix: Matrix;
projMatrix: Matrix;//当Matrix变化的时候,需要重新计算this.far
@@ -22,19 +28,23 @@ class Camera extends Object3D {
};
private animating: boolean = false;
- constructor(public fov = 45, public aspect = 1, public near = 1, public far = 100) {
+ //this.near一旦初始化之后就不应该再修改
+ //this.far可以动态计算
+ //this.aspect在Viewport改变后重新计算
+ //this.fov可以调整以实现缩放效果
+ constructor(private fov = 45, private aspect = 1, private near = 1, private far = 100) {
super();
this.pitch = 90;
this.projMatrix = new Matrix();
this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, this.far);
}
- _setPerspectiveMatrix(fov: number = 45, aspect: number = 1, near: number = 1, far: number = 100): void {
+ private _setPerspectiveMatrix(fov: number = 45, aspect: number = 1, near: number = 1, far: number = 100): void {
this._rawSetPerspectiveMatrix(fov, aspect, near, far);
this._updateFar();
}
- _rawSetPerspectiveMatrix(fov: number = 45, aspect: number = 1, near: number = 1, far: number = 100): void {
+ private _rawSetPerspectiveMatrix(fov: number = 45, aspect: number = 1, near: number = 1, far: number = 100): void {
//https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/mat4.js#L1788
this.fov = fov;
this.aspect = aspect;
@@ -86,7 +96,7 @@ class Camera extends Object3D {
return projViewMatrix;
}
- _setFov(fov: number): void {
+ private _setFov(fov: number): void {
if (!(fov > 0)) {
throw "invalid fov:" + fov;
}
@@ -100,21 +110,7 @@ class Camera extends Object3D {
this._setPerspectiveMatrix(this.fov, aspect, this.near, this.far);
}
- _setNear(near: number): void {
- if (!(near > 0)) {
- throw "invalid near:" + near;
- }
- this._setPerspectiveMatrix(this.fov, this.aspect, near, this.far);
- }
-
- // setFar(far: number): void {
- // if (!(far > 0)) {
- // throw "invalid far:" + far;
- // }
- // this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, far);
- // }
-
- _updateFar():void{
+ private _updateFar(): void {
//重新计算far,保持far在满足正常需求情况下的最小值
//far值:视点与地球切面的距离
var length2EarthOrigin = Vector.fromVertice(this.getPosition()).getLength();
@@ -128,56 +124,198 @@ class Camera extends Object3D {
return this.matrix.getInverseMatrix();
}
- updateViewMatrix(): Matrix{
+ update(): void {
+ //通过修改position和fov以更新matrix和projMatrix
+ //this._updatePositionAndFov();
+
+ //在_updatePositionAndFov()方法调用之后再计算viewMatrix
this.viewMatrix = this.getViewMatrix();
- return this.viewMatrix;
- }
- updateProjMatrix(): Matrix{
+ //最后更新far
this._updateFar();
- return this.projMatrix;
- }
- updateProjViewMatrix(): Matrix{
- this.updateViewMatrix();
- this.updateProjMatrix();
+ //update projViewMatrix
this.projViewMatrix = this.projMatrix.multiplyMatrix(this.viewMatrix);
- return this.projViewMatrix;
}
- private _setVirtualPosition(virtualPosisition: Vertice){
+ //计算从第几级level开始不满足视景体的near值
+ //比如第10级满足near,第11级不满足near,那么返回10
+ private _getSafeThresholdLevelForNear(){
+ var thresholdNear = this.near * this.nearFactor;
+ var pow2level = this.baseTheoryDistanceFromCamera2EarthSurface / thresholdNear;
+ var level = (Math).log2(pow2level);
+ return Math.floor(level);
+ }
+ /**
+ * 根据层级计算出摄像机应该放置到距离地球表面多远的位置
+ * @param level
+ * @return {*}
+ */
+ private _getTheoryDistanceFromCamera2EarthSurface(level: number): number {
+ return this.baseTheoryDistanceFromCamera2EarthSurface / Math.pow(2, level);
}
- private _getVirtualPosition(): Vertice{
+ private _setVirtualPosition(virtualPosisition: Vertice) {
+
+ }
+
+ private _getVirtualPosition(): Vertice {
return null;
}
- private _zoomInByFov(fov1: number, deltaLevel: number): number{
- // if(length2Surface > (this.near * 0.6)){
- // var deltaLength = length2SurfaceNow - length2Surface;
- // var dir = this.getLightDirection();
- // dir.setLength(deltaLength);
- // var pNew = Vector.verticePlusVector(pOld, dir);
- // this.setPosition(pNew.x, pNew.y, pNew.z);
- // }else{
- // var deltaLevel = level - Kernel.globe.CURRENT_LEVEL;
- // var newFov = this._zoomInByFov(this.fov, deltaLevel)
- // this._setFov(newFov);
- // }
+ //返回更新后的fov值,如果返回结果 < 0,说明无需更新fov
+ private _updatePositionAndFov(): number{
+ // var safeThresholdLevel = this._getSafeThresholdLevelForNear();
+ // if(this.getLevel() > safeThresholdLevel){
+
+ // }
+ var distance2EarthSurface = this.getDistance2EarthSurface();
+ var thresholdNear = this.near * this.nearFactor;
+ if(distance2EarthSurface <= thresholdNear){
+ //摄像机距离地球太近,导致图层不满足视景体的near值
+ //我们需要将摄像机的位置拉远,以满足near值
+ var safeLevel = this._getSafeThresholdLevelForNear();
+ var deltaLevel = this.getLevel() - safeLevel;
+ if(deltaLevel !== 0){
+ this._rawSetLevel(deltaLevel);
+ //摄像机位置拉远之后,我们看到的地球变小,为此,我们需要把fov值变小,以抵消摄像机位置距离增大导致的变化
+ var newFov = this._calculateFovByDeltaLevel(this.fov, deltaLevel);
+ this._setFov(newFov);
+ return this.fov;
+ }
+ }
+ return -1;
+ }
+
+ //通过调整fov的值造成层级缩放的效果
+ private _calculateFovByDeltaLevel(oldFov: number, deltaLevel: number): number {
+ //tan(halfFov) = h / distance
+ var radianOldFov = MathUtils.degreeToRadian(oldFov);
+ var halfRadianOldFov = radianOldFov / 2;
+ var tanOld = Math.tan(halfRadianOldFov);
+ var tanNew = tanOld / Math.pow(2, deltaLevel);
+ var halfRadianNewFov = Math.atan(tanNew);
+ var radianNewFov = halfRadianNewFov * 2;
+ var newFov = MathUtils.radianToDegree(radianNewFov);
+ this.deltaFovLevel += deltaLevel;
+ return newFov;
+ }
+
+ getLevel(): number {
+ return this.level;
+ }
+
+ setLevel(level: number): void {
+ var isLevelChanged = this._rawSetLevel(level);
+ if (isLevelChanged) {
+ //不要在this._setLevel()方法中更新this.level,因为这会影响animateToLevel()方法
+ this.level = level;
+ Kernel.globe.refresh();
+ }
+ }
+
+ //设置观察到的层级,不要在该方法中修改this.level的值
+ private _rawSetLevel(level: number): boolean {
+ if (!(Utils.isNonNegativeInteger(level))) {
+ throw "invalid level:" + level;
+ }
+ level = level > Kernel.MAX_LEVEL ? Kernel.MAX_LEVEL : level; //超过最大的渲染级别就不渲染
+ if (level === this.level) {
+ return false;
+ }
+ var globe = Kernel.globe;
+ var pOld = this.getPosition();
+ if (pOld.x === 0 && pOld.y === 0 && pOld.z === 0) {
+ //初始设置camera
+ var length = this._getTheoryDistanceFromCamera2EarthSurface(level) + Kernel.EARTH_RADIUS; //level等级下摄像机应该到球心的距离
+ //var newPosition = MathUtils.geographicToCartesianCoord(115, 0, Kernel.EARTH_RADIUS + length)
+ var origin = new Vertice(0, 0, 0);
+ var vector = this.getLightDirection().getOpposite();
+ vector.setLength(length);
+ var newPosition = vector.getVertice();
+ this.look(newPosition, origin);
+ } else {
+ var distance2SurfaceNow = this._getTheoryDistanceFromCamera2EarthSurface(this.getLevel());
+ var distance2SurfaceNew = this._getTheoryDistanceFromCamera2EarthSurface(level);
+ var deltaDistance = distance2SurfaceNow - distance2SurfaceNew;
+ var dir = this.getLightDirection();
+ dir.setLength(deltaDistance);
+ var pNew = Vector.verticePlusVector(pOld, dir);
+ this.setPosition(pNew.x, pNew.y, pNew.z);
+ }
+ return true;
+ }
+
+ isAnimating(): boolean {
+ return this.animating;
+ }
+
+ animateToLevel(level: number): void {
+ var newCamera = this._animateToLevel(level);
+ this._animateToCamera(newCamera, () => {
+ this.level = level;
+ });
+ }
+
+ private _animateToCamera(newCamera: Camera, cb: () => void) {
+ if (this.isAnimating()) {
+ return;
+ }
+ this.animating = true;
+ var oldPosition = this.getPosition();
+ var newPosition = newCamera.matrix.getPosition();
+ var span = this.animationDuration;
+ var singleSpan = 1000 / 60;
+ var count = Math.floor(span / singleSpan);
+ var deltaX = (newPosition.x - oldPosition.x) / count;
+ var deltaY = (newPosition.y - oldPosition.y) / count;
+ var deltaZ = (newPosition.z - oldPosition.z) / count;
+ var start: number = -1;
+ var callback = (timestap: number) => {
+ if (start < 0) {
+ start = timestap;
+ }
+ var a = timestap - start;
+ if (a >= span) {
+ (Object).assign(this, newCamera.toJson());
+ this.animating = false;
+ cb();
+ } else {
+ var p = this.getPosition();
+ this.setPosition(p.x + deltaX, p.y + deltaY, p.z + deltaZ);
+ requestAnimationFrame(callback);
+ }
+ };
+ requestAnimationFrame(callback);
+ }
- var radianFov1 = MathUtils.degreeToRadian(fov1);
- var halfRadianFov1 = radianFov1 / 2;
- var tan1 = Math.tan(halfRadianFov1);
- var tan2 = tan1 / Math.pow(2, deltaLevel);
- var halfRadianFov2 = Math.atan(tan2);
- var radianFov2 = halfRadianFov2 * 2;
- var fov2 = MathUtils.radianToDegree(radianFov2);
- return fov2;
+ private _animateToLevel(level: number): Camera {
+ if (!(Utils.isNonNegativeInteger(level))) {
+ throw "invalid level:" + level;
+ }
+ var camera = this._clone();
+ //don't call setLevel method because it will update CURRENT_LEVEL
+ camera._rawSetLevel(level);
+ return camera;
}
- update():void{
- this.updateProjViewMatrix();
+ private _clone(): Camera {
+ var camera: Camera = new Camera();
+ (Object).assign(camera, this.toJson());
+ return camera;
+ }
+
+ toJson(): any {
+ return {
+ pitch: this.pitch,
+ near: this.near,
+ far: this.far,
+ fov: this.fov,
+ aspect: this.aspect,
+ matrix: this.matrix.clone(),
+ projMatrix: this.projMatrix.clone()
+ };
}
look(cameraPnt: Vertice, targetPnt: Vertice, upDirection: Vector = new Vector(0, 1, 0)): void {
@@ -346,109 +484,6 @@ class Camera extends Object3D {
return plan;
}
- isAnimating(): boolean{
- return this.animating;
- }
-
- animateToLevel(level: number): void {
- var newCamera = this._animateToLevel(level);
- this._animateToCamera(newCamera, () => {
- Kernel.globe.level = level;
- });
- }
-
- private _animateToCamera(newCamera: Camera, cb: ()=>void){
- if(this.isAnimating()){
- return;
- }
- this.animating = true;
- var oldPosition = this.getPosition();
- var newPosition = newCamera.matrix.getPosition();
- var span = this.animationDuration;
- var singleSpan = 1000 / 60;
- var count = Math.floor(span / singleSpan);
- var deltaX = (newPosition.x - oldPosition.x) / count;
- var deltaY = (newPosition.y - oldPosition.y) / count;
- var deltaZ = (newPosition.z - oldPosition.z) / count;
- var start:number = -1;
- var callback = (timestap: number) => {
- if(start < 0){
- start = timestap;
- }
- var a = timestap - start;
- if(a >= span){
- (Object).assign(this, newCamera.toJson());
- this.animating = false;
- cb();
- }else{
- var p = this.getPosition();
- this.setPosition(p.x + deltaX, p.y + deltaY, p.z + deltaZ);
- requestAnimationFrame(callback);
- }
- };
- requestAnimationFrame(callback);
- }
-
- private _animateToLevel(level: number): Camera{
- if (!(Utils.isNonNegativeInteger(level))) {
- throw "invalid level:" + level;
- }
- var camera = this._clone();
- //don't call setLevel method because it will update CURRENT_LEVEL
- camera._setLevel(level);
- return camera;
- }
-
- private _clone(): Camera{
- var camera: Camera = new Camera();
- (Object).assign(camera, this.toJson());
- return camera;
- }
-
- toJson(): any {
- return {
- pitch: this.pitch,
- near: this.near,
- far: this.far,
- fov: this.fov,
- aspect: this.aspect,
- matrix: this.matrix.clone(),
- projMatrix: this.projMatrix.clone()
- };
- }
-
- setLevel(level: number): void{
- this._setLevel(level);
- //don't update CURRENT_LEVEL in _setLevel method because it will affect animateToLevel method
- Kernel.globe.level = level;
- }
-
- //设置观察到的层级
- private _setLevel(level: number): void {
- if (!(Utils.isNonNegativeInteger(level))) {
- throw "invalid level:" + level;
- }
- var globe = Kernel.globe;
- var pOld = this.getPosition();
- if (pOld.x === 0 && pOld.y === 0 && pOld.z === 0) {
- //初始设置camera
- var length = MathUtils.getLengthFromCamera2EarthSurface(level) + Kernel.EARTH_RADIUS; //level等级下摄像机应该到球心的距离
- var origin = new Vertice(0, 0, 0);
- var vector = this.getLightDirection().getOpposite();
- vector.setLength(length);
- var newPosition = vector.getVertice();
- this.look(newPosition, origin);
- } else {
- var length2SurfaceNow = MathUtils.getLengthFromCamera2EarthSurface(globe.getLevel());
- var length2Surface = MathUtils.getLengthFromCamera2EarthSurface(level);
- var deltaLength = length2SurfaceNow - length2Surface;
- var dir = this.getLightDirection();
- dir.setLength(deltaLength);
- var pNew = Vector.verticePlusVector(pOld, dir);
- this.setPosition(pNew.x, pNew.y, pNew.z);
- }
- }
-
//判断世界坐标系中的点是否在Canvas中可见
//options:projView、verticeInNDC
isWorldVerticeVisibleInCanvas(verticeInWorld: Vertice, options?: any): boolean {
@@ -520,7 +555,8 @@ class Camera extends Object3D {
return false;
}
- function handleRow(centerRow: number, centerColumn: number) {
+ //处理一整行
+ function handleRow(centerRow: number, centerColumn: number): TileGrid[] {
var result: TileGrid[] = [];
var grid = new TileGrid(level, centerRow, centerColumn); // {level:level,row:centerRow,column:centerColumn};
var visibleInfo = this.getTileVisibleInfo(grid.level, grid.row, grid.column, options);
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index ea6a40a..ec6a4d9 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -13,7 +13,6 @@ import EventUtils = require("./Event");
class Globe {
REFRESH_INTERVAL: number = 300; //Globe自动刷新时间间隔,以毫秒为单位
idTimeOut: any = null; //refresh自定刷新的timeOut的handle
- level: number = -1; //当前渲染等级
renderer: Renderer = null;
scene: Scene = null;
camera: Camera = null;
@@ -75,21 +74,12 @@ class Globe {
}
getLevel(){
- return this.level;
+ return this.camera ? this.camera.getLevel() : -1;
}
setLevel(level: number) {
- if (!Utils.isNonNegativeInteger(level)) {
- throw "invalid level:" + level;
- }
-
- level = level > Kernel.MAX_LEVEL ? Kernel.MAX_LEVEL : level; //超过最大的渲染级别就不渲染
- if (level != this.getLevel()) {
- if (this.camera instanceof Camera) {
- //要先执行camera.setLevel,然后再刷新
- this.camera.setLevel(level);
- this.refresh();
- }
+ if(this.camera){
+ this.camera.setLevel(level);
}
}
diff --git a/src/world/math/Math.ts b/src/world/math/Math.ts
index 4e052ca..e72b5f5 100644
--- a/src/world/math/Math.ts
+++ b/src/world/math/Math.ts
@@ -325,15 +325,6 @@ const MathUtils = {
return [canvasX, canvasY];
},
- /**
- * 根据层级计算出摄像机应该放置到距离地球表面多远的位置
- * @param level
- * @return {*}
- */
- getLengthFromCamera2EarthSurface(level: number): number{
- return 1.23 * Kernel.EARTH_RADIUS / Math.pow(2, level);
- },
-
/**将经纬度转换为笛卡尔空间直角坐标系中的x、y、z
* @lon 经度(角度单位)
* @lat 纬度(角度单位)
From e69fe965ee4315853aededd72a8aa9e7d7d07cee Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Sat, 26 Nov 2016 18:35:03 +0800
Subject: [PATCH 052/109] update,#14
---
src/world/Camera.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index e1d10cf..80a220b 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -229,7 +229,6 @@ class Camera extends Object3D {
if (pOld.x === 0 && pOld.y === 0 && pOld.z === 0) {
//初始设置camera
var length = this._getTheoryDistanceFromCamera2EarthSurface(level) + Kernel.EARTH_RADIUS; //level等级下摄像机应该到球心的距离
- //var newPosition = MathUtils.geographicToCartesianCoord(115, 0, Kernel.EARTH_RADIUS + length)
var origin = new Vertice(0, 0, 0);
var vector = this.getLightDirection().getOpposite();
vector.setLength(length);
From 01d41eb63032c0eef2ff44c8c93f9fc5eee7666a Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Sat, 26 Nov 2016 19:12:04 +0800
Subject: [PATCH 053/109] make _updatePositionAndFov basically work,#14
---
src/world/Camera.ts | 12 +++++++-----
src/world/layers/PoiLayer.ts | 4 ++--
src/world/layers/TiledLayer.ts | 4 ++--
3 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index 80a220b..9e551c1 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -125,8 +125,10 @@ class Camera extends Object3D {
}
update(): void {
+ this.viewMatrix = null;
+
//通过修改position和fov以更新matrix和projMatrix
- //this._updatePositionAndFov();
+ this._updatePositionAndFov();
//在_updatePositionAndFov()方法调用之后再计算viewMatrix
this.viewMatrix = this.getViewMatrix();
@@ -178,7 +180,7 @@ class Camera extends Object3D {
var safeLevel = this._getSafeThresholdLevelForNear();
var deltaLevel = this.getLevel() - safeLevel;
if(deltaLevel !== 0){
- this._rawSetLevel(deltaLevel);
+ this._rawUpdatePositionByLevel(safeLevel);
//摄像机位置拉远之后,我们看到的地球变小,为此,我们需要把fov值变小,以抵消摄像机位置距离增大导致的变化
var newFov = this._calculateFovByDeltaLevel(this.fov, deltaLevel);
this._setFov(newFov);
@@ -207,7 +209,7 @@ class Camera extends Object3D {
}
setLevel(level: number): void {
- var isLevelChanged = this._rawSetLevel(level);
+ var isLevelChanged = this._rawUpdatePositionByLevel(level);
if (isLevelChanged) {
//不要在this._setLevel()方法中更新this.level,因为这会影响animateToLevel()方法
this.level = level;
@@ -216,7 +218,7 @@ class Camera extends Object3D {
}
//设置观察到的层级,不要在该方法中修改this.level的值
- private _rawSetLevel(level: number): boolean {
+ private _rawUpdatePositionByLevel(level: number): boolean {
if (!(Utils.isNonNegativeInteger(level))) {
throw "invalid level:" + level;
}
@@ -295,7 +297,7 @@ class Camera extends Object3D {
}
var camera = this._clone();
//don't call setLevel method because it will update CURRENT_LEVEL
- camera._rawSetLevel(level);
+ camera._rawUpdatePositionByLevel(level);
return camera;
}
diff --git a/src/world/layers/PoiLayer.ts b/src/world/layers/PoiLayer.ts
index 2744c60..db95d1e 100644
--- a/src/world/layers/PoiLayer.ts
+++ b/src/world/layers/PoiLayer.ts
@@ -12,8 +12,8 @@ class PoiLayer extends GraphicGroup{
constructor(){
super();
- //var p = MathUtils.geographicToCartesianCoord(116.408540, 39.902350, Kernel.EARTH_RADIUS + 0.001);
- var p = MathUtils.geographicToCartesianCoord(0, 0, Kernel.EARTH_RADIUS * 1.2);
+ var p = MathUtils.geographicToCartesianCoord(116.408540, 39.902350, Kernel.EARTH_RADIUS + 0.001);
+ //var p = MathUtils.geographicToCartesianCoord(0, 0, Kernel.EARTH_RADIUS * 1.2);
var marker = new Marker(p.x, p.y, p.z);
var url = "/WebGlobe/src/world/images/poi.png";
var material = new PoiMaterial(url, 24);
diff --git a/src/world/layers/TiledLayer.ts b/src/world/layers/TiledLayer.ts
index 5dadd3a..d1bd0ac 100644
--- a/src/world/layers/TiledLayer.ts
+++ b/src/world/layers/TiledLayer.ts
@@ -9,10 +9,10 @@ abstract class TiledLayer extends GraphicGroup {
//重写
draw(camera: Camera){
//此处将深度测试设置为ALWAYS是为了解决两个不同层级的切片在拖动时一起渲染会导致屏闪的问题
- //Kernel.gl.depthFunc(Kernel.gl.ALWAYS);
+ Kernel.gl.depthFunc(Kernel.gl.ALWAYS);
super.draw(camera);
//将深度测试恢复成LEQUAL
- //Kernel.gl.depthFunc(Kernel.gl.LEQUAL);
+ Kernel.gl.depthFunc(Kernel.gl.LEQUAL);
}
//重写
From 8d433c0b1861bf3269ea1fb78183a49c945be808 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Sat, 26 Nov 2016 22:10:16 +0800
Subject: [PATCH 054/109] fix globe.tick() bug and make
camera._updatePositionAndFov() work,#14
---
src/world/Camera.ts | 131 +++++++++++++++++++++++++++++++++++---------
src/world/Globe.ts | 7 ++-
2 files changed, 111 insertions(+), 27 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index 9e551c1..c99d696 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -11,10 +11,10 @@ import Matrix = require('./math/Matrix');
import Object3D = require('./Object3D');
class Camera extends Object3D {
+ private readonly initFov: number;
private readonly animationDuration: number = 600;//层级变化的动画周期是600毫秒
private readonly nearFactor: number = 0.6;
private readonly baseTheoryDistanceFromCamera2EarthSurface = 1.23 * Kernel.EARTH_RADIUS;
-
deltaFovLevel: number = 0;
thresholdLevelForNear: number = -1;
level: number = -1; //当前渲染等级
@@ -34,6 +34,7 @@ class Camera extends Object3D {
//this.fov可以调整以实现缩放效果
constructor(private fov = 45, private aspect = 1, private near = 1, private far = 100) {
super();
+ this.initFov = this.fov;
this.pitch = 90;
this.projMatrix = new Matrix();
this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, this.far);
@@ -142,7 +143,7 @@ class Camera extends Object3D {
//计算从第几级level开始不满足视景体的near值
//比如第10级满足near,第11级不满足near,那么返回10
- private _getSafeThresholdLevelForNear(){
+ private _getSafeThresholdLevelForNear() {
var thresholdNear = this.near * this.nearFactor;
var pow2level = this.baseTheoryDistanceFromCamera2EarthSurface / thresholdNear;
var level = (Math).log2(pow2level);
@@ -167,32 +168,104 @@ class Camera extends Object3D {
}
//返回更新后的fov值,如果返回结果 < 0,说明无需更新fov
- private _updatePositionAndFov(): number{
+ private _updatePositionAndFov(): number {
+ //是否满足near值,和fov没有关系,和position有关
+ //但是改变position的话,fov也要相应变动以满足对应的缩放效果
+
// var safeThresholdLevel = this._getSafeThresholdLevelForNear();
// if(this.getLevel() > safeThresholdLevel){
// }
- var distance2EarthSurface = this.getDistance2EarthSurface();
- var thresholdNear = this.near * this.nearFactor;
- if(distance2EarthSurface <= thresholdNear){
- //摄像机距离地球太近,导致图层不满足视景体的near值
+ const currentLevel = this.getLevel();
+
+ var safeLevel = this._getSafeThresholdLevelForNear();
+
+ if(currentLevel > safeLevel){
+ //摄像机距离地球太近,导致不满足视景体的near值,
//我们需要将摄像机的位置拉远,以满足near值
- var safeLevel = this._getSafeThresholdLevelForNear();
- var deltaLevel = this.getLevel() - safeLevel;
- if(deltaLevel !== 0){
- this._rawUpdatePositionByLevel(safeLevel);
- //摄像机位置拉远之后,我们看到的地球变小,为此,我们需要把fov值变小,以抵消摄像机位置距离增大导致的变化
- var newFov = this._calculateFovByDeltaLevel(this.fov, deltaLevel);
- this._setFov(newFov);
- return this.fov;
- }
- }
+ this._rawUpdatePositionByLevel(safeLevel);
+ //比如safeLevel是10,而currentLevel是11,则deltaLevel为1
+ var deltaLevel = currentLevel - safeLevel;
+ //摄像机位置与地球表面距离变大之后,我们看到的地球变小,为此,我们需要把fov值变小,以抵消摄像机位置距离增大导致的变化
+ //deltaLevel应该为正正数,计算出的newFov应该比this.initFov要小
+ var newFov = this._calculateFovByDeltaLevel(this.initFov, deltaLevel);
+ this._setFov(newFov);
+ }else{
+ this._rawUpdatePositionByLevel(currentLevel);
+ this._setFov(this.initFov);
+ }
+
+ // var distance2EarthSurface = this.getDistance2EarthSurface();
+ // var thresholdNear = this.near * this.nearFactor;
+ // if (distance2EarthSurface <= thresholdNear) {
+ // //摄像机距离地球太近,导致不满足视景体的near值
+ // //我们需要将摄像机的位置拉远,以满足near值
+
+ // //比如currentLevel为11,safeLevel为10
+ // deltaLevel = currentLevel - safeLevel;
+ // //此处的deltaLevel应该为正数
+ // if (deltaLevel !== 0) {
+ // newLevel = safeLevel;
+ // this._rawUpdatePositionByLevel(newLevel);
+ // //摄像机位置与地球表面距离变大之后,我们看到的地球变小,为此,我们需要把fov值变小,以抵消摄像机位置距离增大导致的变化
+ // var newFov = this._calculateFovByDeltaLevel(this.initFov, deltaLevel);
+ // this._setFov(newFov);
+ // return this.fov;
+ // }
+ // } else {
+ // //现在满足near值
+
+ // if (this.fov < this.initFov * 0.95 && currentLevel <= safeLevel) {
+ // //如果当前fov的值比初始的initFov值小,说明当前的fov被缩放过(0.95用于精度问题,防止出现29.999999与30进行对比的情况)
+ // //比如currentLevel为11,this.fov为15,this.initFov为10,deltaLevel应该为负值
+ // deltaLevel = this._calculateDeltaLevelByFov(this.fov, this.initFov);
+ // newLevel = currentLevel + deltaLevel;
+ // //上面的newLevel是float类型,向上取整,不要向下取整
+ // newLevel = Math.ceil(newLevel);
+ // //deltaLevel应该为负整数
+ // deltaLevel = newLevel - currentLevel;
+ // //比如currentLevel为11,newLevel为10,deltaLevel为-1
+ // this._rawUpdatePositionByLevel(newLevel);
+ // var newFov = this._calculateFovByDeltaLevel(this.fov, deltaLevel);
+ // this._setFov(newFov);
+ // return this.fov;
+ // } else if (this.fov > this.initFov * 1.05) {
+ // //不应该出现当前fov值比初始initFov的大的情况
+ // throw `_updatePositionAndFov() Invalid fov: ${this.fov}`;
+ // }
+ //}
+
return -1;
}
- //通过调整fov的值造成层级缩放的效果
+
+ //fov从oldFov变成了newFov,计算相当于缩放了几级level
+ //比如从10级缩放到了第11级,fov从30变成了15,即oldFov为30,newFov为15,deltaLevel为1
+ //通过Math.log2()计算出结果,所以返回的是小数,可能是正数也可能是负数
+ private _calculateDeltaLevelByFov(oldFov: number, newFov: number): number {
+ //tan(halfFov) = h / distance,level不同的情况下h不变
+ //h1 = l1*tanθ1
+ //h2 = l2*tanθ2
+ //l2 = l1 * Math.pow(2, deltaLevel)
+ //deltaLevel = Math.log2(tanθ1 / tanθ2)
+ var radianOldFov = MathUtils.degreeToRadian(oldFov);
+ var halfRadianOldFov = radianOldFov / 2;
+ var tanOld = Math.tan(halfRadianOldFov);
+
+ var radianNewFov = MathUtils.degreeToRadian(newFov);
+ var halfRadianNewFov = radianNewFov / 2;
+ var tanNew = Math.tan(halfRadianNewFov);
+
+ var deltaLevel = (Math).log2(tanOld / tanNew);
+ return deltaLevel;
+ }
+
+ //通过调整fov的值造成层级缩放的效果,比如在第10级的时候,oldFov为正常的30度,当放大到11级的时候,deltaLevel为1,计算出的新的newFov为15度多
private _calculateFovByDeltaLevel(oldFov: number, deltaLevel: number): number {
- //tan(halfFov) = h / distance
+ //tan(halfFov) = h / distance,level不同的情况下h不变
+ //h1 = l1*tanθ1
+ //h2 = l2*tanθ2
+ //l2 = l1 * Math.pow(2, deltaLevel)
var radianOldFov = MathUtils.degreeToRadian(oldFov);
var halfRadianOldFov = radianOldFov / 2;
var tanOld = Math.tan(halfRadianOldFov);
@@ -237,13 +310,19 @@ class Camera extends Object3D {
var newPosition = vector.getVertice();
this.look(newPosition, origin);
} else {
- var distance2SurfaceNow = this._getTheoryDistanceFromCamera2EarthSurface(this.getLevel());
- var distance2SurfaceNew = this._getTheoryDistanceFromCamera2EarthSurface(level);
- var deltaDistance = distance2SurfaceNow - distance2SurfaceNew;
- var dir = this.getLightDirection();
- dir.setLength(deltaDistance);
- var pNew = Vector.verticePlusVector(pOld, dir);
- this.setPosition(pNew.x, pNew.y, pNew.z);
+ var length = this._getTheoryDistanceFromCamera2EarthSurface(level) + Kernel.EARTH_RADIUS; //level等级下摄像机应该到球心的距离
+ var vector = this.getLightDirection().getOpposite();
+ vector.setLength(length);
+ var newPosition = vector.getVertice();
+ this.setPosition(newPosition.x, newPosition.y, newPosition.z);
+
+ // var distance2SurfaceNow = this._getTheoryDistanceFromCamera2EarthSurface(this.getLevel());
+ // var distance2SurfaceNew = this._getTheoryDistanceFromCamera2EarthSurface(level);
+ // var deltaDistance = distance2SurfaceNow - distance2SurfaceNew;
+ // var dir = this.getLightDirection();
+ // dir.setLength(deltaDistance);
+ // var pNew = Vector.verticePlusVector(pOld, dir);
+ // this.setPosition(pNew.x, pNew.y, pNew.z);
}
return true;
}
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index ec6a4d9..ed1b827 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -122,7 +122,12 @@ class Globe {
tick() {
var globe = Kernel.globe;
if (globe) {
- globe.refresh();
+ try{
+ //如果refresh方法出现异常而且没有捕捉,那么就会导致无法继续设置setTimeout,从而无法进一步更新切片
+ globe.refresh();
+ }catch(e){
+ console.error(e);
+ }
this.idTimeOut = setTimeout(globe.tick, globe.REFRESH_INTERVAL);
}
}
From ae928a5e9e2339ef05a972dc7637be3318c7bcc6 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Sun, 27 Nov 2016 01:17:54 +0800
Subject: [PATCH 055/109] add setPitch() and getPitch() method for camera,#14
---
src/world/Camera.ts | 12 ++++++++++--
src/world/Event.ts | 6 +++---
src/world/Globe.ts | 3 +--
src/world/Kernel.ts | 18 +++++++++---------
4 files changed, 23 insertions(+), 16 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index c99d696..3d1293f 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -15,10 +15,10 @@ class Camera extends Object3D {
private readonly animationDuration: number = 600;//层级变化的动画周期是600毫秒
private readonly nearFactor: number = 0.6;
private readonly baseTheoryDistanceFromCamera2EarthSurface = 1.23 * Kernel.EARTH_RADIUS;
+ private pitch: number;
deltaFovLevel: number = 0;
thresholdLevelForNear: number = -1;
- level: number = -1; //当前渲染等级
- pitch: number;
+ level: number = -1; //当前渲染等级
viewMatrix: Matrix;
projMatrix: Matrix;//当Matrix变化的时候,需要重新计算this.far
projViewMatrix: Matrix;
@@ -77,6 +77,14 @@ class Camera extends Object3D {
);
}
+ getPitch(): number{
+ return this.pitch;
+ }
+
+ setPitch(pitch: number): void{
+
+ }
+
getLightDirection(): Vector {
var dirVertice = this.matrix.getColumnZ();
var direction = new Vector(-dirVertice.x, -dirVertice.y, -dirVertice.z);
diff --git a/src/world/Event.ts b/src/world/Event.ts
index 1c7b9ec..250da89 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -172,11 +172,11 @@ const EventModule = {
//上、下、左、右:38、40、37、39
if (keyNum == 38 || keyNum == 40) {
if (keyNum == 38) {
- if (camera.pitch <= MIN_PITCH) {
+ if (camera.getPitch() <= MIN_PITCH) {
return;
}
} else if (keyNum == 40) {
- if (camera.pitch >= 90) {
+ if (camera.getPitch() >= 90) {
return;
}
DELTA_PITCH *= -1;
@@ -195,7 +195,7 @@ const EventModule = {
dirZ.setLength(legnth2Intersect);
var pNew = Vector.verticePlusVector(pIntersect, dirZ);
camera.look(pNew, pIntersect);
- camera.pitch -= DELTA_PITCH;
+ camera.setPitch(camera.getPitch() - DELTA_PITCH);
globe.refresh();
} else {
alert("视线与地球无交点");
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index ed1b827..39553b0 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -145,7 +145,7 @@ class Globe {
projView: projView,
threshold: 1
};
- options.threshold = Math.min(90 / this.camera.pitch, 1.5);
+ options.threshold = Math.min(90 / this.camera.getPitch(), 1.5);
//最大级别的level所对应的可见TileGrids
var lastLevelTileGrids = this.camera.getVisibleTilesByLevel(level, options);
var levelsTileGrids: any[] = []; //level-2
@@ -166,7 +166,6 @@ class Globe {
levelsTileGrids.splice(0, 1);
}
}
-
}
export = Globe;
\ No newline at end of file
diff --git a/src/world/Kernel.ts b/src/world/Kernel.ts
index ec6c06f..e906352 100644
--- a/src/world/Kernel.ts
+++ b/src/world/Kernel.ts
@@ -7,16 +7,16 @@ const radius = 500;//6378137
const maxProjectedCoord = Math.PI * radius;
const Kernel = {
- gl: null,
+ gl: null,
canvas: null,
- renderer: null,
- globe: null,
- idCounter: 0, //Object3D对象的唯一标识
- BASE_LEVEL: 6, //渲染的基准层级
- MAX_LEVEL: 14,//最大的渲染级别
- EARTH_RADIUS: radius,
- MAX_PROJECTED_COORD: maxProjectedCoord,
- proxy: ""
+ renderer: null,
+ globe: null,
+ idCounter: 0, //Object3D对象的唯一标识
+ BASE_LEVEL: 6, //渲染的基准层级
+ MAX_LEVEL: 14,//最大的渲染级别
+ EARTH_RADIUS: radius,
+ MAX_PROJECTED_COORD: maxProjectedCoord,
+ proxy: ""
};
export = Kernel;
\ No newline at end of file
From 3171c01252c77902072cdc2aea8aa68dd5ef4a91 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Sun, 27 Nov 2016 14:36:55 +0800
Subject: [PATCH 056/109] keep some fields and method private,#14,#18
---
src/world/Camera.ts | 156 ++++++++++--------------------
src/world/Event.ts | 2 +-
src/world/Globe.ts | 4 +-
src/world/Object3D.ts | 10 +-
src/world/Renderer.ts | 1 -
src/world/graphics/MeshGraphic.ts | 2 +-
src/world/graphics/Poi.ts | 2 +-
7 files changed, 67 insertions(+), 110 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index 3d1293f..858f736 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -16,17 +16,16 @@ class Camera extends Object3D {
private readonly nearFactor: number = 0.6;
private readonly baseTheoryDistanceFromCamera2EarthSurface = 1.23 * Kernel.EARTH_RADIUS;
private pitch: number;
- deltaFovLevel: number = 0;
- thresholdLevelForNear: number = -1;
- level: number = -1; //当前渲染等级
- viewMatrix: Matrix;
- projMatrix: Matrix;//当Matrix变化的时候,需要重新计算this.far
- projViewMatrix: Matrix;
+ private level: number = -1; //当前渲染等级
+ private viewMatrix: Matrix;//视点矩阵,即Camera模型矩阵的逆矩阵
+ private projMatrix: Matrix;//当Matrix变化的时候,需要重新计算this.far
+ private projViewMatrix: Matrix;//获取投影矩阵与视点矩阵的乘积
+ 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没有全部被地球充满
};
- private animating: boolean = false;
//this.near一旦初始化之后就不应该再修改
//this.far可以动态计算
@@ -78,6 +77,8 @@ class Camera extends Object3D {
}
getPitch(): number{
+ var lightDirection = this.getLightDirection();
+
return this.pitch;
}
@@ -98,11 +99,8 @@ class Camera extends Object3D {
return length2EarthSurface;
}
- //获取投影矩阵与视点矩阵的乘积
- getProjViewMatrix(): Matrix {
- var viewMatrix = this.getViewMatrix();
- var projViewMatrix = this.projMatrix.multiplyMatrix(viewMatrix);
- return projViewMatrix;
+ getProjViewMatrixForDraw(): Matrix{
+ return this.projViewMatrix;
}
private _setFov(fov: number): void {
@@ -179,15 +177,12 @@ class Camera extends Object3D {
private _updatePositionAndFov(): number {
//是否满足near值,和fov没有关系,和position有关
//但是改变position的话,fov也要相应变动以满足对应的缩放效果
-
- // var safeThresholdLevel = this._getSafeThresholdLevelForNear();
- // if(this.getLevel() > safeThresholdLevel){
-
- // }
const currentLevel = this.getLevel();
-
var safeLevel = this._getSafeThresholdLevelForNear();
+ //_rawUpdatePositionByLevel()方法会修改this.matrix
+ //_setFov()方法会修改this.projMatrix
+
if(currentLevel > safeLevel){
//摄像机距离地球太近,导致不满足视景体的near值,
//我们需要将摄像机的位置拉远,以满足near值
@@ -203,46 +198,6 @@ class Camera extends Object3D {
this._setFov(this.initFov);
}
- // var distance2EarthSurface = this.getDistance2EarthSurface();
- // var thresholdNear = this.near * this.nearFactor;
- // if (distance2EarthSurface <= thresholdNear) {
- // //摄像机距离地球太近,导致不满足视景体的near值
- // //我们需要将摄像机的位置拉远,以满足near值
-
- // //比如currentLevel为11,safeLevel为10
- // deltaLevel = currentLevel - safeLevel;
- // //此处的deltaLevel应该为正数
- // if (deltaLevel !== 0) {
- // newLevel = safeLevel;
- // this._rawUpdatePositionByLevel(newLevel);
- // //摄像机位置与地球表面距离变大之后,我们看到的地球变小,为此,我们需要把fov值变小,以抵消摄像机位置距离增大导致的变化
- // var newFov = this._calculateFovByDeltaLevel(this.initFov, deltaLevel);
- // this._setFov(newFov);
- // return this.fov;
- // }
- // } else {
- // //现在满足near值
-
- // if (this.fov < this.initFov * 0.95 && currentLevel <= safeLevel) {
- // //如果当前fov的值比初始的initFov值小,说明当前的fov被缩放过(0.95用于精度问题,防止出现29.999999与30进行对比的情况)
- // //比如currentLevel为11,this.fov为15,this.initFov为10,deltaLevel应该为负值
- // deltaLevel = this._calculateDeltaLevelByFov(this.fov, this.initFov);
- // newLevel = currentLevel + deltaLevel;
- // //上面的newLevel是float类型,向上取整,不要向下取整
- // newLevel = Math.ceil(newLevel);
- // //deltaLevel应该为负整数
- // deltaLevel = newLevel - currentLevel;
- // //比如currentLevel为11,newLevel为10,deltaLevel为-1
- // this._rawUpdatePositionByLevel(newLevel);
- // var newFov = this._calculateFovByDeltaLevel(this.fov, deltaLevel);
- // this._setFov(newFov);
- // return this.fov;
- // } else if (this.fov > this.initFov * 1.05) {
- // //不应该出现当前fov值比初始initFov的大的情况
- // throw `_updatePositionAndFov() Invalid fov: ${this.fov}`;
- // }
- //}
-
return -1;
}
@@ -281,7 +236,6 @@ class Camera extends Object3D {
var halfRadianNewFov = Math.atan(tanNew);
var radianNewFov = halfRadianNewFov * 2;
var newFov = MathUtils.radianToDegree(radianNewFov);
- this.deltaFovLevel += deltaLevel;
return newFov;
}
@@ -340,7 +294,13 @@ class Camera extends Object3D {
}
animateToLevel(level: number): void {
- var newCamera = this._animateToLevel(level);
+ if (!(Utils.isNonNegativeInteger(level))) {
+ throw "invalid level:" + level;
+ }
+ var newCamera = this._clone();
+ //don't call setLevel method because it will update CURRENT_LEVEL
+ newCamera._rawUpdatePositionByLevel(level);
+
this._animateToCamera(newCamera, () => {
this.level = level;
});
@@ -378,16 +338,6 @@ class Camera extends Object3D {
requestAnimationFrame(callback);
}
- private _animateToLevel(level: number): Camera {
- if (!(Utils.isNonNegativeInteger(level))) {
- throw "invalid level:" + level;
- }
- var camera = this._clone();
- //don't call setLevel method because it will update CURRENT_LEVEL
- camera._rawUpdatePositionByLevel(level);
- return camera;
- }
-
private _clone(): Camera {
var camera: Camera = new Camera();
(Object).assign(camera, this.toJson());
@@ -426,19 +376,19 @@ class Camera extends Object3D {
this._updateFar();
}
- lookAt(targetPnt: Vertice, upDirection?: Vector): void {
+ private _lookAt(targetPnt: Vertice, upDirection?: Vector): void {
var targetPntCopy = targetPnt.clone();
var position = this.getPosition();
this.look(position, targetPntCopy, upDirection);
}
//点变换: World->NDC
- convertVerticeFromWorldToNDC(verticeInWorld: Vertice, /*optional*/ projViewMatrix?: Matrix): Vertice {
- if (!(projViewMatrix instanceof Matrix)) {
- projViewMatrix = this.getProjViewMatrix();
- }
+ private convertVerticeFromWorldToNDC(verticeInWorld: Vertice): Vertice {
+ // if (!(projViewMatrix instanceof Matrix)) {
+ // projViewMatrix = this.getProjViewMatrix();
+ // }
var columnWorld = [verticeInWorld.x, verticeInWorld.y, verticeInWorld.z, 1];
- var columnProject = projViewMatrix.multiplyColumn(columnWorld);
+ var columnProject = this.projViewMatrix.multiplyColumn(columnWorld);
var w = columnProject[3];
var columnNDC: number[] = [];
columnNDC[0] = columnProject[0] / w;
@@ -450,7 +400,7 @@ class Camera extends Object3D {
}
//点变换: NDC->World
- convertVerticeFromNdcToWorld(verticeInNDC: Vertice): Vertice {
+ private convertVerticeFromNdcToWorld(verticeInNDC: Vertice): Vertice {
var columnNDC: number[] = [verticeInNDC.x, verticeInNDC.y, verticeInNDC.z, 1]; //NDC归一化坐标
var inverseProj = this.projMatrix.getInverseMatrix(); //投影矩阵的逆矩阵
var columnCameraTemp = inverseProj.multiplyColumn(columnNDC); //带引号的“视坐标”
@@ -468,7 +418,7 @@ class Camera extends Object3D {
}
//点变换: Camera->World
- convertVerticeFromCameraToWorld(verticeInCamera: Vertice, /*optional*/ viewMatrix?: Matrix): Vertice {
+ private convertVerticeFromCameraToWorld(verticeInCamera: Vertice, /*optional*/ viewMatrix?: Matrix): Vertice {
if (!(viewMatrix instanceof Matrix)) {
viewMatrix = this.getViewMatrix();
}
@@ -481,7 +431,7 @@ class Camera extends Object3D {
}
//向量变换: Camera->World
- convertVectorFromCameraToWorld(vectorInCamera: Vector, /*optional*/ viewMatrix?: Matrix): Vector {
+ private convertVectorFromCameraToWorld(vectorInCamera: Vector, /*optional*/ viewMatrix?: Matrix): Vector {
if (!(vectorInCamera instanceof Vector)) {
throw "invalid vectorInCamera: not Vector";
}
@@ -565,7 +515,7 @@ class Camera extends Object3D {
}
//得到摄像机的XOZ平面的方程
- getPlanXOZ(): Plan {
+ private getPlanXOZ(): Plan {
var position = this.getPosition();
var direction = this.getLightDirection();
var plan = MathUtils.getCrossPlaneByLine(position, direction);
@@ -574,7 +524,7 @@ class Camera extends Object3D {
//判断世界坐标系中的点是否在Canvas中可见
//options:projView、verticeInNDC
- isWorldVerticeVisibleInCanvas(verticeInWorld: Vertice, options?: any): boolean {
+ private isWorldVerticeVisibleInCanvas(verticeInWorld: Vertice, options?: any): boolean {
if (!(verticeInWorld instanceof Vertice)) {
throw "invalid verticeInWorld: not Vertice";
}
@@ -590,10 +540,10 @@ class Camera extends Object3D {
var length2Pick = MathUtils.getLengthFromVerticeToVertice(cameraP, pickVertice);
if (length2Vertice < length2Pick + 5) {
if (!(options.verticeInNDC instanceof Vertice)) {
- if (!(options.projView instanceof Matrix)) {
- options.projView = this.getProjViewMatrix();
- }
- options.verticeInNDC = this.convertVerticeFromWorldToNDC(verticeInWorld, options.projView);
+ // if (!(options.projView instanceof Matrix)) {
+ // options.projView = this.getProjViewMatrix();
+ // }
+ options.verticeInNDC = this.convertVerticeFromWorldToNDC(verticeInWorld);
}
var result = options.verticeInNDC.x >= -1 && options.verticeInNDC.x <= 1 && options.verticeInNDC.y >= -threshold && options.verticeInNDC.y <= 1;
return result;
@@ -604,7 +554,7 @@ class Camera extends Object3D {
//判断地球表面的某个经纬度在Canvas中是否应该可见
//options:projView、verticeInNDC
- isGeoVisibleInCanvas(lon: number, lat: number, options?: any): boolean {
+ private isGeoVisibleInCanvas(lon: number, lat: number, options?: any): boolean {
var verticeInWorld = MathUtils.geographicToCartesianCoord(lon, lat);
var result = this.isWorldVerticeVisibleInCanvas(verticeInWorld, options);
return result;
@@ -624,9 +574,9 @@ class Camera extends Object3D {
}
var result: TileGrid[] = [];
options = options || {};
- if (!(options.projView instanceof Matrix)) {
- options.projView = this.getProjViewMatrix();
- }
+ // if (!(options.projView instanceof Matrix)) {
+ // options.projView = this.getProjViewMatrix();
+ // }
//向左、向右、向上、向下最大的循环次数
var LOOP_LIMIT = Math.min(10, Math.pow(2, level) - 1);
@@ -691,7 +641,7 @@ class Camera extends Object3D {
return result;
}
- var verticalCenterInfo = this._getVerticalVisibleCenterInfo(options);
+ var verticalCenterInfo = this._getVerticalVisibleCenterInfo();
var centerGrid = TileGrid.getTileGridByGeo(verticalCenterInfo.lon, verticalCenterInfo.lat, level);
var handleRowThis = handleRow.bind(this);
@@ -735,7 +685,7 @@ class Camera extends Object3D {
}
//options:projView
- getTileVisibleInfo(level: number, row: number, column: number, options?: any): any {
+ private getTileVisibleInfo(level: number, row: number, column: number, options?: any): any {
if (!(level >= 0)) {
throw "invalid level";
}
@@ -783,9 +733,9 @@ class Camera extends Object3D {
height: null,
area: null
};
- if (!(options.projView instanceof Matrix)) {
- options.projView = this.getProjViewMatrix();
- }
+ // if (!(options.projView instanceof Matrix)) {
+ // options.projView = this.getProjViewMatrix();
+ // }
result.Egeo = MathUtils.getTileGeographicEnvelopByGrid(level, row, column);
var tileMinLon = result.Egeo.minLon;
var tileMaxLon = result.Egeo.maxLon;
@@ -796,7 +746,7 @@ class Camera extends Object3D {
result.lb.lon = tileMinLon;
result.lb.lat = tileMinLat;
result.lb.verticeInWorld = MathUtils.geographicToCartesianCoord(result.lb.lon, result.lb.lat);
- result.lb.verticeInNDC = this.convertVerticeFromWorldToNDC(result.lb.verticeInWorld, options.projView);
+ result.lb.verticeInNDC = this.convertVerticeFromWorldToNDC(result.lb.verticeInWorld);
result.lb.visible = this.isWorldVerticeVisibleInCanvas(result.lb.verticeInWorld, {
verticeInNDC: result.lb.verticeInNDC,
projView: options.projView,
@@ -810,7 +760,7 @@ class Camera extends Object3D {
result.lt.lon = tileMinLon;
result.lt.lat = tileMaxLat;
result.lt.verticeInWorld = MathUtils.geographicToCartesianCoord(result.lt.lon, result.lt.lat);
- result.lt.verticeInNDC = this.convertVerticeFromWorldToNDC(result.lt.verticeInWorld, options.projView);
+ result.lt.verticeInNDC = this.convertVerticeFromWorldToNDC(result.lt.verticeInWorld);
result.lt.visible = this.isWorldVerticeVisibleInCanvas(result.lt.verticeInWorld, {
verticeInNDC: result.lt.verticeInNDC,
projView: options.projView,
@@ -824,7 +774,7 @@ class Camera extends Object3D {
result.rt.lon = tileMaxLon;
result.rt.lat = tileMaxLat;
result.rt.verticeInWorld = MathUtils.geographicToCartesianCoord(result.rt.lon, result.rt.lat);
- result.rt.verticeInNDC = this.convertVerticeFromWorldToNDC(result.rt.verticeInWorld, options.projView);
+ result.rt.verticeInNDC = this.convertVerticeFromWorldToNDC(result.rt.verticeInWorld);
result.rt.visible = this.isWorldVerticeVisibleInCanvas(result.rt.verticeInWorld, {
verticeInNDC: result.rt.verticeInNDC,
projView: options.projView,
@@ -838,7 +788,7 @@ class Camera extends Object3D {
result.rb.lon = tileMaxLon;
result.rb.lat = tileMinLat;
result.rb.verticeInWorld = MathUtils.geographicToCartesianCoord(result.rb.lon, result.rb.lat);
- result.rb.verticeInNDC = this.convertVerticeFromWorldToNDC(result.rb.verticeInWorld, options.projView);
+ result.rb.verticeInNDC = this.convertVerticeFromWorldToNDC(result.rb.verticeInWorld);
result.rb.visible = this.isWorldVerticeVisibleInCanvas(result.rb.verticeInWorld, {
verticeInNDC: result.rb.verticeInNDC,
projView: options.projView,
@@ -869,11 +819,11 @@ class Camera extends Object3D {
}
//地球一直是关于纵轴中心对称的,获取垂直方向上中心点信息
- private _getVerticalVisibleCenterInfo(options?: any): any {
- options = options || {};
- if (!options.projView) {
- options.projView = this.getProjViewMatrix();
- }
+ private _getVerticalVisibleCenterInfo(): any {
+ // options = options || {};
+ // if (!options.projView) {
+ // options.projView = this.getProjViewMatrix();
+ // }
var result = {
ndcY: null,
pIntersect: null,
diff --git a/src/world/Event.ts b/src/world/Event.ts
index 250da89..19b0cbe 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -187,7 +187,7 @@ const EventModule = {
var pIntersect = pickResult[0];
var pCamera = camera.getPosition();
var legnth2Intersect = MathUtils.getLengthFromVerticeToVertice(pCamera, pIntersect);
- var mat = camera.matrix.clone();
+ var mat = camera.cloneMatrix();
mat.setColumnTrans(pIntersect.x, pIntersect.y, pIntersect.z);
var DELTA_RADIAN = MathUtils.degreeToRadian(DELTA_PITCH);
mat.localRotateX(DELTA_RADIAN);
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index 39553b0..e83aad8 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -140,9 +140,9 @@ class Globe {
this.camera.update();
var level = this.getLevel() + 3;
this.tiledLayer.updateSubLayerCount(level);
- var projView = this.camera.getProjViewMatrix();
+ //var projView = this.camera.getProjViewMatrix();
var options = {
- projView: projView,
+ //projView: projView,
threshold: 1
};
options.threshold = Math.min(90 / this.camera.getPitch(), 1.5);
diff --git a/src/world/Object3D.ts b/src/world/Object3D.ts
index 9f64aa8..4be75e1 100644
--- a/src/world/Object3D.ts
+++ b/src/world/Object3D.ts
@@ -5,12 +5,20 @@ import Vertice = require('./math/Vertice');
import Vector = require('./math/Vector');
class Object3D {
- matrix: Matrix;
+ protected matrix: Matrix;
constructor() {
this.matrix = new Matrix();
}
+ getMatrix(): Matrix{
+ return this.matrix;
+ }
+
+ cloneMatrix(): Matrix{
+ return this.matrix.clone();
+ }
+
//需要子类重写
getPosition(): Vertice {
var position = this.matrix.getPosition();
diff --git a/src/world/Renderer.ts b/src/world/Renderer.ts
index 378d7c2..8105eb4 100644
--- a/src/world/Renderer.ts
+++ b/src/world/Renderer.ts
@@ -63,7 +63,6 @@ class Renderer {
Kernel.gl.enable(Kernel.gl.DEPTH_TEST);
Kernel.gl.depthFunc(Kernel.gl.LEQUAL);
Kernel.gl.depthMask(true);
- camera.viewMatrix = null;
//update viewMatrix, projMatrix and projViewMatrix
camera.update();
scene.draw(camera);
diff --git a/src/world/graphics/MeshGraphic.ts b/src/world/graphics/MeshGraphic.ts
index 0005ac1..c05353e 100644
--- a/src/world/graphics/MeshGraphic.ts
+++ b/src/world/graphics/MeshGraphic.ts
@@ -80,7 +80,7 @@ class MeshGraphic extends Graphic {
gl.vertexAttribPointer(locPosition, 3, gl.FLOAT, false, 0, 0);
//uPMVMatrix
- var pmvMatrix = camera.projViewMatrix.multiplyMatrix(this.geometry.matrix);
+ var pmvMatrix = camera.getProjViewMatrixForDraw().multiplyMatrix(this.geometry.getMatrix());
var locPMVMatrix = this.program.getUniformLocation('uPMVMatrix');
gl.uniformMatrix4fv(locPMVMatrix, false, pmvMatrix.elements);
diff --git a/src/world/graphics/Poi.ts b/src/world/graphics/Poi.ts
index 50c7f20..c3d7b96 100644
--- a/src/world/graphics/Poi.ts
+++ b/src/world/graphics/Poi.ts
@@ -54,7 +54,7 @@ class Poi extends Graphic {
gl.vertexAttribPointer(locPosition, 3, gl.FLOAT, false, 0, 0);
//uPMVMatrix
- var pmvMatrix = camera.projViewMatrix;
+ var pmvMatrix = camera.getProjViewMatrixForDraw();
var locPMVMatrix = this.program.getUniformLocation('uPMVMatrix');
gl.uniformMatrix4fv(locPMVMatrix, false, pmvMatrix.elements);
From ea179d4360ecec974b208096358bba202e4ed5ed Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Sun, 27 Nov 2016 15:14:17 +0800
Subject: [PATCH 057/109] optimize Camera: remove some uncessary local
variables for method,#14
---
src/world/Camera.ts | 116 +++++++++++++-------------------------------
1 file changed, 35 insertions(+), 81 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index 858f736..1c7046b 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -20,6 +20,7 @@ class Camera extends Object3D {
private viewMatrix: Matrix;//视点矩阵,即Camera模型矩阵的逆矩阵
private projMatrix: Matrix;//当Matrix变化的时候,需要重新计算this.far
private projViewMatrix: Matrix;//获取投影矩阵与视点矩阵的乘积
+ private projViewMatrixForDraw: Matrix;//实际传递给shader的矩阵是projViewMatrixForDraw,而不是projViewMatrix
private animating: boolean = false;
Enum: any = {
@@ -76,6 +77,26 @@ class Camera extends Object3D {
);
}
+ //更新各种矩阵,保守起见,可以在每帧绘制之前调用
+ //理论上只在用户交互的时候调用就可以
+ update(): void {
+ this.viewMatrix = null;
+ //视点矩阵是camera的模型矩阵的逆矩阵
+ //this.viewMatrix = this.matrix.getInverseMatrix();
+
+ //通过修改position和fov以更新matrix和projMatrix
+ this._updatePositionAndFov();
+
+ //在_updatePositionAndFov()方法调用之后再计算viewMatrix
+ this.viewMatrix = this.matrix.getInverseMatrix();
+
+ //最后更新far
+ this._updateFar();
+
+ //update projViewMatrix
+ this.projViewMatrix = this.projMatrix.multiplyMatrix(this.viewMatrix);
+ }
+
getPitch(): number{
var lightDirection = this.getLightDirection();
@@ -126,27 +147,6 @@ class Camera extends Object3D {
this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, far);
}
- getViewMatrix(): Matrix {
- //视点矩阵是camera的模型矩阵的逆矩阵
- return this.matrix.getInverseMatrix();
- }
-
- update(): void {
- this.viewMatrix = null;
-
- //通过修改position和fov以更新matrix和projMatrix
- this._updatePositionAndFov();
-
- //在_updatePositionAndFov()方法调用之后再计算viewMatrix
- this.viewMatrix = this.getViewMatrix();
-
- //最后更新far
- this._updateFar();
-
- //update projViewMatrix
- this.projViewMatrix = this.projMatrix.multiplyMatrix(this.viewMatrix);
- }
-
//计算从第几级level开始不满足视景体的near值
//比如第10级满足near,第11级不满足near,那么返回10
private _getSafeThresholdLevelForNear() {
@@ -165,14 +165,6 @@ class Camera extends Object3D {
return this.baseTheoryDistanceFromCamera2EarthSurface / Math.pow(2, level);
}
- private _setVirtualPosition(virtualPosisition: Vertice) {
-
- }
-
- private _getVirtualPosition(): Vertice {
- return null;
- }
-
//返回更新后的fov值,如果返回结果 < 0,说明无需更新fov
private _updatePositionAndFov(): number {
//是否满足near值,和fov没有关系,和position有关
@@ -201,7 +193,6 @@ class Camera extends Object3D {
return -1;
}
-
//fov从oldFov变成了newFov,计算相当于缩放了几级level
//比如从10级缩放到了第11级,fov从30变成了15,即oldFov为30,newFov为15,deltaLevel为1
//通过Math.log2()计算出结果,所以返回的是小数,可能是正数也可能是负数
@@ -384,9 +375,6 @@ class Camera extends Object3D {
//点变换: World->NDC
private convertVerticeFromWorldToNDC(verticeInWorld: Vertice): Vertice {
- // if (!(projViewMatrix instanceof Matrix)) {
- // projViewMatrix = this.getProjViewMatrix();
- // }
var columnWorld = [verticeInWorld.x, verticeInWorld.y, verticeInWorld.z, 1];
var columnProject = this.projViewMatrix.multiplyColumn(columnWorld);
var w = columnProject[3];
@@ -409,38 +397,25 @@ class Camera extends Object3D {
var cameraZ = columnCameraTemp[2] / columnCameraTemp[3];
var cameraW = 1;
var columnCamera = [cameraX, cameraY, cameraZ, cameraW]; //真实的视坐标
-
- var viewMatrix = this.getViewMatrix();
- var inverseView = viewMatrix.getInverseMatrix(); //视点矩阵的逆矩阵
- var columnWorld = inverseView.multiplyColumn(columnCamera); //单击点的世界坐标
+ var columnWorld = this.matrix.multiplyColumn(columnCamera); //单击点的世界坐标
var verticeInWorld = new Vertice(columnWorld[0], columnWorld[1], columnWorld[2]);
return verticeInWorld;
}
//点变换: Camera->World
- private convertVerticeFromCameraToWorld(verticeInCamera: Vertice, /*optional*/ viewMatrix?: Matrix): Vertice {
- if (!(viewMatrix instanceof Matrix)) {
- viewMatrix = this.getViewMatrix();
- }
+ private convertVerticeFromCameraToWorld(verticeInCamera: Vertice): Vertice {
var verticeInCameraCopy = verticeInCamera.clone();
- var inverseMatrix = viewMatrix.getInverseMatrix();
var column = [verticeInCameraCopy.x, verticeInCameraCopy.y, verticeInCameraCopy.z, 1];
- var column2 = inverseMatrix.multiplyColumn(column);
+ var column2 = this.matrix.multiplyColumn(column);
var verticeInWorld = new Vertice(column2[0], column2[1], column2[2]);
return verticeInWorld;
}
//向量变换: Camera->World
- private convertVectorFromCameraToWorld(vectorInCamera: Vector, /*optional*/ viewMatrix?: Matrix): Vector {
- if (!(vectorInCamera instanceof Vector)) {
- throw "invalid vectorInCamera: not Vector";
- }
- if (!(viewMatrix instanceof Matrix)) {
- viewMatrix = this.getViewMatrix();
- }
+ private convertVectorFromCameraToWorld(vectorInCamera: Vector): Vector {
var vectorInCameraCopy = vectorInCamera.clone();
var verticeInCamera = vectorInCameraCopy.getVertice();
- var verticeInWorld = this.convertVerticeFromCameraToWorld(verticeInCamera, viewMatrix);
+ var verticeInWorld = this.convertVerticeFromCameraToWorld(verticeInCamera);
var originInWorld = this.getPosition();
var vectorInWorld = Vector.verticeMinusVertice(verticeInWorld, originInWorld);
vectorInWorld.normalize();
@@ -523,12 +498,8 @@ class Camera extends Object3D {
}
//判断世界坐标系中的点是否在Canvas中可见
- //options:projView、verticeInNDC
- private isWorldVerticeVisibleInCanvas(verticeInWorld: Vertice, options?: any): boolean {
- if (!(verticeInWorld instanceof Vertice)) {
- throw "invalid verticeInWorld: not Vertice";
- }
- options = options || {};
+ //options: {verticeInNDC,threshold}
+ private isWorldVerticeVisibleInCanvas(verticeInWorld: Vertice, options: any = {}): boolean {
var threshold = typeof options.threshold == "number" ? Math.abs(options.threshold) : 1;
var cameraP = this.getPosition();
var dir = Vector.verticeMinusVertice(verticeInWorld, cameraP);
@@ -540,9 +511,6 @@ class Camera extends Object3D {
var length2Pick = MathUtils.getLengthFromVerticeToVertice(cameraP, pickVertice);
if (length2Vertice < length2Pick + 5) {
if (!(options.verticeInNDC instanceof Vertice)) {
- // if (!(options.projView instanceof Matrix)) {
- // options.projView = this.getProjViewMatrix();
- // }
options.verticeInNDC = this.convertVerticeFromWorldToNDC(verticeInWorld);
}
var result = options.verticeInNDC.x >= -1 && options.verticeInNDC.x <= 1 && options.verticeInNDC.y >= -threshold && options.verticeInNDC.y <= 1;
@@ -553,7 +521,7 @@ class Camera extends Object3D {
}
//判断地球表面的某个经纬度在Canvas中是否应该可见
- //options:projView、verticeInNDC
+ //options: verticeInNDC
private isGeoVisibleInCanvas(lon: number, lat: number, options?: any): boolean {
var verticeInWorld = MathUtils.geographicToCartesianCoord(lon, lat);
var result = this.isWorldVerticeVisibleInCanvas(verticeInWorld, options);
@@ -567,16 +535,12 @@ class Camera extends Object3D {
* 3.形成的NDC四边形是顺时针方向
*/
//获取level层级下的可见切片
- //options:projView
- getVisibleTilesByLevel(level: number, options?: any): TileGrid[] {
+ //options:
+ getVisibleTilesByLevel(level: number, options: any = {}): TileGrid[] {
if (!(level >= 0)) {
throw "invalid level";
}
var result: TileGrid[] = [];
- options = options || {};
- // if (!(options.projView instanceof Matrix)) {
- // options.projView = this.getProjViewMatrix();
- // }
//向左、向右、向上、向下最大的循环次数
var LOOP_LIMIT = Math.min(10, Math.pow(2, level) - 1);
@@ -684,8 +648,8 @@ class Camera extends Object3D {
return result;
}
- //options:projView
- private getTileVisibleInfo(level: number, row: number, column: number, options?: any): any {
+ //options: threshold
+ private getTileVisibleInfo(level: number, row: number, column: number, options: any = {}): any {
if (!(level >= 0)) {
throw "invalid level";
}
@@ -695,7 +659,7 @@ class Camera extends Object3D {
if (!(column >= 0)) {
throw "invalid column";
}
- options = options || {};
+
var threshold = typeof options.threshold == "number" ? Math.abs(options.threshold) : 1;
var result: any = {
lb: {
@@ -733,9 +697,7 @@ class Camera extends Object3D {
height: null,
area: null
};
- // if (!(options.projView instanceof Matrix)) {
- // options.projView = this.getProjViewMatrix();
- // }
+
result.Egeo = MathUtils.getTileGeographicEnvelopByGrid(level, row, column);
var tileMinLon = result.Egeo.minLon;
var tileMaxLon = result.Egeo.maxLon;
@@ -749,7 +711,6 @@ class Camera extends Object3D {
result.lb.verticeInNDC = this.convertVerticeFromWorldToNDC(result.lb.verticeInWorld);
result.lb.visible = this.isWorldVerticeVisibleInCanvas(result.lb.verticeInWorld, {
verticeInNDC: result.lb.verticeInNDC,
- projView: options.projView,
threshold: threshold
});
if (result.lb.visible) {
@@ -763,7 +724,6 @@ class Camera extends Object3D {
result.lt.verticeInNDC = this.convertVerticeFromWorldToNDC(result.lt.verticeInWorld);
result.lt.visible = this.isWorldVerticeVisibleInCanvas(result.lt.verticeInWorld, {
verticeInNDC: result.lt.verticeInNDC,
- projView: options.projView,
threshold: threshold
});
if (result.lt.visible) {
@@ -777,7 +737,6 @@ class Camera extends Object3D {
result.rt.verticeInNDC = this.convertVerticeFromWorldToNDC(result.rt.verticeInWorld);
result.rt.visible = this.isWorldVerticeVisibleInCanvas(result.rt.verticeInWorld, {
verticeInNDC: result.rt.verticeInNDC,
- projView: options.projView,
threshold: threshold
});
if (result.rt.visible) {
@@ -791,7 +750,6 @@ class Camera extends Object3D {
result.rb.verticeInNDC = this.convertVerticeFromWorldToNDC(result.rb.verticeInWorld);
result.rb.visible = this.isWorldVerticeVisibleInCanvas(result.rb.verticeInWorld, {
verticeInNDC: result.rb.verticeInNDC,
- projView: options.projView,
threshold: threshold
});
if (result.rb.visible) {
@@ -820,10 +778,6 @@ class Camera extends Object3D {
//地球一直是关于纵轴中心对称的,获取垂直方向上中心点信息
private _getVerticalVisibleCenterInfo(): any {
- // options = options || {};
- // if (!options.projView) {
- // options.projView = this.getProjViewMatrix();
- // }
var result = {
ndcY: null,
pIntersect: null,
From d8d7f6085899701718e3d7ec298fd67b53f4225a Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Sun, 27 Nov 2016 15:23:50 +0800
Subject: [PATCH 058/109] rename methods of Camera
---
src/world/Camera.ts | 134 ++++++++++++++++++++++----------------------
1 file changed, 68 insertions(+), 66 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index 1c7046b..22b1a47 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -373,54 +373,7 @@ class Camera extends Object3D {
this.look(position, targetPntCopy, upDirection);
}
- //点变换: World->NDC
- private convertVerticeFromWorldToNDC(verticeInWorld: Vertice): Vertice {
- var columnWorld = [verticeInWorld.x, verticeInWorld.y, verticeInWorld.z, 1];
- var columnProject = this.projViewMatrix.multiplyColumn(columnWorld);
- var w = columnProject[3];
- var columnNDC: number[] = [];
- columnNDC[0] = columnProject[0] / w;
- columnNDC[1] = columnProject[1] / w;
- columnNDC[2] = columnProject[2] / w;
- columnNDC[3] = 1;
- var verticeInNDC = new Vertice(columnNDC[0], columnNDC[1], columnNDC[2]);
- return verticeInNDC;
- }
- //点变换: NDC->World
- private convertVerticeFromNdcToWorld(verticeInNDC: Vertice): Vertice {
- var columnNDC: number[] = [verticeInNDC.x, verticeInNDC.y, verticeInNDC.z, 1]; //NDC归一化坐标
- var inverseProj = this.projMatrix.getInverseMatrix(); //投影矩阵的逆矩阵
- var columnCameraTemp = inverseProj.multiplyColumn(columnNDC); //带引号的“视坐标”
- var cameraX = columnCameraTemp[0] / columnCameraTemp[3];
- var cameraY = columnCameraTemp[1] / columnCameraTemp[3];
- var cameraZ = columnCameraTemp[2] / columnCameraTemp[3];
- var cameraW = 1;
- var columnCamera = [cameraX, cameraY, cameraZ, cameraW]; //真实的视坐标
- var columnWorld = this.matrix.multiplyColumn(columnCamera); //单击点的世界坐标
- var verticeInWorld = new Vertice(columnWorld[0], columnWorld[1], columnWorld[2]);
- return verticeInWorld;
- }
-
- //点变换: Camera->World
- private convertVerticeFromCameraToWorld(verticeInCamera: Vertice): Vertice {
- var verticeInCameraCopy = verticeInCamera.clone();
- var column = [verticeInCameraCopy.x, verticeInCameraCopy.y, verticeInCameraCopy.z, 1];
- var column2 = this.matrix.multiplyColumn(column);
- var verticeInWorld = new Vertice(column2[0], column2[1], column2[2]);
- return verticeInWorld;
- }
-
- //向量变换: Camera->World
- private convertVectorFromCameraToWorld(vectorInCamera: Vector): Vector {
- var vectorInCameraCopy = vectorInCamera.clone();
- var verticeInCamera = vectorInCameraCopy.getVertice();
- var verticeInWorld = this.convertVerticeFromCameraToWorld(verticeInCamera);
- var originInWorld = this.getPosition();
- var vectorInWorld = Vector.verticeMinusVertice(verticeInWorld, originInWorld);
- vectorInWorld.normalize();
- return vectorInWorld;
- }
//根据canvasX和canvasY获取拾取向量
getPickDirectionByCanvas(canvasX: number, canvasY: number): Vector {
@@ -441,7 +394,7 @@ class Camera extends Object3D {
//根据ndcX和ndcY获取拾取向量
getPickDirectionByNDC(ndcX: number, ndcY: number): Vector {
var verticeInNDC = new Vertice(ndcX, ndcY, 0.499);
- var verticeInWorld = this.convertVerticeFromNdcToWorld(verticeInNDC);
+ var verticeInWorld = this._convertVerticeFromNdcToWorld(verticeInNDC);
var cameraPositon = this.getPosition(); //摄像机的世界坐标
var pickDirection = Vector.verticeMinusVertice(verticeInWorld, cameraPositon);
pickDirection.normalize();
@@ -490,16 +443,65 @@ class Camera extends Object3D {
}
//得到摄像机的XOZ平面的方程
- private getPlanXOZ(): Plan {
+ private _getPlanXOZ(): Plan {
var position = this.getPosition();
var direction = this.getLightDirection();
var plan = MathUtils.getCrossPlaneByLine(position, direction);
return plan;
}
+ //点变换: World->NDC
+ private _convertVerticeFromWorldToNDC(verticeInWorld: Vertice): Vertice {
+ var columnWorld = [verticeInWorld.x, verticeInWorld.y, verticeInWorld.z, 1];
+ var columnProject = this.projViewMatrix.multiplyColumn(columnWorld);
+ var w = columnProject[3];
+ var columnNDC: number[] = [];
+ columnNDC[0] = columnProject[0] / w;
+ columnNDC[1] = columnProject[1] / w;
+ columnNDC[2] = columnProject[2] / w;
+ columnNDC[3] = 1;
+ var verticeInNDC = new Vertice(columnNDC[0], columnNDC[1], columnNDC[2]);
+ return verticeInNDC;
+ }
+
+ //点变换: NDC->World
+ private _convertVerticeFromNdcToWorld(verticeInNDC: Vertice): Vertice {
+ var columnNDC: number[] = [verticeInNDC.x, verticeInNDC.y, verticeInNDC.z, 1]; //NDC归一化坐标
+ var inverseProj = this.projMatrix.getInverseMatrix(); //投影矩阵的逆矩阵
+ var columnCameraTemp = inverseProj.multiplyColumn(columnNDC); //带引号的“视坐标”
+ var cameraX = columnCameraTemp[0] / columnCameraTemp[3];
+ var cameraY = columnCameraTemp[1] / columnCameraTemp[3];
+ var cameraZ = columnCameraTemp[2] / columnCameraTemp[3];
+ var cameraW = 1;
+ var columnCamera = [cameraX, cameraY, cameraZ, cameraW]; //真实的视坐标
+ var columnWorld = this.matrix.multiplyColumn(columnCamera); //单击点的世界坐标
+ var verticeInWorld = new Vertice(columnWorld[0], columnWorld[1], columnWorld[2]);
+ return verticeInWorld;
+ }
+
+ //点变换: Camera->World
+ private _convertVerticeFromCameraToWorld(verticeInCamera: Vertice): Vertice {
+ var verticeInCameraCopy = verticeInCamera.clone();
+ var column = [verticeInCameraCopy.x, verticeInCameraCopy.y, verticeInCameraCopy.z, 1];
+ var column2 = this.matrix.multiplyColumn(column);
+ var verticeInWorld = new Vertice(column2[0], column2[1], column2[2]);
+ return verticeInWorld;
+ }
+
+ //向量变换: Camera->World
+ private _convertVectorFromCameraToWorld(vectorInCamera: Vector): Vector {
+ var vectorInCameraCopy = vectorInCamera.clone();
+ var verticeInCamera = vectorInCameraCopy.getVertice();
+ var verticeInWorld = this._convertVerticeFromCameraToWorld(verticeInCamera);
+ var originInWorld = this.getPosition();
+ var vectorInWorld = Vector.verticeMinusVertice(verticeInWorld, originInWorld);
+ vectorInWorld.normalize();
+ return vectorInWorld;
+ }
+
//判断世界坐标系中的点是否在Canvas中可见
- //options: {verticeInNDC,threshold}
- private isWorldVerticeVisibleInCanvas(verticeInWorld: Vertice, options: any = {}): boolean {
+ //options: verticeInNDC,threshold
+ private _isWorldVerticeVisibleInCanvas(verticeInWorld: Vertice, options: any = {}): boolean {
var threshold = typeof options.threshold == "number" ? Math.abs(options.threshold) : 1;
var cameraP = this.getPosition();
var dir = Vector.verticeMinusVertice(verticeInWorld, cameraP);
@@ -511,7 +513,7 @@ class Camera extends Object3D {
var length2Pick = MathUtils.getLengthFromVerticeToVertice(cameraP, pickVertice);
if (length2Vertice < length2Pick + 5) {
if (!(options.verticeInNDC instanceof Vertice)) {
- options.verticeInNDC = this.convertVerticeFromWorldToNDC(verticeInWorld);
+ options.verticeInNDC = this._convertVerticeFromWorldToNDC(verticeInWorld);
}
var result = options.verticeInNDC.x >= -1 && options.verticeInNDC.x <= 1 && options.verticeInNDC.y >= -threshold && options.verticeInNDC.y <= 1;
return result;
@@ -522,9 +524,9 @@ class Camera extends Object3D {
//判断地球表面的某个经纬度在Canvas中是否应该可见
//options: verticeInNDC
- private isGeoVisibleInCanvas(lon: number, lat: number, options?: any): boolean {
+ private _isGeoVisibleInCanvas(lon: number, lat: number, options?: any): boolean {
var verticeInWorld = MathUtils.geographicToCartesianCoord(lon, lat);
- var result = this.isWorldVerticeVisibleInCanvas(verticeInWorld, options);
+ var result = this._isWorldVerticeVisibleInCanvas(verticeInWorld, options);
return result;
}
@@ -561,7 +563,7 @@ class Camera extends Object3D {
function handleRow(centerRow: number, centerColumn: number): TileGrid[] {
var result: TileGrid[] = [];
var grid = new TileGrid(level, centerRow, centerColumn); // {level:level,row:centerRow,column:centerColumn};
- var visibleInfo = this.getTileVisibleInfo(grid.level, grid.row, grid.column, options);
+ var visibleInfo = this._getTileVisibleInfo(grid.level, grid.row, grid.column, options);
var isRowCenterVisible = checkVisible(visibleInfo);
if (isRowCenterVisible) {
(grid as any).visibleInfo = visibleInfo;
@@ -575,7 +577,7 @@ class Camera extends Object3D {
leftLoopTime++;
grid = TileGrid.getTileGridByBrother(level, centerRow, leftColumn, MathUtils.LEFT, mathOptions);
leftColumn = grid.column;
- visibleInfo = this.getTileVisibleInfo(grid.level, grid.row, grid.column, options);
+ visibleInfo = this._getTileVisibleInfo(grid.level, grid.row, grid.column, options);
visible = checkVisible(visibleInfo);
if (visible) {
(grid).visibleInfo = visibleInfo;
@@ -592,7 +594,7 @@ class Camera extends Object3D {
rightLoopTime++;
grid = TileGrid.getTileGridByBrother(level, centerRow, rightColumn, MathUtils.RIGHT, mathOptions);
rightColumn = grid.column;
- visibleInfo = this.getTileVisibleInfo(grid.level, grid.row, grid.column, options);
+ visibleInfo = this._getTileVisibleInfo(grid.level, grid.row, grid.column, options);
visible = checkVisible(visibleInfo);
if (visible) {
(grid).visibleInfo = visibleInfo;
@@ -649,7 +651,7 @@ class Camera extends Object3D {
}
//options: threshold
- private getTileVisibleInfo(level: number, row: number, column: number, options: any = {}): any {
+ private _getTileVisibleInfo(level: number, row: number, column: number, options: any = {}): any {
if (!(level >= 0)) {
throw "invalid level";
}
@@ -708,8 +710,8 @@ class Camera extends Object3D {
result.lb.lon = tileMinLon;
result.lb.lat = tileMinLat;
result.lb.verticeInWorld = MathUtils.geographicToCartesianCoord(result.lb.lon, result.lb.lat);
- result.lb.verticeInNDC = this.convertVerticeFromWorldToNDC(result.lb.verticeInWorld);
- result.lb.visible = this.isWorldVerticeVisibleInCanvas(result.lb.verticeInWorld, {
+ result.lb.verticeInNDC = this._convertVerticeFromWorldToNDC(result.lb.verticeInWorld);
+ result.lb.visible = this._isWorldVerticeVisibleInCanvas(result.lb.verticeInWorld, {
verticeInNDC: result.lb.verticeInNDC,
threshold: threshold
});
@@ -721,8 +723,8 @@ class Camera extends Object3D {
result.lt.lon = tileMinLon;
result.lt.lat = tileMaxLat;
result.lt.verticeInWorld = MathUtils.geographicToCartesianCoord(result.lt.lon, result.lt.lat);
- result.lt.verticeInNDC = this.convertVerticeFromWorldToNDC(result.lt.verticeInWorld);
- result.lt.visible = this.isWorldVerticeVisibleInCanvas(result.lt.verticeInWorld, {
+ result.lt.verticeInNDC = this._convertVerticeFromWorldToNDC(result.lt.verticeInWorld);
+ result.lt.visible = this._isWorldVerticeVisibleInCanvas(result.lt.verticeInWorld, {
verticeInNDC: result.lt.verticeInNDC,
threshold: threshold
});
@@ -734,8 +736,8 @@ class Camera extends Object3D {
result.rt.lon = tileMaxLon;
result.rt.lat = tileMaxLat;
result.rt.verticeInWorld = MathUtils.geographicToCartesianCoord(result.rt.lon, result.rt.lat);
- result.rt.verticeInNDC = this.convertVerticeFromWorldToNDC(result.rt.verticeInWorld);
- result.rt.visible = this.isWorldVerticeVisibleInCanvas(result.rt.verticeInWorld, {
+ result.rt.verticeInNDC = this._convertVerticeFromWorldToNDC(result.rt.verticeInWorld);
+ result.rt.visible = this._isWorldVerticeVisibleInCanvas(result.rt.verticeInWorld, {
verticeInNDC: result.rt.verticeInNDC,
threshold: threshold
});
@@ -747,8 +749,8 @@ class Camera extends Object3D {
result.rb.lon = tileMaxLon;
result.rb.lat = tileMinLat;
result.rb.verticeInWorld = MathUtils.geographicToCartesianCoord(result.rb.lon, result.rb.lat);
- result.rb.verticeInNDC = this.convertVerticeFromWorldToNDC(result.rb.verticeInWorld);
- result.rb.visible = this.isWorldVerticeVisibleInCanvas(result.rb.verticeInWorld, {
+ result.rb.verticeInNDC = this._convertVerticeFromWorldToNDC(result.rb.verticeInWorld);
+ result.rb.visible = this._isWorldVerticeVisibleInCanvas(result.rb.verticeInWorld, {
verticeInNDC: result.rb.verticeInNDC,
threshold: threshold
});
From 98166252facab6f9e04d0da59287a6d86d1f4a52 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Sun, 27 Nov 2016 15:51:59 +0800
Subject: [PATCH 059/109] rename methods of Camera,#14
---
src/world/Camera.ts | 28 +++++++++++++---------------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index 22b1a47..50c4a67 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -317,7 +317,7 @@ class Camera extends Object3D {
}
var a = timestap - start;
if (a >= span) {
- (Object).assign(this, newCamera.toJson());
+ (Object).assign(this, newCamera._toJson());
this.animating = false;
cb();
} else {
@@ -331,11 +331,11 @@ class Camera extends Object3D {
private _clone(): Camera {
var camera: Camera = new Camera();
- (Object).assign(camera, this.toJson());
+ (Object).assign(camera, this._toJson());
return camera;
}
- toJson(): any {
+ private _toJson(): any {
return {
pitch: this.pitch,
near: this.near,
@@ -373,12 +373,10 @@ class Camera extends Object3D {
this.look(position, targetPntCopy, upDirection);
}
-
-
//根据canvasX和canvasY获取拾取向量
- getPickDirectionByCanvas(canvasX: number, canvasY: number): Vector {
+ private _getPickDirectionByCanvas(canvasX: number, canvasY: number): Vector {
var ndcXY = MathUtils.convertPointFromCanvasToNDC(canvasX, canvasY);
- var pickDirection = this.getPickDirectionByNDC(ndcXY[0], ndcXY[1]);
+ var pickDirection = this._getPickDirectionByNDC(ndcXY[0], ndcXY[1]);
return pickDirection;
}
@@ -392,7 +390,7 @@ class Camera extends Object3D {
}
//根据ndcX和ndcY获取拾取向量
- getPickDirectionByNDC(ndcX: number, ndcY: number): Vector {
+ private _getPickDirectionByNDC(ndcX: number, ndcY: number): Vector {
var verticeInNDC = new Vertice(ndcX, ndcY, 0.499);
var verticeInWorld = this._convertVerticeFromNdcToWorld(verticeInNDC);
var cameraPositon = this.getPosition(); //摄像机的世界坐标
@@ -401,7 +399,7 @@ class Camera extends Object3D {
return pickDirection;
}
- //获取直线与地球的交点,该方法与World.Math.getLineIntersectPointWithEarth功能基本一样,只不过该方法对相交点进行了远近排序
+ //获取直线与地球的交点,该方法与MathUtils.getLineIntersectPointWithEarth功能基本一样,只不过该方法对相交点进行了远近排序
getPickCartesianCoordInEarthByLine(line: Line): Vertice[] {
var result: Vertice[] = [];
//pickVertice是笛卡尔空间直角坐标系中的坐标
@@ -427,15 +425,15 @@ class Camera extends Object3D {
//计算拾取射线与地球的交点,以笛卡尔空间直角坐标系坐标数组的形式返回
getPickCartesianCoordInEarthByCanvas(canvasX: number, canvasY: number): Vertice[] {
- var pickDirection = this.getPickDirectionByCanvas(canvasX, canvasY);
+ var pickDirection = this._getPickDirectionByCanvas(canvasX, canvasY);
var p = this.getPosition();
var line = new Line(p, pickDirection);
var result = this.getPickCartesianCoordInEarthByLine(line);
return result;
}
- getPickCartesianCoordInEarthByNDC(ndcX: number, ndcY: number): Vertice[] {
- var pickDirection = this.getPickDirectionByNDC(ndcX, ndcY);
+ private _getPickCartesianCoordInEarthByNDC(ndcX: number, ndcY: number): Vertice[] {
+ var pickDirection = this._getPickDirectionByNDC(ndcX, ndcY);
var p = this.getPosition();
var line = new Line(p, pickDirection);
var result = this.getPickCartesianCoordInEarthByLine(line);
@@ -797,7 +795,7 @@ class Camera extends Object3D {
var ndcY: number;
//从上往下找topNdcY
for (ndcY = 1.0; ndcY >= -1.0; ndcY -= delta) {
- pickResults = this.getPickCartesianCoordInEarthByNDC(0, ndcY);
+ pickResults = this._getPickCartesianCoordInEarthByNDC(0, ndcY);
if (pickResults.length > 0) {
topNdcY = ndcY;
break;
@@ -806,7 +804,7 @@ class Camera extends Object3D {
//从下往上找
for (ndcY = -1.0; ndcY <= 1.0; ndcY += delta) {
- pickResults = this.getPickCartesianCoordInEarthByNDC(0, ndcY);
+ pickResults = this._getPickCartesianCoordInEarthByNDC(0, ndcY);
if (pickResults.length > 0) {
bottomNdcY = ndcY;
break;
@@ -814,7 +812,7 @@ class Camera extends Object3D {
}
result.ndcY = (topNdcY + bottomNdcY) / 2;
}
- pickResults = this.getPickCartesianCoordInEarthByNDC(0, result.ndcY);
+ pickResults = this._getPickCartesianCoordInEarthByNDC(0, result.ndcY);
result.pIntersect = pickResults[0];
var lonlat = MathUtils.cartesianCoordToGeographic(result.pIntersect);
result.lon = lonlat[0];
From b8de76cd0826c6fef7d621700b5347da09d142f8 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Sun, 27 Nov 2016 16:59:17 +0800
Subject: [PATCH 060/109] update,#14
---
src/world/Camera.ts | 131 ++++++++++++++++++++++++--------------------
src/world/Event.ts | 10 +++-
2 files changed, 80 insertions(+), 61 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index 50c4a67..f637821 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -80,71 +80,38 @@ class Camera extends Object3D {
//更新各种矩阵,保守起见,可以在每帧绘制之前调用
//理论上只在用户交互的时候调用就可以
update(): void {
- this.viewMatrix = null;
- //视点矩阵是camera的模型矩阵的逆矩阵
- //this.viewMatrix = this.matrix.getInverseMatrix();
-
- //通过修改position和fov以更新matrix和projMatrix
- this._updatePositionAndFov();
+ this._normalUpdate();
+ //this._updateProjViewMatrixForDraw();
+ }
- //在_updatePositionAndFov()方法调用之后再计算viewMatrix
+ _normalUpdate(){
+ //视点矩阵是camera的模型矩阵的逆矩阵
this.viewMatrix = this.matrix.getInverseMatrix();
- //最后更新far
+ //通过修改far值更新projMatrix
this._updateFar();
- //update projViewMatrix
+ //更新projViewMatrix
this.projViewMatrix = this.projMatrix.multiplyMatrix(this.viewMatrix);
}
- getPitch(): number{
- var lightDirection = this.getLightDirection();
-
- return this.pitch;
- }
-
- setPitch(pitch: number): void{
-
- }
-
- getLightDirection(): Vector {
- var dirVertice = this.matrix.getColumnZ();
- var direction = new Vector(-dirVertice.x, -dirVertice.y, -dirVertice.z);
- direction.normalize();
- return direction;
- }
-
- getDistance2EarthSurface(): number {
- var position = this.getPosition();
- var length2EarthSurface = Vector.fromVertice(position).getLength() - Kernel.EARTH_RADIUS;
- return length2EarthSurface;
- }
+ _updateProjViewMatrixForDraw(){
+ var matrix = this.matrix.clone();
+ var viewMatrix = this.viewMatrix.clone();
+ var projMatrix = this.projMatrix.clone();
+ var projViewMatrix = this.projViewMatrix.clone();
- getProjViewMatrixForDraw(): Matrix{
- return this.projViewMatrix;
- }
+ //通过修改position和fov以更新matrix和projMatrix
+ this._updatePositionAndFov();
- private _setFov(fov: number): void {
- if (!(fov > 0)) {
- throw "invalid fov:" + fov;
- }
- this._setPerspectiveMatrix(fov, this.aspect, this.near, this.far);
- }
+ //在_updatePositionAndFov()方法调用之后再计算viewMatrix
+ this.viewMatrix = this.matrix.getInverseMatrix();
- setAspect(aspect: number): void {
- if (!(aspect > 0)) {
- throw "invalid aspect:" + aspect;
- }
- this._setPerspectiveMatrix(this.fov, aspect, this.near, this.far);
- }
+ //最后更新far
+ this._updateFar();
- private _updateFar(): void {
- //重新计算far,保持far在满足正常需求情况下的最小值
- //far值:视点与地球切面的距离
- var length2EarthOrigin = Vector.fromVertice(this.getPosition()).getLength();
- var far = Math.sqrt(length2EarthOrigin * length2EarthOrigin - Kernel.EARTH_RADIUS * Kernel.EARTH_RADIUS);
- far *= 1.05;
- this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, far);
+ //update projViewMatrix
+ this.projViewMatrixForDraw = projMatrix.multiplyMatrix(viewMatrix);
}
//计算从第几级level开始不满足视景体的near值
@@ -166,14 +133,14 @@ class Camera extends Object3D {
}
//返回更新后的fov值,如果返回结果 < 0,说明无需更新fov
- private _updatePositionAndFov(): number {
+ private _updatePositionAndFov() {
//是否满足near值,和fov没有关系,和position有关
//但是改变position的话,fov也要相应变动以满足对应的缩放效果
const currentLevel = this.getLevel();
var safeLevel = this._getSafeThresholdLevelForNear();
- //_rawUpdatePositionByLevel()方法会修改this.matrix
- //_setFov()方法会修改this.projMatrix
+ //_rawUpdatePositionByLevel()方法会修改matrix
+ //_setFov()方法会修改projMatrix
if(currentLevel > safeLevel){
//摄像机距离地球太近,导致不满足视景体的near值,
@@ -189,8 +156,6 @@ class Camera extends Object3D {
this._rawUpdatePositionByLevel(currentLevel);
this._setFov(this.initFov);
}
-
- return -1;
}
//fov从oldFov变成了newFov,计算相当于缩放了几级level
@@ -280,6 +245,56 @@ class Camera extends Object3D {
return true;
}
+ getPitch(): number{
+ var lightDirection = this.getLightDirection();
+
+ return this.pitch;
+ }
+
+ setPitch(pitch: number): void{
+
+ }
+
+ getLightDirection(): Vector {
+ var dirVertice = this.matrix.getColumnZ();
+ var direction = new Vector(-dirVertice.x, -dirVertice.y, -dirVertice.z);
+ direction.normalize();
+ return direction;
+ }
+
+ getDistance2EarthSurface(): number {
+ var position = this.getPosition();
+ var length2EarthSurface = Vector.fromVertice(position).getLength() - Kernel.EARTH_RADIUS;
+ return length2EarthSurface;
+ }
+
+ getProjViewMatrixForDraw(): Matrix{
+ return this.projViewMatrix;
+ }
+
+ private _setFov(fov: number): void {
+ if (!(fov > 0)) {
+ throw "invalid fov:" + fov;
+ }
+ this._setPerspectiveMatrix(fov, this.aspect, this.near, this.far);
+ }
+
+ setAspect(aspect: number): void {
+ if (!(aspect > 0)) {
+ throw "invalid aspect:" + aspect;
+ }
+ this._setPerspectiveMatrix(this.fov, aspect, this.near, this.far);
+ }
+
+ private _updateFar(): void {
+ //重新计算far,保持far在满足正常需求情况下的最小值
+ //far值:视点与地球切面的距离
+ var length2EarthOrigin = Vector.fromVertice(this.getPosition()).getLength();
+ var far = Math.sqrt(length2EarthOrigin * length2EarthOrigin - Kernel.EARTH_RADIUS * Kernel.EARTH_RADIUS);
+ far *= 1.05;
+ this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, far);
+ }
+
isAnimating(): boolean {
return this.animating;
}
diff --git a/src/world/Event.ts b/src/world/Event.ts
index 19b0cbe..74c49c5 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -159,6 +159,10 @@ const EventModule = {
}
},
+ /**
+ * 通过向上和向下的键盘按键调整Camera视线方向的倾斜角度pitch
+ * 初始pitch值为0
+ */
onKeyDown(event: KeyboardEvent) {
var globe = Kernel.globe;
if (!globe) {
@@ -186,19 +190,19 @@ const EventModule = {
if (pickResult.length > 0) {
var pIntersect = pickResult[0];
var pCamera = camera.getPosition();
- var legnth2Intersect = MathUtils.getLengthFromVerticeToVertice(pCamera, pIntersect);
+ var distance2Intersect = MathUtils.getLengthFromVerticeToVertice(pCamera, pIntersect);
var mat = camera.cloneMatrix();
mat.setColumnTrans(pIntersect.x, pIntersect.y, pIntersect.z);
var DELTA_RADIAN = MathUtils.degreeToRadian(DELTA_PITCH);
mat.localRotateX(DELTA_RADIAN);
var dirZ = mat.getColumnZ();
- dirZ.setLength(legnth2Intersect);
+ dirZ.setLength(distance2Intersect);
var pNew = Vector.verticePlusVector(pIntersect, dirZ);
camera.look(pNew, pIntersect);
camera.setPitch(camera.getPitch() - DELTA_PITCH);
globe.refresh();
} else {
- alert("视线与地球无交点");
+ console.log("视线与地球无交点");
}
}
}
From 1fc49578069280efdffcd36076627c2618b53019 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Sun, 27 Nov 2016 17:18:29 +0800
Subject: [PATCH 061/109] add algorithm for pitch,#14
---
src/world/Event.ts | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/world/Event.ts b/src/world/Event.ts
index 74c49c5..54877c7 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -162,6 +162,15 @@ const EventModule = {
/**
* 通过向上和向下的键盘按键调整Camera视线方向的倾斜角度pitch
* 初始pitch值为0
+ * 当在A时刻要将pitch值从0变成一个非0值时,我们需要记录A时刻Camera的模型矩阵A.matrix和当时的级别A.level
+ * 然后经过多次修改pitch值以及多次缩放后到达B时刻,B时刻的pitch值为B.pitch,层级为B.level
+ * 即便摄像机视线没有指向真实地球的中心了,我们也会假象一个虚拟地球,让我们的经过pitch倾斜后的实现指向虚拟地球的中心以便套用公式计算缩放距离
+ * 我们这样确定在B时刻摄像机的matrix:
+ * 1. 我们计算的起点是A时刻Camera的初始状态(A.matrix和A.level)
+ * 2. 将A.matrix.localRotateX(B.pitch),这样就将摄像机旋转了,即确定了B时刻摄像机模型坐标系坐标轴的方向
+ * 3. 我们还需要确定B时刻摄像机的位置,按照标准公式计算在A.level层级下,Camera距离地球表面的距离应该是A.distance2Surface
+ * 相应的,按照标准公式计算在B.level层级下,Camera距离地球表面的距离应该是B.distance2Surface
+ * 那么我们将A.matrix.getPosition()沿着B.matrix.getLightDirection()视线往前移动(B.distance2Surface - A.distance2Surface)的距离即可
*/
onKeyDown(event: KeyboardEvent) {
var globe = Kernel.globe;
From 97d058f94f7228c182b71704b82522ad95dc753f Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Sun, 27 Nov 2016 18:36:03 +0800
Subject: [PATCH 062/109] update camera.setPitch() and setLevel()method, but
not work as expected,#14
---
src/world/Camera.ts | 75 +++++++++++++++++++++++++++++++++++----------
src/world/Event.ts | 38 ++++-------------------
2 files changed, 64 insertions(+), 49 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index f637821..b0acd9e 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -15,12 +15,19 @@ class Camera extends Object3D {
private readonly animationDuration: number = 600;//层级变化的动画周期是600毫秒
private readonly nearFactor: number = 0.6;
private readonly baseTheoryDistanceFromCamera2EarthSurface = 1.23 * Kernel.EARTH_RADIUS;
- private pitch: number;
+ private readonly maxPitch = 54;
+
private level: number = -1; //当前渲染等级
+
+ private pitch: number;//Camera视线的倾斜角度,初始值为0,表示视线经过球心,单位为角度。正值表示抬头,赋值表示低头。
+ private pitchStartMatrix: Matrix;//从0开始倾斜视线时刻的模型矩阵,如果pitch=0,那么pitchStartMatrix为null值。
+ private pitchStartLevel: number = -1;//从0开始倾斜视线时刻的level,如果pitch=0,那么pitchStartLevel为负值。
+
private viewMatrix: Matrix;//视点矩阵,即Camera模型矩阵的逆矩阵
private projMatrix: Matrix;//当Matrix变化的时候,需要重新计算this.far
private projViewMatrix: Matrix;//获取投影矩阵与视点矩阵的乘积
private projViewMatrixForDraw: Matrix;//实际传递给shader的矩阵是projViewMatrixForDraw,而不是projViewMatrix
+
private animating: boolean = false;
Enum: any = {
@@ -35,7 +42,7 @@ class Camera extends Object3D {
constructor(private fov = 45, private aspect = 1, private near = 1, private far = 100) {
super();
this.initFov = this.fov;
- this.pitch = 90;
+ this.pitch = 0;
this.projMatrix = new Matrix();
this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, this.far);
}
@@ -228,31 +235,65 @@ class Camera extends Object3D {
var newPosition = vector.getVertice();
this.look(newPosition, origin);
} else {
- var length = this._getTheoryDistanceFromCamera2EarthSurface(level) + Kernel.EARTH_RADIUS; //level等级下摄像机应该到球心的距离
- var vector = this.getLightDirection().getOpposite();
- vector.setLength(length);
- var newPosition = vector.getVertice();
- this.setPosition(newPosition.x, newPosition.y, newPosition.z);
-
- // var distance2SurfaceNow = this._getTheoryDistanceFromCamera2EarthSurface(this.getLevel());
- // var distance2SurfaceNew = this._getTheoryDistanceFromCamera2EarthSurface(level);
- // var deltaDistance = distance2SurfaceNow - distance2SurfaceNew;
- // var dir = this.getLightDirection();
- // dir.setLength(deltaDistance);
- // var pNew = Vector.verticePlusVector(pOld, dir);
- // this.setPosition(pNew.x, pNew.y, pNew.z);
+ // if(this.pitch === 0){
+ // var length = this._getTheoryDistanceFromCamera2EarthSurface(level) + Kernel.EARTH_RADIUS; //level等级下摄像机应该到球心的距离
+ // var vector = this.getLightDirection().getOpposite().setLength(length);
+ // var newPosition = vector.getVertice();
+ // this.setPosition(newPosition.x, newPosition.y, newPosition.z);
+ // }else{
+ // }
+ var distance2SurfaceOld = this._getTheoryDistanceFromCamera2EarthSurface(this.getLevel());
+ var distance2SurfaceNew = this._getTheoryDistanceFromCamera2EarthSurface(level);
+ var deltaDistance = distance2SurfaceOld - distance2SurfaceNew;
+ var dir = this.getLightDirection().setLength(deltaDistance);
+ var pNew = Vector.verticePlusVector(pOld, dir);
+ this.setPosition(pNew.x, pNew.y, pNew.z);
}
return true;
}
getPitch(): number{
- var lightDirection = this.getLightDirection();
-
return this.pitch;
}
setPitch(pitch: number): void{
+ if(this.pitch === pitch || pitch >= this.maxPitch){
+ return;
+ }
+
+ if(pitch < 0){
+ pitch = 0;
+ }
+
+ if(this.pitch === 0){
+ //没有倾斜=>倾斜
+ this.pitchStartMatrix = this.matrix.clone();
+ this.pitchStartLevel = this.level;
+ }
+
+ //处理旋转角度
+ this.pitch = pitch;
+ var radian = MathUtils.degreeToRadian(this.pitch);
+ var newMatrix = this.pitchStartMatrix.clone();
+ newMatrix.localRotateX(radian);
+
+ //处理level
+ var distance2SurfaceLevel1 = this._getTheoryDistanceFromCamera2EarthSurface(this.pitchStartLevel);
+ var distance2SurfaceLevel2 = this._getTheoryDistanceFromCamera2EarthSurface(this.level);
+ var deltaDistance = distance2SurfaceLevel2 - distance2SurfaceLevel1;
+ var lightDirection = newMatrix.getColumnZ().getOpposite().setLength(deltaDistance);
+ var newPosition = Vector.verticePlusVector(newMatrix.getColumnTrans(), lightDirection);
+ newMatrix.setColumnTrans(newPosition.x, newPosition.y, newPosition.z);
+
+ //如果当前的pitch为0,重置pitchStartMatrix和pitchStartLevel
+ if(this.pitch === 0){
+ this.pitchStartMatrix = null;
+ this.pitchStartLevel = -1;
+ }
+ //更新this.matrix
+ this.matrix = newMatrix;
+ Kernel.globe.refresh();
}
getLightDirection(): Vector {
diff --git a/src/world/Event.ts b/src/world/Event.ts
index 54877c7..29fc3bb 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -178,44 +178,18 @@ const EventModule = {
return;
}
- var MIN_PITCH = 36;
var DELTA_PITCH = 2;
var camera = globe.camera;
var keyNum = event.keyCode !== undefined ? event.keyCode : event.which;
//上、下、左、右:38、40、37、39
- if (keyNum == 38 || keyNum == 40) {
- if (keyNum == 38) {
- if (camera.getPitch() <= MIN_PITCH) {
- return;
- }
- } else if (keyNum == 40) {
- if (camera.getPitch() >= 90) {
- return;
- }
- DELTA_PITCH *= -1;
- }
-
- var pickResult = camera.getDirectionIntersectPointWithEarth();
- if (pickResult.length > 0) {
- var pIntersect = pickResult[0];
- var pCamera = camera.getPosition();
- var distance2Intersect = MathUtils.getLengthFromVerticeToVertice(pCamera, pIntersect);
- var mat = camera.cloneMatrix();
- mat.setColumnTrans(pIntersect.x, pIntersect.y, pIntersect.z);
- var DELTA_RADIAN = MathUtils.degreeToRadian(DELTA_PITCH);
- mat.localRotateX(DELTA_RADIAN);
- var dirZ = mat.getColumnZ();
- dirZ.setLength(distance2Intersect);
- var pNew = Vector.verticePlusVector(pIntersect, dirZ);
- camera.look(pNew, pIntersect);
- camera.setPitch(camera.getPitch() - DELTA_PITCH);
- globe.refresh();
- } else {
- console.log("视线与地球无交点");
- }
+ if(keyNum === 38){
+ //向上键
+ camera.setPitch(camera.getPitch() + DELTA_PITCH);
+ }else if(keyNum === 40){
+ //向下键
+ camera.setPitch(camera.getPitch() - DELTA_PITCH);
}
}
-
};
export = EventModule;
\ No newline at end of file
From 451248a69ddc8afb1b182ca4908aabc4152aa834 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Mon, 28 Nov 2016 00:40:43 +0800
Subject: [PATCH 063/109] update setDeltaPitch,getPitch and setLevel,#14
---
src/world/Camera.ts | 140 ++++++++++++++++++++++++++++----------------
src/world/Event.ts | 4 +-
2 files changed, 91 insertions(+), 53 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index b0acd9e..4941e49 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -19,9 +19,9 @@ class Camera extends Object3D {
private level: number = -1; //当前渲染等级
- private pitch: number;//Camera视线的倾斜角度,初始值为0,表示视线经过球心,单位为角度。正值表示抬头,赋值表示低头。
- private pitchStartMatrix: Matrix;//从0开始倾斜视线时刻的模型矩阵,如果pitch=0,那么pitchStartMatrix为null值。
- private pitchStartLevel: number = -1;//从0开始倾斜视线时刻的level,如果pitch=0,那么pitchStartLevel为负值。
+ private isPitchZero: boolean = true;//表示当前Camera视线有没有发生倾斜
+ //private pitchStartMatrix: Matrix;//从0开始倾斜视线时刻的模型矩阵,如果pitch=0,那么pitchStartMatrix为null值。
+ //private pitchStartLevel: number = -1;//从0开始倾斜视线时刻的level,如果pitch=0,那么pitchStartLevel为负值。
private viewMatrix: Matrix;//视点矩阵,即Camera模型矩阵的逆矩阵
private projMatrix: Matrix;//当Matrix变化的时候,需要重新计算this.far
@@ -42,7 +42,6 @@ class Camera extends Object3D {
constructor(private fov = 45, private aspect = 1, private near = 1, private far = 100) {
super();
this.initFov = this.fov;
- this.pitch = 0;
this.projMatrix = new Matrix();
this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, this.far);
}
@@ -91,7 +90,7 @@ class Camera extends Object3D {
//this._updateProjViewMatrixForDraw();
}
- _normalUpdate(){
+ _normalUpdate() {
//视点矩阵是camera的模型矩阵的逆矩阵
this.viewMatrix = this.matrix.getInverseMatrix();
@@ -102,7 +101,7 @@ class Camera extends Object3D {
this.projViewMatrix = this.projMatrix.multiplyMatrix(this.viewMatrix);
}
- _updateProjViewMatrixForDraw(){
+ _updateProjViewMatrixForDraw() {
var matrix = this.matrix.clone();
var viewMatrix = this.viewMatrix.clone();
var projMatrix = this.projMatrix.clone();
@@ -149,7 +148,7 @@ class Camera extends Object3D {
//_rawUpdatePositionByLevel()方法会修改matrix
//_setFov()方法会修改projMatrix
- if(currentLevel > safeLevel){
+ if (currentLevel > safeLevel) {
//摄像机距离地球太近,导致不满足视景体的near值,
//我们需要将摄像机的位置拉远,以满足near值
this._rawUpdatePositionByLevel(safeLevel);
@@ -159,7 +158,7 @@ class Camera extends Object3D {
//deltaLevel应该为正正数,计算出的newFov应该比this.initFov要小
var newFov = this._calculateFovByDeltaLevel(this.initFov, deltaLevel);
this._setFov(newFov);
- }else{
+ } else {
this._rawUpdatePositionByLevel(currentLevel);
this._setFov(this.initFov);
}
@@ -242,60 +241,100 @@ class Camera extends Object3D {
// this.setPosition(newPosition.x, newPosition.y, newPosition.z);
// }else{
// }
- var distance2SurfaceOld = this._getTheoryDistanceFromCamera2EarthSurface(this.getLevel());
- var distance2SurfaceNew = this._getTheoryDistanceFromCamera2EarthSurface(level);
- var deltaDistance = distance2SurfaceOld - distance2SurfaceNew;
- var dir = this.getLightDirection().setLength(deltaDistance);
- var pNew = Vector.verticePlusVector(pOld, dir);
- this.setPosition(pNew.x, pNew.y, pNew.z);
+ //无论Camera视线倾斜多少,永远保持视线与地球的交叉点到摄像机的距离满足公式
+ // var distance2Intersect = this._getTheoryDistanceFromCamera2EarthSurface(level);
+ // var distance2SurfaceOld = this._getTheoryDistanceFromCamera2EarthSurface(this.getLevel());
+ // var distance2SurfaceNew = this._getTheoryDistanceFromCamera2EarthSurface(level);
+ // var deltaDistance = distance2SurfaceOld - distance2SurfaceNew;
+ // var dir = this.getLightDirection().setLength(deltaDistance);
+ // var pNew = Vector.verticePlusVector(pOld, dir);
+ // this.setPosition(pNew.x, pNew.y, pNew.z);
+ var matrix = this.matrix.clone();
+ var hasIntersect = this._calculateNewCameraPositionByLevel(matrix, level);
+ if (hasIntersect) {
+ this.matrix = matrix;
+ } else {
+ throw "_rawUpdatePositionByLevel: light direction doesn't have intersects with earth";
+ }
}
return true;
}
- getPitch(): number{
- return this.pitch;
+ _calculateNewCameraPositionByLevel(matrix: Matrix, level: number): boolean {
+ //matrix表示已经调整了pitch后的摄像机模型矩阵,要根据level计算matrix的position
+ var direction = matrix.getColumnZ().getOpposite();
+ var currentCameraPosition = matrix.getPosition();
+ var line = new Line(currentCameraPosition, direction);
+ var intersects = this.getPickCartesianCoordInEarthByLine(line);
+ //我们要保证经过这次旋转之后,视线会与地球有交点
+ if (intersects.length < 2) {
+ return false;
+ }
+ var intersect = intersects[0];
+ var camera2Intersect = MathUtils.getLengthFromVerticeToVertice(currentCameraPosition, intersect);
+ var theoryDistance2Interscet = this._getTheoryDistanceFromCamera2EarthSurface(this.level);
+ var deltaVectorFromIntersect2NewPosition = matrix.getColumnZ().normalize().setLength(theoryDistance2Interscet);
+ var newCameraPosition = Vector.verticePlusVector(intersect, deltaVectorFromIntersect2NewPosition);
+ matrix.setColumnTrans(newCameraPosition.x, newCameraPosition.y, newCameraPosition.z);
+ return true;
}
- setPitch(pitch: number): void{
- if(this.pitch === pitch || pitch >= this.maxPitch){
+ setDeltaPitch(deltaPitch: number) {
+ var currentPitch = this.getPitch();
+ var newPitch = currentPitch + deltaPitch;
+ if (newPitch > this.maxPitch) {
return;
}
-
- if(pitch < 0){
- pitch = 0;
- }
-
- if(this.pitch === 0){
- //没有倾斜=>倾斜
- this.pitchStartMatrix = this.matrix.clone();
- this.pitchStartLevel = this.level;
+ if (newPitch < 0) {
+ newPitch = 0;
}
-
- //处理旋转角度
- this.pitch = pitch;
- var radian = MathUtils.degreeToRadian(this.pitch);
- var newMatrix = this.pitchStartMatrix.clone();
- newMatrix.localRotateX(radian);
-
- //处理level
- var distance2SurfaceLevel1 = this._getTheoryDistanceFromCamera2EarthSurface(this.pitchStartLevel);
- var distance2SurfaceLevel2 = this._getTheoryDistanceFromCamera2EarthSurface(this.level);
- var deltaDistance = distance2SurfaceLevel2 - distance2SurfaceLevel1;
- var lightDirection = newMatrix.getColumnZ().getOpposite().setLength(deltaDistance);
- var newPosition = Vector.verticePlusVector(newMatrix.getColumnTrans(), lightDirection);
- newMatrix.setColumnTrans(newPosition.x, newPosition.y, newPosition.z);
-
- //如果当前的pitch为0,重置pitchStartMatrix和pitchStartLevel
- if(this.pitch === 0){
- this.pitchStartMatrix = null;
- this.pitchStartLevel = -1;
+ //我们要保证经过这次旋转之后,视线会与地球有交点
+ // var distance2Origin = Vector.fromVertice(this.getPosition()).getLength();
+ // var sinv = Kernel.EARTH_RADIUS / distance2Origin;
+ // var maxPitch = MathUtils.radianToDegree(Math.asin(sinv));
+ // if(newPitch > maxPitch){
+ // return;
+ // }
+
+ //计算最终的deltaPitch
+ deltaPitch = newPitch - currentPitch;
+ var deltaRadian = MathUtils.degreeToRadian(deltaPitch);
+ //先不对this.matrix进行更新,对其拷贝进行更新
+ var matrix = this.matrix.clone();
+ matrix.localRotateX(deltaRadian);
+ var hasIntersect = this._calculateNewCameraPositionByLevel(matrix, this.level);
+ if (!hasIntersect) {
+ //我们要保证经过这次旋转之后,视线会与地球有交点
+ return;
}
- //更新this.matrix
- this.matrix = newMatrix;
+ //刷新
+ this.isPitchZero = newPitch === 0;
+ this.matrix = matrix;
Kernel.globe.refresh();
}
+ //pitch表示Camera视线的倾斜角度,初始值为0,表示视线经过球心,单位为角度,范围是[0, this.maxPitch]
+ getPitch(): number {
+ //计算夹角
+ var lightDirection = this.getLightDirection();
+ var vectorFromCmeraToEarthOrigin = Vector.fromVertice(this.getPosition()).getOpposite().normalize();
+ var cosθ = lightDirection.dot(vectorFromCmeraToEarthOrigin);
+ var radian = Math.acos(cosθ);
+
+ //计算夹角的正负
+ var crossVector = vectorFromCmeraToEarthOrigin.cross(lightDirection).normalize();
+ var zAxisDirection = this.matrix.getColumnZ().normalize();
+ if (crossVector.dot(zAxisDirection) > 0) {
+ //正值
+ radian = Math.abs(radian);
+ } else {
+ //负值
+ radian = - Math.abs(radian);
+ }
+ return MathUtils.radianToDegree(radian);
+ }
+
getLightDirection(): Vector {
var dirVertice = this.matrix.getColumnZ();
var direction = new Vector(-dirVertice.x, -dirVertice.y, -dirVertice.z);
@@ -309,7 +348,7 @@ class Camera extends Object3D {
return length2EarthSurface;
}
- getProjViewMatrixForDraw(): Matrix{
+ getProjViewMatrixForDraw(): Matrix {
return this.projViewMatrix;
}
@@ -393,7 +432,6 @@ class Camera extends Object3D {
private _toJson(): any {
return {
- pitch: this.pitch,
near: this.near,
far: this.far,
fov: this.fov,
@@ -841,7 +879,7 @@ class Camera extends Object3D {
lat: null
};
var pickResults: Vertice[];
- if (this.pitch == 90) {
+ if (this.isPitchZero) {
result.ndcY = 0;
} else {
var count = 10;
diff --git a/src/world/Event.ts b/src/world/Event.ts
index 29fc3bb..8d7b36c 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -184,10 +184,10 @@ const EventModule = {
//上、下、左、右:38、40、37、39
if(keyNum === 38){
//向上键
- camera.setPitch(camera.getPitch() + DELTA_PITCH);
+ camera.setDeltaPitch(DELTA_PITCH);
}else if(keyNum === 40){
//向下键
- camera.setPitch(camera.getPitch() - DELTA_PITCH);
+ camera.setDeltaPitch(DELTA_PITCH);
}
}
};
From a085f090120ed03da88d183db471ff6ba57859c6 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Mon, 28 Nov 2016 12:54:17 +0800
Subject: [PATCH 064/109] fix bug of
camera._calculateNewCameraPositionByLevel() method,#14
---
src/world/Camera.ts | 2 +-
src/world/Event.ts | 9 ---------
2 files changed, 1 insertion(+), 10 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index 4941e49..29d09ad 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -272,7 +272,7 @@ class Camera extends Object3D {
}
var intersect = intersects[0];
var camera2Intersect = MathUtils.getLengthFromVerticeToVertice(currentCameraPosition, intersect);
- var theoryDistance2Interscet = this._getTheoryDistanceFromCamera2EarthSurface(this.level);
+ var theoryDistance2Interscet = this._getTheoryDistanceFromCamera2EarthSurface(level);
var deltaVectorFromIntersect2NewPosition = matrix.getColumnZ().normalize().setLength(theoryDistance2Interscet);
var newCameraPosition = Vector.verticePlusVector(intersect, deltaVectorFromIntersect2NewPosition);
matrix.setColumnTrans(newCameraPosition.x, newCameraPosition.y, newCameraPosition.z);
diff --git a/src/world/Event.ts b/src/world/Event.ts
index 8d7b36c..f7e47ad 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -162,15 +162,6 @@ const EventModule = {
/**
* 通过向上和向下的键盘按键调整Camera视线方向的倾斜角度pitch
* 初始pitch值为0
- * 当在A时刻要将pitch值从0变成一个非0值时,我们需要记录A时刻Camera的模型矩阵A.matrix和当时的级别A.level
- * 然后经过多次修改pitch值以及多次缩放后到达B时刻,B时刻的pitch值为B.pitch,层级为B.level
- * 即便摄像机视线没有指向真实地球的中心了,我们也会假象一个虚拟地球,让我们的经过pitch倾斜后的实现指向虚拟地球的中心以便套用公式计算缩放距离
- * 我们这样确定在B时刻摄像机的matrix:
- * 1. 我们计算的起点是A时刻Camera的初始状态(A.matrix和A.level)
- * 2. 将A.matrix.localRotateX(B.pitch),这样就将摄像机旋转了,即确定了B时刻摄像机模型坐标系坐标轴的方向
- * 3. 我们还需要确定B时刻摄像机的位置,按照标准公式计算在A.level层级下,Camera距离地球表面的距离应该是A.distance2Surface
- * 相应的,按照标准公式计算在B.level层级下,Camera距离地球表面的距离应该是B.distance2Surface
- * 那么我们将A.matrix.getPosition()沿着B.matrix.getLightDirection()视线往前移动(B.distance2Surface - A.distance2Surface)的距离即可
*/
onKeyDown(event: KeyboardEvent) {
var globe = Kernel.globe;
From 55f4999177297a6336ac26ae3f8a12a8bc982ba6 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Mon, 28 Nov 2016 17:54:46 +0800
Subject: [PATCH 065/109] update refactor,#14
---
src/world/Camera.ts | 50 ++++++++++++++++-----------------
src/world/Event.ts | 2 +-
src/world/VertexBufferObject.ts | 12 ++++----
src/world/math/Math.ts | 14 +++++++++
4 files changed, 47 insertions(+), 31 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index 29d09ad..3204c47 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -226,7 +226,7 @@ class Camera extends Object3D {
var globe = Kernel.globe;
var pOld = this.getPosition();
if (pOld.x === 0 && pOld.y === 0 && pOld.z === 0) {
- //初始设置camera
+ //init camera
var length = this._getTheoryDistanceFromCamera2EarthSurface(level) + Kernel.EARTH_RADIUS; //level等级下摄像机应该到球心的距离
var origin = new Vertice(0, 0, 0);
var vector = this.getLightDirection().getOpposite();
@@ -234,27 +234,24 @@ class Camera extends Object3D {
var newPosition = vector.getVertice();
this.look(newPosition, origin);
} else {
- // if(this.pitch === 0){
- // var length = this._getTheoryDistanceFromCamera2EarthSurface(level) + Kernel.EARTH_RADIUS; //level等级下摄像机应该到球心的距离
- // var vector = this.getLightDirection().getOpposite().setLength(length);
- // var newPosition = vector.getVertice();
- // this.setPosition(newPosition.x, newPosition.y, newPosition.z);
- // }else{
- // }
- //无论Camera视线倾斜多少,永远保持视线与地球的交叉点到摄像机的距离满足公式
- // var distance2Intersect = this._getTheoryDistanceFromCamera2EarthSurface(level);
- // var distance2SurfaceOld = this._getTheoryDistanceFromCamera2EarthSurface(this.getLevel());
- // var distance2SurfaceNew = this._getTheoryDistanceFromCamera2EarthSurface(level);
- // var deltaDistance = distance2SurfaceOld - distance2SurfaceNew;
- // var dir = this.getLightDirection().setLength(deltaDistance);
- // var pNew = Vector.verticePlusVector(pOld, dir);
- // this.setPosition(pNew.x, pNew.y, pNew.z);
- var matrix = this.matrix.clone();
- var hasIntersect = this._calculateNewCameraPositionByLevel(matrix, level);
- if (hasIntersect) {
- this.matrix = matrix;
- } else {
- throw "_rawUpdatePositionByLevel: light direction doesn't have intersects with earth";
+ var currentPosition = this.getPosition();
+ if(this.isPitchZero){
+ var length = this._getTheoryDistanceFromCamera2EarthSurface(level) + Kernel.EARTH_RADIUS;
+ var vector = this.getLightDirection().getOpposite().setLength(length);
+ var newPosition = vector.getVertice();
+ this.setPosition(newPosition.x, newPosition.y, newPosition.z);
+ }else{
+ var intersects = this.getDirectionIntersectPointWithEarth();
+ if(intersects.length === 0){
+ throw "no intersect";
+ }
+ var intersect = intersects[0];
+ var distance2Intersect = MathUtils.getLengthFromVerticeToVertice(currentPosition, intersect);
+ var deltaLevel = level - this.level;
+ var newDistance2Intersect = distance2Intersect / Math.pow(2, deltaLevel);
+ var deltaDistance = distance2Intersect - newDistance2Intersect;
+ var deltaVector = this.getLightDirection().setLength(deltaDistance);
+ var newPosition = Vector.verticePlusVector(currentPosition, deltaVector);
}
}
return true;
@@ -298,6 +295,9 @@ class Camera extends Object3D {
//计算最终的deltaPitch
deltaPitch = newPitch - currentPitch;
+ if(deltaPitch === 0){
+ return;
+ }
var deltaRadian = MathUtils.degreeToRadian(deltaPitch);
//先不对this.matrix进行更新,对其拷贝进行更新
var matrix = this.matrix.clone();
@@ -320,12 +320,12 @@ class Camera extends Object3D {
var lightDirection = this.getLightDirection();
var vectorFromCmeraToEarthOrigin = Vector.fromVertice(this.getPosition()).getOpposite().normalize();
var cosθ = lightDirection.dot(vectorFromCmeraToEarthOrigin);
- var radian = Math.acos(cosθ);
+ var radian = MathUtils.acosSafely(cosθ);
//计算夹角的正负
var crossVector = vectorFromCmeraToEarthOrigin.cross(lightDirection).normalize();
- var zAxisDirection = this.matrix.getColumnZ().normalize();
- if (crossVector.dot(zAxisDirection) > 0) {
+ var xAxisDirection = this.matrix.getColumnX().normalize();
+ if (crossVector.dot(xAxisDirection) > 0) {
//正值
radian = Math.abs(radian);
} else {
diff --git a/src/world/Event.ts b/src/world/Event.ts
index f7e47ad..eaf3b49 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -178,7 +178,7 @@ const EventModule = {
camera.setDeltaPitch(DELTA_PITCH);
}else if(keyNum === 40){
//向下键
- camera.setDeltaPitch(DELTA_PITCH);
+ camera.setDeltaPitch(-DELTA_PITCH);
}
}
};
diff --git a/src/world/VertexBufferObject.ts b/src/world/VertexBufferObject.ts
index 49e9155..be2006b 100644
--- a/src/world/VertexBufferObject.ts
+++ b/src/world/VertexBufferObject.ts
@@ -22,15 +22,17 @@ class VertexBufferObject{
this.bind();
}
- if(this.target === Kernel.gl.ARRAY_BUFFER){
- Kernel.gl.bufferData(Kernel.gl.ARRAY_BUFFER, new Float32Array(data), usage);
- }else if(this.target === Kernel.gl.ELEMENT_ARRAY_BUFFER){
- Kernel.gl.bufferData(Kernel.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(data), usage);
+ var gl = Kernel.gl;
+
+ if(this.target === gl.ARRAY_BUFFER){
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), usage);
+ }else if(this.target === gl.ELEMENT_ARRAY_BUFFER){
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(data), usage);
}
}
destroy(){
- if(Kernel.gl.isBuffer(this.buffer)){
+ if(this.buffer){
Kernel.gl.deleteBuffer(this.buffer);
}
this.buffer = null;
diff --git a/src/world/math/Math.ts b/src/world/math/Math.ts
index e72b5f5..34bed55 100644
--- a/src/world/math/Math.ts
+++ b/src/world/math/Math.ts
@@ -29,6 +29,20 @@ const MathUtils = {
return ( value & ( value - 1 ) ) === 0 && value !== 0;
},
+ asinSafely(value: number){
+ if(value > 1){
+ value = 1;
+ }
+ return Math.asin(value);
+ },
+
+ acosSafely(value: number){
+ if(value > 1){
+ value = 1;
+ }
+ return Math.acos(value);
+ },
+
/**
* 将其他进制的数字转换为10进制
* @param numSys 要准换的进制
From c8e0abe23619ea342982c36516f214fe5742df1f Mon Sep 17 00:00:00 2001
From: iSpring
Date: Mon, 28 Nov 2016 22:13:24 +0800
Subject: [PATCH 066/109] update getPitch() method of Camera,#14
---
src/world/Camera.ts | 42 ++++++++++++++++++++++--------------------
1 file changed, 22 insertions(+), 20 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index 3204c47..e4ff990 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -19,9 +19,9 @@ class Camera extends Object3D {
private level: number = -1; //当前渲染等级
- private isPitchZero: boolean = true;//表示当前Camera视线有没有发生倾斜
- //private pitchStartMatrix: Matrix;//从0开始倾斜视线时刻的模型矩阵,如果pitch=0,那么pitchStartMatrix为null值。
- //private pitchStartLevel: number = -1;//从0开始倾斜视线时刻的level,如果pitch=0,那么pitchStartLevel为负值。
+ //旋转的时候,绕着视线与地球交点进行旋转
+ //定义抬头时,旋转角为正值
+ private isZeroPitch: boolean = true;//表示当前Camera视线有没有发生倾斜
private viewMatrix: Matrix;//视点矩阵,即Camera模型矩阵的逆矩阵
private projMatrix: Matrix;//当Matrix变化的时候,需要重新计算this.far
@@ -235,7 +235,7 @@ class Camera extends Object3D {
this.look(newPosition, origin);
} else {
var currentPosition = this.getPosition();
- if(this.isPitchZero){
+ if(this.isZeroPitch){
var length = this._getTheoryDistanceFromCamera2EarthSurface(level) + Kernel.EARTH_RADIUS;
var vector = this.getLightDirection().getOpposite().setLength(length);
var newPosition = vector.getVertice();
@@ -285,13 +285,6 @@ class Camera extends Object3D {
if (newPitch < 0) {
newPitch = 0;
}
- //我们要保证经过这次旋转之后,视线会与地球有交点
- // var distance2Origin = Vector.fromVertice(this.getPosition()).getLength();
- // var sinv = Kernel.EARTH_RADIUS / distance2Origin;
- // var maxPitch = MathUtils.radianToDegree(Math.asin(sinv));
- // if(newPitch > maxPitch){
- // return;
- // }
//计算最终的deltaPitch
deltaPitch = newPitch - currentPitch;
@@ -309,29 +302,38 @@ class Camera extends Object3D {
}
//刷新
- this.isPitchZero = newPitch === 0;
+ this.isZeroPitch = newPitch === 0;
this.matrix = matrix;
Kernel.globe.refresh();
}
//pitch表示Camera视线的倾斜角度,初始值为0,表示视线经过球心,单位为角度,范围是[0, this.maxPitch]
getPitch(): number {
+ var intersects = this.getDirectionIntersectPointWithEarth();
+ if(intersects.length === 0){
+ throw "no intersects";
+ }
+ var intersect = intersects[0];
+
//计算夹角
- var lightDirection = this.getLightDirection();
- var vectorFromCmeraToEarthOrigin = Vector.fromVertice(this.getPosition()).getOpposite().normalize();
- var cosθ = lightDirection.dot(vectorFromCmeraToEarthOrigin);
+ var vectorOrigin2Intersect = Vector.fromVertice(intersect);
+ var length1 = vectorOrigin2Intersect.getLength();
+ var vectorIntersect2Camera = Vector.verticeMinusVertice(this.getPosition(), intersect);
+ var length2 = vectorIntersect2Camera.getLength();
+ var cosθ = vectorOrigin2Intersect.dot(vectorIntersect2Camera) / (length1 * length2);
var radian = MathUtils.acosSafely(cosθ);
//计算夹角的正负
- var crossVector = vectorFromCmeraToEarthOrigin.cross(lightDirection).normalize();
- var xAxisDirection = this.matrix.getColumnX().normalize();
- if (crossVector.dot(xAxisDirection) > 0) {
+ var crossVector = vectorOrigin2Intersect.cross(vectorIntersect2Camera);
+ var xAxisDirection = this.matrix.getColumnX()
+ if(crossVector.dot(xAxisDirection)){
//正值
radian = Math.abs(radian);
- } else {
+ }else{
//负值
radian = - Math.abs(radian);
}
+
return MathUtils.radianToDegree(radian);
}
@@ -879,7 +881,7 @@ class Camera extends Object3D {
lat: null
};
var pickResults: Vertice[];
- if (this.isPitchZero) {
+ if (this.isZeroPitch) {
result.ndcY = 0;
} else {
var count = 10;
From f58b7c90457205c59c8f9b6d58ff13f65edf01a6 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Tue, 29 Nov 2016 12:15:22 +0800
Subject: [PATCH 067/109] update Camera,#14
---
src/world/Camera.ts | 182 ++++++++++++++++++++------------------------
src/world/Globe.ts | 2 -
2 files changed, 83 insertions(+), 101 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index e4ff990..983479a 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -44,6 +44,7 @@ class Camera extends Object3D {
this.initFov = this.fov;
this.projMatrix = new Matrix();
this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, this.far);
+ this._initCameraPosition();
}
private _setPerspectiveMatrix(fov: number = 45, aspect: number = 1, near: number = 1, far: number = 100): void {
@@ -103,15 +104,15 @@ class Camera extends Object3D {
_updateProjViewMatrixForDraw() {
var matrix = this.matrix.clone();
- var viewMatrix = this.viewMatrix.clone();
+ // var viewMatrix = this.viewMatrix.clone();
var projMatrix = this.projMatrix.clone();
- var projViewMatrix = this.projViewMatrix.clone();
+ // var projViewMatrix = this.projViewMatrix.clone();
//通过修改position和fov以更新matrix和projMatrix
- this._updatePositionAndFov();
+ this._updatePositionAndFov(matrix, projMatrix);
//在_updatePositionAndFov()方法调用之后再计算viewMatrix
- this.viewMatrix = this.matrix.getInverseMatrix();
+ var viewMatrix = matrix.getInverseMatrix();
//最后更新far
this._updateFar();
@@ -120,26 +121,8 @@ class Camera extends Object3D {
this.projViewMatrixForDraw = projMatrix.multiplyMatrix(viewMatrix);
}
- //计算从第几级level开始不满足视景体的near值
- //比如第10级满足near,第11级不满足near,那么返回10
- private _getSafeThresholdLevelForNear() {
- var thresholdNear = this.near * this.nearFactor;
- var pow2level = this.baseTheoryDistanceFromCamera2EarthSurface / thresholdNear;
- var level = (Math).log2(pow2level);
- return Math.floor(level);
- }
-
- /**
- * 根据层级计算出摄像机应该放置到距离地球表面多远的位置
- * @param level
- * @return {*}
- */
- private _getTheoryDistanceFromCamera2EarthSurface(level: number): number {
- return this.baseTheoryDistanceFromCamera2EarthSurface / Math.pow(2, level);
- }
-
//返回更新后的fov值,如果返回结果 < 0,说明无需更新fov
- private _updatePositionAndFov() {
+ private _updatePositionAndFov(cameraMatrix: Matrix, projMatrix: Matrix) {
//是否满足near值,和fov没有关系,和position有关
//但是改变position的话,fov也要相应变动以满足对应的缩放效果
const currentLevel = this.getLevel();
@@ -151,7 +134,7 @@ class Camera extends Object3D {
if (currentLevel > safeLevel) {
//摄像机距离地球太近,导致不满足视景体的near值,
//我们需要将摄像机的位置拉远,以满足near值
- this._rawUpdatePositionByLevel(safeLevel);
+ this._updatePositionByLevel(safeLevel, cameraMatrix);
//比如safeLevel是10,而currentLevel是11,则deltaLevel为1
var deltaLevel = currentLevel - safeLevel;
//摄像机位置与地球表面距离变大之后,我们看到的地球变小,为此,我们需要把fov值变小,以抵消摄像机位置距离增大导致的变化
@@ -159,11 +142,29 @@ class Camera extends Object3D {
var newFov = this._calculateFovByDeltaLevel(this.initFov, deltaLevel);
this._setFov(newFov);
} else {
- this._rawUpdatePositionByLevel(currentLevel);
+ this._updatePositionByLevel(currentLevel, cameraMatrix);
this._setFov(this.initFov);
}
}
+ //计算从第几级level开始不满足视景体的near值
+ //比如第10级满足near,第11级不满足near,那么返回10
+ private _getSafeThresholdLevelForNear() {
+ var thresholdNear = this.near * this.nearFactor;
+ var pow2level = this.baseTheoryDistanceFromCamera2EarthSurface / thresholdNear;
+ var level = (Math).log2(pow2level);
+ return Math.floor(level);
+ }
+
+ /**
+ * 根据层级计算出摄像机应该放置到距离地球表面多远的位置
+ * @param level
+ * @return {*}
+ */
+ private _getTheoryDistanceFromCamera2EarthSurface(level: number): number {
+ return this.baseTheoryDistanceFromCamera2EarthSurface / Math.pow(2, level);
+ }
+
//fov从oldFov变成了newFov,计算相当于缩放了几级level
//比如从10级缩放到了第11级,fov从30变成了15,即oldFov为30,newFov为15,deltaLevel为1
//通过Math.log2()计算出结果,所以返回的是小数,可能是正数也可能是负数
@@ -206,74 +207,42 @@ class Camera extends Object3D {
}
setLevel(level: number): void {
- var isLevelChanged = this._rawUpdatePositionByLevel(level);
- if (isLevelChanged) {
- //不要在this._setLevel()方法中更新this.level,因为这会影响animateToLevel()方法
- this.level = level;
- Kernel.globe.refresh();
- }
- }
-
- //设置观察到的层级,不要在该方法中修改this.level的值
- private _rawUpdatePositionByLevel(level: number): boolean {
if (!(Utils.isNonNegativeInteger(level))) {
throw "invalid level:" + level;
}
level = level > Kernel.MAX_LEVEL ? Kernel.MAX_LEVEL : level; //超过最大的渲染级别就不渲染
if (level === this.level) {
- return false;
- }
- var globe = Kernel.globe;
- var pOld = this.getPosition();
- if (pOld.x === 0 && pOld.y === 0 && pOld.z === 0) {
- //init camera
- var length = this._getTheoryDistanceFromCamera2EarthSurface(level) + Kernel.EARTH_RADIUS; //level等级下摄像机应该到球心的距离
- var origin = new Vertice(0, 0, 0);
- var vector = this.getLightDirection().getOpposite();
- vector.setLength(length);
- var newPosition = vector.getVertice();
- this.look(newPosition, origin);
- } else {
- var currentPosition = this.getPosition();
- if(this.isZeroPitch){
- var length = this._getTheoryDistanceFromCamera2EarthSurface(level) + Kernel.EARTH_RADIUS;
- var vector = this.getLightDirection().getOpposite().setLength(length);
- var newPosition = vector.getVertice();
- this.setPosition(newPosition.x, newPosition.y, newPosition.z);
- }else{
- var intersects = this.getDirectionIntersectPointWithEarth();
- if(intersects.length === 0){
- throw "no intersect";
- }
- var intersect = intersects[0];
- var distance2Intersect = MathUtils.getLengthFromVerticeToVertice(currentPosition, intersect);
- var deltaLevel = level - this.level;
- var newDistance2Intersect = distance2Intersect / Math.pow(2, deltaLevel);
- var deltaDistance = distance2Intersect - newDistance2Intersect;
- var deltaVector = this.getLightDirection().setLength(deltaDistance);
- var newPosition = Vector.verticePlusVector(currentPosition, deltaVector);
- }
+ return;
}
- return true;
+ var isLevelChanged = this._updatePositionByLevel(level, this.matrix);
+ //不要在this._setLevel()方法中更新this.level,因为这会影响animateToLevel()方法
+ this.level = level;
+ Kernel.globe.refresh();
}
- _calculateNewCameraPositionByLevel(matrix: Matrix, level: number): boolean {
- //matrix表示已经调整了pitch后的摄像机模型矩阵,要根据level计算matrix的position
- var direction = matrix.getColumnZ().getOpposite();
- var currentCameraPosition = matrix.getPosition();
- var line = new Line(currentCameraPosition, direction);
- var intersects = this.getPickCartesianCoordInEarthByLine(line);
- //我们要保证经过这次旋转之后,视线会与地球有交点
- if (intersects.length < 2) {
- return false;
+ private _initCameraPosition() {
+ var initLevel = 0;
+ var length = this._getTheoryDistanceFromCamera2EarthSurface(initLevel) + Kernel.EARTH_RADIUS; //level等级下摄像机应该到球心的距离
+ var origin = new Vertice(0, 0, 0);
+ var vector = this.getLightDirection().getOpposite();
+ vector.setLength(length);
+ var newPosition = vector.getVertice();
+ this._look(newPosition, origin);
+ }
+
+ //设置观察到的层级,不要在该方法中修改this.level的值
+ private _updatePositionByLevel(level: number, cameraMatrix: Matrix) {
+ var globe = Kernel.globe;
+ var intersects = this._getDirectionIntersectPointWithEarth(cameraMatrix);
+ if (intersects.length === 0) {
+ throw "no intersect";
}
- var intersect = intersects[0];
- var camera2Intersect = MathUtils.getLengthFromVerticeToVertice(currentCameraPosition, intersect);
+ var intersect = intersects[0];
var theoryDistance2Interscet = this._getTheoryDistanceFromCamera2EarthSurface(level);
- var deltaVectorFromIntersect2NewPosition = matrix.getColumnZ().normalize().setLength(theoryDistance2Interscet);
- var newCameraPosition = Vector.verticePlusVector(intersect, deltaVectorFromIntersect2NewPosition);
- matrix.setColumnTrans(newCameraPosition.x, newCameraPosition.y, newCameraPosition.z);
- return true;
+ var vector = cameraMatrix.getColumnZ();
+ vector.setLength(theoryDistance2Interscet);
+ var newCameraPosition = Vector.verticePlusVector(intersect, vector);
+ cameraMatrix.setColumnTrans(newCameraPosition.x, newCameraPosition.y, newCameraPosition.z);
}
setDeltaPitch(deltaPitch: number) {
@@ -288,18 +257,25 @@ class Camera extends Object3D {
//计算最终的deltaPitch
deltaPitch = newPitch - currentPitch;
- if(deltaPitch === 0){
+ if (deltaPitch === 0) {
return;
}
+
+ var intersects = this.getDirectionIntersectPointWithEarth();
+ if (intersects.length === 0) {
+ throw "no intersects";
+ }
+ var intersect = intersects[0];
+
var deltaRadian = MathUtils.degreeToRadian(deltaPitch);
//先不对this.matrix进行更新,对其拷贝进行更新
var matrix = this.matrix.clone();
+ //将matrix移动到交点位置
+ matrix.setColumnTrans(intersect.x, intersect.y, intersect.z);
+ //旋转
matrix.localRotateX(deltaRadian);
- var hasIntersect = this._calculateNewCameraPositionByLevel(matrix, this.level);
- if (!hasIntersect) {
- //我们要保证经过这次旋转之后,视线会与地球有交点
- return;
- }
+ //更新matrix的position
+ this._updatePositionByLevel(this.level, matrix);
//刷新
this.isZeroPitch = newPitch === 0;
@@ -309,8 +285,11 @@ class Camera extends Object3D {
//pitch表示Camera视线的倾斜角度,初始值为0,表示视线经过球心,单位为角度,范围是[0, this.maxPitch]
getPitch(): number {
+ if (this.isZeroPitch) {
+ return 0;
+ }
var intersects = this.getDirectionIntersectPointWithEarth();
- if(intersects.length === 0){
+ if (intersects.length === 0) {
throw "no intersects";
}
var intersect = intersects[0];
@@ -326,10 +305,10 @@ class Camera extends Object3D {
//计算夹角的正负
var crossVector = vectorOrigin2Intersect.cross(vectorIntersect2Camera);
var xAxisDirection = this.matrix.getColumnX()
- if(crossVector.dot(xAxisDirection)){
+ if (crossVector.dot(xAxisDirection)) {
//正值
radian = Math.abs(radian);
- }else{
+ } else {
//负值
radian = - Math.abs(radian);
}
@@ -387,7 +366,7 @@ class Camera extends Object3D {
}
var newCamera = this._clone();
//don't call setLevel method because it will update CURRENT_LEVEL
- newCamera._rawUpdatePositionByLevel(level);
+ // newCamera._updatePositionByLevel(level);
this._animateToCamera(newCamera, () => {
this.level = level;
@@ -443,7 +422,7 @@ class Camera extends Object3D {
};
}
- look(cameraPnt: Vertice, targetPnt: Vertice, upDirection: Vector = new Vector(0, 1, 0)): void {
+ private _look(cameraPnt: Vertice, targetPnt: Vertice, upDirection: Vector = new Vector(0, 1, 0)): void {
var cameraPntCopy = cameraPnt.clone();
var targetPntCopy = targetPnt.clone();
var up = upDirection.clone();
@@ -466,7 +445,7 @@ class Camera extends Object3D {
private _lookAt(targetPnt: Vertice, upDirection?: Vector): void {
var targetPntCopy = targetPnt.clone();
var position = this.getPosition();
- this.look(position, targetPntCopy, upDirection);
+ this._look(position, targetPntCopy, upDirection);
}
//根据canvasX和canvasY获取拾取向量
@@ -476,15 +455,20 @@ class Camera extends Object3D {
return pickDirection;
}
- //获取当前视线与地球的交点
- getDirectionIntersectPointWithEarth(): Vertice[] {
- var dir = this.getLightDirection();
- var p = this.getPosition();
+ private _getDirectionIntersectPointWithEarth(cameraMatrix: Matrix): Vertice[]{
+ var dir = cameraMatrix.getColumnZ().getOpposite();
+ var p = cameraMatrix.getPosition();
var line = new Line(p, dir);
var result = this.getPickCartesianCoordInEarthByLine(line);
return result;
}
+ //获取当前视线与地球的交点
+ getDirectionIntersectPointWithEarth(): Vertice[] {
+ var result = this._getDirectionIntersectPointWithEarth(this.matrix);
+ return result;
+ }
+
//根据ndcX和ndcY获取拾取向量
private _getPickDirectionByNDC(ndcX: number, ndcY: number): Vector {
var verticeInNDC = new Vertice(ndcX, ndcY, 0.499);
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index e83aad8..5d73811 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -140,9 +140,7 @@ class Globe {
this.camera.update();
var level = this.getLevel() + 3;
this.tiledLayer.updateSubLayerCount(level);
- //var projView = this.camera.getProjViewMatrix();
var options = {
- //projView: projView,
threshold: 1
};
options.threshold = Math.min(90 / this.camera.getPitch(), 1.5);
From c1eea4b0a685f2e2f3b04a7a84449196b8a27183 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Tue, 29 Nov 2016 13:15:31 +0800
Subject: [PATCH 068/109] update projViewMatrixForDraw and use it to draw
graphics, basically solve the depth issue,#14
---
src/world/Camera.ts | 125 ++++++++++++++++++++++++--------------------
1 file changed, 67 insertions(+), 58 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index 983479a..f3bb2b9 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -15,7 +15,7 @@ class Camera extends Object3D {
private readonly animationDuration: number = 600;//层级变化的动画周期是600毫秒
private readonly nearFactor: number = 0.6;
private readonly baseTheoryDistanceFromCamera2EarthSurface = 1.23 * Kernel.EARTH_RADIUS;
- private readonly maxPitch = 54;
+ private readonly maxPitch = 40;
private level: number = -1; //当前渲染等级
@@ -52,31 +52,34 @@ class Camera extends Object3D {
this._updateFar();
}
- private _rawSetPerspectiveMatrix(fov: number = 45, aspect: number = 1, near: number = 1, far: number = 100): void {
+ private _rawSetPerspectiveMatrix(fov: number = 45, aspect: number = 1, near: number = 1, far: number = 100, projMatrix: Matrix = this.projMatrix): void {
//https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/mat4.js#L1788
- this.fov = fov;
- this.aspect = aspect;
- this.near = near;
- this.far = far;
+ if(this.projMatrix === projMatrix){
+ this.fov = fov;
+ this.aspect = aspect;
+ this.near = near;
+ this.far = far;
+ }
+
var mat = [
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
];
- var halfFov = this.fov * Math.PI / 180 / 2;
+ var halfFov = fov * Math.PI / 180 / 2;
var f = 1 / Math.tan(halfFov);
- var nf = 1 / (this.near - this.far);
+ var nf = 1 / (near - far);
- mat[0] = f / this.aspect;
+ mat[0] = f / aspect;
mat[5] = f;
- mat[10] = (this.far + this.near) * nf;
+ mat[10] = (far + near) * nf;
mat[11] = -1;
- mat[14] = 2 * this.near * this.far * nf;
+ mat[14] = 2 * near * far * nf;
mat[15] = 0;
//by comparision with matrixProjection.exe and glMatrix, the 11th element is always -1
- this.projMatrix.setElements(
+ projMatrix.setElements(
mat[0], mat[1], mat[2], mat[3],
mat[4], mat[5], mat[6], mat[7],
mat[8], mat[9], mat[10], mat[11],
@@ -84,11 +87,43 @@ class Camera extends Object3D {
);
}
+ private _setFov(fov: number): void {
+ if (!(fov > 0)) {
+ throw "invalid fov:" + fov;
+ }
+ this._setPerspectiveMatrix(fov, this.aspect, this.near, this.far);
+ }
+
+ setAspect(aspect: number): void {
+ if (!(aspect > 0)) {
+ throw "invalid aspect:" + aspect;
+ }
+ this._setPerspectiveMatrix(this.fov, aspect, this.near, this.far);
+ }
+
+ private _updateFar(): void {
+ var far = this._getMinimalFar(this.matrix.getPosition());
+ this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, far);
+ }
+
+ private _getMinimalFar(cameraPosition: Vertice): number{
+ //重新计算far,保持far在满足正常需求情况下的最小值
+ //far值:视点与地球切面的距离
+ var distance2EarthOrigin = Vector.fromVertice(cameraPosition).getLength();
+ var far = Math.sqrt(distance2EarthOrigin * distance2EarthOrigin - Kernel.EARTH_RADIUS * Kernel.EARTH_RADIUS);
+ far *= 1.05;
+ return far;
+ }
+
//更新各种矩阵,保守起见,可以在每帧绘制之前调用
//理论上只在用户交互的时候调用就可以
update(): void {
this._normalUpdate();
- //this._updateProjViewMatrixForDraw();
+ this._updateProjViewMatrixForDraw();
+ }
+
+ getProjViewMatrixForDraw(): Matrix {
+ return this.projViewMatrixForDraw;
}
_normalUpdate() {
@@ -103,34 +138,35 @@ class Camera extends Object3D {
}
_updateProjViewMatrixForDraw() {
- var matrix = this.matrix.clone();
- // var viewMatrix = this.viewMatrix.clone();
- var projMatrix = this.projMatrix.clone();
- // var projViewMatrix = this.projViewMatrix.clone();
+ var newMatrix = this.matrix.clone();
- //通过修改position和fov以更新matrix和projMatrix
- this._updatePositionAndFov(matrix, projMatrix);
+ //通过修改position以更新matrix
+ var newFov = this._updatePositionAndFov(newMatrix);
+ var aspect = this.aspect;
+ var near = this.near;
- //在_updatePositionAndFov()方法调用之后再计算viewMatrix
- var viewMatrix = matrix.getInverseMatrix();
+ //计算newFar
+ var newPosition = newMatrix.getPosition();
+ var newFar = this._getMinimalFar(newPosition);
- //最后更新far
- this._updateFar();
+ //根据newFov和newFar重新计算
+ var newProjMatrix = new Matrix();
+ this._rawSetPerspectiveMatrix(newFov, aspect, near, newFar, newProjMatrix);
+
+ //在_updatePositionAndFov()方法调用之后再计算newViewMatrix
+ var newViewMatrix = newMatrix.getInverseMatrix();
- //update projViewMatrix
- this.projViewMatrixForDraw = projMatrix.multiplyMatrix(viewMatrix);
+ //最后计算projViewMatrixForDraw
+ this.projViewMatrixForDraw = newProjMatrix.multiplyMatrix(newViewMatrix);
}
//返回更新后的fov值,如果返回结果 < 0,说明无需更新fov
- private _updatePositionAndFov(cameraMatrix: Matrix, projMatrix: Matrix) {
+ private _updatePositionAndFov(cameraMatrix: Matrix): number {
//是否满足near值,和fov没有关系,和position有关
//但是改变position的话,fov也要相应变动以满足对应的缩放效果
const currentLevel = this.getLevel();
var safeLevel = this._getSafeThresholdLevelForNear();
- //_rawUpdatePositionByLevel()方法会修改matrix
- //_setFov()方法会修改projMatrix
-
if (currentLevel > safeLevel) {
//摄像机距离地球太近,导致不满足视景体的near值,
//我们需要将摄像机的位置拉远,以满足near值
@@ -140,10 +176,10 @@ class Camera extends Object3D {
//摄像机位置与地球表面距离变大之后,我们看到的地球变小,为此,我们需要把fov值变小,以抵消摄像机位置距离增大导致的变化
//deltaLevel应该为正正数,计算出的newFov应该比this.initFov要小
var newFov = this._calculateFovByDeltaLevel(this.initFov, deltaLevel);
- this._setFov(newFov);
+ return newFov;
} else {
this._updatePositionByLevel(currentLevel, cameraMatrix);
- this._setFov(this.initFov);
+ return this.initFov;
}
}
@@ -329,33 +365,6 @@ class Camera extends Object3D {
return length2EarthSurface;
}
- getProjViewMatrixForDraw(): Matrix {
- return this.projViewMatrix;
- }
-
- private _setFov(fov: number): void {
- if (!(fov > 0)) {
- throw "invalid fov:" + fov;
- }
- this._setPerspectiveMatrix(fov, this.aspect, this.near, this.far);
- }
-
- setAspect(aspect: number): void {
- if (!(aspect > 0)) {
- throw "invalid aspect:" + aspect;
- }
- this._setPerspectiveMatrix(this.fov, aspect, this.near, this.far);
- }
-
- private _updateFar(): void {
- //重新计算far,保持far在满足正常需求情况下的最小值
- //far值:视点与地球切面的距离
- var length2EarthOrigin = Vector.fromVertice(this.getPosition()).getLength();
- var far = Math.sqrt(length2EarthOrigin * length2EarthOrigin - Kernel.EARTH_RADIUS * Kernel.EARTH_RADIUS);
- far *= 1.05;
- this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, far);
- }
-
isAnimating(): boolean {
return this.animating;
}
From 97387e9d0cbb43bc1a07248aeee04a0fe5a6c005 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Tue, 29 Nov 2016 18:29:40 +0800
Subject: [PATCH 069/109] don't udpate far because it can zoom out the extent a
little,#14
---
src/world/Camera.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index f3bb2b9..0f69bdf 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -102,8 +102,8 @@ class Camera extends Object3D {
}
private _updateFar(): void {
- var far = this._getMinimalFar(this.matrix.getPosition());
- this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, far);
+ // var far = this._getMinimalFar(this.matrix.getPosition());
+ // this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, far);
}
private _getMinimalFar(cameraPosition: Vertice): number{
@@ -147,7 +147,7 @@ class Camera extends Object3D {
//计算newFar
var newPosition = newMatrix.getPosition();
- var newFar = this._getMinimalFar(newPosition);
+ var newFar = this.far; //this._getMinimalFar(newPosition);
//根据newFov和newFar重新计算
var newProjMatrix = new Matrix();
From fb104cb54ba9da76251ca9103262d9181826720c Mon Sep 17 00:00:00 2001
From: iSpring
Date: Tue, 29 Nov 2016 19:22:11 +0800
Subject: [PATCH 070/109] make Camera.getPickCartesinanCoordInEarthByCanvas()
work with no error by using projViewMatrixForDraw instead of
projViewMatrix,#14
---
main.js | 6 ++--
src/world/Camera.ts | 78 +++++++++++++++++++++++++++++----------------
src/world/Event.ts | 2 +-
src/world/Kernel.ts | 2 +-
4 files changed, 56 insertions(+), 32 deletions(-)
diff --git a/main.js b/main.js
index 62e9a21..075db09 100644
--- a/main.js
+++ b/main.js
@@ -1,10 +1,12 @@
window.onload = function() {
- require(["world/Globe", "world/layers/BingTiledLayer", "world/layers/NokiaTiledLayer", "world/layers/OsmTiledLayer",
+ require(["world/Kernel", "world/Globe", "world/layers/BingTiledLayer", "world/layers/NokiaTiledLayer", "world/layers/OsmTiledLayer",
"world/layers/SosoTiledLayer", "world/layers/TiandituTiledLayer", "world/layers/GoogleTiledLayer",
"world/layers/PoiLayer"],
- function(Globe, BingTiledLayer, NokiaTiledLayer, OsmTiledLayer, SosoTiledLayer, TiandituTiledLayer, GoogleTiledLayer,
+ function(Kernel, Globe, BingTiledLayer, NokiaTiledLayer, OsmTiledLayer, SosoTiledLayer, TiandituTiledLayer, GoogleTiledLayer,
PoiLayer) {
+ window.Kernel = Kernel;
+
function startWebGL() {
var canvas = document.getElementById("canvasId");
window.globe = new Globe(canvas);
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index 0f69bdf..cb4bb85 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -26,6 +26,10 @@ class Camera extends Object3D {
private viewMatrix: Matrix;//视点矩阵,即Camera模型矩阵的逆矩阵
private projMatrix: Matrix;//当Matrix变化的时候,需要重新计算this.far
private projViewMatrix: Matrix;//获取投影矩阵与视点矩阵的乘积
+
+ private matrixForDraw: Matrix;
+ private viewMatrixForDraw: Matrix;
+ private projMatrixForDraw: Matrix;
private projViewMatrixForDraw: Matrix;//实际传递给shader的矩阵是projViewMatrixForDraw,而不是projViewMatrix
private animating: boolean = false;
@@ -138,26 +142,26 @@ class Camera extends Object3D {
}
_updateProjViewMatrixForDraw() {
- var newMatrix = this.matrix.clone();
+ this.matrixForDraw = this.matrix.clone();
//通过修改position以更新matrix
- var newFov = this._updatePositionAndFov(newMatrix);
+ var newFov = this._updatePositionAndFov(this.matrixForDraw);
var aspect = this.aspect;
var near = this.near;
//计算newFar
- var newPosition = newMatrix.getPosition();
+ var newPosition = this.matrixForDraw.getPosition();
var newFar = this.far; //this._getMinimalFar(newPosition);
//根据newFov和newFar重新计算
- var newProjMatrix = new Matrix();
- this._rawSetPerspectiveMatrix(newFov, aspect, near, newFar, newProjMatrix);
+ this.projMatrixForDraw = new Matrix();
+ this._rawSetPerspectiveMatrix(newFov, aspect, near, newFar, this.projMatrixForDraw);
//在_updatePositionAndFov()方法调用之后再计算newViewMatrix
- var newViewMatrix = newMatrix.getInverseMatrix();
+ this.viewMatrixForDraw = this.matrixForDraw.getInverseMatrix();
//最后计算projViewMatrixForDraw
- this.projViewMatrixForDraw = newProjMatrix.multiplyMatrix(newViewMatrix);
+ this.projViewMatrixForDraw = this.projMatrixForDraw.multiplyMatrix(this.viewMatrixForDraw);
}
//返回更新后的fov值,如果返回结果 < 0,说明无需更新fov
@@ -297,7 +301,7 @@ class Camera extends Object3D {
return;
}
- var intersects = this.getDirectionIntersectPointWithEarth();
+ var intersects = this._getDirectionIntersectPointWithEarth(this.matrix);
if (intersects.length === 0) {
throw "no intersects";
}
@@ -324,7 +328,7 @@ class Camera extends Object3D {
if (this.isZeroPitch) {
return 0;
}
- var intersects = this.getDirectionIntersectPointWithEarth();
+ var intersects = this._getDirectionIntersectPointWithEarth(this.matrix);
if (intersects.length === 0) {
throw "no intersects";
}
@@ -352,6 +356,38 @@ class Camera extends Object3D {
return MathUtils.radianToDegree(radian);
}
+ //计算拾取射线与地球的交点,以笛卡尔空间直角坐标系坐标数组的形式返回
+ //该方法需要projViewMatrixForDraw系列矩阵进行计算
+ getPickCartesianCoordInEarthByCanvas(canvasX: number, canvasY: number): Vertice[] {
+ this.update();
+
+ //暂存projViewMatrix系列矩阵
+ var matrix = this.matrix;
+ var viewMatrix = this.viewMatrix;
+ var projMatrix = this.projMatrix;
+ var projViewMatrix = this.projViewMatrix;
+
+ //将projViewMatrix系列矩阵赋值为projViewMatrixForDraw系列矩阵
+ this.matrix = this.matrixForDraw;
+ this.viewMatrix = this.viewMatrixForDraw;
+ this.projMatrix = this.projMatrixForDraw;
+ this.projViewMatrix = this.projViewMatrixForDraw;
+
+ //基于projViewMatrixForDraw系列矩阵进行计算,应该没有误差
+ var pickDirection = this._getPickDirectionByCanvas(canvasX, canvasY);
+ var p = this.getPosition();
+ var line = new Line(p, pickDirection);
+ var result = this._getPickCartesianCoordInEarthByLine(line);
+
+ //还原projViewMatrix系列矩阵
+ this.matrix = matrix;
+ this.viewMatrix = viewMatrix;
+ this.projMatrix = projMatrix;
+ this.projViewMatrix = projViewMatrix;
+
+ return result;
+ }
+
getLightDirection(): Vector {
var dirVertice = this.matrix.getColumnZ();
var direction = new Vector(-dirVertice.x, -dirVertice.y, -dirVertice.z);
@@ -464,17 +500,12 @@ class Camera extends Object3D {
return pickDirection;
}
+ //获取cameraMatrix视线与地球的交点
private _getDirectionIntersectPointWithEarth(cameraMatrix: Matrix): Vertice[]{
var dir = cameraMatrix.getColumnZ().getOpposite();
var p = cameraMatrix.getPosition();
var line = new Line(p, dir);
- var result = this.getPickCartesianCoordInEarthByLine(line);
- return result;
- }
-
- //获取当前视线与地球的交点
- getDirectionIntersectPointWithEarth(): Vertice[] {
- var result = this._getDirectionIntersectPointWithEarth(this.matrix);
+ var result = this._getPickCartesianCoordInEarthByLine(line);
return result;
}
@@ -489,7 +520,7 @@ class Camera extends Object3D {
}
//获取直线与地球的交点,该方法与MathUtils.getLineIntersectPointWithEarth功能基本一样,只不过该方法对相交点进行了远近排序
- getPickCartesianCoordInEarthByLine(line: Line): Vertice[] {
+ private _getPickCartesianCoordInEarthByLine(line: Line): Vertice[] {
var result: Vertice[] = [];
//pickVertice是笛卡尔空间直角坐标系中的坐标
var pickVertices = MathUtils.getLineIntersectPointWithEarth(line);
@@ -512,20 +543,11 @@ class Camera extends Object3D {
return result;
}
- //计算拾取射线与地球的交点,以笛卡尔空间直角坐标系坐标数组的形式返回
- getPickCartesianCoordInEarthByCanvas(canvasX: number, canvasY: number): Vertice[] {
- var pickDirection = this._getPickDirectionByCanvas(canvasX, canvasY);
- var p = this.getPosition();
- var line = new Line(p, pickDirection);
- var result = this.getPickCartesianCoordInEarthByLine(line);
- return result;
- }
-
private _getPickCartesianCoordInEarthByNDC(ndcX: number, ndcY: number): Vertice[] {
var pickDirection = this._getPickDirectionByNDC(ndcX, ndcY);
var p = this.getPosition();
var line = new Line(p, pickDirection);
- var result = this.getPickCartesianCoordInEarthByLine(line);
+ var result = this._getPickCartesianCoordInEarthByLine(line);
return result;
}
@@ -593,7 +615,7 @@ class Camera extends Object3D {
var cameraP = this.getPosition();
var dir = Vector.verticeMinusVertice(verticeInWorld, cameraP);
var line = new Line(cameraP, dir);
- var pickResult = this.getPickCartesianCoordInEarthByLine(line);
+ var pickResult = this._getPickCartesianCoordInEarthByLine(line);
if (pickResult.length > 0) {
var pickVertice = pickResult[0];
var length2Vertice = MathUtils.getLengthFromVerticeToVertice(cameraP, verticeInWorld);
diff --git a/src/world/Event.ts b/src/world/Event.ts
index eaf3b49..6bffb78 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -56,7 +56,7 @@ const EventModule = {
var pickResult = Kernel.globe.camera.getPickCartesianCoordInEarthByCanvas(this.previousX, this.previousY);
if (pickResult.length > 0) {
this.dragGeo = MathUtils.cartesianCoordToGeographic(pickResult[0]);
- //console.log("单击点三维坐标:(" + pickResult[0].x + "," + pickResult[0].y + "," + pickResult[0].z + ");经纬度坐标:[" + this.dragGeo[0] + "," + this.dragGeo[1] + "]");
+ console.log("单击点三维坐标:(" + pickResult[0].x + "," + pickResult[0].y + "," + pickResult[0].z + ");经纬度坐标:[" + this.dragGeo[0] + "," + this.dragGeo[1] + "]");
}
this.canvas.addEventListener("mousemove", this.onMouseMoveListener, false);
}
diff --git a/src/world/Kernel.ts b/src/world/Kernel.ts
index e906352..033086d 100644
--- a/src/world/Kernel.ts
+++ b/src/world/Kernel.ts
@@ -13,7 +13,7 @@ const Kernel = {
globe: null,
idCounter: 0, //Object3D对象的唯一标识
BASE_LEVEL: 6, //渲染的基准层级
- MAX_LEVEL: 14,//最大的渲染级别
+ MAX_LEVEL: 17,//最大的渲染级别
EARTH_RADIUS: radius,
MAX_PROJECTED_COORD: maxProjectedCoord,
proxy: ""
From e7ea85a32cc80a5934cd44042c1f491bca9f0f17 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Tue, 29 Nov 2016 21:25:23 +0800
Subject: [PATCH 071/109] update version to 0.3.0,#14
---
package.json | 2 +-
versions.txt | 7 ++++++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index 01c3981..35357f7 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "webglobe",
- "version": "0.2.4",
+ "version": "0.3.0",
"description": "A WebGL virtual globe and map engine.",
"main": "require.js",
"scripts": {
diff --git a/versions.txt b/versions.txt
index 80869e4..1f8dabf 100644
--- a/versions.txt
+++ b/versions.txt
@@ -94,4 +94,9 @@
0.2.3 将world/geometries/Geomtry重命名为world/geometries/Mesh,并在package.json中添加了多个npm scripts,对应gulp中定义的tasks
-0.2.4 之前EARTH_RADIUS的值为6378137,特别大,导致了深度值计算有问题,从而使得深度测试不能正常进行。将EARTH_RADIUS改成14000,使得深度测试可以正常进行。并加入了Poi和PoiLayer这两个类。
\ No newline at end of file
+0.2.4 之前EARTH_RADIUS的值为6378137,特别大,导致了深度值计算有问题,从而使得深度测试不能正常进行。将EARTH_RADIUS改成14000,使得深度测试可以正常进行。并加入了Poi和PoiLayer这两个类。
+
+0.3.0 将EARTH_RADIUS从14000改为500,在0-10级的时候,通过改变Camera的position实现缩放,在10级之后通过改变fov实现缩放。
+ Camera中所有的计算(比如计算视野中的可见切片)都是基于matrix、viewMatrix、projMatrix和projViewMatrix。
+ 但是实际传递给shader用于绘图的是projViewMatrixForDraw。Camera.getPickCartesianCoordInEarthByCanvas()方法也是基于projViewMatrixForDraw系列矩阵的。
+ 该版本提高了深度值的精度,基本解决了z值精度问题。在update()方法中会计算projViewMatrixForDraw系列矩阵。
\ No newline at end of file
From 35042aa734c42453e6b072e49e8140b620767b14 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Tue, 29 Nov 2016 22:22:26 +0800
Subject: [PATCH 072/109] udpate Camera.ts,#14
---
src/world/Camera.ts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index cb4bb85..59e184a 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -413,18 +413,17 @@ class Camera extends Object3D {
//don't call setLevel method because it will update CURRENT_LEVEL
// newCamera._updatePositionByLevel(level);
- this._animateToCamera(newCamera, () => {
+ this._animateToCamera(newCamera.matrix.getPosition(), () => {
this.level = level;
});
}
- private _animateToCamera(newCamera: Camera, cb: () => void) {
+ private _animateToCamera(newPosition: Vertice, cb: () => void) {
if (this.isAnimating()) {
return;
}
this.animating = true;
var oldPosition = this.getPosition();
- var newPosition = newCamera.matrix.getPosition();
var span = this.animationDuration;
var singleSpan = 1000 / 60;
var count = Math.floor(span / singleSpan);
@@ -438,7 +437,8 @@ class Camera extends Object3D {
}
var a = timestap - start;
if (a >= span) {
- (Object).assign(this, newCamera._toJson());
+ // (Object).assign(this, newCamera._toJson());
+ this.setPosition(newPosition.x, newPosition.y, newPosition.z);
this.animating = false;
cb();
} else {
From 9d65853cb456be548e48fdcdd75236d7404927fd Mon Sep 17 00:00:00 2001
From: iSpring
Date: Tue, 29 Nov 2016 23:07:48 +0800
Subject: [PATCH 073/109] make Globe.animateToLevel() with version 0.3.0,#14
---
src/world/Camera.ts | 90 +++++++++++++++++++++++++--------------------
src/world/Event.ts | 4 +-
2 files changed, 52 insertions(+), 42 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index 59e184a..6dee2cc 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -19,6 +19,8 @@ class Camera extends Object3D {
private level: number = -1; //当前渲染等级
+ private animationLevel: number = -1;//非整数,表示缩放动画过程中的level
+
//旋转的时候,绕着视线与地球交点进行旋转
//定义抬头时,旋转角为正值
private isZeroPitch: boolean = true;//表示当前Camera视线有没有发生倾斜
@@ -58,13 +60,13 @@ class Camera extends Object3D {
private _rawSetPerspectiveMatrix(fov: number = 45, aspect: number = 1, near: number = 1, far: number = 100, projMatrix: Matrix = this.projMatrix): void {
//https://github.com/toji/gl-matrix/blob/master/src/gl-matrix/mat4.js#L1788
- if(this.projMatrix === projMatrix){
+ if (this.projMatrix === projMatrix) {
this.fov = fov;
this.aspect = aspect;
this.near = near;
this.far = far;
}
-
+
var mat = [
1, 0, 0, 0,
0, 1, 0, 0,
@@ -110,7 +112,7 @@ class Camera extends Object3D {
// this._rawSetPerspectiveMatrix(this.fov, this.aspect, this.near, far);
}
- private _getMinimalFar(cameraPosition: Vertice): number{
+ private _getMinimalFar(cameraPosition: Vertice): number {
//重新计算far,保持far在满足正常需求情况下的最小值
//far值:视点与地球切面的距离
var distance2EarthOrigin = Vector.fromVertice(cameraPosition).getLength();
@@ -168,7 +170,9 @@ class Camera extends Object3D {
private _updatePositionAndFov(cameraMatrix: Matrix): number {
//是否满足near值,和fov没有关系,和position有关
//但是改变position的话,fov也要相应变动以满足对应的缩放效果
- const currentLevel = this.getLevel();
+ const currentLevel = this.animating ? this.animationLevel : this.level;
+
+ //safeLevel不是整数
var safeLevel = this._getSafeThresholdLevelForNear();
if (currentLevel > safeLevel) {
@@ -193,7 +197,8 @@ class Camera extends Object3D {
var thresholdNear = this.near * this.nearFactor;
var pow2level = this.baseTheoryDistanceFromCamera2EarthSurface / thresholdNear;
var level = (Math).log2(pow2level);
- return Math.floor(level);
+ //return Math.floor(level);
+ return level;
}
/**
@@ -271,13 +276,13 @@ class Camera extends Object3D {
}
//设置观察到的层级,不要在该方法中修改this.level的值
- private _updatePositionByLevel(level: number, cameraMatrix: Matrix) {
+ private _updatePositionByLevel(level: number, cameraMatrix: Matrix) {
var globe = Kernel.globe;
var intersects = this._getDirectionIntersectPointWithEarth(cameraMatrix);
if (intersects.length === 0) {
throw "no intersect";
}
- var intersect = intersects[0];
+ var intersect = intersects[0];
var theoryDistance2Interscet = this._getTheoryDistanceFromCamera2EarthSurface(level);
var vector = cameraMatrix.getColumnZ();
vector.setLength(theoryDistance2Interscet);
@@ -405,24 +410,21 @@ class Camera extends Object3D {
return this.animating;
}
- animateToLevel(level: number): void {
- if (!(Utils.isNonNegativeInteger(level))) {
- throw "invalid level:" + level;
- }
- var newCamera = this._clone();
- //don't call setLevel method because it will update CURRENT_LEVEL
- // newCamera._updatePositionByLevel(level);
-
- this._animateToCamera(newCamera.matrix.getPosition(), () => {
- this.level = level;
- });
- }
-
- private _animateToCamera(newPosition: Vertice, cb: () => void) {
+ animateToLevel(newLevel: number): void {
if (this.isAnimating()) {
return;
}
- this.animating = true;
+
+ if (!(Utils.isNonNegativeInteger(newLevel))) {
+ throw "invalid level:" + newLevel;
+ }
+ var newCameraMatrix = this.matrix.clone();
+ this._updatePositionByLevel(newLevel, newCameraMatrix);
+ var newPosition = newCameraMatrix.getPosition();
+
+ //don't call setLevel method because it will update CURRENT_LEVEL
+ // newCamera._updatePositionByLevel(newLevel);
+
var oldPosition = this.getPosition();
var span = this.animationDuration;
var singleSpan = 1000 / 60;
@@ -430,7 +432,11 @@ class Camera extends Object3D {
var deltaX = (newPosition.x - oldPosition.x) / count;
var deltaY = (newPosition.y - oldPosition.y) / count;
var deltaZ = (newPosition.z - oldPosition.z) / count;
+ var deltaLevel = (newLevel - this.level) / count;
var start: number = -1;
+ this.animationLevel = this.level;
+ this.animating = true;
+
var callback = (timestap: number) => {
if (start < 0) {
start = timestap;
@@ -438,10 +444,14 @@ class Camera extends Object3D {
var a = timestap - start;
if (a >= span) {
// (Object).assign(this, newCamera._toJson());
- this.setPosition(newPosition.x, newPosition.y, newPosition.z);
+ // this.setPosition(newPosition.x, newPosition.y, newPosition.z);
+ // this.animating = false;
+ //cb();
this.animating = false;
- cb();
+ this.animationLevel = -1;
+ this.setLevel(newLevel);
} else {
+ this.animationLevel += deltaLevel;
var p = this.getPosition();
this.setPosition(p.x + deltaX, p.y + deltaY, p.z + deltaZ);
requestAnimationFrame(callback);
@@ -450,22 +460,22 @@ class Camera extends Object3D {
requestAnimationFrame(callback);
}
- private _clone(): Camera {
- var camera: Camera = new Camera();
- (Object).assign(camera, this._toJson());
- return camera;
- }
+ // private _clone(): Camera {
+ // var camera: Camera = new Camera();
+ // (Object).assign(camera, this._toJson());
+ // return camera;
+ // }
- private _toJson(): any {
- return {
- near: this.near,
- far: this.far,
- fov: this.fov,
- aspect: this.aspect,
- matrix: this.matrix.clone(),
- projMatrix: this.projMatrix.clone()
- };
- }
+ // private _toJson(): any {
+ // return {
+ // near: this.near,
+ // far: this.far,
+ // fov: this.fov,
+ // aspect: this.aspect,
+ // matrix: this.matrix.clone(),
+ // projMatrix: this.projMatrix.clone()
+ // };
+ // }
private _look(cameraPnt: Vertice, targetPnt: Vertice, upDirection: Vector = new Vector(0, 1, 0)): void {
var cameraPntCopy = cameraPnt.clone();
@@ -501,7 +511,7 @@ class Camera extends Object3D {
}
//获取cameraMatrix视线与地球的交点
- private _getDirectionIntersectPointWithEarth(cameraMatrix: Matrix): Vertice[]{
+ private _getDirectionIntersectPointWithEarth(cameraMatrix: Matrix): Vertice[] {
var dir = cameraMatrix.getColumnZ().getOpposite();
var p = cameraMatrix.getPosition();
var line = new Line(p, dir);
diff --git a/src/world/Event.ts b/src/world/Event.ts
index 6bffb78..f11665e 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -154,8 +154,8 @@ const EventModule = {
}
var newLevel = globe.getLevel() + deltaLevel;
if(newLevel >= 0){
- globe.setLevel(newLevel);
- //globe.animateToLevel(newLevel);
+ //globe.setLevel(newLevel);
+ globe.animateToLevel(newLevel);
}
},
From a0f2cb4fab520a1428b6c8059f69be3f21bf8ceb Mon Sep 17 00:00:00 2001
From: iSpring
Date: Tue, 29 Nov 2016 23:19:28 +0800
Subject: [PATCH 074/109] disable user interaction when animating,#14
---
src/world/Event.ts | 107 ++++++++++++++++++++++++---------------------
1 file changed, 56 insertions(+), 51 deletions(-)
diff --git a/src/world/Event.ts b/src/world/Event.ts
index f11665e..bfce024 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -49,51 +49,54 @@ const EventModule = {
},
onMouseDown(event: MouseEvent) {
- if (Kernel.globe) {
- this.bMouseDown = true;
- this.previousX = event.layerX || event.offsetX;
- this.previousY = event.layerY || event.offsetY;
- var pickResult = Kernel.globe.camera.getPickCartesianCoordInEarthByCanvas(this.previousX, this.previousY);
- if (pickResult.length > 0) {
- this.dragGeo = MathUtils.cartesianCoordToGeographic(pickResult[0]);
- console.log("单击点三维坐标:(" + pickResult[0].x + "," + pickResult[0].y + "," + pickResult[0].z + ");经纬度坐标:[" + this.dragGeo[0] + "," + this.dragGeo[1] + "]");
- }
- this.canvas.addEventListener("mousemove", this.onMouseMoveListener, false);
+ var globe = Kernel.globe;
+ if (!globe || globe.isAnimating()) {
+ return;
}
+ this.bMouseDown = true;
+ this.previousX = event.layerX || event.offsetX;
+ this.previousY = event.layerY || event.offsetY;
+ var pickResult = Kernel.globe.camera.getPickCartesianCoordInEarthByCanvas(this.previousX, this.previousY);
+ if (pickResult.length > 0) {
+ this.dragGeo = MathUtils.cartesianCoordToGeographic(pickResult[0]);
+ console.log("单击点三维坐标:(" + pickResult[0].x + "," + pickResult[0].y + "," + pickResult[0].z + ");经纬度坐标:[" + this.dragGeo[0] + "," + this.dragGeo[1] + "]");
+ }
+ this.canvas.addEventListener("mousemove", this.onMouseMoveListener, false);
},
onMouseMove(event: MouseEvent) {
var globe = Kernel.globe;
- if (globe && this.bMouseDown) {
- var currentX = event.layerX || event.offsetX;
- var currentY = event.layerY || event.offsetY;
- var pickResult = globe.camera.getPickCartesianCoordInEarthByCanvas(currentX, currentY);
- if (pickResult.length > 0) {
- //鼠标在地球范围内
- if (this.dragGeo) {
- //鼠标拖动过程中要显示底图
- //globe.showAllSubTiledLayerAndTiles();
- var newGeo = MathUtils.cartesianCoordToGeographic(pickResult[0]);
- this.moveGeo(this.dragGeo[0], this.dragGeo[1], newGeo[0], newGeo[1]);
- } else {
- //进入地球内部
- this.dragGeo = MathUtils.cartesianCoordToGeographic(pickResult[0]);
- }
- this.previousX = currentX;
- this.previousY = currentY;
- this.canvas.style.cursor = "pointer";
+ if (!globe || globe.isAnimating() || !this.bMouseDown) {
+ return;
+ }
+ var currentX = event.layerX || event.offsetX;
+ var currentY = event.layerY || event.offsetY;
+ var pickResult = globe.camera.getPickCartesianCoordInEarthByCanvas(currentX, currentY);
+ if (pickResult.length > 0) {
+ //鼠标在地球范围内
+ if (this.dragGeo) {
+ //鼠标拖动过程中要显示底图
+ //globe.showAllSubTiledLayerAndTiles();
+ var newGeo = MathUtils.cartesianCoordToGeographic(pickResult[0]);
+ this.moveGeo(this.dragGeo[0], this.dragGeo[1], newGeo[0], newGeo[1]);
} else {
- //鼠标超出地球范围
- this.previousX = -1;
- this.previousY = -1;
- this.dragGeo = null;
- this.canvas.style.cursor = "default";
+ //进入地球内部
+ this.dragGeo = MathUtils.cartesianCoordToGeographic(pickResult[0]);
}
+ this.previousX = currentX;
+ this.previousY = currentY;
+ this.canvas.style.cursor = "pointer";
+ } else {
+ //鼠标超出地球范围
+ this.previousX = -1;
+ this.previousY = -1;
+ this.dragGeo = null;
+ this.canvas.style.cursor = "default";
}
},
moveGeo(oldLon: number, oldLat: number, newLon: number, newLat: number) {
- if(oldLon === newLon && oldLat === newLat){
+ if (oldLon === newLon && oldLat === newLat) {
return;
}
var p1 = MathUtils.geographicToCartesianCoord(oldLon, oldLat);
@@ -119,25 +122,27 @@ const EventModule = {
onDbClick(event: MouseEvent) {
var globe = Kernel.globe;
- if (globe) {
- var absoluteX = event.layerX || event.offsetX;
- var absoluteY = event.layerY || event.offsetY;
- var pickResult = globe.camera.getPickCartesianCoordInEarthByCanvas(absoluteX, absoluteY);
+ if (!globe || globe.isAnimating()) {
+ return;
+ }
+
+ var absoluteX = event.layerX || event.offsetX;
+ var absoluteY = event.layerY || event.offsetY;
+ var pickResult = globe.camera.getPickCartesianCoordInEarthByCanvas(absoluteX, absoluteY);
+ globe.setLevel(globe.getLevel() + 1);
+ if (pickResult.length >= 1) {
+ var pickVertice = pickResult[0];
+ var lonlat = MathUtils.cartesianCoordToGeographic(pickVertice);
+ var lon = lonlat[0];
+ var lat = lonlat[1];
globe.setLevel(globe.getLevel() + 1);
- if (pickResult.length >= 1) {
- var pickVertice = pickResult[0];
- var lonlat = MathUtils.cartesianCoordToGeographic(pickVertice);
- var lon = lonlat[0];
- var lat = lonlat[1];
- globe.setLevel(globe.getLevel() + 1);
- this.moveLonLatToCanvas(lon, lat, absoluteX, absoluteY);
- }
+ this.moveLonLatToCanvas(lon, lat, absoluteX, absoluteY);
}
},
onMouseWheel(event: MouseWheelEvent) {
var globe = Kernel.globe;
- if (!globe) {
+ if (!globe || globe.isAnimating()) {
return;
}
@@ -153,7 +158,7 @@ const EventModule = {
deltaLevel = -parseInt((delta / 3));
}
var newLevel = globe.getLevel() + deltaLevel;
- if(newLevel >= 0){
+ if (newLevel >= 0) {
//globe.setLevel(newLevel);
globe.animateToLevel(newLevel);
}
@@ -165,7 +170,7 @@ const EventModule = {
*/
onKeyDown(event: KeyboardEvent) {
var globe = Kernel.globe;
- if (!globe) {
+ if (!globe || globe.isAnimating()) {
return;
}
@@ -173,10 +178,10 @@ const EventModule = {
var camera = globe.camera;
var keyNum = event.keyCode !== undefined ? event.keyCode : event.which;
//上、下、左、右:38、40、37、39
- if(keyNum === 38){
+ if (keyNum === 38) {
//向上键
camera.setDeltaPitch(DELTA_PITCH);
- }else if(keyNum === 40){
+ } else if (keyNum === 40) {
//向下键
camera.setDeltaPitch(-DELTA_PITCH);
}
From 0fe8c831192922e9c2643c5c5359fe5d263e146d Mon Sep 17 00:00:00 2001
From: iSpring
Date: Tue, 29 Nov 2016 23:23:10 +0800
Subject: [PATCH 075/109] update version to 0.3.1
---
package.json | 2 +-
versions.txt | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/package.json b/package.json
index 35357f7..5a5b5d0 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "webglobe",
- "version": "0.3.0",
+ "version": "0.3.1",
"description": "A WebGL virtual globe and map engine.",
"main": "require.js",
"scripts": {
diff --git a/versions.txt b/versions.txt
index 1f8dabf..da58fb2 100644
--- a/versions.txt
+++ b/versions.txt
@@ -99,4 +99,6 @@
0.3.0 将EARTH_RADIUS从14000改为500,在0-10级的时候,通过改变Camera的position实现缩放,在10级之后通过改变fov实现缩放。
Camera中所有的计算(比如计算视野中的可见切片)都是基于matrix、viewMatrix、projMatrix和projViewMatrix。
但是实际传递给shader用于绘图的是projViewMatrixForDraw。Camera.getPickCartesianCoordInEarthByCanvas()方法也是基于projViewMatrixForDraw系列矩阵的。
- 该版本提高了深度值的精度,基本解决了z值精度问题。在update()方法中会计算projViewMatrixForDraw系列矩阵。
\ No newline at end of file
+ 该版本提高了深度值的精度,基本解决了z值精度问题。在update()方法中会计算projViewMatrixForDraw系列矩阵。
+
+0.3.1 使得Globe.animateToLevel()可以在0.3.0的版本上运行,解决办法是引入了camera.animationLevel,其值是非整数。
\ No newline at end of file
From 352df4b236e2c3545346c6c2904c31fb568eef80 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Wed, 30 Nov 2016 09:50:46 +0800
Subject: [PATCH 076/109] remove some comments
---
src/world/Camera.ts | 26 +-------------------------
1 file changed, 1 insertion(+), 25 deletions(-)
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index 6dee2cc..e1d94f9 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -153,7 +153,7 @@ class Camera extends Object3D {
//计算newFar
var newPosition = this.matrixForDraw.getPosition();
- var newFar = this.far; //this._getMinimalFar(newPosition);
+ var newFar = this.far; //this._getMinimalFar(newPosition);
//根据newFov和newFar重新计算
this.projMatrixForDraw = new Matrix();
@@ -422,9 +422,6 @@ class Camera extends Object3D {
this._updatePositionByLevel(newLevel, newCameraMatrix);
var newPosition = newCameraMatrix.getPosition();
- //don't call setLevel method because it will update CURRENT_LEVEL
- // newCamera._updatePositionByLevel(newLevel);
-
var oldPosition = this.getPosition();
var span = this.animationDuration;
var singleSpan = 1000 / 60;
@@ -443,10 +440,6 @@ class Camera extends Object3D {
}
var a = timestap - start;
if (a >= span) {
- // (Object).assign(this, newCamera._toJson());
- // this.setPosition(newPosition.x, newPosition.y, newPosition.z);
- // this.animating = false;
- //cb();
this.animating = false;
this.animationLevel = -1;
this.setLevel(newLevel);
@@ -460,23 +453,6 @@ class Camera extends Object3D {
requestAnimationFrame(callback);
}
- // private _clone(): Camera {
- // var camera: Camera = new Camera();
- // (Object).assign(camera, this._toJson());
- // return camera;
- // }
-
- // private _toJson(): any {
- // return {
- // near: this.near,
- // far: this.far,
- // fov: this.fov,
- // aspect: this.aspect,
- // matrix: this.matrix.clone(),
- // projMatrix: this.projMatrix.clone()
- // };
- // }
-
private _look(cameraPnt: Vertice, targetPnt: Vertice, upDirection: Vector = new Vector(0, 1, 0)): void {
var cameraPntCopy = cameraPnt.clone();
var targetPntCopy = targetPnt.clone();
From 035e241d40f58d3013dd00fba47abb08b8c09aa3 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Wed, 30 Nov 2016 10:20:57 +0800
Subject: [PATCH 077/109] update MAX_LEVEL to 15
---
src/world/Kernel.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/world/Kernel.ts b/src/world/Kernel.ts
index 033086d..69eb736 100644
--- a/src/world/Kernel.ts
+++ b/src/world/Kernel.ts
@@ -13,7 +13,7 @@ const Kernel = {
globe: null,
idCounter: 0, //Object3D对象的唯一标识
BASE_LEVEL: 6, //渲染的基准层级
- MAX_LEVEL: 17,//最大的渲染级别
+ MAX_LEVEL: 15,//最大的渲染级别
EARTH_RADIUS: radius,
MAX_PROJECTED_COORD: maxProjectedCoord,
proxy: ""
From 0ce8a06cec6d9584163ab6e78ac4f5747a729c80 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Wed, 30 Nov 2016 12:41:49 +0800
Subject: [PATCH 078/109] call Math.asin() and Math.acos() safely,#20
---
src/world/Event.ts | 2 +-
src/world/math/Math.ts | 21 ++++++++++++---------
2 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/src/world/Event.ts b/src/world/Event.ts
index bfce024..2ab4743 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -59,7 +59,7 @@ const EventModule = {
var pickResult = Kernel.globe.camera.getPickCartesianCoordInEarthByCanvas(this.previousX, this.previousY);
if (pickResult.length > 0) {
this.dragGeo = MathUtils.cartesianCoordToGeographic(pickResult[0]);
- console.log("单击点三维坐标:(" + pickResult[0].x + "," + pickResult[0].y + "," + pickResult[0].z + ");经纬度坐标:[" + this.dragGeo[0] + "," + this.dragGeo[1] + "]");
+ //console.log("单击点三维坐标:(" + pickResult[0].x + "," + pickResult[0].y + "," + pickResult[0].z + ");经纬度坐标:[" + this.dragGeo[0] + "," + this.dragGeo[1] + "]");
}
this.canvas.addEventListener("mousemove", this.onMouseMoveListener, false);
},
diff --git a/src/world/math/Math.ts b/src/world/math/Math.ts
index 34bed55..462a5be 100644
--- a/src/world/math/Math.ts
+++ b/src/world/math/Math.ts
@@ -33,6 +33,9 @@ const MathUtils = {
if(value > 1){
value = 1;
}
+ if(value < -1){
+ value = -1;
+ }
return Math.asin(value);
},
@@ -40,6 +43,9 @@ const MathUtils = {
if(value > 1){
value = 1;
}
+ if(value < -1){
+ value = -1;
+ }
return Math.acos(value);
},
@@ -375,26 +381,23 @@ const MathUtils = {
var y = verticeCopy.y;
var z = verticeCopy.z;
var sin2 = y / Kernel.EARTH_RADIUS;
- if(sin2 > 1){
- sin2 = 2;
- }else if(sin2 < -1){
- sin2 = -1;
- }
- var radianLat = Math.asin(sin2);
+ var radianLat = this.asinSafely(sin2);
var cos2 = Math.cos(radianLat);
var sin1 = x / (Kernel.EARTH_RADIUS * cos2);
if(sin1 > 1){
sin1 = 1;
- }else if(sin1 < -1){
+ }
+ if(sin1 < -1){
sin1 = -1;
}
var cos1 = z / (Kernel.EARTH_RADIUS * cos2);
if(cos1 > 1){
cos1 = 1;
- }else if(cos1 < -1){
+ }
+ if(cos1 < -1){
cos1 = -1;
}
- var radianLog = Math.asin(sin1);
+ var radianLog = this.asinSafely(sin1);
if(sin1 >= 0){
//经度在[0,π]
if(cos1 >= 0){
From cbd9c526812b0d528e5d30016f3ed3aee67bfbde Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Wed, 30 Nov 2016 18:55:58 +0800
Subject: [PATCH 079/109] optimize Camera.update() method and update version to
0.3.2,#21
---
package.json | 2 +-
src/world/Camera.ts | 61 ++++++++++++++++++++++++++--------------
src/world/math/Matrix.ts | 24 ++++++++++++----
versions.txt | 4 ++-
4 files changed, 63 insertions(+), 28 deletions(-)
diff --git a/package.json b/package.json
index 5a5b5d0..7a33dc8 100644
--- a/package.json
+++ b/package.json
@@ -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": {
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index e1d94f9..e96fb62 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -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;//获取投影矩阵与视点矩阵的乘积
@@ -36,11 +42,6 @@ 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改变后重新计算
@@ -48,6 +49,8 @@ class Camera extends Object3D {
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();
@@ -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 {
@@ -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();
@@ -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();
}
@@ -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) => {
@@ -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);
diff --git a/src/world/math/Matrix.ts b/src/world/math/Matrix.ts
index 63d8274..948e69e 100644
--- a/src/world/math/Matrix.ts
+++ b/src/world/math/Matrix.ts
@@ -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,
@@ -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];
}
@@ -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;
+ });
}
/**
@@ -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 {
diff --git a/versions.txt b/versions.txt
index da58fb2..ab43142 100644
--- a/versions.txt
+++ b/versions.txt
@@ -101,4 +101,6 @@
但是实际传递给shader用于绘图的是projViewMatrixForDraw。Camera.getPickCartesianCoordInEarthByCanvas()方法也是基于projViewMatrixForDraw系列矩阵的。
该版本提高了深度值的精度,基本解决了z值精度问题。在update()方法中会计算projViewMatrixForDraw系列矩阵。
-0.3.1 使得Globe.animateToLevel()可以在0.3.0的版本上运行,解决办法是引入了camera.animationLevel,其值是非整数。
\ No newline at end of file
+0.3.1 使得Globe.animateToLevel()可以在0.3.0的版本上运行,解决办法是引入了camera.animationLevel,其值是非整数。
+
+0.3.2 优化了Camera.update()方法,只有发生用户交互的情况下才实际进行计算。
\ No newline at end of file
From 75e58f130b5dc8f6a2999f8b27215110e30fd827 Mon Sep 17 00:00:00 2001
From: iSpring
Date: Wed, 30 Nov 2016 23:22:50 +0800
Subject: [PATCH 080/109] optimize Globe.refresh() method and update to version
0.3.3,#21
---
package.json | 2 +-
src/world/Camera.ts | 48 ++++++++++++++++++++++++++++++-
src/world/Definitions.d.ts | 12 ++++++++
src/world/Event.ts | 2 +-
src/world/Globe.ts | 13 +++++++--
src/world/GraphicGroup.ts | 2 +-
src/world/Renderer.ts | 2 +-
src/world/graphics/Graphic.ts | 2 +-
src/world/graphics/MeshGraphic.ts | 2 +-
src/world/graphics/Poi.ts | 2 +-
src/world/layers/TiledLayer.ts | 2 +-
versions.txt | 4 ++-
12 files changed, 80 insertions(+), 13 deletions(-)
diff --git a/package.json b/package.json
index 7a33dc8..41d876f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "webglobe",
- "version": "0.3.2",
+ "version": "0.3.3",
"description": "A WebGL virtual globe and map engine.",
"main": "require.js",
"scripts": {
diff --git a/src/world/Camera.ts b/src/world/Camera.ts
index e96fb62..cc0ecb1 100644
--- a/src/world/Camera.ts
+++ b/src/world/Camera.ts
@@ -10,6 +10,48 @@ import TileGrid = require('./TileGrid');
import Matrix = require('./math/Matrix');
import Object3D = require('./Object3D');
+export class CameraCore{
+ constructor(private fov: number, private aspect: number, private near: number, private far: number, private realLevel: number, private matrix: Matrix){
+
+ }
+
+ getFov(){
+ return this.fov;
+ }
+
+ getAspect(){
+ return this.aspect;
+ }
+
+ getNear(){
+ return this.near;
+ }
+
+ getFar(){
+ return this.far;
+ }
+
+ getRealLeavel(){
+ return this.realLevel;
+ }
+
+ getMatrix(){
+ return this.matrix;
+ }
+
+ equals(other: CameraCore): boolean{
+ if(!other){
+ return false;
+ }
+ return this.fov === other.getFov() &&
+ this.aspect === other.getAspect() &&
+ this.near === other.getNear() &&
+ this.far === other.getFar() &&
+ this.realLevel === other.getRealLeavel() &&
+ this.matrix.equals(other.getMatrix());
+ }
+}
+
class Camera extends Object3D {
private readonly initFov: number;
private readonly animationDuration: number = 600;//层级变化的动画周期是600毫秒
@@ -138,6 +180,10 @@ class Camera extends Object3D {
this.lastMatrix.setMatrixByOther(this.matrix);
}
+ getCameraCore(){
+ return new CameraCore(this.fov, this.aspect, this.near, this.far, this.realLevel, this.matrix.clone());
+ }
+
private _isNeedUpdate(): boolean{
return (this.fov !== this.lastFov) ||
(this.aspect !== this.lastAspect) ||
@@ -937,4 +983,4 @@ class Camera extends Object3D {
}
}
-export = Camera;
\ No newline at end of file
+export default Camera;
\ No newline at end of file
diff --git a/src/world/Definitions.d.ts b/src/world/Definitions.d.ts
index 6a3859f..fcc57a3 100644
--- a/src/world/Definitions.d.ts
+++ b/src/world/Definitions.d.ts
@@ -1,3 +1,5 @@
+import Matrix = require('./math/Matrix');
+
interface WebGLProgramExtension extends WebGLProgram{
uMVMatrix: WebGLUniformLocation;
uPMatrix: WebGLUniformLocation;
@@ -9,4 +11,14 @@ interface WebGLProgramExtension extends WebGLProgram{
export interface WebGLRenderingContextExtension extends WebGLRenderingContext{
shaderProgram: WebGLProgramExtension;
+}
+
+export interface IMockCamera{
+ fov: number;
+ aspect: number;
+ near: number;
+ far: number;
+ realLevel: number;
+ matrix: Matrix;
+ equals(other: IMockCamera): boolean;
}
\ No newline at end of file
diff --git a/src/world/Event.ts b/src/world/Event.ts
index 2ab4743..22e38d8 100644
--- a/src/world/Event.ts
+++ b/src/world/Event.ts
@@ -2,7 +2,7 @@
import Kernel = require("./Kernel");
import MathUtils = require("./math/Math");
import Vector = require("./math/Vector");
-import Camera = require("./Camera");
+import Camera from "./Camera";
type MouseMoveListener = (e: MouseEvent) => {};
diff --git a/src/world/Globe.ts b/src/world/Globe.ts
index 5d73811..e51de78 100644
--- a/src/world/Globe.ts
+++ b/src/world/Globe.ts
@@ -2,7 +2,7 @@
import Kernel = require("./Kernel");
import Utils = require("./Utils");
import Renderer = require("./Renderer");
-import Camera = require("./Camera");
+import Camera, {CameraCore} from "./Camera";
import Scene = require("./Scene");
import TiledLayer = require("./layers/TiledLayer");
import SubTiledLayer = require("./layers/SubTiledLayer");
@@ -17,6 +17,7 @@ class Globe {
scene: Scene = null;
camera: Camera = null;
tiledLayer: TiledLayer = null;
+ private cameraCore: CameraCore = null;
constructor(canvas: HTMLCanvasElement) {
Kernel.globe = this;
@@ -132,12 +133,18 @@ class Globe {
}
}
- refresh() {
+ refresh(force: boolean = false) {
if (!this.tiledLayer || !this.scene || !this.camera) {
return;
}
//先更新camera中的各种矩阵
- this.camera.update();
+ this.camera.update(force);
+ var newCameraCore = this.camera.getCameraCore();
+ var isNeedRefresh = force || !newCameraCore.equals(this.cameraCore);
+ this.cameraCore = newCameraCore;
+ if(!isNeedRefresh){
+ return;
+ }
var level = this.getLevel() + 3;
this.tiledLayer.updateSubLayerCount(level);
var options = {
diff --git a/src/world/GraphicGroup.ts b/src/world/GraphicGroup.ts
index 83bef4e..67f49a6 100644
--- a/src/world/GraphicGroup.ts
+++ b/src/world/GraphicGroup.ts
@@ -1,7 +1,7 @@
///
import Kernel = require("./Kernel");
import Graphic = require("./graphics/Graphic");
-import Camera = require("./Camera");
+import Camera from "./Camera";
type Drawable = Graphic | GraphicGroup;
diff --git a/src/world/Renderer.ts b/src/world/Renderer.ts
index 8105eb4..78084dd 100644
--- a/src/world/Renderer.ts
+++ b/src/world/Renderer.ts
@@ -2,7 +2,7 @@
import Kernel = require("./Kernel");
import EventUtils = require("./Event");
import Scene = require("./Scene");
-import Camera = require("./Camera");
+import Camera from "./Camera";
import {WebGLRenderingContextExtension, WebGLProgramExtension} from "./Definitions";
class Renderer {
diff --git a/src/world/graphics/Graphic.ts b/src/world/graphics/Graphic.ts
index af08ed8..8abfe33 100644
--- a/src/world/graphics/Graphic.ts
+++ b/src/world/graphics/Graphic.ts
@@ -5,7 +5,7 @@ import Geometry = require("../geometries/Geometry");
import Material = require("../materials/Material");
import Program = require("../Program");
import ProgramUtils = require("../ProgramUtils");
-import Camera = require("../Camera");
+import Camera from "../Camera";
interface GraphicOptions{
geometry: Geometry;
diff --git a/src/world/graphics/MeshGraphic.ts b/src/world/graphics/MeshGraphic.ts
index c05353e..3792a15 100644
--- a/src/world/graphics/MeshGraphic.ts
+++ b/src/world/graphics/MeshGraphic.ts
@@ -5,7 +5,7 @@ import Program = require("../Program");
import Graphic = require("./Graphic");
import Mesh = require("../geometries/Mesh");
import MeshTextureMaterial = require("../materials/MeshTextureMaterial");
-import Camera = require("../Camera");
+import Camera from "../Camera";
const vs =
`
diff --git a/src/world/graphics/Poi.ts b/src/world/graphics/Poi.ts
index c3d7b96..da94e61 100644
--- a/src/world/graphics/Poi.ts
+++ b/src/world/graphics/Poi.ts
@@ -5,7 +5,7 @@ import Graphic = require('./Graphic');
import Marker = require('../geometries/Marker');
import PoiMaterial = require('../materials/PoiMaterial');
import Program = require("../Program");
-import Camera = require("../Camera");
+import Camera from "../Camera";
const vs =
`
diff --git a/src/world/layers/TiledLayer.ts b/src/world/layers/TiledLayer.ts
index d1bd0ac..afa39f6 100644
--- a/src/world/layers/TiledLayer.ts
+++ b/src/world/layers/TiledLayer.ts
@@ -2,7 +2,7 @@
import Kernel = require('../Kernel');
import GraphicGroup = require('../GraphicGroup');
import SubTiledLayer = require('./SubTiledLayer');
-import Camera = require('../Camera');
+import Camera from '../Camera';
abstract class TiledLayer extends GraphicGroup {
diff --git a/versions.txt b/versions.txt
index ab43142..7880673 100644
--- a/versions.txt
+++ b/versions.txt
@@ -103,4 +103,6 @@
0.3.1 使得Globe.animateToLevel()可以在0.3.0的版本上运行,解决办法是引入了camera.animationLevel,其值是非整数。
-0.3.2 优化了Camera.update()方法,只有发生用户交互的情况下才实际进行计算。
\ No newline at end of file
+0.3.2 优化了Camera.update()方法,只有发生用户交互的情况下才实际进行计算。
+
+0.3.3 优化了Globe.refresh()方法,只有发生用具交互的情况下才重新计算可见切片。
\ No newline at end of file
From 177a1ca2e2b2bd12cfb74b4fcea9a3412bd9ddcb Mon Sep 17 00:00:00 2001
From: iSpring
Date: Wed, 30 Nov 2016 23:46:52 +0800
Subject: [PATCH 081/109] clear color to black
---
src/world/Renderer.ts | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/world/Renderer.ts b/src/world/Renderer.ts
index 78084dd..c63e1b7 100644
--- a/src/world/Renderer.ts
+++ b/src/world/Renderer.ts
@@ -58,12 +58,13 @@ class Renderer {
}
render(scene: Scene, camera: Camera) {
- Kernel.gl.viewport(0, 0, Kernel.canvas.width, Kernel.canvas.height);
- Kernel.gl.clear(Kernel.gl.COLOR_BUFFER_BIT | Kernel.gl.DEPTH_BUFFER_BIT);
- Kernel.gl.enable(Kernel.gl.DEPTH_TEST);
- Kernel.gl.depthFunc(Kernel.gl.LEQUAL);
- Kernel.gl.depthMask(true);
- //update viewMatrix, projMatrix and projViewMatrix
+ var gl = Kernel.gl;
+ gl.viewport(0, 0, Kernel.canvas.width, Kernel.canvas.height);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.clearColor(0, 0, 0, 1);
+ gl.enable(gl.DEPTH_TEST);
+ gl.depthFunc(gl.LEQUAL);
+ gl.depthMask(true);
camera.update();
scene.draw(camera);
}
From 62e361a45352263aff5baf535fc428d3acf7ff0c Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Thu, 1 Dec 2016 12:59:25 +0800
Subject: [PATCH 082/109] update versions.txt
---
versions.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/versions.txt b/versions.txt
index 7880673..80557a2 100644
--- a/versions.txt
+++ b/versions.txt
@@ -105,4 +105,4 @@
0.3.2 优化了Camera.update()方法,只有发生用户交互的情况下才实际进行计算。
-0.3.3 优化了Globe.refresh()方法,只有发生用具交互的情况下才重新计算可见切片。
\ No newline at end of file
+0.3.3 优化了Globe.refresh()方法,只有发生用户交互的情况下才重新计算可见切片。
\ No newline at end of file
From b10c0357643448ddde5e1bf41d8abf2452a1c813 Mon Sep 17 00:00:00 2001
From: Qun Sun
Date: Thu, 1 Dec 2016 13:12:31 +0800
Subject: [PATCH 083/109] add Atmosphere files,#16
---
src/world/geometries/Atmosphere.ts | 13 +++++
src/world/graphics/Atmosphere.ts | 84 +++++++++++++++++++++++++++++
src/world/images/atmosphere.png | Bin 0 -> 112776 bytes
src/world/images/atmosphere64.png | Bin 0 -> 2767 bytes
4 files changed, 97 insertions(+)
create mode 100644 src/world/geometries/Atmosphere.ts
create mode 100644 src/world/graphics/Atmosphere.ts
create mode 100644 src/world/images/atmosphere.png
create mode 100644 src/world/images/atmosphere64.png
diff --git a/src/world/geometries/Atmosphere.ts b/src/world/geometries/Atmosphere.ts
new file mode 100644
index 0000000..4fca050
--- /dev/null
+++ b/src/world/geometries/Atmosphere.ts
@@ -0,0 +1,13 @@
+///
+
+import Vertice = require("./MeshVertice");
+import Triangle = require("./Triangle");
+import Mesh = require("./Mesh");
+
+class Atmosphere extends Mesh {
+ constructor(public vertices: Vertice[], public triangles: Triangle[]) {
+ super();
+ }
+}
+
+export = Atmosphere;
\ No newline at end of file
diff --git a/src/world/graphics/Atmosphere.ts b/src/world/graphics/Atmosphere.ts
new file mode 100644
index 0000000..af33552
--- /dev/null
+++ b/src/world/graphics/Atmosphere.ts
@@ -0,0 +1,84 @@
+///
+
+import Kernel = require("../Kernel");
+import Graphic = require('./Graphic');
+import Marker = require('../geometries/Marker');
+import MeshTextureMaterial = require('../materials/MeshTextureMaterial');
+import Program = require("../Program");
+import Camera from "../Camera";
+
+const vs =
+`
+attribute vec3 aPosition;
+uniform mat4 uPMVMatrix;
+uniform float uSize;
+
+void main(void) {
+ gl_Position = uPMVMatrix * vec4(aPosition, 1.0);
+ gl_PointSize = uSize;
+}
+`;
+
+//http://stackoverflow.com/questions/3497068/textured-points-in-opengl-es-2-0
+const fs =
+`
+precision mediump float;
+uniform sampler2D uSampler;
+
+void main()
+{
+ gl_FragColor = texture2D(uSampler, vec2(gl_PointCoord.x, 1.0 - gl_PointCoord.y));
+}
+`;
+
+class Atmosphere extends Graphic {
+ constructor(public geometry: Marker, public material: MeshTextureMaterial){
+ super(geometry, material);
+ }
+
+ createProgram(){
+ return new Program(this.getProgramType(), vs, fs);
+ }
+
+ onDraw(camera: Camera){
+ // var gl = Kernel.gl;
+
+ // //gl.disable(gl.DEPTH_TEST);
+ // gl.enable(gl.BLEND);
+ // gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+
+ // //aPosition
+ // var locPosition = this.program.getAttribLocation('aPosition');
+ // this.program.enableVertexAttribArray('aPosition');
+ // this.geometry.vbo.bind();
+ // gl.vertexAttribPointer(locPosition, 3, gl.FLOAT, false, 0, 0);
+
+ // //uPMVMatrix
+ // var pmvMatrix = camera.getProjViewMatrixForDraw();
+ // var locPMVMatrix = this.program.getUniformLocation('uPMVMatrix');
+ // gl.uniformMatrix4fv(locPMVMatrix, false, pmvMatrix.elements);
+
+ // //uSize
+ // var locSize = this.program.getUniformLocation('uSize');
+ // gl.uniform1f(locSize, this.material.size);
+
+ // //set uSampler
+ // var locSampler = this.program.getUniformLocation('uSampler');
+ // gl.activeTexture(gl.TEXTURE0);
+ // //world.Cache.activeTexture(gl.TEXTURE0);
+ // gl.bindTexture(gl.TEXTURE_2D, this.material.texture);
+ // gl.uniform1i(locSampler, 0);
+
+ // //绘图,1表示1个点
+ // gl.drawArrays(gl.POINTS, 0, 1);
+
+ // //释放当前绑定对象
+ // //gl.enable(gl.DEPTH_TEST);
+ // gl.disable(gl.BLEND);
+ // gl.bindBuffer(gl.ARRAY_BUFFER, null);
+ // gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
+ // gl.bindTexture(gl.TEXTURE_2D, null);
+ }
+}
+
+export = Atmosphere;
\ No newline at end of file
diff --git a/src/world/images/atmosphere.png b/src/world/images/atmosphere.png
new file mode 100644
index 0000000000000000000000000000000000000000..4f0a404aef2cf914a8a14503fd0b326f7c70a573
GIT binary patch
literal 112776
zcmV)lK%c*fP);vBBC`WqHl;uh=?EmpFhmZA|mG>q<<$O5|Q&DVrC(t`vi5|
z`T67T>ptpGcztz`>;LRWUkluy)N}FUdcuzb&ga+fquPXYJE-TsuH!x@bzO5$_1;WG
zqT2C%(DRvKyPtic+vPm}@r?R9=QEubGtZ|!GkvGqI{Uw9chjc6ACk|+x7YPD_H%aQ
z4vi6Wj(e8SPf1^y`|JO+@55xlKVg2kzssM&^=aYWAAR1RfByXQ=bt};A7+2#a#=XQ=PlDV5*I3bRDq4PTE+K_E_mpN!ltqhMIoi
zjd8$>f3I#>Revw_voTZK8yVH{$N)mm>W!Jzcl3rxc28s+q2D{>2DQa27QRfbjC+OUObX>uHnATt2RPjeP+~jh(fj&
z>pjC?ULiL6dHqI&-q(y%^(<)r)$Pg&!s0va`qd#!q_5}4x_VE82D!H7V(((t|Gu5!
zT+8|;>)*fs`@g^1_&5%(&eeaP4}G5F|Mt&Q88!Y~eU5IB<2YD9um0@(UmFF?Oy_44
zR3<~P{Qc22&~s$ROi-aGk)l8U{QuMd_^clpc&HiN-+Au5`8*W@P@xnVqOj_bR^g4O
zA=t{W+3Yh(kQpx8mE5~>caL+8FZy?i6cK$KjQvp%`3mYbLAR)A7jEWdhwey%;H@An
zT%d!0Qa|TrUVV3N=6+-M=jr3R`=R^#@6i7fLu2Kb>iu5*lU@I#@B43+0YF4=M8w2=
zuFmhDi_qh<_erTdi0iw1mpRQ(QQr%lXu)~x>G^8U=kz$=&3C$fCldADee4}ew=U^<
z&-hG!M?Bx_zP5fJ{oeQc+r`d*ub(O2$D8f;`Kr&)KGE0JZF#>pdhWO|TelDQjc*hC
z|Jg5ewZpk!zxR!RcJX~-pTT;;xbIL~WuN))^xt|s>ka8PNc6a3cYkYeWNm)8F<)~a
zdiu8i^u}lJdAG5h3vpA8?`U0V+#Yd5M$V(2fBrdF`YoG}{&V{-SprHle9rYj_g{P_
zzh-C)T-^GWjR$dK&W~ww>rq^v@cZL?#kOI%HlsO*=10~y+5GbJCQHVNW5~}33h#$t
zLOn0h`il(3`+RDQUi>|RcF}%$zXKKL*?HyRQ*^w)ZUH-y%jsG=KRzgbTRi;KgZjv1
zp~}18$xoPiOjLL~9g-o#wyWalsC~O@cIUsk-=1y%SEES48x6PXay~Lo^xuYrxURpd
z9Em9sA;q|@Py;Sdooo(F#`PqZjYCVjq2GvkSIP
zk(ZlUso8Zi%d9#l_gd=TvGQq8L?e`LJ)<^87&t>LTwdL1lfvA?E@RVnp+cv#hMYolx
zbJ_i!O?(EUfYcc9*S?=vKp*Hk=lz!jDu{N|2?f5*EYRTFU(9vzxYPf}`=fb9S3jcu
zjlWSC6L~92XlV}p&hAO$xYV=N_N$*)JKH#iH74H>#XNIvu5)R22|
zy7uopxC%+&W(oY7P@W0$!eDEdK!V(O#~qSGg;~;hoU{4$ERM22_BT+Na&w+s*KZk}
z*EvNAsPTkl85MfIU!IvaUCzuZ0?>```g3p2qPbvAnw|BZhimeeM(?K8S}T=bld({u
zb4<+NbF(5y<7_^@6DDFXgAM+1ex>m)aSg%=zT(e$+)qwyLqC$nem!pEji3S}34gyg
z8Xky`<8+zC^<2{I=#^D4*H^b-&_fU)sBZC5A9t`zZ)9M{++`7ll%P{oO2zo`h^nQP{&iy
zYRYaMxW>QhgD`(Uo7+;_e5GSOHg!Kv;|8eBIj&Er-^9)NbOYAyNOt|wYa;pfSM9{$
z`So1!^TA-kettFU2D|?A$C>%;Hx?f3LLGR?1CNVl=jkzR+D`33*}Q_&nQeay+qR7r
zO0G}9*w5Mut$S!3vfI$yQR
z@fIh0z|(XJ`m>QB
zzgMMx2Q%{zU<@ZO*kJ|TdfTmWt9wRx7Kz5MIVVZ93G0A3hsHT7>>Rb=M7qDdBPIl#
zHGM6KMkJ$SUBmcejq^ckRb0prC9ro*q7DYMLC!03B(pu6tuxB*cW)9qiWjjW#=%nR)#!=*wTXp#UkOb+y63(ODz91Iu)9Q`marP*r}
z&_@V>O^H#&LlnKshb|KpB!UK|T~5(S4gN+pe%S$k0F*-jY8VF$+5{xZ!L`LTfcZ?n
zhhI-6I@#WVrpAw?1UTyK@c=BjwF+WM8g${p-f+%0T4xN1ki4LP$sYh-0%O3fOB_HD
zW%Nl
zb(=&7;n6}!W13VuY3Wxk+`D0_p)uNSwnX!A-(=J=?T4Cn5|O_YOurh+n)G{h4mHM6
zxpFff$4}e#!`k4b;lp=c4KFSfH1KXGUg)y}m!2HFyEXTfN6wprddmFA3yV;<0I#y$
zy%OcguDe^IKn-G6Z;E0{BBzso!uB`y@NwJ7*d&?Ep|7kq|Ec3vDrzPu=oFQiuAQ%#
z3ttlHS*=*;=Ef?I%Svv_E8FquIl_E=^HYo|iEA96%zh;_X7N%2u?GT)tpege?qw#Z
z*$SV}H1|H7>+%97_Yb)TI?jsn3JAnw1s6H!8=AS{;(UZC2L+!S+8z`^lzVy6XA`H7
z7T3^>JjKVFvwWB|Y6RwiiT(L=e9TZ1*Biv}N?Q!XR6{@N?_B1WXFc?v56xdE2hlFT*VKeKF^W_YT5+-(vW
z;O_rPF{O$@oe^89zK>`18*QtQx8`P0w9gS)4{aMgupwc^{;F`Ri@lNz!{YrM0@xG9
zFjQK0S>K2G`^UE9L@Ku4Fk}Bqa-TW7qCFRsEDHq&NUeclxrFq5yW12k(0V-H*JctS
z=Hr{6>Ff9bJ3$(Usj8f&aq9*y^GSnQat2Rft5qPJXkNd+%t28PDipbop8iw=HdrdemR{Qa@YrUVHGm{N+
zvT08?!-)>Y?wYjfO?@fPf5l1auDNQU)5hjGsU+E9)s!dt>y^gON`BdjfzzRllXa`(
zs2HI~rvXsCy#UrB&n(3p&w)W&&pbwXp*c&DNZts<{92x9iIRZzDQj2#r`YQnCQUuRz93BpPa@|j|jEPKR6G_}gR;|+yp);A!V
zaOw>|<(*b-_=S+4QKmdfN?GuNI>doC`_n%V>eH7)g)|RSt*X?mmibNDVmp*(3dgV5
z>pOF(JZ^FBtngHHXic`?uVma$LRdR2vE7S(7z+2~q7@v41r(t~*99{;QG?DCAICSp
zCZB~F?9U|ouu>fK=iHg5ShwBi95DwyZJW7E
z{r#~l!
zOnV09G$x(5&%Mylu=Cq>(5S=e1H
zw$C%cefyeug*V+vEP5xlZ8x!oM;xp(-hr41Og~FjgEpcUtz3g^&F)u_rzItB>-GH;
z)yKH*+5VnHiYC$9XMQHvTvq_}hJCh1H0{gBH*deCucK^ZXCq#L&{v^iqBTN+Da^P+
zdHag&`H#q)pBgYzNO-b2%EH8bmi6t`Bpt7)M)|0a$z-E_#+aQZmFBp%Ac{dMNGwXK}_r7GCP6;rGW}&MU=EjwEv1>!3z7irm|1bi(w#nfRkG$QHc?tICU+5*NvYq&t6h=wedgJ|^n96?%1%7sm2ogd
zOjgjkU1G4+4f-ScWGWdxHHKCN^}4>Wl~fM{;Ilo{#d=l5_9s*Mn$^Ygvk5r9l=n03
zxApi`?{#LAVhhF^df}r9@dXz49fi#)48O~Vy|RI>urbbyW{-KVrZgGBldDHe37QBRnL
zf)OB%37m2Z38)Sa%NWv$$x6bK_w+Of
zVF)nLqaa+~kFKHVU38xdc)qD_*2@0gasWARj
z8f#=_GtL$QTYl4dj_WWCt}ci@=}SX!hGsrPQR&SSM%?E4vp8IqZQ5rGukgk{8={G&
zRqJr0*R-3)$S0v7S?d?XjWr52RIsV%9a`yw6=bcrcV=yPZki<{P{ZVcdA8+6O!OPS+
zyxp)F`OnpxaIy*-lTVp&fw2k3D6l+UXJ#9gxFOS9n>diHNEHj5Al5g^DzD?nshIr)
zC1fymk2quGBFvPB&K1C{C`b-6*(n6Hk!PLjux<8zI<*4J%uozUTvgYuqu$?<-OeRB
zgv@*&!`jR|$BsPQnD<69=ZO>AeSCKJ+vAw?x{uG!dtKkD`?GpC1kCv7sX&?Qe(D;`
zToBs~%D~<4x*ZbW>bj-=f-qTtAEI2Y4;N
z?C3tIfJoo&ZY&CFa|DJGSeFnDMnV~4-W|=0^EhT={^sr5KQ3Sy6AN*>{AriQYB4U<
ztxdrq6GszFSR-{B(_~Kxne9!I;8z@36nB)qzSj61w6qgSY3lZOy#cCCVTyC_ssw&+
z!_7;@t#O~X#Y$d6I!(_-W`<0}dq2)6nsHN@{?f+IMqA?b>Hdz2@6&c4^wTu=V`sfv
zVe%uIt2?&qPV(L>B3ODXwCmR{bwaZ?h+9+Q>27?87(;SpZceM=s6l-C7}RY5a5EU&
z3O*Ol5x3VFy75d`-Nh?XDs+le*G5_ZIf?+J2$biJetR5qL-h7EqXHOs$E;NB0Y_eEy=PiOzabyQ-z`j{K@
z4A~
z{>g)&clP7f$8-%K>fT#FU`k7m9;sNL{Iv~8JFs)7_8o!oPlNR^%SQ-6wc2Mqu}O(B8`C+`(WwBt;V_{h5hB
zHI$xB{2PYc$2Hc|HlDy$(=wdtc-z}#=M`6X+)NX&?Q1CZz-~Hv{ra5V()dAdX
zR8#!vOQ8zSP~uKgA0{=!JF%k)fbpI}3K*lEL@SHkh
zmXnQDz+LWk_TS@U5NR5+V}F{el5Y?IB-&fk>78%Oh>6$=I)VYa90jdK!g
z!EMRONL?%0m&IpbFi-G^rqE8}`UH(42CGi?t=$(GtZ59&mj%3|o@+N#%{SkE_g9N{
z$Bsv{0u#q=y@!MM;V*#$?lqA6I{4eSEgtYw4s99!O@q%@y~cI8Ftz}`25za3x8UnJ
zLR)jgZf3n%fEMYQfDX}W4oKXd=1cDv{_Ev|3#c_Y9G9h}AAeEZ#BsZ!XJ9_?&-ei$7m1CN}a
zKa2{&YZt+F?QxE|M|D0jd?*-73=A+%|9AI$WMpyn45Ho@I6vn3;DFcdcfPlC=~Zg}
zodFHpem;*$-uLRC$G!A5fn_D(Jt#3ab0aiwlQJXTq4fYoz&HQ#+{7Pz6d_y`%3Tkv&lc
zn=4BK8KP<)iPRr~PQ*Qjpb8;K1zJ~+)cb#JUzPSm@;rtXgJ#u{{+bngqOUq3#uZ|s
z&n3#Ms>oLIn6VAm{D=V4pIrjeO>r8@T!|D3m~iZ?l2w~<(U0L+!HIgNqE0=?RWU%3
ziiISyilQnlQ|%-C_U-q7y=U-Ui!EH8EYIqT{p4A4V4JnAHUaU*53Py9gwazOL!aS;
zdP8QTjZq&@@<66-G})aPZR)fcOI2+$O0szzUtMR^A5!*T$@WDL{;(MhHFLJtz
zt^9lq34PPp>IBJI37#cuOKQ|f!mVZf3|L7Nrs$4t!|u<yc5
zPRl1PsvkCP5n1<UIM@+&rLa~;ZXmdw1AHVkY{L#3f^D7*tWS
zaMCcJ00ZDlTH>oJTN6BVr5vp?SSA$>tJ(2iv)bUQj{3xko@}}ke017ZE9gyUNWQ#3
zUr-yk;why?$eH^IbhQKPWy0pwt!qTDDX*l({-w@nTPeOSpqpoO7FJ4}&HEQR=+jtI
zi{yFwZmQL0h(4z3;Z+X7?w+D?{i%BCPGwfLCUp+oc#Y(@Z@>RrV-wxBkvKbvowA+&
zOfg@J{r$>HWR7-Iu&H8$p7*#F@dyY4X%#nX59<4SHf*F`r`7IG#lib{R-!YMzK^#t
z{k@Q|jy>0l1}QbfG)-)U>T?=8c}3#UitO^2goalIrB)5q4vCo8l@saM#wthaRCv<`f;OP>bmX
z`4M}NEg8$|9e{qo>SeD=E^eUg~6Vd3nDp}3BxZPupsJQ3nU|hlK?jV(AksE~aVDxGB
zSww9lAY}fY@mz7plt+rhyuT
zpz&(aQ%aH0Zr*hB!H-ivr_h{12yq<4tj0U3HGz#(yY74YKK3&^H&~4WG7h4iU%J2J
ze2i;bM4b1=c|P{TdY>5p&$3pn#7>{R#|Jt?K1Qsgk=?S+=Kde
zrMY@IxAS_YZ309|$Ed+XJ(C(wD?SSfbH#q6h3EJhG}-&mNv5A>$B=C|Y-p~ARA_VD
zzLG`m)fDWnbkzC~hOX3|D{R(lW9)<7a3e)@_S2J-z43>}S6|^^=g3MW3uOqvKcGLo
zp9#0qZu09yyMPvs*^z4e(y>>10^VAM7k3C{Ch*or&=o)1Z_^UhkJ_A9h`Uy*T!>}~
zlwC>O*ESbc47k|>zAwAnE$&3~vfK&5*MwYPS90;A#`G#dMt6Y}_N
zR`II1>nphDcX`iO)y<{`>N8yb69i&nY<;c9=jxnV-7I-9A829yT8UA=YMy;oKkepp
zOxBj^F*|Gj1d-Xv=lR-_Ghc$H1_Qve(UE1dGv8(GZ;mz4Tw4N3HF`?SSf~D0r7qX^
zhSe5Z{7$ww3N^)7`n@5i5mWw4CIIc;_iQ(PAJ!x{N!ys~spIs!!ogm#
z{&{vq#K4G-%g$BIgA9%@7n6ih@fvTs-+aG1rot2jI-fz0V}T{NS!ubstkZL6pj}Ut
zlyK9WGh}yKar(&%vLcJMNWXAI}uv7i%
z5(RKdZF?d{KJaYP
zH_B>sV+qXZSp7U>-vG)D*IVV66-%9~DMH6`%oTF9S~Vokfo8?@S?5b$Wtvk)j^`0t
zDHBUMT?StNh~*9ZU9#4F0$3w}&!^Z%FrO4fW2Qu=r^dj_y1r70G(~&9C>IQW`~8o9
zM^+I_-=@yS*NQ|`Xc$qdb{EyYyvCRqbt9{N#Do6{NSEwyNw%mjZgWWQEK^7GuC`U-
zqC`QCjG7k%g)t6FYq4F}wJ;MkYJ(FKXr+pFwaS-)+(qmYabpouYdy9=af!({LzX*6
z`zZVlL!950waBbmS!`bOd0lq*dAG{dJfha-XS#`wsBaee#S%b^+W{?I_;a)YjqINRcX*=s?cqK#3Dpg
zfYyll%%Q=Fqhju*^<*FlojkiJ1X|xin3(w6?|=M99~5K23Q?IJ&7S2piA#Hl#?GSa
z=H2TOU#t-F-gR=#z&r^nQAPqnvelN1V|9K`_3s(wVP|pE);v)gJJAPmpf40T=*?3&
z7wui4f}WUL2rio>x|ZA(>b)Z^l>C@1%54^Iq$DTjTx
zfsNq!-535SXk-x{+#z?Ea?4MXWI9M}N?F_)A(N7;mCf}th=*2^!zN*=c7tsCYr@{Q
zN_qU!5Z23Gg4haH}`6}Cawz{(9Y;sWD50B?w5fZSs{aLoN)>+g_yS_cMh8tSa!(}?^QCW{!Rbr>>u?c}x_wr`>a_(1%HY3fju5F@umB^_5qv8QWHfX}x6h
z1Yb4!X3=HbXI_)r=tL)a-sD1n`hrN`JBYSrEQuV&)^xT!Cv1xo)NH#y(EmORtjDs~
zQ$O3DvHo|32nSvI%zY4hOrTav^n1K89n7e9pR(#tb5Q4G85!_Y<3Y7ZfD4wmB_&v{9LL
zA81X5YmnUw#0dvVGNIGT9I${e>Ia!s+hpUs^bNEA_hX;enA6LM$%z2`^pB~pMQW_)
z(6?Yj2~v;DvVy_DUGa+Y(B--v8J@N9P(zmP!~@uY|5s8Mzn1#%sT$T0wK2-BUKJA<
zL)9u6bjYWKFI`sqGu~=){Y*vmW#N&eKVXTN6cr5C_18C;9_+wXt+_mWhdDS$E+E||dPtI$jb*LPHrQ8B~TW=r)G1UDi2PLpI6L*uPLnf
z%=tvKkmPQm#XKwJbw8ipH}3|(+JIcOkaq^{XUD^L)U=59ikGLx&3d)N49BB|MQqxy
zUqa&YRf|fuFw189t{`cvBq6UbP+#4~)8fua9rZMSh6aY{E^Fzl#_^Y0!(K55x-m&K
zucD%6eVIBL6GwH*==jldXPUdVqWVa*Qas%lkNn*aKmU^``bPW^d^-Qo-#HAyig`r=
zr)G9Ai->S?kMoO1sgV&n6Oq7xN6d;PP#te@WBVEV&w)VMqdxok-aa(FH
z^~x+r_e4a(pnY8Dx_=HFV!=4wrdVgiv?b|&KgWT)j&E<>w7xdp*V11#y}e>PEIOP-#*d
z+fG*81akh`AgkWgyW6j{@Q|S}wBT)k`|g`NtIU38{?^9GaEhotksU~k^=91k|CjWF
zRv_KoXBjEgxmxGcv0
z1-SUXpzV|OD;OcE(MmD!Jn=TCOrmuNG19s@b;xBDdl$u9UBgzy!afas;O~C;`QKlJ
z_US8wd#7ow)L2j}5HB@w)o$(h#E@Dvl2%LpR~|ndDiZnLv3)=xQ#)j@ljB8C+BsBp
zXup;sk=gZ}gfn-cKTkM|eQJb1lkTu{u5Zgw-9VrkhaxY(uaVj8hymfCnp5cS^j#z&MkIoI0s=DW@AIXB
z>QBZ#r`bUQsztQ63ISSnpo?;m*9h5Z8t64OwI=v3K};{FNh6;g#rDXvMtI$Q{k8n{
zFVqz++K+SCJ-4{)UnsdkXVtAETCbe__hY~N;phM01)DL^8tKYP9CKoEPh&_`9B3+=
zxl^b45k}9HwQvGysn1}RZDL4;Z1)w*zi2~KdGT5C?N^NdUDY~Jf;&P0D$e-i{4`s7
zLOeuG6~d%);nj0vhbKW-jSLY3ab>DRgUTnOpt}M2|BL<>N#@w<+C;RL6u8t!h(=d^
zzS2i4y#6K1JV0BQrF-3m%npzZ$2yc2hG;cYuQ96hUBgUEENlkEVff;WUWGjM0=UXAI+lpOxx1H
z2wm9(WN~eo_QUGjdIsYC2m|L;{W#5>e*djsGz
zywshz1q~Z;rOtI_G42+A`ihL4Rpzmsb60C&Cn&|lE9%O#p7CyWG{Qf6;ok9dR~P-x
z*w{%vntG?Zy6<0ufx5d`uU>-|5y};Wb7!1ClehJmPRFyQ>m6!2Az`M)IrZr|aBp-9
z1-+w&w*V87gp~gG<8DzR|Io~b3$~zuOOzwKvO8VyMpV2qlQVn2{$V=cglFE5zwdiL
zPkqfhHls*N*=O+4)kf!Y+VA```giV=Vd8UTpP%;;5;?AZWad-?&bHP4j5d{-leBW5
zEowJ~yG@SkeeUa=-|KO6_gB0xyLNmZf4(pMIC;OPqVN=k?`GRn-&f3MB6xzw_Pg(Q
zAK=*IOk6&Rmj^9*cR+}PA92u;yH;RNW4F*`jGRPP%2wxh0G%HF9fM~GIS9#OY#2kS
z(G8mB{&brdTAZi6Bl_A0cn)6laP{#=v2jfd3T_N@TG-ssH7R-D6-|zbp-(g`kv%rh
zSM*NPcIL&uDH$86tv)O%mcRS)SO1Y|xIE1?HY7T>N>k0hTlX|igJn%ot+VDj=uyA>
zy%A|+U>#!qD0s2%r#%$MerE)?CRe_UkjX^sv*B)oOv-!a*-@-=<+TjSbIN=I*CyJKNa=HT5?xn3)(Hyu3bb+;1}2)36HV5bXUop0
z@nENnrk$tzCA3dofpkv#c0x$ip)?b|m2DzBZ2<5_<4j=jRfvANDbthi$(M|=K06S1
z30Wo{)C#Et5BqpEneUl)|JdY9FPhwsM5HY~Lso3$JcePR69p0STx%`gnzfpn
zxX<)+k+~KZi%~~C6^+4&m?b0w#(2~j)K!7MfC`lx854&*-Ds6Zel!AjpX;BIuV>Wg
zV~$`6d~T19WsVj?F|+s1QN#Sa4825sX3y0qaK6@vsy47_<^8vA&-Z>1XT0Naa-YZQ
zd~%56WFKMEpSsVoap#ZK<=23JChd3Rz*P6n`ph~@8tv!P09c79tyqX(GS2f6*PW`Q
zbty-45p44i4@QeCl2hJNM!q6;CU+lk8wUC;M~?KOzJs={qo31jIZ_o84UUCZU8tkx6G(%FnlLpvY(&LiJ
z9jbf70(y5(qx9mGb;K9T6Ob27+E4e5Bz-7Ab`TYg>vu_a@vKQ#^v>M1(*BxcEE3IF
z7JvjIC)e}E+GZ{wKiClKx?=VV_i%QJ11l1FO4%_n`Wi?is$#n^iYCP5Rru^(xBHTyMBh__N*lKitfX-3afV#o~wrYlxnTh
z09Y+$GMi^%K8D4n>CLZ!Qyz_~tul>dq)fQyr{Rt2{sgp1)9ZlDFWrZkrgQq-NMH5E
z{jwY4sJxn0o(Z8mi*FQW^2{slVJBmw8Y|n2$P1vG_7dV`;F1Lh_8V{(CWy}px5AVm
zYZQ7+;HqluymY>7Y@9^1^5-cV>_ky@mwtCwMC_F;enhiS?KE#~qQW>acuItazyI-<
z|75oJcXOvRhSFyg;P^ESTkfA(K&)HfwWF@rU`f^oz=npLWn}n!qL&@EzMVCH+E1Cz
zw+8{by~?xsk&|tOtn1{Q7I0w(iD({7LJf-OtA!G_z%J^-0N?-}G36SW^hsJ`j{p>R
zQ3$Siy>+qN&=qg+P1^zm8SB}{*QEg_z1;e@>$03XDW
zcu1NJ1y*o4$za2nY1S-J&y>hk7&bn~!gmJGTUpzLy$`&Q!0-LJLNeyV^hk4t;B-4}
zGBX2`Lx2+0F>E1ZHhjidKVGDmD4aWQl+ZW^L|mWD-~af_KW!|LNi2wHw9-K>Yw+%z
zA#gJEOG
zAn@$y$#f1l-mV$yXtB$>=H!Sz3dZ3LhGxS6q!8B*jnh?bS2k}Qm*U|*w<8K0D?ZuI
zu2}JJGP(MArITcCOe2moIBq2>YHAG5NZKY_pCE
zbaABh!o&6YwF7cb3iHs~64x2DqWE3CT2~jSsC$TY2HB%Bfy|)EbRi7tD20B6^sfUq
zGG`N*=qcyNq|M>=8YpUO5IRO8vLo&p5TY1(G=N?NIfR-FBFo?Z^vi$xq|@Z{ji)^H
zoS;7)-f0V@{6@Fu@$+~)3z@CKBzc{eS@%gTGwI9KX6B+Dr~)uKy97;j7bh_frvb2|Sl2zwGd#{;T48Vk@$S%hPA2=a?f#i<`85jlbQ!)Y;jJAW^k;M$CUfem
zNs`@|Kb>PR-56e_6+kpgx?M?#T6ZFzX=iT=XGke>p&~1UMH+Ja~?y6g`cDw{KV+a^Ak-uVv0VS^PlC&HpW*}5g3T`d~5oC;AN`VB2(ZS#U^vi$t
z0h66+rjj=CvWVu{+qAIIjP$o@O_%*kGhD6o-#ma)Z+4Y8v9gJ-WGB*K(SC(t`cWbx
zujVOVVT`NVcY@EZXb8ySy!wo`r@^|w3+vO)`IAbZRq6E{jq>zT(|%aPvbaQ-_RyLs
z?jlL%VGP#J4b_QLhWJ3H`$y+A^kcjV+YjdrfB(}j|BQl>a9>`Utb7-Ueq?kpDe5L=
zsJ`FRWuuzEZ*JCy)^S2;Mpt%?&2%N8JFU;>K%h4Ndy+sSZKWf=F1=^rrVD{O26v>>
z;m4oV`Fq-vWLmNP@zfoxv}Nv;ng~K1NjVSFTp*(QsUGJ&i
z%g28ysVqU`0=1D#ZVuPW_6FB46M$-BTcwpoNwu#&3FXuwGr_cVWAL*K?Rt*=!3m89
zk!xSSo*^m=f2{8}SBX+3Gq12F!~Q^t{G9k+phAw4zKQz)|M1hV|5>qOs97<}94(Bo
zH5+e|d5W&}*aTOu-_JtxVv-UpW9OC2Gw+NRmiNt=d>gw?j+
zRjebsX>+k6rTj;Ovg?%!hq1eavgLOa0*kgRt3IX((?rd&;zC-9dp0n9l~teV9CUIc
zNMj)w7ONAmp(IJK*`P6q)+1fR256AT+;Cil0-iyF()@!BEFw@)2pBU-1shyP7*sF1
z_J`xS=#Q@I>bec{4?q3-pM%tq$OLZ3y=NiEGlWA-hFmlPGl;W`H4%(|NXQrVaU%=-
zNa}*e3}F0s1-DEBA5!F?qZl3nvSR#*6wC8DJa02yy`!=vMX@Ekuju-GS2IgM22Oyh
z;$2y=(;>GLxtpF`fj}X2i_gjM`^m~uxC-4aqTPC*F6?JHYQt(*l%&ly3==Fcms$-8
z3lJ>8gwu+vcBc&)KcX4Ob+%CRfVGdJO9+Vvz+6D}%AwAjumu3aTCPu!`?nMRcxBk}
zBWgY;LPop!I}=!aQuWZmjH?1uUxQ4tz3~q}|N5WPoHdDpoC$y6gMSRuKVE}S+Dm>W
zPL;v=*{e!evCwD01oVJDNC_{~0}7FnG8^NmGU$RS+h3{2x9AddS9w*2el?F{!Z37M-u**S3RLxE_gSl+$spF2
zTO(0(8c;~HAX9CwQ6R6whs_|H4?9^xYA68Lkx!@eROga{N!>lO*9eTXX$%=E7`!ho
zOv}xidLd%a*V*x0^c6wGEi>ORzrw1omQPK@LqJ4E~orQtWn#LlZ#x)V6Sc~LT#%n?25Lo{RP-{wp9ixT9H?Uh5l84l!oaK
zKmX>xXizryOej9<;~W`#*s`W|h4Ourr8hL#%edPl6PuFS(ZUf3tdhL2(A);nj;L+-
zeO7z_y4vzWH4PvpSvY0QisgVdS|zfrXj_ES^&h7J@L45m6S>-H3E?38xJ@WQFJ8P?V?|R4KxR$7s_kGS)L8XkWM0lHd4<`GSoNgqD^NO4PIYPY2#cc{$W};
z*;py2vetCJ5Er%*y7zVBgpYEtcafI9*8S{vAdwkKc07WN;2FcH79}Y_U>atmfm9!p
zeFt3;zS~>Cykq8Yy}O?j&S(k@0DC3t_dV}-eg~@eCA+4?HkF8+R@|2yxFYb-`r+r_
z{Fj??im8VMQf{L4HR9_t=YMyf+wW%Wb%quhP8mtwfz`bdUQ+j+KCkkc
z?=~WuB^pxLkkRws?>6D6;LCuREFrI8;>GNw2m!q<`X7G&&3{GfgdKat1+U#?cbaTf
z)|VC*i)qMXf*|aWpsYy8ezc)8ZSx6f_XGl@1-E=m6h4I7CMeO)T-fcGSB&x1zo%gl
z8o1uO=v)i2f6&iI&7V~rnN|3SUo=;zFxN9Ii(m5R8HwKlnU-WNN{72HvE(`z*Pv_4
z*$WU0y$#KAEe|&g(>|N@scejal_~@-P!@Cz{aH4aeP5xm-zAbBjgia4KBO1)
z%aliAWn-mgeWHOw;D4{?+eB)JKtE58-C0*?anA1aS%)4@)Pr~O3l7l7{<;U*{J6uR
zWWIX(aL2JlJYlo3H4;*Lgs~bXf+6_b0N@C#kcbE~UlZ4&HbTtIk7E=6jhnsI^ywK2)+;IqaW5etWj1Fm84Np}l&8k*RXK+m3W8!#r?OqwQL&J!{
zeb~*3Y`pN~T|hsy1W+ZK#y|Z0n}5OFXVly93;s+Q1U$SJ&JcYhL~u-;P<8KNbAR0a
zZt&tdX44rL^B
zu_}8%+;~Kt*gO5{_3~?^Aa~6wZ@{5=bhtK8lIcx4?0Y!N(A4v3PBK1bgtPQ4+J4UTM=9L)^Ky*zT}k+9fjF>lMf{Ee)s_GL;OfeVpy_l_kb
z5_#-3xThQfgAk(k(a)-p%M%gI);ohB>dgAPgLD@CnTe0H?%zB7URltDswPp8Ng$jx
ze`c(+s&GKr@%DGcC1H{vSxr_{DS-y5BozY;GUPd2TXUM+6%uNNSD)Exhr5mS*x@8>
z?iV88HhEj+iy#co3%U2Ah|;z8Kuf{RKmO{s|6;?k{!>WQh|e4|B0a$|4Y>f5tW{WF
z&u){N)|yYCu`suhHz9)8fgbglAB);aZAx5RZyFQ5mM3o{g3S|N!#$6HcP))iegBhr
zanoo3X+W009k+MW2eBkX84!z5(Ml=20~!SY03ZNKL_t*UN;20Z0qxqn6Et!vpWUum
z6D0GQbx!6Typn@3tAx6<=DX0zv<`CW>Cg9xIG_v83RP86c@O+dHNM&O=Wt(U9IWqG
zxc{Vt@rhPALo6C<+3bG&)o=eBnk5%avmc3O+13*{up4~SK|ZHCo-Hz8D)V6tFXLft*%osvn~o&FoNBT?LT6*U`ZJnFYzi&v!H8`N{jPd-#1Q
zW4hs1?}Wxvmeiw@R;p`ebFXTnF5JTl?b_*R=i6
zamVmlyfDXhs(U)ae!6*goAd!b&-(ai?tOskpzLoNoQqPmar$*M2(pY-{qW2blSddQ
z4WT3}pUuh1-r&WJjGwKtcYX4Y|J`3R>*&K77_2hfG)Vw^JzjS6kFkz$Hc%P$7y7%J
z5Y3|FpGRj-$E<6PYf%L1JyQSvdeTw;xZ8s~zY_GS9Q0!wKM>kBc($^*bL-zTLt;e5s=Jz0NchOBE$onzx?mSk{0L4YQL{LTrRIT3V4((rfM(hn|j$@Z8F_6Tb%bpR>
zy^}ZggOLvqJu`h16qmNY`9rg
zWj74aJfga-s<4VjEWHvfDTB7$(EUI^1`Ev8Ab56jU4_vn*O+8gPmGf)G=umgjzL(3
z8)Io|NUS2Nlm6f$)YBO&sNJ7nFdg^7lsu|Kr#mKEgq#x1ctTdfl`Cjm_1$VkN{8B-
z@87N$3n1~e-fK{TldfSSxM3eb)MxA-%U_Ry=`HOF2cbTnowl1?b|62VK_ABul(<`%p<&L%AvIE5
z8*>72$3E7%>2Y9sx&)nw<8|-IE8OwpT^MQPX)p44e*@NSbT1&R^xW>c4coK!{oMj&
zGKmkDN$pTx*IqUY*e)8H>;3*41^#qqv(A3T8&j2eOhkri7E{-19(&6v|Nfstx=dtK
zBd#dy>JczKaF3{_Y=+h0P^gR#0wC6sEZqJ)%Ay-SeLF)!wQi3?wk0uMJVyl-_A3l8
z!x3_}@sT4KXCE5XR>tUQ5FX@aKRO~hD;aMF7nuW`Ak5&JoH-#(##&xeTQ)~%-sp$W=G&Q`(#0T!QJIxQxL)#UZ=F6a;-|
zdxI!SNRz`6(Ri>uE@k`iXy!8<6VD0=TU?VDYGS6sQbhC0tx0~#iU{BRia-7GyMHM$
z5ILeXOP)xI49IC?K!bwabk>=Bl3;WwlhEnDuCO(A8_mi>|LkV)r1vx~{Un-IJXFu~
zjQG)H>0GfLyJKFtN$(gryZ51mu}o>7hzs6=#=z-pFyQ
z#I$-7bUgRXgA1sOL&iLz_>4bQ3o5W@T42CSt`KQYUIr2v%=7VM-kJZE>3Stq`p<6+
z@aFeXpHrl=GWS(T%cUcruOrHIe!T4cJSXmY-di1WUNd1cVL9JLo$JkYO(=Kh<5cLK
zof}YOgW5!5yUsCsR)?8s7b2d=k=M!K?h@n9@S46qT|Z7eW77R|wz+>+_xqua(_`Tp
zqc?hGM9HaXOO(Kd-iLu}XZ*tVlp6`h-!twSkEF*Rv*lb8o2=u?NWvHsKljua&&ICY
z1MYEe)_5