|
@@ -915,21 +915,22 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
- flyToPano(toPano) { //飞向漫游点
|
|
|
|
|
- if(!toPano)return
|
|
|
|
|
|
|
+ flyToPano(toPano={}) { //飞向漫游点
|
|
|
|
|
+
|
|
|
if(typeof toPano == 'number')toPano = this.panos[toPano]
|
|
if(typeof toPano == 'number')toPano = this.panos[toPano]
|
|
|
if(toPano instanceof Panorama){
|
|
if(toPano instanceof Panorama){
|
|
|
toPano = {pano: toPano}
|
|
toPano = {pano: toPano}
|
|
|
}
|
|
}
|
|
|
|
|
+ if(!toPano?.pano )return toPano?.deferred?.resolve(false)
|
|
|
|
|
|
|
|
|
|
|
|
|
let done = (makeIt, disturb)=>{
|
|
let done = (makeIt, disturb)=>{
|
|
|
//console.log('flyToPano done ', toPano.pano.id, makeIt, disturb )
|
|
//console.log('flyToPano done ', toPano.pano.id, makeIt, disturb )
|
|
|
if(makeIt || disturb) { // disturb已经开始飞行但中途取消
|
|
if(makeIt || disturb) { // disturb已经开始飞行但中途取消
|
|
|
- toPano.callback && toPano.callback(makeIt)
|
|
|
|
|
//this.flying = false
|
|
//this.flying = false
|
|
|
this.cancelFlyToPano(toPano)
|
|
this.cancelFlyToPano(toPano)
|
|
|
this.updateClosestPano(this.closestPano,false) //飞行结束后取消点击漫游点时得到的closestPano
|
|
this.updateClosestPano(this.closestPano,false) //飞行结束后取消点击漫游点时得到的closestPano
|
|
|
|
|
+ toPano.callback && toPano.callback(makeIt)
|
|
|
}else{
|
|
}else{
|
|
|
if(toPano.retryUntilArrive){//一直试直到可以飞成功
|
|
if(toPano.retryUntilArrive){//一直试直到可以飞成功
|
|
|
//console.log('wait for reFly to pano ', toPano.pano.id)
|
|
//console.log('wait for reFly to pano ', toPano.pano.id)
|
|
@@ -1835,10 +1836,10 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
option1 = void 0 !== option1 ? option1 : 0.6 //.75; 2024.3.22改小,也就是可以走的角度范围增加,主要针对像山野那种很大的场景,不知道可以走哪,容易因角度范围内无近点而飞到远处的情况。但不能太小,总是横着走路
|
|
option1 = void 0 !== option1 ? option1 : 0.6 //.75; 2024.3.22改小,也就是可以走的角度范围增加,主要针对像山野那种很大的场景,不知道可以走哪,容易因角度范围内无近点而飞到远处的情况。但不能太小,总是横着走路
|
|
|
var o = option2 ? "angle" : "direction";
|
|
var o = option2 ? "angle" : "direction";
|
|
|
|
|
|
|
|
- var floor = viewer.modules.SiteModel.currentFloor;
|
|
|
|
|
|
|
+ /* var floor = viewer.modules.SiteModel.currentFloor;
|
|
|
var entity = viewer.modules.SiteModel.inEntity;
|
|
var entity = viewer.modules.SiteModel.inEntity;
|
|
|
let scaleFactor = Math.pow( this.currentPano?.pointcloud.scale.x || 1 , 2)
|
|
let scaleFactor = Math.pow( this.currentPano?.pointcloud.scale.x || 1 , 2)
|
|
|
- let changeTexCount = 0, maxWaitDur = 300
|
|
|
|
|
|
|
+ */let changeTexCount = 0, maxWaitDur = 300
|
|
|
//maxSamplerChangeTex = THREE.Math.clamp( maxWaitDur / Potree.timeCollect.depthSampler.median, 2, 10) //计算换贴图最大数目
|
|
//maxSamplerChangeTex = THREE.Math.clamp( maxWaitDur / Potree.timeCollect.depthSampler.median, 2, 10) //计算换贴图最大数目
|
|
|
|
|
|
|
|
|
|
|
|
@@ -2165,7 +2166,7 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
let cos = dir.dot(vec2)
|
|
let cos = dir.dot(vec2)
|
|
|
//let result = (- dis1 - Math.pow(dis2 , 1.5)) / (cos + 2) // cos+2是为了调整到1-3,
|
|
//let result = (- dis1 - Math.pow(dis2 , 1.5)) / (cos + 2) // cos+2是为了调整到1-3,
|
|
|
|
|
|
|
|
- let result = (dis1 + dis2*0.3) * ( -1 + cos*0.4 ) //尽量贴近最佳位置的角度, 或贴近相机原来的角度 。尽量靠近最佳观测点,并且优先选择靠近目标点的位置.(注意cos的乘数不能太接近1,否则容易只考虑角度)
|
|
|
|
|
|
|
+ let result = (dis1 + dis2*0.3) * ( -1 + cos*0.9 ) //尽量贴近最佳位置的角度, 或贴近相机原来的角度 。尽量靠近最佳观测点,并且优先选择靠近目标点的位置.(注意cos的乘数不能太接近1,否则容易只考虑角度)
|
|
|
//Potree.Log(pano.id, dis1, dis2, cos, result,{font:{toFixed:2,fontSize:10}})
|
|
//Potree.Log(pano.id, dis1, dis2, cos, result,{font:{toFixed:2,fontSize:10}})
|
|
|
|
|
|
|
|
return result
|
|
return result
|
|
@@ -2314,7 +2315,7 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
|
|
|
|
|
let levelThreshold1 = Potree.settings.navTileClass == '1k' ? 1.3 : 1.7 , levelThreshold2 = 2
|
|
let levelThreshold1 = Potree.settings.navTileClass == '1k' ? 1.3 : 1.7 , levelThreshold2 = 2
|
|
|
|
|
|
|
|
- var t = this.zoomLevel > levelThreshold1,
|
|
|
|
|
|
|
+ var t = Potree.settings.highestQualityTile || this.zoomLevel > levelThreshold1,
|
|
|
n = !(this.flying && this.nextPano && this.nextPano !== this.currentPano),
|
|
n = !(this.flying && this.nextPano && this.nextPano !== this.currentPano),
|
|
|
r = t && n;
|
|
r = t && n;
|
|
|
this.tileDownloader.tilePrioritizer.setZoomingActive(r);
|
|
this.tileDownloader.tilePrioritizer.setZoomingActive(r);
|
|
@@ -2336,13 +2337,13 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
if (r && (!currentPano.zoomed || this.qualityManager.zoomLevelResolution && this.qualityManager.zoomLevelResolution != '4k')) {//needZoom
|
|
if (r && (!currentPano.zoomed || this.qualityManager.zoomLevelResolution && this.qualityManager.zoomLevelResolution != '4k')) {//needZoom
|
|
|
currentPano.zoomed || o(currentPano, !0);
|
|
currentPano.zoomed || o(currentPano, !0);
|
|
|
|
|
|
|
|
- if(Potree.settings.navTileClass == '1k' && Potree.settings.tileClass != '1k' && this.zoomLevel < levelThreshold2){
|
|
|
|
|
|
|
+ if(Potree.settings.navTileClass == 1024 && Potree.settings.tileClass > 1024 && this.zoomLevel < levelThreshold2){
|
|
|
this.panoRenderer.enableHighQuality( function() {//开启2k
|
|
this.panoRenderer.enableHighQuality( function() {//开启2k
|
|
|
- if(Potree.settings.tileClass != '4k') o(currentPano, !0);
|
|
|
|
|
|
|
+ if(Potree.settings.tileClass < 4096) o(currentPano, !0);
|
|
|
}.bind(this));
|
|
}.bind(this));
|
|
|
}else{
|
|
}else{
|
|
|
this.panoRenderer.enableUltraHighQualityMode(function() {//开启4k getMaxZoomPanoSize
|
|
this.panoRenderer.enableUltraHighQualityMode(function() {//开启4k getMaxZoomPanoSize
|
|
|
- this.qualityManager.useUltraHighResolutionPanos && (Potree.settings.zoom.max = Potree.config.ultraHighQualityMaxZoom);
|
|
|
|
|
|
|
+ //this.qualityManager.useUltraHighResolutionPanos && (Potree.settings.zoom.max = this.currentPano.getZoomMax() ) //加了其他逻辑太复杂,改为一开始就根据tileClass修改好了max
|
|
|
o(currentPano, !0)
|
|
o(currentPano, !0)
|
|
|
}.bind(this));
|
|
}.bind(this));
|
|
|
}
|
|
}
|
|
@@ -2352,7 +2353,7 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- if(r && Potree.settings.navTileClass == '1k' && Potree.settings.tileClass == '4k' ){ //目前只有手机端navTileClass == '1k' (分三个梯度)
|
|
|
|
|
|
|
+ if(r && Potree.settings.navTileClass == 1024 && Potree.settings.tileClass >= 4096 ){ //目前只有手机端navTileClass == '1k' (分三个梯度)
|
|
|
var change = (zoomedFlag)=>{
|
|
var change = (zoomedFlag)=>{
|
|
|
this.qualityManager.updateMaximums()//更新maxZoomPanoSize
|
|
this.qualityManager.updateMaximums()//更新maxZoomPanoSize
|
|
|
this.panoRenderer.setupZoomRenderTarget() //更新renderTarget
|
|
this.panoRenderer.setupZoomRenderTarget() //更新renderTarget
|
|
@@ -2387,7 +2388,7 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
|
|
|
|
|
addHighMapCube(){//创建8*8的tile cube 主要因手机版崩溃 要在电脑端测试得设置maxRenderTargetSize
|
|
addHighMapCube(){//创建8*8的tile cube 主要因手机版崩溃 要在电脑端测试得设置maxRenderTargetSize
|
|
|
|
|
|
|
|
- if( Potree.settings.tileClass == '4k' && this.qualityManager.maxRenderTargetSize == 2048){
|
|
|
|
|
|
|
+ if( this.qualityManager.maxRenderTargetSize < Potree.settings.tileClass && !this.highMapCube){
|
|
|
|
|
|
|
|
var geo = new THREE.PlaneGeometry(1, 1, 1, 1)
|
|
var geo = new THREE.PlaneGeometry(1, 1, 1, 1)
|
|
|
var cube = new THREE.Object3D;
|
|
var cube = new THREE.Object3D;
|
|
@@ -2475,10 +2476,10 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
cube.scale.set(s,s,s)
|
|
cube.scale.set(s,s,s)
|
|
|
}//注:由于原本的mesh上加了深度贴图,可能距离镜头比这里的近。凡是在cube以内的部分都会挡住cube导致模糊。但是应该不常见吧(另外到天空的边缘也是很近)。姑且depthTest=false
|
|
}//注:由于原本的mesh上加了深度贴图,可能距离镜头比这里的近。凡是在cube以内的部分都会挡住cube导致模糊。但是应该不常见吧(另外到天空的边缘也是很近)。姑且depthTest=false
|
|
|
|
|
|
|
|
- this.highMapCube.visible = false;
|
|
|
|
|
- Potree.Utils.setObjectLayers(this.highMapCube, 'sceneObjects'/* 'skybox' */) //因它的深度是错误的,故不在skybox层渲染,影响edlRT, 而在renderOverlay时渲染覆盖。
|
|
|
|
|
|
|
+ this.hideHighMap()
|
|
|
|
|
+ Potree.Utils.setObjectLayers(this.highMapCube, 'sceneObjects'/* 'skybox' */) // 它的深度是错误的,故不在skybox层渲染,影响edlRT, 而在renderOverlay时渲染覆盖。
|
|
|
//console.warn('addHighMapCube')
|
|
//console.warn('addHighMapCube')
|
|
|
-
|
|
|
|
|
|
|
+ //this.panoRenderer.deleteZoomRT() //要等不在使用时再删
|
|
|
|
|
|
|
|
viewer.addEventListener('update',()=>{
|
|
viewer.addEventListener('update',()=>{
|
|
|
if (this.highMapCube.visibleTiles) {
|
|
if (this.highMapCube.visibleTiles) {
|
|
@@ -2511,7 +2512,7 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
|
|
|
|
|
|
|
|
|
|
updateTiles(direction) {
|
|
updateTiles(direction) {
|
|
|
- if (!this.highMapCube || !this.highMapCube.visible) return
|
|
|
|
|
|
|
+ if (!this.canUseMapCube() || !this.highMapCube.visible) return
|
|
|
|
|
|
|
|
if (this.highMapCube.tiles.filter(e => e.image).length <= 10) return //加载的太少了
|
|
if (this.highMapCube.tiles.filter(e => e.image).length <= 10) return //加载的太少了
|
|
|
//performance.mark('updateTiles-start')
|
|
//performance.mark('updateTiles-start')
|
|
@@ -2523,31 +2524,59 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
/* let hcos = Math.cos(hfov / 2)
|
|
/* let hcos = Math.cos(hfov / 2)
|
|
|
let vcos = Math.cos(vfov / 2) */
|
|
let vcos = Math.cos(vfov / 2) */
|
|
|
let list = this.highMapCube.tiles
|
|
let list = this.highMapCube.tiles
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ let frustumMatrix = new THREE.Matrix4
|
|
|
|
|
+ frustumMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)
|
|
|
|
|
+ let frustum = new THREE.Frustum();
|
|
|
|
|
+ frustum.setFromProjectionMatrix(frustumMatrix)
|
|
|
|
|
+ let p_ = new THREE.Vector3
|
|
|
|
|
+ let time = performance.now()
|
|
|
|
|
+
|
|
|
|
|
+ //let history_ = [],same = 0
|
|
|
|
|
+
|
|
|
list.forEach(e => {
|
|
list.forEach(e => {
|
|
|
//屏幕外的不显示
|
|
//屏幕外的不显示
|
|
|
- let pos = e.getWorldPosition(new THREE.Vector3())
|
|
|
|
|
|
|
+ /* let pos = e.getWorldPosition(new THREE.Vector3())
|
|
|
let dir = new THREE.Vector3().subVectors(pos, this.highMapCube.position).normalize()
|
|
let dir = new THREE.Vector3().subVectors(pos, this.highMapCube.position).normalize()
|
|
|
-
|
|
|
|
|
|
|
+ //再看好像不对
|
|
|
let hcos_ = dir.clone().setZ(direction.z).normalize().dot(direction) //在direction的斜面上水平角度差
|
|
let hcos_ = dir.clone().setZ(direction.z).normalize().dot(direction) //在direction的斜面上水平角度差
|
|
|
let hRad = Math.acos(hcos_)
|
|
let hRad = Math.acos(hcos_)
|
|
|
let vRad = -200
|
|
let vRad = -200
|
|
|
- if (/* hRad > hfov + 0.08 */ hRad / hfov > 1.5 ) {
|
|
|
|
|
|
|
+ if ( hRad / hfov > 1.5 ) {
|
|
|
e.score = -100
|
|
e.score = -100
|
|
|
} else {
|
|
} else {
|
|
|
vRad = Math.abs(Math.acos(dir.z) - Math.acos(direction.z))
|
|
vRad = Math.abs(Math.acos(dir.z) - Math.acos(direction.z))
|
|
|
- if (/* vRad > vfov + 0.08 */ vRad / vfov > 1.5 ) {
|
|
|
|
|
|
|
+ if ( vRad / vfov > 1.5 ) {
|
|
|
e.score = -100
|
|
e.score = -100
|
|
|
} else {
|
|
} else {
|
|
|
e.score = -(hRad / hfov + vRad / vfov)
|
|
e.score = -(hRad / hfov + vRad / vfov)
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- e.scores = hRad.toFixed(3) + ', ' + vRad.toFixed(3)
|
|
|
|
|
-
|
|
|
|
|
|
|
+ } */
|
|
|
|
|
+ let a = frustum.intersectsObject(e)//外包围球粗略判断
|
|
|
|
|
+ if(a){//显示所有在屏幕上有显示的tile
|
|
|
|
|
+ e.score = 1
|
|
|
|
|
+ /* for(let i=0;i<4;i++){//精确计算,检测是否四个顶点都在屏幕内(虽然减少不了多少个 )
|
|
|
|
|
+ p_.copy(e.geometry.vertices[i]).applyMatrix4(e.matrixWorld)
|
|
|
|
|
+
|
|
|
|
|
+ if(history_.find(o=>math.closeTo(o,p_)) || frustum.containsPoint(p_) ){
|
|
|
|
|
+ e.score = 2
|
|
|
|
|
+ history_.push( p_.clone() )
|
|
|
|
|
+ break
|
|
|
|
|
+ }//
|
|
|
|
|
+ 若tile底部横跨屏幕,且中心点不在屏幕,将检测不到,所以不算了
|
|
|
|
|
+ */
|
|
|
|
|
+ }else e.score = -100
|
|
|
|
|
+ //e.score = frustum.intersectsObject(e) ? 1 : -100
|
|
|
|
|
+ //e.scores = hRad.toFixed(3) + ', ' + vRad.toFixed(3)
|
|
|
if (e.score == -100) {
|
|
if (e.score == -100) {
|
|
|
this.resetTile(e)
|
|
this.resetTile(e)
|
|
|
}
|
|
}
|
|
|
})
|
|
})
|
|
|
this.highMapCube.visibleTiles = list.filter(e => e.score > -100)
|
|
this.highMapCube.visibleTiles = list.filter(e => e.score > -100)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ //console.log('cost', performance.now() - time, 'same',same)
|
|
|
//list.forEach(e=>e.scoreLabel.setText(e.scores))
|
|
//list.forEach(e=>e.scoreLabel.setText(e.scores))
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2646,11 +2675,14 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
|
+ canUseMapCube(pano = this.currentPano, panoSize){
|
|
|
|
|
+ if(typeof pano == 'number') pano = this.getPano(pano)
|
|
|
|
|
+ return this.highMapCube && (panoSize || pano?.pointcloud.tileClass) >= 4096//this.qualityManager.maxRenderTargetSize
|
|
|
|
|
+ } //考虑到可能2k 4k 6k的场景同时存在,而maxRenderTargetSize也可能是任意一个,所以只要有一个>4096的,4096时也用cube
|
|
|
|
|
|
|
|
|
|
|
|
|
resetHighMap() {
|
|
resetHighMap() {
|
|
|
- if (!this.highMapCube) return
|
|
|
|
|
|
|
+ if (!this.canUseMapCube()) return
|
|
|
this.highMapCube.children.forEach(e =>
|
|
this.highMapCube.children.forEach(e =>
|
|
|
e.children.forEach(tile => {
|
|
e.children.forEach(tile => {
|
|
|
this.resetTile(tile, true)
|
|
this.resetTile(tile, true)
|
|
@@ -2663,7 +2695,7 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
setHighMap(pano){
|
|
setHighMap(pano){
|
|
|
- if(!this.highMapCube) return
|
|
|
|
|
|
|
+ if(!this.canUseMapCube()) return
|
|
|
this.highMapCube.position.copy(pano.position)
|
|
this.highMapCube.position.copy(pano.position)
|
|
|
|
|
|
|
|
//可以利用第0个pano查看,其 rotation4dkk是(_x: 0, _y: -1.5707963267948966, _z: 0 )而手动旋转至(_x:1.5707963, _y: -1.57079, _z: 0)时才正确,说明要在4dkk的旋转基础上,绕x轴转90度,(也就是转成navvis坐标系), 然后得到YupToZup的函数写法的
|
|
//可以利用第0个pano查看,其 rotation4dkk是(_x: 0, _y: -1.5707963267948966, _z: 0 )而手动旋转至(_x:1.5707963, _y: -1.57079, _z: 0)时才正确,说明要在4dkk的旋转基础上,绕x轴转90度,(也就是转成navvis坐标系), 然后得到YupToZup的函数写法的
|
|
@@ -2679,15 +2711,15 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
showHighMap(){
|
|
showHighMap(){
|
|
|
- if(!this.highMapCube) return
|
|
|
|
|
|
|
+ if(!this.canUseMapCube() || this.currentPano.tile) return
|
|
|
//console.warn('showHighMap')
|
|
//console.warn('showHighMap')
|
|
|
- this.highMapCube.visible = true;
|
|
|
|
|
|
|
+ Potree.Utils.updateVisible(this.highMapCube, 'show', true)
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
hideHighMap(){
|
|
hideHighMap(){
|
|
|
if(!this.highMapCube) return
|
|
if(!this.highMapCube) return
|
|
|
//console.warn('hideHighMap')
|
|
//console.warn('hideHighMap')
|
|
|
- this.highMapCube.visible = false;
|
|
|
|
|
|
|
+ Potree.Utils.updateVisible(this.highMapCube, 'show', false)
|
|
|
}
|
|
}
|
|
|
//缩小后继续显示cube呢还是不显示? 不显示的话,就要把cube上的复制到renderTarget上……会不会又崩溃,or没加载的显示???
|
|
//缩小后继续显示cube呢还是不显示? 不显示的话,就要把cube上的复制到renderTarget上……会不会又崩溃,or没加载的显示???
|
|
|
|
|
|
|
@@ -2722,7 +2754,12 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
if(Potree.settings.editType == 'pano'){
|
|
if(Potree.settings.editType == 'pano'){
|
|
|
Potree.settings.datasetsPanos[pointcloud.dataset_id].panos.push(pano);
|
|
Potree.settings.datasetsPanos[pointcloud.dataset_id].panos.push(pano);
|
|
|
}
|
|
}
|
|
|
- })
|
|
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ if(data.length){
|
|
|
|
|
+ this.qualityManager.updateTileClass(pointcloud.tileClass)
|
|
|
|
|
+ this.addHighMapCube()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|