ParticleEditor.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import * as THREE from "../../../../libs/three.js/build/three.module.js";
  2. import FireParticle from '../../objects/fireParticle/fire/FireParticle.js'
  3. import SmokeParticle from '../../objects/fireParticle/smoke/SmokeParticle.js'
  4. import ExplodeParticle from '../../objects/fireParticle/explode/ExplodeParticle.js'
  5. import CurveCtrl from '../../objects/tool/CurveCtrl.js'
  6. import {LineDraw} from "../../utils/DrawUtil.js";
  7. import Common from '../../utils/Common.js'
  8. import DepthBasicMaterial from "../../materials/DepthBasicMaterial.js";
  9. const colors = {
  10. 'fire+smoke':0xffffff,
  11. 'smoke': 0xffffff,
  12. 'explode':0xffffff,
  13. }
  14. let depthMatPrefix = {
  15. clipDistance : 100, occlusionDistance:60, /* 变为backColor距离 */
  16. maxClipFactor:0.5, backColor:"#777" ,
  17. useDepth:true, transparent: !0,
  18. }
  19. let lineMats;
  20. let getLineMat = function(type){
  21. if(!lineMats){
  22. lineMats = {
  23. 'fire+smoke':LineDraw.createFatLineMat($.extend(depthMatPrefix,{
  24. color: colors['fire+smoke'],
  25. lineWidth: 2
  26. })),
  27. 'smoke' :LineDraw.createFatLineMat($.extend(depthMatPrefix,{
  28. color: colors['smoke'],
  29. lineWidth: 2
  30. })),
  31. 'explode' :LineDraw.createFatLineMat($.extend(depthMatPrefix,{
  32. color: colors['explode'],
  33. lineWidth: 2
  34. })),
  35. }
  36. }
  37. return lineMats[type]
  38. }
  39. let handleMats
  40. let getHandleMat = function(type){
  41. if(!handleMats){
  42. let texLoader = new THREE.TextureLoader()
  43. handleMats = {
  44. "fire+smoke" : new DepthBasicMaterial($.extend(depthMatPrefix,{
  45. map: texLoader.load(Potree.resourcePath+'/textures/icon-fire.png' ),
  46. color: colors['fire+smoke'],
  47. })),
  48. "smoke" : new DepthBasicMaterial($.extend(depthMatPrefix,{
  49. map: texLoader.load(Potree.resourcePath+'/textures/icon-smoke.png' ),
  50. color: colors['smoke'],
  51. })),
  52. "explode" : new DepthBasicMaterial($.extend(depthMatPrefix,{
  53. map: texLoader.load(Potree.resourcePath+'/textures/icon-explode.png' ),
  54. color: colors['explode'],
  55. })),
  56. }
  57. }
  58. return handleMats[type]
  59. }
  60. let ParticleEditor = {
  61. bus: THREE.EventDispatcher,
  62. particleGroup : new THREE.Object3D ,
  63. curveGroup:new THREE.Object3D ,
  64. init:function(){
  65. this.particleGroup.name = 'particles'
  66. viewer.scene.scene.add( this.particleGroup );
  67. this.curveGroup.name = 'particles-curves'
  68. viewer.scene.scene.add( this.curveGroup );
  69. },
  70. addParticle : function(prop={}){
  71. let particle
  72. if(prop.type == 'fire'){
  73. particle = new FireParticle(prop)
  74. }else if(prop.type == 'smoke'){
  75. particle = new SmokeParticle(prop)
  76. }else if(prop.type == 'explode'){
  77. particle = new ExplodeParticle(prop)
  78. }
  79. this.particleGroup.add(particle)
  80. return particle
  81. }
  82. ,
  83. removeParticle(particle){
  84. //particle.dispatchEvent('delete')
  85. particle.dispose();
  86. this.particleGroup.remove(particle)
  87. particle.curve.dispose()
  88. }
  89. ,
  90. update(delta){
  91. this.particleGroup.children.forEach(e=>e.update(delta))
  92. }
  93. ,
  94. startInsertion(type = 'fire', prop={}){ //viewer.modules.ParticleEditor.startInsertion()
  95. let deferred = $.Deferred();
  96. let particles = [];
  97. let finish = (ifDone)=>{
  98. if(ifDone){
  99. deferred.resolve(particles)
  100. }
  101. viewer.dispatchEvent({
  102. type : "CursorChange", action : "remove", name:"addSth"
  103. });
  104. viewer.removeEventListener('global_click', click)
  105. this.bus.removeEventListener('cancel_insertions',cancel)
  106. }
  107. let curve = new CurveCtrl([], getLineMat(type), colors[type], type+'_curve', {handleMat:getHandleMat(type)} )
  108. this.curveGroup.add(curve)
  109. prop.curve = curve
  110. prop.type = type
  111. //console.log('创建curve',type,curve.uuid)
  112. let cancel = ()=>{
  113. console.log('cancel_insertions', curve.uuid )
  114. curve.dispose();
  115. finish(false)
  116. }
  117. this.bus.dispatchEvent('cancel_insertions')//删除旧的
  118. this.bus.addEventListener('cancel_insertions',cancel)
  119. var click = (e)=>{
  120. if(e.button === THREE.MOUSE.RIGHT){
  121. if(curve.points.length>=1){ //if(type.includes('fire') || type.includes('smoke') ){
  122. particles = this.createFromData(prop)
  123. finish(true)
  124. }
  125. return
  126. }
  127. var I = e.intersect && (e.intersect.orthoIntersect || e.intersect.location)
  128. if(!I)return
  129. curve.addPoint(I, null, true)
  130. if(type == 'explode'){
  131. particles = this.createFromData(prop)
  132. finish(true)
  133. }
  134. return {stopContinue:true}//防止继续执行别的侦听,如flytopano
  135. }
  136. viewer.addEventListener('global_click', click, 10)//add importance:10
  137. viewer.dispatchEvent({
  138. type : "CursorChange", action : "add", name:"addSth"
  139. });
  140. return deferred.promise()
  141. },
  142. createFromData(prop){
  143. const type = prop.type;
  144. var particles = []
  145. let curve = prop.curve;
  146. if(!curve){
  147. curve = new CurveCtrl(prop.points, getLineMat(type), colors[type], type+'_curve', {handleMat:getHandleMat(type)} )
  148. this.curveGroup.add(curve)
  149. }
  150. if(type.includes('fire') || type.includes('smoke') ){
  151. if(type.includes('fire')){
  152. var fire = this.addParticle({
  153. type : 'fire',
  154. positions : curve.points,
  155. curve,
  156. radius : prop.radius,
  157. height: prop.height,
  158. strength : prop.strength,
  159. })
  160. particles.push(fire)
  161. }
  162. if(type.includes('smoke')){
  163. var smoke = this.addParticle({
  164. type : 'smoke',
  165. positions : curve.points,
  166. curve,
  167. positionStyle : 'sphere' ,
  168. strength : prop.smokeStrength,
  169. radius: prop.smokeRadius,
  170. height: prop.smokeHeight,
  171. })
  172. particles.push(smoke)
  173. }
  174. }else if(type == 'explode'){
  175. var explode = this.addParticle({
  176. type : 'explode',
  177. position : curve.points[0],
  178. strength: prop.strength,
  179. radius : prop.radius,
  180. particleSpaceTime: prop.particleSpaceTime,
  181. curve,
  182. delayStartTime:prop.delayStartTime,
  183. })
  184. particles.push(explode)
  185. }
  186. var geoNeedsUpdate
  187. curve.addEventListener('dragCurvePoint',()=>{
  188. geoNeedsUpdate = true
  189. Common.intervalTool.isWaiting('particlePointChange', ()=>{ //延时update,防止卡顿
  190. if(geoNeedsUpdate){
  191. particles.forEach(e=>e.updateGeometry())
  192. geoNeedsUpdate = false
  193. curve.dispatchEvent('sendUpdatePoints')
  194. return true
  195. }
  196. }, 400)
  197. })
  198. return particles
  199. }
  200. }
  201. export default ParticleEditor