Reticule.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import * as THREE from "../../libs/three.js/build/three.module.js";
  2. import {MOUSE} from '../defines.js'
  3. import {transitions, easing, lerp} from '../utils/transitions.js'
  4. import math from '../utils/math.js'
  5. let texLoader = new THREE.TextureLoader()
  6. let defaultOpacity = 0.7
  7. //鼠标指示小圆片
  8. export default class Reticule extends THREE.Mesh{
  9. constructor(viewer){
  10. var defaultTex = texLoader.load(Potree.resourcePath+'/textures/whiteCircle.png'/* reticule-256x256.png' */)
  11. var crosshairTex = texLoader.load(Potree.resourcePath+'/textures/reticule_cross_hair.png')
  12. super(new THREE.PlaneBufferGeometry(0.15,0.15,1,1),new THREE.MeshBasicMaterial({
  13. side: THREE.DoubleSide ,
  14. map: defaultTex,
  15. transparent:true,
  16. depthTest: !1,
  17. opacity: defaultOpacity,
  18. //depthWrite: !1,
  19. }))
  20. //this.layers.set(0/* RenderLayers.RETICULE */);
  21. this.renderOrder = 0
  22. this.layers.set(Potree.config.renderLayers.marker);
  23. this.direction = new THREE.Vector3;
  24. this.hidden = !0;
  25. this.mouseLastMoveTime = Date.now();
  26. //viewer.inputHandler.addInputListener(this);
  27. viewer.addEventListener('global_mousemove',this.move.bind(this))
  28. viewer.addEventListener('measureMovePoint',()=>{
  29. this.material.map = crosshairTex
  30. this.state = 'crosshair'
  31. })
  32. viewer.addEventListener('endMeasureMove',()=>{
  33. this.material.map = defaultTex
  34. this.state = 'default'
  35. })
  36. this.state = 'default'
  37. viewer.setObjectLayers(this, 'reticule' )
  38. }
  39. move(e){
  40. if(e.buttons == MOUSE.NONE || this.state == 'crosshair' ){//按下时不更新,除非拖拽测量
  41. this.hidden = false,
  42. this.mouseLastMoveTime = Date.now()
  43. this.updatePosition(e.intersectPoint, e.hoverViewport)
  44. }
  45. }
  46. hide(){
  47. //console.log("hide Reticule")
  48. this.hidden || (this.hidden = !0,
  49. transitions.start(lerp.property(this.material , "opacity", 0), 500))
  50. }
  51. show(){
  52. if(!this.visible)return
  53. //console.log("show Reticule")
  54. this.hidden = !1,
  55. this.material.opacity <= 0 && transitions.start(lerp.property(this.material, "opacity", defaultOpacity), 300)
  56. }
  57. //鼠标静止一段时间它就会消失
  58. updateVisible(){
  59. Date.now() - this.mouseLastMoveTime > 1500 && !this.hidden && this.hide()
  60. }
  61. updatePosition(intersectPoint, viewport ){ //在地图(当地图融合到viewer时)和场景里都显示且完全相同(大小可能不同)
  62. if (!this.hidden && this.visible) {
  63. if (!intersectPoint /* || !intersectPoint.point.normal */)
  64. return //this.hide();
  65. var atMap = !intersectPoint.location
  66. let normal = intersectPoint.point ? new THREE.Vector3().fromArray(intersectPoint.point.normal ) : new THREE.Vector3(0,0,1)//地图无normal
  67. let s, camera
  68. let location = intersectPoint.location || intersectPoint.orthoIntersect.clone()
  69. if(!atMap){
  70. camera = viewport.camera
  71. let n = camera.position.distanceTo(location)
  72. s = 1 + .01 * n;
  73. n < 1 && (s -= 1 - n)
  74. }else{
  75. camera = viewer.mapViewer.camera
  76. s = math.getScaleForConstantSize({width2d:300, position:location, camera, resolution:viewport.resolution2} )
  77. location.setZ(0);//低于相机高度即可
  78. }
  79. this.show();
  80. this.scale.set(s, s, s);
  81. this.direction = this.direction.multiplyScalar(.8);
  82. this.direction.add(normal.clone().multiplyScalar(.2));
  83. this.position.copy(location).add(normal.clone().multiplyScalar(.01));
  84. this.lookAt(this.position.clone().add(this.direction));
  85. }
  86. }
  87. }