123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- let BaseLayer = mars3d.layer.BaseLayer;
- let THREE = window.THREE;
- //与THREE.js集成
- class ThreeLayer extends BaseLayer {
- constructor(options = {}) {
- super(options);
- this._pointerEvents = this.options.pointerEvents;
- }
- _showHook(show) {
- if (show) {
- this._threejsContainer.style.visibility = "visible";
- } else {
- this._threejsContainer.style.visibility = "hidden";
- }
- }
- /**
- * 对象添加到地图前创建一些对象的钩子方法,
- * 只会调用一次
- * @return {void} 无
- * @private
- */
- _mountedHook() {
- if (!THREE) {
- throw new Error("请引入 three.js 库 ");
- }
- let scene = this._map.scene;
- let threeContainer = mars3d.DomUtil.create("div", "mars3d-threejs");
- threeContainer.style.position = "absolute";
- threeContainer.style.top = "0px";
- threeContainer.style.left = "0px";
- threeContainer.style.width = scene.canvas.clientWidth + "px";
- threeContainer.style.height = scene.canvas.clientHeight + "px";
- threeContainer.style.pointerEvents = this._pointerEvents ? "auto" : "none"; //auto时可以交互,但是没法放大地球, none 没法交互
- this._container = threeContainer;
- let fov = 45;
- let aspect = scene.canvas.clientWidth / scene.canvas.clientHeight;
- let near = 1;
- let far = 10 * 1000 * 1000; // needs to be far to support Cesium's world-scale rendering
- this.scene = new THREE.Scene();
- this.camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
- this.renderer = new THREE.WebGLRenderer({ alpha: true });
- threeContainer.appendChild(this.renderer.domElement);
- }
- /**
- * 对象添加到地图上的创建钩子方法,
- * 每次add时都会调用
- * @return {void} 无
- * @private
- */
- _addedHook() {
- if (this._container) {
- this._map.container.appendChild(this._container);
- }
- this._map.useDefaultRenderLoop = false; //关闭自动渲染
- let that = this;
- (function frame() {
- //animateFrame: requestAnimationFrame事件句柄,用来清除操作
- that._animateFrame = window.requestAnimationFrame(frame);
- that.update(); //按帧率执行
- })();
- }
- /**
- * 对象从地图上移除的创建钩子方法,
- * 每次remove时都会调用
- * @return {void} 无
- * @private
- */
- _removedHook() {
- window.cancelAnimationFrame(this._animateFrame);
- delete this._animateFrame;
- this._map.useDefaultRenderLoop = true;
- if (this._container) {
- this._map.container.removeChild(this._container);
- }
- }
- update() {
- this.renderCesium();
- this.renderThreeObj();
- this.renderCamera();
- }
- renderCesium() {
- this._map.viewer.render();
- }
- renderThreeObj() {
- var width = this._container.clientWidth;
- var height = this._container.clientHeight;
- this.renderer.setSize(width, height);
- this.renderer.render(this.scene, this.camera);
- }
- renderCamera() {
- // register Three.js scene with Cesium
- this.camera.fov = Cesium.Math.toDegrees(this._map.camera.frustum.fovy); // ThreeJS FOV is vertical
- this.camera.updateProjectionMatrix();
- // Clone Cesium Camera projection position so the
- // Three.js Object will appear to be at the same place as above the Cesium Globe
- this.camera.matrixAutoUpdate = false;
- this.camera.lookAt(new THREE.Vector3(0, 0, 0));
- var cvm = this._map.camera.viewMatrix;
- var civm = this._map.camera.inverseViewMatrix;
- this.camera.matrixWorld.set(
- civm[0],
- civm[4],
- civm[8],
- civm[12],
- civm[1],
- civm[5],
- civm[9],
- civm[13],
- civm[2],
- civm[6],
- civm[10],
- civm[14],
- civm[3],
- civm[7],
- civm[11],
- civm[15]
- );
- this.camera.matrixWorldInverse.set(
- cvm[0],
- cvm[4],
- cvm[8],
- cvm[12],
- cvm[1],
- cvm[5],
- cvm[9],
- cvm[13],
- cvm[2],
- cvm[6],
- cvm[10],
- cvm[14],
- cvm[3],
- cvm[7],
- cvm[11],
- cvm[15]
- );
- var width = this._map.scene.canvas.clientWidth;
- var height = this._map.scene.canvas.clientHeight;
- this.camera.aspect = width / height;
- this.renderer.setSize(width, height);
- this.camera.updateProjectionMatrix();
- this.renderer.clear();
- this.renderer.render(this.scene, this.camera);
- }
- }
|