fireDoor.threejs.ts 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  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. fhmType = type;
  86. const fhmConfigurations = {
  87. fireDoor: {
  88. render: fireDoor ? () => fireDoor.render() : null,
  89. group: fireDoor ? fireDoor.group : null,
  90. newP: { x: -654.2006991449887, y: 103.16181473511944, z: -30.348656073478562 },
  91. newT: { x: -7.380506513422206, y: 56.36967052459397, z: -29.230675020846963 },
  92. },
  93. fireDoorF: {
  94. render: fireDoorF ? () => fireDoorF.render() : null,
  95. group: fireDoorF ? fireDoorF.group : null,
  96. newP: { x: -655.0169729333649, y: 47.24181078408825, z: -9.781926649842067 },
  97. newT: { x: -7.380506513422206, y: 47.24181078408821, z: -37.9244016972381 },
  98. },
  99. fireDoorSsl: {
  100. render: fireDoorSsl ? () => fireDoorSsl.render() : null,
  101. group: fireDoorSsl ? fireDoorSsl.group : null,
  102. newP: { x: 342.74781900192056, y: 183.50210411099545, z: 451.0806333923029 },
  103. newT: { x: 72.33938301176254, y: -35.03891296652319, z: -37.91742549963208 },
  104. },
  105. fireDoorRed: {
  106. render: fireDoorRed ? () => fireDoorRed.render() : null,
  107. group: fireDoorRed ? fireDoorRed.group : null,
  108. newP: { x: 66.14, y: 52.98, z: 112.23 },
  109. newT: { x: 6.049, y: 7.907, z: -25.566 },
  110. },
  111. };
  112. if (type == 'fireDoor' || type == 'fireDoorF') {
  113. model.orbitControls.maxPolarAngle = Math.PI / 2;
  114. model.orbitControls.minPolarAngle = Math.PI / 3;
  115. model.orbitControls.minDistance = 600;
  116. model.orbitControls.maxDistance = 900;
  117. model.orbitControls.update();
  118. } else if (type == 'fireDoorRed' || type == 'fireDoorSsl') {
  119. model.orbitControls.maxPolarAngle = Math.PI;
  120. model.orbitControls.minPolarAngle = 0;
  121. model.orbitControls.enableRotate = true;
  122. model.orbitControls.minDistance = 0;
  123. model.orbitControls.maxDistance = Infinity;
  124. model.orbitControls.update();
  125. }
  126. const config = fhmConfigurations[fhmType];
  127. const oldCameraPosition = { x: -1000, y: 100, z: 500 };
  128. return new Promise((resolve) => {
  129. if (config && config.group) {
  130. model.startAnimation = config.render;
  131. group = config.group;
  132. setTimeout(async () => {
  133. await animateCamera(oldCameraPosition, { x: 0, y: 0, z: 0 }, config.newP, config.newT, model);
  134. model.scene?.add(config.group);
  135. resolve(null);
  136. }, 1000);
  137. } else {
  138. resolve(null);
  139. throw new Error(`Unsupported fhmType: ${fhmType}`);
  140. }
  141. });
  142. };
  143. export const initCameraCanvas = async (playerVal1) => {
  144. if (fhmType === 'fireDoor' && fireDoor) {
  145. return await fireDoor.initCamera.call(fireDoor, playerVal1);
  146. } else if (fhmType === 'fireDoorF' && fireDoorF) {
  147. return await fireDoorF.initCamera.call(fireDoorF, playerVal1);
  148. } else if (fhmType === 'fireDoorSsl' && fireDoorSsl) {
  149. return await fireDoorSsl.initCamera.call(fireDoorSsl, playerVal1);
  150. } else if (fhmType === 'fireDoorRed' && fireDoorRed) {
  151. return await fireDoorRed.initCamera.call(fireDoorRed, playerVal1);
  152. }
  153. };
  154. const loadModel = (code): Promise<any> => {
  155. if (code === 'fireDoor') return import('./fireDoor.threejs.fire').then((r) => r.default);
  156. if (code === 'fireDoorF') return import('./fireDoor.threejs.fireF').then((r) => r.default);
  157. if (code === 'fireDoorSsl') return import('./fireDoor.threejs.ssl').then((r) => r.default);
  158. if (code === 'fireDoorRed') return import('./fireDoor.threejs.fire.redGate').then((r) => r.default);
  159. return import('./fireDoor.threejs.fire.redGate').then((r) => r.default);
  160. };
  161. export const mountedThree = () => {
  162. return new Promise(async (resolve) => {
  163. model = new UseThree('#damper3D', '', '#deviceDetail');
  164. model.setEnvMap('test1.hdr');
  165. model.renderer.toneMappingExposure = 1.0;
  166. model.camera.position.set(100, 0, 1000);
  167. const dictCodes = getDictItemsByCode('fireDoorStyle');
  168. if (dictCodes && dictCodes.length > 0) {
  169. for (let i = 0; i < dictCodes.length; i++) {
  170. const dict = dictCodes[i];
  171. switch (dict.value) {
  172. case 'fireDoor':
  173. const FireDoor = await loadModel('fireDoor');
  174. fireDoor = new FireDoor(model);
  175. fireDoor.mountedThree();
  176. break;
  177. case 'fireDoorF':
  178. const FireDoorF = await loadModel('fireDoorF');
  179. fireDoorF = new FireDoorF(model);
  180. fireDoorF.mountedThree();
  181. break;
  182. case 'fireDoorSsl':
  183. const FireDoorSsl = await loadModel('fireDoorSsl');
  184. fireDoorSsl = new FireDoorSsl(model);
  185. fireDoorSsl.mountedThree();
  186. break;
  187. case 'fireDoorRed':
  188. const FireDoorRed = await loadModel('fireDoorRed');
  189. fireDoorRed = new FireDoorRed(model);
  190. fireDoorRed.mountedThree();
  191. break;
  192. }
  193. }
  194. resolve(null);
  195. } else {
  196. const FireDoorRed = await loadModel('');
  197. fireDoorRed = new FireDoorRed(model);
  198. fireDoorRed.mountedThree();
  199. }
  200. resolve(null);
  201. model.animate();
  202. startAnimation();
  203. });
  204. };
  205. export const destroy = () => {
  206. if (model) {
  207. model.orbitControls.maxPolarAngle = Math.PI;
  208. model.orbitControls.minPolarAngle = 0;
  209. model.orbitControls.enableRotate = true;
  210. model.orbitControls.minDistance = 0;
  211. model.orbitControls.maxDistance = Infinity;
  212. model.orbitControls.update();
  213. model.isRender = false;
  214. if (fireDoor) fireDoor.destroy();
  215. fireDoor = null;
  216. if (fireDoorF) fireDoorF.destroy();
  217. fireDoorF = null;
  218. if (fireDoorSsl) fireDoorSsl.destroy();
  219. fireDoorSsl = null;
  220. if (fireDoorRed) fireDoorRed.destroy();
  221. fireDoorRed = null;
  222. // @ts-ignore-next-line
  223. group = null;
  224. model.mixers = [];
  225. model.destroy();
  226. }
  227. model = null;
  228. };