|
@@ -10,6 +10,9 @@ import {Utils} from "../utils.js";
|
|
|
import Common from "../custom/utils/Common.js";
|
|
|
import DepthBasicMaterial from '../custom/materials/DepthBasicMaterial.js'
|
|
|
import browser from "../custom/utils/browser.js";
|
|
|
+import math from "../custom/utils/math.js";
|
|
|
+
|
|
|
+
|
|
|
|
|
|
let {Buttons} = Potree.defines
|
|
|
|
|
@@ -27,6 +30,8 @@ export class InputHandler extends THREE.EventDispatcher {
|
|
|
this.interactiveObjects = new Set();
|
|
|
this.inputListeners = [];
|
|
|
this.blacklist = new Set();
|
|
|
+
|
|
|
+
|
|
|
|
|
|
this.drag = null;
|
|
|
this.mouse = new THREE.Vector2(0, 0);
|
|
@@ -99,9 +104,25 @@ export class InputHandler extends THREE.EventDispatcher {
|
|
|
|
|
|
|
|
|
{
|
|
|
- this.addEventListener('isMeasuring',(e)=>{
|
|
|
- //console.log('isMeasuring',e.v,e.cause)
|
|
|
- this.isMeasuring = e.v
|
|
|
+ this.measuring = [] //正在编辑的measure
|
|
|
+ //let mesureInfo = new THREE.EventDispatcher()
|
|
|
+ this.addEventListener('measuring',(e)=>{
|
|
|
+ //true优先级高于false, 正在添加时dropMarker也不会停止
|
|
|
+
|
|
|
+ //Potree.Utils.updateVisible(mesureInfo, e.situation, e.v, 0, e.v?'add':'cancel' )//借用该函数,使true优先级高于false,防止正在添加时dropMarker而停止
|
|
|
+ if(e.v){
|
|
|
+ this.measuring.includes(e.object) || this.measuring.push(e.object)
|
|
|
+ }else{
|
|
|
+ let index = this.measuring.indexOf(e.object)
|
|
|
+ index > -1 && this.measuring.splice(index, 1)
|
|
|
+ }
|
|
|
+
|
|
|
+ if(this.measuring.length == 0 && this.measuring.length>0 ){
|
|
|
+ this.viewer.viewports.forEach((viewport)=>{
|
|
|
+ this.collectClosePoints(viewport, true )//forceUpdate
|
|
|
+ })
|
|
|
+ }
|
|
|
+ //console.log('measuring',e.v, e.cause, e.situation, this.measuring.length )
|
|
|
})
|
|
|
}
|
|
|
|
|
@@ -421,7 +442,7 @@ export class InputHandler extends THREE.EventDispatcher {
|
|
|
//isTouch必须更新 否则是旧的
|
|
|
this.hoveredElements = this.getHoveredElements();
|
|
|
let dontIntersect = false
|
|
|
- this.intersect = this.getIntersect(viewport,null,null,dontIntersect) //更新intersect,避免在没有mousemove但flyToPano后intersect未更新。
|
|
|
+ this.intersect = this.getIntersect({viewport, dontIntersect, clientX:e.clientX, clientY:e.clientY}) //更新intersect,避免在没有mousemove但flyToPano后intersect未更新。
|
|
|
//this.intersect = this.getWholeIntersect()
|
|
|
}
|
|
|
if(!viewport)return //why add this?
|
|
@@ -787,7 +808,7 @@ export class InputHandler extends THREE.EventDispatcher {
|
|
|
|
|
|
ifBlockedByIntersect({pos3d, margin=0, cameraPos, pickWindowSize, pano, useDepthTex, viewport}={}){//某点是否被遮挡(不允许camera修改位置, 因为depthTex不好置换)
|
|
|
viewport = viewport || this.hoverViewport || viewer.mainViewport
|
|
|
- let intersect = this.getIntersect(viewport, true, pickWindowSize, null, null, useDepthTex, {pos3d, cameraPos, pano})
|
|
|
+ let intersect = this.getIntersect({viewport, onlyGetIntersect:true, pickWindowSize, useDepthTex, pos3d, cameraPos, pano })
|
|
|
let cameraPos_ = (!cameraPos && pano) ? pano.position : (cameraPos||viewport.view.position)
|
|
|
if(intersect && intersect.distance+margin <= pos3d.distanceTo(cameraPos_)){
|
|
|
return intersect //被遮挡
|
|
@@ -795,10 +816,25 @@ export class InputHandler extends THREE.EventDispatcher {
|
|
|
//点云模式,对没加载出的点云不准确。 尤其是需要修改相机位置时,因临时修改并不能使点云加载。
|
|
|
}
|
|
|
|
|
|
+ collectClosePoints(viewport, forceUpdate){//获取吸附点
|
|
|
+ if(!Potree.settings.adsorption)return
|
|
|
+
|
|
|
+ let point2ds = []
|
|
|
+
|
|
|
+ //吸附测量线端点
|
|
|
+
|
|
|
+ viewer.scene.measurements.forEach(e=>{
|
|
|
+ if(this.measuring.includes(e)) return//不吸附到正在拖拽的自身
|
|
|
+ point2ds.push(...e.getPointsPos2d(viewport, forceUpdate))
|
|
|
+ })
|
|
|
+
|
|
|
+ return point2ds
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
- getIntersect(viewport, onlyGetIntersect, pickWindowSize, dontIntersect, usePointcloud, useDepthTex, prop={}){// usePointcloud:必须使用点云
|
|
|
- let intersectPoint
|
|
|
+ getIntersect({viewport, onlyGetIntersect, pickWindowSize, dontIntersect, usePointcloud, useDepthTex, cameraPos, point, pano, clientX, clientY}={}){// usePointcloud:必须使用点云
|
|
|
+ let intersect, intersectPoint, intersectOnModel, allElements
|
|
|
let camera = viewport.camera
|
|
|
let raycaster
|
|
|
|
|
@@ -806,27 +842,28 @@ export class InputHandler extends THREE.EventDispatcher {
|
|
|
|
|
|
let getByDepthTex = ()=>{
|
|
|
let intersect
|
|
|
- if(prop.pos3d){
|
|
|
- let cameraPos = prop.pano ? prop.pano.position : camera.position
|
|
|
- let dir = new THREE.Vector3().subVectors(prop.pos3d, cameraPos).normalize();
|
|
|
+ if(point){
|
|
|
+ let cameraPos = pano ? pano.position : camera.position
|
|
|
+ let dir = new THREE.Vector3().subVectors(point, cameraPos).normalize();
|
|
|
intersect = {dir}
|
|
|
}else{
|
|
|
intersect = Utils.getIntersect(camera, [viewer.images360.cube], this.pointer, raycaster)
|
|
|
}
|
|
|
- intersectPoint = viewer.images360.depthSampler.sample(intersect, prop.pano, !!prop.pos3d) //可能不准确, 因pano可能未加载depthTex
|
|
|
+ intersectPoint = viewer.images360.depthSampler.sample(intersect, pano, !!point) //可能不准确, 因pano可能未加载depthTex
|
|
|
if(intersectPoint && Potree.settings.depTexLocBindDataset){
|
|
|
- intersectPoint.pointcloud = (prop.pano || viewer.images360.currentPano).pointcloud
|
|
|
+ intersectPoint.pointcloud = ( pano || viewer.images360.currentPano).pointcloud
|
|
|
//在全景模式下,虽然深度图上的点可能对应别的pointcloud,但因为是在当前全景图处得到的,所以即使将原本对应的点云移走,该点也不移动是有道理的。它可以永远跟着该全景图。
|
|
|
}
|
|
|
}
|
|
|
|
|
|
let getByCloud = ()=>{
|
|
|
- if(prop.pos3d){//指定了目标点,而非只是用pointer所在位置
|
|
|
- prop.cameraPos && camera.position.copy(prop.cameraPos)
|
|
|
- camera.lookAt(prop.pos3d)
|
|
|
+ let pointer, mouse
|
|
|
+ if(point){//指定了目标点,而非只是用pointer所在位置
|
|
|
+ cameraPos && camera.position.copy( cameraPos)
|
|
|
+ camera.lookAt(point)
|
|
|
camera.updateMatrixWorld()
|
|
|
- prop.pointer = this.pointer.clone()
|
|
|
- prop.mouse = this.mouse.clone()
|
|
|
+ pointer = this.pointer.clone()
|
|
|
+ mouse = this.mouse.clone()
|
|
|
this.pointer.set(0,0) //画布中心
|
|
|
this.mouse.set(Math.round(viewport.resolution.x/2), Math.round(viewport.resolution.y/2))
|
|
|
}
|
|
@@ -838,77 +875,101 @@ export class InputHandler extends THREE.EventDispatcher {
|
|
|
camera,
|
|
|
this.viewer,
|
|
|
this.viewer.scene.pointclouds,
|
|
|
- {pickClipped: true, isMeasuring: this.isMeasuring, pickWindowSize, cameraChanged: !!prop.pos3d }
|
|
|
+ {pickClipped: true, measuring: this.measuring.length>0, pickWindowSize, cameraChanged: !!point }
|
|
|
|
|
|
);
|
|
|
//恢复
|
|
|
- if(prop.pos3d){
|
|
|
+ if(point){
|
|
|
viewport.view.applyToCamera(camera)
|
|
|
- this.pointer.copy(prop.pointer)
|
|
|
- this.mouse.copy(prop.mouse)
|
|
|
+ this.pointer.copy(pointer)
|
|
|
+ this.mouse.copy(mouse)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if(this.measuring.length && Potree.settings.adsorption ){//吸附
|
|
|
+ let points = this.collectClosePoints(viewport)
|
|
|
+
|
|
|
+ let points2 = points.filter(e=>e.trueSide && e.inSight
|
|
|
+ && math.closeTo(this.mouse, e.posInViewport, Potree.config.measure.adsorptMinDis)
|
|
|
+ )
|
|
|
+
|
|
|
+ let disArr = points2.map(e=> e.pos.distanceToSquared(this.mouse) )
|
|
|
+
|
|
|
+ let min = points2.slice().sort((a,b)=>disArr[points.indexOf(a)] - disArr[points.indexOf(b)])
|
|
|
+ if(min[0]){
|
|
|
+ intersect = {
|
|
|
+ //hoveredElement
|
|
|
+ location: min[0].pos3d,
|
|
|
+ //point: {normal: allElements[0].face.normal },
|
|
|
+ //normal
|
|
|
+ //distance
|
|
|
+ object: min[0].object,
|
|
|
+ adsorption:true
|
|
|
+ }
|
|
|
+ console.log('找到吸附点', min[0].pos3d, min[0].object.uuid)
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
|
|
|
- let canUseDepthTex = (Potree.settings.displayMode == 'showPanos' || useDepthTex)
|
|
|
- && viewer.images360.currentPano.pointcloud.hasDepthTex && viewport == viewer.mainViewport && !usePointcloud
|
|
|
-
|
|
|
-
|
|
|
- if(canUseDepthTex)getByDepthTex()
|
|
|
- else getByCloud()
|
|
|
- /* if(canUseDepthTex && !this.isMeasuring){
|
|
|
- getByDepthTex()
|
|
|
- }else{
|
|
|
- getByCloud()
|
|
|
- if(!intersectPoint && canUseDepthTex ){ //若在测量,先尝试点云,再用全景 //后来发现有深度图的点云全景visibleNode为空,pick不到的
|
|
|
- getByDepthTex()
|
|
|
- }
|
|
|
- } */
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- //console.log(viewport.name , intersectPoint && intersectPoint.location )
|
|
|
- let intersect
|
|
|
- let intersectOnModel, allElements
|
|
|
-
|
|
|
-
|
|
|
- if(Potree.settings.intersectOnObjs && !dontIntersect){
|
|
|
- if(prop.point){
|
|
|
- raycaster = new THREE.Raycaster()
|
|
|
- var dir = new THREE.Vector3().subVectors(prop.point, camera.position).normalize()
|
|
|
- raycaster.set(camera.position, dir) //var origin = new THREE.Vector3(pointer.x, pointer.y, -1).unproject(camera),
|
|
|
- }
|
|
|
+ if(!intersect){
|
|
|
|
|
|
+ let canUseDepthTex = (Potree.settings.displayMode == 'showPanos' || useDepthTex)
|
|
|
+ && viewer.images360.currentPano.pointcloud.hasDepthTex && viewport == viewer.mainViewport && !usePointcloud
|
|
|
|
|
|
- allElements = this.getHoveredElements(viewer.objs.children, true, raycaster)
|
|
|
|
|
|
+ if(canUseDepthTex)getByDepthTex()
|
|
|
+ else getByCloud()
|
|
|
+ /* if(canUseDepthTex && this.measuring.length){
|
|
|
+ getByDepthTex()
|
|
|
+ }else{
|
|
|
+ getByCloud()
|
|
|
+ if(!intersectPoint && canUseDepthTex ){ //若在测量,先尝试点云,再用全景 //后来发现有深度图的点云全景visibleNode为空,pick不到的
|
|
|
+ getByDepthTex()
|
|
|
+ }
|
|
|
+ } */
|
|
|
+
|
|
|
+ //console.log(viewport.name , intersectPoint && intersectPoint.location )
|
|
|
+
|
|
|
+
|
|
|
|
|
|
- if(allElements[0]){
|
|
|
- intersectOnModel = {//模拟点云的intersectPoint的结构写法
|
|
|
- hoveredElement : allElements[0] ,
|
|
|
- location: allElements[0].point,
|
|
|
- //point: {normal: allElements[0].face.normal },
|
|
|
- normal: allElements[0].face && allElements[0].face.normal,
|
|
|
- distance: allElements[0].distance,
|
|
|
- object: allElements[0].object
|
|
|
- }
|
|
|
+ if(Potree.settings.intersectOnObjs && !dontIntersect){
|
|
|
+ if(point){
|
|
|
+ raycaster = new THREE.Raycaster()
|
|
|
+ var dir = new THREE.Vector3().subVectors(point, camera.position).normalize()
|
|
|
+ raycaster.set(camera.position, dir) //var origin = new THREE.Vector3(pointer.x, pointer.y, -1).unproject(camera),
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ allElements = this.getHoveredElements(viewer.objs.children, true, raycaster)
|
|
|
+
|
|
|
+
|
|
|
+ if(allElements[0]){
|
|
|
+ intersectOnModel = {//模拟点云的intersectPoint的结构写法
|
|
|
+ hoveredElement : allElements[0] ,
|
|
|
+ location: allElements[0].point,
|
|
|
+ //point: {normal: allElements[0].face.normal },
|
|
|
+ normal: allElements[0].face && allElements[0].face.normal,
|
|
|
+ distance: allElements[0].distance,
|
|
|
+ object: allElements[0].object
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if(intersectPoint && intersectOnModel){
|
|
|
- if(intersectPoint.distance < intersectOnModel.distance){
|
|
|
- intersect = intersectPoint
|
|
|
+ if(intersectPoint && intersectOnModel){
|
|
|
+ if(intersectPoint.distance < intersectOnModel.distance){
|
|
|
+ intersect = intersectPoint
|
|
|
+ }else{
|
|
|
+ intersect = intersectOnModel
|
|
|
+ }
|
|
|
}else{
|
|
|
- intersect = intersectOnModel
|
|
|
+ intersect = intersectOnModel || intersectPoint
|
|
|
}
|
|
|
- }else{
|
|
|
- intersect = intersectOnModel || intersectPoint
|
|
|
- }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
if(viewport.camera.type == 'OrthographicCamera'/* == 'mapViewport' */){
|
|
@@ -999,21 +1060,11 @@ export class InputHandler extends THREE.EventDispatcher {
|
|
|
let dontIntersect = this.drag && viewport.alignment || isFlying || !Potree.settings.intersectWhenHover // flying 时可能卡顿
|
|
|
//console.log('dontIntersectPointcloud',dontIntersectPointcloud)
|
|
|
|
|
|
- /* if(e.onlyGetIntersect ) */intersect = this.getIntersect(viewport, e.onlyGetIntersect, e.pickWindowSize, !!dontIntersect, e.whichPointcloud) //数据集多的时候卡顿
|
|
|
- /* else Potree.Common.intervalTool.isWaiting('getIntersect', ()=>{
|
|
|
- this.intersect = this.getIntersect(viewport, e.onlyGetIntersect, e.pickWindowSize, !!dontIntersect, e.whichPointcloud) //数据集多的时候卡顿
|
|
|
- }, 156); */
|
|
|
-
|
|
|
- //console.log('intersect', intersect)
|
|
|
+ intersect = this.getIntersect(Object.assign({}, e, {viewport, dontIntersect, clientX:e.clientX, clientY:e.clientY })) //数据集多的时候卡顿
|
|
|
+
|
|
|
}
|
|
|
|
|
|
- if(e.onlyGetIntersect){
|
|
|
- /* if(Potree.settings.intersectOnObjs){
|
|
|
- let hoveredElements = this.getHoveredElements() //应该不用发送mouseover事件吧
|
|
|
- let intersect = this.getWholeIntersect(hoveredElements, intersectPoint)
|
|
|
- return intersect
|
|
|
- }
|
|
|
- return intersectPoint */
|
|
|
+ if(e.onlyGetIntersect){
|
|
|
return intersect
|
|
|
}
|
|
|
e.preventDefault();
|