|
@@ -13,28 +13,29 @@ import QualityManager from './tile/QualityManager'
|
|
import TileDownloader from './tile/TileDownloader'
|
|
import TileDownloader from './tile/TileDownloader'
|
|
import PanoRenderer from './tile/PanoRenderer'
|
|
import PanoRenderer from './tile/PanoRenderer'
|
|
import TilePrioritizer from './tile/TilePrioritizer'
|
|
import TilePrioritizer from './tile/TilePrioritizer'
|
|
-import { PanoSizeClass,Vectors} from '../../defines'
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-//import Axis from '../../viewer/Axis'
|
|
|
|
|
|
+import { PanoSizeClass,Vectors,GLCubeFaces, PanoramaEvents} from '../../defines'
|
|
|
|
+
|
|
|
|
+import {transitions, easing, lerp} from "../../utils/transitions.js";
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+var rot90 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,0,1), Math.PI/2 ); //使用的是刚好适合全景图的,给cube贴图需要转90°
|
|
|
|
+
|
|
let raycaster = new THREE.Raycaster();
|
|
let raycaster = new THREE.Raycaster();
|
|
//let currentlyHovered = null;
|
|
//let currentlyHovered = null;
|
|
|
|
|
|
-var texLoader = new THREE.TextureLoader()
|
|
|
|
|
|
+let texLoader = new THREE.TextureLoader()
|
|
let cm = new ModelTextureMaterial()
|
|
let cm = new ModelTextureMaterial()
|
|
|
|
+let sm = new THREE.MeshBasicMaterial({side: THREE.BackSide});
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+let tileArr = []
|
|
let previousView = {
|
|
let previousView = {
|
|
controls: null,
|
|
controls: null,
|
|
position: null,
|
|
position: null,
|
|
target: null,
|
|
target: null,
|
|
};
|
|
};
|
|
-let sm = new THREE.MeshBasicMaterial({side: THREE.BackSide});
|
|
|
|
-var tileArr = []
|
|
|
|
|
|
|
|
-/* let sgHigh = new THREE.SphereGeometry(1, 128, 128);
|
|
|
|
- */
|
|
|
|
|
|
+const HighMapCubeWidth = 1
|
|
|
|
+
|
|
export class Images360 extends EventDispatcher{
|
|
export class Images360 extends EventDispatcher{
|
|
|
|
|
|
constructor(viewer, params){
|
|
constructor(viewer, params){
|
|
@@ -52,12 +53,13 @@ export class Images360 extends EventDispatcher{
|
|
|
|
|
|
|
|
|
|
//add:
|
|
//add:
|
|
- let size = params.boundSize
|
|
|
|
- this.cube = new THREE.Mesh(new THREE.BoxBufferGeometry( size.x, size.y, size.z ), cm);
|
|
|
|
|
|
+ let size = params.boundSize
|
|
|
|
+
|
|
|
|
+ this.cube = new THREE.Mesh(new THREE.BoxBufferGeometry( Math.max(size.x, HighMapCubeWidth), Math.max(size.y, HighMapCubeWidth), Math.max(size.z, HighMapCubeWidth) ), cm);
|
|
this.cube.position.copy(params.center)
|
|
this.cube.position.copy(params.center)
|
|
this.cube.visible = false;
|
|
this.cube.visible = false;
|
|
this.cube.layers.set(Potree.config.renderLayers.skybox)
|
|
this.cube.layers.set(Potree.config.renderLayers.skybox)
|
|
- this.cube.name = 'skybox'
|
|
|
|
|
|
+ this.cube.name = 'skyboxCube'
|
|
viewer.scene.scene.add(this.cube)
|
|
viewer.scene.scene.add(this.cube)
|
|
|
|
|
|
|
|
|
|
@@ -66,8 +68,8 @@ export class Images360 extends EventDispatcher{
|
|
|
|
|
|
this.currentPano = null;
|
|
this.currentPano = null;
|
|
this.mouseLastMoveTime = Date.now()
|
|
this.mouseLastMoveTime = Date.now()
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+ this.scrollZoomSpeed = 0.06
|
|
|
|
+ this.zoomLevel = 1
|
|
|
|
|
|
this.tileDownloader = new TileDownloader;
|
|
this.tileDownloader = new TileDownloader;
|
|
this.qualityManager = new QualityManager
|
|
this.qualityManager = new QualityManager
|
|
@@ -79,29 +81,62 @@ export class Images360 extends EventDispatcher{
|
|
this.ultraHighPanoSize = this.qualityManager.getPanoSize(PanoSizeClass.ULTRAHIGH);
|
|
this.ultraHighPanoSize = this.qualityManager.getPanoSize(PanoSizeClass.ULTRAHIGH);
|
|
this.tileDownloader.processPriorityQueue = !1;
|
|
this.tileDownloader.processPriorityQueue = !1;
|
|
this.tileDownloader.tilePrioritizer = new TilePrioritizer(this.qualityManager, this.basePanoSize, this.standardPanoSize, this.highPanoSize, this.ultraHighPanoSize);
|
|
this.tileDownloader.tilePrioritizer = new TilePrioritizer(this.qualityManager, this.basePanoSize, this.standardPanoSize, this.highPanoSize, this.ultraHighPanoSize);
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ {//高分辨率cube 放大
|
|
|
|
+ this.addHighMapCube()
|
|
|
|
+ viewer.on(PanoramaEvents.Enter,(e)=>{
|
|
|
|
+ this.setHighMap(e.newPano)
|
|
|
|
+ })
|
|
|
|
+ viewer.on('panoSetZoom',(pano, zoomed)=>{
|
|
|
|
+ if(Potree.settings.displayMode == 'showPanos'){
|
|
|
|
+ zoomed ? this.showHighMap() : this.hideHighMap() //add
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ let scroll = (e)=>{
|
|
|
|
+ let zoom;
|
|
|
|
+ if(Potree.settings.displayMode == 'showPanos' && Potree.settings.zoom.enabled){
|
|
|
|
+ if(e.delta > 0){
|
|
|
|
+ zoom = 1 + this.scrollZoomSpeed
|
|
|
|
+ }else{
|
|
|
|
+ zoom = 1 - this.scrollZoomSpeed
|
|
|
|
+ }
|
|
|
|
+ e.delta != 0 && this.zoomBy(zoom)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ viewer.addEventListener('global_mousewheel', scroll);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
viewer.addEventListener('global_click'/* "global_drop" */, (e) => {//不用"mouseup" 是因为 mouseup有drag object时也会触发
|
|
viewer.addEventListener('global_click'/* "global_drop" */, (e) => {//不用"mouseup" 是因为 mouseup有drag object时也会触发
|
|
if(Potree.settings.unableNavigate || this.flying || e.button != THREE.MOUSE.LEFT )return //
|
|
if(Potree.settings.unableNavigate || this.flying || e.button != THREE.MOUSE.LEFT )return //
|
|
|
|
|
|
/* if(currentlyHovered && currentlyHovered.pano){
|
|
/* if(currentlyHovered && currentlyHovered.pano){
|
|
this.focusPano(currentlyHovered.pano);
|
|
this.focusPano(currentlyHovered.pano);
|
|
}else{//add */
|
|
}else{//add */
|
|
- if(!Potree.settings.dblToFocusPoint || this.currentPano){//双击不会focus点云 或者 已经focusPano了
|
|
|
|
|
|
+ if(!Potree.settings.dblToFocusPoint && this.currentPano){//双击不会focus点云 或者 已经focusPano了
|
|
this.flyToPanoClosestToMouse()
|
|
this.flyToPanoClosestToMouse()
|
|
}
|
|
}
|
|
-
|
|
|
|
-
|
|
|
|
//}
|
|
//}
|
|
})
|
|
})
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
viewer.addEventListener("global_mousemove", (e) => {
|
|
viewer.addEventListener("global_mousemove", (e) => {
|
|
if(!Potree.settings.unableNavigate && Potree.settings.ifShowMarker && e.hoverViewport == viewer.mainViewport){//如果不显示marker,就在点击时再更新
|
|
if(!Potree.settings.unableNavigate && Potree.settings.ifShowMarker && e.hoverViewport == viewer.mainViewport){//如果不显示marker,就在点击时再更新
|
|
this.updateClosestPano(e.intersectPoint)
|
|
this.updateClosestPano(e.intersectPoint)
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
|
|
+
|
|
if(!Potree.settings.isOfficial){
|
|
if(!Potree.settings.isOfficial){
|
|
this.domRoot = viewer.renderer.domElement.parentElement;
|
|
this.domRoot = viewer.renderer.domElement.parentElement;
|
|
let elUnfocus = $("<input type='button' value='unfocus'></input>");
|
|
let elUnfocus = $("<input type='button' value='unfocus'></input>");
|
|
@@ -172,7 +207,7 @@ export class Images360 extends EventDispatcher{
|
|
if(mode != displayMode){
|
|
if(mode != displayMode){
|
|
let config = Potree.config.displayMode[mode]
|
|
let config = Potree.config.displayMode[mode]
|
|
let config2
|
|
let config2
|
|
-
|
|
|
|
|
|
+ let camera = viewer.scene.getActiveCamera()
|
|
|
|
|
|
if(this.isAtPano() ){//this.currentPano
|
|
if(this.isAtPano() ){//this.currentPano
|
|
if(this.flying)config2 = config.transition
|
|
if(this.flying)config2 = config.transition
|
|
@@ -231,9 +266,15 @@ export class Images360 extends EventDispatcher{
|
|
}
|
|
}
|
|
|
|
|
|
this.cube.visible = config.atPano.showSkybox
|
|
this.cube.visible = config.atPano.showSkybox
|
|
- this.cube.visible && this.cube.material.setProjectedPanos(this.currentPano, this.currentPano, 1)
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+ if(this.cube.visible){
|
|
|
|
+ this.cube.material.setProjectedPanos(this.currentPano, this.currentPano, 1)
|
|
|
|
+ }else{
|
|
|
|
+ this.smoothZoomTo(1)
|
|
|
|
+ this.resetHighMap()
|
|
|
|
+ this.hideHighMap()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
|
|
/* viewer.dispatchEvent({
|
|
/* viewer.dispatchEvent({
|
|
type: "enableChangePos",
|
|
type: "enableChangePos",
|
|
@@ -242,6 +283,15 @@ export class Images360 extends EventDispatcher{
|
|
}) */
|
|
}) */
|
|
viewer.mainViewport.unableChangePos = !config.canLeavePano
|
|
viewer.mainViewport.unableChangePos = !config.canLeavePano
|
|
|
|
|
|
|
|
+ if(mode == 'showPanos'){
|
|
|
|
+ camera.far = viewer.farWhenShowPano
|
|
|
|
+ }else if(Potree.settings.limitFar){
|
|
|
|
+ camera.far = Potree.settings.cameraFar;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ camera.updateProjectionMatrix()
|
|
|
|
+
|
|
|
|
+
|
|
displayMode = mode
|
|
displayMode = mode
|
|
if(this.elDisplayModel){
|
|
if(this.elDisplayModel){
|
|
this.elDisplayModel.value = mode == 'showPointCloud' ? ">>全景" : '>>点云'
|
|
this.elDisplayModel.value = mode == 'showPointCloud' ? ">>全景" : '>>点云'
|
|
@@ -383,7 +433,7 @@ export class Images360 extends EventDispatcher{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- isAtPano(){//
|
|
|
|
|
|
+ isAtPano(){//是否在某个漫游点上
|
|
return this.currentPano && viewer.scene.view.position.equals(this.currentPano.position)
|
|
return this.currentPano && viewer.scene.view.position.equals(this.currentPano.position)
|
|
}
|
|
}
|
|
|
|
|
|
@@ -391,12 +441,26 @@ export class Images360 extends EventDispatcher{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+ updateProjectedPanos(){//更新材质贴图
|
|
|
|
+ //console.warn('updateProjectedPanos')
|
|
|
|
+ this.projectedPano0 && this.projectedPano1 && this.setProjectedPanos({pano0:this.projectedPano0, pano1:this.projectedPano1})
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
|
|
|
|
+ setProjectedPanos(o={}){//设置cube和点云的材质贴图
|
|
|
|
+ this.cube.material.setProjectedPanos(o.pano0, o.pano1, o.progress)
|
|
|
|
+ if(o.ifPointcloud){
|
|
|
|
+ viewer.scene.pointclouds.forEach(e=>{
|
|
|
|
+ e.material.setProjectedPanos(o.pano0, o.pano1, o.progress, o.easeInOutRatio)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //console.warn('setProjectedPanos ', o.pano0.id , o.pano1.id)
|
|
|
|
+ this.projectedPano0 = o.pano0
|
|
|
|
+ this.projectedPano1 = o.pano1
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -434,7 +498,7 @@ export class Images360 extends EventDispatcher{
|
|
|
|
|
|
var duration = toPano.duration || 300+Math.min(Potree.config.transitionsTime.flySpeed * this.position.distanceTo(pano.position), Potree.config.transitionsTime.panoToPano )
|
|
var duration = toPano.duration || 300+Math.min(Potree.config.transitionsTime.flySpeed * this.position.distanceTo(pano.position), Potree.config.transitionsTime.panoToPano )
|
|
|
|
|
|
- //console.log("flyto "+pano.id + ' duration: ' + duration )
|
|
|
|
|
|
+ //console.warn("flyto "+pano.id + ' duration: ' + duration )
|
|
|
|
|
|
this.nextPano = pano
|
|
this.nextPano = pano
|
|
//不飞的话是否不要执行这段?
|
|
//不飞的话是否不要执行这段?
|
|
@@ -449,17 +513,14 @@ export class Images360 extends EventDispatcher{
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- //this.load(pano).then( () => {
|
|
|
|
- this.cube.visible = config.atPano.showSkybox
|
|
|
|
- this.cube.visible && this.cube.material.setProjectedPanos(this.currentPano, pano, 0)
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+ this.cube.visible = config.atPano.showSkybox
|
|
|
|
+ /* this.cube.visible && this.cube.material.setProjectedPanos(this.currentPano, pano, 0)
|
|
|
|
+
|
|
|
|
+ if(config.transition.showPoint){
|
|
viewer.scene.pointclouds.forEach(e=>{
|
|
viewer.scene.pointclouds.forEach(e=>{
|
|
- viewer.updateVisible(e, 'displayMode',config.transition.showPoint)
|
|
|
|
- })
|
|
|
|
-
|
|
|
|
|
|
+ viewer.updateVisible(e, 'displayMode', true)
|
|
|
|
+ })
|
|
|
|
|
|
if(config.transition.pointUsePanoTex){
|
|
if(config.transition.pointUsePanoTex){
|
|
let easeInOutRatio = pointcloudVisi ? 0.3 : 0
|
|
let easeInOutRatio = pointcloudVisi ? 0.3 : 0
|
|
@@ -467,43 +528,79 @@ export class Images360 extends EventDispatcher{
|
|
e.material.setProjectedPanos(this.currentPano, pano, 0, easeInOutRatio)
|
|
e.material.setProjectedPanos(this.currentPano, pano, 0, easeInOutRatio)
|
|
})
|
|
})
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
|
|
- const endPosition = pano.position.clone()
|
|
|
|
- this.flying = true
|
|
|
|
- viewer.scene.view.setView(endPosition, target ,duration, ()=>{//done
|
|
|
|
-
|
|
|
|
- if(!config.atPano.pointUsePanoTex){
|
|
|
|
- viewer.scene.pointclouds.forEach(e=>{
|
|
|
|
- e.material.stopProjectedPanos()
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
- //this.currentPano.exit()
|
|
|
|
- //pano.enter()
|
|
|
|
- this.currentPano = pano;
|
|
|
|
- this.flying = false
|
|
|
|
- this.nextPano = null;
|
|
|
|
- viewer.scene.pointclouds.forEach(e=>{
|
|
|
|
- viewer.updateVisible(e, 'displayMode',pointcloudVisi)
|
|
|
|
- })
|
|
|
|
- done(true);
|
|
|
|
- },(progress)=>{//onUpdate
|
|
|
|
- this.cube.material.uniforms.progress.value = progress
|
|
|
|
-
|
|
|
|
|
|
+ } */
|
|
|
|
+ if(config.transition.showPoint){
|
|
|
|
+ viewer.scene.pointclouds.forEach(e=>{
|
|
|
|
+ viewer.updateVisible(e, 'displayMode', true)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ this.setProjectedPanos({
|
|
|
|
+ progress:0,
|
|
|
|
+ ifSkybox: this.cube.visible,
|
|
|
|
+ ifPointcloud : config.transition.pointUsePanoTex,
|
|
|
|
+ easeInOutRatio : pointcloudVisi ? 0.3 : 0,
|
|
|
|
+ pano0:this.currentPano,
|
|
|
|
+ pano1:pano
|
|
|
|
+ })
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ const endPosition = pano.position.clone()
|
|
|
|
+ this.flying = true
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ this.beforeFlyToPano(pano,duration)
|
|
|
|
+
|
|
|
|
+ viewer.scene.view.setView(endPosition, target ,duration, ()=>{//done
|
|
|
|
+
|
|
|
|
+ if(!config.atPano.pointUsePanoTex){
|
|
viewer.scene.pointclouds.forEach(e=>{
|
|
viewer.scene.pointclouds.forEach(e=>{
|
|
- e.material.uniforms.progress.value = progress
|
|
|
|
|
|
+ e.material.stopProjectedPanos()
|
|
})
|
|
})
|
|
- }, easeName )
|
|
|
|
-
|
|
|
|
- {
|
|
|
|
- toPano.duration = duration
|
|
|
|
- toPano.easeName = easeName
|
|
|
|
- this.emit('flyToPano', toPano)
|
|
|
|
}
|
|
}
|
|
- //})
|
|
|
|
|
|
+ //this.currentPano.exit()
|
|
|
|
+ //pano.enter()
|
|
|
|
+ this.currentPano = pano;
|
|
|
|
+ this.flying = false
|
|
|
|
+ this.nextPano = null;
|
|
|
|
+ viewer.scene.pointclouds.forEach(e=>{
|
|
|
|
+ viewer.updateVisible(e, 'displayMode',pointcloudVisi)
|
|
|
|
+ })
|
|
|
|
+ done(true);
|
|
|
|
+ },(progress)=>{//onUpdate
|
|
|
|
+ this.cube.material.uniforms.progress.value = progress
|
|
|
|
+
|
|
|
|
+ viewer.scene.pointclouds.forEach(e=>{
|
|
|
|
+ e.material.uniforms.progress.value = progress
|
|
|
|
+ })
|
|
|
|
+ }, easeName )
|
|
|
|
+
|
|
|
|
+ {
|
|
|
|
+ toPano.duration = duration
|
|
|
|
+ toPano.easeName = easeName
|
|
|
|
+ this.emit('flyToPano', toPano)
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
|
|
+ beforeFlyToPano(pano, duration){
|
|
|
|
+ if(Potree.settings.displayMode == 'showPanos'){
|
|
|
|
+ this.resetHighMap()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.smoothZoomTo(1, duration / 2);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
focusPano(toPano ){
|
|
focusPano(toPano ){
|
|
@@ -535,7 +632,7 @@ export class Images360 extends EventDispatcher{
|
|
|
|
|
|
this.selectingEnabled = false;
|
|
this.selectingEnabled = false;
|
|
|
|
|
|
- //console.log("flyto "+pano.file.split('/').pop() )
|
|
|
|
|
|
+ //console.warn("flyto "+pano.file.split('/').pop() )
|
|
var dur = toPano.duration == void 0 ? 700 : toPano.duration
|
|
var dur = toPano.duration == void 0 ? 700 : toPano.duration
|
|
|
|
|
|
if(config.atPano.showSkybox){
|
|
if(config.atPano.showSkybox){
|
|
@@ -548,22 +645,25 @@ export class Images360 extends EventDispatcher{
|
|
return ;
|
|
return ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- //this.load(pano).then( () => {
|
|
|
|
-
|
|
|
|
- //this.panos.forEach(e=>e.marker.material.depthTest = false)
|
|
|
|
-
|
|
|
|
|
|
+
|
|
|
|
|
|
|
|
|
|
- this.cube.visible = config.atPano.showSkybox
|
|
|
|
- this.cube.visible && this.cube.material.setProjectedPanos(pano, pano, 0)
|
|
|
|
-
|
|
|
|
- if(config.atPano.pointUsePanoTex){//false
|
|
|
|
- viewer.scene.pointclouds.forEach(e=>{
|
|
|
|
- e.material.setProjectedPanos(pano, pano, 0)
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
|
|
+ this.cube.visible = config.atPano.showSkybox
|
|
|
|
+ /* this.cube.visible && this.cube.material.setProjectedPanos(pano, pano, 0)
|
|
|
|
+
|
|
|
|
+ if(config.atPano.pointUsePanoTex){//false
|
|
|
|
+ viewer.scene.pointclouds.forEach(e=>{
|
|
|
|
+ e.material.setProjectedPanos(pano, pano, 0)
|
|
|
|
+ })
|
|
|
|
+ } */
|
|
|
|
|
|
- //});
|
|
|
|
|
|
+ this.setProjectedPanos({
|
|
|
|
+ progress:0,
|
|
|
|
+ ifSkybox: this.cube.visible,
|
|
|
|
+ ifPointcloud : config.atPano.pointUsePanoTex,
|
|
|
|
+ pano0:pano,
|
|
|
|
+ pano1:pano
|
|
|
|
+ })
|
|
|
|
|
|
|
|
|
|
let newCamPos = pano.position.clone()
|
|
let newCamPos = pano.position.clone()
|
|
@@ -633,55 +733,29 @@ export class Images360 extends EventDispatcher{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
|
|
-
|
|
|
|
- /* bump(direction) {//撞墙弹回效果
|
|
|
|
- if (!this.flying) {
|
|
|
|
- var t, i, n, r = settings.transition,
|
|
|
|
- o = (r.flytimeMaxDistanceThreshold * r.flytimeDistanceMultiplier + r.flyTime) / 10,
|
|
|
|
- a = this.camera.getWorldDirection().dot(direction),
|
|
|
|
- s = Math.abs(a) > .5;
|
|
|
|
- if (s)
|
|
|
|
- t = function() {
|
|
|
|
- transitions.start(lerp.property(this.cameraControls.cameras[ViewMode.PANORAMA], "zoom", a > 0 ? 1.04 : .96), o, i, 0, easing.easeInOutSine, "bumpZStart")
|
|
|
|
- }
|
|
|
|
- .bind(this),
|
|
|
|
- i = function() {
|
|
|
|
- transitions.start(lerp.property(this.cameraControls.cameras[ViewMode.PANORAMA], "zoom", 1), 3 * o, n, 0, easing.easeInOutSine, "bumpZRelax")
|
|
|
|
- }
|
|
|
|
- .bind(this);
|
|
|
|
- else {
|
|
|
|
- var l = this.camera.position.clone(),
|
|
|
|
- c = direction.clone();
|
|
|
|
- this.raycaster.set(l, c);
|
|
|
|
- var h = this.model.floors.reduce(function(e, t) {
|
|
|
|
- return e.concat(t.collider.children)
|
|
|
|
- }, []),
|
|
|
|
- d = this.raycaster.intersectObjects(h),
|
|
|
|
- p = d.length > 0 ? d[0].distance / 25 : .04,
|
|
|
|
- g = l.clone().add(c.multiplyScalar(p));
|
|
|
|
- t = function() {
|
|
|
|
- transitions.start(lerp.vector(this.cameraControls.cameras[ViewMode.PANORAMA].position, g), o, i, 0, easing.easeInOutSine, "bumpTStart")
|
|
|
|
- }
|
|
|
|
- .bind(this),
|
|
|
|
- i = function() {
|
|
|
|
- transitions.start(lerp.vector(this.cameraControls.cameras[ViewMode.PANORAMA].position, l), 5 * o, n, 0, easing.easeInOutSine, "bumpTRelax")
|
|
|
|
- }
|
|
|
|
- .bind(this)
|
|
|
|
- }
|
|
|
|
|
|
+ bump(direction) {//撞墙弹回效果
|
|
|
|
+ if (!this.flying) {
|
|
|
|
+ this.flying = !0
|
|
|
|
|
|
|
|
+ let distance = Potree.settings.displayMode == 'showPanos' ? 0.4 : 0.2;//感觉点云模式比全景模式更明显,所以降低
|
|
|
|
+ let currentPos = this.position.clone()
|
|
|
|
+ let endPosition = new THREE.Vector3().addVectors(this.position, direction.clone().multiplyScalar(distance))
|
|
|
|
|
|
- n = (){
|
|
|
|
- this.mode == "panorama" && (this.flying = !1) //改
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- this.flying = !0,
|
|
|
|
- t()
|
|
|
|
|
|
+ let duration = 150
|
|
|
|
+ viewer.scene.view.setView(endPosition, null , duration, ()=>{//done
|
|
|
|
+ viewer.scene.view.setView(currentPos, null , duration*5, ()=>{//done
|
|
|
|
+ this.flying = !1
|
|
|
|
+ },null,'easeInOutSine')
|
|
|
|
+
|
|
|
|
+ } ,(progress)=>{//onUpdate
|
|
|
|
+
|
|
|
|
+ }, 'easeInOutSine' )
|
|
}
|
|
}
|
|
- };
|
|
|
|
- */
|
|
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+ //备注:将4dkk中的‘前后方向变化fov、左右方向移动镜头’ 都改为移动镜头。 因为这里无法判断左右离壁距离。
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -735,7 +809,7 @@ export class Images360 extends EventDispatcher{
|
|
callback: deferred.resolve.bind(deferred, !0)
|
|
callback: deferred.resolve.bind(deferred, !0)
|
|
} );
|
|
} );
|
|
} else {
|
|
} else {
|
|
- //this.bump(direction);
|
|
|
|
|
|
+ this.bump(direction);
|
|
deferred.resolve(!1);
|
|
deferred.resolve(!1);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -869,7 +943,7 @@ export class Images360 extends EventDispatcher{
|
|
this.updatePanoRenderer(vectorForward)
|
|
this.updatePanoRenderer(vectorForward)
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
|
|
+ this.updateZoomPano();
|
|
|
|
|
|
|
|
|
|
}
|
|
}
|
|
@@ -997,6 +1071,291 @@ export class Images360 extends EventDispatcher{
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //---------------scroll zoom ------------------------------------------
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /* zoomIn = function() { //放大
|
|
|
|
+ this.zoomBy(1 + this.zoomSpeed);
|
|
|
|
+ }
|
|
|
|
+ zoomOut = function() {//缩小
|
|
|
|
+ this.zoomBy(1 - this.zoomSpeed);
|
|
|
|
+ } */
|
|
|
|
+ zoomBy(e) {//以倍数
|
|
|
|
+ this.zoomTo(this.zoomLevel * e);
|
|
|
|
+ }
|
|
|
|
+ zoomTo(zoomLevel) {//缩放到某绝对zoomLevel
|
|
|
|
+ let zoom = Potree.settings.zoom
|
|
|
|
+ if (zoom.enabled) {
|
|
|
|
+ zoomLevel = THREE.Math.clamp(zoomLevel, zoom.min, zoom.max)
|
|
|
|
+ if(zoomLevel == this.zoomLevel) return;
|
|
|
|
+
|
|
|
|
+ /* if (zoomLevel > this.zoomLevel) {
|
|
|
|
+ this.emit(ZoomEvents.ZoomIn);
|
|
|
|
+ zoomLevel === settings.zoom.max && this.emit(ZoomEvents.ZoomMax);
|
|
|
|
+ } else if (zoomLevel < this.zoomLevel) {
|
|
|
|
+ this.emit(ZoomEvents.ZoomOut);
|
|
|
|
+ zoomLevel === settings.zoom.min && this.emit(ZoomEvents.ZoomMin);
|
|
|
|
+ } */
|
|
|
|
+
|
|
|
|
+ this.zoomLevel = zoomLevel;
|
|
|
|
+ viewer.setFOV(Potree.config.view.fov * (1 / this.zoomLevel))
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ zoomFovTo( fov ) { //通过fov来算zoomLevel
|
|
|
|
+ let zoomLevel = this.baseFov / fov;
|
|
|
|
+ this.zoomTo( zoomLevel );
|
|
|
|
+ }
|
|
|
|
+ smoothZoomTo(aimLevel, dur=0) {
|
|
|
|
+ var currentLevel = this.zoomLevel
|
|
|
|
+ if(currentLevel == aimLevel)return;
|
|
|
|
+
|
|
|
|
+ var fun = (progress)=>{
|
|
|
|
+ //progress > 1 && (progress = 1)
|
|
|
|
+ let level = currentLevel * (1 - progress) + aimLevel * progress
|
|
|
|
+ this.zoomTo(level, !0)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ transitions.start(fun, dur, null, null, 0 , easing['easeInOutQuad'] )
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /* zoomDefault{
|
|
|
|
+ this.zoomTo(1, !0)
|
|
|
|
+ }
|
|
|
|
+ smoothZoomToDefault(e, t) {
|
|
|
|
+ var i, n = this.zoomLevel,
|
|
|
|
+ r = function(e) {
|
|
|
|
+ e > 1 && (e = 1),
|
|
|
|
+ i = n * (1 - e) + e,
|
|
|
|
+ this.zoomTo(i, !0)
|
|
|
|
+ }
|
|
|
|
+ .bind(this),
|
|
|
|
+ o = function() {
|
|
|
|
+ this.zoomDefault(),
|
|
|
|
+ t && window.setTimeout(t, 50)
|
|
|
|
+ }
|
|
|
|
+ .bind(this);
|
|
|
|
+ transitions.start(r, e, o, null, 0, easing[settings.transition.blendEasing])
|
|
|
|
+ } */
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ updateZoomPano() {
|
|
|
|
+ if (!this.panoRenderer.zoomPanoRenderingDisabled && Potree.settings.displayMode == 'showPanos') {
|
|
|
|
+ var currentPano = this.currentPano;
|
|
|
|
+ if (currentPano) {
|
|
|
|
+ var activationThreshold = Potree.settings.navTileClass == '2k' && Potree.settings.tileClass == '4k' ? 1.7 : Potree.settings.zoom.activationThreshold//1.1
|
|
|
|
+ var t = this.zoomLevel > activationThreshold,
|
|
|
|
+ n = !(this.flying && this.nextPano && this.nextPano !== this.currentPano),
|
|
|
|
+ r = t && n;
|
|
|
|
+ this.tileDownloader.tilePrioritizer.setZoomingActive(r);
|
|
|
|
+ this.panoRenderer.setZoomingActive(r, currentPano, !0);
|
|
|
|
+
|
|
|
|
+ var o = (pano, zoomedFlag)=>{
|
|
|
|
+ this.panoRenderer.resetRenderStatus(pano.id, !1, !0, this.qualityManager.getMaxNavPanoSize());
|
|
|
|
+ this.panoRenderer.clearAllQueuedUploadsForPano(pano.id);
|
|
|
|
+ this.panoRenderer.renderPanoTiles(pano.id, null, !1, !1);
|
|
|
|
+ pano.setZoomed(zoomedFlag);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (r && (!currentPano.zoomed || this.qualityManager.zoomLevelResolution && this.qualityManager.zoomLevelResolution != '4k')) {
|
|
|
|
+ currentPano.zoomed || o(currentPano, !0);
|
|
|
|
+
|
|
|
|
+ if(Potree.settings.navTileClass == '1k' && Potree.settings.tileClass != '1k' && this.zoomLevel < 2){
|
|
|
|
+ this.panoRenderer.enableHighQuality( function() {//开启2k
|
|
|
|
+ if(Potree.settings.tileClass != '4k') o(currentPano, !0);
|
|
|
|
+ }.bind(this));
|
|
|
|
+ }else{
|
|
|
|
+ this.panoRenderer.enableUltraHighQualityMode(function() {//开启4k getMaxZoomPanoSize
|
|
|
|
+ this.qualityManager.useUltraHighResolutionPanos && (Potree.settings.zoom.max = Potree.config.ultraHighQualityMaxZoom);
|
|
|
|
+ o(currentPano, !0)
|
|
|
|
+ }.bind(this));
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ !t && currentPano.zoomed && o(currentPano, !1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if(r && Potree.settings.navTileClass == '1k' && Potree.settings.tileClass == '4k' ){ //目前只有手机端navTileClass == '1k'
|
|
|
|
+ var change = (zoomedFlag)=>{
|
|
|
|
+ this.qualityManager.updateMaximums()//更新maxZoomPanoSize
|
|
|
|
+ this.panoRenderer.setupZoomRenderTarget() //更新renderTarget
|
|
|
|
+ //currentPano.setZoomed(t);//更新uniforms贴图
|
|
|
|
+ }
|
|
|
|
+ this.qualityManager.zoomLevelResolution = this.zoomLevel >= 2 ? '4k' : this.zoomLevel > 1.1 ? '2k' : '1k'
|
|
|
|
+
|
|
|
|
+ if(this.oldZoomLevel < 2 && this.zoomLevel >= 2){//1k/2k-4k
|
|
|
|
+ change()
|
|
|
|
+ o(currentPano, t)
|
|
|
|
+ }else if(this.oldZoomLevel <= Potree.settings.zoom.activationThreshold && this.zoomLevel > Potree.settings.zoom.activationThreshold){//1k-2k
|
|
|
|
+ change()
|
|
|
|
+ }else if(this.oldZoomLevel > 2 && this.zoomLevel <= 2){//4k-2k/1k
|
|
|
|
+ change()
|
|
|
|
+ o(currentPano, t)
|
|
|
|
+ }else if(this.oldZoomLevel > Potree.settings.zoom.activationThreshold && this.zoomLevel <= Potree.settings.zoom.activationThreshold){//2k-1k
|
|
|
|
+ change()
|
|
|
|
+ }
|
|
|
|
+ this.oldZoomLevel = this.zoomLevel
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //--------------------
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ addHighMapCube(){//创建8*8的tile cube 主要因手机版崩溃 要在电脑端测试得设置maxRenderTargetSize
|
|
|
|
+
|
|
|
|
+ if( Potree.settings.tileClass == '4k' && this.qualityManager.maxRenderTargetSize == 2048){
|
|
|
|
+
|
|
|
|
+ var geo = new THREE.PlaneGeometry(1, 1, 1, 1)
|
|
|
|
+ var cube = new THREE.Object3D;
|
|
|
|
+ for(var cubeIndex=0; cubeIndex<6; cubeIndex++){
|
|
|
|
+ var face = new THREE.Object3D;
|
|
|
|
+ for(var i=0;i<8;i++){
|
|
|
|
+ for(var j=0;j<8;j++){
|
|
|
|
+ var tile = new THREE.Mesh(geo, new THREE.MeshBasicMaterial({
|
|
|
|
+ //side:THREE.DoubleSide
|
|
|
|
+ }))
|
|
|
|
+ tile.position.set(i-3.5, j-3.5, -4);
|
|
|
|
+
|
|
|
|
+ tile.material.opacity = 0.4;
|
|
|
|
+ tile.material.transparent = true
|
|
|
|
+ var colorHue = Math.random();
|
|
|
|
+ tile.material.color = (new THREE.Color()).setHSL(colorHue, 0.5, 0.9)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ tile.visible = false
|
|
|
|
+ face.add(tile)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ switch(cubeIndex){
|
|
|
|
+ case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_X:
|
|
|
|
+ face.rotation.set(0,Math.PI/2,0);
|
|
|
|
+ break;
|
|
|
|
+ case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
|
|
|
|
+ face.rotation.set(0,-Math.PI/2,0);
|
|
|
|
+ break;
|
|
|
|
+ case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
|
|
|
|
+ var rot1 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,1,0),Math.PI)
|
|
|
|
+ var rot2 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1,0,0),Math.PI/2)
|
|
|
|
+
|
|
|
|
+ face.quaternion.copy(rot1).multiply(rot2)
|
|
|
|
+ //face.rotation.set(Math.PI/2,0,0);
|
|
|
|
+ break;
|
|
|
|
+ case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
|
|
|
|
+ //face.rotation.set(-Math.PI/2,0,0);
|
|
|
|
+ var rot1 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,1,0),Math.PI)
|
|
|
|
+ var rot2 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(1,0,0),-Math.PI/2)
|
|
|
|
+
|
|
|
|
+ face.quaternion.copy(rot1).multiply(rot2)
|
|
|
|
+ break;
|
|
|
|
+ case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
|
|
|
|
+ face.rotation.set(0,Math.PI,0);
|
|
|
|
+ break;
|
|
|
|
+ case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
|
|
|
|
+ face.rotation.set(0,0,0);
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ face.scale.set(1,-1,1)
|
|
|
|
+ cube.add(face)
|
|
|
|
+ }
|
|
|
|
+ cube.name = 'highMapCube'
|
|
|
|
+ this.highMapCube = cube
|
|
|
|
+ viewer.scene.scene.add(cube)
|
|
|
|
+ //cube.scale.set(0.01,0.01,0.01)
|
|
|
|
+
|
|
|
|
+ this.highMapCube.visible = false;
|
|
|
|
+ viewer.setObjectLayers(this.highMapCube, 'sceneObjects'/* 'skybox' */) //如果是skybox层,点云可见时会被遮住,depthTest为false呢? 但不会遮住场景物体
|
|
|
|
+ console.warn('addHighMapCube')
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ isHighMapLoaded( cubeFace, tileX, tileY){
|
|
|
|
+ var tile = this.highMapCube.children[cubeFace].children[tileX*8+tileY];
|
|
|
|
+ return !!tile.material.map
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ updateHighMap(tex, cubeFace, tileX, tileY){
|
|
|
|
+ //console.warn('updateHighMap')
|
|
|
|
+ var tile = this.highMapCube.children[cubeFace].children[tileX*8+tileY];
|
|
|
|
+
|
|
|
|
+ tile.material.map = tex;
|
|
|
|
+
|
|
|
|
+ tile.material.opacity = 1;
|
|
|
|
+ tile.material.transparent = false
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ tile.visible = true
|
|
|
|
+ tile.material.needsUpdate = true //发现每次开始放大但还未放大到4k时也会把之前加载过的4k加载
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ resetHighMap(){
|
|
|
|
+
|
|
|
|
+ if(!this.highMapCube) return
|
|
|
|
+ console.warn('resetHighMap')
|
|
|
|
+ this.highMapCube.children.forEach(e=>e.children.forEach(tile=>{
|
|
|
|
+ if(tile.material.map){
|
|
|
|
+ tile.material.map.dispose()
|
|
|
|
+ tile.material.map.loaded = !1
|
|
|
|
+ tile.material.map.version = 0
|
|
|
|
+
|
|
|
|
+ var h = viewer.renderer.properties.get(tile.material.map)
|
|
|
|
+ viewer.renderer.getContext().deleteTexture(h.__webglTexture)
|
|
|
|
+ //类似app.sceneRenderer.deallocateCubeTexture(tile.material.map)
|
|
|
|
+
|
|
|
|
+ tile.material.map = null
|
|
|
|
+ /* tile.material.opacity = 0.4;
|
|
|
|
+ tile.material.transparent = true */
|
|
|
|
+ tile.material.needsUpdate = true
|
|
|
|
+ tile.visible = false
|
|
|
|
+ }
|
|
|
|
+ }))
|
|
|
|
+ this.highMapCube.visible = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ setHighMap(pano){
|
|
|
|
+ if(!this.highMapCube) return
|
|
|
|
+ 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的函数写法的
|
|
|
|
+
|
|
|
|
+ this.highMapCube.quaternion.copy( math.convertQuaternion.YupToZup( pano.quaternion4dkk ) )
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ showHighMap(){
|
|
|
|
+ if(!this.highMapCube) return
|
|
|
|
+ console.warn('showHighMap')
|
|
|
|
+ this.highMapCube.visible = true;
|
|
|
|
+ }
|
|
|
|
+ hideHighMap(){
|
|
|
|
+ if(!this.highMapCube) return
|
|
|
|
+ console.warn('hideHighMap')
|
|
|
|
+ this.highMapCube.visible = false;
|
|
|
|
+ }
|
|
|
|
+ //缩小后继续显示cube呢还是不显示? 不显示的话,就要把cube上的复制到renderTarget上……会不会又崩溃,or没加载的显示???
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -1132,10 +1491,8 @@ Images360.sortFunctions = {//排序函数,涉及到两个item相减
|
|
export class Images360Loader{
|
|
export class Images360Loader{
|
|
|
|
|
|
static async load(viewer, params, callback ){
|
|
static async load(viewer, params, callback ){
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- let center = viewer.transform.lonlatToLocal.inverse(viewer.bound.center)
|
|
|
|
|
|
+
|
|
|
|
+ let center = params.center.clone()
|
|
center = {lat:center.y, lon:center.x} //中心点
|
|
center = {lat:center.y, lon:center.x} //中心点
|
|
|
|
|
|
Potree.loadPanos(center,(data)=>{
|
|
Potree.loadPanos(center,(data)=>{
|
|
@@ -1158,7 +1515,7 @@ export class Images360Loader{
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
- viewer.setObjectLayers(images360.node, 'marker')
|
|
|
|
|
|
+ viewer.setObjectLayers(images360.node, 'marker'/* 'sceneObjects' */)
|
|
|
|
|
|
viewer.images360 = window.images360 = images360//add
|
|
viewer.images360 = window.images360 = images360//add
|
|
images360.tileDownloader.setPanoData(images360.panos, [] /* , Potree.settings.number */);
|
|
images360.tileDownloader.setPanoData(images360.panos, [] /* , Potree.settings.number */);
|