import * as THREE from "../../../libs/three.js/build/three.module.js"; import DepthBasicMaterial from "../materials/DepthBasicMaterial.js"; import math from "../utils/math.js"; const geo = new THREE.PlaneBufferGeometry(1,1) export default class Sprite extends THREE.Mesh{ constructor(options){ super(geo, options.mat || new DepthBasicMaterial(options))/* ({map:options.map, useDepth:options.useDepth})) */ this.root = options.root || this; this.renderOrder = options.renderOrder != void 0 ? options.renderOrder : 4; this.pickOrder = options.pickOrder || 0 this.sizeInfo = options.sizeInfo this.dontFixOrient = options.dontFixOrient this.root.matrixAutoUpdate = false; this.matrixMap = new Map() this.name = options.name || 'sprite' this.useViewport = null this.viewports = options.viewports//指定更新的viewports this.visible_ = true let update = (e)=>{ this.update(e) } viewer.mapViewer && viewer.mapViewer.addEventListener("camera_changed", update) viewer.addEventListener("camera_changed", update) /* if(viewer.viewports.length == 1){//直接更新。如果有多个不在这更新,在"render.begin" this.update(e) } */ let applyMatrix = (e)=>{ this.applyMatrix(e) } viewer.addEventListener("raycaster", applyMatrix) //before render viewer.addEventListener("render.begin", applyMatrix) //before render //magnifier时要禁止吗 this.addEventListener('dispose', ()=>{ viewer.mapViewer && viewer.mapViewer.removeEventListener("camera_changed", update) viewer.removeEventListener("camera_changed", update) viewer.removeEventListener("raycaster", applyMatrix) //before render viewer.removeEventListener("render.begin", applyMatrix) this.dispose() }) } set visible(v){ this.visible_ = v if(v){ this.update() } } get visible(){ return this.visible_ } realVisible(){ let v = true let parent = this let lastParent while(parent){ if(parent.visible === false){ v = false break; } lastParent = parent parent = parent.parent } if(v && !(lastParent instanceof THREE.Scene)){//已被删除 v = false } if(!this.latestRealVisi && v){//变为可见后先update this.latestRealVisi = true setTimeout(()=>{ this.update() },1)//延迟 防止无限调用 return false } this.latestRealVisi = v return v; } update(e){ if(!e){ let viewports = this.viewports || viewer.viewports if(!viewports)return viewports.forEach(view=>{ this.update({viewport:view}) }) return; } if(!this.root || ! this.realVisible() /* this.visible */ )return if(this.viewports && !this.viewports.includes(e.viewport) )return if(e.viewport.name == 'magnifier')return let camera = e.viewport.camera //rotation if(!this.dontFixOrient){ //orthoCamera一般要加dontFixOrient let parentQua = this.root.parent.getWorldQuaternion(new THREE.Quaternion) this.root.quaternion.multiplyQuaternions(parentQua.invert(),camera.quaternion) //乘上parentQua.invert()是为了中和掉父结点的qua,使只剩下camera.quaternion } //scale var info = this.sizeInfo if(info){ this.root.updateMatrix();//先更新,getWorldPosition才能得到正确的 this.root.updateMatrixWorld(true) var scale if(info.restricMeshScale){//仅限制最大或最小的话,不判断像素大小,直接限制mesh的scale var dis = camera.position.distanceTo(this.root.getWorldPosition(new THREE.Vector3())) if(dis < info.nearBound){ scale = info.scale * dis / info.nearBound }else{ scale = info.scale } }else{ scale = math.getScaleForConstantSize($.extend(info,{//规定下最小最大像素 camera , position:this.root.getWorldPosition(new THREE.Vector3()) , resolution: e.viewport.resolution//2 })) } if(!isNaN(scale)){ this.root.scale.set(scale, scale, scale); } } this.root.updateMatrix(); this.root.updateMatrixWorld(true) this.matrixMap.set(e.viewport, this.root.matrix.clone()) this.useViewport = e.viewport } applyMatrix(e){ if(!e)e = {viewport:viewer.mainViewport}//随便写一个viewport if(e.viewport.name == 'magnifier')return if(this.viewports && !this.viewports.includes(e.viewport) )return if( !this.root || !this.realVisible() )return var matrix = this.matrixMap.get(e.viewport); if(!matrix){ this.update(e) matrix = this.matrixMap.get(e.viewport); } if(e.viewport == this.useViewport){ return } this.useViewport = e.viewport this.root.matrix.copy(matrix) this.root.updateMatrixWorld(true) //console.log(this.root.name + e.viewport.name + " : "+this.root.matrixWorld.elements) } setUniforms(name,value){ this.material.setUniforms(name,value) } dispose(){ this.removeAllListeners() this.parent && this.parent.remove(this) } }