import * as THREE from "three"; import FloorplanControls from "../controls/FloorplanControls.js"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; import Line from "../box/object/Line"; import LinePoints from "../box/object/LinePoints.js"; import { LineMaterial } from "three/examples/jsm/lines/LineMaterial.js"; const convertScreenToNDC = function (event, domElement) { let x = (event.offsetX / domElement.clientWidth) * 2 - 1; let y = -(event.offsetY / domElement.clientHeight) * 2 + 1; return new THREE.Vector2(x, y); }; export default class Player { constructor(scene) { this.scene = scene; this.orthCamera = scene.orthCamera; this.floorplanControls = null; this.raycaster = null; this.position = new THREE.Vector3(); this.pointerdown = new THREE.Vector2(); this.pointerup = new THREE.Vector2(); this.pointer = new THREE.Vector2(); this.touchImg = null; this.activeEdge = null; this.drawLine = null; this.startObj = null; this.allowDrawing = false; this.drawing = false; this.inited = false; this.renderLines = []; this.activeEdges = []; this.matLine = null; this.lineColor = 0xe44d54; this.init(); } init = () => { // //floorplanControls // this.floorplanControls = new FloorplanControls(this.orthCamera, this.scene.domElement, this); this.floorplanControls = new OrbitControls( this.orthCamera, this.scene.domElement ); this.floorplanControls.enablePan = true; // this.floorplanControls.target.set(0, 1, 0); // this.floorplanControls.rotateSpeed = 0.5; // this.floorplanControls.panSpeed = 0.75 // this.floorplanControls.maxDistance = 100 // this.floorplanControls.minDistance = 3.5 this.floorplanControls.maxZoom = 500; this.floorplanControls.minZoom = 100; this.floorplanControls.enableRotate = false; this.raycaster = new THREE.Raycaster(); this.onBindEvent(); this.inited = true; console.log("this.floorplanControls", this.floorplanControls); this.matLine = new LineMaterial({ color: this.lineColor, linewidth: 3, // in world units with size attenuation, pixels otherwise dashed: false, alphaToCoverage: true, }); this.matLine.resolution = new THREE.Vector2( this.scene.width, this.scene.height ); }; onPointerMove = (e) => { if (!this.drawing) return; this.pointermove = convertScreenToNDC(e, this.scene.domElement); this.raycaster.setFromCamera(this.pointermove, this.orthCamera); let intersectArr = this.scene.boxManager.imgList; // if(this.startObj) { // let i = intersectArr.indexOf(this.startObj) // intersectArr.splice(i, 1) // } const intersects = this.raycaster.intersectObjects(intersectArr, false); if (intersects[0] && intersects[0].object !== this.startObj) { this.touchImg = intersects[0]; this.setActiveLine(this.touchImg); } }; onPointerDown = (e) => { console.log("start draw"); this.pointerdown = convertScreenToNDC(e, this.scene.domElement); this.raycaster.setFromCamera(this.pointerdown, this.orthCamera); let intersectArr = this.scene.boxManager.imgList; const intersects = this.raycaster.intersectObjects(intersectArr, false); console.log("intersects", intersects); if (intersects[0]) { this.startObj = intersects[0].object; this.drawing = true; } else { this.startObj = null; this.drawing = false; } // this.floorplanControls.enabled = false; }; onPointerUp = (e) => { // console.log("last Line-wPos", points); this.pointerup = convertScreenToNDC(e, this.scene.domElement); this.drawing = false; this.floorplanControls.enabled = true; this.startObj = null; if (this.drawLine) { const points = this.drawLine.userData.points; const dir = this.drawLine.userData.dir; const finishLine = new LinePoints(points, 0, this.matLine); this.renderLines.push(points); this.scene.scene.add(finishLine); const imageId = this.touchImg.object.userData; console.log("this.touchImg", dir, imageId, points); } }; Listener = { onPointerDown: this.onPointerDown.bind(this), onPointerMove: this.onPointerMove.bind(this), onPointerUp: this.onPointerUp.bind(this), }; onBindEvent = () => { this.scene.domElement.addEventListener( "pointerdown", this.Listener.onPointerDown ); this.scene.domElement.addEventListener( "pointermove", this.Listener.onPointerMove, false ); this.scene.domElement.addEventListener( "pointerup", this.Listener.onPointerUp ); }; unbindEvent = () => { this.scene.domElement.removeEventListener( "pointerdown", this.Listener.onPointerDown ); this.scene.domElement.removeEventListener( "pointermove", this.Listener.onPointerMove ); this.scene.domElement.removeEventListener( "pointerup", this.Listener.onPointerUp ); }; buildLine = () => { if (this.drawLine) { this.drawLine.removeFromParent(); } // console.log("this.drawLine", this.drawLine); let s = new THREE.Vector3(this.pointerdown.x, this.pointerdown.y, -1); let e = new THREE.Vector3(this.pointermove.x, this.pointermove.y, -1); s.unproject(this.orthCamera); e.unproject(this.orthCamera); s.y = 5; e.y = 5; const matLine = new LineMaterial({ color: this.lineColor, linewidth: 3, // in world units with size attenuation, pixels otherwise dashed: false, alphaToCoverage: true, }); matLine.resolution = new THREE.Vector2(this.scene.width, this.scene.height); this.drawLine = new Line(s, e, this.activeEdge, matLine); this.scene.scene.add(this.drawLine); }; setActiveLine = (obj) => { function getTouchLine(x, y) { // [0 - 1] x -= 0.5; y -= 0.5; // console.log(x, y); if (x >= 0 && y >= 0) { if (x > y) { return 3; } else { return 0; } } else if (x >= 0 && y <= 0) { if (x > Math.abs(y)) { return 3; } else { return 2; } } else if (x <= 0 && y >= 0) { if (Math.abs(x) > y) { return 1; } else { return 0; } } else if (x <= 0 && y <= 0) { if (-x > -y) { return 1; } else { return 2; } } } if (this.activeEdge) { this.activeEdge.visible = false; this.activeEdge = null; } let num = getTouchLine(obj.uv.x, obj.uv.y); this.activeEdge = obj.object.touchLines.getObjectByName(num); this.activeEdge.visible = true; this.buildLine(); }; update = () => { if (this.floorplanControls.enabled) { this.floorplanControls && this.floorplanControls.update(); } }; }