CMPS-3480 - Computer Graphics
Lab-6

Lab 6 - Ray Casting, Vectors, Surface Intersection

Elements:
3 dimensions
Vectors and rays
Ray-plane intersection equation
Object definition
Orthographic projection
Overview:
Your first goal for this lab...
generate this image on screen.


Your second goal for this lab...
generate this image on screen.


You will create these images by casting rays through every pixel in your
drawing area. If the ray hits an object, return the color of the object. 

Your scene has 3 flat disks, or rings. We will learn how to determine the
precise spot that a ray hits a plane, and thus a ring sitting in that plane.
Step 1:
Go to your Odin /3480/6/ directory.

Copy files in...

$ cp /home/fac/gordon/p/3480/code/lab6/* .
$ make
$ ./lab6
Step 2:
Notice the comments at the top of the lab6.cpp program.
You should probably complete the functions listed.
Some of these functions are already in your other programs.

typedef double Flt; typedef Flt Vec[3]; Flt vecDotProduct(Vec v0, Vec v1) { //Return the dot product of the 2 vectors } Flt vecLength(Vec v) { //Return the length of the vector v } void vecNormalize(Vec v) { //Normalize the vector v } int rayPlaneIntersection(Vec center, Vec normal, Ray *ray, Hit *hit) { //Determine if ray intersects plane defined by center, normal. //Fill in hit.t and hit.p } int rayRingIntersection(Object *o, Ray *ray, Hit *hit) { if (rayPlaneIntersection(o->center, o->normal, ray, hit) { //Determine if the hit point is within the ring radius. return 1; } return 0; }
Notes are commented in the program code to help you. We will also discuss this assignment in class.
Step 3:
I will put more details here if needed.

Step 4:
Run your program and see the 3 rings on screen.

Each ring is defined to be in a plane.
What if you tilt the plane?
See if you can tilt the ring planes to produce image #2.
The round rings will look like ellipses.

Step 5:
Produce image similar to the following...



Try to reproduce this image exactly,
  then you can add other interesting features.




Homework
Render your initials using a triangle mesh.


Here is a triangle mesh for my own initial.



Here is a triangle mesh rendered.



You will need the following code to render triangles...
The code can also be found at:
   /home/fac/gordon/p/3480/code/lab6/tri.cpp


void getTriangleNormal(Vec tri[3], Vec norm)
{
    Vec v0,v1;
    vecSub(tri[1], tri[0], v0);
    vecSub(tri[2], tri[0], v1);
    vecCrossProduct(v0, v1, norm);
    //VecCross(v0, v1, norm);
    vecNormalize(norm);
}

int getBarycentric2(Vec a, Vec b, Vec c, Vec p, Flt *u, Flt *v)
{
    //From Christer Ericson's Real-Time Collision Detection
    Vec v0,v1,v2;
    vecSub(b, a, v0);
    vecSub(c, a, v1);
    vecSub(p, a, v2);
    Flt d00 = vecDotProduct(v0, v0);
    Flt d01 = vecDotProduct(v0, v1);
    Flt d11 = vecDotProduct(v1, v1);
    Flt d20 = vecDotProduct(v2, v0);
    Flt d21 = vecDotProduct(v2, v1);
    Flt denom = d00 * d11 - d01 * d01;
    if (denom == 0.0) return 0;
    *u = (d11 * d20 - d01 * d21) / denom;
    *v = (d00 * d21 - d01 * d20) / denom;
    return (*u >= 0.0 && *v >= 0.0 && *u + *v <= 1.0);
}

int pointInTriangle(Vec a, Vec b, Vec c, Vec p, Flt *u, Flt *v)
{
    //source:
    //http://blogs.msdn.com/b/rezanour/archive/2011/08/07/
    //
    Vec cross0,cross1,cross2;
    Vec ba,ca,pa;
    vecSub(b,a,ba);
    vecSub(c,a,ca);
    vecSub(p,a,pa);
    //This is a half-space test
    vecCrossProduct(ca,pa,cross1);
    vecCrossProduct(ca,ba,cross0);
    if (vecDotProduct(cross0, cross1) < 0.0)
        return 0;
    //This is a half-space test
    vecCrossProduct(ba,pa,cross2);
    vecCrossProduct(ba,ca,cross0);
    if (vecDotProduct(cross0, cross2) < 0.0)
        return 0;
    //Point is within 2 half-spaces
    //Get area proportions
    //Area is actually length/2
    Flt areaABC = vecLength(cross0);
    Flt areaV = vecLength(cross1);
    Flt areaU = vecLength(cross2);
    *u = areaU / areaABC;
    *v = areaV / areaABC;
    return (*u >= 0.0 && *v >= 0.0 && *u + *v <= 1.0);
}

int rayTriangleIntersect(Object *o, Ray *ray, Hit *hit)
{
    //Does the ray intersect the triangle's plane?
    if (rayPlaneIntersect(o->tri[1], o->norm, ray, hit)) {
        //yes
        Flt u,v;
        //Flt w;
        if (pointInTriangle(o->tri[0], o->tri[1],
            o->tri[2], hit->p, &u, &v)) {
            //w = 1.0 - u - v;
            return 1;
        }
    }
    return 0;
}