Sprite.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import * as THREE from "../../../libs/three.js/build/three.module.js";
  2. import DepthBasicMaterial from "../materials/DepthBasicMaterial.js";
  3. import math from "../utils/math.js";
  4. const geo = new THREE.PlaneBufferGeometry(1,1)
  5. export default class Sprite extends THREE.Mesh{
  6. constructor(options){
  7. super(geo, options.mat || new DepthBasicMaterial(options))/* ({map:options.map, useDepth:options.useDepth})) */
  8. this.root = options.root || this;
  9. this.renderOrder = options.renderOrder != void 0 ? options.renderOrder : 4;
  10. this.pickOrder = options.pickOrder || 0
  11. this.sizeInfo = options.sizeInfo
  12. this.dontFixOrient = options.dontFixOrient
  13. this.root.matrixAutoUpdate = false;
  14. this.matrixMap = new Map()
  15. this.name = options.name || 'sprite'
  16. this.useViewport = null
  17. this.viewports = options.viewports//指定更新的viewports
  18. this.visible_ = true
  19. let update = (e)=>{
  20. this.update(e)
  21. }
  22. viewer.mapViewer && viewer.mapViewer.addEventListener("camera_changed", update)
  23. viewer.addEventListener("camera_changed", update)
  24. /* if(viewer.viewports.length == 1){//直接更新。如果有多个不在这更新,在"render.begin"
  25. this.update(e)
  26. } */
  27. let applyMatrix = (e)=>{
  28. this.applyMatrix(e)
  29. }
  30. viewer.addEventListener("raycaster", applyMatrix) //before render
  31. viewer.addEventListener("render.begin", applyMatrix) //before render //magnifier时要禁止吗
  32. this.addEventListener('dispose', ()=>{
  33. viewer.mapViewer && viewer.mapViewer.removeEventListener("camera_changed", update)
  34. viewer.removeEventListener("camera_changed", update)
  35. viewer.removeEventListener("raycaster", applyMatrix) //before render
  36. viewer.removeEventListener("render.begin", applyMatrix)
  37. this.dispose()
  38. })
  39. }
  40. set visible(v){
  41. this.visible_ = v
  42. if(v){
  43. this.update()
  44. }
  45. }
  46. get visible(){
  47. return this.visible_
  48. }
  49. realVisible(){
  50. let v = true
  51. let parent = this
  52. let lastParent
  53. while(parent){
  54. if(parent.visible === false){
  55. v = false
  56. break;
  57. }
  58. lastParent = parent
  59. parent = parent.parent
  60. }
  61. if(v && !(lastParent instanceof THREE.Scene)){//已被删除
  62. v = false
  63. }
  64. if(!this.latestRealVisi && v){//变为可见后先update
  65. this.latestRealVisi = true
  66. setTimeout(()=>{
  67. this.update()
  68. },1)//延迟 防止无限调用
  69. return false
  70. }
  71. this.latestRealVisi = v
  72. return v;
  73. }
  74. update(e){
  75. if(!e){
  76. let viewports = this.viewports || viewer.viewports
  77. if(!viewports)return
  78. viewports.forEach(view=>{
  79. this.update({viewport:view})
  80. })
  81. return;
  82. }
  83. if(!this.root || ! this.realVisible() /* this.visible */ )return
  84. if(this.viewports && !this.viewports.includes(e.viewport) )return
  85. if(e.viewport.name == 'magnifier')return
  86. let camera = e.viewport.camera
  87. //rotation
  88. if(!this.dontFixOrient){ //orthoCamera一般要加dontFixOrient
  89. let parentQua = this.root.parent.getWorldQuaternion(new THREE.Quaternion)
  90. this.root.quaternion.multiplyQuaternions(parentQua.invert(),camera.quaternion) //乘上parentQua.invert()是为了中和掉父结点的qua,使只剩下camera.quaternion
  91. }
  92. //scale
  93. var info = this.sizeInfo
  94. if(info){
  95. this.root.updateMatrix();//先更新,getWorldPosition才能得到正确的
  96. this.root.updateMatrixWorld(true)
  97. var scale
  98. if(info.restricMeshScale){//仅限制最大或最小的话,不判断像素大小,直接限制mesh的scale
  99. var dis = camera.position.distanceTo(this.root.getWorldPosition(new THREE.Vector3()))
  100. if(dis < info.nearBound){
  101. scale = info.scale * dis / info.nearBound
  102. }else{
  103. scale = info.scale
  104. }
  105. }else{
  106. scale = math.getScaleForConstantSize($.extend(info,{//规定下最小最大像素
  107. camera , position:this.root.getWorldPosition(new THREE.Vector3()) ,
  108. resolution: e.viewport.resolution//2
  109. }))
  110. }
  111. if(!isNaN(scale)){
  112. this.root.scale.set(scale, scale, scale);
  113. }
  114. }
  115. this.root.updateMatrix();
  116. this.root.updateMatrixWorld(true)
  117. this.matrixMap.set(e.viewport, this.root.matrix.clone())
  118. this.useViewport = e.viewport
  119. }
  120. applyMatrix(e){
  121. if(!e)e = {viewport:viewer.mainViewport}//随便写一个viewport
  122. if(e.viewport.name == 'magnifier')return
  123. if(this.viewports && !this.viewports.includes(e.viewport) )return
  124. if( !this.root || !this.realVisible() )return
  125. var matrix = this.matrixMap.get(e.viewport);
  126. if(!matrix){
  127. this.update(e)
  128. matrix = this.matrixMap.get(e.viewport);
  129. }
  130. if(e.viewport == this.useViewport){
  131. return
  132. }
  133. this.useViewport = e.viewport
  134. this.root.matrix.copy(matrix)
  135. this.root.updateMatrixWorld(true)
  136. //console.log(this.root.name + e.viewport.name + " : "+this.root.matrixWorld.elements)
  137. }
  138. setUniforms(name,value){
  139. this.material.setUniforms(name,value)
  140. }
  141. dispose(){
  142. this.removeAllListeners()
  143. this.parent && this.parent.remove(this)
  144. }
  145. }