Particles.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. from PandaModules import *
  2. from ParticleManagerGlobal import *
  3. from PhysicsManagerGlobal import *
  4. import ParticleSystem
  5. import BaseParticleFactory
  6. import PointParticleFactory
  7. import ZSpinParticleFactory
  8. import OrientedParticleFactory
  9. import BaseParticleRenderer
  10. import PointParticleRenderer
  11. import LineParticleRenderer
  12. import GeomParticleRenderer
  13. import SparkleParticleRenderer
  14. import SpriteParticleRenderer
  15. import BaseParticleEmitter
  16. import BoxEmitter
  17. import DiscEmitter
  18. import LineEmitter
  19. import PointEmitter
  20. import RectangleEmitter
  21. import RingEmitter
  22. import SphereSurfaceEmitter
  23. import SphereVolumeEmitter
  24. import TangentRingEmitter
  25. import string
  26. import os
  27. import DirectNotifyGlobal
  28. import sys
  29. class Particles(ParticleSystem.ParticleSystem):
  30. notify = DirectNotifyGlobal.directNotify.newCategory('Particles')
  31. id = 1
  32. def __init__(self, name=None, poolSize=1024):
  33. """__init__(name, poolSize)"""
  34. if (name == None):
  35. self.name = 'particles-%d' % Particles.id
  36. Particles.id += 1
  37. else:
  38. self.name = name
  39. ParticleSystem.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 = hidden.attachNewNode(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. self.node = None
  68. self.factory = None
  69. self.renderer = None
  70. self.emitter = None
  71. def enable(self):
  72. """enable()"""
  73. if (self.fEnabled == 0):
  74. physicsMgr.attachPhysical(self)
  75. particleMgr.attachParticlesystem(self)
  76. self.fEnabled = 1
  77. def disable(self):
  78. """disable()"""
  79. if (self.fEnabled == 1):
  80. physicsMgr.removePhysical(self)
  81. particleMgr.removeParticlesystem(self)
  82. self.fEnabled = 0
  83. def isEnabled(self):
  84. return self.fEnabled
  85. def getNode(self):
  86. return self.node
  87. def setFactory(self, type):
  88. """setFactory(type)"""
  89. if (self.factoryType == type):
  90. return None
  91. if (self.factory):
  92. self.factory = None
  93. self.factoryType = type
  94. if (type == "PointParticleFactory"):
  95. self.factory = PointParticleFactory.PointParticleFactory()
  96. elif (type == "ZSpinParticleFactory"):
  97. self.factory = ZSpinParticleFactory.ZSpinParticleFactory()
  98. elif (type == "OrientedParticleFactory"):
  99. self.factory = OrientedParticleFactory.OrientedParticleFactory()
  100. else:
  101. print "unknown factory type: %s" % type
  102. return None
  103. self.factory.setLifespanBase(0.5)
  104. ParticleSystem.ParticleSystem.setFactory(self, self.factory)
  105. def setRenderer(self, type):
  106. """setRenderer(type)"""
  107. if (self.rendererType == type):
  108. return None
  109. if (self.renderer):
  110. self.renderer = None
  111. self.rendererType = type
  112. if (type == "PointParticleRenderer"):
  113. self.renderer = PointParticleRenderer.PointParticleRenderer()
  114. self.renderer.setPointSize(1.0)
  115. elif (type == "LineParticleRenderer"):
  116. self.renderer = LineParticleRenderer.LineParticleRenderer()
  117. elif (type == "GeomParticleRenderer"):
  118. self.renderer = GeomParticleRenderer.GeomParticleRenderer()
  119. npath = hidden.attachNewNode(NamedNode('default-geom'))
  120. # This was moved here because we do not want to download
  121. # the direct tools with toontown.
  122. import DirectSelection
  123. bbox = DirectSelection.DirectBoundingBox(npath)
  124. self.renderer.setGeomNode(bbox.lines.node())
  125. elif (type == "SparkleParticleRenderer"):
  126. self.renderer = SparkleParticleRenderer.SparkleParticleRenderer()
  127. elif (type == "SpriteParticleRenderer"):
  128. self.renderer = SpriteParticleRenderer.SpriteParticleRenderer()
  129. if (self.renderer.getSourceType() ==
  130. SpriteParticleRenderer.SpriteParticleRenderer.STTexture):
  131. t = loader.loadTexture('phase_3/maps/eyes.jpg')
  132. if (t == None):
  133. print "Couldn't find default texture: evil_eye.rgb!"
  134. return None
  135. self.renderer.setTexture(t)
  136. else:
  137. # Use default model file and node
  138. # See SpriteParticleRenderer-extensions.py
  139. self.renderer.setTextureFromNode()
  140. else:
  141. print "unknown renderer type: %s" % type
  142. return None
  143. ParticleSystem.ParticleSystem.setRenderer(self, self.renderer)
  144. def setEmitter(self, type):
  145. """setEmitter(type)"""
  146. if (self.emitterType == type):
  147. return None
  148. if (self.emitter):
  149. self.emitter = None
  150. self.emitterType = type
  151. if (type == "BoxEmitter"):
  152. self.emitter = BoxEmitter.BoxEmitter()
  153. elif (type == "DiscEmitter"):
  154. self.emitter = DiscEmitter.DiscEmitter()
  155. elif (type == "LineEmitter"):
  156. self.emitter = LineEmitter.LineEmitter()
  157. elif (type == "PointEmitter"):
  158. self.emitter = PointEmitter.PointEmitter()
  159. elif (type == "RectangleEmitter"):
  160. self.emitter = RectangleEmitter.RectangleEmitter()
  161. elif (type == "RingEmitter"):
  162. self.emitter = RingEmitter.RingEmitter()
  163. elif (type == "SphereSurfaceEmitter"):
  164. self.emitter = SphereSurfaceEmitter.SphereSurfaceEmitter()
  165. elif (type == "SphereVolumeEmitter"):
  166. self.emitter = SphereVolumeEmitter.SphereVolumeEmitter()
  167. self.emitter.setRadius(1.0)
  168. elif (type == "TangentRingEmitter"):
  169. self.emitter = TangentRingEmitter.TangentRingEmitter()
  170. else:
  171. print "unknown emitter type: %s" % type
  172. return None
  173. ParticleSystem.ParticleSystem.setEmitter(self, self.emitter)
  174. def addForce(self, force):
  175. """addForce(force)"""
  176. if (force.isLinear()):
  177. self.addLinearForce(force)
  178. else:
  179. self.addAngularForce(force)
  180. def removeForce(self, force):
  181. """removeForce(force)"""
  182. if (force == None):
  183. self.notify.warning('removeForce() - force == None!')
  184. return
  185. if (force.isLinear()):
  186. self.removeLinearForce(force)
  187. else:
  188. self.removeAngularForce(force)
  189. def setRenderNodePath(self, nodePath):
  190. self.setRenderParent(nodePath.node())
  191. ## Getters ##
  192. def getName(self):
  193. """getName()"""
  194. return self.name
  195. def getFactory(self):
  196. """getFactory()"""
  197. return self.factory
  198. def getEmitter(self):
  199. """getEmitter()"""
  200. return self.emitter
  201. def getRenderer(self):
  202. """getRenderer()"""
  203. return self.renderer
  204. def printParams(self, file = sys.stdout, targ = 'self'):
  205. """printParams(file, targ)"""
  206. file.write('# Particles parameters\n')
  207. file.write(targ + '.setFactory(\"' + self.factoryType + '\")\n')
  208. file.write(targ + '.setRenderer(\"' + self.rendererType + '\")\n')
  209. file.write(targ + '.setEmitter(\"' + self.emitterType + '\")\n')
  210. # System parameters
  211. file.write(targ + ('.setPoolSize(%d)\n' %
  212. int(self.getPoolSize())))
  213. file.write(targ + ('.setBirthRate(%.4f)\n' %
  214. self.getBirthRate()))
  215. file.write(targ + ('.setLitterSize(%d)\n' %
  216. int(self.getLitterSize())))
  217. file.write(targ + ('.setLitterSpread(%d)\n' %
  218. self.getLitterSpread()))
  219. file.write(targ + ('.setSystemLifespan(%.4f)\n' %
  220. self.getSystemLifespan()))
  221. file.write(targ + ('.setLocalVelocityFlag(%d)\n' %
  222. self.getLocalVelocityFlag()))
  223. file.write(targ + ('.setSystemGrowsOlderFlag(%d)\n' %
  224. self.getSystemGrowsOlderFlag()))
  225. file.write('# Factory parameters\n')
  226. file.write(targ + ('.factory.setLifespanBase(%.4f)\n' %
  227. self.factory.getLifespanBase()))
  228. file.write(targ + '.factory.setLifespanSpread(%.4f)\n' % \
  229. self.factory.getLifespanSpread())
  230. file.write(targ + '.factory.setMassBase(%.4f)\n' % \
  231. self.factory.getMassBase())
  232. file.write(targ + '.factory.setMassSpread(%.4f)\n' % \
  233. self.factory.getMassSpread())
  234. file.write(targ + '.factory.setTerminalVelocityBase(%.4f)\n' % \
  235. self.factory.getTerminalVelocityBase())
  236. file.write(targ + '.factory.setTerminalVelocitySpread(%.4f)\n' % \
  237. self.factory.getTerminalVelocitySpread())
  238. if (self.factoryType == "PointParticleFactory"):
  239. file.write('# Point factory parameters\n')
  240. elif (self.factoryType == "ZSpinParticleFactory"):
  241. file.write('# Z Spin factory parameters\n')
  242. file.write(targ + '.factory.setInitialAngle(%.4f)\n' % \
  243. self.factory.getInitialAngle())
  244. file.write(targ + '.factory.setFinalAngle(%.4f)\n' % \
  245. self.factory.getFinalAngle())
  246. file.write(targ + '.factory.setInitialAngleSpread(%.4f)\n' % \
  247. self.factory.getInitialAngleSpread())
  248. file.write(targ + '.factory.setFinalAngleSpread(%.4f)\n' % \
  249. self.factory.getFinalAngleSpread())
  250. elif (self.factoryType == "OrientedParticleFactory"):
  251. file.write('# Oriented factory parameters\n')
  252. file.write(targ + '.factory.setInitialOrientation(%.4f)\n' % \
  253. self.factory.getInitialOrientation())
  254. file.write(targ + '.factory.setFinalOrientation(%.4f)\n' % \
  255. self.factory.getFinalOrientation())
  256. file.write('# Renderer parameters\n')
  257. alphaMode = self.renderer.getAlphaMode()
  258. aMode = "PRALPHANONE"
  259. if (alphaMode == BaseParticleRenderer.BaseParticleRenderer.PRALPHANONE):
  260. aMode = "PRALPHANONE"
  261. elif (alphaMode ==
  262. BaseParticleRenderer.BaseParticleRenderer.PRALPHAOUT):
  263. aMode = "PRALPHAOUT"
  264. elif (alphaMode ==
  265. BaseParticleRenderer.BaseParticleRenderer.PRALPHAIN):
  266. aMode = "PRALPHAIN"
  267. elif (alphaMode ==
  268. BaseParticleRenderer.BaseParticleRenderer.PRALPHAUSER):
  269. aMode = "PRALPHAUSER"
  270. file.write(targ + '.renderer.setAlphaMode(BaseParticleRenderer.' + aMode + ')\n')
  271. file.write(targ + '.renderer.setUserAlpha(%.2f)\n' % \
  272. self.renderer.getUserAlpha())
  273. if (self.rendererType == "Point"):
  274. file.write('# Point parameters\n')
  275. file.write(targ + '.renderer.setPointSize(%.2f)\n' % \
  276. self.renderer.getPointSize())
  277. sColor = self.renderer.getStartColor()
  278. file.write((targ + '.renderer.setStartColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
  279. sColor = self.renderer.getEndColor()
  280. file.write((targ + '.renderer.setEndColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
  281. blendType = self.renderer.getBlendType()
  282. bType = "PPONECOLOR"
  283. if (blendType == PointParticleRenderer.PointParticleRenderer.PPONECOLOR):
  284. bType = "PPONECOLOR"
  285. elif (blendType == PointParticleRenderer.PointParticleRenderer.PPBLENDLIFE):
  286. bType = "PPBLENDLIFE"
  287. elif (blendType == PointParticleRenderer.PointParticleRenderer.PPBLENDVEL):
  288. bType = "PPBLENDVEL"
  289. file.write(targ + '.renderer.setBlendType(PointParticleRenderer.' + bType + ')\n')
  290. blendMethod = self.renderer.getBlendMethod()
  291. bMethod = "PPNOBLEND"
  292. if (blendMethod == BaseParticleRenderer.BaseParticleRenderer.PPNOBLEND):
  293. bMethod = "PPNOBLEND"
  294. elif (blendMethod == BaseParticleRenderer.BaseParticleRenderer.PPBLENDLINEAR):
  295. bMethod = "PPBLENDLINEAR"
  296. elif (blendMethod == BaseParticleRenderer.BaseParticleRenderer.PPBLENDCUBIC):
  297. bMethod = "PPBLENDCUBIC"
  298. file.write(targ + '.renderer.setBlendMethod(BaseParticleRenderer.' + bMethod + ')\n')
  299. elif (self.rendererType == "LineParticleRenderer"):
  300. file.write('# Line parameters\n')
  301. sColor = self.renderer.getHeadColor()
  302. file.write((targ + '.renderer.setHeadColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
  303. sColor = self.renderer.getTailColor()
  304. file.write((targ + '.renderer.setTailColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
  305. elif (self.rendererType == "GeomParticleRenderer"):
  306. file.write('# Geom parameters\n')
  307. node = self.renderer.getGeomNode()
  308. file.write(targ + '.renderer.setGeomNode(' + node.getName() + ')\n')
  309. elif (self.rendererType == "SparkleParticleRenderer"):
  310. file.write('# Sparkle parameters\n')
  311. sColor = self.renderer.getCenterColor()
  312. file.write((targ + '.renderer.setCenterColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
  313. sColor = self.renderer.getEdgeColor()
  314. file.write((targ + '.renderer.setEdgeColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
  315. file.write(targ + '.renderer.setBirthRadius(%.4f)\n' % self.renderer.getBirthRadius())
  316. file.write(targ + '.renderer.setDeathRadius(%.4f)\n' % self.renderer.getDeathRadius())
  317. lifeScale = self.renderer.getLifeScale()
  318. lScale = "SPNOSCALE"
  319. if (lifeScale == SparkleParticleRenderer.SparkleParticleRenderer.SPSCALE):
  320. lScale = "SPSCALE"
  321. file.write(targ + '.renderer.setLifeScale(SparkleParticleRenderer.' + lScale + ')\n')
  322. elif (self.rendererType == "SpriteParticleRenderer"):
  323. file.write('# Sprite parameters\n')
  324. if (self.renderer.getSourceType() ==
  325. SpriteParticleRenderer.SpriteParticleRenderer.STTexture):
  326. tex = self.renderer.getTexture()
  327. file.write(targ + '.renderer.setTexture(loader.loadTexture(\'' + tex.getName() + '\'))\n')
  328. else:
  329. modelName = self.renderer.getSourceFileName()
  330. nodeName = self.renderer.getSourceNodeName()
  331. file.write(targ + '.renderer.setTextureFromNode("%s", "%s")\n' % (modelName, nodeName))
  332. sColor = self.renderer.getColor()
  333. file.write((targ + '.renderer.setColor(Vec4(%.2f, %.2f, %.2f, %.2f))\n' % (sColor[0], sColor[1], sColor[2], sColor[3])))
  334. file.write(targ + '.renderer.setXScaleFlag(%d)\n' % self.renderer.getXScaleFlag())
  335. file.write(targ + '.renderer.setYScaleFlag(%d)\n' % self.renderer.getYScaleFlag())
  336. file.write(targ + '.renderer.setAnimAngleFlag(%d)\n' % self.renderer.getAnimAngleFlag())
  337. file.write(targ + '.renderer.setInitialXScale(%.4f)\n' % self.renderer.getInitialXScale())
  338. file.write(targ + '.renderer.setFinalXScale(%.4f)\n' % self.renderer.getFinalXScale())
  339. file.write(targ + '.renderer.setInitialYScale(%.4f)\n' % self.renderer.getInitialYScale())
  340. file.write(targ + '.renderer.setFinalYScale(%.4f)\n' % self.renderer.getFinalYScale())
  341. file.write(targ + '.renderer.setNonanimatedTheta(%.4f)\n' % self.renderer.getNonanimatedTheta())
  342. blendMethod = self.renderer.getAlphaBlendMethod()
  343. bMethod = "PPNOBLEND"
  344. if (blendMethod == BaseParticleRenderer.BaseParticleRenderer.PPNOBLEND):
  345. bMethod = "PPNOBLEND"
  346. elif (blendMethod == BaseParticleRenderer.BaseParticleRenderer.PPBLENDLINEAR):
  347. bMethod = "PPBLENDLINEAR"
  348. elif (blendMethod == BaseParticleRenderer.BaseParticleRenderer.PPBLENDCUBIC):
  349. bMethod = "PPBLENDCUBIC"
  350. file.write(targ + '.renderer.setAlphaBlendMethod(BaseParticleRenderer.' + bMethod + ')\n')
  351. file.write(targ + '.renderer.setAlphaDisable(%d)\n' % self.renderer.getAlphaDisable())
  352. file.write('# Emitter parameters\n')
  353. emissionType = self.emitter.getEmissionType()
  354. eType = "ETEXPLICIT"
  355. if (emissionType == BaseParticleEmitter.BaseParticleEmitter.ETEXPLICIT):
  356. eType = "ETEXPLICIT"
  357. elif (emissionType == BaseParticleEmitter.BaseParticleEmitter.ETRADIATE):
  358. eType = "ETRADIATE"
  359. elif (emissionType == BaseParticleEmitter.BaseParticleEmitter.ETCUSTOM):
  360. eType = "ETCUSTOM"
  361. file.write(targ + '.emitter.setEmissionType(BaseParticleEmitter.' + eType + ')\n')
  362. file.write(targ + '.emitter.setAmplitude(%.4f)\n' % self.emitter.getAmplitude())
  363. file.write(targ + '.emitter.setAmplitudeSpread(%.4f)\n' % self.emitter.getAmplitudeSpread())
  364. oForce = self.emitter.getOffsetForce()
  365. file.write((targ + '.emitter.setOffsetForce(Vec3(%.4f, %.4f, %.4f))\n' % (oForce[0], oForce[1], oForce[2])))
  366. oForce = self.emitter.getExplicitLaunchVector()
  367. file.write((targ + '.emitter.setExplicitLaunchVector(Vec3(%.4f, %.4f, %.4f))\n' % (oForce[0], oForce[1], oForce[2])))
  368. orig = self.emitter.getRadiateOrigin()
  369. file.write((targ + '.emitter.setRadiateOrigin(Point3(%.4f, %.4f, %.4f))\n' % (orig[0], orig[1], orig[2])))
  370. if (self.emitterType == "BoxEmitter"):
  371. file.write('# Box parameters\n')
  372. bound = self.emitter.getMinBound()
  373. file.write((targ + '.emitter.setMinBound(Point3(%.4f, %.4f, %.4f))\n' % (bound[0], bound[1], bound[2])))
  374. bound = self.emitter.getMaxBound()
  375. file.write((targ + '.emitter.setMaxBound(Point3(%.4f, %.4f, %.4f))\n' % (bound[0], bound[1], bound[2])))
  376. elif (self.emitterType == "DiscEmitter"):
  377. file.write('# Disc parameters\n')
  378. file.write(targ + '.emitter.setRadius(%.4f)\n' % self.emitter.getRadius())
  379. if (eType == "ETCUSTOM"):
  380. file.write(targ + '.emitter.setOuterAngle(%.4f)\n' % self.emitter.getOuterAngle())
  381. file.write(targ + '.emitter.setInnerAngle(%.4f)\n' % self.emitter.getInnerAngle())
  382. file.write(targ + '.emitter.setOuterMagnitude(%.4f)\n' % self.emitter.getOuterMagnitude())
  383. file.write(targ + '.emitter.setInnerMagnitude(%.4f)\n' % self.emitter.getInnerMagnitude())
  384. file.write(targ + '.emitter.setCubicLerping(%d)\n' % self.emitter.getCubicLerping())
  385. elif (self.emitterType == "LineEmitter"):
  386. file.write('# Line parameters\n')
  387. point = self.emitter.getEndpoint1()
  388. file.write((targ + '.emitter.setEndpoint1(Point3(%.4f, %.4f, %.4f))\n' % (point[0], point[1], point[2])))
  389. point = self.emitter.getEndpoint2()
  390. file.write((targ + '.emitter.setEndpoint2(Point3(%.4f, %.4f, %.4f))\n' % (point[0], point[1], point[2])))
  391. elif (self.emitterType == "PointEmitter"):
  392. file.write('# Point parameters\n')
  393. point = self.emitter.getLocation()
  394. file.write((targ + '.emitter.setLocation(Point3(%.4f, %.4f, %.4f))\n' % (point[0], point[1], point[2])))
  395. elif (self.emitterType == "RectangleEmitter"):
  396. file.write('# Rectangle parameters\n')
  397. bound = self.emitter.getMinBound()
  398. file.write((targ + '.emitter.setMinBound(Point2(%.4f, %.4f))\n' % (point[0], point[1])))
  399. bound = self.emitter.getMaxBound()
  400. file.write((targ + '.emitter.setMaxBound(Point2(%.4f, %.4f))\n' % (point[0], point[1])))
  401. elif (self.emitterType == "RingEmitter"):
  402. file.write('# Ring parameters\n')
  403. file.write(targ + '.emitter.setRadius(%.4f)\n' % self.emitter.getRadius())
  404. if (eType == "ETCUSTOM"):
  405. file.write(targ + '.emitter.setAngle(%.4f)\n' % self.emitter.getAngle())
  406. elif (self.emitterType == "SphereSurfaceEmitter"):
  407. file.write('# Sphere Surface parameters\n')
  408. file.write(targ + '.emitter.setRadius(%.4f)\n' % self.emitter.getRadius())
  409. elif (self.emitterType == "SphereVolumeEmitter"):
  410. file.write('# Sphere Volume parameters\n')
  411. file.write(targ + '.emitter.setRadius(%.4f)\n' % self.emitter.getRadius())
  412. elif (self.emitterType == "TangentRingEmitter"):
  413. file.write('# Tangent Ring parameters\n')
  414. file.write(targ + '.emitter.setRadius(%.4f)\n' % self.emitter.getRadius())