Player.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. import * as THREE from "three";
  2. import FloorplanControls from "../controls/FloorplanControls.js";
  3. import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
  4. import Line from "../box/object/Line";
  5. import LinePoints from "../box/object/LinePoints.js";
  6. import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js";
  7. const convertScreenToNDC = function (event, domElement) {
  8. let x = (event.offsetX / domElement.clientWidth) * 2 - 1;
  9. let y = -(event.offsetY / domElement.clientHeight) * 2 + 1;
  10. return new THREE.Vector2(x, y);
  11. };
  12. export default class Player {
  13. constructor(scene) {
  14. this.scene = scene;
  15. this.orthCamera = scene.orthCamera;
  16. this.floorplanControls = null;
  17. this.raycaster = null;
  18. this.position = new THREE.Vector3();
  19. this.pointerdown = new THREE.Vector2();
  20. this.pointerup = new THREE.Vector2();
  21. this.pointer = new THREE.Vector2();
  22. this.touchImg = null;
  23. this.activeEdge = null;
  24. this.drawLine = null;
  25. this.startObj = null;
  26. this.allowDrawing = false;
  27. this.drawing = false;
  28. this.inited = false;
  29. this.renderLines = [];
  30. this.activeEdges = [];
  31. this.matLine = null;
  32. this.lineColor = 0xe44d54;
  33. this.init();
  34. }
  35. init = () => {
  36. // //floorplanControls
  37. // this.floorplanControls = new FloorplanControls(this.orthCamera, this.scene.domElement, this);
  38. this.floorplanControls = new OrbitControls(
  39. this.orthCamera,
  40. this.scene.domElement
  41. );
  42. this.floorplanControls.enablePan = true;
  43. // this.floorplanControls.target.set(0, 1, 0);
  44. // this.floorplanControls.rotateSpeed = 0.5;
  45. // this.floorplanControls.panSpeed = 0.75
  46. // this.floorplanControls.maxDistance = 100
  47. // this.floorplanControls.minDistance = 3.5
  48. this.floorplanControls.maxZoom = 500;
  49. this.floorplanControls.minZoom = 100;
  50. this.floorplanControls.enableRotate = false;
  51. this.raycaster = new THREE.Raycaster();
  52. this.onBindEvent();
  53. this.inited = true;
  54. console.log("this.floorplanControls", this.floorplanControls);
  55. this.matLine = new LineMaterial({
  56. color: this.lineColor,
  57. linewidth: 3, // in world units with size attenuation, pixels otherwise
  58. dashed: false,
  59. alphaToCoverage: true,
  60. });
  61. this.matLine.resolution = new THREE.Vector2(
  62. this.scene.width,
  63. this.scene.height
  64. );
  65. };
  66. onPointerMove = (e) => {
  67. if (!this.drawing) return;
  68. this.pointermove = convertScreenToNDC(e, this.scene.domElement);
  69. this.raycaster.setFromCamera(this.pointermove, this.orthCamera);
  70. let intersectArr = this.scene.boxManager.imgList;
  71. // if(this.startObj) {
  72. // let i = intersectArr.indexOf(this.startObj)
  73. // intersectArr.splice(i, 1)
  74. // }
  75. const intersects = this.raycaster.intersectObjects(intersectArr, false);
  76. if (intersects[0] && intersects[0].object !== this.startObj) {
  77. this.touchImg = intersects[0];
  78. this.setActiveLine(this.touchImg);
  79. }
  80. };
  81. onPointerDown = (e) => {
  82. console.log("start draw");
  83. this.pointerdown = convertScreenToNDC(e, this.scene.domElement);
  84. this.raycaster.setFromCamera(this.pointerdown, this.orthCamera);
  85. let intersectArr = this.scene.boxManager.imgList;
  86. const intersects = this.raycaster.intersectObjects(intersectArr, false);
  87. console.log("intersects", intersects);
  88. if (intersects[0]) {
  89. this.startObj = intersects[0].object;
  90. this.drawing = true;
  91. } else {
  92. this.startObj = null;
  93. this.drawing = false;
  94. }
  95. // this.floorplanControls.enabled = false;
  96. };
  97. onPointerUp = (e) => {
  98. // console.log("last Line-wPos", points);
  99. this.pointerup = convertScreenToNDC(e, this.scene.domElement);
  100. this.drawing = false;
  101. this.floorplanControls.enabled = true;
  102. this.startObj = null;
  103. if (this.drawLine) {
  104. const points = this.drawLine.userData.points;
  105. const dir = this.drawLine.userData.dir;
  106. const finishLine = new LinePoints(points, 0, this.matLine);
  107. this.renderLines.push(points);
  108. this.scene.scene.add(finishLine);
  109. const imageId = this.touchImg.object.userData;
  110. const activeLineItem = {
  111. id: imageId,
  112. dir: [dir],
  113. };
  114. console.log("this.touchImg", activeLineItem, points);
  115. this.insertActiveEdge(activeLineItem);
  116. // this.showAllActiveEdges();
  117. }
  118. };
  119. Listener = {
  120. onPointerDown: this.onPointerDown.bind(this),
  121. onPointerMove: this.onPointerMove.bind(this),
  122. onPointerUp: this.onPointerUp.bind(this),
  123. };
  124. onBindEvent = () => {
  125. this.scene.domElement.addEventListener(
  126. "pointerdown",
  127. this.Listener.onPointerDown
  128. );
  129. this.scene.domElement.addEventListener(
  130. "pointermove",
  131. this.Listener.onPointerMove,
  132. false
  133. );
  134. this.scene.domElement.addEventListener(
  135. "pointerup",
  136. this.Listener.onPointerUp
  137. );
  138. };
  139. unbindEvent = () => {
  140. this.scene.domElement.removeEventListener(
  141. "pointerdown",
  142. this.Listener.onPointerDown
  143. );
  144. this.scene.domElement.removeEventListener(
  145. "pointermove",
  146. this.Listener.onPointerMove
  147. );
  148. this.scene.domElement.removeEventListener(
  149. "pointerup",
  150. this.Listener.onPointerUp
  151. );
  152. };
  153. buildLine = () => {
  154. if (this.drawLine) {
  155. this.drawLine.removeFromParent();
  156. }
  157. let s = new THREE.Vector3(this.pointerdown.x, this.pointerdown.y, -1);
  158. let e = new THREE.Vector3(this.pointermove.x, this.pointermove.y, -1);
  159. s.unproject(this.orthCamera);
  160. e.unproject(this.orthCamera);
  161. s.y = 5;
  162. e.y = 5;
  163. const matLine = new LineMaterial({
  164. color: this.lineColor,
  165. linewidth: 3, // in world units with size attenuation, pixels otherwise
  166. dashed: false,
  167. alphaToCoverage: true,
  168. });
  169. matLine.resolution = new THREE.Vector2(this.scene.width, this.scene.height);
  170. this.drawLine = new Line(s, e, this.activeEdge, matLine);
  171. this.scene.scene.add(this.drawLine);
  172. };
  173. setActiveLine = (obj) => {
  174. function getTouchLine(x, y) {
  175. // [0 - 1]
  176. x -= 0.5;
  177. y -= 0.5;
  178. // console.log(x, y);
  179. if (x >= 0 && y >= 0) {
  180. if (x > y) {
  181. return 3;
  182. } else {
  183. return 0;
  184. }
  185. } else if (x >= 0 && y <= 0) {
  186. if (x > Math.abs(y)) {
  187. return 3;
  188. } else {
  189. return 2;
  190. }
  191. } else if (x <= 0 && y >= 0) {
  192. if (Math.abs(x) > y) {
  193. return 1;
  194. } else {
  195. return 0;
  196. }
  197. } else if (x <= 0 && y <= 0) {
  198. if (-x > -y) {
  199. return 1;
  200. } else {
  201. return 2;
  202. }
  203. }
  204. }
  205. if (this.activeEdge) {
  206. this.activeEdge.visible = false;
  207. this.activeEdge = null;
  208. }
  209. let num = getTouchLine(obj.uv.x, obj.uv.y);
  210. this.activeEdge = obj.object.touchLines.getObjectByName(num);
  211. this.activeEdge.visible = true;
  212. this.buildLine();
  213. };
  214. insertActiveEdge(item) {
  215. const exist = this.activeEdges.find((s) => item.id === s.id);
  216. if (exist) {
  217. exist.dir = [...new Set([...exist.dir, ...item.dir])];
  218. } else {
  219. this.activeEdges.push(item);
  220. }
  221. }
  222. showAllActiveEdges() {
  223. if (this.inited) {
  224. let imgList = this.scene.boxManager.imgList;
  225. this.activeEdges.forEach((edge) => {
  226. const exist = imgList.find((item) => item.userData === edge.id);
  227. // console.log("exist", exist);
  228. if (exist) {
  229. edge.dir.forEach((dir) => {
  230. exist.touchLines.children[dir].visible = true;
  231. });
  232. }
  233. });
  234. }
  235. }
  236. update = () => {
  237. if (this.floorplanControls.enabled) {
  238. this.floorplanControls && this.floorplanControls.update();
  239. this.scene.boxManager && this.showAllActiveEdges();
  240. }
  241. };
  242. }