ThreeLayer.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. let BaseLayer = mars3d.layer.BaseLayer;
  2. let THREE = window.THREE;
  3. //与THREE.js集成
  4. class ThreeLayer extends BaseLayer {
  5. constructor(options = {}) {
  6. super(options);
  7. this._pointerEvents = this.options.pointerEvents;
  8. }
  9. _showHook(show) {
  10. if (show) {
  11. this._threejsContainer.style.visibility = "visible";
  12. } else {
  13. this._threejsContainer.style.visibility = "hidden";
  14. }
  15. }
  16. /**
  17. * 对象添加到地图前创建一些对象的钩子方法,
  18. * 只会调用一次
  19. * @return {void} 无
  20. * @private
  21. */
  22. _mountedHook() {
  23. if (!THREE) {
  24. throw new Error("请引入 three.js 库 ");
  25. }
  26. let scene = this._map.scene;
  27. let threeContainer = mars3d.DomUtil.create("div", "mars3d-threejs");
  28. threeContainer.style.position = "absolute";
  29. threeContainer.style.top = "0px";
  30. threeContainer.style.left = "0px";
  31. threeContainer.style.width = scene.canvas.clientWidth + "px";
  32. threeContainer.style.height = scene.canvas.clientHeight + "px";
  33. threeContainer.style.pointerEvents = this._pointerEvents ? "auto" : "none"; //auto时可以交互,但是没法放大地球, none 没法交互
  34. this._container = threeContainer;
  35. let fov = 45;
  36. let aspect = scene.canvas.clientWidth / scene.canvas.clientHeight;
  37. let near = 1;
  38. let far = 10 * 1000 * 1000; // needs to be far to support Cesium's world-scale rendering
  39. this.scene = new THREE.Scene();
  40. this.camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
  41. this.renderer = new THREE.WebGLRenderer({ alpha: true });
  42. threeContainer.appendChild(this.renderer.domElement);
  43. }
  44. /**
  45. * 对象添加到地图上的创建钩子方法,
  46. * 每次add时都会调用
  47. * @return {void} 无
  48. * @private
  49. */
  50. _addedHook() {
  51. if (this._container) {
  52. this._map.container.appendChild(this._container);
  53. }
  54. this._map.useDefaultRenderLoop = false; //关闭自动渲染
  55. let that = this;
  56. (function frame() {
  57. //animateFrame: requestAnimationFrame事件句柄,用来清除操作
  58. that._animateFrame = window.requestAnimationFrame(frame);
  59. that.update(); //按帧率执行
  60. })();
  61. }
  62. /**
  63. * 对象从地图上移除的创建钩子方法,
  64. * 每次remove时都会调用
  65. * @return {void} 无
  66. * @private
  67. */
  68. _removedHook() {
  69. window.cancelAnimationFrame(this._animateFrame);
  70. delete this._animateFrame;
  71. this._map.useDefaultRenderLoop = true;
  72. if (this._container) {
  73. this._map.container.removeChild(this._container);
  74. }
  75. }
  76. update() {
  77. this.renderCesium();
  78. this.renderThreeObj();
  79. this.renderCamera();
  80. }
  81. renderCesium() {
  82. this._map.viewer.render();
  83. }
  84. renderThreeObj() {
  85. var width = this._container.clientWidth;
  86. var height = this._container.clientHeight;
  87. this.renderer.setSize(width, height);
  88. this.renderer.render(this.scene, this.camera);
  89. }
  90. renderCamera() {
  91. // register Three.js scene with Cesium
  92. this.camera.fov = Cesium.Math.toDegrees(this._map.camera.frustum.fovy); // ThreeJS FOV is vertical
  93. this.camera.updateProjectionMatrix();
  94. // Clone Cesium Camera projection position so the
  95. // Three.js Object will appear to be at the same place as above the Cesium Globe
  96. this.camera.matrixAutoUpdate = false;
  97. this.camera.lookAt(new THREE.Vector3(0, 0, 0));
  98. var cvm = this._map.camera.viewMatrix;
  99. var civm = this._map.camera.inverseViewMatrix;
  100. this.camera.matrixWorld.set(
  101. civm[0],
  102. civm[4],
  103. civm[8],
  104. civm[12],
  105. civm[1],
  106. civm[5],
  107. civm[9],
  108. civm[13],
  109. civm[2],
  110. civm[6],
  111. civm[10],
  112. civm[14],
  113. civm[3],
  114. civm[7],
  115. civm[11],
  116. civm[15]
  117. );
  118. this.camera.matrixWorldInverse.set(
  119. cvm[0],
  120. cvm[4],
  121. cvm[8],
  122. cvm[12],
  123. cvm[1],
  124. cvm[5],
  125. cvm[9],
  126. cvm[13],
  127. cvm[2],
  128. cvm[6],
  129. cvm[10],
  130. cvm[14],
  131. cvm[3],
  132. cvm[7],
  133. cvm[11],
  134. cvm[15]
  135. );
  136. var width = this._map.scene.canvas.clientWidth;
  137. var height = this._map.scene.canvas.clientHeight;
  138. this.camera.aspect = width / height;
  139. this.renderer.setSize(width, height);
  140. this.camera.updateProjectionMatrix();
  141. this.renderer.clear();
  142. this.renderer.render(this.scene, this.camera);
  143. }
  144. }