Particles.py 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. from pandac.PandaModules import *
  2. from ParticleManagerGlobal import *
  3. from direct.showbase.PhysicsManagerGlobal import *
  4. from pandac.PandaModules import ParticleSystem
  5. from pandac.PandaModules import BaseParticleFactory
  6. from pandac.PandaModules import PointParticleFactory
  7. from pandac.PandaModules import ZSpinParticleFactory
  8. #from pandac.PandaModules import OrientedParticleFactory
  9. from pandac.PandaModules import BaseParticleRenderer
  10. from pandac.PandaModules import PointParticleRenderer
  11. from pandac.PandaModules import LineParticleRenderer
  12. from pandac.PandaModules import GeomParticleRenderer
  13. from pandac.PandaModules import SparkleParticleRenderer
  14. #from pandac.PandaModules import SpriteParticleRenderer
  15. from pandac.PandaModules import BaseParticleEmitter
  16. from pandac.PandaModules import BoxEmitter
  17. from pandac.PandaModules import DiscEmitter
  18. from pandac.PandaModules import LineEmitter
  19. from pandac.PandaModules import PointEmitter
  20. from pandac.PandaModules import RectangleEmitter
  21. from pandac.PandaModules import RingEmitter
  22. from pandac.PandaModules import SphereSurfaceEmitter
  23. from pandac.PandaModules import SphereVolumeEmitter
  24. from pandac.PandaModules import TangentRingEmitter
  25. import SpriteParticleRendererExt
  26. import string
  27. import os
  28. from direct.directnotify import DirectNotifyGlobal
  29. import sys
  30. class Particles(ParticleSystem):
  31. notify = DirectNotifyGlobal.directNotify.newCategory('Particles')
  32. id = 1
  33. def __init__(self, name=None, poolSize=1024):
  34. if (name == None):
  35. self.name = 'particles-%d' % Particles.id
  36. Particles.id += 1
  37. else:
  38. self.name = name
  39. ParticleSystem.__init__(self, poolSize)
  40. # self.setBirthRate(0.02)
  41. # self.setLitterSize(10)
  42. # self.setLitterSpread(0)
  43. # Set up a physical node
  44. self.node = PhysicalNode(self.name)
  45. self.nodePath = NodePath(self.node)
  46. self.setRenderParent(self.node)
  47. self.node.addPhysical(self)
  48. self.factory = None
  49. self.factoryType = "undefined"
  50. # self.setFactory("PointParticleFactory")
  51. self.renderer = None
  52. self.rendererType = "undefined"
  53. # self.setRenderer("PointParticleRenderer")
  54. self.emitter = None
  55. self.emitterType = "undefined"
  56. # self.setEmitter("SphereVolumeEmitter")
  57. # Enable particles by default
  58. self.fEnabled = 0
  59. #self.enable()
  60. def cleanup(self):
  61. self.disable()
  62. self.clearLinearForces()
  63. self.clearAngularForces()
  64. self.setRenderParent(self.node)
  65. self.node.removePhysical(self)
  66. self.nodePath.removeNode()
  67. del self.node
  68. del self.nodePath
  69. del self.factory
  70. del self.renderer
  71. del self.emitter
  72. def enable(self):
  73. if (self.fEnabled == 0):
  74. physicsMgr.attachPhysical(self)
  75. particleMgr.attachParticlesystem(self)
  76. self.fEnabled = 1
  77. def disable(self):
  78. if (self.fEnabled == 1):
  79. physicsMgr.removePhysical(self)
  80. particleMgr.removeParticlesystem(self)
  81. self.fEnabled = 0
  82. def isEnabled(self):
  83. return self.fEnabled
  84. def getNode(self):
  85. return self.node
  86. def setFactory(self, type):
  87. if (self.factoryType == type):
  88. return None
  89. if (self.factory):
  90. self.factory = None
  91. self.factoryType = type
  92. if (type == "PointParticleFactory"):
  93. self.factory = PointParticleFactory()
  94. elif (type == "ZSpinParticleFactory"):
  95. self.factory = ZSpinParticleFactory()
  96. elif (type == "OrientedParticleFactory"):
  97. self.factory = OrientedParticleFactory()
  98. else:
  99. print "unknown factory type: %s" % type
  100. return None
  101. self.factory.setLifespanBase(0.5)
  102. ParticleSystem.setFactory(self, self.factory)
  103. def setRenderer(self, type):
  104. if (self.rendererType == type):
  105. return None
  106. if (self.renderer):
  107. self.renderer = None
  108. self.rendererType = type
  109. if (type == "PointParticleRenderer"):
  110. self.renderer = PointParticleRenderer()
  111. self.renderer.setPointSize(1.0)
  112. elif (type == "LineParticleRenderer"):
  113. self.renderer = LineParticleRenderer()
  114. elif (type == "GeomParticleRenderer"):
  115. self.renderer = GeomParticleRenderer()
  116. # This was moved here because we do not want to download
  117. # the direct tools with toontown.
  118. if __dev__:
  119. from direct.directtools import DirectSelection
  120. npath = NodePath('default-geom')
  121. bbox = DirectSelection.DirectBoundingBox(npath)
  122. self.renderer.setGeomNode(bbox.lines.node())
  123. elif (type == "SparkleParticleRenderer"):
  124. self.renderer = SparkleParticleRenderer()
  125. elif (type == "SpriteParticleRenderer"):
  126. self.renderer = SpriteParticleRendererExt.SpriteParticleRendererExt()
  127. self.renderer.setTextureFromFile()
  128. else:
  129. print "unknown renderer type: %s" % type
  130. return None
  131. ParticleSystem.setRenderer(self, self.renderer)
  132. def setEmitter(self, type):
  133. """setEmitter(type)"""
  134. if (self.emitterType == type):
  135. return None
  136. if (self.emitter):
  137. self.emitter = None
  138. self.emitterType = type
  139. if (type == "BoxEmitter"):
  140. self.emitter = BoxEmitter()
  141. elif (type == "DiscEmitter"):
  142. self.emitter = DiscEmitter()
  143. elif (type == "LineEmitter"):
  144. self.emitter = LineEmitter()
  145. elif (type == "PointEmitter"):
  146. self.emitter = PointEmitter()
  147. elif (type == "RectangleEmitter"):
  148. self.emitter = RectangleEmitter()
  149. elif (type == "RingEmitter"):
  150. self.emitter = RingEmitter()
  151. elif (type == "SphereSurfaceEmitter"):
  152. self.emitter = SphereSurfaceEmitter()
  153. elif (type == "SphereVolumeEmitter"):
  154. self.emitter = SphereVolumeEmitter()
  155. self.emitter.setRadius(1.0)
  156. elif (type == "TangentRingEmitter"):
  157. self.emitter = TangentRingEmitter()
  158. else:
  159. print "unknown emitter type: %s" % type
  160. return None
  161. ParticleSystem.setEmitter(self, self.emitter)
  162. def addForce(self, force):
  163. if (force.isLinear()):
  164. self.addLinearForce(force)
  165. else:
  166. self.addAngularForce(force)
  167. def removeForce(self, force):
  168. if (force == None):
  169. self.notify.warning('removeForce() - force == None!')
  170. return
  171. if (force.isLinear()):
  172. self.removeLinearForce(force)
  173. else:
  174. self.removeAngularForce(force)
  175. def setRenderNodePath(self, nodePath):
  176. self.setRenderParent(nodePath.node())
  177. ## Getters ##
  178. def getName(self):
  179. return self.name
  180. def getFactory(self):
  181. return self.factory
  182. def getEmitter(self):
  183. return self.emitter
  184. def getRenderer(self):
  185. return self.renderer
  186. def printParams(self, file = sys.stdout, targ = 'self'):
  187. file.write('# Particles parameters\n')
  188. file.write(targ + '.setFactory(\"' + self.factoryType + '\")\n')
  189. file.write(targ + '.setRenderer(\"' + self.rendererType + '\")\n')
  190. file.write(targ + '.setEmitter(\"' + self.emitterType + '\")\n')
  191. # System parameters
  192. file.write(targ + ('.setPoolSize(%d)\n' %
  193. int(self.getPoolSize())))
  194. file.write(targ + ('.setBirthRate(%.4f)\n' %
  195. self.getBirthRate()))
  196. file.write(targ + ('.setLitterSize(%d)\n' %
  197. int(self.getLitterSize())))
  198. file.write(targ + ('.setLitterSpread(%d)\n' %
  199. self.getLitterSpread()))
  200. file.write(targ + ('.setSystemLifespan(%.4f)\n' %
  201. self.getSystemLifespan()))
  202. file.write(targ + ('.setLocalVelocityFlag(%d)\n' %
  203. self.getLocalVelocityFlag()))
  204. file.write(targ + ('.setSystemGrowsOlderFlag(%d)\n' %
  205. self.getSystemGrowsOlderFlag()))
  206. file.write('# Factory parameters\n')
  207. file.write(targ + ('.factory.setLifespanBase(%.4f)\n' %
  208. self.factory.getLifespanBase()))
  209. file.write(targ + '.factory.setLifespanSpread(%.4f)\n' % \
  210. self.factory.getLifespanSpread())
  211. file.write(targ + '.factory.setMassBase(%.4f)\n' % \
  212. self.factory.getMassBase())
  213. file.write(targ + '.factory.setMassSpread(%.4f)\n' % \
  214. self.factory.getMassSpread())
  215. file.write(targ + '.factory.setTerminalVelocityBase(%.4f)\n' % \
  216. self.factory.getTerminalVelocityBase())
  217. file.write(targ + '.factory.setTerminalVelocitySpread(%.4f)\n' % \
  218. self.factory.getTerminalVelocitySpread())
  219. if (self.factoryType == "PointParticleFactory"):
  220. file.write('# Point factory parameters\n')
  221. elif (self.factoryType == "ZSpinParticleFactory"):
  222. file.write('# Z Spin factory parameters\n')
  223. file.write(targ + '.factory.setInitialAngle(%.4f)\n' % \
  224. self.factory.getInitialAngle())
  225. file.write(targ + '.factory.setInitialAngleSpread(%.4f)\n' % \
  226. self.factory.getInitialAngleSpread())
  227. file.write(targ + '.factory.enableAngularVelocity(%d)\n' % \
  228. self.factory.getAngularVelocityEnabled())
  229. if(self.factory.getAngularVelocityEnabled()):
  230. file.write(targ + '.factory.setAngularVelocity(%.4f)\n' % \
  231. self.factory.getAngularVelocity())
  232. file.write(targ + '.factory.setAngularVelocitySpread(%.4f)\n' % \
  233. self.factory.getAngularVelocitySpread())
  234. else:
  235. file.write(targ + '.factory.setFinalAngle(%.4f)\n' % \
  236. self.factory.getFinalAngle())
  237. file.write(targ + '.factory.setFinalAngleSpread(%.4f)\n' % \
  238. self.factory.getFinalAngleSpread())
  239. elif (self.factoryType == "OrientedParticleFactory"):
  240. file.write('# Oriented factory parameters\n')
  241. file.write(targ + '.factory.setInitialOrientation(%.4f)\n' % \
  242. self.factory.getInitialOrientation())
  243. file.write(targ + '.factory.setFinalOrientation(%.4f)\n' % \
  244. self.factory.getFinalOrientation())
  245. file.write('# Renderer parameters\n')
  246. alphaMode = self.renderer.getAlphaMode()
  247. aMode = "PRALPHANONE"
  248. if (alphaMode == BaseParticleRenderer.PRALPHANONE):
  249. aMode = "PRALPHANONE"
  250. elif (alphaMode == BaseParticleRenderer.PRALPHAOUT):
  251. aMode = "PRALPHAOUT"
  252. elif (alphaMode == BaseParticleRenderer.PRALPHAIN):
  253. aMode = "PRALPHAIN"
  254. elif (alphaMode == BaseParticleRenderer.PRALPHAINOUT):
  255. aMode = "PRALPHAINOUT"
  256. elif (alphaMode == BaseParticleRenderer.PRALPHAUSER):
  257. aMode = "PRALPHAUSER"
  258. file.write(targ + '.renderer.setAlphaMode(BaseParticleRenderer.' + aMode + ')\n')
  259. file.write(targ + '.renderer.setUserAlpha(%.2f)\n' % \
  260. self.renderer.getUserAlpha())
  261. if (self.rendererType == "PointParticleRenderer"):
  262. file.write('# Point parameters\n')
  263. file.write(targ + '.renderer.setPointSize(%.2f)\n' % \
  264. self.renderer.getPointSize())
  265. sColor = self.renderer.getStartColor()
  266. file.write((targ + '.renderer.setStartColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
  267. sColor = self.renderer.getEndColor()
  268. file.write((targ + '.renderer.setEndColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
  269. blendType = self.renderer.getBlendType()
  270. bType = "PPONECOLOR"
  271. if (blendType == PointParticleRenderer.PPONECOLOR):
  272. bType = "PPONECOLOR"
  273. elif (blendType == PointParticleRenderer.PPBLENDLIFE):
  274. bType = "PPBLENDLIFE"
  275. elif (blendType == PointParticleRenderer.PPBLENDVEL):
  276. bType = "PPBLENDVEL"
  277. file.write(targ + '.renderer.setBlendType(PointParticleRenderer.' + bType + ')\n')
  278. blendMethod = self.renderer.getBlendMethod()
  279. bMethod = "PPNOBLEND"
  280. if (blendMethod == BaseParticleRenderer.PPNOBLEND):
  281. bMethod = "PPNOBLEND"
  282. elif (blendMethod == BaseParticleRenderer.PPBLENDLINEAR):
  283. bMethod = "PPBLENDLINEAR"
  284. elif (blendMethod == BaseParticleRenderer.PPBLENDCUBIC):
  285. bMethod = "PPBLENDCUBIC"
  286. file.write(targ + '.renderer.setBlendMethod(BaseParticleRenderer.' + bMethod + ')\n')
  287. elif (self.rendererType == "LineParticleRenderer"):
  288. file.write('# Line parameters\n')
  289. sColor = self.renderer.getHeadColor()
  290. file.write((targ + '.renderer.setHeadColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
  291. sColor = self.renderer.getTailColor()
  292. file.write((targ + '.renderer.setTailColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
  293. elif (self.rendererType == "GeomParticleRenderer"):
  294. file.write('# Geom parameters\n')
  295. node = self.renderer.getGeomNode()
  296. file.write(targ + '.renderer.setGeomNode(' + node.getName() + ')\n')
  297. cbmLut = ('MNone','MAdd','MSubtract','MInvSubtract','MMin','MMax')
  298. cboLut = ('OZero','OOne','OIncomingColor','OOneMinusIncomingColor','OFbufferColor',
  299. 'OOneMinusFbufferColor','OIncomingAlpha','OOneMinusIncomingAlpha',
  300. 'OFbufferAlpha','OOneMinusFbufferAlpha','OConstantColor',
  301. 'OOneMinusConstantColor','OConstantAlpha','OOneMinusConstantAlpha',
  302. 'OIncomingColorSaturate')
  303. cbAttrib = self.renderer.getRenderNode().getAttrib(ColorBlendAttrib.getClassType())
  304. if(cbAttrib):
  305. cbMode = cbAttrib.getMode()
  306. if(cbMode > 0):
  307. if(cbMode in (ColorBlendAttrib.MAdd,ColorBlendAttrib.MSubtract,ColorBlendAttrib.MInvSubtract)):
  308. cboa = cbAttrib.getOperandA()
  309. cbob = cbAttrib.getOperandB()
  310. file.write(targ+'.renderer.setColorBlendMode(ColorBlendAttrib.%s,ColorBlendAttrib.%s,ColorBlendAttrib.%s)\n' %
  311. (cbmLut[cbMode],cboLut[cboa],cboLut[cbob]))
  312. else:
  313. file.write(targ+'.renderer.setColorBlendMode(ColorBlendAttrib.%s)\n' % cbmLut[cbMode])
  314. cim = self.renderer.getColorInterpolationManager()
  315. segIdList = eval('['+cim.getSegmentIdList().replace(' ',', ')+']')
  316. for sid in segIdList:
  317. seg = cim.getSegment(sid)
  318. if seg.isEnabled():
  319. t_b = seg.getTimeBegin()
  320. t_e = seg.getTimeEnd()
  321. fun = seg.getFunction()
  322. typ = type(fun).__name__
  323. if typ == 'ColorInterpolationFunctionConstant':
  324. c_a = fun.getColorA()
  325. file.write(targ+'.renderer.getColorInterpolationManager().addConstant('+`t_b`+','+`t_e`+','+ \
  326. 'Vec4('+`c_a[0]`+','+`c_a[1]`+','+`c_a[2]`+','+`c_a[3]`+'))\n')
  327. elif typ == 'ColorInterpolationFunctionLinear':
  328. c_a = fun.getColorA()
  329. c_b = fun.getColorB()
  330. file.write(targ+'.renderer.getColorInterpolationManager().addLinear('+`t_b`+','+`t_e`+','+ \
  331. 'Vec4('+`c_a[0]`+','+`c_a[1]`+','+`c_a[2]`+','+`c_a[3]`+'),' + \
  332. 'Vec4('+`c_b[0]`+','+`c_b[1]`+','+`c_b[2]`+','+`c_b[3]`+'))\n')
  333. elif typ == 'ColorInterpolationFunctionStepwave':
  334. c_a = fun.getColorA()
  335. c_b = fun.getColorB()
  336. w_a = fun.getWidthA()
  337. w_b = fun.getWidthB()
  338. file.write(targ+'.renderer.getColorInterpolationManager().addStepwave('+`t_b`+','+`t_e`+','+ \
  339. 'Vec4('+`c_a[0]`+','+`c_a[1]`+','+`c_a[2]`+','+`c_a[3]`+'),' + \
  340. 'Vec4('+`c_b[0]`+','+`c_b[1]`+','+`c_b[2]`+','+`c_b[3]`+'),' + \
  341. `w_a`+','+`w_b`+')\n')
  342. elif typ == 'ColorInterpolationFunctionSinusoid':
  343. c_a = fun.getColorA()
  344. c_b = fun.getColorB()
  345. per = fun.getPeriod()
  346. file.write(targ+'.renderer.getColorInterpolationManager().addSinusoid('+`t_b`+','+`t_e`+','+ \
  347. 'Vec4('+`c_a[0]`+','+`c_a[1]`+','+`c_a[2]`+','+`c_a[3]`+'),' + \
  348. 'Vec4('+`c_b[0]`+','+`c_b[1]`+','+`c_b[2]`+','+`c_b[3]`+'),' + \
  349. `per`+')\n')
  350. elif (self.rendererType == "SparkleParticleRenderer"):
  351. file.write('# Sparkle parameters\n')
  352. sColor = self.renderer.getCenterColor()
  353. file.write((targ + '.renderer.setCenterColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
  354. sColor = self.renderer.getEdgeColor()
  355. file.write((targ + '.renderer.setEdgeColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
  356. file.write(targ + '.renderer.setBirthRadius(%.4f)\n' % self.renderer.getBirthRadius())
  357. file.write(targ + '.renderer.setDeathRadius(%.4f)\n' % self.renderer.getDeathRadius())
  358. lifeScale = self.renderer.getLifeScale()
  359. lScale = "SPNOSCALE"
  360. if (lifeScale == SparkleParticleRenderer.SPSCALE):
  361. lScale = "SPSCALE"
  362. file.write(targ + '.renderer.setLifeScale(SparkleParticleRenderer.' + lScale + ')\n')
  363. elif (self.rendererType == "SpriteParticleRenderer"):
  364. file.write('# Sprite parameters\n')
  365. if (self.renderer.getAnimateFramesEnable()):
  366. file.write(targ + '.renderer.setAnimateFramesEnable(True)\n')
  367. rate = self.renderer.getAnimateFramesRate()
  368. if(rate):
  369. file.write(targ + '.renderer.setAnimationFrameRate(%.3f)\n'%rate)
  370. animCount = self.renderer.getNumAnims()
  371. for x in range(animCount):
  372. anim = self.renderer.getAnim(x)
  373. if(anim.getSourceType() == SpriteAnim.STTexture):
  374. file.write(targ + '.renderer.%sTexture(loader.loadTexture(\'%s\'))\n' % ((x>0 and 'add' or 'set',)[0], anim.getTexSource()))
  375. else:
  376. file.write(targ + '.renderer.%sTextureFromNode(\'%s\',\'%s\')\n' % ((x>0 and 'add' or 'set',)[0], anim.getModelSource(), anim.getNodeSource()))
  377. sColor = self.renderer.getColor()
  378. file.write((targ + '.renderer.setColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
  379. file.write(targ + '.renderer.setXScaleFlag(%d)\n' % self.renderer.getXScaleFlag())
  380. file.write(targ + '.renderer.setYScaleFlag(%d)\n' % self.renderer.getYScaleFlag())
  381. file.write(targ + '.renderer.setAnimAngleFlag(%d)\n' % self.renderer.getAnimAngleFlag())
  382. file.write(targ + '.renderer.setInitialXScale(%.4f)\n' % self.renderer.getInitialXScale())
  383. file.write(targ + '.renderer.setFinalXScale(%.4f)\n' % self.renderer.getFinalXScale())
  384. file.write(targ + '.renderer.setInitialYScale(%.4f)\n' % self.renderer.getInitialYScale())
  385. file.write(targ + '.renderer.setFinalYScale(%.4f)\n' % self.renderer.getFinalYScale())
  386. file.write(targ + '.renderer.setNonanimatedTheta(%.4f)\n' % self.renderer.getNonanimatedTheta())
  387. blendMethod = self.renderer.getAlphaBlendMethod()
  388. bMethod = "PPNOBLEND"
  389. if (blendMethod == BaseParticleRenderer.PPNOBLEND):
  390. bMethod = "PPNOBLEND"
  391. elif (blendMethod == BaseParticleRenderer.PPBLENDLINEAR):
  392. bMethod = "PPBLENDLINEAR"
  393. elif (blendMethod == BaseParticleRenderer.PPBLENDCUBIC):
  394. bMethod = "PPBLENDCUBIC"
  395. file.write(targ + '.renderer.setAlphaBlendMethod(BaseParticleRenderer.' + bMethod + ')\n')
  396. file.write(targ + '.renderer.setAlphaDisable(%d)\n' % self.renderer.getAlphaDisable())
  397. # Save the color blending to file
  398. cbmLut = ('MNone','MAdd','MSubtract','MInvSubtract','MMin','MMax')
  399. cboLut = ('OZero','OOne','OIncomingColor','OOneMinusIncomingColor','OFbufferColor',
  400. 'OOneMinusFbufferColor','OIncomingAlpha','OOneMinusIncomingAlpha',
  401. 'OFbufferAlpha','OOneMinusFbufferAlpha','OConstantColor',
  402. 'OOneMinusConstantColor','OConstantAlpha','OOneMinusConstantAlpha',
  403. 'OIncomingColorSaturate')
  404. cbAttrib = self.renderer.getRenderNode().getAttrib(ColorBlendAttrib.getClassType())
  405. if(cbAttrib):
  406. cbMode = cbAttrib.getMode()
  407. if(cbMode > 0):
  408. if(cbMode in (ColorBlendAttrib.MAdd,ColorBlendAttrib.MSubtract,ColorBlendAttrib.MInvSubtract)):
  409. cboa = cbAttrib.getOperandA()
  410. cbob = cbAttrib.getOperandB()
  411. file.write(targ+'.renderer.setColorBlendMode(ColorBlendAttrib.%s,ColorBlendAttrib.%s,ColorBlendAttrib.%s)\n' %
  412. (cbmLut[cbMode],cboLut[cboa],cboLut[cbob]))
  413. else:
  414. file.write(targ+'.renderer.setColorBlendMode(ColorBlendAttrib.%s)\n' % cbmLut[cbMode])
  415. cim = self.renderer.getColorInterpolationManager()
  416. segIdList = eval('['+cim.getSegmentIdList().replace(' ',', ')+']')
  417. for sid in segIdList:
  418. seg = cim.getSegment(sid)
  419. if seg.isEnabled():
  420. t_b = seg.getTimeBegin()
  421. t_e = seg.getTimeEnd()
  422. fun = seg.getFunction()
  423. typ = type(fun).__name__
  424. if typ == 'ColorInterpolationFunctionConstant':
  425. c_a = fun.getColorA()
  426. file.write(targ+'.renderer.getColorInterpolationManager().addConstant('+`t_b`+','+`t_e`+','+ \
  427. 'Vec4('+`c_a[0]`+','+`c_a[1]`+','+`c_a[2]`+','+`c_a[3]`+'))\n')
  428. elif typ == 'ColorInterpolationFunctionLinear':
  429. c_a = fun.getColorA()
  430. c_b = fun.getColorB()
  431. file.write(targ+'.renderer.getColorInterpolationManager().addLinear('+`t_b`+','+`t_e`+','+ \
  432. 'Vec4('+`c_a[0]`+','+`c_a[1]`+','+`c_a[2]`+','+`c_a[3]`+'),' + \
  433. 'Vec4('+`c_b[0]`+','+`c_b[1]`+','+`c_b[2]`+','+`c_b[3]`+'))\n')
  434. elif typ == 'ColorInterpolationFunctionStepwave':
  435. c_a = fun.getColorA()
  436. c_b = fun.getColorB()
  437. w_a = fun.getWidthA()
  438. w_b = fun.getWidthB()
  439. file.write(targ+'.renderer.getColorInterpolationManager().addStepwave('+`t_b`+','+`t_e`+','+ \
  440. 'Vec4('+`c_a[0]`+','+`c_a[1]`+','+`c_a[2]`+','+`c_a[3]`+'),' + \
  441. 'Vec4('+`c_b[0]`+','+`c_b[1]`+','+`c_b[2]`+','+`c_b[3]`+'),' + \
  442. `w_a`+','+`w_b`+')\n')
  443. elif typ == 'ColorInterpolationFunctionSinusoid':
  444. c_a = fun.getColorA()
  445. c_b = fun.getColorB()
  446. per = fun.getPeriod()
  447. file.write(targ+'.renderer.getColorInterpolationManager().addSinusoid('+`t_b`+','+`t_e`+','+ \
  448. 'Vec4('+`c_a[0]`+','+`c_a[1]`+','+`c_a[2]`+','+`c_a[3]`+'),' + \
  449. 'Vec4('+`c_b[0]`+','+`c_b[1]`+','+`c_b[2]`+','+`c_b[3]`+'),' + \
  450. `per`+')\n')
  451. file.write('# Emitter parameters\n')
  452. emissionType = self.emitter.getEmissionType()
  453. eType = "ETEXPLICIT"
  454. if (emissionType == BaseParticleEmitter.ETEXPLICIT):
  455. eType = "ETEXPLICIT"
  456. elif (emissionType == BaseParticleEmitter.ETRADIATE):
  457. eType = "ETRADIATE"
  458. elif (emissionType == BaseParticleEmitter.ETCUSTOM):
  459. eType = "ETCUSTOM"
  460. file.write(targ + '.emitter.setEmissionType(BaseParticleEmitter.' + eType + ')\n')
  461. file.write(targ + '.emitter.setAmplitude(%.4f)\n' % self.emitter.getAmplitude())
  462. file.write(targ + '.emitter.setAmplitudeSpread(%.4f)\n' % self.emitter.getAmplitudeSpread())
  463. oForce = self.emitter.getOffsetForce()
  464. file.write((targ + '.emitter.setOffsetForce(Vec3(%.4f, %.4f, %.4f))\n' % (oForce[0], oForce[1], oForce[2])))
  465. oForce = self.emitter.getExplicitLaunchVector()
  466. file.write((targ + '.emitter.setExplicitLaunchVector(Vec3(%.4f, %.4f, %.4f))\n' % (oForce[0], oForce[1], oForce[2])))
  467. orig = self.emitter.getRadiateOrigin()
  468. file.write((targ + '.emitter.setRadiateOrigin(Point3(%.4f, %.4f, %.4f))\n' % (orig[0], orig[1], orig[2])))
  469. if (self.emitterType == "BoxEmitter"):
  470. file.write('# Box parameters\n')
  471. bound = self.emitter.getMinBound()
  472. file.write((targ + '.emitter.setMinBound(Point3(%.4f, %.4f, %.4f))\n' % (bound[0], bound[1], bound[2])))
  473. bound = self.emitter.getMaxBound()
  474. file.write((targ + '.emitter.setMaxBound(Point3(%.4f, %.4f, %.4f))\n' % (bound[0], bound[1], bound[2])))
  475. elif (self.emitterType == "DiscEmitter"):
  476. file.write('# Disc parameters\n')
  477. file.write(targ + '.emitter.setRadius(%.4f)\n' % self.emitter.getRadius())
  478. if (eType == "ETCUSTOM"):
  479. file.write(targ + '.emitter.setOuterAngle(%.4f)\n' % self.emitter.getOuterAngle())
  480. file.write(targ + '.emitter.setInnerAngle(%.4f)\n' % self.emitter.getInnerAngle())
  481. file.write(targ + '.emitter.setOuterMagnitude(%.4f)\n' % self.emitter.getOuterMagnitude())
  482. file.write(targ + '.emitter.setInnerMagnitude(%.4f)\n' % self.emitter.getInnerMagnitude())
  483. file.write(targ + '.emitter.setCubicLerping(%d)\n' % self.emitter.getCubicLerping())
  484. elif (self.emitterType == "LineEmitter"):
  485. file.write('# Line parameters\n')
  486. point = self.emitter.getEndpoint1()
  487. file.write((targ + '.emitter.setEndpoint1(Point3(%.4f, %.4f, %.4f))\n' % (point[0], point[1], point[2])))
  488. point = self.emitter.getEndpoint2()
  489. file.write((targ + '.emitter.setEndpoint2(Point3(%.4f, %.4f, %.4f))\n' % (point[0], point[1], point[2])))
  490. elif (self.emitterType == "PointEmitter"):
  491. file.write('# Point parameters\n')
  492. point = self.emitter.getLocation()
  493. file.write((targ + '.emitter.setLocation(Point3(%.4f, %.4f, %.4f))\n' % (point[0], point[1], point[2])))
  494. elif (self.emitterType == "RectangleEmitter"):
  495. file.write('# Rectangle parameters\n')
  496. point = self.emitter.getMinBound()
  497. file.write((targ + '.emitter.setMinBound(Point2(%.4f, %.4f))\n' % (point[0], point[1])))
  498. point = self.emitter.getMaxBound()
  499. file.write((targ + '.emitter.setMaxBound(Point2(%.4f, %.4f))\n' % (point[0], point[1])))
  500. elif (self.emitterType == "RingEmitter"):
  501. file.write('# Ring parameters\n')
  502. file.write(targ + '.emitter.setRadius(%.4f)\n' % self.emitter.getRadius())
  503. if (eType == "ETCUSTOM"):
  504. file.write(targ + '.emitter.setAngle(%.4f)\n' % self.emitter.getAngle())
  505. elif (self.emitterType == "SphereSurfaceEmitter"):
  506. file.write('# Sphere Surface parameters\n')
  507. file.write(targ + '.emitter.setRadius(%.4f)\n' % self.emitter.getRadius())
  508. elif (self.emitterType == "SphereVolumeEmitter"):
  509. file.write('# Sphere Volume parameters\n')
  510. file.write(targ + '.emitter.setRadius(%.4f)\n' % self.emitter.getRadius())
  511. elif (self.emitterType == "TangentRingEmitter"):
  512. file.write('# Tangent Ring parameters\n')
  513. file.write(targ + '.emitter.setRadius(%.4f)\n' % self.emitter.getRadius())