LWJGL Forum

Programming => OpenGL => Topic started by: manji on October 30, 2010, 19:26:28

Title: how to aim correctly at first person shooter
Post by: manji on October 30, 2010, 19:26:28
I have the follow problem. The character of my fps game, can shoot bullets, towards where the corsair points. I want the bullets to be rendered. This works well when the gun is at the center of the window, and you can see the bullets heading to the target. Now, when I try to place the camera higher, near the head of the character, the bullets are also going higher, missing the target. This of course makes sense, and it wouldn't be a problem if did not want to render the bullets. But how can I efficiently make it work? It must be a common issue in most fps and other games, sorry for my noob question.
Title: Re: how to aim correctly at first person shooter
Post by: CodeBunny on October 30, 2010, 19:30:03
I'm not sure, but I think you can use a ray to discover where the "centered" camera bullets would first intersect an object, and then you just fire a bullet from your offset gun towards those coordinates.
Title: Re: how to aim correctly at first person shooter
Post by: manji on November 01, 2010, 18:14:11
Thank you for your answer CodeBunny. I searched this issue a little more, and yes, ray tracing (AABB) seems to be the way. I have implemented an algorithm found at the book Real-Time Collision Detection, Christer Ericson, 2005. But I still have a problem. The algorithm works fine, it does detect if and where intersections occur. But, it gives me a wrong y coordinate when I am aiming at the 2 sides parallel to the xy plane. With all the other sides, there seems to be no problem. I place the algorithm I use here:
private boolean intersects(Box b){

   final float EPSILON = 0.00000001f;
   float tmin = 0.0f;
   float tmax = Float.MAX_VALUE;          
   // Camera position
   float[] cameraPos = {xWorld, yWorld, zWorld};
   // Camera direction
   float[] dir = {xDir, yDir, zDir};

   // For all three slabs
   for (int i=0; i<3; i++){
   // Avoid division by zero later
       if (Math.abs(dir[i]) < EPSILON){
           // Ray is parallel to slab. No hit if origin not within slab
           if (cameraPos[i] < b.min[i] || cameraPos[i] > b.max[i]){
               return false;
           }
       }
       else{
           // Compute intersection t value of ray with near and far plane of slab
            float odd = 1.0f/dir[i];
           float t1 = (b.min[i] - cameraPos[i])*odd;
           float t2 = (b.max[i] - cameraPos[i])*odd;                  

            // Make t1 be intersection with near plane, t2 with far plane
           if (t1 > t2){
               float t = t1;
                t1 = t2;
               t2 = t;
           }

            // Compute the intersection of slab intersection intervals
           if (t1 > tmin){
               tmin = t1;
            }
            if (t2 < tmax){
               tmax = t2;  
           }

            // Exit with no collision as soon as slab intersection becomes empty
           if (tmin > tmax){
               return false;
            }
       }
        // Ray intersects the slab. Return point and intersection t value (tmin)
        intersectionPos[i] = cameraPos[i] + dir[i]*tmin; // Declared as member variable
   }
   return true;
}

Any thoughts?
Title: Re: how to aim correctly at first person shooter
Post by: CodeBunny on November 03, 2010, 00:54:34
I'm not the best person to ask, I've never used RayTracing algorithms before.

What do you mean by "wrong y coordinate"? The xy-plane of a bounding box would be the top and bottom of the box - do you mean the reported value is the center of the box, or 0, or something else?

I do know that JME has built-in support for this. It's a great 3D engine, if you're not opposed to using a pre-made setup I'd suggest using that. Plus, you wouldn't have to stick with bounding boxes for raytracing - I believe their method works for any geometric shape.
Title: Re: how to aim correctly at first person shooter
Post by: manji on November 03, 2010, 11:09:18
QuoteWhat do you mean by "wrong y coordinate"?
For now, I test my algorithm by placing my character looking at a box, and print the location on the box he is looking at. The strange thing is that when he is looking at the sides parallel to the xy plane, the y coordinate on the box he is looking at(according to the ray intersection code) is wrong. For example when he is looking at the bottom of the side, I get 0,3 when the right one i 0.0. Or when looking at the top of the side I get 0.8 then the right one is 1.0. And when he changes his view only parallel to the local x axis of the box(hope that makes sense), the y coordinate also changes. For all the other sides, I seem to have the right coordinates for any position on the sides.

Just now, I noticed something very interesting and helpful. What influences this difference in the output, is the order of the planes being checked. The slab that is checked in the middle, will return false results! For example if the loop goes xzy, the z coordinates will be wrong when looking at a pair of sides (don't know which ones for sure). So I guess there is something wrong in the logic of the algorithm... But I cannot find it two days now!

QuoteI do know that JME has built-in support for this.
Yes, I know about JME. I had begun studying it, but the support on the new revision, JME3, was lacking documentation so I gave up. I also tried jBullet but I couldn't even install it. I think it is for the best, because this way I get to learn stuff, which I find interesting.
Title: Re: how to aim correctly at first person shooter
Post by: manji on November 03, 2010, 14:21:24
Solution Found!!!
Ok, guys, it was a very silly mistake of mine, sorry  ;D
intersectionPos must be calculated outside of the loop, because where it is now, tmin is not final of course.
I believe though that this piece of code can be useful for anyone searching for a simple, clever and maybe efficient way of checking ray-box intersection.