nitrogen.threejs.ts 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. import * as THREE from 'three';
  2. import { animateCamera, setModalCenter, updateAxisCenter } from '/@/utils/threejs/util';
  3. import UseThree from '../../../../utils/threejs/useThree';
  4. import NitrogenOverground from './nitrogen.dishang.threejs';
  5. import NitrogenUnderground from './nitrogen.dixia.threejs';
  6. import NitrogenFlex from './nitrogen.flex.threejs';
  7. import useEvent from '../../../../utils/threejs/useEvent';
  8. // import * as dat from 'dat.gui';
  9. // const gui = new dat.GUI();
  10. // gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
  11. // 模型对象、 文字对象
  12. let model: UseThree | undefined, //
  13. group: THREE.Object3D | undefined,
  14. nitrogenObj: NitrogenOverground | undefined,
  15. nitrogenUndergroundObj: NitrogenUnderground | undefined,
  16. nitrogenFlexObj: NitrogenFlex | undefined,
  17. modalType = 'nitrogen';
  18. const { mouseDownFn } = useEvent();
  19. // 鼠标点击、松开事件
  20. const mouseEvent = (event) => {
  21. if (event.button == 0) {
  22. mouseDownFn(model as UseThree, group as THREE.Object3D, event, (intersects) => {
  23. if (modalType === 'nitrogen') {
  24. nitrogenObj?.mousedownModel.call(nitrogenObj, intersects);
  25. }
  26. console.log('摄像头控制信息', model?.orbitControls, model?.camera);
  27. });
  28. }
  29. };
  30. /* 添加监控数据 */
  31. export const attachMonitorCards = () => {
  32. nitrogenUndergroundObj?.addCssText?.call(nitrogenUndergroundObj);
  33. };
  34. export const addText = () => {
  35. if (modalType === 'nitrogen') {
  36. return nitrogenObj?.addCssText?.call(nitrogenObj);
  37. }
  38. };
  39. export const play = () => {
  40. if (modalType === 'nitrogen') {
  41. return nitrogenObj?.play.call(nitrogenObj);
  42. }
  43. };
  44. // 切换风窗类型
  45. export const setModelType = (type, nitrogenNum?) => {
  46. modalType = type;
  47. model?.camera?.position.set(-1000, 100, 500);
  48. return new Promise((resolve) => {
  49. // 地上模型、地下模型切换
  50. if (modalType === 'nitrogen' && nitrogenObj && nitrogenObj.group) {
  51. if (model?.scene?.getObjectByName('nitrogenUnderground') && nitrogenUndergroundObj && nitrogenUndergroundObj.group) {
  52. model.scene.remove(nitrogenUndergroundObj.group);
  53. nitrogenUndergroundObj.clearCssText();
  54. }
  55. if (nitrogenNum) {
  56. nitrogenObj.nitrogenNum = nitrogenNum;
  57. const flag = nitrogenNum % 2 == 0 ? 0 : 1;
  58. const currentNitrogenNum = nitrogenObj.group.children.length - 2;
  59. // 判断地上注氮机的机数
  60. if (currentNitrogenNum < nitrogenNum) {
  61. for (let i = 0; i < nitrogenNum; i++) {
  62. let nitrogenModal = nitrogenObj.group.getObjectByName('nitrogenModal' + i) as THREE.Object3D;
  63. if (!nitrogenModal) {
  64. nitrogenModal = nitrogenObj.nitrogenGroup[i];
  65. nitrogenObj.group.add(nitrogenModal);
  66. }
  67. const c = Math.floor(nitrogenNum / 2);
  68. if (flag) {
  69. nitrogenModal.position.set(0, 0, 1.355 * (c - i));
  70. } else {
  71. nitrogenModal.position.set(0, 0, (c - i - 0.5) * 1.355);
  72. }
  73. }
  74. } else if (currentNitrogenNum > nitrogenNum) {
  75. for (let i = nitrogenNum - 1; i < nitrogenNum; i++) {
  76. const nitrogenModal = nitrogenObj.group.getObjectByName('nitrogenModal' + i) as THREE.Object3D;
  77. nitrogenObj.group.remove(nitrogenModal);
  78. }
  79. } else {
  80. }
  81. setModalCenter(nitrogenObj.group);
  82. nitrogenObj.addCssText();
  83. nitrogenObj.setModalPosition();
  84. }
  85. group = nitrogenObj.group;
  86. const oldCameraPosition = { x: -1000, y: 100, z: 500 };
  87. const oldControlsPosition = { x: -10, y: 10, z: 10 };
  88. model?.scene?.add(nitrogenObj.group);
  89. let newCameraPosition = { x: 0, y: 0, z: 0 },
  90. newControlsPosition = { x: 0, y: 0, z: 0 };
  91. debugger;
  92. if (group.children.length == 5) {
  93. newCameraPosition = { x: 3.4434042980363104, y: 34.06459454762187, z: 106.31900957493957 };
  94. newControlsPosition = { x: 3.060603700582905, y: -10.818677071155214, z: 6.036159227572685 };
  95. } else if (group.children.length == 4) {
  96. newCameraPosition = { x: 3.90030651836962, y: 38.026892031369755, z: 87.12943006242206 };
  97. newControlsPosition = { x: 3.584174940307743, y: -6.858117412269035, z: 4.311833565101436 };
  98. } else if (group.children.length == 3) {
  99. newCameraPosition = { x: 4.033864762820565, y: 46.68282110004381, z: 82.43762902763777 };
  100. newControlsPosition = { x: 3.7177327628205648, y: 1.7978121000437965, z: -0.37996697236224625 };
  101. } else if (group.children.length == 6) {
  102. newCameraPosition = { x: -112.9018092843876, y: 27.56046920110982, z: 1.512031119343565 };
  103. newControlsPosition = { x: -3.4116337023356875, y: -25.657219350386075, z: 1.0940848922982402 };
  104. }
  105. setTimeout(async () => {
  106. model?.scene?.add(group);
  107. resolve(null);
  108. await animateCamera(oldCameraPosition, oldControlsPosition, newCameraPosition, newControlsPosition, model, 0.8);
  109. }, 300);
  110. } else if (modalType === 'nitrogenUnderground' && nitrogenUndergroundObj && nitrogenUndergroundObj.group) {
  111. if (model?.scene?.getObjectByName('nitrogen') && nitrogenObj && nitrogenObj.group) {
  112. model.scene.remove(nitrogenObj.group);
  113. nitrogenObj.clearCssText();
  114. }
  115. nitrogenUndergroundObj.nitrogenNum = nitrogenNum;
  116. group = nitrogenUndergroundObj.group;
  117. nitrogenUndergroundObj.addCssText();
  118. const oldCameraPosition = { x: -1000, y: 100, z: 500 };
  119. const oldControlsPosition = { x: -10, y: 10, z: 10 };
  120. const fitted = nitrogenUndergroundObj.getCameraConfig?.();
  121. const newCameraPosition = fitted?.camera || { x: 21.7662617168586, y: 65.76772405405443, z: 106.19314654690366 },
  122. newControlsPosition = fitted?.target || { x: -13.223797639205223, y: 13.119121404116392, z: 0.7650646324543227 };
  123. setTimeout(async () => {
  124. model?.scene?.add(group);
  125. resolve(null);
  126. await animateCamera(oldCameraPosition, oldControlsPosition, newCameraPosition, newControlsPosition, model, 0.8);
  127. }, 300);
  128. } else if (modalType === 'nitrogenFlex' && nitrogenFlexObj && nitrogenFlexObj.group) {
  129. // 地下管路模型(基底 + 注氮机),与地上模型、地下管网模型三者共存,互不影响
  130. if (model?.scene?.getObjectByName('nitrogen') && nitrogenObj && nitrogenObj.group) {
  131. model.scene.remove(nitrogenObj.group);
  132. nitrogenObj.clearCssText();
  133. }
  134. if (model?.scene?.getObjectByName('nitrogenUnderground') && nitrogenUndergroundObj && nitrogenUndergroundObj.group) {
  135. model.scene.remove(nitrogenUndergroundObj.group);
  136. nitrogenUndergroundObj.clearCssText();
  137. }
  138. // 机数由后端决定(1~3 台),动态增减
  139. nitrogenFlexObj.setUnitCount(nitrogenNum ?? 3);
  140. group = nitrogenFlexObj.group;
  141. const oldCameraPosition = { x: -1000, y: 100, z: 500 };
  142. const oldControlsPosition = { x: -10, y: 10, z: 10 };
  143. const { camera, target } = nitrogenFlexObj.getCameraConfig();
  144. setTimeout(async () => {
  145. model?.scene?.add(group as THREE.Object3D);
  146. resolve(null);
  147. await animateCamera(oldCameraPosition, oldControlsPosition, camera, target, model, 0.8);
  148. }, 300);
  149. }
  150. });
  151. };
  152. /**
  153. * @param undergroundModelName 地下三维模型名称,默认 nitrogenUnderground
  154. */
  155. export const mountedThree = (undergroundModelName = 'nitrogenUnderground') => {
  156. return new Promise(async (resolve) => {
  157. model = new UseThree('#nitrogen3D', '#nitrogenCss3D');
  158. model.setEnvMap('test1.hdr');
  159. model.renderer.toneMappingExposure = 1.0;
  160. model.canvasContainer?.addEventListener('mousedown', mouseEvent.bind(null));
  161. nitrogenObj = new NitrogenOverground(model);
  162. await nitrogenObj.mountedThree(4);
  163. nitrogenUndergroundObj = new NitrogenUnderground(model, undergroundModelName);
  164. await nitrogenUndergroundObj.mountedThree();
  165. // 先展示地下主模型,避免柔性模型资源缺失/缓存异常阻塞整个监控界面
  166. setModelType('nitrogenUnderground');
  167. resolve(null);
  168. model.animate();
  169. // 地下管路模型(基底 + 注氮机)按需后台加载,失败不影响主界面
  170. nitrogenFlexObj = new NitrogenFlex(model);
  171. nitrogenFlexObj.mountedThree().catch((error) => {
  172. console.warn('[nitrogen] 柔性模型加载失败,已跳过', error);
  173. });
  174. });
  175. };
  176. export const destroy = () => {
  177. if (model) {
  178. model.isRender = false;
  179. console.log('场景销毁前信息----------->', model.renderer?.info);
  180. nitrogenObj?.destroy();
  181. nitrogenObj = undefined;
  182. nitrogenUndergroundObj?.destroy();
  183. nitrogenUndergroundObj = undefined;
  184. nitrogenFlexObj?.destroy();
  185. nitrogenFlexObj = undefined;
  186. group = undefined;
  187. model.destroy();
  188. model = undefined;
  189. }
  190. };