xzw 2 anni fa
parent
commit
3ff6ef4748

+ 1 - 7
src/custom/utils/transitions.js

@@ -262,13 +262,7 @@ var lerp = {
             
         }
     },
-    matrix4: function(currentTime, startY) {
-        var wholeY = currentTime.clone();
-        return function(duration) {
-            for (var r = currentTime.elements, o = wholeY.elements, a = startY.elements, s = 0; s < 16; s++)
-                r[s] = o[s] * (1 - duration) + a[s] * duration
-        }
-    },
+    
     allUniforms: function(currentTime, startY, wholeY) {
         var duration = currentTime.map(function(currentTime) {
             return this.uniform(currentTime, startY, wholeY)

+ 12 - 12
src/custom/viewer/ViewerNew.js

@@ -3442,7 +3442,7 @@ export class Viewer extends ViewerBase{
             position = new THREE.Vector3, //相机最终位置
             dis;                          //相机距离目标
         duration = duration == void 0 ? 1200 : duration;      
-        let camera = viewer.scene.getActiveCamera()
+        let camera = o.endCamera || o.camera || viewer.scene.getActiveCamera()
         let cameraPos = camera.position.clone()
         let boundSize  
         /* if(camera.type == 'OrthographicCamera'){
@@ -3794,23 +3794,23 @@ export class Viewer extends ViewerBase{
 
 
 
- 
+  
+        if(o.startCamera && o.endCamera){
+            viewer.scene.view.tranCamera(this.mainViewport,  { endPosition:position, target ,
+                boundSize, 
+                callback:()=>{
+                    //console.log('focusOnObjectSuccess: '+object.name,  type)
+                    deferred.resolve()
+                }, startCamera:o.startCamera, endCamera:o.endCamera, midCamera:this.scene.cameraBasic
+            }, duration)
          
-            
-        /*} else if(dimension == 2){//线
-            
-        }else if(dimension == 3){//面
-            
-        }else{//立体
-            
-        } */
-        if(camera.type == "OrthographicCamera"){   
+        }else if(camera.type == "OrthographicCamera"){   
             viewer.scene.view.moveOrthoCamera(this.mainViewport,  { endPosition:position, target ,
                 boundSize, 
                 callback:()=>{
                     //console.log('focusOnObjectSuccess: '+object.name,  type)
                     deferred.resolve()
-                }
+                }, 
             }, duration)
         }else{
             viewer.scene.view.setView({position, target, duration, callback:()=>{

+ 2 - 0
src/viewer/ExtendScene.js

@@ -16,6 +16,8 @@ class ExtendScene extends Scene{
 		this.cameraP = new THREE.PerspectiveCamera(this.fov, 1, Potree.config.view.near, Potree.config.view.near);
 		this.cameraO = new THREE.OrthographicCamera(-1, 1, 1, -1, Potree.config.view.near, Potree.settings.cameraFar);
         this.cameraP.limitFar = true//add
+		this.cameraBasic = new THREE.PerspectiveCamera();//add 不自动计算的渐变相机
+        //this.cameraBasic.matrixAutoUpdate = false 
 		this.initializeExtend();
         
         //-------------

+ 55 - 10
src/viewer/ExtendView.js

@@ -50,7 +50,7 @@ class ExtendView extends View {
     }
     
     set quaternion(q){
-        this.direction = new THREE.Vector3(0,0,-1).applyQuaternion(q)
+        this.direction = new THREE.Vector3(0,0,-1).applyQuaternion(q) //注意如果得到的dir.x==dir.y==0,  yaw不会变为0, 导致算的quaternion和q不一致
     }
     
     copy(a){
@@ -180,7 +180,7 @@ class ExtendView extends View {
     setView( info = {}){
         // position, target, duration = 0, callback = null, onUpdate = null, Easing='', cancelFun
         this.cancelFlying()
-        let posWaitDone,  rotWaitDone 
+        let posWaitDone,  rotWaitDone , dir
         
         let posDone = ()=>{
             rotWaitDone || done()
@@ -188,10 +188,12 @@ class ExtendView extends View {
         }
         let rotDone = ()=>{
             if(endTarget){
-                this.lookAt(endTarget); //compute radius for orbitcontrol
+                this.lookAt(endTarget); //compute radius for orbitcontrol 
             }else if(endQuaternion){
                 this.rotation = new THREE.Euler().setFromQuaternion(endQuaternion)
             }
+            if(dir.x == 0 && dir.y == 0)this.yaw = 0 //统一一下 朝上的话是正的。朝下的一般不是0,会保留一个接近0的小数所以不用管
+            //if(info.yaw != void 0) this.yaw = info.yaw //当dir.x=dir.y=0时,计算不到yaw,所以需要补充
             posWaitDone || done()
             rotWaitDone = false 
         }
@@ -218,12 +220,12 @@ class ExtendView extends View {
 		if(info.target ){
 			endTarget = new THREE.Vector3().copy(info.target)  
             endQuaternion = math.getQuaFromPosAim(endPosition,endTarget) //若为垂直,会自动偏向x负的方向
-            let dir = new THREE.Vector3().subVectors(endTarget, endPosition).normalize()
+            dir = new THREE.Vector3().subVectors(endTarget, endPosition).normalize()
             //console.log(dir, this.direction)  
             
-            let view = this.clone();
+            /* let view = this.clone();
             view.direction = dir;
-            console.log(view.yaw, view.pitch,  this.yaw,  this.pitch)
+            console.log(view.yaw, view.pitch,  this.yaw,  this.pitch) */
             
             
 		}else if(info.quaternion){
@@ -231,7 +233,7 @@ class ExtendView extends View {
         }
          
         if(endQuaternion){ 
-            startQuaternion = new THREE.Quaternion().setFromEuler(this.rotation)
+            startQuaternion = this.quaternion//new THREE.Quaternion().setFromEuler(this.rotation)
             needRot = endQuaternion
             /*  const startTarget = this.getPivot();
             let startQuaternion = math.getQuaFromPosAim(startPosition,startTarget) */
@@ -277,7 +279,7 @@ class ExtendView extends View {
                    
                     let quaternion = (new THREE.Quaternion()).copy(startQuaternion) 
                     lerp.quaternion(quaternion, endQuaternion)(progress)  //在垂直的视角下的角度突变的厉害,这时候可能渐变yaw比较好
-             
+                    //console.log(quaternion)
                     //this.rotation = new THREE.Euler().setFromQuaternion(quaternion)
                     this.quaternion = quaternion
                      
@@ -315,13 +317,16 @@ class ExtendView extends View {
     
     //平移Ortho相机
     moveOrthoCamera(viewport,  info, duration,  easeName){//boundSize优先于endZoom。
-        let camera = viewport.camera
+        let camera = info.camera || viewport.camera
         
         let startZoom = camera.zoom 
         let endPosition = info.endPosition 
         let boundSize = info.boundSize
         let endZoom = info.endZoom
         let margin = info.margin || {x:0,y:0}/* 200 */ //像素
+        let onUpdate = info.onUpdate 
+        
+        
         
         if(info.bound){//需要修改boundSize以适应相机的旋转,当相机不在xy水平面上朝向z时
             endPosition = endPosition || info.bound.getCenter(new THREE.Vector3())
@@ -336,9 +341,12 @@ class ExtendView extends View {
             boundSize.set(1,1)  //避免infinity
         }
         
+        
+        
+        
         this.setView( Object.assign(info,  { position:endPosition,  duration, 
             
-            onUpdate:(progress)=>{ 
+            onUpdate:(progress, delta)=>{ 
                 if(boundSize || endZoom){ 
                     if(boundSize){
                         let aspect = boundSize.x / boundSize.y
@@ -356,6 +364,7 @@ class ExtendView extends View {
                     
                     camera.zoom = endZoom * progress + startZoom * (1 - progress)
                     camera.updateProjectionMatrix() 
+                    onUpdate && onUpdate(progress, delta)
                 } 
             },
             
@@ -398,6 +407,42 @@ class ExtendView extends View {
     
         
         
+    } 
+    
+    
+    tranCamera(viewport,  info, duration,  easeName){
+        viewport.camera = info.midCamera
+        //viewport.camera.matrixWorld = info.endCamera.matrixWorld
+        
+        
+        //viewer.setCameraMode(CameraMode.ORTHOGRAPHIC) 
+        info.midCamera.projectionMatrix.copy(info.startCamera.projectionMatrix)
+        
+        let onUpdate = info.onUpdate
+        info.onUpdate = (progress, delta)=>{ 
+            lerp.matrix4(info.midCamera.projectionMatrix, info.endCamera.projectionMatrix)(progress) 
+            
+            /* console.log('matrixWorld', viewport.camera.position.toArray(), viewport.camera.matrixWorld.toArray())
+            console.log('projectionMatrix', info.endCamera.zoom,  viewport.camera.projectionMatrix.toArray())
+             */
+            onUpdate && onUpdate(progress, delta)
+        }
+        
+        let callback = info.callback
+        info.callback = ()=>{ 
+            viewport.camera = info.endCamera 
+            callback && callback()
+        } 
+        
+        
+        info.camera = info.endCamera
+        
+        if(info.camera.type == "OrthographicCamera"){
+            this.moveOrthoCamera(viewport,  info, duration,  easeName)
+        }else{
+            this.setView( Object.assign(info,  { duration}) )
+        }
+        
     }
     
      

+ 114 - 28
src/viewer/NavigationCube.js

@@ -591,22 +591,12 @@ class NavigationCube{
                 faceMesh.addEventListener('click', (e)=>{
                     this.changingView = true 
                     faceMesh.material.uniforms.faceColor.value.set(Colors.blue) 
-                 
-                    if(viewer.mainViewport.camera != viewer.scene.cameraO){
-                        viewer.scene.cameraO.position.copy(viewer.mainViewport.camera.position)
-                        viewer.scene.cameraO.quaternion.copy(viewer.mainViewport.camera.quaternion)
-                        viewer.mainViewport.camera = viewer.scene.cameraO
-                        viewer.setCameraMode(CameraMode.ORTHOGRAPHIC) 
-                        navCubeViewer.controls.setEnable(false)
-                    }
-                    
-                    viewer.focusOnObject(viewer.bound, 'boundingBox', 1000, {dir:directions[name].clone()}).promise.done(()=>{
+                    navCubeViewer.switchView('ortho', directions[name].clone(),()=>{
                         this.changingView = false
                         faceMesh.material.uniforms.faceColor.value.set(Colors.black)
-                        //console.log('回2', name)
-                        navCubeViewer.dispatchEvent('content_changed')
                     })
                     
+                    
                 }); 
                  
             })
@@ -767,6 +757,7 @@ class NavCubeViewer extends ViewerBase{
     updateCamera(){  
         let view = this.listenViewport.view
         this.view.quaternion = view.quaternion   //this.view.rotation = view.rotation 
+        this.view.yaw = view.yaw
         var dir = view.direction;  //相机朝向
         this.view.position.copy(dir.multiplyScalar(this.view.radius).negate())  //相机绕着指南针中心(000)转动
           
@@ -779,27 +770,122 @@ class NavCubeViewer extends ViewerBase{
     }
     
     pushHomeBtn(){
-        if(viewer.mainViewport.camera == viewer.scene.cameraO){
-            //viewer.scene.cameraP.position.copy(viewer.mainViewport.camera.position)
-            //viewer.scene.cameraP.quaternion.copy(viewer.mainViewport.camera.quaternion)
-            viewer.mainViewport.camera = viewer.scene.cameraP
-            viewer.setCameraMode(CameraMode.PERSPECTIVE)
+        this.switchView('perspective')
+    }  
+    
+    /* switchView(type, dir, done){
+        let view = viewer.mainViewport.view
+        if(type == 'ortho'){
+            if(viewer.mainViewport.camera != viewer.scene.cameraO){
+                viewer.scene.cameraO.position.copy(viewer.mainViewport.camera.position)
+                viewer.scene.cameraO.quaternion.copy(viewer.mainViewport.camera.quaternion)
+                viewer.mainViewport.camera = viewer.scene.cameraO
+                viewer.setCameraMode(CameraMode.ORTHOGRAPHIC) 
+                navCubeViewer.controls.setEnable(false)
+                 
+                //假设保持到目前中心的视角范围不变
+                splitScreen.setShiftTarget(viewer.mainViewport, viewer.bound.center)
+                let dis = new THREE.Vector3().subVectors(viewer.mainViewport.shiftTarget,  viewer.scene.cameraO.position).length() ;   //-nearestPano[0].score
+	                    
+                //根据2d->3d的式子逆求zoom
+                let halfHeight = Math.abs(dis) * Math.tan( THREE.Math.degToRad(viewer.scene.cameraP.fov/2)); 
+                viewer.scene.cameraO.zoom = viewer.scene.cameraO.top / halfHeight;
+                viewer.scene.cameraO.updateProjectionMatrix();
+                 
+                console.log('zoom', viewer.scene.cameraO.zoom)
+                
+            }
             
-            //假设保持到目前中心的视角范围不变
-            let view = viewer.mainViewport.view
-            splitScreen.setShiftTarget(viewer.mainViewport, viewer.bound.center)
-            viewer.mainViewport.targetPlane.setFromNormalAndCoplanarPoint( view.direction.clone(), viewer.bound.center )  
-            viewer.mainViewport.targetPlane.projectPoint(view.position, viewer.mainViewport.shiftTarget )  
-             
-            let halfHeight = viewer.scene.cameraO.top/viewer.scene.cameraO.zoom 
-            let dis = halfHeight / Math.tan( THREE.Math.degToRad(viewer.scene.cameraP.fov/2)) 
+            viewer.focusOnObject(viewer.bound, 'boundingBox', 1000, {dir }).promise.done(()=>{
+                done && done()
+                //console.log('回2', name)
+                navCubeViewer.dispatchEvent('content_changed')
+            })
+        }else{
             
-            view.position.copy(viewer.mainViewport.shiftTarget).sub(view.direction.clone().multiplyScalar(dis)); 
-            this.controls.setEnable(true) 
+            if(viewer.mainViewport.camera == viewer.scene.cameraO){
+                //viewer.scene.cameraP.position.copy(viewer.mainViewport.camera.position)
+                //viewer.scene.cameraP.quaternion.copy(viewer.mainViewport.camera.quaternion)
+                viewer.mainViewport.camera = viewer.scene.cameraP
+                viewer.setCameraMode(CameraMode.PERSPECTIVE)
+                
+                //假设保持到目前中心的视角范围不变
+                
+                splitScreen.setShiftTarget(viewer.mainViewport, viewer.bound.center)
+                viewer.mainViewport.targetPlane.setFromNormalAndCoplanarPoint( view.direction.clone(), viewer.bound.center )  
+                viewer.mainViewport.targetPlane.projectPoint(view.position, viewer.mainViewport.shiftTarget )  
+                 
+                let halfHeight = viewer.scene.cameraO.top/viewer.scene.cameraO.zoom 
+                let dis = halfHeight / Math.tan( THREE.Math.degToRad(viewer.scene.cameraP.fov/2)) 
+                
+                view.position.copy(viewer.mainViewport.shiftTarget).sub(view.direction.clone().multiplyScalar(dis)); 
+                this.controls.setEnable(true) 
+            } 
         }
-    }  
+    } */
+    switchView(type, dir, done){
+        let view = viewer.mainViewport.view
+        if(type == 'ortho'){
+            let startCamera, endCamera
+            if(viewer.mainViewport.camera != viewer.scene.cameraO){
+                startCamera = viewer.scene.cameraP
+                endCamera = viewer.scene.cameraO
+                viewer.scene.cameraO.position.copy(viewer.mainViewport.camera.position)
+                viewer.scene.cameraO.quaternion.copy(viewer.mainViewport.camera.quaternion)
+                viewer.mainViewport.camera = viewer.scene.cameraO //先设置为cameraO, 才能计算top
+                viewer.setCameraMode(CameraMode.ORTHOGRAPHIC) //updateScreenSize set cameraO.top
+                
+                navCubeViewer.controls.setEnable(false)
+                 
+                //假设保持到目前中心的视角范围不变
+                splitScreen.setShiftTarget(viewer.mainViewport, viewer.bound.center)
+                let dis = new THREE.Vector3().subVectors(viewer.mainViewport.shiftTarget,  viewer.scene.cameraO.position).length() ;   //-nearestPano[0].score
+	                    
+                //根据2d->3d的式子逆求zoom
+                let halfHeight = Math.abs(dis) * Math.tan( THREE.Math.degToRad(viewer.scene.cameraP.fov/2)); 
+                viewer.scene.cameraO.zoom = viewer.scene.cameraO.top / halfHeight;
+                viewer.scene.cameraO.updateProjectionMatrix();
+                    
+            }
+            
+            viewer.focusOnObject(viewer.bound, 'boundingBox', 1000, {
+                dir , startCamera, endCamera
+            }).promise.done(()=>{  
+                
+                done && done()
+                navCubeViewer.dispatchEvent('content_changed')
+            })
+        }else{
+            
+            if(viewer.mainViewport.camera == viewer.scene.cameraO){
+                //viewer.scene.cameraP.position.copy(viewer.mainViewport.camera.position)
+                //viewer.scene.cameraP.quaternion.copy(viewer.mainViewport.camera.quaternion)
+                viewer.mainViewport.camera = viewer.scene.cameraP
+                viewer.setCameraMode(CameraMode.PERSPECTIVE)
+                
+                //假设保持到目前中心的视角范围不变
+                
+                splitScreen.setShiftTarget(viewer.mainViewport, viewer.bound.center)
+                viewer.mainViewport.targetPlane.setFromNormalAndCoplanarPoint( view.direction.clone(), viewer.bound.center )  
+                viewer.mainViewport.targetPlane.projectPoint(view.position, viewer.mainViewport.shiftTarget )  
+                 
+                let halfHeight = viewer.scene.cameraO.top/viewer.scene.cameraO.zoom 
+                let dis = halfHeight / Math.tan( THREE.Math.degToRad(viewer.scene.cameraP.fov/2)) 
+                
+                let position = new THREE.Vector3().copy(viewer.mainViewport.shiftTarget).sub(view.direction.clone().multiplyScalar(dis)); 
+                //view.position.copy(viewer.mainViewport.shiftTarget).sub(view.direction.clone().multiplyScalar(dis)); 
+                this.controls.setEnable(true)
 
 
+                view.tranCamera(viewer.mainViewport,  { position ,   
+                    callback:()=>{ 
+                    }, startCamera:viewer.scene.cameraO, endCamera:viewer.scene.cameraP, midCamera:viewer.scene.cameraBasic
+                }, 500)
+
+                
+            } 
+        }
+    } 
     rotateSideCamera(angle){
         splitScreen.rotateSideCamera(viewer.mainViewport,angle)
     }

+ 2 - 2
src/viewer/View.js

@@ -45,8 +45,8 @@ export class View{//base
         
 		if(dir.x === 0 && dir.y === 0){
 			this.pitch = Math.PI / 2 * Math.sign(dir.z); 
-            this.yaw = 0   //add:还是要指定一下, 否则不统一
-            
+            //this.yaw = 0   
+            //console.log('yaw没变',this.yaw)
 		}else{
 			let yaw = Math.atan2(dir.y, dir.x) - Math.PI / 2;
 			let pitch = Math.atan2(dir.z, Math.sqrt(dir.x * dir.x + dir.y * dir.y));