Camera Collisions

What are some possible methods of keeping my camera on the meshes I've created? I'm trying to get the camera to walk up a ramp I made but can't think of anything good. The only thing I've thought of is to create a line going down from the position, compare that collision point (the line and the plane I'm "on") with the point that represents the camera's feet and adjust the camera. Some flaws I've thought of include keeping track of which face I'm on. Any ideas?

Couple comments. Depending on your game, you may need to solve this problem more generally for various actors in your game. The camera in effect is just another body in the game.

"Keeping track of which face you are on" - isn't that just collision detection? Narrow down the faces which could intersect the camera's "foot" by using a bounding box test maybe, then collision detect each one with a line-polygon intersection test until you find the one you are over.

Here's another thought: if the terrain has abrupt changes the camera movement will do the same. A nice way around it would be to use the terrain to figure out where the camera wants to be as you were already considering. But then you want to move the camera to that height smoothly, using smooth velocity changes maybe. Or you could cheat: generate a smoothed approximation of the terrain mesh, which you keep invisible. The camera would use that terrain to hover over instead of the one with the abrupt changes.

I agree with Matt -- you'll want to come up with a general purpose ray collision system at the very least. After all, everything that moves in the game should have *some* kind of collision detection.

For my game ( a third person driving type game ) -- for which I have put a lot of work into camera control -- I came up with a sort of ray-based positioning system. Instead of just having a camera with a position and a direction to look at, I have instead two rays. The positioning ray starts at the center of the player vehicle and projects backwards and up a little. The orientation ray projects forward from the vehicle.

The camera is placed at the end of the positioning ray and the camera is made to look at the point at the end of the orientation ray. Obviously, these two rays are kept in sync in worldspace with the transformation of the player vehicle.

The rays have collision detection against the scene -- where collision is performed from the origin of the ray outwards. So if the player vehicle backs up against a cliff, the positioning ray will be shortened and the camera will be pushed forward. In truth, I've actually turned off collision detection for the orientation ray -- it was visuall disturbing and ultimately unnecessary. But the collision for the positioning ray works beautifully -- and prevents scenarios where, say, a tree or boulder might come between the player and the camera.

Now, as Matt mentioned, you'll have bumpiness. I like his idea of a special smoothed mesh -- personally I use a signal smoothing algorithm. Every input from the position and orientation rays to the camera is pushed into a ( separate ) accumulator stack and the average of the last N values in the stack is sent to the camera. Obviously, you'll want to come up with a reasonably efficient implementation; mine is a fixed size buffer with modulo iteration and a maintained average, so it's nearly computationally free.

This takes out jitter -- completely -- and makes certain that sudden position changes are smoothly handled.

Efficient ray collision with arbitrary geometry is non-trivial. There's a lot of discussion on that topic in this forum, and I, as always, will promote the Open Dynamics Engine. It has a very efficient ray-to-trimesh collider ( among other goodies ).

For a really cheap way to do the camera, you can just take the position of the object you're following and add some vector to it. You can smooth out this movement by making the camera an object and taking into account its last position (you could give the camera a velocity and point it towards the goal destination) or do what T+X said.

You'll then need to make sure the camera doesn't collide with anything (again, you can make it a collidable object) and also make sure nothing comes between the camera and the object you're looking at, or alternatively if you have a way to render things transparently you could do that if you notice the object is behind something.

Finally, it may be possible for the camera to get stuck on something, so you have to make sure that if the camera gets too far behind you will need to warp it or somesuch. You could warp it to the location of the object, and then allow it to move out a bit so that it's close to the desired distance.

I noticed that it wasn't mentioned and I thought I would point out that attaching the camera with a spring and some constraints on the possible angles of view could be a good option. This would help remove jitter and would be better than just adding a vector. You'd still need the warping thing so it doesn't get stuck of course.