123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346 |
- import * as THREE from "../../libs/three.js/build/three.module.js";
- import {Utils} from "../utils.js";
- import { EventDispatcher } from "../EventDispatcher.js";
- import Sprite from '../viewer/Sprite'
- const texLoader = new THREE.TextureLoader()
- const arrowSpacing = 1 //间隔
- const arrowSize = arrowSpacing * 0.5
- const planeGeo = new THREE.PlaneBufferGeometry(1,1);
- const sphereSizeInfo = {
- nearBound : 2, scale:arrowSize, restricMeshScale : true,
- }
- export class RouteGuider extends EventDispatcher{
- constructor () {
- super();
- this._routeStart = null
- this._routeEnd = null
- this.route = [];
- this.curve = []
- this.sceneMeshGroup = new THREE.Object3D;
- this.mapMeshGroup = new THREE.Object3D;
-
- viewer.addEventListener('loadPointCloudDone',this.init.bind(this))
-
-
- }
- init(){
- if(this.inited) return;
-
- var polesMats = {
- shadowMat: new THREE.MeshBasicMaterial({
- transparent:true, depthTest:false,
- map: texLoader.load(Potree.resourcePath+'/textures/pano_instruction_bottomMarker.png' )
- }),
- sphereMat : new THREE.MeshBasicMaterial({
- transparent:true, depthTest:false,
- map: texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png' )
- }),
- hatMats:{
- start: new THREE.MeshBasicMaterial({
- transparent:true, depthTest:false,
- map: texLoader.load(Potree.resourcePath+'/textures/pano_instruction_start_route.png' )
- }),
- end: new THREE.MeshBasicMaterial({
- transparent:true, depthTest:false,
- map: texLoader.load(Potree.resourcePath+'/textures/pano_instruction_target_reached.png' )
- })
- }
- }
-
- this.poleStart = this.createPole(polesMats, 'start')
- this.poleEnd = this.createPole(polesMats, 'end')
-
- this.sceneMeshGroup.add(this.poleStart)
- this.sceneMeshGroup.add(this.poleEnd)
-
-
- let map = texLoader.load(Potree.resourcePath+'/textures/routePoint_panorama.png' )
- map.anisotropy = 4 // 各向异性过滤 .防止倾斜模糊
- this.arrow = new THREE.Mesh(planeGeo, new THREE.MeshBasicMaterial({
- transparent:true,
- depthTest:false,
- map
- }))
- this.arrow.scale.set(arrowSize,arrowSize,arrowSize)
- viewer.setObjectLayers(this.arrow, 'route' )
-
-
- this.testArrow = this.arrow.clone();
- this.testArrow.material = this.arrow.material.clone()
- this.testArrow.material.color = 'red'
-
- this.arrows = new THREE.Object3D;
- this.sceneMeshGroup.add(this.arrows)
-
- viewer.setObjectLayers(this.sceneMeshGroup, 'route' )
- //this.sceneMeshGroup.traverse(e=>e.renderOrder = 90)
-
-
- viewer.scene.scene.add(this.sceneMeshGroup);
- this.sceneMeshGroup.visible = /* this.poleStart.visibile = this.poleEnd.visibile = */ false
-
- //-------------map---------------------
-
- this.mapMarkStart = new THREE.Mesh( planeGeo, new THREE.MeshBasicMaterial({
- transparent:true, depthTest:false,
- map: texLoader.load(Potree.resourcePath+'/textures/map_instruction_start_route.png' )
- }))
- this.mapMarkEnd = new THREE.Mesh( planeGeo, new THREE.MeshBasicMaterial({
- transparent:true, depthTest:false,
- map: texLoader.load(Potree.resourcePath+'/textures/map_instruction_target_reached.png' )
- }))
-
-
- this.mapArrow = new THREE.Mesh( planeGeo, new THREE.MeshBasicMaterial({
- transparent:true, depthTest:false,
- map: texLoader.load(Potree.resourcePath+'/textures/routePoint_map_fsna.png' )
- }))
- this.mapArrow.scale.set(arrowSize,arrowSize,arrowSize)
- this.mapArrows = new THREE.Object3D;
- this.mapArrows.name = 'mapArrows'
- //viewer.setObjectLayers(this.mapArrow, 'route' )
-
-
-
-
- this.mapMeshGroup.add(this.mapMarkStart)
- this.mapMeshGroup.add(this.mapMarkEnd)
- this.mapMeshGroup.add(this.mapArrows)
- this.mapMeshGroup.name = 'mapRouteLayer'
- this.mapMeshGroup.visible = /* this.mapMarkStart.visible = this.mapMarkEnd.visible = */ false
-
- viewer.mapViewer.emit('add',{object:this.mapMeshGroup, name:'route'})
- this.mapArrow.layers.mask = this.mapArrows.layers.mask // 修改成和map中的layer一样的
-
- this.inited = true
- }
-
-
- createPole(polesMats, name){
- const height = 1.5, sphereCount = 6, shadowSize = sphereSizeInfo.scale, sphereSize = 0.04
-
- var group = new THREE.Object3D;
- group.name = 'pole_'+name
- var shadow = new THREE.Mesh(planeGeo,polesMats.shadowMat)
- shadow.scale.set(shadowSize,shadowSize,shadowSize)
- var sliceDis = height / (sphereCount+1);
- group.add(shadow)
-
- for(let i=0;i<sphereCount;i++){
- var sphere = new Sprite({mat: polesMats.sphereMat})
- sphere.position.set(0,0,sliceDis*(i+1))
- sphere.scale.set(sphereSize,sphereSize,sphereSize);
- group.add(sphere)
- }
-
- var hatSphere = new Sprite({mat: polesMats.hatMats[name], sizeInfo:sphereSizeInfo})
- hatSphere.position.set(0,0,height)
- hatSphere.scale.copy(shadow.scale)
- group.add(hatSphere)
- return group
- }
-
-
- addTestArrow(){
-
- }
-
- addArrow(position){
- var arrow = this.arrow.clone()
- arrow.position.copy(position);
- this.arrows.add(arrow);
- }
- addMapArrow(position){
- var mapArrow = this.mapArrow.clone()
- mapArrow.position.copy(position).setZ(0)
- this.mapArrows.add(mapArrow);
- }
-
-
- setArrowDir(arrows,index){
- let arrow = arrows[index]
- var nextOne = arrows[index+1];
- var nextPos = nextOne ? nextOne.position : this.routeEnd
- var direction = new THREE.Vector3().subVectors(arrow.position, nextPos).setZ(0);
- //direction.normalize();
- //console.log(direction.toArray())
- var angle = Math.atan2(direction.y, direction.x ) + Math.PI/2 //Math.PI/2是因为贴图本身箭头方向不朝x
- arrow.rotation.z = angle
- //console.log(angle)
- }
-
-
- get routeStart(){
- return this._routeStart && this._routeStart.clone()
- }
-
- set routeStart(pos){
- this._routeStart = pos && pos.clone()
- this.generateRoute()
- }
-
- get routeEnd(){
- return this._routeEnd && this._routeEnd.clone()
- }
-
- set routeEnd(pos){
- this._routeEnd = pos && pos.clone()
- this.generateRoute()
- }
-
-
-
-
- generateRoute(){
- if(!this.routeStart || !this.routeEnd)return
- this.clearRoute()
-
- //array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
-
-
- let create = ()=>{
- this.routeLenth = this.route.reduce((total, currentValue, currentIndex, arr)=>{
- if(currentIndex == 0)return 0
- return total + currentValue.distanceTo(arr[currentIndex-1]);
- },0)
- let count = Math.max(2,Math.round(this.routeLenth / arrowSpacing))//点数
-
- const curve = new THREE.CatmullRomCurve3( this.route );
- curve.curveType = 'catmullrom'
- this.curve = curve
-
- const scenePoints = curve.getSpacedPoints( count );//更平均
- //const scenePoints = curve.getPoints( count );
- scenePoints.splice(0,1);//去掉首尾
- scenePoints.pop()
- this.scenePoints = scenePoints
-
- this.updateMapArrows()
-
-
-
- this.displayRoute()
- }
-
-
- if(Potree.fileServer){
-
- let start = this.routeStart;
- let end = this.routeEnd;
- let startLonlat = viewer.transform.lonlatToLocal.inverse(start)
- let endLonlat = viewer.transform.lonlatToLocal.inverse(end)
-
- var query = {
- source_longitude: startLonlat.x,
- source_latitude: startLonlat.y,
- source_z: start.z,
- destination_longitude: endLonlat.x,
- destination_latitude: endLonlat.y,
- destination_z: end.z
- };
- let url = `/laser/route/${Potree.settings.number}/getRoute?`
- for(let i in query){
- url+= (i + '='+ query[i] +'&')
- }
-
-
- Potree.fileServer.get(url).then((data)=>{
- console.log(data)
-
- data.forEach(item=>{
- let pos = viewer.transform.lonlatToLocal.forward(item.location)
- pos = new THREE.Vector3().fromArray(pos)
- this.route.push(pos)
- })
-
- create()
- /*
- distance: 0.17581000000000116
- distance_to_previous: 0.17581000000000116
- id: 567
- instruction: {type: 'source_projection_to_navgraph'}
- latitude: 22.366605927999238
- location: (3) [113.5957510575092, 22.366605927999238, -1.12419]
- longitude: 113.5957510575092
- z: -1.12419
- */
-
- })
-
-
- }else{
- //创个直线
- /* const sliceDis = 1
- let dis = this.routeStart.distanceTo(this.routeEnd);
- let count = Math.max(2,Math.round(dis / sliceDis))//点数
- let realSlideDis = dis / (count-1);
- let dir = new THREE.Vector3().subVectors(this.routeEnd, this.routeStart).normalize().multiplyScalar(realSlideDis);
- this.route = [this.routeStart];
- for(let i=0;i<count-1;i++){
- let lastOne = this.route[i];
- this.route.push(new THREE.Vector3().addVectors(lastOne,dir))
- }
- this.route.splice(0,1) //route不用包含收尾 */
- this.route = [this.routeStart, this.routeEnd]
- create()
-
- }
-
- }
-
- updateMapArrows(){
-
- let count = Math.max(2,Math.round(this.routeLenth / viewer.mapViewer.camera.zoom *10/ arrowSpacing))//点数
- const mapPoints = this.curve.getSpacedPoints( count );
- mapPoints.splice(0,1);//去掉首尾
- mapPoints.pop()
-
- this.mapPoints = mapPoints
- }
-
-
-
- displayRoute(){
- this.sceneMeshGroup.visible = true
- this.mapMeshGroup.visible = true
- this.poleStart.position.copy(this.routeStart)
- this.poleEnd.position.copy(this.routeEnd)
- this.mapMarkStart.position.copy(this.routeStart).setZ(0)
- this.mapMarkEnd.position.copy(this.routeEnd).setZ(0)
- this.scenePoints.forEach(e=>this.addArrow(e))
- this.mapPoints.forEach(e=>this.addMapArrow(e))
- this.arrows.children.forEach((e,i)=>this.setArrowDir(this.arrows.children,i));
- this.mapArrows.children.forEach((e,i)=>this.setArrowDir(this.mapArrows.children,i));
- }
-
- clearRoute(){
- this.routeLenth = 0
- this.route = []
- this.scenePoints = []
- this.mapPoints = []
-
- let arrows = this.arrows.children.slice(0)
- let mapArrows = this.mapArrows.children.slice(0)
- arrows.forEach(e=>{
- this.arrows.remove(e)
- })
- mapArrows.forEach(e=>{
- this.mapArrows.remove(e)
- })
- }
-
- clear(){//退出
- this.sceneMeshGroup.visible = false
- this.mapMeshGroup.visible = false
- this.routeStart = null
- this.routeEnd = null
- this.clearRoute()
-
- }
- }
|