import * as THREE from "../../../libs/three.js/build/three.module.js"; import BasicMaterial from '../materials/BasicMaterial.js' const planeGeometry = new THREE.PlaneBufferGeometry(1,1) const height4dkk = 0.5 //4dkk的planeGeometry高度 let texLoader = new THREE.TextureLoader() import FlvVideoPlayerBase from '../utils/media/FlvVideoPlayerBase' import H5VideoPlayerBase from '../utils/media/H5VideoPlayerBase' const videoPlayer = Potree.browser.nonsupportH5Video ? new FlvVideoPlayerBase() : new H5VideoPlayerBase() export default class Overlay extends THREE.Object3D { constructor(data){ super() this.data = data var plane = new THREE.Mesh( planeGeometry, new BasicMaterial({ color: '#00c8af', opacity: 0.2, transparent: !0, polygonOffset: true, //是否开启多边形偏移 //ie不开启时blank也不会闪烁 polygonOffsetFactor: -0.9, //多边形偏移因子 polygonOffsetUnits: -4.0, //多边形偏移单位 }) ) this.add(plane) this.plane = plane this.setContent( data.media[0], data.url, data.isNew) //this.setScale(data.width, data.height) this.scale.set(data.width||1, data.height||1, 1) //需要把width转化一下吗,还是后端转化? data.reverse && (this.scale.x *= -1) this.addEventListener('dispose',this.dispose.bind(this)) let updatePlayInSight = ()=>{ Common.intervalTool.isWaiting('updatePlayInSight', ()=>{ Overlay.updatePlayInSight() },500) } this.addEventListener('isVisible',updatePlayInSight) this.addEventListener('transformChanged',updatePlayInSight) } setContent(type, src, autoSize){ this.mediaType = type let loadDone = ()=>{ autoSize && this.autoSize() this.plane.material.uniforms.color.value = new THREE.Color('#fff') this.plane.material.opacity = 1 } if(type == 'photo'){ this.plane.material.map = texLoader.load(src, loadDone) }else{ var video = videoPlayer.getVideo(src,this) this.addEventListener('loadedmetadata', loadDone) /* var video = $(``)[0] video.setAttribute("crossOrigin", 'Anonymous')//要在src设置好前解决跨域 video.src = src video.onloadeddata = loadDone */ video.play() this.plane.material.map = new THREE.VideoTexture(video) Potree.Common.mobileAutoPlay(video, ()=>{ if(!this.disposed){ video.play() } }) } } autoSize(){//根据素材改变长宽 let size = this.getMediaSize() if(size.x > 0 && size.y > 0){ let area = this.plane.scale.x * this.plane.scale.y let r = Math.sqrt(area / (size.x * size.y)) this.scale.x = size.x * r this.scale.y = size.y * r } this.dispatchEvent('scale_changed') } getMediaSize(){ let size = new THREE.Vector2; let media = this.plane.material.map.image if(media){ if(this.mediaType == 'photo'){ size.x = media.width; size.y = media.height; }else{ size.x = media.videoWidth size.y = media.videoHeight } } return size } dispose(){ //geo和mat已经在mergeEditor里删了,这要删一下video啥的吗? let index = viewer.scene.overlays.indexOf(this) if(index == -1)return viewer.scene.overlays.splice(index,1) if(this.mediaType == 'video'){ let media = this.plane.material.map.image media?.pause() this.disposed = true } } videoControl(state){ var video = this.plane.material.map.image if(!video)return this.shouldPlay = state if (!state || state == 'stop') { if (!video.paused){ video.pause() console.log('videoControl paused ') } }else if(state) { if (video.paused){ console.log('videoControl play ') //video = this.loadVideo() video.play() } } } static updatePlayInSight(){ const min = 0.15//最小可播放尺寸(屏幕宽高都是2) let camera = viewer.mainViewport.camera let camDir = viewer.mainViewport.view.direction let frustumMatrix = new THREE.Matrix4 frustumMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse) let frustum = new THREE.Frustum(); frustum.setFromProjectionMatrix(frustumMatrix) let insight = (overlay)=>{ if(overlay.plane.material.side!=2){ //side为0 let dir = overlay.plane.getWorldDirection(new THREE.Vector3) if(dir.dot(camDir)>0 ){ console.log('dir.dot(camDir)',dir.dot(camDir)) return false } //可能看到背面。若能看到正面,视线方向和plane朝向必定为钝角 } let bound = overlay.bound.clone() let insight = frustum.intersectsBox(bound ) if(!insight)return false bound.applyMatrix4(frustumMatrix); //project on screen let boundSize = bound.getSize(new THREE.Vector3) if(boundSize.x < min && boundSize.y < min){ //console.log('too small', boundSize) return false } return true } viewer.scene.overlays.forEach(overlay=>{ if(overlay.mediaType != 'video')return let shouldPlay = overlay.realVisible() && insight(overlay) overlay.videoControl(shouldPlay) }) } }