fireDoor.threejs.fireF.ts 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import * as THREE from 'three';
  2. import { useAppStore } from '/@/store/modules/app';
  3. // import * as dat from 'dat.gui';
  4. // const gui = new dat.GUI();
  5. // gui.domElement.style = 'position:absolute;top:100px;left:10px;z-index:99999999999999';
  6. class FireDoorF {
  7. modelName = 'fireDoorF';
  8. model; //
  9. group;
  10. isLRAnimation = true; // 是否开启左右摇摆动画
  11. direction = 1; // 摇摆方向
  12. animationTimer: NodeJS.Timeout | null = null; // 摇摆开启定时器
  13. player1;
  14. player2;
  15. deviceDetailCSS3D;
  16. playerStartClickTime1 = new Date().getTime();
  17. playerStartClickTime2 = new Date().getTime();
  18. fmClock = new THREE.Clock();
  19. mixers: THREE.AnimationMixer | undefined;
  20. appStore = useAppStore();
  21. damperOpenMesh;
  22. damperClosedMesh;
  23. clipActionArr = {
  24. door: null as unknown as THREE.AnimationAction,
  25. };
  26. constructor(model) {
  27. this.model = model;
  28. }
  29. addLight() {
  30. const directionalLight = new THREE.DirectionalLight(0xffffff, 1.5);
  31. directionalLight.position.set(344, 690, 344);
  32. this.group?.add(directionalLight);
  33. directionalLight.target = this.group as THREE.Object3D;
  34. const pointLight2 = new THREE.PointLight(0xffeeee, 1, 300);
  35. pointLight2.position.set(-4, 10, 1.8);
  36. pointLight2.shadow.bias = 0.05;
  37. this.group?.add(pointLight2);
  38. const pointLight3 = new THREE.PointLight(0xffeeee, 1, 200);
  39. pointLight3.position.set(-0.5, -0.5, 0.75);
  40. pointLight3.shadow.bias = 0.05;
  41. this.group?.add(pointLight3);
  42. }
  43. resetCamera() {
  44. this.model.camera.far = 274;
  45. this.model.orbitControls?.update();
  46. this.model.camera.updateProjectionMatrix();
  47. }
  48. // 设置模型位置
  49. setModalPosition() {
  50. this.group?.scale.set(22, 22, 22);
  51. this.group?.position.set(-20, 20, 9);
  52. }
  53. /* 风门动画 */
  54. render() {
  55. if (!this.model) {
  56. return;
  57. }
  58. if (this.mixers && this.fmClock.running) {
  59. this.mixers.update(2);
  60. }
  61. }
  62. /* 点击风门 */
  63. mousedownModel(intersects: THREE.Intersection<THREE.Object3D<THREE.Event>>[]) {
  64. console.log('摄像头控制信息', this.model?.orbitControls, this.model?.camera);
  65. }
  66. mouseUpModel() {}
  67. /* 提取风门序列帧,初始化前后门动画 */
  68. initAnimation() {
  69. debugger;
  70. const fireGroup = this.group.children[0]?.getObjectByName('Fire-doorf');
  71. if (fireGroup) {
  72. const tracks = fireGroup.animations[0].tracks;
  73. debugger;
  74. this.mixers = new THREE.AnimationMixer(fireGroup.children[0]);
  75. const door = new THREE.AnimationClip('door', 100, tracks);
  76. const frontClipAction = this.mixers.clipAction(door, fireGroup);
  77. frontClipAction.clampWhenFinished = true;
  78. frontClipAction.loop = THREE.LoopOnce;
  79. this.clipActionArr.door = frontClipAction;
  80. }
  81. }
  82. // 播放动画
  83. play(handlerState, timeScale = 0.01) {
  84. debugger;
  85. let handler = () => {};
  86. if (this.clipActionArr.door) {
  87. switch (handlerState) {
  88. case 1: // 打开门
  89. handler = () => {
  90. this.clipActionArr.door.paused = true;
  91. this.clipActionArr.door.reset();
  92. this.clipActionArr.door.time = 1.7;
  93. this.clipActionArr.door.timeScale = -timeScale;
  94. // this.clipActionArr.door.clampWhenFinished = true;
  95. this.clipActionArr.door.play();
  96. this.fmClock.start();
  97. // 显示打开前门文字
  98. if (this.damperOpenMesh) this.damperOpenMesh.visible = true;
  99. };
  100. break;
  101. case 2: // 关闭门
  102. handler = () => {
  103. this.clipActionArr.door.paused = true;
  104. this.clipActionArr.door.reset(); //
  105. this.clipActionArr.door.time = 0;
  106. this.clipActionArr.door.timeScale = timeScale;
  107. // this.clipActionArr.door.clampWhenFinished = true;
  108. this.clipActionArr.door.play();
  109. this.fmClock.start();
  110. if (this.damperOpenMesh) this.damperOpenMesh.visible = false;
  111. };
  112. break;
  113. default:
  114. }
  115. handler();
  116. }
  117. }
  118. mountedThree() {
  119. this.group = new THREE.Object3D();
  120. this.group.name = this.modelName;
  121. return new Promise((resolve) => {
  122. if (!this.model) {
  123. resolve(null);
  124. }
  125. this.model.setGLTFModel(['Fire-doorf'], this.group).then(() => {
  126. this.setModalPosition();
  127. console.log(this.group);
  128. // 初始化左右摇摆动画;
  129. this.initAnimation();
  130. });
  131. });
  132. }
  133. destroy() {
  134. if (this.model) {
  135. if (this.mixers) {
  136. this.mixers.uncacheClip(this.clipActionArr.door.getClip());
  137. this.mixers.uncacheAction(this.clipActionArr.door.getClip(), this.group);
  138. this.mixers.uncacheRoot(this.group);
  139. if (this.model.animations[0]) this.model.animations[0].tracks = [];
  140. }
  141. this.model.clearGroup(this.group);
  142. this.clipActionArr.door = undefined;
  143. this.mixers = undefined;
  144. // document.getElementById('damper3D').parentElement.remove(document.getElementById('damper3D'))
  145. }
  146. }
  147. }
  148. export default FireDoorF;