fireDoor.threejs.ts 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. import * as THREE from 'three';
  2. import UseThree from '../../../../utils/threejs/useThree';
  3. import { getDictItemsByCode } from '/@/utils/dict';
  4. import { animateCamera } from '/@/utils/threejs/util';
  5. import useEvent from '../../../../utils/threejs/useEvent';
  6. // 模型对象、 文字对象
  7. let model,
  8. fireDoor, //液压风门
  9. fireDoorF, //保德风门
  10. fireDoorSsl, // 思山岭防火门
  11. fireDoorRed, // 防火门
  12. group: THREE.Object3D,
  13. fhmType = '';
  14. const { mouseDownFn } = useEvent();
  15. // 初始化左右摇摆动画
  16. const startAnimation = () => {
  17. // 定义鼠标点击事件
  18. model.canvasContainer?.addEventListener('mousedown', mouseEvent.bind(null));
  19. model.canvasContainer?.addEventListener('pointerup', (event) => {
  20. event.stopPropagation();
  21. // 单道、 双道
  22. if (fhmType === 'fireDoor') {
  23. fireDoor?.mouseUpModel.call(fireDoor);
  24. }
  25. if (fhmType === 'fireDoorF') {
  26. fireDoorF?.mouseUpModel.call(fireDoorF);
  27. }
  28. if (fhmType === 'fireDoorSsl') {
  29. fireDoorSsl?.mouseUpModel.call(fireDoorSsl);
  30. }
  31. if (fhmType === 'fireDoorRed') {
  32. fireDoorRed?.mouseUpModel.call(fireDoorRed);
  33. }
  34. });
  35. };
  36. // 鼠标点击、松开事件
  37. const mouseEvent = (event) => {
  38. if (event.button == 0) {
  39. mouseDownFn(model, group, event, (intersects) => {
  40. if (fhmType === 'fireDoor' && fireDoor) {
  41. fireDoor?.mousedownModel.call(fireDoor, intersects);
  42. }
  43. if (fhmType === 'fireDoorF' && fireDoorF) {
  44. fireDoorF?.mousedownModel.call(fireDoorF, intersects);
  45. }
  46. if (fhmType === 'fireDoorSsl' && fireDoorSsl) {
  47. fireDoorSsl?.mousedownModel.call(fireDoorSsl, intersects);
  48. }
  49. if (fhmType === 'fireDoorRed' && fireDoorRed) {
  50. fireDoorRed?.mousedownModel.call(fireDoorRed, intersects);
  51. }
  52. });
  53. // console.log('摄像头控制信息', model.orbitControls, model.camera);
  54. }
  55. };
  56. export const play = (handlerState, flag?) => {
  57. if (fhmType === 'fireDoor' && fireDoor) {
  58. return fireDoor.play.call(fireDoor, handlerState, flag);
  59. }
  60. if (fhmType === 'fireDoorF' && fireDoorF) {
  61. return fireDoorF.play.call(fireDoorF, handlerState, flag);
  62. }
  63. if (fhmType === 'fireDoorSsl' && fireDoorSsl) {
  64. return fireDoorSsl.play.call(fireDoorSsl, handlerState, flag);
  65. }
  66. if (fhmType === 'fireDoorRed' && fireDoorRed) {
  67. return fireDoorRed.play.call(fireDoorRed, handlerState, flag);
  68. }
  69. };
  70. // 切换风门类型
  71. export const setModelType = (type) => {
  72. // 重置动画
  73. if (fhmType === 'fireDoor' && fireDoor) {
  74. fireDoor.resetAnimate();
  75. }
  76. if (fhmType === 'fireDoorF' && fireDoorF) {
  77. fireDoorF.resetAnimate();
  78. }
  79. if (fhmType === 'fireDoorSsl' && fireDoorSsl) {
  80. fireDoorSsl.resetAnimate();
  81. }
  82. if (fhmType === 'fireDoorRed' && fireDoorRed) {
  83. fireDoorRed.resetAnimate();
  84. }
  85. const fhmConfigurations = {
  86. fireDoor: {
  87. render: fireDoor ? () => fireDoor.render() : null,
  88. group: fireDoor ? fireDoor.group : null,
  89. newP: { x: -654.2006991449887, y: 103.16181473511944, z: -30.348656073478562 },
  90. newT: { x: -7.380506513422206, y: 56.36967052459397, z: -29.230675020846963 },
  91. },
  92. fireDoorF: {
  93. render: fireDoorF ? () => fireDoorF.render() : null,
  94. group: fireDoorF ? fireDoorF.group : null,
  95. newP: { x: -655.0169729333649, y: 47.24181078408825, z: -9.781926649842067 },
  96. newT: { x: -7.380506513422206, y: 47.24181078408821, z: -37.9244016972381 },
  97. },
  98. fireDoorSsl: {
  99. render: fireDoorSsl ? () => fireDoorSsl.render() : null,
  100. group: fireDoorSsl ? fireDoorSsl.group : null,
  101. newP: { x: 342.74781900192056, y: 183.50210411099545, z: 451.0806333923029 },
  102. newT: { x: 72.33938301176254, y: -35.03891296652319, z: -37.91742549963208 },
  103. },
  104. fireDoorRed: {
  105. render: fireDoorRed ? () => fireDoorRed.render() : null,
  106. group: fireDoorRed ? fireDoorRed.group : null,
  107. newP: { x: 66.14, y: 52.98, z: 112.23 },
  108. newT: { x: 6.049, y: 7.907, z: -25.566 },
  109. },
  110. };
  111. const oldConfig = fhmConfigurations[fhmType];
  112. const config = fhmConfigurations[type];
  113. fhmType = type;
  114. if (type == 'fireDoor' || type == 'fireDoorF') {
  115. model.orbitControls.maxPolarAngle = Math.PI / 2;
  116. model.orbitControls.minPolarAngle = Math.PI / 3;
  117. model.orbitControls.minDistance = 600;
  118. model.orbitControls.maxDistance = 900;
  119. model.orbitControls.update();
  120. } else if (type == 'fireDoorRed' || type == 'fireDoorSsl') {
  121. model.orbitControls.maxPolarAngle = Math.PI;
  122. model.orbitControls.minPolarAngle = 0;
  123. model.orbitControls.enableRotate = true;
  124. model.orbitControls.minDistance = 0;
  125. model.orbitControls.maxDistance = Infinity;
  126. model.orbitControls.update();
  127. }
  128. const oldCameraPosition = { x: -1000, y: 100, z: 500 };
  129. return new Promise((resolve) => {
  130. if (oldConfig && oldConfig.group) {
  131. model.scene?.remove(oldConfig.group);
  132. }
  133. if (config && config.group) {
  134. model.startAnimation = config.render;
  135. group = config.group;
  136. setTimeout(async () => {
  137. await animateCamera(oldCameraPosition, { x: 0, y: 0, z: 0 }, config.newP, config.newT, model);
  138. model.scene?.add(config.group);
  139. resolve(null);
  140. }, 1000);
  141. } else {
  142. resolve(null);
  143. throw new Error(`Unsupported fhmType: ${fhmType}`);
  144. }
  145. });
  146. };
  147. export const initCameraCanvas = async (playerVal1) => {
  148. if (fhmType === 'fireDoor' && fireDoor) {
  149. return await fireDoor.initCamera.call(fireDoor, playerVal1);
  150. } else if (fhmType === 'fireDoorF' && fireDoorF) {
  151. return await fireDoorF.initCamera.call(fireDoorF, playerVal1);
  152. } else if (fhmType === 'fireDoorSsl' && fireDoorSsl) {
  153. return await fireDoorSsl.initCamera.call(fireDoorSsl, playerVal1);
  154. } else if (fhmType === 'fireDoorRed' && fireDoorRed) {
  155. return await fireDoorRed.initCamera.call(fireDoorRed, playerVal1);
  156. }
  157. };
  158. const loadModel = (code): Promise<any> => {
  159. if (code === 'fireDoor') return import('./fireDoor.threejs.fire').then((r) => r.default);
  160. if (code === 'fireDoorF') return import('./fireDoor.threejs.fireF').then((r) => r.default);
  161. if (code === 'fireDoorSsl') return import('./fireDoor.threejs.ssl').then((r) => r.default);
  162. if (code === 'fireDoorRed') return import('./fireDoor.threejs.fire.redGate').then((r) => r.default);
  163. return import('./fireDoor.threejs.fire.redGate').then((r) => r.default);
  164. };
  165. export const mountedThree = () => {
  166. return new Promise(async (resolve) => {
  167. model = new UseThree('#damper3D', '', '#deviceDetail');
  168. model.setEnvMap('test1.hdr');
  169. model.renderer.toneMappingExposure = 1.0;
  170. model.camera.position.set(100, 0, 1000);
  171. const dictCodes = getDictItemsByCode('fireDoorStyle');
  172. if (dictCodes && dictCodes.length > 0) {
  173. for (let i = 0; i < dictCodes.length; i++) {
  174. const dict = dictCodes[i];
  175. switch (dict.value) {
  176. case 'fireDoor':
  177. const FireDoor = await loadModel('fireDoor');
  178. fireDoor = new FireDoor(model);
  179. fireDoor.mountedThree();
  180. break;
  181. case 'fireDoorF':
  182. const FireDoorF = await loadModel('fireDoorF');
  183. fireDoorF = new FireDoorF(model);
  184. fireDoorF.mountedThree();
  185. break;
  186. case 'fireDoorSsl':
  187. const FireDoorSsl = await loadModel('fireDoorSsl');
  188. fireDoorSsl = new FireDoorSsl(model);
  189. fireDoorSsl.mountedThree();
  190. break;
  191. case 'fireDoorRed':
  192. const FireDoorRed = await loadModel('fireDoorRed');
  193. fireDoorRed = new FireDoorRed(model);
  194. fireDoorRed.mountedThree();
  195. break;
  196. }
  197. }
  198. resolve(null);
  199. } else {
  200. const FireDoorRed = await loadModel('');
  201. fireDoorRed = new FireDoorRed(model);
  202. fireDoorRed.mountedThree();
  203. }
  204. resolve(null);
  205. model.animate();
  206. startAnimation();
  207. });
  208. };
  209. export const destroy = () => {
  210. if (model) {
  211. model.orbitControls.maxPolarAngle = Math.PI;
  212. model.orbitControls.minPolarAngle = 0;
  213. model.orbitControls.enableRotate = true;
  214. model.orbitControls.minDistance = 0;
  215. model.orbitControls.maxDistance = Infinity;
  216. model.orbitControls.update();
  217. model.isRender = false;
  218. if (fireDoor) fireDoor.destroy();
  219. fireDoor = null;
  220. if (fireDoorF) fireDoorF.destroy();
  221. fireDoorF = null;
  222. if (fireDoorSsl) fireDoorSsl.destroy();
  223. fireDoorSsl = null;
  224. if (fireDoorRed) fireDoorRed.destroy();
  225. fireDoorRed = null;
  226. // @ts-ignore-next-line
  227. group = null;
  228. model.mixers = [];
  229. model.destroy();
  230. }
  231. model = null;
  232. };