• entries
    222
  • comments
    608
  • views
    588284

Goodness Gracious, Great Balls of Lava

Sign in to follow this  
benryves

745 views

I've reworked the VM completely to use an array of a union of a float and an int, rather than the MemoryStream kludge I was using before. This also removes a lot of the multiply-or-divide-by-four mess I had with converting indices to positions within the memory stream.

There are (as far as I know) three ways to invoke QuakeC methods. The first is when an entity is spawned, and this is only valid when the level is being loaded (the function that matches the entity's classname is called). The second is when an entity is touched (its touch function is called) and the third is when its internal timer, nextthink, fires (its think function is called).

The third is the easiest one to start with. On a monster-free level, there are still "thinking" items - every powerup item has droptofloor() scheduled to run.

A strange feature of custom levels has been that all of the power-up items have been floating in mid-air.



By hacking together some crude collision detection (face bouncing boxes and axial planes only) I could make those objects sit in the right place:



With many thanks to Zipster pointing me in the right direction I have extended this to perform collision detection of a moving vertex against all world faces.



Here I fire a vertex (with a lava ball drawn around it to show where it is) through the world. When I hit a face I reflect the velocity by the face normal.

It looks much more realistic if I decrease the velocity z component over time (to simulate gravity) and reduce the magnitude of the velocity each time it hits a surface, so I can now bounce objects around the world:





Performing the collision detection against every single face in the world is not very efficient (though on modern hardware I'm still in the high nineties). There are other problems to look into - such as collisions with invisible brushes used for triggers and collision rules when it comes to water and the sky, not to mention that I should really be performing bounding-box collision detection, not just single moving points. Points also need to slide off surfices, not just stop dead in their tracks.

Once a vertex hits a plane and has been reflected I push it out of the surface very slightly to stop it from getting trapped inside the plane. This has the side effect of lifting the vertex a little above the floor, which it then drops back against, making it slide down sloping floors.
Sign in to follow this  


2 Comments


Recommended Comments

Awesome as usual, but why test against every face? Surely you have the code to find what leaf the camera is in, shouldn't that work for any point. I'm pretty sure each leaf contains enough information for collision detection, although it's been a while.

Share this comment


Link to comment
Quote:
Original post by Scet
but why test against every face?
That's why I list it as a problem. [smile]

The test itself if generally pretty fast (it performs a bouncing-box test with the face first, then has optimisations for axial planes - which most surfaces tend to be). Checking it works with the entire level was just a start, now I can try and optimise it. There are still some flaws with my code; for example, as some of the entities are touching the floor in the game they end up falling through it without a hack to move them up slightly before moving them back down again. IIRC Quake uses 1/32 as it's floating-point epsilon, which seems rather generous as far as collision accuracy goes.

Quote:
Surely you have the code to find what leaf the camera is in, shouldn't that work for any point.
Yes, it should. The Quake BSP level format defines some additional specifically for collision detection (the clip nodes) which should help. I haven't had much success with this as the BSP structure still confuses me somewhat (what with there being seemingly unrelated geometry in nodes and leaves - theoretically you can use the tree to order drawing, but I am yet to find out a working combination).

Your solution (using the convex leaf as used by the renderer) would seem by far and away the easiest technique as far as writing more code and decoding more formats go.

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now