This week only. Pastebin PRO Accounts Christmas Special! Don't miss out!Want more features on Pastebin? Sign Up, it's FREE!
Guest

RayTriangleIntersectionTest

By: a guest on Nov 25th, 2013  |  syntax: Java  |  size: 6.36 KB  |  views: 78  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. package com.pixldevelopment.terminal;
  2.  
  3. import com.pixldevelopment.wastelandengine.other.math.Vector.Vector3;
  4.  
  5. /**
  6.  * A ray and triangle intersection test example.
  7.  *
  8.  * @author simengangstad
  9.  * @since 11.10.13
  10.  */
  11. public class RayTriangleIntersectionTest
  12. {
  13.     /**
  14.      * Main staring point.
  15.      *
  16.      * @param args The run arguments.
  17.      */
  18.     public static void main(String[] args)
  19.     {
  20.         new RayTriangleIntersectionTest();
  21.     }
  22.  
  23.     /**
  24.      * Initializes the RayTriangleIntersectionTest.
  25.      */
  26.     public RayTriangleIntersectionTest()
  27.     {
  28.         Vector3 v1 = new Vector3(-1.0f, 0.0f, 0.0f);
  29.         Vector3 v2 = new Vector3(1.0f, 0.0f, 0.0f);
  30.         Vector3 v3 = new Vector3(0.0f, 1.0f, 0.0f);
  31.  
  32.         System.out.println(this.checkIntersection(v1, v2, v3, new Ray(new Vector3(0.0f, 0.5f, 1.0f), new Vector3(0.0f, 0.0f, -1.0f))));
  33.     }
  34.  
  35.     /**
  36.      * Checks intersection between a ray and a triangle.
  37.      *
  38.      * @param v1 The first vertex in the triangle.
  39.      * @param v2 The second vertex in the triangle.
  40.      * @param v3 The third vertex in the triangle.
  41.      * @param ray The ray.
  42.      *
  43.      * @return If the ray intersects the triangle.
  44.      */
  45.     private boolean checkIntersection(Vector3 v1, Vector3 v2, Vector3 v3, Ray ray)
  46.     {
  47.         float t = ray.rayCast(v1, v2, v3);
  48.  
  49.         if (t == Float.MAX_VALUE)
  50.         {
  51.             // Ray didn't hit anything.
  52.  
  53.             return false;
  54.         }
  55.         else
  56.         {
  57.             // Hit!
  58.  
  59.             return true;
  60.         }
  61.     }
  62.  
  63.     /**
  64.      * A ray, has a origin and a direction.
  65.      */
  66.     private class Ray
  67.     {
  68.         /**
  69.          * The origin and direction of the ray.
  70.          */
  71.         private Vector3 origin, direction;
  72.  
  73.         /**
  74.          * Initializes the ray with a origin and a direction.
  75.          *
  76.          * @param origin The origin.
  77.          * @param direction the direction.
  78.          */
  79.         public Ray(Vector3 origin, Vector3 direction)
  80.         {
  81.             this.origin = origin;
  82.             this.direction = direction;
  83.         }
  84.  
  85.         /**
  86.          * @return The origin of the Ray.
  87.          */
  88.         public Vector3 getOrigin()
  89.         {
  90.             return this.origin;
  91.         }
  92.  
  93.         /**
  94.          * Sets the origin.
  95.          *
  96.          * @param origin The new origin.
  97.          */
  98.         public void setOrigin(Vector3 origin)
  99.         {
  100.             if (!this.origin.equals(origin))
  101.             {
  102.                 this.origin = origin;
  103.             }
  104.         }
  105.  
  106.         /**
  107.          * @return The direction of the Ray.
  108.          */
  109.         public Vector3 getDirection()
  110.         {
  111.             return this.direction;
  112.         }
  113.  
  114.         /**
  115.          * Sets the direction.
  116.          *
  117.          * @param direction The new direction.
  118.          */
  119.         public void setDirection(Vector3 direction)
  120.         {
  121.             if (!this.direction.equals(direction))
  122.             {
  123.                 this.direction = direction;
  124.             }
  125.         }
  126.  
  127.         /**
  128.          * Casts a ray from the origin and across the direction and checks if it hits a triangle.
  129.          *
  130.          * @param v1 The first vertex in the triangle.
  131.          * @param v2 The second vertex in the triangle.
  132.          * @param v3 The third vertex in the triangle.
  133.          *
  134.          * @return The t, how far the triangle is from the origin (in the equation point = origin + t(direction)). Returns Float.MAX_VALUE if no intersection.
  135.          */
  136.         public float rayCast(Vector3 v1, Vector3 v2, Vector3 v3)
  137.         {
  138.             float t;
  139.  
  140.             if ((t = this.intersectsTriangle(v1, v2, v3)) > 0.0f) // If we hit something, then return the t.
  141.             {
  142.                 return t;
  143.             }
  144.             else // If we didn't hit something, return a value that indicates that we didn't hit something.
  145.             {
  146.                 return Float.MAX_VALUE;
  147.             }
  148.         }
  149.  
  150.         /**
  151.          * Checks if the point is "inside" the given vertices.
  152.          *
  153.          * @param v1 First vertex.
  154.          * @param v2 Second vertex.
  155.          * @param point The point.
  156.          * @param normal The normal.
  157.          *
  158.          * @return If it's inside.
  159.          */
  160.         private boolean isInside(Vector3 v1, Vector3 v2, Vector3 point, Vector3 normal)
  161.         {
  162.             float t0 = (((v2.getY() - v1.getY()) * (point.getZ() - v1.getZ())) - ((point.getY() - v1.getY()) * (v2.getZ() - v1.getZ())));
  163.             float t1 = (((v2.getZ() - v1.getZ()) * (point.getX() - v1.getX())) - ((point.getZ() - v1.getZ()) * (v2.getX() - v1.getX())));
  164.             float t2 = (((v2.getX() - v1.getX()) * (point.getY() - v1.getY())) - ((point.getX() - v1.getX()) * (v2.getY() - v1.getY())));
  165.  
  166.             float dot = t0 * normal.getX() + t1 * normal.getY() + t2 * normal.getZ();
  167.  
  168.             if(dot < 0.0f)
  169.             {
  170.                 return false;
  171.             }
  172.             else
  173.             {
  174.                 return true;
  175.             }
  176.         }
  177.  
  178.         /**
  179.          * Checks if the ray intersects a triangle.
  180.          *
  181.          * @param v1 First vertex.
  182.          * @param v2 Second vertex.
  183.          * @param v3 Third vertex.
  184.          *
  185.          * @return The t, how far the triangle is from the origin (in the equation point = origin + t(direction)).
  186.          */
  187.         private float intersectsTriangle(Vector3 v1, Vector3 v2, Vector3 v3)
  188.         {
  189.             Vector3 normal = new Vector3().computeNormal(v1, v2, v3);
  190.  
  191.             float dot = normal.dotProduct(this.direction);
  192.  
  193.             if(dot < 0.0f) // Ray and triangle is not parallel.
  194.             {
  195.                 float t = -(normal.getX() * (this.origin.getX() - v1.getX()) + normal.getY() * (this.origin.getY() - v1.getY()) + normal.getZ() * (this.origin.getZ() - v1.getZ())) / dot;
  196.  
  197.                 if(t < 0.0f)
  198.                 {
  199.                     return 0.0f;
  200.                 }
  201.  
  202.                 Vector3 point = new Vector3(this.direction.multiply(t).add(this.origin));
  203.  
  204.                 if(this.isInside(v1, v2, point, normal) &&
  205.                    this.isInside(v2, v3, point, normal) &&
  206.                    this.isInside(v3, v1, point, normal))
  207.                 {
  208.                     // P is inside triangle.
  209.                     return t;
  210.                 }
  211.  
  212.  
  213.                 return 0.0f;
  214.             }
  215.  
  216.             return 0.0f;
  217.         }
  218.     }
  219. }
clone this paste RAW Paste Data