@openglobus/og 0.13.7 → 0.13.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/css/og.css +388 -129
- package/dist/@openglobus/og.css +1 -1
- package/dist/@openglobus/og.esm.js +2 -2
- package/dist/@openglobus/og.esm.js.map +1 -1
- package/dist/@openglobus/og.umd.js +2 -2
- package/dist/@openglobus/og.umd.js.map +1 -1
- package/package.json +20 -19
- package/src/og/Globe.js +15 -16
- package/src/og/Object3d.js +417 -0
- package/src/og/arial.js +1705 -1703
- package/src/og/camera/Camera.js +640 -640
- package/src/og/control/EarthCoordinates.js +1 -1
- package/src/og/control/GeoImageDragControl.js +102 -75
- package/src/og/control/LayerAnimation.js +383 -0
- package/src/og/control/LayerSwitcher.js +506 -159
- package/src/og/control/Lighting.js +27 -27
- package/src/og/control/MouseNavigation.js +460 -460
- package/src/og/control/RulerSwitcher.js +69 -0
- package/src/og/control/Sun.js +170 -170
- package/src/og/control/UIhelpers.js +146 -0
- package/src/og/control/ZoomControl.js +0 -2
- package/src/og/control/index.js +5 -1
- package/src/og/control/ruler/Ruler.js +43 -0
- package/src/og/control/ruler/RulerScene.js +374 -0
- package/src/og/control/visibleExtent/Segment.js +3 -5
- package/src/og/ellipsoid/Ellipsoid.js +19 -0
- package/src/og/ellipsoid/wgs84.js +1 -1
- package/src/og/entity/Entity.js +1 -1
- package/src/og/entity/GeoObject.js +1 -1
- package/src/og/entity/LabelHandler.js +6 -2
- package/src/og/entity/LabelWorker.js +38 -53
- package/src/og/layer/BaseGeoImage.js +347 -312
- package/src/og/layer/CanvasTiles.js +312 -290
- package/src/og/layer/GeoImage.js +222 -214
- package/src/og/layer/GeoVideo.js +291 -291
- package/src/og/layer/Layer.js +94 -70
- package/src/og/layer/Material.js +109 -109
- package/src/og/layer/Vector.js +81 -14
- package/src/og/layer/XYZ.js +23 -11
- package/src/og/light/LightSource.js +364 -363
- package/src/og/math/Vec3.js +1 -1
- package/src/og/math.js +6 -6
- package/src/og/quadTree/Node.js +8 -6
- package/src/og/renderer/Renderer.js +2 -3
- package/src/og/res/images.js +0 -2
- package/src/og/scene/Planet.js +106 -44
- package/src/og/segment/Segment.js +34 -64
- package/src/og/segment/Slice.js +1 -1
- package/src/og/shaders/drawnode.js +1 -1
- package/src/og/shaders/label.js +30 -42
- package/src/og/terrain/GlobusTerrain.js +31 -20
- package/src/og/terrain/MapboxTerrain.js +1 -1
- package/src/og/utils/BaseWorker.js +46 -0
- package/src/og/utils/FontAtlas.js +1 -2
- package/src/og/utils/GeoImageCreator.js +164 -161
- package/src/og/utils/Loader.js +187 -153
- package/src/og/utils/NormalMapCreator.js +403 -412
- package/src/og/utils/PlainSegmentWorker.js +29 -55
- package/src/og/utils/TerrainWorker.js +572 -589
- package/src/og/utils/VectorTileCreator.js +1 -1
- package/src/og/utils/functionComposition.js +13 -0
- package/src/og/webgl/Handler.js +42 -41
- package/src/og/webgl/ProgramController.js +143 -143
- package/types/Object3d.d.ts +22 -0
- package/types/arial.d.ts +1 -0
- package/types/camera/PlanetCamera.d.ts +4 -0
- package/types/control/GeoImageDragControl.d.ts +2 -0
- package/types/control/LayerAnimation.d.ts +73 -0
- package/types/control/LayerSwitcher.d.ts +55 -11
- package/types/control/MouseNavigation.d.ts +1 -0
- package/types/control/MouseWheelZoomControl.d.ts +1 -0
- package/types/control/Sun.d.ts +2 -1
- package/types/control/TouchNavigation.d.ts +1 -0
- package/types/control/UIhelpers.d.ts +13 -0
- package/types/control/index.d.ts +3 -1
- package/types/control/ruler/Ruler.d.ts +13 -0
- package/types/control/ruler/RulerScene.d.ts +48 -0
- package/types/ellipsoid/Ellipsoid.d.ts +8 -0
- package/types/entity/LabelHandler.d.ts +2 -0
- package/types/entity/LabelWorker.d.ts +5 -7
- package/types/layer/BaseGeoImage.d.ts +9 -1
- package/types/layer/CanvasTiles.d.ts +5 -1
- package/types/layer/GeoImage.d.ts +1 -0
- package/types/layer/GeoTexture2d.d.ts +1 -0
- package/types/layer/Layer.d.ts +28 -32
- package/types/layer/Vector.d.ts +9 -0
- package/types/layer/WMS.d.ts +1 -0
- package/types/layer/XYZ.d.ts +8 -5
- package/types/math.d.ts +2 -2
- package/types/quadTree/EntityCollectionNode.d.ts +7 -0
- package/types/quadTree/Node.d.ts +1 -2
- package/types/renderer/Renderer.d.ts +1 -1
- package/types/renderer/RendererEvents.d.ts +16 -0
- package/types/res/images.d.ts +0 -1
- package/types/scene/Planet.d.ts +21 -6
- package/types/segment/SegmentLonLat.d.ts +2 -0
- package/types/terrain/BilTerrain.d.ts +6 -0
- package/types/terrain/GlobusTerrain.d.ts +7 -0
- package/types/terrain/MapboxTerrain.d.ts +8 -0
- package/types/utils/BaseWorker.d.ts +14 -0
- package/types/utils/Loader.d.ts +4 -1
- package/types/utils/PlainSegmentWorker.d.ts +4 -6
- package/types/utils/TerrainWorker.d.ts +4 -6
- package/types/utils/functionComposition.d.ts +5 -0
- package/types/webgl/Handler.d.ts +4 -1
package/src/og/camera/Camera.js
CHANGED
|
@@ -1,640 +1,640 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import * as math from "../math.js";
|
|
4
|
-
import { Events } from "../Events.js";
|
|
5
|
-
import { Frustum } from "./Frustum.js";
|
|
6
|
-
import { Vec2 } from "../math/Vec2.js";
|
|
7
|
-
import { Vec3 } from "../math/Vec3.js";
|
|
8
|
-
import { Vec4 } from "../math/Vec4.js";
|
|
9
|
-
import { Mat3 } from "../math/Mat3.js";
|
|
10
|
-
import { Mat4 } from "../math/Mat4.js";
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Camera class.
|
|
14
|
-
* @class
|
|
15
|
-
* @param {Renderer} [renderer] - Renderer uses the camera instance.
|
|
16
|
-
* @param {Object} [options] - Camera options:
|
|
17
|
-
* @param {Object} [options.name] - Camera name.
|
|
18
|
-
* @param {number} [options.viewAngle=38] - Camera angle of view. Default is 30.0
|
|
19
|
-
* @param {number} [options.near=1] - Camera near plane distance. Default is 1.0
|
|
20
|
-
* @param {number} [options.far=og.math.MAX] - Camera far plane distance. Deafult is og.math.MAX
|
|
21
|
-
* @param {Vec3} [options.eye=[0,0,0]] - Camera eye position. Default (0,0,0)
|
|
22
|
-
* @param {Vec3} [options.look=[0,0,0]] - Camera look position. Default (0,0,0)
|
|
23
|
-
* @param {Vec3} [options.up=[0,1,0]] - Camera eye position. Default (0,1,0)
|
|
24
|
-
*
|
|
25
|
-
* @fires og.Camera#viewchange
|
|
26
|
-
*/
|
|
27
|
-
class Camera {
|
|
28
|
-
/**
|
|
29
|
-
* @param {Renderer} [renderer] - Renderer uses the camera instance.
|
|
30
|
-
* @param {Object} [options] - Camera options:
|
|
31
|
-
*/
|
|
32
|
-
constructor(renderer, options) {
|
|
33
|
-
/**
|
|
34
|
-
* Assigned renderer
|
|
35
|
-
* @public
|
|
36
|
-
* @type {Renderer}
|
|
37
|
-
*/
|
|
38
|
-
this.renderer = renderer;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Camera events handler
|
|
42
|
-
* @public
|
|
43
|
-
* @type {Events}
|
|
44
|
-
*/
|
|
45
|
-
this.events = new Events(EVENT_NAMES, this);
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Camera position.
|
|
49
|
-
* @public
|
|
50
|
-
* @type {Vec3}
|
|
51
|
-
*/
|
|
52
|
-
this.eye = new Vec3();
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Camera RTE high position
|
|
56
|
-
* @public
|
|
57
|
-
* @type {Vec3}
|
|
58
|
-
*/
|
|
59
|
-
this.eyeHigh = new Float32Array(3);
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Camera RTE low position
|
|
63
|
-
* @public
|
|
64
|
-
* @type {Vec3}
|
|
65
|
-
*/
|
|
66
|
-
this.eyeLow = new Float32Array(3);
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Aspect ratio.
|
|
70
|
-
* @protected
|
|
71
|
-
* @type {Number}
|
|
72
|
-
*/
|
|
73
|
-
this._aspect = options.aspect || this.renderer.handler.getClientAspect();
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Camera view angle in degrees
|
|
77
|
-
* @protected
|
|
78
|
-
* @type {Number}
|
|
79
|
-
*/
|
|
80
|
-
this._viewAngle = options.viewAngle || 38.0;
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Camera normal matrix.
|
|
84
|
-
* @protected
|
|
85
|
-
* @type {Mat3}
|
|
86
|
-
*/
|
|
87
|
-
this._normalMatrix = new Mat3();
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Camera view matrix.
|
|
91
|
-
* @protected
|
|
92
|
-
* @type {Mat4}
|
|
93
|
-
*/
|
|
94
|
-
this._viewMatrix = new Mat4();
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Camera right vector.
|
|
98
|
-
* @protected
|
|
99
|
-
* @type {Vec3}
|
|
100
|
-
*/
|
|
101
|
-
this._r = new Vec3(1.0, 0.0, 0.0); // up x n
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Camera up vector.
|
|
105
|
-
* @protected
|
|
106
|
-
* @type {Vec3}
|
|
107
|
-
*/
|
|
108
|
-
this._u = new Vec3(0.0, 1.0, 0.0); // n x u - UP
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Camera forward vector.
|
|
112
|
-
* @protected
|
|
113
|
-
* @type {Vec3}
|
|
114
|
-
*/
|
|
115
|
-
this._b = new Vec3(0.0, 0.0, 1.0); // eye - look - FORWARD
|
|
116
|
-
|
|
117
|
-
// Previous frame values
|
|
118
|
-
this._pu = this._r.clone();
|
|
119
|
-
this._pv = this._u.clone();
|
|
120
|
-
this._pn = this._b.clone();
|
|
121
|
-
this._peye = this.eye.clone();
|
|
122
|
-
this.isMoved = false;
|
|
123
|
-
|
|
124
|
-
this._tanViewAngle_hrad = 0.0;
|
|
125
|
-
this._tanViewAngle_hradOneByHeight = 0.0;
|
|
126
|
-
|
|
127
|
-
this.frustums = [];
|
|
128
|
-
|
|
129
|
-
this.nearFarArr = [];
|
|
130
|
-
|
|
131
|
-
this.frustumColors = [];
|
|
132
|
-
|
|
133
|
-
if (options.frustums) {
|
|
134
|
-
for (let i = 0, len = options.frustums.length; i < len; i++) {
|
|
135
|
-
let fi = options.frustums[i];
|
|
136
|
-
|
|
137
|
-
let fr = new Frustum({
|
|
138
|
-
fov: this._viewAngle,
|
|
139
|
-
aspect: this._aspect,
|
|
140
|
-
near: fi[0],
|
|
141
|
-
far: fi[1]
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
fr._cameraFrustumIndex = this.frustums.length;
|
|
145
|
-
this.frustums.push(fr);
|
|
146
|
-
this.renderer.assignPickingColor(fr);
|
|
147
|
-
this.nearFarArr.push.apply(this.nearFarArr, [fi[0], fi[1]]);
|
|
148
|
-
this.frustumColors.push.apply(this.frustumColors, fr._pickingColorU);
|
|
149
|
-
}
|
|
150
|
-
} else {
|
|
151
|
-
let near = 1.0,
|
|
152
|
-
far = 10000.0;
|
|
153
|
-
|
|
154
|
-
let fr = new Frustum({
|
|
155
|
-
fov: this._viewAngle,
|
|
156
|
-
aspect: this._aspect,
|
|
157
|
-
near: near,
|
|
158
|
-
far: far
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
fr._cameraFrustumIndex = this.frustums.length;
|
|
162
|
-
this.frustums.push(fr);
|
|
163
|
-
this.renderer.assignPickingColor(fr);
|
|
164
|
-
this.nearFarArr = new Array([near, far]);
|
|
165
|
-
this.frustumColors.push.apply(this.frustumColors, fr._pickingColorU);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
this.FARTHEST_FRUSTUM_INDEX = this.frustums.length - 1;
|
|
169
|
-
|
|
170
|
-
this._currentFrustum = 0;
|
|
171
|
-
|
|
172
|
-
renderer && this._init(options);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
checkMoveEnd() {
|
|
176
|
-
var u = this._r,
|
|
177
|
-
v = this._u,
|
|
178
|
-
n = this._b,
|
|
179
|
-
eye = this.eye;
|
|
180
|
-
|
|
181
|
-
if (this._peye.equal(eye) && this._pu.equal(u) && this._pv.equal(v) && this._pn.equal(n)) {
|
|
182
|
-
if (this.isMoved) {
|
|
183
|
-
this.events.dispatch(this.events.moveend, this);
|
|
184
|
-
}
|
|
185
|
-
this.isMoved = false;
|
|
186
|
-
} else {
|
|
187
|
-
this.isMoved = true;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
this._pu.copy(u);
|
|
191
|
-
this._pv.copy(v);
|
|
192
|
-
this._pn.copy(n);
|
|
193
|
-
this._peye.copy(eye);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Camera initialization.
|
|
198
|
-
* @public
|
|
199
|
-
* @param {Renderer} renderer - OpenGlobus renderer object.
|
|
200
|
-
* @param {Object} [options] - Camera options:
|
|
201
|
-
* @param {number} [options.viewAngle] - Camera angle of view. Default is 30.0
|
|
202
|
-
* @param {number} [options.near] - Camera near plane distance. Default is 1.0
|
|
203
|
-
* @param {number} [options.far] - Camera far plane distance. Deafult is og.math.MAX
|
|
204
|
-
* @param {Vec3} [options.eye] - Camera eye position. Default (0,0,0)
|
|
205
|
-
* @param {Vec3} [options.look] - Camera look position. Default (0,0,0)
|
|
206
|
-
* @param {Vec3} [options.up] - Camera eye position. Default (0,1,0)
|
|
207
|
-
*/
|
|
208
|
-
_init(options) {
|
|
209
|
-
this._setProj(this._viewAngle, this._aspect);
|
|
210
|
-
|
|
211
|
-
this.set(
|
|
212
|
-
options.eye || new Vec3(0.0, 0.0, 1.0),
|
|
213
|
-
options.look || new Vec3(),
|
|
214
|
-
options.up || new Vec3(0.0, 1.0, 0.0)
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
getUp() {
|
|
219
|
-
return this._u.clone();
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
getDown() {
|
|
223
|
-
return this._u.negateTo();
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
getRight() {
|
|
227
|
-
return this._r.clone();
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
getLeft() {
|
|
231
|
-
return this._r.negateTo();
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
getForward() {
|
|
235
|
-
return this._b.negateTo();
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
getBackward() {
|
|
239
|
-
return this._b.clone();
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Updates camera view space
|
|
244
|
-
* @public
|
|
245
|
-
* @virtual
|
|
246
|
-
*/
|
|
247
|
-
update() {
|
|
248
|
-
var u = this._r,
|
|
249
|
-
v = this._u,
|
|
250
|
-
n = this._b,
|
|
251
|
-
eye = this.eye;
|
|
252
|
-
|
|
253
|
-
Vec3.doubleToTwoFloat32Array(eye, this.eyeHigh, this.eyeLow);
|
|
254
|
-
|
|
255
|
-
this._viewMatrix.set([
|
|
256
|
-
u.x,
|
|
257
|
-
v.x,
|
|
258
|
-
n.x,
|
|
259
|
-
0.0,
|
|
260
|
-
u.y,
|
|
261
|
-
v.y,
|
|
262
|
-
n.y,
|
|
263
|
-
0.0,
|
|
264
|
-
u.z,
|
|
265
|
-
v.z,
|
|
266
|
-
n.z,
|
|
267
|
-
0.0,
|
|
268
|
-
-eye.dot(u),
|
|
269
|
-
-eye.dot(v),
|
|
270
|
-
-eye.dot(n),
|
|
271
|
-
1.0
|
|
272
|
-
]);
|
|
273
|
-
|
|
274
|
-
this._normalMatrix = this._viewMatrix.toMatrix3(); // this._viewMatrix.toInverseMatrix3().transposeTo();
|
|
275
|
-
|
|
276
|
-
for (let i = 0, len = this.frustums.length; i < len; i++) {
|
|
277
|
-
this.frustums[i].setViewMatrix(this._viewMatrix);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
this.events.dispatch(this.events.viewchange, this);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* Refresh camera matrices
|
|
285
|
-
* @public
|
|
286
|
-
*/
|
|
287
|
-
refresh() {
|
|
288
|
-
this._setProj(this._viewAngle, this._aspect);
|
|
289
|
-
this.update();
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Sets aspect ratio
|
|
294
|
-
* @public
|
|
295
|
-
* @param {Number} aspect - Camera aspect ratio
|
|
296
|
-
*/
|
|
297
|
-
setAspectRatio(aspect) {
|
|
298
|
-
this._aspect = aspect;
|
|
299
|
-
this.refresh();
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Returns aspect ratio
|
|
304
|
-
* @public
|
|
305
|
-
* @returns {number} - Aspect ratio
|
|
306
|
-
*/
|
|
307
|
-
getAspectRatio() {
|
|
308
|
-
return this._aspect;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
/**
|
|
312
|
-
* Sets up camera projection
|
|
313
|
-
* @public
|
|
314
|
-
* @param {nnumber} angle - Camera's view angle
|
|
315
|
-
* @param {number} aspect - Screen aspect ration
|
|
316
|
-
*/
|
|
317
|
-
_setProj(angle, aspect) {
|
|
318
|
-
this._viewAngle = angle;
|
|
319
|
-
this._aspect = aspect;
|
|
320
|
-
this._tanViewAngle_hrad = Math.tan(angle * math.RADIANS_HALF);
|
|
321
|
-
this._tanViewAngle_hradOneByHeight =
|
|
322
|
-
this._tanViewAngle_hrad * this.renderer.handler._oneByHeight;
|
|
323
|
-
var c = this.renderer.handler.canvas;
|
|
324
|
-
this._projSizeConst = Math.min(c.clientWidth < 256 ? 256 : c.clientWidth, c.clientHeight < 256 ? 256 : c.clientHeight) / (angle * math.RADIANS);
|
|
325
|
-
for (let i = 0, len = this.frustums.length; i < len; i++) {
|
|
326
|
-
this.frustums[i].setProjectionMatrix(
|
|
327
|
-
angle,
|
|
328
|
-
aspect,
|
|
329
|
-
this.frustums[i].near,
|
|
330
|
-
this.frustums[i].far
|
|
331
|
-
);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* Sets camera view angle in degrees
|
|
337
|
-
* @public
|
|
338
|
-
* @param {number} angle - View angle
|
|
339
|
-
*/
|
|
340
|
-
setViewAngle(angle) {
|
|
341
|
-
this._viewAngle = angle;
|
|
342
|
-
this.refresh();
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Gets camera view angle in degrees
|
|
347
|
-
* @public
|
|
348
|
-
* @returns {number} angle -
|
|
349
|
-
*/
|
|
350
|
-
getViewAngle() {
|
|
351
|
-
return this._viewAngle;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/**
|
|
355
|
-
* Sets camera to eye position
|
|
356
|
-
* @public
|
|
357
|
-
* @param {Vec3} eye - Camera position
|
|
358
|
-
* @param {Vec3} look - Look point
|
|
359
|
-
* @param {Vec3} up - Camera up vector
|
|
360
|
-
* @returns {Camera} - This camera
|
|
361
|
-
*/
|
|
362
|
-
set(eye, look, up) {
|
|
363
|
-
this.eye.x = eye.x;
|
|
364
|
-
this.eye.y = eye.y;
|
|
365
|
-
this.eye.z = eye.z;
|
|
366
|
-
look = look || this._b;
|
|
367
|
-
up = up || this._u;
|
|
368
|
-
this._b.x = eye.x - look.x;
|
|
369
|
-
this._b.y = eye.y - look.y;
|
|
370
|
-
this._b.z = eye.z - look.z;
|
|
371
|
-
this._r.copy(up.cross(this._b));
|
|
372
|
-
this._b.normalize();
|
|
373
|
-
this._r.normalize();
|
|
374
|
-
this._u.copy(this._b.cross(this._r));
|
|
375
|
-
return this;
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
/**
|
|
379
|
-
* Sets camera look point
|
|
380
|
-
* @public
|
|
381
|
-
* @param {Vec3} look - Look point
|
|
382
|
-
* @param {Vec3} [up] - Camera up vector otherwise camera current up vector(this._u)
|
|
383
|
-
*/
|
|
384
|
-
look(look, up) {
|
|
385
|
-
this._b.set(this.eye.x - look.x, this.eye.y - look.y, this.eye.z - look.z);
|
|
386
|
-
this._r.copy((up || this._u).cross(this._b));
|
|
387
|
-
this._b.normalize();
|
|
388
|
-
this._r.normalize();
|
|
389
|
-
this._u.copy(this._b.cross(this._r));
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
/**
|
|
393
|
-
* Slides camera to vector d - (du, dv, dn)
|
|
394
|
-
* @public
|
|
395
|
-
* @param {number} du - delta X
|
|
396
|
-
* @param {number} dv - delta Y
|
|
397
|
-
* @param {number} dn - delta Z
|
|
398
|
-
*/
|
|
399
|
-
slide(du, dv, dn) {
|
|
400
|
-
this.eye.x += du * this._r.x + dv * this._u.x + dn * this._b.x;
|
|
401
|
-
this.eye.y += du * this._r.y + dv * this._u.y + dn * this._b.y;
|
|
402
|
-
this.eye.z += du * this._r.z + dv * this._u.z + dn * this._b.z;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Roll the camera to the angle in degrees
|
|
407
|
-
* @public
|
|
408
|
-
* @param {number} angle - Delta roll angle in degrees
|
|
409
|
-
*/
|
|
410
|
-
roll(angle) {
|
|
411
|
-
var cs = Math.cos(math.RADIANS * angle);
|
|
412
|
-
var sn = Math.sin(math.RADIANS * angle);
|
|
413
|
-
var t = this._r.clone();
|
|
414
|
-
this._r.set(
|
|
415
|
-
cs * t.x - sn * this._u.x,
|
|
416
|
-
cs * t.y - sn * this._u.y,
|
|
417
|
-
cs * t.z - sn * this._u.z
|
|
418
|
-
);
|
|
419
|
-
this._u.set(
|
|
420
|
-
sn * t.x + cs * this._u.x,
|
|
421
|
-
sn * t.y + cs * this._u.y,
|
|
422
|
-
sn * t.z + cs * this._u.z
|
|
423
|
-
);
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
/**
|
|
427
|
-
* Pitch the camera to the angle in degrees
|
|
428
|
-
* @public
|
|
429
|
-
* @param {number} angle - Delta pitch angle in degrees
|
|
430
|
-
*/
|
|
431
|
-
pitch(angle) {
|
|
432
|
-
var cs = Math.cos(math.RADIANS * angle);
|
|
433
|
-
var sn = Math.sin(math.RADIANS * angle);
|
|
434
|
-
var t = this._b.clone();
|
|
435
|
-
this._b.set(
|
|
436
|
-
cs * t.x - sn * this._u.x,
|
|
437
|
-
cs * t.y - sn * this._u.y,
|
|
438
|
-
cs * t.z - sn * this._u.z
|
|
439
|
-
);
|
|
440
|
-
this._u.set(
|
|
441
|
-
sn * t.x + cs * this._u.x,
|
|
442
|
-
sn * t.y + cs * this._u.y,
|
|
443
|
-
sn * t.z + cs * this._u.z
|
|
444
|
-
);
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Yaw the camera to the angle in degrees
|
|
449
|
-
* @public
|
|
450
|
-
* @param {number} angle - Delta yaw angle in degrees
|
|
451
|
-
*/
|
|
452
|
-
yaw(angle) {
|
|
453
|
-
var cs = Math.cos(math.RADIANS * angle);
|
|
454
|
-
var sn = Math.sin(math.RADIANS * angle);
|
|
455
|
-
var t = this._r.clone();
|
|
456
|
-
this._r.set(
|
|
457
|
-
cs * t.x - sn * this._b.x,
|
|
458
|
-
cs * t.y - sn * this._b.y,
|
|
459
|
-
cs * t.z - sn * this._b.z
|
|
460
|
-
);
|
|
461
|
-
this._b.set(
|
|
462
|
-
sn * t.x + cs * this._b.x,
|
|
463
|
-
sn * t.y + cs * this._b.y,
|
|
464
|
-
sn * t.z + cs * this._b.z
|
|
465
|
-
);
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
/**
|
|
469
|
-
* Returns normal vector direction to to the unprojected screen point from camera eye
|
|
470
|
-
* @public
|
|
471
|
-
* @param {number} x - Scren X coordinate
|
|
472
|
-
* @param {number} y - Scren Y coordinate
|
|
473
|
-
* @returns {Vec3} - Direction vector
|
|
474
|
-
*/
|
|
475
|
-
unproject(x, y) {
|
|
476
|
-
var c = this.renderer.handler.canvas,
|
|
477
|
-
w = c.width * 0.5,
|
|
478
|
-
h = c.height * 0.5;
|
|
479
|
-
|
|
480
|
-
var px = (x - w) / w,
|
|
481
|
-
py = -(y - h) / h;
|
|
482
|
-
|
|
483
|
-
var world1 = this.frustums[0]._inverseProjectionViewMatrix.mulVec4(new Vec4(px, py, -1.0, 1.0)).affinity(),
|
|
484
|
-
world2 = this.frustums[0]._inverseProjectionViewMatrix.mulVec4(new Vec4(px, py, 0.0, 1.0)).affinity();
|
|
485
|
-
|
|
486
|
-
return world2.subA(world1).toVec3().normalize();
|
|
487
|
-
}
|
|
488
|
-
|
|
489
|
-
/**
|
|
490
|
-
* Gets projected 3d point to the 2d screen coordiantes
|
|
491
|
-
* @public
|
|
492
|
-
* @param {Vec3} v - Cartesian 3d coordiantes
|
|
493
|
-
* @returns {Vec2} - Screen point coordinates
|
|
494
|
-
*/
|
|
495
|
-
project(v) {
|
|
496
|
-
var r = this.frustums[0]._projectionViewMatrix.mulVec4(v.toVec4()),
|
|
497
|
-
c = this.renderer.handler.canvas;
|
|
498
|
-
return new Vec2((1 + r.x / r.w) * c.width * 0.5, (1 - r.y / r.w) * c.height * 0.5);
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
/**
|
|
502
|
-
* Rotates camera around center point
|
|
503
|
-
* @public
|
|
504
|
-
* @param {number} angle - Rotation angle in radians
|
|
505
|
-
* @param {boolean} isArc - If true camera up vector gets from current up vector every frame,
|
|
506
|
-
* otherwise up is always input parameter.
|
|
507
|
-
* @param {Vec3} center - Point that the camera rotates around
|
|
508
|
-
* @param {Vecto3} [up] - Camera up vector
|
|
509
|
-
*/
|
|
510
|
-
rotateAround(angle, isArc, center, up) {
|
|
511
|
-
center = center || Vec3.ZERO;
|
|
512
|
-
up = up || Vec3.UP;
|
|
513
|
-
|
|
514
|
-
var rot = new Mat4().setRotation(isArc ? this._u : up, angle);
|
|
515
|
-
var tr = new Mat4().setIdentity().translate(center);
|
|
516
|
-
var ntr = new Mat4().setIdentity().translate(center.negateTo());
|
|
517
|
-
|
|
518
|
-
var trm = tr.mul(rot).mul(ntr);
|
|
519
|
-
|
|
520
|
-
this.eye = trm.mulVec3(this.eye);
|
|
521
|
-
this._u = rot.mulVec3(this._u).normalize();
|
|
522
|
-
this._r = rot.mulVec3(this._r).normalize();
|
|
523
|
-
this._b = rot.mulVec3(this._b).normalize();
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
/**
|
|
527
|
-
* Rotates camera around center point by horizontal.
|
|
528
|
-
* @public
|
|
529
|
-
* @param {number} angle - Rotation angle in radians.
|
|
530
|
-
* @param {boolaen} isArc - If true camera up vector gets from current up vector every frame,
|
|
531
|
-
* otherwise up is always input parameter.
|
|
532
|
-
* @param {Vec3} center - Point that the camera rotates around.
|
|
533
|
-
* @param {Vec3} [up] - Camera up vector.
|
|
534
|
-
*/
|
|
535
|
-
rotateHorizontal(angle, isArc, center, up = Vec3.ZERO) {
|
|
536
|
-
this.rotateAround(angle, isArc, center, up);
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
/**
|
|
540
|
-
* Rotates camera around center point by vecrtical.
|
|
541
|
-
* @param {number} angle - Rotation angle in radians.
|
|
542
|
-
* @param {Vec3} center - Point that the camera rotates around.
|
|
543
|
-
*/
|
|
544
|
-
rotateVertical(angle, center) {
|
|
545
|
-
this.rotateAround(angle, false, center, this._r);
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
/**
|
|
549
|
-
* Gets 3d size factor. Uses in LOD distance calculation.
|
|
550
|
-
* @public
|
|
551
|
-
* @param {Vec3} p - Far point.
|
|
552
|
-
* @param {Vec3} r - Far point.
|
|
553
|
-
* @returns {number} - Size factor.
|
|
554
|
-
*/
|
|
555
|
-
projectedSize(p, r) {
|
|
556
|
-
return Math.atan(r / this.eye.distance(p)) * this._projSizeConst;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
/**
|
|
560
|
-
* Returns normal matrix.
|
|
561
|
-
* @public
|
|
562
|
-
* @returns {Mat3} - Normal matrix.
|
|
563
|
-
*/
|
|
564
|
-
getNormalMatrix() {
|
|
565
|
-
return this._normalMatrix._m;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
/**
|
|
569
|
-
* Returns model matrix.
|
|
570
|
-
* @public
|
|
571
|
-
* @returns {Mat4} - View matrix.
|
|
572
|
-
*/
|
|
573
|
-
getViewMatrix() {
|
|
574
|
-
return this._viewMatrix._m;
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
setCurrentFrustum(k) {
|
|
578
|
-
this._currentFrustum = k;
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
getCurrentFrustum() {
|
|
582
|
-
return this._currentFrustum;
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
get frustum() {
|
|
586
|
-
return this.frustums[this._currentFrustum];
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
/**
|
|
590
|
-
* Returns projection matrix.
|
|
591
|
-
* @public
|
|
592
|
-
* @returns {Mat4} - Projection matrix.
|
|
593
|
-
*/
|
|
594
|
-
getProjectionMatrix() {
|
|
595
|
-
return this.frustum._projectionMatrix._m;
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
/**
|
|
599
|
-
* Returns projection and model matrix product.
|
|
600
|
-
* @public
|
|
601
|
-
* @return {Mat4} - Projection-view matrix.
|
|
602
|
-
*/
|
|
603
|
-
getProjectionViewMatrix() {
|
|
604
|
-
return this.frustum._projectionViewMatrix._m;
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
/**
|
|
608
|
-
* Returns inverse projection and model matrix product.
|
|
609
|
-
* @public
|
|
610
|
-
* @returns {Mat4} - Inversed projection-view matrix.
|
|
611
|
-
*/
|
|
612
|
-
getInverseProjectionViewMatrix() {
|
|
613
|
-
return this.frustum._inverseProjectionViewMatrix._m;
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
/**
|
|
617
|
-
* Returns inverse projection matrix.
|
|
618
|
-
* @public
|
|
619
|
-
* @returns {Mat4} - Inversed projection-view matrix.
|
|
620
|
-
*/
|
|
621
|
-
getInverseProjectionMatrix() {
|
|
622
|
-
return this.frustum._inverseProjectionMatrix._m;
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
const EVENT_NAMES = [
|
|
627
|
-
/**
|
|
628
|
-
* When camera has been updated.
|
|
629
|
-
* @event og.Camera#viewchange
|
|
630
|
-
*/
|
|
631
|
-
"viewchange",
|
|
632
|
-
|
|
633
|
-
/**
|
|
634
|
-
* Camera is stopped.
|
|
635
|
-
* @event og.Camera#moveend
|
|
636
|
-
*/
|
|
637
|
-
"moveend"
|
|
638
|
-
];
|
|
639
|
-
|
|
640
|
-
export { Camera };
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import * as math from "../math.js";
|
|
4
|
+
import { Events } from "../Events.js";
|
|
5
|
+
import { Frustum } from "./Frustum.js";
|
|
6
|
+
import { Vec2 } from "../math/Vec2.js";
|
|
7
|
+
import { Vec3 } from "../math/Vec3.js";
|
|
8
|
+
import { Vec4 } from "../math/Vec4.js";
|
|
9
|
+
import { Mat3 } from "../math/Mat3.js";
|
|
10
|
+
import { Mat4 } from "../math/Mat4.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Camera class.
|
|
14
|
+
* @class
|
|
15
|
+
* @param {Renderer} [renderer] - Renderer uses the camera instance.
|
|
16
|
+
* @param {Object} [options] - Camera options:
|
|
17
|
+
* @param {Object} [options.name] - Camera name.
|
|
18
|
+
* @param {number} [options.viewAngle=38] - Camera angle of view. Default is 30.0
|
|
19
|
+
* @param {number} [options.near=1] - Camera near plane distance. Default is 1.0
|
|
20
|
+
* @param {number} [options.far=og.math.MAX] - Camera far plane distance. Deafult is og.math.MAX
|
|
21
|
+
* @param {Vec3} [options.eye=[0,0,0]] - Camera eye position. Default (0,0,0)
|
|
22
|
+
* @param {Vec3} [options.look=[0,0,0]] - Camera look position. Default (0,0,0)
|
|
23
|
+
* @param {Vec3} [options.up=[0,1,0]] - Camera eye position. Default (0,1,0)
|
|
24
|
+
*
|
|
25
|
+
* @fires og.Camera#viewchange
|
|
26
|
+
*/
|
|
27
|
+
class Camera {
|
|
28
|
+
/**
|
|
29
|
+
* @param {Renderer} [renderer] - Renderer uses the camera instance.
|
|
30
|
+
* @param {Object} [options] - Camera options:
|
|
31
|
+
*/
|
|
32
|
+
constructor(renderer, options) {
|
|
33
|
+
/**
|
|
34
|
+
* Assigned renderer
|
|
35
|
+
* @public
|
|
36
|
+
* @type {Renderer}
|
|
37
|
+
*/
|
|
38
|
+
this.renderer = renderer;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Camera events handler
|
|
42
|
+
* @public
|
|
43
|
+
* @type {Events}
|
|
44
|
+
*/
|
|
45
|
+
this.events = new Events(EVENT_NAMES, this);
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Camera position.
|
|
49
|
+
* @public
|
|
50
|
+
* @type {Vec3}
|
|
51
|
+
*/
|
|
52
|
+
this.eye = new Vec3();
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Camera RTE high position
|
|
56
|
+
* @public
|
|
57
|
+
* @type {Vec3}
|
|
58
|
+
*/
|
|
59
|
+
this.eyeHigh = new Float32Array(3);
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Camera RTE low position
|
|
63
|
+
* @public
|
|
64
|
+
* @type {Vec3}
|
|
65
|
+
*/
|
|
66
|
+
this.eyeLow = new Float32Array(3);
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Aspect ratio.
|
|
70
|
+
* @protected
|
|
71
|
+
* @type {Number}
|
|
72
|
+
*/
|
|
73
|
+
this._aspect = options.aspect || this.renderer.handler.getClientAspect();
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Camera view angle in degrees
|
|
77
|
+
* @protected
|
|
78
|
+
* @type {Number}
|
|
79
|
+
*/
|
|
80
|
+
this._viewAngle = options.viewAngle || 38.0;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Camera normal matrix.
|
|
84
|
+
* @protected
|
|
85
|
+
* @type {Mat3}
|
|
86
|
+
*/
|
|
87
|
+
this._normalMatrix = new Mat3();
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Camera view matrix.
|
|
91
|
+
* @protected
|
|
92
|
+
* @type {Mat4}
|
|
93
|
+
*/
|
|
94
|
+
this._viewMatrix = new Mat4();
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Camera right vector.
|
|
98
|
+
* @protected
|
|
99
|
+
* @type {Vec3}
|
|
100
|
+
*/
|
|
101
|
+
this._r = new Vec3(1.0, 0.0, 0.0); // up x n
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Camera up vector.
|
|
105
|
+
* @protected
|
|
106
|
+
* @type {Vec3}
|
|
107
|
+
*/
|
|
108
|
+
this._u = new Vec3(0.0, 1.0, 0.0); // n x u - UP
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Camera forward vector.
|
|
112
|
+
* @protected
|
|
113
|
+
* @type {Vec3}
|
|
114
|
+
*/
|
|
115
|
+
this._b = new Vec3(0.0, 0.0, 1.0); // eye - look - FORWARD
|
|
116
|
+
|
|
117
|
+
// Previous frame values
|
|
118
|
+
this._pu = this._r.clone();
|
|
119
|
+
this._pv = this._u.clone();
|
|
120
|
+
this._pn = this._b.clone();
|
|
121
|
+
this._peye = this.eye.clone();
|
|
122
|
+
this.isMoved = false;
|
|
123
|
+
|
|
124
|
+
this._tanViewAngle_hrad = 0.0;
|
|
125
|
+
this._tanViewAngle_hradOneByHeight = 0.0;
|
|
126
|
+
|
|
127
|
+
this.frustums = [];
|
|
128
|
+
|
|
129
|
+
this.nearFarArr = [];
|
|
130
|
+
|
|
131
|
+
this.frustumColors = [];
|
|
132
|
+
|
|
133
|
+
if (options.frustums) {
|
|
134
|
+
for (let i = 0, len = options.frustums.length; i < len; i++) {
|
|
135
|
+
let fi = options.frustums[i];
|
|
136
|
+
|
|
137
|
+
let fr = new Frustum({
|
|
138
|
+
fov: this._viewAngle,
|
|
139
|
+
aspect: this._aspect,
|
|
140
|
+
near: fi[0],
|
|
141
|
+
far: fi[1]
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
fr._cameraFrustumIndex = this.frustums.length;
|
|
145
|
+
this.frustums.push(fr);
|
|
146
|
+
this.renderer.assignPickingColor(fr);
|
|
147
|
+
this.nearFarArr.push.apply(this.nearFarArr, [fi[0], fi[1]]);
|
|
148
|
+
this.frustumColors.push.apply(this.frustumColors, fr._pickingColorU);
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
let near = 1.0,
|
|
152
|
+
far = 10000.0;
|
|
153
|
+
|
|
154
|
+
let fr = new Frustum({
|
|
155
|
+
fov: this._viewAngle,
|
|
156
|
+
aspect: this._aspect,
|
|
157
|
+
near: near,
|
|
158
|
+
far: far
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
fr._cameraFrustumIndex = this.frustums.length;
|
|
162
|
+
this.frustums.push(fr);
|
|
163
|
+
this.renderer.assignPickingColor(fr);
|
|
164
|
+
this.nearFarArr = new Array([near, far]);
|
|
165
|
+
this.frustumColors.push.apply(this.frustumColors, fr._pickingColorU);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
this.FARTHEST_FRUSTUM_INDEX = this.frustums.length - 1;
|
|
169
|
+
|
|
170
|
+
this._currentFrustum = 0;
|
|
171
|
+
|
|
172
|
+
renderer && this._init(options);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
checkMoveEnd() {
|
|
176
|
+
var u = this._r,
|
|
177
|
+
v = this._u,
|
|
178
|
+
n = this._b,
|
|
179
|
+
eye = this.eye;
|
|
180
|
+
|
|
181
|
+
if (this._peye.equal(eye) && this._pu.equal(u) && this._pv.equal(v) && this._pn.equal(n)) {
|
|
182
|
+
if (this.isMoved) {
|
|
183
|
+
this.events.dispatch(this.events.moveend, this);
|
|
184
|
+
}
|
|
185
|
+
this.isMoved = false;
|
|
186
|
+
} else {
|
|
187
|
+
this.isMoved = true;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
this._pu.copy(u);
|
|
191
|
+
this._pv.copy(v);
|
|
192
|
+
this._pn.copy(n);
|
|
193
|
+
this._peye.copy(eye);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Camera initialization.
|
|
198
|
+
* @public
|
|
199
|
+
* @param {Renderer} renderer - OpenGlobus renderer object.
|
|
200
|
+
* @param {Object} [options] - Camera options:
|
|
201
|
+
* @param {number} [options.viewAngle] - Camera angle of view. Default is 30.0
|
|
202
|
+
* @param {number} [options.near] - Camera near plane distance. Default is 1.0
|
|
203
|
+
* @param {number} [options.far] - Camera far plane distance. Deafult is og.math.MAX
|
|
204
|
+
* @param {Vec3} [options.eye] - Camera eye position. Default (0,0,0)
|
|
205
|
+
* @param {Vec3} [options.look] - Camera look position. Default (0,0,0)
|
|
206
|
+
* @param {Vec3} [options.up] - Camera eye position. Default (0,1,0)
|
|
207
|
+
*/
|
|
208
|
+
_init(options) {
|
|
209
|
+
this._setProj(this._viewAngle, this._aspect);
|
|
210
|
+
|
|
211
|
+
this.set(
|
|
212
|
+
options.eye || new Vec3(0.0, 0.0, 1.0),
|
|
213
|
+
options.look || new Vec3(),
|
|
214
|
+
options.up || new Vec3(0.0, 1.0, 0.0)
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
getUp() {
|
|
219
|
+
return this._u.clone();
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
getDown() {
|
|
223
|
+
return this._u.negateTo();
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
getRight() {
|
|
227
|
+
return this._r.clone();
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
getLeft() {
|
|
231
|
+
return this._r.negateTo();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
getForward() {
|
|
235
|
+
return this._b.negateTo();
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
getBackward() {
|
|
239
|
+
return this._b.clone();
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Updates camera view space
|
|
244
|
+
* @public
|
|
245
|
+
* @virtual
|
|
246
|
+
*/
|
|
247
|
+
update() {
|
|
248
|
+
var u = this._r,
|
|
249
|
+
v = this._u,
|
|
250
|
+
n = this._b,
|
|
251
|
+
eye = this.eye;
|
|
252
|
+
|
|
253
|
+
Vec3.doubleToTwoFloat32Array(eye, this.eyeHigh, this.eyeLow);
|
|
254
|
+
|
|
255
|
+
this._viewMatrix.set([
|
|
256
|
+
u.x,
|
|
257
|
+
v.x,
|
|
258
|
+
n.x,
|
|
259
|
+
0.0,
|
|
260
|
+
u.y,
|
|
261
|
+
v.y,
|
|
262
|
+
n.y,
|
|
263
|
+
0.0,
|
|
264
|
+
u.z,
|
|
265
|
+
v.z,
|
|
266
|
+
n.z,
|
|
267
|
+
0.0,
|
|
268
|
+
-eye.dot(u),
|
|
269
|
+
-eye.dot(v),
|
|
270
|
+
-eye.dot(n),
|
|
271
|
+
1.0
|
|
272
|
+
]);
|
|
273
|
+
|
|
274
|
+
this._normalMatrix = this._viewMatrix.toMatrix3(); // this._viewMatrix.toInverseMatrix3().transposeTo();
|
|
275
|
+
|
|
276
|
+
for (let i = 0, len = this.frustums.length; i < len; i++) {
|
|
277
|
+
this.frustums[i].setViewMatrix(this._viewMatrix);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
this.events.dispatch(this.events.viewchange, this);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Refresh camera matrices
|
|
285
|
+
* @public
|
|
286
|
+
*/
|
|
287
|
+
refresh() {
|
|
288
|
+
this._setProj(this._viewAngle, this._aspect);
|
|
289
|
+
this.update();
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Sets aspect ratio
|
|
294
|
+
* @public
|
|
295
|
+
* @param {Number} aspect - Camera aspect ratio
|
|
296
|
+
*/
|
|
297
|
+
setAspectRatio(aspect) {
|
|
298
|
+
this._aspect = aspect;
|
|
299
|
+
this.refresh();
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Returns aspect ratio
|
|
304
|
+
* @public
|
|
305
|
+
* @returns {number} - Aspect ratio
|
|
306
|
+
*/
|
|
307
|
+
getAspectRatio() {
|
|
308
|
+
return this._aspect;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Sets up camera projection
|
|
313
|
+
* @public
|
|
314
|
+
* @param {nnumber} angle - Camera's view angle
|
|
315
|
+
* @param {number} aspect - Screen aspect ration
|
|
316
|
+
*/
|
|
317
|
+
_setProj(angle, aspect) {
|
|
318
|
+
this._viewAngle = angle;
|
|
319
|
+
this._aspect = aspect;
|
|
320
|
+
this._tanViewAngle_hrad = Math.tan(angle * math.RADIANS_HALF);
|
|
321
|
+
this._tanViewAngle_hradOneByHeight =
|
|
322
|
+
this._tanViewAngle_hrad * this.renderer.handler._oneByHeight;
|
|
323
|
+
var c = this.renderer.handler.canvas;
|
|
324
|
+
this._projSizeConst = Math.min(c.clientWidth < 256 ? 256 : c.clientWidth, c.clientHeight < 256 ? 256 : c.clientHeight) / (angle * math.RADIANS);
|
|
325
|
+
for (let i = 0, len = this.frustums.length; i < len; i++) {
|
|
326
|
+
this.frustums[i].setProjectionMatrix(
|
|
327
|
+
angle,
|
|
328
|
+
aspect,
|
|
329
|
+
this.frustums[i].near,
|
|
330
|
+
this.frustums[i].far
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Sets camera view angle in degrees
|
|
337
|
+
* @public
|
|
338
|
+
* @param {number} angle - View angle
|
|
339
|
+
*/
|
|
340
|
+
setViewAngle(angle) {
|
|
341
|
+
this._viewAngle = angle;
|
|
342
|
+
this.refresh();
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Gets camera view angle in degrees
|
|
347
|
+
* @public
|
|
348
|
+
* @returns {number} angle -
|
|
349
|
+
*/
|
|
350
|
+
getViewAngle() {
|
|
351
|
+
return this._viewAngle;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Sets camera to eye position
|
|
356
|
+
* @public
|
|
357
|
+
* @param {Vec3} eye - Camera position
|
|
358
|
+
* @param {Vec3} look - Look point
|
|
359
|
+
* @param {Vec3} up - Camera up vector
|
|
360
|
+
* @returns {Camera} - This camera
|
|
361
|
+
*/
|
|
362
|
+
set(eye, look, up) {
|
|
363
|
+
this.eye.x = eye.x;
|
|
364
|
+
this.eye.y = eye.y;
|
|
365
|
+
this.eye.z = eye.z;
|
|
366
|
+
look = look || this._b;
|
|
367
|
+
up = up || this._u;
|
|
368
|
+
this._b.x = eye.x - look.x;
|
|
369
|
+
this._b.y = eye.y - look.y;
|
|
370
|
+
this._b.z = eye.z - look.z;
|
|
371
|
+
this._r.copy(up.cross(this._b));
|
|
372
|
+
this._b.normalize();
|
|
373
|
+
this._r.normalize();
|
|
374
|
+
this._u.copy(this._b.cross(this._r));
|
|
375
|
+
return this;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Sets camera look point
|
|
380
|
+
* @public
|
|
381
|
+
* @param {Vec3} look - Look point
|
|
382
|
+
* @param {Vec3} [up] - Camera up vector otherwise camera current up vector(this._u)
|
|
383
|
+
*/
|
|
384
|
+
look(look, up) {
|
|
385
|
+
this._b.set(this.eye.x - look.x, this.eye.y - look.y, this.eye.z - look.z);
|
|
386
|
+
this._r.copy((up || this._u).cross(this._b));
|
|
387
|
+
this._b.normalize();
|
|
388
|
+
this._r.normalize();
|
|
389
|
+
this._u.copy(this._b.cross(this._r));
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Slides camera to vector d - (du, dv, dn)
|
|
394
|
+
* @public
|
|
395
|
+
* @param {number} du - delta X
|
|
396
|
+
* @param {number} dv - delta Y
|
|
397
|
+
* @param {number} dn - delta Z
|
|
398
|
+
*/
|
|
399
|
+
slide(du, dv, dn) {
|
|
400
|
+
this.eye.x += du * this._r.x + dv * this._u.x + dn * this._b.x;
|
|
401
|
+
this.eye.y += du * this._r.y + dv * this._u.y + dn * this._b.y;
|
|
402
|
+
this.eye.z += du * this._r.z + dv * this._u.z + dn * this._b.z;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Roll the camera to the angle in degrees
|
|
407
|
+
* @public
|
|
408
|
+
* @param {number} angle - Delta roll angle in degrees
|
|
409
|
+
*/
|
|
410
|
+
roll(angle) {
|
|
411
|
+
var cs = Math.cos(math.RADIANS * angle);
|
|
412
|
+
var sn = Math.sin(math.RADIANS * angle);
|
|
413
|
+
var t = this._r.clone();
|
|
414
|
+
this._r.set(
|
|
415
|
+
cs * t.x - sn * this._u.x,
|
|
416
|
+
cs * t.y - sn * this._u.y,
|
|
417
|
+
cs * t.z - sn * this._u.z
|
|
418
|
+
);
|
|
419
|
+
this._u.set(
|
|
420
|
+
sn * t.x + cs * this._u.x,
|
|
421
|
+
sn * t.y + cs * this._u.y,
|
|
422
|
+
sn * t.z + cs * this._u.z
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Pitch the camera to the angle in degrees
|
|
428
|
+
* @public
|
|
429
|
+
* @param {number} angle - Delta pitch angle in degrees
|
|
430
|
+
*/
|
|
431
|
+
pitch(angle) {
|
|
432
|
+
var cs = Math.cos(math.RADIANS * angle);
|
|
433
|
+
var sn = Math.sin(math.RADIANS * angle);
|
|
434
|
+
var t = this._b.clone();
|
|
435
|
+
this._b.set(
|
|
436
|
+
cs * t.x - sn * this._u.x,
|
|
437
|
+
cs * t.y - sn * this._u.y,
|
|
438
|
+
cs * t.z - sn * this._u.z
|
|
439
|
+
);
|
|
440
|
+
this._u.set(
|
|
441
|
+
sn * t.x + cs * this._u.x,
|
|
442
|
+
sn * t.y + cs * this._u.y,
|
|
443
|
+
sn * t.z + cs * this._u.z
|
|
444
|
+
);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Yaw the camera to the angle in degrees
|
|
449
|
+
* @public
|
|
450
|
+
* @param {number} angle - Delta yaw angle in degrees
|
|
451
|
+
*/
|
|
452
|
+
yaw(angle) {
|
|
453
|
+
var cs = Math.cos(math.RADIANS * angle);
|
|
454
|
+
var sn = Math.sin(math.RADIANS * angle);
|
|
455
|
+
var t = this._r.clone();
|
|
456
|
+
this._r.set(
|
|
457
|
+
cs * t.x - sn * this._b.x,
|
|
458
|
+
cs * t.y - sn * this._b.y,
|
|
459
|
+
cs * t.z - sn * this._b.z
|
|
460
|
+
);
|
|
461
|
+
this._b.set(
|
|
462
|
+
sn * t.x + cs * this._b.x,
|
|
463
|
+
sn * t.y + cs * this._b.y,
|
|
464
|
+
sn * t.z + cs * this._b.z
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Returns normal vector direction to to the unprojected screen point from camera eye
|
|
470
|
+
* @public
|
|
471
|
+
* @param {number} x - Scren X coordinate
|
|
472
|
+
* @param {number} y - Scren Y coordinate
|
|
473
|
+
* @returns {Vec3} - Direction vector
|
|
474
|
+
*/
|
|
475
|
+
unproject(x, y) {
|
|
476
|
+
var c = this.renderer.handler.canvas,
|
|
477
|
+
w = c.width * 0.5,
|
|
478
|
+
h = c.height * 0.5;
|
|
479
|
+
|
|
480
|
+
var px = (x - w) / w,
|
|
481
|
+
py = -(y - h) / h;
|
|
482
|
+
|
|
483
|
+
var world1 = this.frustums[0]._inverseProjectionViewMatrix.mulVec4(new Vec4(px, py, -1.0, 1.0)).affinity(),
|
|
484
|
+
world2 = this.frustums[0]._inverseProjectionViewMatrix.mulVec4(new Vec4(px, py, 0.0, 1.0)).affinity();
|
|
485
|
+
|
|
486
|
+
return world2.subA(world1).toVec3().normalize();
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Gets projected 3d point to the 2d screen coordiantes
|
|
491
|
+
* @public
|
|
492
|
+
* @param {Vec3} v - Cartesian 3d coordiantes
|
|
493
|
+
* @returns {Vec2} - Screen point coordinates
|
|
494
|
+
*/
|
|
495
|
+
project(v) {
|
|
496
|
+
var r = this.frustums[0]._projectionViewMatrix.mulVec4(v.toVec4()),
|
|
497
|
+
c = this.renderer.handler.canvas;
|
|
498
|
+
return new Vec2((1 + r.x / r.w) * c.width * 0.5, (1 - r.y / r.w) * c.height * 0.5);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Rotates camera around center point
|
|
503
|
+
* @public
|
|
504
|
+
* @param {number} angle - Rotation angle in radians
|
|
505
|
+
* @param {boolean} isArc - If true camera up vector gets from current up vector every frame,
|
|
506
|
+
* otherwise up is always input parameter.
|
|
507
|
+
* @param {Vec3} center - Point that the camera rotates around
|
|
508
|
+
* @param {Vecto3} [up] - Camera up vector
|
|
509
|
+
*/
|
|
510
|
+
rotateAround(angle, isArc, center, up) {
|
|
511
|
+
center = center || Vec3.ZERO;
|
|
512
|
+
up = up || Vec3.UP;
|
|
513
|
+
|
|
514
|
+
var rot = new Mat4().setRotation(isArc ? this._u : up, angle);
|
|
515
|
+
var tr = new Mat4().setIdentity().translate(center);
|
|
516
|
+
var ntr = new Mat4().setIdentity().translate(center.negateTo());
|
|
517
|
+
|
|
518
|
+
var trm = tr.mul(rot).mul(ntr);
|
|
519
|
+
|
|
520
|
+
this.eye = trm.mulVec3(this.eye);
|
|
521
|
+
this._u = rot.mulVec3(this._u).normalize();
|
|
522
|
+
this._r = rot.mulVec3(this._r).normalize();
|
|
523
|
+
this._b = rot.mulVec3(this._b).normalize();
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* Rotates camera around center point by horizontal.
|
|
528
|
+
* @public
|
|
529
|
+
* @param {number} angle - Rotation angle in radians.
|
|
530
|
+
* @param {boolaen} isArc - If true camera up vector gets from current up vector every frame,
|
|
531
|
+
* otherwise up is always input parameter.
|
|
532
|
+
* @param {Vec3} center - Point that the camera rotates around.
|
|
533
|
+
* @param {Vec3} [up] - Camera up vector.
|
|
534
|
+
*/
|
|
535
|
+
rotateHorizontal(angle, isArc, center, up = Vec3.ZERO) {
|
|
536
|
+
this.rotateAround(angle, isArc, center, up);
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Rotates camera around center point by vecrtical.
|
|
541
|
+
* @param {number} angle - Rotation angle in radians.
|
|
542
|
+
* @param {Vec3} center - Point that the camera rotates around.
|
|
543
|
+
*/
|
|
544
|
+
rotateVertical(angle, center) {
|
|
545
|
+
this.rotateAround(angle, false, center, this._r);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Gets 3d size factor. Uses in LOD distance calculation.
|
|
550
|
+
* @public
|
|
551
|
+
* @param {Vec3} p - Far point.
|
|
552
|
+
* @param {Vec3} r - Far point.
|
|
553
|
+
* @returns {number} - Size factor.
|
|
554
|
+
*/
|
|
555
|
+
projectedSize(p, r) {
|
|
556
|
+
return Math.atan(r / this.eye.distance(p)) * this._projSizeConst;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* Returns normal matrix.
|
|
561
|
+
* @public
|
|
562
|
+
* @returns {Mat3} - Normal matrix.
|
|
563
|
+
*/
|
|
564
|
+
getNormalMatrix() {
|
|
565
|
+
return this._normalMatrix._m;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
/**
|
|
569
|
+
* Returns model matrix.
|
|
570
|
+
* @public
|
|
571
|
+
* @returns {Mat4} - View matrix.
|
|
572
|
+
*/
|
|
573
|
+
getViewMatrix() {
|
|
574
|
+
return this._viewMatrix._m;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
setCurrentFrustum(k) {
|
|
578
|
+
this._currentFrustum = k;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
getCurrentFrustum() {
|
|
582
|
+
return this._currentFrustum;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
get frustum() {
|
|
586
|
+
return this.frustums[this._currentFrustum];
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Returns projection matrix.
|
|
591
|
+
* @public
|
|
592
|
+
* @returns {Mat4} - Projection matrix.
|
|
593
|
+
*/
|
|
594
|
+
getProjectionMatrix() {
|
|
595
|
+
return this.frustum._projectionMatrix._m;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Returns projection and model matrix product.
|
|
600
|
+
* @public
|
|
601
|
+
* @return {Mat4} - Projection-view matrix.
|
|
602
|
+
*/
|
|
603
|
+
getProjectionViewMatrix() {
|
|
604
|
+
return this.frustum._projectionViewMatrix._m;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Returns inverse projection and model matrix product.
|
|
609
|
+
* @public
|
|
610
|
+
* @returns {Mat4} - Inversed projection-view matrix.
|
|
611
|
+
*/
|
|
612
|
+
getInverseProjectionViewMatrix() {
|
|
613
|
+
return this.frustum._inverseProjectionViewMatrix._m;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
/**
|
|
617
|
+
* Returns inverse projection matrix.
|
|
618
|
+
* @public
|
|
619
|
+
* @returns {Mat4} - Inversed projection-view matrix.
|
|
620
|
+
*/
|
|
621
|
+
getInverseProjectionMatrix() {
|
|
622
|
+
return this.frustum._inverseProjectionMatrix._m;
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
const EVENT_NAMES = [
|
|
627
|
+
/**
|
|
628
|
+
* When camera has been updated.
|
|
629
|
+
* @event og.Camera#viewchange
|
|
630
|
+
*/
|
|
631
|
+
"viewchange",
|
|
632
|
+
|
|
633
|
+
/**
|
|
634
|
+
* Camera is stopped.
|
|
635
|
+
* @event og.Camera#moveend
|
|
636
|
+
*/
|
|
637
|
+
"moveend"
|
|
638
|
+
];
|
|
639
|
+
|
|
640
|
+
export { Camera };
|