Comments
Patrick Collands wrote: collands (AT) gmail com I'd be very grateful for an invitation. Thank you.
Cloud Expo on Google News

SYS-CON.TV

2009 East
PLATINUM SPONSORS:
IBM
Smarter Business Solutions Through Dynamic Infrastructure
IBM
Smarter Insights: How the CIO Becomes a Hero Again
Microsoft
Windows Azure
GOLD SPONSORS:
Appsense
Why VDI?
CA
Maximizing the Business Value of Virtualization in Enterprise and Cloud Computing Environments
ExactTarget
Messaging in the Cloud - Email, SMS and Voice
Freedom OSS
Stairway to the Cloud
Sun
Sun's Incubation Platform: Helping Startups Serve the Enterprise
POWER PANELS:
Click For 2008 West
Event Webcasts
One From the Vault: How I Rolled My Own Collision Detection
A Helpful Addition to Your Toolbox

Recently in a Shockwave3D project, I had some problems with the modelsUnderRay command. More precisely, modelsUnderRay seemed to have some problems of its own. Occasionally it just didn't give the correct result, it would miss a model somehow. In the particular application I was building (a landscape that let the user's drive a car around on the surface), this was dramatic because the when modelsUnderRay failed, the car fell through the world. At first I started to develop little stop-gap bits of code that ensured that the built-in functions would work. And then it occurred to me, why not just write my own?

So in my application, I was firing a ray 'down' from the position of the car, and intersecting the land, and then moving the car 'up' so that it would ride on the surface. I was also orienting the car to the normal of the triangle that it was on top of. This is shown in Figure 1.

So as you can see from the diagram, missing the landscape would have rather drastic consequences. Additionally, in doing it myself, I was able to get not only the normal from the original triangle, but the blended normal that weights the three disparate normal at the vertices of the triangle, which allows for a much smoother motion across the surface. The desired "smooth normal" is shown in Figure 2.

So I needed a way to fire a ray at the landscape, see where it hit, and get the resulting normal vector. The code for my collision detection routine is generalized to the code in Listing 1 (which unlike my terrain example uses ALL of the objects in the world, in the same way that modelsUnderRay does). Note also that to debug this I used my 'Visual Debug Lines' that I presented in a previous MXDJ column (http://mxdj.sys-con.com/read/47857.htm).

The true "workhorse" of this routine is the ghTriangleRayCollision routine, that performs the magic of ray/triangle collision detection. This routine is based on an algorithm that I found at the SoftSurfer graphics site [see References, item1#], and that has been published several times in various places. A competing algorithm that could also be used would be the Akenine-Moller algorithm, which is presented in [see References, item #2]. The code for ghTriangleRayCollision is presented in Listing 2.

Finally, I wanted a way to average the normals of the triangle I hit, and get the normal of the exact point, or texel, within the triangle, weighted from the three triangle vertices. So I modified the code in Listing 1 to return not only the texture coordinates, but the three normals for the triangle that I hit. This is simply a matter of reading them out of the mesh in the same way the texture coordinates are read. Once I had the normals, then I knew the following information: the position of the points of the triangle (aTriangleHit in the returned array), the point of collision (vHitPosition in the returned array), and the normals at the vertices of the triangle (aTriangleNormals). With these three pieces of information I used a technique called Barycentric Coordinates to average the normals across the triangle. The Barycentric Coordinates are computed and returned as a vector of weights in the ghGetBarycentricCoords3D function in Code Listing 3.

The final application of the weights to the original vectors occurs in the ghGetTexelValues handler, that takes an array of values (the normals) and a vector that represents the BaryCentric weights of the point. The code for GetTexelValues is shown in Listing 4.

Using these methods, I rolled my own collision detection that was far more accurate than the modelsUnderRay command that exists in the 3D Xtra. It will detect backfacing collisions, will not return a collision when the ray intersects a model's bounding sphere but not the model, and is generally more precise around the edges of individual faces. Additionally, by adding some averaging methods, I was able to more smoothly interpolate across the surface of the triangle, rather than have sharp transitions between the normals of two adjoining triangles. This made for a much smoother terrain-following algorithm, without the overhead of constantly interpolating between the last and current face. Hopefully you too will find these functions a helpful addition to your toolbox in developing your own 3D worlds.

References:

  • Sunday, Dan. "Intersection of Rays, Segments, Planes and Triangles in 3D." The SoftSurfer Graphics Algorithms Collection. Available Online: www.softsurfer.com/Archive/algorithm_0105/algorithm_0105.htm
  • Akenine-Moller, Thomas, and Eric Haines. Real-Time Rendering. 2nd Edition. A. K. Peters. Natick, Massachusetts, 2002.
  • About Andrew M. Phelps
    Andrew M. Phelps, a member of the Editorial Board of Web Developer's & Designer's Journal, is in the Information Technology Department at the Rochester Institute of Technology in Rochester, NY (http://andysgi.rit.edu/).

    In order to post a comment you need to be registered and logged in.

    Register | Sign-in

    Reader Feedback: Page 1 of 1

    This is a great article, at least in substance. The problem is, as previously commented, the source listing is completely unusable. I was able to parse it and remove all of the bad line-breaks (what fun) but then got snarled in several mistyped variable names.

    Andrew, is there any chance you could repost the sample code or just provide a working demo DIR file?

    Thanks!

    The misplaced line breaks make the code impossible to compile. Can you post a corrected version - or even better, a sample file?


    Your Feedback
    Marty Plumbo wrote: This is a great article, at least in substance. The problem is, as previously commented, the source listing is completely unusable. I was able to parse it and remove all of the bad line-breaks (what fun) but then got snarled in several mistyped variable names. Andrew, is there any chance you could repost the sample code or just provide a working demo DIR file? Thanks!
    Rich Mayo wrote: The misplaced line breaks make the code impossible to compile. Can you post a corrected version - or even better, a sample file?
    Latest Cloud Developer Stories
    CloudBench Applications, Inc. announced its financial results for the three months and nine months ending September 30, 2009. All amounts are stated in Canadian dollars unless otherwise noted. Revenues from BasicGov, the Company's cloud computing solution for local government, gr...
    The new contract is an industry first, with CSC being the first Microsoft partner to lead and win a cloud computing services agreement of this scale. Under terms of the contract, CSC will provide Royal Mail Group's 30,000 employees with access to new IT services using Microsoft's...
    Operates in over 170 countries and is one of the world’s leading providers of communications solutions and services. Richard Tarboton talks for MeettheBoss.TV on his role as Head of Energy & Carbon for BT and what they are doing towards reducing carbon emissions.
    CA is going to put its Agile Planner software on salesforce.com’s Force.com platform in the first half to accelerate development time and give users visibility over their development initiatives to reduce time-to-market. Customers are supposed to be able to accelerate the deploym...
    Despite its uncertain fate Sun soldiers on. Monday it trotted out a cloud-based multiplatform desktop as a service for K-12 and community colleges that can run Windows, the Mac OS, Linux and Solaris applications to nearly any client device, including its own Sun Ray thin clients....
    Subscribe to the World's Most Powerful Newsletters
    Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
    Click to Add our RSS Feeds to the Service of Your Choice:
    Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
    myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
    Publish Your Article! Please send it to editorial(at)sys-con.com!

    Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021

    SYS-CON Featured Whitepapers
    ADS BY GOOGLE

    Breaking Cloud Computing News
    CloudBench Applications, Inc. announced its financial results for the three months and nine months e...