• Advertisement
Sign in to follow this  

The old "bullet trajectory" question.

This topic is 4317 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I know it's been asked before, but the previous threads didn't really satisfy me. In an FPS, I know you can use ray intersection to detect whether or not you've hit an enemy when you fire. Just check for an intersection with a ray and any visible enemies' bounding boxes, and so on. Is THIS the easiest way to do it? It seems like there should be an easier way. Maybe not with true 3D. Anyone?

Share this post


Link to post
Share on other sites
Advertisement
I dunno about easier but you can always just put a good old fashioned bullet into the world with a velocity. Then just do normal collision detection with that bullet. What it hits, it hits.

-me

Share this post


Link to post
Share on other sites
What seems difficult to you about this method?

Share this post


Link to post
Share on other sites
If you are using openGL, you could use object picking to see if the bullet intersects an object.

http://www.lighthouse3d.com/opengl/picking/

Share this post


Link to post
Share on other sites
Quote:
Original post by Palidine
I dunno about easier but you can always just put a good old fashioned bullet into the world with a velocity. Then just do normal collision detection with that bullet. What it hits, it hits.

-me


that generally isn't a good idea with small, fast moving projectiles like bullets. Lets say that you have a bullet which is 1 pixel away from a window (with a thickness of 10 pixles) in one frame, and you're using a pixel-perfect collision detection algorithm, ie, your bullet does not collide with the window. the next frame, you displace the bullet using its velocity (maybe 100 m/s / 60 fps = 1.67 m/frame), which ends up displacing the bullet by, say, 40 pixels. the bullet is now on the other side of the window, but when you run your collision detection, it will not detect that the bullet is colliding with anything, because it isn't currently. thus, your bullet passed through an object without every registering a collision, which is bad. its much easier to just have a ray representing the bullets path that frame, and test if it collides with anything, which is, to answer the original question, very fast.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by jdaniel
If you are using openGL, you could use object picking to see if the bullet intersects an object.


Isn't that really slow since it requires essentially a second rendering pass for the picking?

plus it only tells you which object it hit, not necessarially where the point of contact was, so if you want to have your object rebound....

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Quote:
Original post by jdaniel
If you are using openGL, you could use object picking to see if the bullet intersects an object.


Isn't that really slow since it requires essentially a second rendering pass for the picking?

plus it only tells you which object it hit, not necessarially where the point of contact was, so if you want to have your object rebound....


Yeah, it's slow. It's not really true 3D either. And it is relatively easy to use. It seems to address the OP's question.

Share this post


Link to post
Share on other sites
Treating bullets as objects isn't a good idea, for several reasons. First, each bullet would have to be handled by the game logic or physics system as a bullet is a primary object. Imagine the extreme case where you have a chaingun firing 6,000 rounds per minute. That's 100 extra objects a second that the engine would have to handle, which would bring your engine to a crawl just processing something as insignificant as bullet objects. Consider that bullets persist over several frames, meaning that it's a cumulative increase of 100 objects a frame over however many frames the bullets are alive. I won't even get into the multiplayer case. Also consider that in any reasonable engine you'd have to allocate the bullet object just so that it can exist, so not only are you wasting memory for bullets but frequent allocation and deallocation of small blocks of memory are a bad idea in general for any type of memory manager or allocation scheme. Even if the memory is preallocated from the OS, it still needs to be managed, and that's overhead you don't want each frame.

Rays are a much better alternative. There's constant memory overhead and the processing time is proportional to a weapon's firing rate, which dictates how many rays you fire per frame as the player is shooting. And most weapons don't fire insanely fast. Not only that, but collision detection is perfect. You can't "pass through" an object like you can with just checking for object-object collision. As a matter of fact, you'd probably end up performing ray-based intersection each frame with an object-object collision scheme just so you don't pass through objects! The only downside with a ray-based approach is that bullets need to hit their target instantaneously (no delay), or else the persistence of the bullet state requires engine resources akin to making bullets primary objects in the engine. That's why most games use rays for bullets, because it's cheaper and almost as good as a real projectile bullet.

Share this post


Link to post
Share on other sites
Quote:
Original post by SippyCup
I know it's been asked before, but the previous threads didn't really satisfy me. In an FPS, I know you can use ray intersection to detect whether or not you've hit an enemy when you fire. Just check for an intersection with a ray and any visible enemies' bounding boxes, and so on. Is THIS the easiest way to do it? It seems like there should be an easier way. Maybe not with true 3D. Anyone?



In the old days, there was a nifty cheat you could use. Since early FPS engines used billboarded sprites to draw characters, bullet checking was easy. Prior to rendering the frame, you flag the pixel through which the bullet travels (and since most early FPSes didn't have much in the way of aiming, it wasn't uncommon for that pixel to always be in the same location). Then, when blitting the sprites for the enemies in the scene, you check to see if the sprite blits over the "hot" pixel. If so, that enemy is hit by the bullet. Throw in a depth sort and a little gimmickery and you can make sure that the closest enemy to the player is the one that dies (if more than one intersects the bullet's line of sight).

For software-rasterized engines (like almost all early FPS engines, again) you can even extend this trick to handle shooting special "hot zones" on walls.

Of course, that trick is totally useless in an engine that uses full-3D characters. At that point, a proper ray to bounding-box collision check is easily the best method currently available.

Share this post


Link to post
Share on other sites
I found this function in OpenGL Game Programming. The operator% is overloaded for dot product.


const CVector inline RayIntersection(const CVector& rayPos, const CVector* rayDir) const
{
const double a = N % rayDir; // plane normal . ray direction

if (a == 0)
return rayPos; // ray is parallel to plane

return rayPos - rayDir * (DistanceToPlane(rayPos) / a);
}


The dot product returns the angle between the plane normal and the ray's direction. If this angle is zero, wouldn't that mean that the ray is perpendicular to the plane rather than parallel? The normal is perpendicular to the plane. If the angle is zero, then the ray direction is parallel to the normal, which makes it perpendicular to the plane as well. Am I missing something or is this wrong?

It seems like the parallel case would occur if the angle between the normal and ray direction is 90. It also seems like if the angle is less than 90, the ray will never intersect the plane (because it's traveling away from it) and you'd want to return in that case as well.

Share this post


Link to post
Share on other sites
Quote:
Original post by SippyCup
The dot product returns the angle between the plane normal and the ray's direction. If this angle is zero, wouldn't that mean that the ray is perpendicular to the plane rather than parallel? The normal is perpendicular to the plane. If the angle is zero, then the ray direction is parallel to the normal, which makes it perpendicular to the plane as well. Am I missing something or is this wrong?

The dot product returns the cosine of the angle between the vectors, scaled by their magnitudes. So when the ray direction is perpendicular to the plane (parallel to the normal), the angle is zero, but that means the cosine is 1. When the ray is parallel to the plane (perpendicular to the normal), the cosine is 0.

However the code doesn't appear to take into account that a ray has a definite start and end point - it's more like a line/plane intersection method.

Share this post


Link to post
Share on other sites
Ah. That's right. :) Thanks. Yeah, I was thinking it seemed like a line method too. Looks like I need make some modifications. Thanks again!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement