Jump to content
  • Advertisement
Sign in to follow this  
hallgeir

Instant "bullets" - how?

This topic is 4228 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

Hi. I have been searching a little bit but have been unable to find anything about it. If I have some sort of player (let's say a man with a gun), and I want the bullets that come out of that gun to hit instantly in front of where the man with the gun is facing (kind of like in real life. although we know that bullets don't hit instantly, on close range it's as good as instant). How would I know WHAT the bullet hit? In other words, how can I find out what is in front of the player? I'm completely blank on this area so all help would be great. :) Edit: I assumed that this is basically a math question (to find out where the bullet intercepts with the object), but if it's not and I have posted it in the wrong category, then I'm sorry and feel free to move it.

Share this post


Link to post
Share on other sites
Advertisement
What you're asking about is known as "picking", and is generally implemented by finding the intersection between a ray facing out from the gun, and each piece of geometry in the world. That should give you some terms to search on.

Share this post


Link to post
Share on other sites
You can also make the bullet move in the usual "slow bullet" way, but instead of moving it once per update you move it until it hits something (or vanishes for any other reason). This could be easier to implement than performing the ray collision check, if you already understand how to implement the normal bullets efficiently.

Another alternative to using a ray is to use an extremely long and narrow bounding volume to search for intersections. As the length approaches infinity and the width approaches zero, this shape degenerates to behave exactly like a ray, and specialized ray testing would be faster; this method just allows you to reuse already existing collision checks instead of writing a whole new one.

Share this post


Link to post
Share on other sites
Yeah, ray-casting is used 99% of the time. this has a table of intersection tests. Look into the ray column for each algos that you may need, but I suspect the main ones would be ray-triangle, ray-sphere, ray-box, and possibly ray-cylinder. These are rather easy, but require a good grasp of basic vector maths. If you have your muzzle position and your barrel direction, then ray-picking is the way to go. If you don;t or do not want to base your bullet path from the gun but from the crosshair (quake 3), you may need an algorythm to convert from camera space into world space, but that's relatively trivial.

to make the algo efficient, you will possibly need some BVH (bounding volume hierarchy) or other tree structure for fast culling if your scene is complex.

There are other techniques, deprecated, such as using the frame buffer to get what surface is at a particular pixel on screen, but it's not really used anymore, and requires another render pass, with simplified geometry.

Share this post


Link to post
Share on other sites
I probably should have mentioned that the game I'm working on is a 2D game.. not a 3D game.
Also the terrain that is used is basically a texture. If you've played Worms you got the idea approximately.

Can I still use "picking" or ray casting? Or will that only work when dealing with geometrical shapes (like rectangles)?
I kind of need it to be pixel perfect (or close to it)..

Share this post


Link to post
Share on other sites
You sure can. One possibility would be to 'draw' a line pixel by pixel testing each one for collisions (I'm assuming that you can see whether or not a pixel is collided?). Of course, you wouldn't actually draw it, but you'd use the same process. Just you'd check for collisions instead of drawing. If you need to know how to draw lines Google Bresenham's line algorithm, which I'm sure could be modified to work for a ray rather than a line.

Share this post


Link to post
Share on other sites
That changes things completely.

Is it pixel-based, or gemoetry based? Your terrain is made up of segments or just filled pixels (worms). In any case, ray-casting should work the same, or you can use a line-drawing algorithm to find the pixel on the map hit, but I'd use a ray-marching algorithm to walk the pixelmap and keep things consistent.

Share this post


Link to post
Share on other sites
Quote:
Original post by Ezbez
You sure can. One possibility would be to 'draw' a line pixel by pixel testing each one for collisions (I'm assuming that you can see whether or not a pixel is collided?). Of course, you wouldn't actually draw it, but you'd use the same process. Just you'd check for collisions instead of drawing. If you need to know how to draw lines Google Bresenham's line algorithm, which I'm sure could be modified to work for a ray rather than a line.


Ah! That solution you're mentioning there might be something like what I am looking for.
I'm familiar with Bresenham's algorithm, since that is what I use to render my fractal terrain to a texture.

Quote:
Original post by Oliii
Is it pixel-based, or gemoetry based? Your terrain is made up of segments or just filled pixels (worms). In any case, ray-casting should work the same, or you can use a line-drawing algorithm to find the pixel on the map hit, but I'd use a ray-marching algorithm to walk the pixelmap and keep things consistent.


The terrain is pixel based. It's made first by lines. I then use the Bresenham's line algorithm to render the lines to a texture, then filling it up. The reason why I want it on a texture like that, is that I would like to be able to destroy the terrain (kind of like worms).

I will check up the ray casting thing, it sounds interesting in any case. If I don't use it for the terrain-object collision detection, I might use it between objects on the map (which should have a rectangular bounding box). But if you don't mind me asking, what is a ray-marching algorithm? Is it a ray casting algorithm or something that might be even more suited for my problem?

In any case thanks all for all the help so far. :)

Share this post


Link to post
Share on other sites
It's kinda like a line drawing algorithm, such as bresendham. It's to walk onto a grid quickly. It's usually applied to ray versus grids (3D or 2D).

http://members.gamedev.net/oliii/satpost/3DDDA.cpp
http://members.gamedev.net/oliii/satpost/DXInputs.h
http://members.gamedev.net/oliii/satpost/DXInputs.cpp

that's 3D DDA, but 2D works the same, only two dimensions used instead of three.


bool RasteriseDDA(const Vector& Start, const Vector& End, unsigned int Data, bool (*IntersectCallback)(unsigned int Data, int x, int y, int z))
{
// the cell walking
int iCell[3];
int iCellIncrement[3];

// the intersection params on the three dimensions
float fTIncrement[3];
float fT[3];

// calculate the DDA parameters for each dimension
for(int i = 0; i < 3; i ++)
{
const float threshold = 1.0e-6f;

// inverse scaling parameters
float fD = (End - Start);
bool bAligned = (fabs(fD) < threshold)? true : false;
float fInvD = (bAligned)? 0.0f : 1.0f / fD;

// which side of the cell we need to test
float fPlane = (floor(Start) + 0.5f + sign(fD) * 0.5f);

// first cell to trasverse
iCell = floor(Start);
iCellIncrement = sign(fD);

// the DDA increment for that axis
fTIncrement = (bAligned)? 0.0f : fabs(fInvD);

// the first time of intersection
fT = (bAligned)? 1.01f : fabs(fPlane - Start) * fTIncrement;
}

//-------------------------------------------------------------
// very fast DDA method.
// no division. always terminate.
//-------------------------------------------------------------
for(float t = 0.0f; t <= 1.0f; )
{
// Run the callback function on the pixel
// occupied by the ray now.
if (!IntersectCallback(Data, iCell[0], iCell[1], iCell[2]))
break;

// find the dimension with the closest intersection
int iMinAxis = -1;
for(int i = 0; i < 3; i ++)
{
// it's the minimum (or the first)
if (fT < t || iMinAxis == -1)
{
// that will be our dimension to use
// for incrementing.
iMinAxis = i;
t = fT;
}
}

// move to next cell along the dimension of minimum intersection
iCell[iMinAxis] += iCellIncrement[iMinAxis];
fT[iMinAxis] += fTIncrement[iMinAxis];
}

return true;
}




can't remember the particularities, but ray marching will give you EVERY cell intersected by the ray, whereas some line drawing only approximate.

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!