Saturday, 21 May 2011

Moar better collision detection.

Up until now, the only collision detection between the player's ship and the environment had been with the main outline of the world generated by the initial brush carving, which is a relatively simple shape. However, for a properly completed environment there will also be a lot flair (decorative) objects adorning the environment, and it's also important to be able to collide with them.

In addition, the laser impact effects have also been updated, with the impact explosion orientation now being determined by the normal of the impacted surface. It also kicks up some debris particle effects, although these are currently the same regardless of the surface type being hit, and thus look odd for some of the alien flora.

Flair intersection

There were two parts to getting this to work, both of which drew heavily on my existing codebase for creating and merging vector brushes (which has held up surprisingly well, given that there are a few bits that could really do with improving).

The first part is, for a given 2D (or basic 3D) mesh, generating a 2D vector brush of the outline. This abridged version is as follows:
  1. Identify all edges within the mesh. This is something that needs calculating, as by default meshes are stored in terms of vertices/triangles.
  2. Identify the set of triangles that use each edge (the set must at least of size 1, else where the hell did the edge come from?) 
  3. Determine whether each edge is potentially part of the outline.  If an edge has only one triangle associated with it, then it's always an outline edge.  For multiple triangles, it is an outline edge if the third point of each triangle (i.e. that not part of the edge) all lie on the same side of the line.
  4. Throw out all the non-outline-edge edges. 
  5. Starting on any outline edge, following connected edges around until you come back to the original edge in a loop.  In normal situations (apart from some awkward 3D configurations) there will never be any branching to worry about that.  Add that as a vector path.
  6. Repeat 5. for any currently unused outline edges until all are accounted for.
  7. Merge the set of vector paths together to form the final outline (which is a whole different bunch of algorithms).
Then, once you've generated the vector brushes for all the flair objects, you can then merge them together, and then again with the main world outline brush in order to produce the final collision geometry. Finally, take that geometry and generate a binary tree from it in order to allow efficent intersections. 

Friday, 20 May 2011

Rapture Investment Opportunity!

So, if there's anyone out there who believes that the Rapture is going to occur tomorrow, I'd like to offer the last minute opportunity to divest yourself of some wealth and give it to a cheerful heathen.  Not only will it aid indie game development, but by reducing your level of wealth you may help avoid the camel/eye of a needle/Heaven problem*.

*Warning: money not returned in the unlikely event that Rapture does not occur.

Sunday, 15 May 2011

Progress Update

Oops, it's been over a week since the last update! Time really does fly when you're coding away.

OK, the main things I've been working on over the last week or so are as follows:

Player/World collision

This is now basically done, along with player ship damage and particle effects at collision points. The particle effects are a mixture of sparks and rock being disturbed from the walls, which looks quite nice when scraping along the side. It also need a good corresponding sound effect!

There's still some tidying up and improvement to do on this aspect, but it's sufficient for now.  Have a peek:


Scripting zones

In order to make a game with an interesting and interactive world, there need to be scriptable zones within the world that can do a variety of things, from bringing up a certain story conversation, spawning some enemies, changing world states (e.g. opening/closing doors) and a lot of other things. The basic scripting capability now exists, and is embedded within the main global asset management system.  At the moment its capabilities are pretty limited, but these will rapidly expand as I add more scripting interfaces.

Upgraded collision detection

For anyone unfamiliar with collision detection, the basic problem is one of testing your game object's bounding shape (a circle, in the simple case) against all the objects in the world. Now, if you have 10000 primitives (e.g. lines/triangles) in your world, the easiest way is just to test directly against each of the 10000 objects, leading to 10000 geometry tests per object. However, using a hierarchical (tree-based) model you can achieve this in around Log2(10000) = 13 tests, allowing much greater efficiency. Even better, if you increase the number of primitives by a factor of 2, you'll only need one more test. This scaling allows testing against very complex world geometry in an efficient fashion.

Anyway, something that's been niggling at me since I upgraded to using the physics engine is the old hierarchical collision detection, which used a binary tree in order to calculate collisions with each triangle in the world mesh.

However, in reality, using all the triangles was quite wasteful and pointless, as the only important bits are the lines that form the outline of the world itself, and the corresponding bounding circles/bounding boxes were much larger than they needed to be. Since the world is carved from an overall vector brush, though, this outline is directly available, and thus I've refactored the code to produce a collision tree from a set of lines rather than triangles, leading to an overall improvement in efficiency and niceness. This is one of those things that won't have any directly visible effect, but makes further development easier.