123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480 |
- import * as THREE from "three";
- import FloorplanControls from "../controls/FloorplanControls.js";
- import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
- import { TrackballControls } from "three/examples/jsm/controls/TrackballControls.js";
- import Line from "../box/object/Line";
- import LinePoints from "../box/object/LinePoints.js";
- import Marker from "../box/object/marker.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.markPosition = new THREE.Vector3();
- this.touchImg = null;
- this.activeEdge = null;
- this.drawLine = null;
- this.startObj = null;
- this.marker = null;
- this.allowDrawing = false;
- this.drawing = false;
- this.inited = false;
- this.renderLines = [];
- this.renderMarkers = [];
- this.activeEdges = [];
- this.matLine = null;
- this.lineColor = 0xe44d54;
- // 1是画线,2是标方向
- this.mode = 0;
- this.init();
- }
- setMode(mode) {
- this.mode = mode;
- if (mode === 1 || mode === 2) {
- this.reset();
- this.setEditMode();
- }
- if (mode === 0) {
- this.setFreeMode();
- }
- this.scene.emit("mode", this.mode);
- }
- // removeMarker() {
- // if (this.marker) {
- // this.scene.scene.remove(this.marker);
- // this.marker = null;
- // }
- // }
- setFreeMode() {
- this.floorplanControls.enablePan = true;
- this.floorplanControls.mouseButtons = {
- LEFT: THREE.MOUSE.PAN,
- MIDDLE: THREE.MOUSE.DOLLY,
- RIGHT: THREE.MOUSE.PAN,
- };
- this.reset();
- }
- setEditMode() {
- this.floorplanControls.enablePan = true;
- this.floorplanControls.mouseButtons = {
- LEFT: THREE.MOUSE.ROTATE,
- MIDDLE: THREE.MOUSE.DOLLY,
- RIGHT: THREE.MOUSE.PAN,
- };
- }
- 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.mouseButtons = {
- // LEFT: THREE.MOUSE.PAN,
- // MIDDLE: THREE.MOUSE.DOLLY,
- // RIGHT: THREE.MOUSE.PAN
- // }
- this.setMode(0);
- this.floorplanControls.enableRotate = false;
- this.raycaster = new THREE.Raycaster();
- this.onBindEvent();
- this.inited = true;
- 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);
- if (this.mode === 1) {
- 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);
- }
- }
- if (this.mode === 2) {
- if (this.marker) {
- let pos = new THREE.Vector3(this.pointermove.x, this.pointermove.y, -1);
- pos.unproject(this.orthCamera);
- pos.y = 5;
- // console.log("pos", pos);
- this.marker.position.copy(pos);
- }
- }
- };
- onPointerDown = (e) => {
- console.log("start draw");
- this.pointerdown = convertScreenToNDC(e, this.scene.domElement);
- if (this.mode === 1) {
- 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;
- }
- }
- if (this.mode === 2) {
- if (!this.marker) {
- let pos = new THREE.Vector3(this.pointerdown.x, this.pointerdown.y, -1);
- pos.unproject(this.orthCamera);
- pos.y = 5;
- this.marker = new Marker(pos);
- this.scene.scene.add(this.marker);
- this.drawing = true;
- } else {
- // this.drawing = false;
- 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.drawing = false;
- const imageId = intersects[0].object.userData;
- let lasPos = new THREE.Vector3(
- this.pointerdown.x,
- this.pointerdown.y,
- -1
- );
- lasPos.unproject(this.orthCamera);
- lasPos.y = 5;
- const marker = new Marker(lasPos);
- const activeMarkeritem = {
- id: imageId,
- point: lasPos.toArray(),
- };
- const exist = this.renderMarkers.find((item) => item.id === imageId);
- if (!exist) {
- this.scene.scene.add(marker);
- this.renderMarkers.push(activeMarkeritem);
- this.scene.scene.remove(this.marker);
- this.marker = null;
- } else {
- this.scene.emit("markerExist");
- }
- console.log("activeMarkeritem", activeMarkeritem);
- }
- }
- }
- // this.floorplanControls.enabled = false;
- };
- onPointerUp = (e) => {
- this.pointerup = convertScreenToNDC(e, this.scene.domElement);
- console.log("onPointerUp", this.pointerup);
- if (this.mode === 1) {
- 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;
- const activeLineItem = {
- id: imageId,
- dir: [dir],
- };
- console.log("this.touchImg", activeLineItem, points);
- this.insertActiveEdge(activeLineItem);
- this.drawLine = null;
- }
- }
- if (this.mode === 2) {
- // this.drawing = false;
- }
- this.syncDrawData();
- };
- 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();
- }
- 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();
- };
- insertActiveEdge(item) {
- const exist = this.activeEdges.find((s) => item.id === s.id);
- if (exist) {
- exist.dir = [...new Set([...exist.dir, ...item.dir])];
- } else {
- this.activeEdges.push(item);
- }
- }
- insertActiveMarker(item) {
- const exist = this.activeEdges.find((s) => item.id === s.id);
- if (exist) {
- exist.dir = [...new Set([...exist.dir, ...item.dir])];
- } else {
- this.activeEdges.push(item);
- }
- }
- showAllActiveEdges() {
- if (this.inited) {
- let imgList = this.scene.boxManager.imgList;
- this.activeEdges.forEach((edge) => {
- const exist = imgList.find((item) => item.userData === edge.id);
- // console.log("exist", exist);
- if (exist) {
- edge.dir.forEach((dir) => {
- exist.touchLines.children[dir].visible = true;
- });
- }
- });
- }
- }
- getDrawData() {
- let data;
- if (this.scene.sceneType === 1) {
- data = {
- hor_lines: this.renderLines,
- activeEdges: this.activeEdges,
- vir_lines: [],
- hor_markers: this.renderMarkers,
- vir_markers: [],
- };
- } else {
- data = {
- hor_lines: [],
- vir_lines: this.renderLines,
- activeEdges: this.activeEdges,
- vir_markers: this.renderMarkers,
- hor_markers: [],
- };
- }
- // console.log("sceneType", this.scene.sceneType);
- return data;
- }
- syncDrawData() {
- const data = this.getDrawData();
- this.scene.emit("data", data);
- }
- load(type, data) {
- if (type === 1) {
- console.log("data1", data);
- const { activeEdges, hor_lines, hor_markers } = data;
- activeEdges && (this.activeEdges = activeEdges);
- if (hor_lines && Array.isArray(hor_lines)) {
- this.renderLines = hor_lines;
- hor_lines.forEach((line) => {
- const finishLine = new LinePoints(line, 0, this.matLine);
- this.scene.scene.add(finishLine);
- });
- }
- if (hor_markers && Array.isArray(hor_markers)) {
- this.renderMarkers = hor_markers;
- hor_markers.forEach((pos) => {
- console.log("pos");
- const p = new THREE.Vector3().fromArray(pos.point);
- const marker = new Marker(p);
- this.scene.scene.add(marker);
- });
- }
- }
- if (type === 2) {
- const { activeEdges, vir_lines, vir_markers } = data;
- activeEdges && (this.activeEdges = activeEdges);
- if (vir_lines && Array.isArray(vir_lines)) {
- this.renderLines = vir_lines;
- vir_lines.forEach((line) => {
- const finishLine = new LinePoints(line, 0, this.matLine);
- this.scene.scene.add(finishLine);
- });
- }
- if (vir_markers && Array.isArray(vir_markers)) {
- this.renderMarkers = vir_markers;
- vir_markers.forEach((pos) => {
- const p = new THREE.Vector3().fromArray(pos.point);
- const marker = new Marker(p);
- this.scene.scene.add(marker);
- });
- }
- }
- }
- reset() {
- if (this.marker) {
- this.scene.scene.remove(this.marker);
- this.marker = null;
- }
- if (this.drawLine) {
- this.scene.scene.remove(this.drawLine);
- this.drawLine = null;
- }
- if (this.touchImg) {
- this.touchImg = null;
- }
- if (this.activeEdge) {
- this.activeEdge = null;
- }
- this.drawing = false;
- }
- update = () => {
- if (this.floorplanControls.enabled) {
- this.floorplanControls && this.floorplanControls.update();
- this.scene.boxManager && this.showAllActiveEdges();
- }
- };
- }
|