fireDoor.threejs.ts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  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. fhmType = type;
  73. const fhmConfigurations = {
  74. fireDoor: {
  75. render: fireDoor ? () => fireDoor.render() : null,
  76. group: fireDoor ? fireDoor.group : null,
  77. newP: { x: -654.2006991449887, y: 103.16181473511944, z: -30.348656073478562 },
  78. newT: { x: -7.380506513422206, y: 56.36967052459397, z: -29.230675020846963 },
  79. },
  80. fireDoorF: {
  81. render: fireDoorF ? () => fireDoorF.render() : null,
  82. group: fireDoorF ? fireDoorF.group : null,
  83. newP: { x: -655.0169729333649, y: 47.24181078408825, z: -9.781926649842067 },
  84. newT: { x: -7.380506513422206, y: 47.24181078408821, z: -37.9244016972381 },
  85. },
  86. fireDoorSsl: {
  87. render: fireDoorSsl ? () => fireDoorSsl.render() : null,
  88. group: fireDoorSsl ? fireDoorSsl.group : null,
  89. newP: { x: 342.74781900192056, y: 183.50210411099545, z: 451.0806333923029 },
  90. newT: { x: 72.33938301176254, y: -35.03891296652319, z: -37.91742549963208 },
  91. },
  92. fireDoorRed: {
  93. render: fireDoorRed ? () => fireDoorRed.render() : null,
  94. group: fireDoorRed ? fireDoorRed.group : null,
  95. newP: { x: 66.257, y: 57.539, z: 94.313 },
  96. newT: { x: -2.28, y: -0.91, z: -5.68 },
  97. },
  98. };
  99. const config = fhmConfigurations[fhmType];
  100. const oldCameraPosition = { x: -1000, y: 100, z: 500 };
  101. return new Promise((resolve) => {
  102. // 暂停风门1动画
  103. // if (fhmType === 'fireDoor' && fireDoor && fireDoor.group) {
  104. // if (fireDoor.clipActionArr.door) {
  105. // fireDoor.clipActionArr.door.reset();
  106. // fireDoor.clipActionArr.door.time = 0.5;
  107. // fireDoor.clipActionArr.door.stop();
  108. // }
  109. // if (fireDoor.damperOpenMesh) fireDoor.damperOpenMesh.visible = false;
  110. // if (fireDoor.damperClosedMesh) fireDoor.damperClosedMesh.visible = true;
  111. // model.scene.remove(group);
  112. // model.startAnimation = fireDoor.render.bind(fireDoor);
  113. // group = fireDoor.group;
  114. // group.rotation.y = 0;
  115. // const oldCameraPosition = { x: -1000, y: 100, z: 500 };
  116. // setTimeout(async () => {
  117. // resolve(null);
  118. // model.scene.add(fireDoor.group);
  119. // await animateCamera(
  120. // oldCameraPosition,
  121. // { x: 0, y: 0, z: 0 },
  122. // { x: -654.2006991449887, y: 103.16181473511944, z: -30.348656073478562 },
  123. // { x: -7.380506513422206, y: 56.36967052459397, z: -29.230675020846963 },
  124. // model,
  125. // 0.8
  126. // );
  127. // }, 300);
  128. // } else if (fhmType === 'fireDoorF' && fireDoorF && fireDoorF.group) {
  129. // if (fireDoorF.clipActionArr.door) {
  130. // fireDoorF.clipActionArr.door.reset();
  131. // fireDoorF.clipActionArr.door.time = 0;
  132. // fireDoorF.clipActionArr.door.stop();
  133. // }
  134. // model.scene.remove(group);
  135. // model.startAnimation = fireDoorF.render.bind(fireDoorF);
  136. // group = fireDoorF.group;
  137. // group.rotation.y = 0;
  138. // const oldCameraPosition = { x: -1000, y: 100, z: 500 };
  139. // setTimeout(async () => {
  140. // resolve(null);
  141. // model.scene.add(fireDoorF.group);
  142. // await animateCamera(
  143. // oldCameraPosition,
  144. // { x: 0, y: 0, z: 0 },
  145. // { x: -655.0169729333649, y: 47.24181078408825, z: -9.781926649842067 },
  146. // { x: -7.380506513422206, y: 47.24181078408821, z: -37.9244016972381 },
  147. // model,
  148. // 0.8
  149. // );
  150. // }, 300);
  151. // } else if (fhmType === 'fireDoorSsl' && fireDoorSsl && fireDoorSsl.group) {
  152. // // if (fireDoorSsl.clipActionArr.door) {
  153. // // fireDoorSsl.clipActionArr.door.reset();
  154. // // fireDoorSsl.clipActionArr.door.time = 0;
  155. // // fireDoorSsl.clipActionArr.door.stop();
  156. // // }
  157. // // model.scene.remove(group);
  158. // // model.startAnimation = fireDoorSsl.render.bind(fireDoorSsl);
  159. // group = fireDoorSsl.group;
  160. // group.rotation.y = 0;
  161. // const oldCameraPosition = { x: -1000, y: 100, z: 500 };
  162. // setTimeout(async () => {
  163. // resolve(null);
  164. // model.scene.add(fireDoorSsl.group);
  165. // await animateCamera(
  166. // oldCameraPosition,
  167. // { x: 0, y: 0, z: 0 },
  168. // {
  169. // x: 342.74781900192056,
  170. // y: 183.50210411099545,
  171. // z: 451.0806333923029,
  172. // },
  173. // {
  174. // x: 72.33938301176254,
  175. // y: -35.03891296652319,
  176. // z: -37.91742549963208,
  177. // },
  178. // model,
  179. // 0.8
  180. // );
  181. // }, 300);
  182. // }
  183. if (config && config.group) {
  184. model.startAnimation = config.render;
  185. group = config.group;
  186. setTimeout(async () => {
  187. await animateCamera(oldCameraPosition, { x: 0, y: 0, z: 0 }, config.newP, config.newT, model);
  188. model.scene?.add(config.group);
  189. resolve(null);
  190. }, 1000);
  191. } else {
  192. resolve(null);
  193. throw new Error(`Unsupported fhmType: ${fhmType}`);
  194. }
  195. });
  196. };
  197. export const initCameraCanvas = async (playerVal1) => {
  198. if (fhmType === 'fireDoor' && fireDoor) {
  199. return await fireDoor.initCamera.call(fireDoor, playerVal1);
  200. } else if (fhmType === 'fireDoorF' && fireDoorF) {
  201. return await fireDoorF.initCamera.call(fireDoorF, playerVal1);
  202. } else if (fhmType === 'fireDoorSsl' && fireDoorSsl) {
  203. return await fireDoorSsl.initCamera.call(fireDoorSsl, playerVal1);
  204. } else if (fhmType === 'fireDoorRed' && fireDoorRed) {
  205. return await fireDoorRed.initCamera.call(fireDoorRed, playerVal1);
  206. }
  207. };
  208. const setControls = () => {
  209. if (model && model.orbitControls) {
  210. model.orbitControls.maxPolarAngle = Math.PI / 2;
  211. model.orbitControls.minPolarAngle = Math.PI / 3;
  212. model.orbitControls.minDistance = 600;
  213. model.orbitControls.maxDistance = 900;
  214. }
  215. };
  216. const loadModel = (code): Promise<any> => {
  217. if (code === 'fireDoor') return import('./fireDoor.threejs.fire').then((r) => r.default);
  218. if (code === 'fireDoorF') return import('./fireDoor.threejs.fireF').then((r) => r.default);
  219. if (code === 'fireDoorSsl') return import('./fireDoor.threejs.ssl').then((r) => r.default);
  220. if (code === 'fireDoorRed') return import('./fireDoor.threejs.fire.redGate').then((r) => r.default);
  221. return import('./fireDoor.threejs.fire.redGate').then((r) => r.default);
  222. };
  223. export const mountedThree = () => {
  224. return new Promise(async (resolve) => {
  225. model = new UseThree('#damper3D', '', '#deviceDetail');
  226. model.setEnvMap('test1.hdr');
  227. model.renderer.toneMappingExposure = 1.0;
  228. model.camera.position.set(100, 0, 1000);
  229. const dictCodes = getDictItemsByCode('fireDoorStyle');
  230. if (dictCodes && dictCodes.length > 0) {
  231. for (let i = 0; i < dictCodes.length; i++) {
  232. const dict = dictCodes[i];
  233. switch (dict.value) {
  234. case 'fireDoor':
  235. const FireDoor = await loadModel('fireDoor');
  236. fireDoor = new FireDoor(model);
  237. fireDoor.mountedThree();
  238. break;
  239. case 'fireDoorF':
  240. const FireDoorF = await loadModel('fireDoorF');
  241. fireDoorF = new FireDoorF(model);
  242. fireDoorF.mountedThree();
  243. break;
  244. case 'fireDoorSsl':
  245. const FireDoorSsl = await loadModel('fireDoorSsl');
  246. fireDoorSsl = new FireDoorSsl(model);
  247. fireDoorSsl.mountedThree();
  248. break;
  249. case 'fireDoorRed':
  250. const FireDoorRed = await loadModel('fireDoorRed');
  251. fireDoorRed = new FireDoorRed(model);
  252. fireDoorRed.mountedThree();
  253. break;
  254. }
  255. }
  256. resolve(null);
  257. } else {
  258. const FireDoorRed = await loadModel('');
  259. fireDoorRed = new FireDoorRed(model);
  260. fireDoorRed.mountedThree();
  261. }
  262. resolve(null);
  263. setControls();
  264. model.animate();
  265. startAnimation();
  266. });
  267. };
  268. export const destroy = () => {
  269. if (model) {
  270. model.orbitControls.maxPolarAngle = Math.PI;
  271. model.orbitControls.minPolarAngle = 0;
  272. model.orbitControls.enableRotate = true;
  273. model.orbitControls.minDistance = 0;
  274. model.orbitControls.maxDistance = Infinity;
  275. model.orbitControls.update();
  276. model.isRender = false;
  277. if (fireDoor) fireDoor.destroy();
  278. fireDoor = null;
  279. if (fireDoorF) fireDoorF.destroy();
  280. fireDoorF = null;
  281. if (fireDoorSsl) fireDoorSsl.destroy();
  282. fireDoorSsl = null;
  283. if (fireDoorRed) fireDoorRed.destroy();
  284. fireDoorRed = null;
  285. // @ts-ignore-next-line
  286. group = null;
  287. model.mixers = [];
  288. model.destroy();
  289. }
  290. model = null;
  291. };