|
@@ -190,11 +190,8 @@ export class Viewer extends ViewerBase{
|
|
|
|
|
|
this.fakeMeasure = {};
|
|
|
|
|
|
- document.addEventListener('visibilitychange',(e)=>{
|
|
|
- //console.log('visibilitychange', !document.hidden )
|
|
|
- this.dispatchEvent({type:'pageVisible', v:!document.hidden} )
|
|
|
-
|
|
|
- })
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
@@ -802,7 +799,24 @@ export class Viewer extends ViewerBase{
|
|
|
|
|
|
|
|
|
}
|
|
|
-
|
|
|
+ {
|
|
|
+ let interval
|
|
|
+ document.addEventListener('visibilitychange',(e)=>{
|
|
|
+ let v = !document.hidden
|
|
|
+ console.warn('visibilitychange', v )
|
|
|
+ this.dispatchEvent({type:'pageVisible', v } )
|
|
|
+
|
|
|
+ if(this.screenshoting && !v){
|
|
|
+ interval = setInterval(()=>{
|
|
|
+ if(this.screenshoting){ //截图完成时如果还没回来就不loop
|
|
|
+ this.loop(Date.now())
|
|
|
+ }
|
|
|
+ },30)
|
|
|
+ }else if(v && interval){
|
|
|
+ clearInterval(interval)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
|
|
|
/* if(!Potree.isIframeChild){
|
|
|
window.winIndex = 0;
|
|
@@ -3487,7 +3501,8 @@ export class Viewer extends ViewerBase{
|
|
|
//离屏渲染 有抗锯齿问题、在手机上速度慢
|
|
|
var { dataUrl } = viewerMaster.makeScreenshot( new THREE.Vector2(width,height), null, compressRatio );
|
|
|
|
|
|
- }else{
|
|
|
+ }else{
|
|
|
+
|
|
|
//直接渲染 会改变canvas大小
|
|
|
let canvas = this.renderArea.getElementsByTagName('canvas')[0]
|
|
|
this.render({ screenshot : true, width , height, resize :true }); //需要resize
|
|
@@ -3548,6 +3563,7 @@ export class Viewer extends ViewerBase{
|
|
|
|
|
|
|
|
|
if(info.type == 'measure'){
|
|
|
+ this.modules.SiteModel.pauseUpdateEntity = false
|
|
|
this.scene.measurements.forEach(e=>Potree.Utils.updateVisible(e, 'screenshot',true))
|
|
|
info.measurement.setSelected(false, 'screenshot')
|
|
|
}
|
|
@@ -3620,9 +3636,7 @@ export class Viewer extends ViewerBase{
|
|
|
oldStates.viewports.push(mapViewport.clone())
|
|
|
oldStates.attachedToViewer = this.mapViewer.attachedToViewer
|
|
|
oldStates.mapZoom = mapViewport.camera.zoom
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
Potree.Utils.updateVisible(this.mapViewer.cursor, 'screenshot', false)//令mapCursor不可见
|
|
|
}
|
|
|
|
|
@@ -3634,8 +3648,7 @@ export class Viewer extends ViewerBase{
|
|
|
})
|
|
|
}
|
|
|
Potree.Utils.updateVisible(this.reticule, 'screenshot', false)//令reticule不可见
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
Potree.settings.pointDensity = 'screenshot'
|
|
|
|
|
|
|
|
@@ -3662,7 +3675,7 @@ export class Viewer extends ViewerBase{
|
|
|
}
|
|
|
|
|
|
|
|
|
- let maxTime = 2000
|
|
|
+ let maxTime = 1000
|
|
|
setTimeout(()=>{
|
|
|
if(Potree.pointsLoading && Potree.settings.displayMode == 'showPointCloud'){//如果还在加载
|
|
|
|
|
@@ -3670,39 +3683,18 @@ export class Viewer extends ViewerBase{
|
|
|
//if(!finish)console.warn('加载完毕', ' numVisiblePoints', Potree.numVisiblePoints)
|
|
|
dealDone()
|
|
|
},{once:true})
|
|
|
- let lastNumVisiblePoints
|
|
|
- /* { //perspective的不需要,远处加载不完也没大碍
|
|
|
- setTimeout(()=>{//超时不候
|
|
|
- if(!finish ){
|
|
|
- console.warn('加载时间达最长限制的50%,降level, numVisiblePoints', Potree.numVisiblePoints)
|
|
|
- lastNumVisiblePoints = Potree.numVisiblePoints
|
|
|
- decreaseLevel() //加载时间过长
|
|
|
- }
|
|
|
- },maxTime*0.5)
|
|
|
- setTimeout(()=>{// 第一次降有可能没效果,因为大部分level不是最高的
|
|
|
- console.warn('加载时间达最长限制的60%,numVisiblePoints', Potree.numVisiblePoints)
|
|
|
- if(!finish && (Potree.numVisiblePoints - lastNumVisiblePoints) > -20000 ){ //没怎么降
|
|
|
- console.warn('加载时间达最长限制的60%,降level, numVisiblePoints', Potree.numVisiblePoints)
|
|
|
- decreaseLevel() //加载时间过长
|
|
|
- }
|
|
|
- },maxTime*0.6)
|
|
|
- } */
|
|
|
- setTimeout(()=>{//超时不候
|
|
|
+
|
|
|
+
|
|
|
+ setTimeout(()=>{//超时不候(其实之后等待地图还会再加载几秒)
|
|
|
//if(!finish)console.warn('超时, numVisiblePoints', Potree.numVisiblePoints)
|
|
|
dealDone()
|
|
|
},maxTime)
|
|
|
}else{
|
|
|
dealDone()
|
|
|
}
|
|
|
- },200)//先加载一段时间
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ },200)//先加载一段时间
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- let waitPointsTime = Potree.settings.displayMode == 'showPointCloud' ? 300 : 0 //等点云加载
|
|
|
-
|
|
|
+
|
|
|
|
|
|
if(info.type == 'measure'){//要截图双屏
|
|
|
this.scene.measurements.forEach(e=>Potree.Utils.updateVisible(e,'screenshot',e == info.measurement) )
|
|
@@ -3721,35 +3713,36 @@ export class Viewer extends ViewerBase{
|
|
|
updateCamera()
|
|
|
if(useMap){
|
|
|
let waitMap = ()=>{
|
|
|
- console.log('waitMap: '+sid, Date.now(), this.mapViewer.mapLayer.loadingInProgress )
|
|
|
+ console.log('waitMap: '+sid, Date.now(), this.mapViewer.mapLayer.loadingInProgress )
|
|
|
this.mapViewer.waitLoadDone(screenshot.bind(this))//等待地图所有加载完
|
|
|
- }
|
|
|
-
|
|
|
- waitPointLoad(waitMap)
|
|
|
-
|
|
|
- //setTimeout(waitMap.bind(this), waitPointsTime)
|
|
|
- }else{
|
|
|
- //setTimeout(screenshot.bind(this), waitPointsTime)
|
|
|
+ }
|
|
|
+ waitPointLoad(waitMap)
|
|
|
+ }else{
|
|
|
waitPointLoad()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- let {promise} = this.focusOnObject(info.measurement, 'measure', 0, {basePanoSize:1024} )//注意:不同角度截图 得到三维的会不一样,因为focusOnObject是根据方向的
|
|
|
+ let {promise} = this.focusOnObject(info.measurement, 'measure', 0, {
|
|
|
+ basePanoSize:1024, gotoBestView:true,
|
|
|
+ minMapWidth: this.mapViewer.mapLayer.maps.find(e=>e.name == 'map').disabled ? 10 : 20 //有地图的话为了显示出名字需要更大范围
|
|
|
+ })//注意:不同角度截图 得到三维的会不一样,因为focusOnObject是根据方向的
|
|
|
promise.done(()=>{
|
|
|
//console.log('promise.done')
|
|
|
//根据当前位置更新floorplan显示
|
|
|
//console.log('view Pos ', this.mainViewport.view.position.toArray())
|
|
|
- this.updateDatasetAt(true)
|
|
|
- this.modules.SiteModel.updateEntityAt(true)
|
|
|
+
|
|
|
+ this.updateDatasetAt(true)
|
|
|
+ this.modules.SiteModel.updateEntityAt(true, {measure:info.measurement}) //更新测量线所在楼层,展示俯视图
|
|
|
+ this.modules.SiteModel.pauseUpdateEntity = true
|
|
|
//this.updateFpVisiDatasets()
|
|
|
|
|
|
//console.log('currentFloor', this.modules.SiteModel.currentFloor, 'currentDataset', this.atDatasets )
|
|
|
-
|
|
|
+
|
|
|
let floorplanShowed = this.mapViewer.mapLayer.maps.some(e => e.name.includes('floorplan') && e.objectGroup.visible)//如果没有floorplan展示就不分屏(如果focus时飞出数据集从而不展示怎么办。尤其是俯瞰比较长的线时容易这样,或许要根据其所在数据集强制显示)
|
|
|
if(!floorplanShowed && this.mapViewer.attachedToViewer){
|
|
|
this.mapViewer.attachToMainViewer(false) //取消分屏
|
|
|
viewer.updateScreenSize({forceUpdateSize:true, width, height}) //更新viewports相机透视
|
|
|
- let {promise} = this.focusOnObject(info.measurement, 'measure', 0, {basePanoSize:1024} )//因画面比例更改,重新focus
|
|
|
+ let {promise} = this.focusOnObject(info.measurement, 'measure', 0, {basePanoSize:1024,gotoBestView:true,} )//因画面比例更改,重新focus
|
|
|
promise.done(()=>{
|
|
|
begin()
|
|
|
})
|
|
@@ -3891,41 +3884,74 @@ export class Viewer extends ViewerBase{
|
|
|
if (type == 'measure') {
|
|
|
target.copy(object.getCenter())
|
|
|
|
|
|
-
|
|
|
-
|
|
|
//试试改变位置(方向),直视测量线。能避免倾斜角度造成的非常不居中、以及看不到面的情况
|
|
|
- if(object.points.length>2/* && window.focusMeasureFaceToIt */){
|
|
|
-
|
|
|
- let facePlane = object.facePlane || new THREE.Plane().setFromCoplanarPoints(...object.points.slice(0,3) )
|
|
|
- let normal = facePlane.normal.clone()
|
|
|
- let angle = this.scene.view.direction.angleTo(normal)
|
|
|
- let minDiff = THREE.Math.degToRad(60)
|
|
|
- //console.log('angle',angle)
|
|
|
- if(angle>minDiff && angle<Math.PI-minDiff){//当几乎正对时就不执行
|
|
|
- if(angle<Math.PI/2){ //在背面
|
|
|
- normal.negate()
|
|
|
- }
|
|
|
- let dir = new THREE.Vector3().subVectors(camera.position, target).normalize()
|
|
|
- let newDir = new THREE.Vector3().addVectors(dir,normal)//两个角度的中间
|
|
|
- cameraPos.copy(target.clone().add(newDir))
|
|
|
- }
|
|
|
- }else if(object.points.length == 2){ //线段
|
|
|
- let lineDir = new THREE.Vector3().subVectors(object.points[0],object.points[1]).normalize()
|
|
|
- let angle = this.scene.view.direction.angleTo(lineDir)
|
|
|
- let maxDiff = Math.PI*0.25// 45度
|
|
|
- if(angle<maxDiff || angle>Math.PI-maxDiff){//当几乎正对时就不执行
|
|
|
- if(angle>Math.PI/2){ //令dir和lineDir成钝角
|
|
|
- lineDir.negate()
|
|
|
+ if(o.gotoBestView){//直接沿着法线方向看
|
|
|
+ if(object.points.length>2){
|
|
|
+ let facePlane = object.getFacePlane(target)
|
|
|
+ let normal = facePlane.normal.clone();
|
|
|
+
|
|
|
+ if(normal.dot(this.mainViewport.view.direction) > 0){
|
|
|
+ normal.negate() //顺着视线
|
|
|
}
|
|
|
- let dir = new THREE.Vector3().subVectors(camera.position, target).normalize()
|
|
|
- let mid = new THREE.Vector3().addVectors(lineDir, dir).normalize() //中间法向量(如果刚好dir和lineDir反向,那得到的为零向量,就不移动了,但一般不会酱紫吧)
|
|
|
- let newDir = new THREE.Vector3().addVectors(dir, mid)
|
|
|
- cameraPos.copy(target.clone().add(newDir))
|
|
|
- }
|
|
|
+ //normal.z = Math.max(0.2, normal.z)//尽量不要仰视
|
|
|
+ cameraPos.copy(target).add(normal)
|
|
|
+ }else{
|
|
|
+ let lineDir = new THREE.Vector3().subVectors(object.points[0],object.points[1]).normalize()
|
|
|
+ let facePlane = new THREE.Plane().setFromNormalAndCoplanarPoint(lineDir, target)
|
|
|
+ //if(cameraPos.z < target.z + 1)cameraPos.z = target.z + 1//尽量不要仰视
|
|
|
+
|
|
|
+ let dir = new THREE.Vector3().subVectors(cameraPos,target).normalize()
|
|
|
+ dir.z = Math.max(dir.z, 0.4);
|
|
|
+ cameraPos.copy(target).add(dir)//尽量不要仰视
|
|
|
+
|
|
|
+
|
|
|
+ let dis = cameraPos.distanceTo(target)
|
|
|
+ dir = lineDir.clone().multiplyScalar(dis)
|
|
|
+ let line = new THREE.Line3().set(cameraPos.clone().add(dir), cameraPos.clone().add(dir.negate())) //过相机位置作到面的垂线
|
|
|
+ facePlane.intersectLine(line, cameraPos ) //得垂足,作为新的相机位置。就能在测量线中间看测量线
|
|
|
+
|
|
|
+ }
|
|
|
}else{
|
|
|
- console.error('measure 没有facePlane points点数还不为2?')
|
|
|
- }
|
|
|
-
|
|
|
+ if(object.points.length>2){
|
|
|
+ let facePlane = object.getFacePlane(target)
|
|
|
+ let normal = facePlane.normal.clone()
|
|
|
+ let angle = this.scene.view.direction.angleTo(normal)
|
|
|
+ let minDiff = THREE.Math.degToRad(60)
|
|
|
+ //console.log('angle',angle)
|
|
|
+ if(angle>minDiff && angle<Math.PI-minDiff){//当几乎正对时就不执行
|
|
|
+ if(angle<Math.PI/2){ //在背面
|
|
|
+ normal.negate()
|
|
|
+ }
|
|
|
+ let dir = new THREE.Vector3().subVectors(camera.position, target).normalize()
|
|
|
+ let newDir = new THREE.Vector3().addVectors(dir,normal)//两个角度的中间
|
|
|
+ cameraPos.copy(target.clone().add(newDir))
|
|
|
+ }
|
|
|
+ }else if(object.points.length == 2){ //线段
|
|
|
+ let lineDir = new THREE.Vector3().subVectors(object.points[0],object.points[1]).normalize()
|
|
|
+ let angle = this.scene.view.direction.angleTo(lineDir)
|
|
|
+ let maxDiff = Math.PI*0.25// 45度
|
|
|
+ if(angle<maxDiff || angle>Math.PI-maxDiff){//当几乎正对时就不执行
|
|
|
+ if(angle>Math.PI/2){ //令dir和lineDir成钝角
|
|
|
+ lineDir.negate()
|
|
|
+ }
|
|
|
+ let dir = new THREE.Vector3().subVectors(camera.position, target).normalize()
|
|
|
+ let mid = new THREE.Vector3().addVectors(lineDir, dir).normalize() //中间法向量(如果刚好dir和lineDir反向,那得到的为零向量,就不移动了,但一般不会酱紫吧)
|
|
|
+ let newDir = new THREE.Vector3().addVectors(dir, mid)
|
|
|
+ cameraPos.copy(target.clone().add(newDir))
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ console.error('measure 没有facePlane points点数还不为2?')
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //截图时直接飞到最佳视角,也就是平视它所在面。其余时候为了避免镜头旋转过大就算了。
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
position = getPosWithFullBound(object.points, null, target, cameraPos )
|
|
|
|
|
@@ -3934,7 +3960,8 @@ export class Viewer extends ViewerBase{
|
|
|
|
|
|
if(this.mapViewer/* .attachedToViewer */){
|
|
|
//console.log('mapFocusOn: '+target.toArray())
|
|
|
- const minBound = new THREE.Vector2(2,2)//针对垂直线,在地图上只有一个点
|
|
|
+ const minMapWidth = o.minMapWidth || 2 //截图的时候要显示的地图范围较大,为了显示出地区名字
|
|
|
+ const minBound = new THREE.Vector2(minMapWidth,minMapWidth)//针对垂直线,在地图上只有一个点
|
|
|
//原始的bound
|
|
|
let boundOri = new THREE.Box3()
|
|
|
object.points.forEach(e=>{
|
|
@@ -3955,7 +3982,7 @@ export class Viewer extends ViewerBase{
|
|
|
if(Potree.settings.displayMode == 'showPointCloud'){ //点云
|
|
|
let minDis = 0.3;
|
|
|
|
|
|
- //if(o.checkIntersect){
|
|
|
+ if(0 ){//如果没有被选中,会被遮挡。 2023.11.15 最好展示全局(尤其截图时),虽然被遮挡,但focus的过程是选中状态全显示的,可以看出所在范围。
|
|
|
let checkIntersect = ( )=>{
|
|
|
let intersect = this.inputHandler.ifBlockedByIntersect({pos3d:position, cameraPos: target})// 不一定准确
|
|
|
if(intersect){
|
|
@@ -4009,7 +4036,7 @@ export class Viewer extends ViewerBase{
|
|
|
|
|
|
checkIntersect()
|
|
|
//多折线没有areaPlane 有时候会看向空白区域 - -
|
|
|
- //}
|
|
|
+ }
|
|
|
}else if(Potree.settings.displayMode == 'showPanos'){//全景 (比较难校准)
|
|
|
let target2, dir
|
|
|
if( object.measureType.includes('MulDistance')){//因为该线不闭合,可能看向target的方向会没有线,所以换一个target
|
|
@@ -4423,7 +4450,7 @@ export class Viewer extends ViewerBase{
|
|
|
|
|
|
loop(timestamp){
|
|
|
//let startTime = performance.now()
|
|
|
- //console.log('间隔:' ,parseInt((startTime - this.lastEndTime)*100 )/100)
|
|
|
+ console.log('间隔:' /*, parseInt((startTime - this.lastEndTime)*100 )/100 */)
|
|
|
if(this.paused)return
|
|
|
if(performance.getEntriesByName("loopWaitNext-start").length)viewer.addTimeMark('loopWaitNext','end')
|
|
|
|