Particles: Effects or Home-made?

In a situation involving numerous bursts of small numbers of particles (weapons-fire impacts and the like, for the most part, I think), is it more advisable to generate and handle the desired particles myself (presumably using CardMaker, setting a billboard effect and updating and killing them in my main update), or to generate Panda Particle Effects for each impact?

(I have also thought about keeping a single emitter per material type, and simply moving it about and instructing it to issue bursts of particles as desired, but I’m not sure of how well this is likely to work…)

What advice have you?

My thanks for any aid given. :slight_smile:

I’ve got similar doubts.

I decided to make “special effects” with pre-rendered particles on single, animated billboards because it runs smoother then with particles (on my machine).

Most have 256x256 or 128x64 and 10-30 frames, with 10-12 of these in my scene I’m seeing no noticeable slow down, particle effect that look more or less the same (using mostly 16x16 particles or smaller) had a tendency to drop the fps from 70 to 14 (especially on close-up, don’t know why) even with just one emitter.

The down side is that some effects that are easy to make with real particles are very hard to do on one billboard unless it’s really big (like rising smoke) or impossible (like the simple “smoke ring” from the particle demo).

If you want to do the particles without particles I recommend Particle Illusions (there’s a 30 day trial version with no restrictions).

My game has lots of things like this. In fact i found panda3d’s particle system to inflexible. For that i wrote meshDrawer:

Thank you very much, treeform - I recall seeing mention of MeshDrawer, but hadn’t looked into it yet, and had perhaps forgotten it.

I’ll hopefully start using it tonight. :slight_smile:

All right, I have a few questions regarding MeshDrawer, and it seemed reasonable to keep them in here. (Although the above-linked thread may also have been a good idea… :/)

First, based on my fiddling with the sample linked-to above, and my reading of the reference, I don’t see a way to hold on to my particles: as soon as a new set is generated, the old seem to be removed. How might I create persistent particles?

Second, I also don’t see a way to access - or at least animate - my particles: I don’t see methods or parameters to control particle movement, life or transparency, the generation methods don’t seem to return anything, and there doesn’t seem to be an explicit listing method; should I call getRoot and iterate over its children, or is there another way?

My thanks for any help given. :slight_smile:

You can see how the sample does it
Mesh drawer is ment to be drawn too in every frame. So you would keep track of all your particles in a list or some thing and just redraw them every frame. You can also animate them, you can do any thing you want really.

I have updated the sample to show how you can hold on to the particles in an array and then animate them using global clock time.

If you have any other suggestions to the sample please feel free to commit it into the repo.

Aah, I see, thank you! :slight_smile:

I somehow got it into my head that MeshDrawer handled more than just the… well… drawing of meshes.

You know, when I type it like that, it seems especially silly. :stuck_out_tongue:

Hmm… re-generated every frame? If I may ask, wouldn’t it be more efficient to keep a list of generated geometry and provide access to it, presumably reducing the overhead?

[edit] Oh, and I forgot to say thank you for the new sample, both for the sample itself and for taking the time to do it: thank you! :slight_smile: [/edit]

Yes it would in some cases…

I create mesh drawer for my needs of rapidly regenerating the data like ship positions, what they are fireing, who they are aiming etc…

For my needs it would take the same amount of work to update all those positions and parameters then just to pass them in all the time. I have though about such system, but it has to be flexible enough to handle my case and tons of other cases. It would take more C++ code then just simple meshDrawer. Surprisingly meshDrawer works for my needs right now.

I use meshDrawer for drawing lines, icons and other radar things, i also use meshDrawer for drawing treeGUI. MeshDrawer is for drawing some other C++ particle system has to be written to do what you ask, or you can do it in python in the mean time like i do.

Fair enough, and thank you for the explanation.

Alas, I’m hitting trouble again.

I’ve thus far managed to create a simple particle system along the lines of your sample, and ma reasonably happy with the results thus far.

However, I just tried to implement a lightning bolt using the same basis, and am experiencing a crash. Specifically, there seems to be no error reported in SPE’s console, and I get a Windows message indicating that Python has crashed.

A little experimenting has indicated that the crash appears to occur on the second call to linkSegment.

What might be the problem, do you think? :confused:

My code follows (with some comments and formatting added; please forgive any formatting issues):

#Generating a "lightning bolt":
   endPt = Vec3(self.firingQueue.getEntry(0).getSurfacePoint(render))
   startPt = self.rayPath.getPos(render)

   shotPoints = []

   diff = endPt - startPt
   numPoints = diff.lengthSquared()/5.0

   if numPoints > 2:
       diff *= 5.0
       for j in range(int(numPoints)):
           startPt += diff
       # Elements (I think):
       # [0] = list of points
       # [1] = frame
       # [2] = thickness
       # [3] = colour
       # [4] = lifetime
       shots.append((shotPoints, 3, 0.4, Vec4(1, 1, 1, 1), 0.8))

# Later...

   return shots


#In my update method:
   newLightning = []
   for lightning in self.lightning:
      # A new individual is created since tuples
      #  apparently don't support element assignment...
      # Elements (I think):
      # [0] = list of points
      # [1] = frame
      # [2] = thickness
      # [3] = colour
      # [4] = lifetime
      newIndividualLightning = (lightning[0], lightning[1], lightning[2], lightning[3], lightning[4]-dt)
      if newIndividualLightning[4] > 0.0:
         # for each point, create a new linked segment
         for point in newIndividualLightning[0]:
                       Vec3(random.random()-0.5, random.random()-0.5, random.random()-0.5)*2.0,
                                       newIndividualLightning[2], newIndividualLightning[3])
          self.generator.linkSegmentEnd(newIndividualLightning[1], newIndividualLightning[3])
   self.lightning = newLightning