import * as THREE from "../../../../libs/three.js/build/three.module.js"; import FireParticle from '../../objects/fireParticle/fire/FireParticle.js' import SmokeParticle from '../../objects/fireParticle/smoke/SmokeParticle.js' import ExplodeParticle from '../../objects/fireParticle/explode/ExplodeParticle.js' import CurveCtrl from '../../objects/tool/CurveCtrl.js' import {LineDraw} from "../../utils/DrawUtil.js"; import Common from '../../utils/Common.js' import DepthBasicMaterial from "../../materials/DepthBasicMaterial.js"; const colors = { 'fire+smoke':0xffffff, 'smoke': 0xffffff, 'explode':0xffffff, } let depthMatPrefix = { clipDistance : 100, occlusionDistance:60, /* 变为backColor距离 */ maxClipFactor:0.5, backColor:"#777" , useDepth:true, transparent: !0, } let lineMats; let getLineMat = function(type){ if(!lineMats){ lineMats = { 'fire+smoke':LineDraw.createFatLineMat($.extend(depthMatPrefix,{ color: colors['fire+smoke'], lineWidth: 2 })), 'smoke' :LineDraw.createFatLineMat($.extend(depthMatPrefix,{ color: colors['smoke'], lineWidth: 2 })), 'explode' :LineDraw.createFatLineMat($.extend(depthMatPrefix,{ color: colors['explode'], lineWidth: 2 })), } } return lineMats[type] } let handleMats let getHandleMat = function(type){ if(!handleMats){ let texLoader = new THREE.TextureLoader() handleMats = { "fire+smoke" : new DepthBasicMaterial($.extend(depthMatPrefix,{ map: texLoader.load(Potree.resourcePath+'/textures/icon-fire.png' ), color: colors['fire+smoke'], })), "smoke" : new DepthBasicMaterial($.extend(depthMatPrefix,{ map: texLoader.load(Potree.resourcePath+'/textures/icon-smoke.png' ), color: colors['smoke'], })), "explode" : new DepthBasicMaterial($.extend(depthMatPrefix,{ map: texLoader.load(Potree.resourcePath+'/textures/icon-explode.png' ), color: colors['explode'], })), } } return handleMats[type] } let ParticleEditor = { bus: THREE.EventDispatcher, particleGroup : new THREE.Object3D , curveGroup:new THREE.Object3D , init:function(){ this.particleGroup.name = 'particles' viewer.scene.scene.add( this.particleGroup ); this.curveGroup.name = 'particles-curves' viewer.scene.scene.add( this.curveGroup ); }, addParticle : function(prop={}){ let particle if(prop.type == 'fire'){ particle = new FireParticle(prop) }else if(prop.type == 'smoke'){ particle = new SmokeParticle(prop) }else if(prop.type == 'explode'){ particle = new ExplodeParticle(prop) } this.particleGroup.add(particle) return particle } , removeParticle(particle){ //particle.dispatchEvent('delete') particle.dispose(); this.particleGroup.remove(particle) particle.curve.dispose() } , update(delta){ this.particleGroup.children.forEach(e=>e.update(delta)) } , startInsertion(type = 'fire', prop={}){ //viewer.modules.ParticleEditor.startInsertion() let deferred = $.Deferred(); let particles = []; let finish = (ifDone)=>{ if(ifDone){ deferred.resolve(particles) } viewer.dispatchEvent({ type : "CursorChange", action : "remove", name:"addSth" }); viewer.removeEventListener('global_click', click) this.bus.removeEventListener('cancel_insertions',cancel) } let curve = new CurveCtrl([], getLineMat(type), colors[type], type+'_curve', {handleMat:getHandleMat(type)} ) this.curveGroup.add(curve) prop.curve = curve prop.type = type //console.log('创建curve',type,curve.uuid) let cancel = ()=>{ console.log('cancel_insertions', curve.uuid ) curve.dispose(); finish(false) } this.bus.dispatchEvent('cancel_insertions')//删除旧的 this.bus.addEventListener('cancel_insertions',cancel) var click = (e)=>{ if(e.button === THREE.MOUSE.RIGHT){ if(curve.points.length>=1){ //if(type.includes('fire') || type.includes('smoke') ){ particles = this.createFromData(prop) finish(true) } return } var I = e.intersect && (e.intersect.orthoIntersect || e.intersect.location) if(!I)return curve.addPoint(I, null, true) if(type == 'explode'){ particles = this.createFromData(prop) finish(true) } return {stopContinue:true}//防止继续执行别的侦听,如flytopano } viewer.addEventListener('global_click', click, 10)//add importance:10 viewer.dispatchEvent({ type : "CursorChange", action : "add", name:"addSth" }); return deferred.promise() }, createFromData(prop){ const type = prop.type; var particles = [] let curve = prop.curve; if(!curve){ curve = new CurveCtrl(prop.points, getLineMat(type), colors[type], type+'_curve', {handleMat:getHandleMat(type)} ) this.curveGroup.add(curve) } if(type.includes('fire') || type.includes('smoke') ){ if(type.includes('fire')){ var fire = this.addParticle({ type : 'fire', positions : curve.points, curve, radius : prop.radius, height: prop.height, strength : prop.strength, }) particles.push(fire) } if(type.includes('smoke')){ var smoke = this.addParticle({ type : 'smoke', positions : curve.points, curve, positionStyle : 'sphere' , strength : prop.smokeStrength, radius: prop.smokeRadius, height: prop.smokeHeight, }) particles.push(smoke) } }else if(type == 'explode'){ var explode = this.addParticle({ type : 'explode', position : curve.points[0], strength: prop.strength, radius : prop.radius, particleSpaceTime: prop.particleSpaceTime, curve, delayStartTime:prop.delayStartTime, }) particles.push(explode) } var geoNeedsUpdate curve.addEventListener('dragCurvePoint',()=>{ geoNeedsUpdate = true Common.intervalTool.isWaiting('particlePointChange', ()=>{ //延时update,防止卡顿 if(geoNeedsUpdate){ particles.forEach(e=>e.updateGeometry()) geoNeedsUpdate = false curve.dispatchEvent('sendUpdatePoints') return true } }, 400) }) return particles } } export default ParticleEditor