|
@@ -668,6 +668,7 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
|
|
|
flyToPano(toPano) { //飞向漫游点
|
|
|
if(!toPano)return
|
|
|
+ if(typeof toPano == 'number')toPano = this.panos[toPano]
|
|
|
if(toPano instanceof Panorama){
|
|
|
toPano = {pano: toPano}
|
|
|
}
|
|
@@ -779,11 +780,13 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
/* let maxTime = this.isAtPano() ? T.panoToPanoMax : T.flyIn
|
|
|
let duration = toPano.duration == void 0 ? (T.flyMinTime+Math.min(T.flytimeDistanceMultiplier * dis, maxTime)) : toPano.duration
|
|
|
*/
|
|
|
- let maxDis = this.isAtPano() ? T.maxDistanceThreshold : T.maxDistanceThresholdFlyIn
|
|
|
+ /* let maxDis = this.isAtPano() ? T.maxDistanceThreshold : T.maxDistanceThresholdFlyIn
|
|
|
let duration = toPano.duration == void 0 ? Math.min(dis, T.maxDistanceThreshold) * T.flytimeDistanceMultiplier + T.flyMinTime : toPano.duration
|
|
|
-
|
|
|
-
|
|
|
+ */
|
|
|
|
|
|
+ let maxDis = 7
|
|
|
+ let duration = toPano.duration == void 0 ? Math.min(dis, maxDis) * T.flytimeDistanceMultiplier + T.flyMinTime : toPano.duration
|
|
|
+
|
|
|
|
|
|
|
|
|
if(toPano.useBound){
|
|
@@ -1216,55 +1219,120 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
if(!ifNeighbour && map1[pano0.id] != void 0){
|
|
|
ifNeighbour = map1[pano0.id]
|
|
|
}
|
|
|
-
|
|
|
+ let dis = pano0.position.distanceTo(pano1.position)
|
|
|
|
|
|
if(dontCompute) return ifNeighbour
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ let ifSheltered = (mainPano, subPano)=>{ //该点前方近处是否都被遮挡
|
|
|
+
|
|
|
+ /* if(mainPano.id == 9 && subPano.id == 6 || mainPano.id == 6 && subPano.id == 9 ){
|
|
|
+ console.log(1)
|
|
|
+ } */
|
|
|
|
|
|
- let getNeighbour = (mainPano, subPano, jumpStep1, simpleJudge)=>{
|
|
|
- //暂时只判断到pano,不判断到marker的方向
|
|
|
+ let vec = new THREE.Vector3().subVectors(subPano.position, mainPano.position).normalize()
|
|
|
|
|
|
+ let getDir = (angle_, upDown)=>{ //基于vec的方向 向左向右旋转
|
|
|
+ //if(upDown) vec.clone().applyAxisAngle(new THREE.Vector3(1, 0, 0), upDown);
|
|
|
+ return vec.clone().applyAxisAngle(new THREE.Vector3(0, 0, 1), angle_);
|
|
|
+
|
|
|
+ }
|
|
|
+ let minRatio = 0.5
|
|
|
+ let angles = [25,20,18,16,14,12,10,8,7,-7,-8,-10,-12,-14,-16,-18, -20,25] //水平方向角度
|
|
|
+ let wellCount = 0
|
|
|
+ for(let i=0; i<angles.length; i++){
|
|
|
+ let rad = THREE.Math.degToRad(angles[i])
|
|
|
+ let dir = getDir(rad)
|
|
|
+ let intersectPoint = viewer.images360.depthSampler.sample({dir}, mainPano, true)
|
|
|
+ if(!intersectPoint || intersectPoint.distance * Math.cos(Math.abs(rad)) /* + margin */ > dis ){//投影在vec方向的长度不超过漫游点间距
|
|
|
+ wellCount ++
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(wellCount / angles.length > minRatio){//合格个数
|
|
|
+ console.log('ifSheltered haha', 'id:', mainPano.id, subPano.id)
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ 识别一定角度范围内是否有遮挡时
|
|
|
+ 几种奇葩的情况:
|
|
|
+ 在墙的两边的但是墙是倾斜的漫游点:
|
|
|
+ A /
|
|
|
+ /
|
|
|
+ / B
|
|
|
+ 从B出发和BA成20度的射线和墙面的交点会远于A,导致识别为无遮挡。
|
|
|
+ 所以还是改为识别范围内多个深度图像素, 合格像素个数占比 至少要大于50%,因为半边墙壁是50%
|
|
|
+ 如SG-9UsbysDufBw&formal&test 的 6、9点。 而SS-GTmFBp1JN8k&formal&test的 2、3两点是人物遮挡
|
|
|
+ */
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ let getNeighbour = (mainPano, subPano, jumpStep1)=>{
|
|
|
+
|
|
|
let dirPoints = []
|
|
|
if(!jumpStep1){//跳过此步骤,因为之前算过不成功(虽然用另一个漫游点算的可能拍摄时间不同所以有概率不一样,如人走动)
|
|
|
dirPoints.push([subPano.position, mainPano.position])
|
|
|
}
|
|
|
- if(!simpleJudge){
|
|
|
+ if(dis < 20){//在远处去掉对floorPosition的判断
|
|
|
dirPoints.push([subPano.floorPosition.clone().add(new THREE.Vector3(0,0,0.1)), mainPano.position])
|
|
|
}
|
|
|
+ if(dis < 12){//为了防止楼梯拐角、杂点遮挡。 尽量只在穿墙时不可通行
|
|
|
+ dirPoints.push([subPano.position.clone().add(new THREE.Vector3(0,0,0.8)), mainPano.position])
|
|
|
+
|
|
|
+ let normal = math.getNormal2d({p1:subPano.position, p2:mainPano.position}).multiplyScalar(0.3) //左右方向
|
|
|
+
|
|
|
+ dirPoints.push([subPano.position.clone().add(new THREE.Vector3(normal.x,normal.y,0.1)), mainPano.position])
|
|
|
+ dirPoints.push([subPano.position.clone().add(new THREE.Vector3(-normal.x,-normal.y,0.1)), mainPano.position])
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
for(let i=0; i<dirPoints.length; i++){
|
|
|
let dir = new THREE.Vector3().subVectors(dirPoints[i][0], dirPoints[i][1]).normalize();
|
|
|
let intersectPoint = viewer.images360.depthSampler.sample({dir}, mainPano, true)
|
|
|
- if(!intersectPoint || intersectPoint.distance+margin > pano0.position.distanceTo(pano1.position)){
|
|
|
+ if(!intersectPoint || intersectPoint.distance+margin > dirPoints[i][0].distanceTo(dirPoints[i][1])){
|
|
|
+ if(i>2)console.log('haha',i,'id:',mainPano.id,subPano.id)
|
|
|
return true
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if(!ifNeighbour && (map0[pano1.id] == void 0 || (computeTwoDir && map1[pano0.id] == void 0))) {//主方向为空且不为邻居
|
|
|
- let simpleJudge = pano0.position.distanceToSquared(pano1.position) > 300 //在远处去掉对floorPosition的判断
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
if(pano0.depthTex || pano1.depthTex){
|
|
|
|
|
|
if(map0[pano1.id] == void 0 && pano0.depthTex){
|
|
|
- let is = getNeighbour(pano0, pano1, null, simpleJudge)
|
|
|
+ let is = getNeighbour(pano0, pano1)
|
|
|
if(is){
|
|
|
ifNeighbour = true
|
|
|
- }else if(simpleJudge){
|
|
|
+ }else if(dis>16){
|
|
|
ifNeighbour = false
|
|
|
}
|
|
|
map0[pano1.id] = !!is
|
|
|
}
|
|
|
|
|
|
if(map1[pano0.id] == void 0 && pano1.depthTex){
|
|
|
- let is = getNeighbour(pano1, pano0, !ifNeighbour, simpleJudge)
|
|
|
+ let is = getNeighbour(pano1, pano0, !ifNeighbour)
|
|
|
if(is){
|
|
|
ifNeighbour = true
|
|
|
- }else if(simpleJudge){
|
|
|
+ }else if(dis>16){
|
|
|
ifNeighbour = false
|
|
|
}
|
|
|
map1[pano0.id] = !!is
|
|
|
}
|
|
|
ifNeighbour = !!ifNeighbour
|
|
|
|
|
|
+ if(!ifNeighbour && pano0.depthTex && pano1.depthTex && dis<10){//再检查下 只要两方都没有被完全遮挡就算可通行
|
|
|
+ if(ifSheltered(pano0,pano1) && ifSheltered(pano1,pano0)){
|
|
|
+ ifNeighbour = map0[pano1.id] = map1[pano0.id] = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
//console.log('isNeighbour', pano0, pano1, ifNeighbour)
|
|
|
/* if(ifNeighbour){ //需要标记成全部true吗,不标记也能get到,但标记了更直观,不标记保留信息更多
|
|
|
map0[pano1.id] = map1[pano0.id] = true
|
|
@@ -1401,28 +1469,31 @@ export class Images360 extends THREE.EventDispatcher{
|
|
|
} );
|
|
|
} else {
|
|
|
//如果离数据集较远,转动也很难找到点云,就飞到就近点:
|
|
|
- let po = viewer.scene.pointclouds.find(e=>e.visibleNodes.some(a=>a.getLevel() > Math.ceil(e.maxLevel * 0.15) )) //虽然当点云在前方很远的地方也可能符合
|
|
|
-
|
|
|
- if(!po){//无可见点云
|
|
|
- //console.log('no visi cloud')
|
|
|
-
|
|
|
- if(!this.panos.length){//如果场景中没有漫游点,如SG-t-XPf1k9pv3Zg 点击后回到可见区域
|
|
|
- let map = new Map()
|
|
|
- let clouds = viewer.scene.pointclouds.filter(e=>e.root.geometryNode)
|
|
|
- clouds.forEach(e=>map.set(e, e.bound.distanceToPoint(this.position)))
|
|
|
- clouds.sort((a,b)=>map.get(a) - map.get(b))
|
|
|
+ if(Potree.settings.displayMode == 'showPointcloud'){
|
|
|
+ let po = viewer.scene.pointclouds.find(e=>e.visibleNodes.some(a=>a.getLevel() > Math.ceil(e.maxLevel * 0.15) )) //虽然当点云在前方很远的地方也可能符合
|
|
|
+
|
|
|
+ if(!po){//无可见点云
|
|
|
+ //console.log('no visi cloud')
|
|
|
|
|
|
- viewer.flyToDataset({focusOnPoint:true, pointcloud:clouds[0], duration:500 })//飞最近的一个点云
|
|
|
+ if(!this.panos.length){//如果场景中没有漫游点,如SG-t-XPf1k9pv3Zg 点击后回到可见区域
|
|
|
+ if(viewer.scene.pointclouds.length == 0)return
|
|
|
+ let map = new Map()
|
|
|
+ let clouds = viewer.scene.pointclouds.filter(e=>e.root.geometryNode)
|
|
|
+ clouds.forEach(e=>map.set(e, e.bound.distanceToPoint(this.position)))
|
|
|
+ clouds.sort((a,b)=>map.get(a) - map.get(b))
|
|
|
+
|
|
|
+ viewer.flyToDataset({focusOnPoint:true, pointcloud:clouds[0], duration:500 })//飞最近的一个点云
|
|
|
+ return deferred.promise();
|
|
|
+ }
|
|
|
+
|
|
|
+ this.flyToPano({
|
|
|
+ pano: this.findNearestPano(),
|
|
|
+ duration:500,
|
|
|
+ callback: deferred.resolve.bind(deferred, !0)
|
|
|
+ });
|
|
|
return deferred.promise();
|
|
|
+
|
|
|
}
|
|
|
-
|
|
|
- this.flyToPano({
|
|
|
- pano: this.findNearestPano(),
|
|
|
- duration:500,
|
|
|
- callback: deferred.resolve.bind(deferred, !0)
|
|
|
- });
|
|
|
- return deferred.promise();
|
|
|
-
|
|
|
}
|
|
|
|
|
|
this.bump(direction);
|
|
@@ -2754,7 +2825,7 @@ Images360.prototype.updateCube = (function(){//增加细分的版本,且垂直
|
|
|
height = height == void 0 ? (Math.min(skyHeight,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 r = math.linearClamp(height, minH,maxH, minR, maxR)
|
|
|
+ let r = math.linearClamp(height, [minH,maxH], [minR, maxR])
|
|
|
|
|
|
|
|
|
let getZ = (deg)=>{
|
|
@@ -2904,7 +2975,7 @@ Images360.prototype.updateCube = (function(){//增加细分的版本,且垂直
|
|
|
|
|
|
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);
|
|
|
- let r = math.linearClamp(dis2d, minDis,maxDis, maxR, minR)
|
|
|
+ let r = math.linearClamp(dis2d, [minDis,maxDis], [maxR, minR])
|
|
|
//console.log('dis2d',dis2d,'r',r)
|
|
|
|
|
|
|