Shooting and Hit Detection

posted in Lyost's Journal
Published October 16, 2011
Advertisement
Since my plan for the tank game was to be a quick game to develop[sup]1[/sup], I decided to just do hit-scan weapons instead of actually generating a projectile object and tracking it. Naturally, I went with a 2-tiered approach of a fast-rejection phase followed by a more precise test.

Due to my game objects being able to rotate, I went with bounding spheres for the fast-rejection phase. I could have dealt with adjusting an AABB (axis-aligned bounding box[sup]2[/sup]) for rotation or using OBB (oriented bounding box), but decided to go with bounding spheres for the simplicity. XNA already provides a BoundingSphere struct that can be tested for intersection against a ray, so it was the natural choice to use that.

For the more precise phase, I could have gone against a collision mesh and gotten very accurate results from that. But for the sake of playing around a bit, I decided to take a different approach, which I think turned out to be a good exploration of XNA's Ray and BoundingSphere structs. I used an XML file to specify spheres that closely approximate the mesh. In order to allow these spheres to approximate the mesh, they can be scaled and translated along each axis as well as rotated about an arbitrary axis. Each sphere is also attached to a bone so that animation is taken into account.

gallery_49001_299_27160.png
Turret and tank models

gallery_49001_299_34270.png
Turret and tank collision spheres

Manipulating spheres this way is just applying what I learned in my college computer graphics course's ray tracer. If you have never written a ray tracer, I highly recommend the exercise. In that program, there were different primitives that we needed to support (spheres, triangles, cubes, cylinders, etc). The primitives were all unit size and centered at the origin. In order to get a non-unit sphere or triangle, a scale operation had to be applied, which adjusted the primitive instance's world matrix. When it came to rendering, the ray was just multiplied by the inverse of the world matrix. It is worth noting that to use just the inverse both the ray's position and direction were done as Vector4 with the w component being 1 and 0 respectively.

In the tank game, for checking the collision spheres against the ray, I tried adjusting an instance of XNA's Ray struct in the same way and once again using XNA's BoundingSphere struct for the intersection test. This did not work. From looking at the documentation of BoundingSphere.Intersects, I didn't see a reason why it wouldn't. So the next step in my debugging was extracting the relevant values with break points and manually doing the math for the hit and miss test cases. The math worked out correctly. Turns out on the Ray's member documentation page, the direction is specified as a unit vector. There is no note that using a non-unit direction would cause the Intersects method to give incorrect results. This is relevant because by scaling the collision spheres the converted ray's direction will not be a unit length (unless the resulting scale is 1). My solution to this was to implement the ray-sphere intersection test myself in my CollisionSphere class. Another solution would have been to convert the ray then normalize the direction. However, that will give an incorrect t value back, which will mess up determining which is the closest intersection to the ray's source and positioning cross-hairs in 3D space. Maybe it's because of my prior experience for this, but I find it bizarre that XNA's Ray struct has this unit length requirement.

[sup]1[/sup] It has already taken substantially longer than I expected, but I am learning not only the framework, but also more about game development. So, I still intend to complete this project.
[sup]2[/sup] While I assume that most people reading this already know that AABB stands for axis-aligned bounding box, I prefer to define the meanings of all abbreviations at least once just in case someone is unfamiliar.
1 likes 2 comments

Comments

owtackle
Hey there!

I hope you continue to write these journals. I'm new to game development as well as to XNA, but I plan to hurl myself deep into these waters. I especially like that you define the abbreviations, as it would take some time for me to find what AABB stands for.

Keep it up!
October 17, 2011 06:04 AM
Lyost
[quote name='owtackle' timestamp='1318831459']
Hey there!

I hope you continue to write these journals. I'm new to game development as well as to XNA, but I plan to hurl myself deep into these waters. I especially like that you define the abbreviations, as it would take some time for me to find what AABB stands for.

Keep it up!
[/quote]


Thanks! I plan to continue to do these for any interesting issues I encounter in this and minimally my next few projects. The ones so far have been just catching up on things I have already encountered and wanted to write about, and finally getting around to it. The next one will also be a catch-up entry, but after that it's onto whatever interesting thing I encounter in continuing development of my tank game.
October 17, 2011 08:39 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement