Collision in a world of rapid-fire weapons

(This may previously have been answered here; I did search, but may well have missed the appropriate key-words. My apologies if this is so.)

I’m currently working on a small space-like shooter, and have run into a bit of a problem with my weapons.

I originally had each weapons-fire object contain a “from” object, handled (as I recall) by a CollisionHandlerEvent object. This worked well enough, and allowed me to happily collide them with both enemies and my environment, as long as I had only a few shots on-screen at once.

Once I introduced a rapid-fire weapon, however, I found that my frame-rate dropped significantly.

My first solution after investigating through PStats was to rework the system such that weapons-fire objects became “into” objects, with the player and enemies being the “from” objects. While this did indeed improve performance, as I recall, it also introduced another problem: projectiles were now, of course, no longer colliding with the environment.

I had a shot (so to speak ^^; ) at making the environmental colliders “from” objects, but it seems to me that there are potential speed problems there as well (given that that means either many small objects, or one very large object), and I would likely want to use either CollisionTubes (the current representation) or CollisionPolygons, neither of which are valid “from” objects, it seems.

Does anyone have a suggestion for handling numerous projectiles (such as might come from a handful of enemies each bearing rapid-fire weapons) efficiently? Have I perhaps missed some simple solution?

My thanks for any help. :slight_smile:

[edit]
From this old thread:

(Emphasis mine)

Is the above-bolded text still true?

What about casting rays? - each frame a ‘bullet’ casts a ray in its direction of travel - if it hits anything it finds the closest object and checks if its within this frames travel distance - if it is you have impact, otherwise move the bullet that far and do the same next frame. Its obviously more work for you, but casting rays is very cheap. You do of course lose the ability for a bullet to be side swiped by another object, but then I imagine rapid fire means rapid movement anyway, making that not very likely and certainly not perceivable by the player.

The solution might be as simple as restructuring your environment to reflect a good hierarchy, so that bounding volume tests can effectively short-circuit large parts of the scene graph. This way, each bullet will only need to test against a relatively small part of the scene, so it won’t matter if there are lots of bullets flying at once.

David

Thank you both for your responses. :slight_smile:

I think that you may be right, drwr - I should probably have a look at the structure of my environment. Do you have any tips, or a mannual page that I might have a look at (I did take a look, but found little that seemed relevant to this issue)?

Search the forums for ‘octree’, there are scripts to restructure your scene in such a way that its highly optimized for collisions.

It would be nice if we had some tuning tips for collisions in the manual, but alas, at the moment there is nothing.

Your hierarchy should be structured sensibly so that at each node there are just a handful of children, and the bounding volumes of each of these children are distinct from each other. Each child node should in turn contain only a handful of children, and each of these children should have a distinct bounding volume.

Think about the way the collision traverser works: it walks through the scene graph in a depth-first traversal. Imagine for now that you have only one “from” object. (The traverser can handle several at once, but this is more complicated and not important to understand the problem.) At each node, it compares that node’s bounding volume with the bounding volume of your “from” object. Any node that does not intersect with the “from” object gets pruned from the traversal, and its children are not visited. If there are hundreds of collision solids somewhere below the node, then you have just made a huge savings in the collision cost. Clearly, this algorithm is most effective when the scene graph structure reflects the geographic arrangement of objects in your scene.

Also see raytaller’s “Egg Octree” thread for a tool that can separate out your environment hierarchy automatically.

David

Aah, thank you both for pointing me to the octree tool (or tools, as the case may be; I haven’t yet searched), and thank you drwr for the explanation. :slight_smile:

As it happens, I seem to have run into some gameplay issues which to some degree override this issue for me (especially as I’m now re-thinking my environment for gameplay reasons). Nevertheless, I’m glad to have learned these points - perhaps I should make a moment to transfer them to the manual, so that others might more easily find them…

Out of curiosity, am I correct in thinking now that (sans using an octree tool) it would be more efficient to distribute an otherwise flat hierarchy under a level of empty NodePaths that specify only position (presuming that they were clustered based on bounding volume, with no overlaps between sets)?

I’m not 100% sure what you’re describing here, but that sounds like the right idea generally. It’s not even necessary to have any position transforms on the parent NodePaths, nor is it vitally important that there is no overlap at all; the point is just to group together collections of collision solids based on their common location.

David

Aah, fair enough, and thanks - I appreciate the clarification. :slight_smile:

wow also me i appreciate the clarification… :slight_smile:


combat knife lover