fireDoor.threejs.fire.redGate.ts 5.0 KB

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