|
@@ -457,7 +457,7 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
},
|
|
|
set: function(e) {
|
|
|
if(e != currentPano){
|
|
|
- console.log('set currentPano ', e.id)
|
|
|
+ //console.log('set currentPano ', e.id)
|
|
|
currentPano && currentPano.exit()
|
|
|
e && e.enter()
|
|
|
currentPano = e
|
|
@@ -572,7 +572,7 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
var direction = this.getDirection(dir),
|
|
|
option1 = 1 === dir.y ? .4 : .75,
|
|
|
option2 = 1 === Math.abs(dir.x);
|
|
|
- return this.flyDirection(direction, option1, option2)
|
|
|
+ return this.flyDirection(direction, option1, option2, true)
|
|
|
}
|
|
|
getDirection(e) {
|
|
|
if(!e){
|
|
@@ -670,7 +670,7 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
this.cancelFlyToPano()
|
|
|
this.updateClosestPano(this.closestPano,false) //飞行结束后取消点击漫游点时得到的closestPano
|
|
|
}else{
|
|
|
- console.log('makeit fail')
|
|
|
+ /* console.log('makeit fail') */
|
|
|
}
|
|
|
|
|
|
this.dispatchEvent({type:'flyToPanoDone', makeIt})
|
|
@@ -707,14 +707,14 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
this.nextPano = pano
|
|
|
this.latestToPano = toPano
|
|
|
//this.flying = true //防止新的请求
|
|
|
- Potree.Log('flyToPano:'+pano.id + ' , duration:'+toPano.duration, null, 12)
|
|
|
+ /* Potree.Log('flyToPano:'+pano.id + ' , duration:'+toPano.duration, null, 12) */
|
|
|
|
|
|
|
|
|
{//不飞的话是否不要执行这段?
|
|
|
|
|
|
let wait = (e)=> {
|
|
|
if(e.pano && this.latestToPano && e.pano != this.latestToPano.pano)return//loadedDepthImg
|
|
|
- if(this.latestToPano != toPano)return Potree.Log('已经取消')//如果取消了
|
|
|
+ if(this.latestToPano != toPano)return /* Potree.Log('已经取消') *///如果取消了
|
|
|
setTimeout(()=>{
|
|
|
if(this.latestToPano != toPano)return
|
|
|
this.flyToPano(toPano)
|
|
@@ -1618,9 +1618,14 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
size = size || bound.getSize(new THREE.Vector3)
|
|
|
let center = bound.getCenter(new THREE.Vector3)
|
|
|
size.max(new THREE.Vector3(HighMapCubeWidth,HighMapCubeWidth,HighMapCubeWidth))
|
|
|
- this.cube.geometry = new THREE.BoxBufferGeometry(1,1,1,1)
|
|
|
+ this.cube.geometry = new THREE.BoxBufferGeometry(1,1,1,1)
|
|
|
this.cube.scale.copy(size)
|
|
|
this.cube.position.copy(center)
|
|
|
+ if(Potree.settings.testCube){
|
|
|
+ this.cubeTest.geometry = this.cube.geometry
|
|
|
+ this.cubeTest.scale.copy(size)
|
|
|
+ this.cubeTest.position.copy(center)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1634,18 +1639,27 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
this.cube.geometry.dispose();
|
|
|
|
|
|
if(pano1){//过渡
|
|
|
+ let dontAddSides
|
|
|
+ let dis = pano0.position.distanceTo(pano1.position)
|
|
|
|
|
|
- if(pano0.pointcloud != pano1.pointcloud){ //距离太远的数据集,过渡会畸变。所以扩大skybox
|
|
|
- let dis = pano0.position.distanceTo(pano1.position)
|
|
|
- if(dis > 50){
|
|
|
- let bound = getPanoBound(pano0).union(getPanoBound(pano1))
|
|
|
- let size = bound.getSize(new THREE.Vector3)
|
|
|
- let max = Math.max(size.x, size.y, size.z)
|
|
|
- size.set(max,max,max)
|
|
|
- return useBound(bound, size)
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+ let sin = Math.abs(pano0.position.z - pano1.position.z) / dis //俯仰角的sin,随角度增大而增大 0-1
|
|
|
+ let score = (1+sin*3) * dis //score越大创建的mesh越不适合
|
|
|
+ //console.log('dis',dis, this.isNeighbour(pano0, pano1), score)
|
|
|
+
|
|
|
+ if(this.isNeighbour(pano0, pano1) ? score > 1000 : score > 100 ){
|
|
|
+ let bound = getPanoBound(pano0).union(getPanoBound(pano1))
|
|
|
+ let size = bound.getSize(new THREE.Vector3)
|
|
|
+ let max = Math.max(size.x, size.y, size.z)
|
|
|
+ size.set(max,max,max) //距离太远的数据集,过渡会畸变。所以扩大skybox,且为立方体
|
|
|
+ return useBound(bound, size)
|
|
|
+ }else if(this.isNeighbour(pano0, pano1) ? score > 200 : score > 15 ){
|
|
|
+ dontAddSides = true //pano间有阻挡时得到的side点可能使通道变窄,所以去掉。
|
|
|
}
|
|
|
-
|
|
|
+ //俯仰角增大时可能不在同一楼层,算出来的mesh不太好,所以更倾向直接使用cube,或去除side。
|
|
|
+
|
|
|
+
|
|
|
|
|
|
const half = pano0.pointcloud.hasDepthTex && pano0.pointcloud.hasDepthTex ? 6 : (browser.isMobile() ? 2 : 3) //自行输入 (点云计算的慢,还不准)
|
|
|
let count1 = 2*half//偶数个 每个pano向 外dir 个数
|
|
@@ -1668,10 +1682,11 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
let rotMat = new THREE.Matrix4().makeRotationZ(angle_)
|
|
|
return vec.clone().applyMatrix4(rotMat)
|
|
|
}
|
|
|
- let getFar = (dir, pano, origin)=>{//获取在这个方向上和墙体intersect的距离
|
|
|
+ let getFar = (dir, pano, origin, height)=>{//获取在这个方向上和墙体intersect的距离
|
|
|
//在垂直方向上分出多个方向,取一个最可能的接近真实的距离
|
|
|
- let maxH = 40, minH = 2, height = pano.ceilZ - pano.floorPosition.z, minR = 0.5, maxR = 2
|
|
|
- //let r = height (maxH - minH)* 0.14 // 高度约小,角度越小
|
|
|
+ let maxH = 40, minH = 2, minR = 0.5, maxR = 2
|
|
|
+ height = height == void 0 ? (pano.ceilZ - pano.floorPosition.z) : height
|
|
|
+ //let r = height (maxH - minH)* 0.14 // 高度越小,角度越小
|
|
|
let r = minR + ( maxR - minR) * THREE.Math.clamp((height - minH) / (maxH - minH),0,1) //THREE.Math.smoothstep(currentDis, op.nearBound, op.farBound);
|
|
|
|
|
|
let getZ = (deg)=>{
|
|
@@ -1681,8 +1696,8 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
}
|
|
|
let dirs_ = [
|
|
|
//注意:角度太大会碰到天花板或地板,越远越容易碰到, 在地下停车场就会伸展不开。 户外时需要更多向上的方向,所以上方向多一个
|
|
|
- dir.clone().setZ(getZ(30)).normalize(),
|
|
|
- dir.clone().setZ(getZ(15)).normalize(),
|
|
|
+ dir.clone().setZ(getZ(35)).normalize(),
|
|
|
+ dir.clone().setZ(getZ(20)).normalize(),
|
|
|
dir.clone().setZ(getZ(7)).normalize(),
|
|
|
dir.clone(), // 水平方向
|
|
|
dir.clone().setZ(-getZ(5)).normalize(),
|
|
@@ -1703,7 +1718,7 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
return dis
|
|
|
}
|
|
|
|
|
|
- let sideCount = []
|
|
|
+ let sideCount = [0,0]
|
|
|
|
|
|
let addPos = (pano, vec )=>{//添加这个pano这一侧向外半圆的顶点
|
|
|
//添加pano位置对应的最高点最低点:
|
|
@@ -1798,12 +1813,12 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
start+=1 //不包含start和end
|
|
|
for(let m=start;m<end;m++){
|
|
|
dirs2[m].disB = dirs2[end].dis * 0.8
|
|
|
- console.log('changeDis', m, dirs2[m].disB)
|
|
|
+ //console.log('changeDis', m, dirs2[m].disB)
|
|
|
}
|
|
|
}
|
|
|
let start = -1
|
|
|
for(let i=0;i<count1;i++){//遍历时将左边dis比之小很多且宽度较小的改大
|
|
|
- console.log(i, dirs2[i].dis)
|
|
|
+ //console.log(i, dirs2[i].dis)
|
|
|
let j = i-1
|
|
|
let ratios = 0
|
|
|
while(j>start && dirs2[i].dis / dirs2[j].dis > maxRatio1){
|
|
@@ -1857,85 +1872,90 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
return Math.tan(THREE.Math.degToRad(deg))
|
|
|
}
|
|
|
*/
|
|
|
+
|
|
|
|
|
|
- if(pano0.pointcloud.hasDepthTex && pano0.pointcloud.hasDepthTex){
|
|
|
- let panos = [pano0,pano1]
|
|
|
- let vecs = [vec.clone().negate(), vec]
|
|
|
- let axis = [[-1,1],[1,-1]]
|
|
|
- let dis2d = new THREE.Vector2().subVectors(pano0.position, pano1.position).length()//水平上的距离
|
|
|
-
|
|
|
- let maxDis = 50, minDis = 0.5, minR = 0.2, maxR = 1.2
|
|
|
- let r = maxR - ( maxR - minR) * THREE.Math.clamp((dis2d - minDis) / (maxDis - minDis),0,1) //dis2d越大,角度要越小 //THREE.Math.smoothstep(currentDis, op.nearBound, op.farBound);
|
|
|
- //console.log('dis2d',dis2d,'r',r)
|
|
|
- let angles = [35,65].map(deg=>{ //正的在左边 尽量能够平分中间这段墙体。
|
|
|
- let angle = THREE.Math.clamp(deg * r, 5, 80);
|
|
|
- //console.log('angle',angle)
|
|
|
- return THREE.Math.degToRad(angle)
|
|
|
- })
|
|
|
-
|
|
|
- //let angles = [THREE.Math.degToRad(40), THREE.Math.degToRad(70)]
|
|
|
- axis.forEach((axis_, index0)=>{
|
|
|
- let disToSides = []
|
|
|
- let accordingPano = index0 == 0 ? pano0 : pano1; //根据离该点在vec方向上的距离顺序来存顶点
|
|
|
- panos.forEach((pano,index)=>{
|
|
|
- let dirs = [getDir(axis_[index]*angles[0], vecs[index]), getDir(axis_[index]*angles[1], vecs[index])];//一侧的若干角度
|
|
|
-
|
|
|
- dirs.forEach((dir_,i)=>{
|
|
|
- let dis1 = getFar(dir_, pano);
|
|
|
+ if(!dontAddSides){
|
|
|
+ if( pano0.pointcloud.hasDepthTex && pano0.pointcloud.hasDepthTex){
|
|
|
+ let panos = [pano0,pano1]
|
|
|
+ let vecs = [vec.clone().negate(), vec]
|
|
|
+ let axis = [[-1,1],[1,-1]]
|
|
|
+ let dis2d = new THREE.Vector2().subVectors(pano0.position, pano1.position).length()//水平上的距离
|
|
|
+
|
|
|
+ let maxDis = 50, minDis = 0.5, minR = 0.2, maxR = 1.2
|
|
|
+ let r = maxR - ( maxR - minR) * THREE.Math.clamp((dis2d - minDis) / (maxDis - minDis),0,1) //dis2d越大,角度要越小 //THREE.Math.smoothstep(currentDis, op.nearBound, op.farBound);
|
|
|
+ //console.log('dis2d',dis2d,'r',r)
|
|
|
+ let angles = (browser.isMobile ? [50] : [35,65]).map(deg=>{ //正的在左边 尽量能够平分中间这段墙体。 (角度为从中心向外)
|
|
|
+ let angle = THREE.Math.clamp(deg * r, 5, 80);
|
|
|
+ //console.log('angle',angle)
|
|
|
+ return THREE.Math.degToRad(angle)
|
|
|
+ })
|
|
|
+
|
|
|
+ //let angles = [THREE.Math.degToRad(40), THREE.Math.degToRad(70)]
|
|
|
+ axis.forEach((axis_, index0)=>{
|
|
|
+ let disToSides = []
|
|
|
+ let accordingPano = index0 == 0 ? pano0 : pano1; //根据离该点在vec方向上的距离顺序来存顶点
|
|
|
+ panos.forEach((pano,index)=>{
|
|
|
+ let dirs = angles.map(angle=>getDir(axis_[index]*angle, vecs[index]))//一侧的若干角度
|
|
|
|
|
|
- let disToPano2d = dis1 * Math.cos(angles[i])
|
|
|
- if(disToPano2d<dis2d){//超过的话都到另一半pano的半圆了,不计入
|
|
|
- let disToSide = dis1 * Math.sin(angles[i])
|
|
|
-
|
|
|
- if(pano != accordingPano){
|
|
|
- disToPano2d = dis2d - disToPano2d //反一下
|
|
|
- }
|
|
|
+
|
|
|
+ //[getDir(axis_[index]*angles[0], vecs[index]), getDir(axis_[index]*angles[1], vecs[index])];
|
|
|
+
|
|
|
+ dirs.forEach((dir_,i)=>{
|
|
|
+ let dis1 = getFar(dir_, pano);
|
|
|
|
|
|
- dir_.multiplyScalar( dis1 );
|
|
|
- disToSides.push({disToSide,disToPano2d, pano, dir_})
|
|
|
+ let disToPano2d = dis1 * Math.cos(angles[i])
|
|
|
+ if(disToPano2d<dis2d){//超过的话都到另一半pano的半圆了,不计入
|
|
|
+ let disToSide = dis1 * Math.sin(angles[i])
|
|
|
+
|
|
|
+ if(pano != accordingPano){
|
|
|
+ disToPano2d = dis2d - disToPano2d //反一下
|
|
|
+ }
|
|
|
+
|
|
|
+ dir_.multiplyScalar( dis1 );
|
|
|
+ disToSides.push({disToSide,disToPano2d, pano, dir_})
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ if(disToSides.length){
|
|
|
+ //disToSides.sort((a,b)=>{return b-a});//从大到小
|
|
|
+ //由距离accordingPano的近到远:
|
|
|
+ disToSides.sort((a,b)=>{return a.disToPano2d-b.disToPano2d})
|
|
|
+
|
|
|
+ //console.log('disToSides', index0, disToSides)
|
|
|
+ if(disToSides.length == 1 && disToSides[0].disToSide < 0.5){
|
|
|
+ disToSides = [] //如果太近直接去除
|
|
|
}
|
|
|
- })
|
|
|
- })
|
|
|
-
|
|
|
- if(disToSides.length){
|
|
|
- //disToSides.sort((a,b)=>{return b-a});//从大到小
|
|
|
- //由距离accordingPano的近到远:
|
|
|
- disToSides.sort((a,b)=>{return a.disToPano2d-b.disToPano2d})
|
|
|
-
|
|
|
- console.log('disToSides', index0, disToSides)
|
|
|
- if(disToSides.length == 1 && disToSides[0].disToSide < 0.5){
|
|
|
- disToSides = [] //如果太近直接去除
|
|
|
- }
|
|
|
-
|
|
|
- disToSides.forEach(e=>{//求z
|
|
|
- let ratio = e.disToPano2d / dis2d
|
|
|
- let r = accordingPano == pano0 ? (1-ratio) : ratio
|
|
|
- let sideMaxZ_ = pano0.ceilZ * r + pano1.ceilZ * (1-r);
|
|
|
- let sideMinZ_ = pano0.floorPosition.z * r + pano1.floorPosition.z * (1-r);
|
|
|
- [sideMaxZ_,sideMinZ_].forEach(z=>{
|
|
|
- posArr.push(e.pano.position.clone().setZ(z).add(e.dir_)) //是直接使用最长dis的那个intersect点好还是mid
|
|
|
- })
|
|
|
+
|
|
|
+ disToSides.forEach(e=>{//求z
|
|
|
+ let ratio = e.disToPano2d / dis2d
|
|
|
+ let r = accordingPano == pano0 ? (1-ratio) : ratio
|
|
|
+ let sideMaxZ_ = pano0.ceilZ * r + pano1.ceilZ * (1-r);
|
|
|
+ let sideMinZ_ = pano0.floorPosition.z * r + pano1.floorPosition.z * (1-r);
|
|
|
+ [sideMaxZ_,sideMinZ_].forEach(z=>{
|
|
|
+ posArr.push(e.pano.position.clone().setZ(z).add(e.dir_)) //是直接使用最长dis的那个intersect点好还是mid
|
|
|
+ })
|
|
|
+
|
|
|
+ })
|
|
|
|
|
|
- })
|
|
|
-
|
|
|
- }
|
|
|
- sideCount[index0] = disToSides.length //记录侧边个数
|
|
|
- })
|
|
|
-
|
|
|
- }else{
|
|
|
- //这段针对点云时,仅测试才会执行到
|
|
|
- sideCount = [1,1]
|
|
|
- let sideDirs = [getDir(Math.PI/2, vec), getDir(-Math.PI/2, vec)]
|
|
|
- sideDirs.forEach((dir_ ,index)=>{
|
|
|
- let dis = getFar(dir_, null, mid); //直接从中点求两侧的距离
|
|
|
- dir_.multiplyScalar( /* Math.max( */dis/* , sideDis[index]) */ );
|
|
|
- [midMaxZ,midMinZ].forEach(z=>{
|
|
|
- posArr.push(mid.clone().setZ(z).add(dir_))
|
|
|
+ }
|
|
|
+ sideCount[index0] = disToSides.length //记录侧边个数
|
|
|
})
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+ }else{
|
|
|
+ //这段针对点云时,仅测试才会执行到
|
|
|
+ sideCount = [1,1]
|
|
|
+ let sideDirs = [getDir(Math.PI/2, vec), getDir(-Math.PI/2, vec)]
|
|
|
+ sideDirs.forEach((dir_ ,index)=>{
|
|
|
+ let dis = getFar(dir_, null, mid, midMaxZ-midMinZ); //直接从中点求两侧的距离
|
|
|
+ dir_.multiplyScalar( /* Math.max( */dis/* , sideDis[index]) */ );
|
|
|
+ [midMaxZ,midMinZ].forEach(z=>{
|
|
|
+ posArr.push(mid.clone().setZ(z).add(dir_))
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
//中心:
|
|
|
[midMaxZ,midMinZ].forEach(z=>{
|
|
|
posArr.push(mid.clone().setZ(z))
|
|
@@ -2032,6 +2052,8 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
|
|
|
if(Potree.settings.testCube){
|
|
|
this.cubeTest.geometry = geo
|
|
|
+ this.cubeTest.scale.set(1,1,1);
|
|
|
+ this.cubeTest.position.set(0,0,0)
|
|
|
}
|
|
|
|
|
|
}else{
|
|
@@ -2040,21 +2062,19 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ 关于卡顿:
|
|
|
+ 即使使用cube,若scale设置为只容纳两个pano,也会卡顿。但也是有的卡有的不卡。
|
|
|
+ 若按照原先的复杂geo,一般在平直的街道上行走流畅,经过拐弯或者复杂区域较卡。减小geo复杂度没有什么作用。
|
|
|
|
|
|
-
|
|
|
-
|
|
|
+ */
|
|
|
/*
|
|
|
注: 修改skybox,若不准的话,会遮住其他mesh,比如marker。尤其在没有深度贴图时。
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
- /* updateCube(params){
|
|
|
- let size = params.boundSize
|
|
|
- this.cube.scale.set(Math.max(size.x, HighMapCubeWidth), Math.max(size.y, HighMapCubeWidth), Math.max(size.z, HighMapCubeWidth) )
|
|
|
- this.cube.position.copy(params.center)
|
|
|
-
|
|
|
- } */
|
|
|
+
|
|
|
|
|
|
bump(direction) {//撞墙弹回效果
|
|
|
if (!this.bumping && !this.latestToPano) {
|
|
@@ -2129,10 +2149,10 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
}
|
|
|
|
|
|
|
|
|
- flyDirection(direction, option1, option2) {
|
|
|
+ flyDirection(direction, option1, option2, byKey) {
|
|
|
var deferred = $.Deferred();
|
|
|
//this.history.invalidate();
|
|
|
- var panoSet = this.closestPanoInDirection(direction, option1, option2);
|
|
|
+ var panoSet = this.closestPanoInDirection(direction, option1, option2, byKey);
|
|
|
if (panoSet) {
|
|
|
this.flyToPano({
|
|
|
pano: panoSet,
|
|
@@ -2145,10 +2165,10 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
|
|
|
return deferred.promise();
|
|
|
}
|
|
|
- closestPanoInDirection(direction, option1, option2) {
|
|
|
- return this.rankedPanoInDirection(0, direction, option1, option2)
|
|
|
+ closestPanoInDirection(direction, option1, option2, byKey) {
|
|
|
+ return this.rankedPanoInDirection(0, direction, option1, option2, byKey)
|
|
|
}
|
|
|
- rankedPanoInDirection(t, direction, option1, option2){
|
|
|
+ rankedPanoInDirection(t, direction, option1, option2, byKey){
|
|
|
//此direction为mouseDirection,是否需要加上相机角度的权重
|
|
|
var panoSet = {
|
|
|
pano: null,
|
|
@@ -2215,7 +2235,7 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
}
|
|
|
} */
|
|
|
];
|
|
|
- if(viewer.inputHandler.intersect && this.currentPano ){//方便上下楼, 考虑panos之间的角度差
|
|
|
+ if(!byKey && viewer.inputHandler.intersect && this.currentPano ){//方便上下楼, 考虑panos之间的角度差
|
|
|
let pos1 = this.currentPano.floorPosition
|
|
|
let vec1 = new THREE.Vector3().subVectors(viewer.inputHandler.intersect.location, pos1 ).normalize()//应该只有atPano时才会执行到这吧?
|
|
|
list.push( function(pano) {
|