123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- import * as THREE from "../../libs/three.js/build/three.module.js";
- import math from './math'
-
-
-
- let texLoader = new THREE.TextureLoader()
- let circleGeo = new THREE.CircleGeometry(1.45,100);
-
-
-
- const magDistance_ = 2;//相机离目标位置的距离的分界线,当离得远时要缩小fov以使看到的视野固定(望远镜效果)
- const radius_ = 0.2; //当相机离目标位置的距离>magDistance_时,希望看到的视野的半径
- const maxFov = THREE.Math.radToDeg(Math.atan(radius_ / magDistance_ )) * 2//提前计算出当相机离目标位置的距离<magDistance_时的fov,均使用=magDistance_时的fov。只要保证该fov大于主相机的fov就会有放大效果
- const width2dPX = 200/1.4;//px
-
- export default class Magnifier extends THREE.Object3D {//放大镜or望远镜
- constructor (viewer) {
- super()
- this.width = this.height = 256;
- this.camera = new THREE.PerspectiveCamera(50, 1, 0.1, 10000); //fov aspect near far
- this.camera.up = new THREE.Vector3(0,0,1)
-
- this.renderTarget = new THREE.WebGLRenderTarget(this.width,this.height, {
- minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter,
- format: THREE.RGBAFormat ,
- /* type: THREE.FloatType,
- minFilter: THREE.NearestFilter,
- magFilter: THREE.NearestFilter,
- */
- } )
-
- this.rtEDL = new THREE.WebGLRenderTarget(this.width, this.height, {
- minFilter: THREE.NearestFilter,
- magFilter: THREE.NearestFilter,
- format: THREE.RGBAFormat,
- type: THREE.FloatType,
- depthTexture: new THREE.DepthTexture(undefined, undefined, THREE.UnsignedIntType)
- });
-
-
-
- this.mesh = new THREE.Mesh(circleGeo, new THREE.MeshBasicMaterial({
- side: THREE.DoubleSide ,
- map: this.renderTarget.texture ,
- transparent:true,
- depthTest: !1,
- //depthWrite: !1,
- }))
- this.overlayMesh = new THREE.Mesh(circleGeo, new THREE.MeshBasicMaterial({
- side: THREE.DoubleSide ,
- map:texLoader.load(Potree.resourcePath+'/textures/crosshair.png') ,
- transparent:true,
- depthTest: !1,
- //depthWrite: !1,
- }))
- this.add(this.mesh)
- this.add(this.overlayMesh)
- this.position.set(-1000,-1000,-100000)//令它看不见
- this.mesh.renderOrder = 10;
- this.overlayMesh.renderOrder = 11;
- this.aimPos
- //viewer.inputHandler.addInputListener(this)
-
- viewer.addEventListener('camera_changed',(e)=>{ // 平移、滚轮时更新
- if(e.viewport == viewer.mainViewport) this.update()
- })
-
- this.unvisibleReasons = []; //如果length>0代表不可见
-
- this.mesh.layers.set(Potree.config.renderLayers.magnifier);
- this.overlayMesh.layers.set(Potree.config.renderLayers.magnifier);
- //this.layers.set(Potree.config.renderLayers.magnifier);//这句在外层写没用
-
- this.dontRender = false
- viewer.addEventListener('global_drag', (e)=>{//拖拽时不渲染。主要是右键平移时渲染延迟了,会闪烁。
- this.dontRender = true
- })
- viewer.addEventListener('global_drop', (e)=>{
- this.dontRender = false
- })
-
- viewer.addEventListener('global_mousemove', (e)=>{
- if(e.hoverViewport == viewer.mainViewport){
- this.updateVisible("atViewport", true)
- this.update(e.intersectPoint && e.intersectPoint.location)
- }else{
- this.updateVisible("atViewport", false)
- }
- })
-
-
-
-
- /* viewer.addEventListener("beginSplitView",()=>{
- this.updateVisible("splitView", false)
- })
- viewer.addEventListener("finishSplitView",()=>{
- this.updateVisible("splitView", true)
- }) */
-
- viewer.addEventListener("measureMovePoint",()=>{
- this.updateVisible("measure", true)
- })
- viewer.addEventListener("endMeasureMove",()=>{
- this.updateVisible("measure", false)
- })
-
- this.updateVisible("measure", false)
- }
-
-
- updateVisible(reason, ifShow){
- 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){
-
- 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 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
-
- var scale = math.getScaleForConstantSize({//
- width2d : width2dPX,
- camera:viewer.scene.getActiveCamera(), position: this.getWorldPosition(new THREE.Vector3()),
- resulution: viewer.mainViewport.resolution
- })
- this.scale.set(scale, scale, scale);
-
- if(!this.dontRender){
- this.waitRender = true
- }
-
-
-
- }//位置需要计算,不仅仅是点云,所以需要深度图
-
- render(){
-
- if(!this.waitRender)return
- //this.visible = false;//防止放大镜里有自己
- viewer.render({
- target : this.renderTarget,
- viewport : viewer.mainViewport,
- camera : this.camera,
- magnifier : true,
- rtEDL: this.rtEDL,
- width :this.renderTarget.width,
- height: this.renderTarget.height,
- })
- //this.visible = true;
- this.waitRender = false
- }
-
- }
|