|
@@ -9,27 +9,28 @@ const circleGeo = new THREE.CircleGeometry(1.45,100);
|
|
|
const sphereGeo = new THREE.SphereBufferGeometry(0.018,10,10);
|
|
|
|
|
|
|
|
|
-const magDistance_ = 2;//相机离目标位置的距离的分界线,当离得远时要缩小fov以使看到的视野固定(望远镜效果)
|
|
|
-const radius_ = 0.2; //当相机离目标位置的距离>magDistance_时,希望看到的视野的半径
|
|
|
+const magDistance_ = 1;//相机离目标位置的距离的分界线,当离得远时要缩小fov以使看到的视野固定(望远镜效果)
|
|
|
+/* const radius_ = 0.2; //当相机离目标位置的距离>magDistance_时,希望看到的视野的半径
|
|
|
const maxFov = THREE.Math.radToDeg(Math.atan(radius_ / magDistance_ )) * 2//提前计算出当相机离目标位置的距离<magDistance_时的fov,均使用=magDistance_时的fov。只要保证该fov大于主相机的fov就会有放大效果
|
|
|
-
|
|
|
-let w = 200/1.4;
|
|
|
+ */
|
|
|
+let w = 200/1.43;
|
|
|
let maxPX = 1366*1024 //ipad pro. 大于这个分辨率的就直接用devicePixelRatio, 如macbook也是
|
|
|
-const width2dPX = window.devicePixelRatio >= 2 ? ( window.screen.width * window.screen.height >= maxPX ? window.devicePixelRatio : window.devicePixelRatio/1.5)*w : w //触屏或高分辨率的可能要放大些。但在手机上不能太大
|
|
|
-
|
|
|
+const width2dPX = Math.round(window.devicePixelRatio >= 2 ? ( window.screen.width * window.screen.height >= maxPX ? window.devicePixelRatio/1.2 : window.devicePixelRatio/1.5)*w : w) //触屏或高分辨率的可能要放大些。但在手机上不能太大
|
|
|
+console.log('width2dPX', width2dPX)
|
|
|
|
|
|
|
|
|
|
|
|
export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
|
|
|
constructor (viewer) {
|
|
|
super()
|
|
|
- this.width = this.height = 256;
|
|
|
+ this.width = this.height = width2dPX/* * window.devicePixelRatio */;
|
|
|
this.camera = new THREE.PerspectiveCamera(50, 1, 0.1, 10000); //fov aspect near far
|
|
|
this.camera.up = new THREE.Vector3(0,0,1)
|
|
|
|
|
|
|
|
|
this.viewport = new Viewport( null, this.camera, {
|
|
|
- left:0, bottom:0, width:1, height: 1, name:'magnifier' , cameraLayers:['magnifierContent']
|
|
|
+ left:0, bottom:0, width:1, height: 1, name:'magnifier' , cameraLayers:['magnifierContent'],
|
|
|
+ pixelRatio:1
|
|
|
})
|
|
|
this.viewport.setResolution(this.width, this.height,0,0)
|
|
|
|
|
@@ -71,7 +72,7 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
|
|
|
this.targetPoint = new THREE.Mesh(sphereGeo, new THREE.MeshBasicMaterial({
|
|
|
color:"#ff0000",
|
|
|
transparent:true,
|
|
|
- opacity:0.7,
|
|
|
+ opacity:0.65,
|
|
|
|
|
|
}))
|
|
|
this.targetPoint.name = 'magnifierPointTarget'
|
|
@@ -116,17 +117,13 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
|
|
|
this.update(e.intersectPoint && e.intersectPoint.location)
|
|
|
}else{
|
|
|
viewer.updateVisible(this,"atViewport", false) //小地图不显示
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
}
|
|
|
|
|
|
viewer.addEventListener('global_mousemove', updateVisi)
|
|
|
viewer.addEventListener('global_touchstart', updateVisi)
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
|
|
|
/* viewer.addEventListener("beginSplitView",()=>{
|
|
|
this.updateVisible("splitView", false)
|
|
@@ -155,66 +152,96 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
|
|
|
}
|
|
|
|
|
|
|
|
|
- /* updateVisible(reason, ifShow){//当所有加入的条件都不为false时才显示
|
|
|
- if(ifShow){
|
|
|
- var index = this.unvisibleReasons.indexOf(reason)
|
|
|
- index > -1 && this.unvisibleReasons.splice(index, 1)
|
|
|
- if(this.unvisibleReasons.length == 0)this.visible = true
|
|
|
- }else{
|
|
|
- if(!this.unvisibleReasons.includes(reason)) this.unvisibleReasons.push(reason)
|
|
|
- this.visible = false
|
|
|
- }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ update(aimPos){//相机靠近 navvis的做法
|
|
|
+
|
|
|
+ aimPos = aimPos instanceof THREE.Vector3 ? aimPos : this.aimPos
|
|
|
+ if(!aimPos || !this.visible)return
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ var playerCamera = viewer.scene.getActiveCamera()
|
|
|
+ var playerPos = playerCamera.position;//viewer.scene.view.getPivot()
|
|
|
+ var dis = playerPos.distanceTo(aimPos);
|
|
|
+ var dirToCamera = new THREE.Vector3().subVectors(playerPos, aimPos ).normalize()
|
|
|
+
|
|
|
+
|
|
|
+ //相机位置
|
|
|
+ var finalDisToAim = dis>magDistance_ ? magDistance_ : dis / 2;
|
|
|
+ this.camera.position.copy(aimPos).add(dirToCamera.multiplyScalar(finalDisToAim))
|
|
|
+ this.camera.lookAt(aimPos)
|
|
|
+ this.camera.fov = playerCamera.fov / 2
|
|
|
+ this.camera.updateProjectionMatrix()
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //自身位置
|
|
|
+ let pointer = viewer.inputHandler.pointer.clone();
|
|
|
+ let margin = 0.4, maxY = 0.4
|
|
|
+ let screenPos = pointer.clone().setY(pointer.y + (pointer.y>maxY ? -margin : margin ))
|
|
|
+
|
|
|
+ let newPos = new THREE.Vector3(screenPos.x,screenPos.y,0.8).unproject(playerCamera); //z:-1朝外
|
|
|
+ let dir = newPos.clone().sub(playerPos).normalize().multiplyScalar(10);//这个数值要大于playerCamera.near
|
|
|
+ let s = dis>magDistance_ ? 1 : dis / magDistance_ ;
|
|
|
|
|
|
- } */
|
|
|
+ this.position.copy(playerPos.clone().add(dir))
|
|
|
+ this.quaternion.copy(playerCamera.quaternion);
|
|
|
+ this.targetPoint.position.copy(aimPos);
|
|
|
+ this.targetPoint.scale.set(s,s,s)
|
|
|
+ this.aimPos = aimPos
|
|
|
+
|
|
|
+
|
|
|
+ var scale = math.getScaleForConstantSize({//
|
|
|
+ width2d : width2dPX,
|
|
|
+ camera:viewer.scene.getActiveCamera(), position: this.getWorldPosition(new THREE.Vector3()),
|
|
|
+ resolution: viewer.mainViewport.resolution2
|
|
|
+ })
|
|
|
+ this.scale.set(scale, scale, scale);
|
|
|
+
|
|
|
+ if(!this.dontRender){
|
|
|
+ this.waitRender = true
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
|
|
|
- update(aimPos){
|
|
|
+ /* update(aimPos){ //仅改fov的版本
|
|
|
|
|
|
aimPos = aimPos instanceof THREE.Vector3 ? aimPos : this.aimPos
|
|
|
if(!aimPos || !this.visible)return
|
|
|
- //console.log(aimPos)
|
|
|
+
|
|
|
|
|
|
//相机位置
|
|
|
var playerCamera = viewer.scene.getActiveCamera()
|
|
|
var playerPos = playerCamera.position;//viewer.scene.view.getPivot()
|
|
|
var dis = playerPos.distanceTo(aimPos);
|
|
|
- /* var vec = playerPos.clone().sub(aimPos).normalize().multiplyScalar(dis > magDistance_ ? magDistance_ : magDistance_/2)
|
|
|
- this.camera.position.copy(aimPos.clone().add(vec))
|
|
|
- this.camera.lookAt(aimPos) */
|
|
|
+
|
|
|
|
|
|
if(dis<magDistance_){
|
|
|
this.camera.fov = maxFov
|
|
|
}else{
|
|
|
this.camera.fov = THREE.Math.radToDeg(Math.atan(radius_ / dis )) * 2 //radius_是能看到的范围半径。当dis大于magDistance_时就放大,否则维持fov为maxFov
|
|
|
}
|
|
|
+
|
|
|
this.camera.updateProjectionMatrix()
|
|
|
this.camera.position.copy(playerPos)
|
|
|
this.camera.lookAt(aimPos)
|
|
|
|
|
|
this.quaternion.copy(playerCamera.quaternion);
|
|
|
-
|
|
|
- //mesh位置
|
|
|
- /* let screenPos = viewer.inputHandler.mouse.clone();
|
|
|
- let clientWidth = viewer.inputHandler.domElement.clientWidth * viewer.mainViewport.width;
|
|
|
- let clientHeight = viewer.inputHandler.domElement.clientHeight * viewer.mainViewport.height;
|
|
|
- screenPos.x = screenPos.x / clientWidth * 2 - 1;
|
|
|
- screenPos.y = -((screenPos.y < 300 ? 200 : -200) + screenPos.y) / clientHeight * 2 + 1; */
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
let pointer = viewer.inputHandler.pointer.clone();
|
|
|
let margin = 0.4, maxY = 0.4
|
|
|
let screenPos = pointer.clone().setY(pointer.y + (pointer.y>maxY ? -margin : margin ))
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
|
|
|
let newPos = new THREE.Vector3(screenPos.x,screenPos.y,0.8).unproject(playerCamera); //z:-1朝外
|
|
|
let dir = newPos.clone().sub(playerPos).normalize().multiplyScalar(10);//这个数值要大于playerCamera.near
|
|
|
|
|
|
this.position.copy(playerPos.clone().add(dir))
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
this.aimPos = aimPos
|
|
|
this.targetPoint.position.copy(aimPos);
|
|
|
|
|
@@ -227,11 +254,13 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
|
|
|
|
|
|
if(!this.dontRender){
|
|
|
this.waitRender = true
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+ }
|
|
|
}//位置需要计算,不仅仅是点云,所以需要深度图
|
|
|
+ */
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
render(){
|
|
|
|
|
@@ -248,6 +277,10 @@ export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
|
|
|
})
|
|
|
//this.visible = true;
|
|
|
this.waitRender = false
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
}
|
|
|
|
|
|
}
|