Esempio n. 1
0
//HAVE THEM IMPLEMENT THIS
//The ray in this function is not transformed because it was *already* transformed in Mesh::GetIntersection
Intersection Triangle::GetIntersection(Ray r){
    //1. Ray-plane intersection
    Intersection result;
    float t =  glm::dot(plane_normal, (points[0] - r.origin)) / glm::dot(plane_normal, r.direction);

    glm::vec3 P = r.origin + t * r.direction;
    //2. Barycentric test
    float S = 0.5f * glm::length(glm::cross(points[0] - points[1], points[0] - points[2]));
    float s1 = 0.5f * glm::length(glm::cross(P - points[1], P - points[2]))/S;
    float s2 = 0.5f * glm::length(glm::cross(P - points[2], P - points[0]))/S;
    float s3 = 0.5f * glm::length(glm::cross(P - points[0], P - points[1]))/S;
    float sum = s1 + s2 + s3;

    if(s1 >= 0 && s1 <= 1 && s2 >= 0 && s2 <= 1 && s3 >= 0 && s3 <= 1 && fequal(sum, 1.0f)){
        result.t = t;
        result.texture_color = Material::GetImageColorInterp(GetUVCoordinates(glm::vec3(P)), material->texture);
        result.object_hit = this;
        //TODO: Store the tangent and bitangent
        glm::vec3 dis[2] = {points[1] - points[0], points[2] - points[0]};
        glm::vec2 uv_points[3] = {GetUVCoordinates(points[1]), GetUVCoordinates(points[1]), GetUVCoordinates(points[2])};
        glm::vec2 uv_dis[2] = {uv_points[1] - uv_points[0], uv_points[2] - uv_points[0]};

        result.tangent = (uv_dis[1].y*dis[0] - uv_dis[0].y*dis[1])/(uv_dis[1].y*uv_dis[0].x - uv_dis[0].x*uv_dis[1].y);
        result.bitangent = (dis[1] - uv_dis[1].x*result.tangent)/uv_dis[1].y;
    }
    return result;
}
Esempio n. 2
0
Intersection Disc::GetIntersection(Ray r)
{
    //Transform the ray
    Ray r_loc = r.GetTransformedCopy(transform.invT());
    Intersection result;

    //Ray-plane intersection
    float t = glm::dot(glm::vec3(0,0,1), (glm::vec3(0.5f, 0.5f, 0) - r_loc.origin)) / glm::dot(glm::vec3(0,0,1), r_loc.direction);
    glm::vec4 P = glm::vec4(t * r_loc.direction + r_loc.origin, 1);
    //Check that P is within the bounds of the disc (not bothering to take the sqrt of the dist b/c we know the radius)
    float dist2 = (P.x * P.x + P.y * P.y);
    if(t > 0 && dist2 <= 0.25f)
    {
        result.point = glm::vec3(transform.T() * P);
        result.normal = glm::normalize(glm::vec3(transform.invTransT() * glm::vec4(ComputeNormal(glm::vec3(P)), 0)));
        result.object_hit = this;
        result.t = glm::distance(result.point, r.origin);
        //was interp
        result.texture_color = Material::GetImageColor(GetUVCoordinates(glm::vec3(P)), material->texture);

        //Compute tangent and bitangent
        glm::vec3 T = glm::normalize(glm::cross(glm::vec3(0,1,0), ComputeNormal(glm::vec3(P))));
        glm::vec3 B = glm::cross(ComputeNormal(glm::vec3(P)), T);
        result.tangent = glm::normalize(glm::vec3(transform.T() * glm::vec4(T, 0)));
        result.bitangent = glm::normalize(glm::vec3(transform.T() * glm::vec4(B, 0)));
    }
    return result;
}
//HAVE THEM IMPLEMENT THIS
//The ray in this function is not transformed because it was *already* transformed in Mesh::GetIntersection
Intersection Triangle::GetIntersection(Ray r){
    //1. Ray-plane intersection
    Intersection result;
    float t =  glm::dot(plane_normal, (points[0] - r.origin)) / glm::dot(plane_normal, r.direction);

    glm::vec3 P = r.origin + t * r.direction;
    //2. Barycentric test
    float S = 0.5f * glm::length(glm::cross(points[1] - points[0], points[2] - points[0]));
    float s1 = 0.5f * glm::length(glm::cross(points[1]-P, points[2]-P))/S;
    float s2 = 0.5f * glm::length(glm::cross(points[2]-P, points[0]-P))/S;
    float s3 = 0.5f * glm::length(glm::cross(points[0]-P, points[1]-P))/S;
    float sum = s1 + s2 + s3;

    if(s1 >= 0 && s1 <= 1 && s2 >= 0 && s2 <= 1 && s3 >= 0 && s3 <= 1){
        result.t = t;
        result.texture_color = Material::GetImageColorInterp(GetUVCoordinates(glm::vec3(P)), material->texture);
        result.object_hit = this;
        result.point = glm::vec3(transform.invT()*glm::vec4(P, 1.0f)); //tranform T to world coords
        result.normal = glm::vec3(glm::normalize(transform.invTransT()*glm::vec4(plane_normal, 1.0f))); //transform normal to world coords
        //TODO: Store the tangent and bitangent
        glm::vec3 changeP1 = this->points[1] - this->points[0];
        glm::vec3 changeP2 = this->points[2] - this->points[0];
        glm::vec2 changeUV1 = this->uvs[1] - this->uvs[0];
        glm::vec2 changeUV2 = this->uvs[2] - this->uvs[0];

        result.tangent = glm::normalize(changeUV2[1]*changeP1 - changeUV1[1]*changeP2);
        result.bitangent =glm::normalize((changeP2 - changeUV2[0]*result.tangent)/changeUV2[1]);
    }
    return result;
}
Esempio n. 4
0
//HAVE THEM IMPLEMENT THIS
//The ray in this function is not transformed because it was *already* transformed in Mesh::GetIntersection
Intersection Triangle::GetIntersection(Ray r){
    //1. Ray-plane intersection
    Intersection result;
    float t =  glm::dot(plane_normal, (points[0] - r.origin)) / glm::dot(plane_normal, r.direction);

    glm::vec3 P = r.origin + t * r.direction;
    //2. Barycentric test
    float S = 0.5f * glm::length(glm::cross(points[0] - points[1], points[0] - points[2]));
    float s1 = 0.5f * glm::length(glm::cross(P - points[1], P - points[2]))/S;
    float s2 = 0.5f * glm::length(glm::cross(P - points[2], P - points[0]))/S;
    float s3 = 0.5f * glm::length(glm::cross(P - points[0], P - points[1]))/S;
    float sum = s1 + s2 + s3;

    if(s1 >= 0 && s1 <= 1 && s2 >= 0 && s2 <= 1 && s3 >= 0 && s3 <= 1 && fequal(sum, 1.0f)){
        result.t = t;
        result.texture_color = Material::GetImageColorInterp(GetUVCoordinates(glm::vec3(P)), material->texture);
        result.object_hit = this;
        //TODO: Store the tangent and bitangent
        glm::vec2 dUV1 = uvs[0] - uvs[1];
        glm::vec2 dUV2 = uvs[0] - uvs[2];
        glm::vec3 pos1 = points[0] - points[1];
        glm::vec3 pos2 = points[0] - points[2];
        glm::vec3 tangent = (dUV2.y * pos1 - dUV1.y * pos2)/(dUV2.y * dUV1.x - dUV1.y * dUV2.x);
        glm::vec3 bitangent;
        if(!fequal(dUV2.y, 0.0f))
            bitangent = (pos2 - dUV2.x * tangent) / dUV2.y;
        else
            bitangent = (pos1 - dUV1.x * tangent) / dUV1.y;
        result.tangent = tangent;
        result.bitangent = bitangent;
    }
    return result;
}
Esempio n. 5
0
Intersection SquarePlane::GetIntersection(Ray r)
{
    //Transform the ray
    Ray rLocal = r.GetTransformedCopy(transform.invT());
    Intersection result;

    //Ray-plane intersection
    float t = glm::dot(glm::vec3(0,0,1), (glm::vec3(0.5f, 0.5f, 0) - rLocal.origin)) / glm::dot(glm::vec3(0,0,1), rLocal.direction);
    glm::vec4 P = glm::vec4(t * rLocal.direction + rLocal.origin, 1);
    //Check that P is within the bounds of the square
    if(t > 0 && P.x >= -0.5f && P.x <= 0.5f && P.y >= -0.5f && P.y <= 0.5f)
    {
        result.point = glm::vec3(transform.T() * P);
        result.normal = glm::normalize(glm::vec3(transform.invTransT() * glm::vec4(ComputeNormal(glm::vec3(P)), 0)));
        result.object_hit = this;
        result.t = glm::distance(result.point, r.origin);
        //was interp
        result.texture_color = Material::GetImageColor(GetUVCoordinates(glm::vec3(P)), material->texture);

        glm::vec3 T = glm::normalize(glm::cross(glm::vec3(0,1,0), ComputeNormal(glm::vec3(P))));
        glm::vec3 B = glm::cross(ComputeNormal(glm::vec3(P)), T);
        result.tangent = glm::normalize(glm::vec3(transform.T() * glm::vec4(T, 0)));
        result.bitangent = glm::normalize(glm::vec3(transform.T() * glm::vec4(B, 0)));

        return result;
    }
    return result;
}
Esempio n. 6
0
Intersection SquarePlane::GetIntersection(Ray r)
{
    //Transform the ray
    Ray r_loc = r.GetTransformedCopy(transform.invT());
    Intersection result;

    //Ray-plane intersection
    float t = glm::dot(glm::vec3(0,0,1), (glm::vec3(0.5f, 0.5f, 0) - r_loc.origin)) / glm::dot(glm::vec3(0,0,1), r_loc.direction);
    glm::vec4 P = glm::vec4(t * r_loc.direction + r_loc.origin, 1);
    //Check that P is within the bounds of the square
    if(t > 0 && P.x >= -0.5f && P.x <= 0.5f && P.y >= -0.5f && P.y <= 0.5f)
    {
        result.point = glm::vec3(transform.T() * P);
        result.normal = glm::normalize(glm::vec3(transform.invTransT() * glm::vec4(ComputeNormal(glm::vec3(P)), 0)));
        result.object_hit = this;
        result.t = glm::distance(result.point, r.origin);
        result.texture_color = Material::GetImageColorInterp(GetUVCoordinates(glm::vec3(P)), material->texture);
        // Store the tangent and bitangent
        glm::vec3 tangent;
        glm::vec3 bitangent;
        ComputeTangents(ComputeNormal(glm::vec3(P)), tangent, bitangent);
        result.tangent = glm::normalize(glm::vec3(transform.T() * glm::vec4(tangent, 0)));
        result.bitangent = glm::normalize(glm::vec3(transform.T() * glm::vec4(bitangent, 0)));

        return result;
    }
    return result;
}
Intersection Ring::GetIntersection(Ray r)
{
    //Transform the ray
    Ray r_loc = r.GetTransformedCopy(transform.invT());
    Intersection result;

    //Ray-plane intersection
    float t = glm::dot(glm::vec3(0,0,1), (glm::vec3(0.5f, 0.5f, 0) - r_loc.origin)) / glm::dot(glm::vec3(0,0,1), r_loc.direction);
    glm::vec4 P = glm::vec4(t * r_loc.direction + r_loc.origin, 1);

    float dist2 = (P.x * P.x + P.y * P.y);
    if(t > 0 && dist2 <= 1.0f && dist2 >= 0.25f)
    {
        result.point = glm::vec3(transform.T() * P);
        result.object_hit = this;
        result.t = glm::distance(result.point, r.origin);
        result.texture_color = Material::GetImageColorInterp(GetUVCoordinates(glm::vec3(P)), material->texture);

        //Store the tangent and bitangent
        SetNormalTangentBitangent(glm::vec3(P),result);

        return result;
    }
    return result;
}
Esempio n. 8
0
Intersection SquarePlane::SquarePlane::GetIntersection(Ray r)
{
    //---Q5---
    //TODO
    static const float EPS( 1e-4 );
    Ray rInWorld = r;
    Intersection result;

    r = r.GetTransformedCopy( transform.invT() );
    result.t = -r.origin[ 2 ] / r.direction[ 2 ];

    if( result.t - EPS < 0.f ) return Intersection();

    result.point = r.origin + result.t * r.direction;

    if( glm::abs( result.point[ 0 ] ) > .5f ) return Intersection();
    if( glm::abs( result.point[ 1 ] ) > .5f ) return Intersection();

    result.color = material->GetImageColor( GetUVCoordinates( result.point ), material->texture ) * material->base_color;
    result.point = glm::vec3( transform.T() * glm::vec4( result.point, 1.f ) );
    result.normal = glm::normalize(glm::vec3( transform.invTransT() * glm::vec4( 0.f, 0.f, 1.f, 0.f ) ) );
    result.t = glm::length( result.point - rInWorld.origin );
    result.object_hit = this;

    return result;
}
Esempio n. 9
0
Intersection SquarePlane::GetSampledIntersection(float randX, float randY, const glm::vec3 &isx_normal)
{
    glm::vec4 point = glm::vec4(-0.5 + randX, -0.5 + randY, 0.f, 1.f);
    Intersection result;
    result.point = glm::vec3(transform.T() * point);
    result.normal = glm::normalize(glm::vec3(transform.invTransT() * glm::vec4(ComputeNormal(glm::vec3(point)), 0)));
    result.object_hit = this;
    result.texture_color = Material::GetImageColor(GetUVCoordinates(glm::vec3(point)), material->texture);
    return result;
}
Esempio n. 10
0
Intersection Sphere::GetIntersection(Ray r)
{
    //Transform the ray
    Ray r_loc = r.GetTransformedCopy(transform.invT());
    Intersection result;

    float A = pow(r_loc.direction[0], 2) + pow(r_loc.direction[1], 2) + pow(r_loc.direction[2], 2);
    float B = 2*(r_loc.direction[0]*r_loc.origin[0] + r_loc.direction[1] * r_loc.origin[1] + r_loc.direction[2] * r_loc.origin[2]);
    float C = pow(r_loc.origin[0], 2) + pow(r_loc.origin[1], 2) + pow(r_loc.origin[2], 2) - 0.25f;//Radius is 0.5f
    float discriminant = B*B - 4*A*C;
    //If the discriminant is negative, then there is no real root
    if(discriminant < 0){
        return result;
    }
    float t = (-B - sqrt(discriminant))/(2*A);
    if(t < 0)
    {
        t = (-B + sqrt(discriminant))/(2*A);
    }
    if(t >= 0)
    {
        glm::vec4 P = glm::vec4(r_loc.origin + t*r_loc.direction, 1);
        result.point = glm::vec3(transform.T() * P);
        glm::vec2 uv = GetUVCoordinates(glm::vec3(P));
        result.normal = glm::normalize(glm::vec3(transform.invTransT() * (P - glm::vec4(0,0,0,1))));
        result.t = glm::distance(result.point, r.origin);
        result.texture_color = Material::GetImageColorInterp(uv, material->texture);
        result.object_hit = this;
        //TODO: Store the tangent and bitangent

        glm::vec3 N( glm::normalize( glm::vec3( P ) ) );
        glm::vec4 T, B;

        if( glm::length( N - glm::vec3( 0.f, 0.f, 1.f ) ) < 1e-5 ){
            T = glm::vec4( 1.f, 0.f, 0.f, 0.f );
            B = glm::vec4( 0.f, 1.f, 0.f, 0.f );
        }else if( glm::length( N - glm::vec3( 0.f, 0.f, -1.f ) ) ){
            T = glm::vec4( 1.f, 0.f, 0.f, 0.f );
            B = glm::vec4( 0.f, -1.f, 0.f, 0.f );
        }else{
            glm::vec3 Z( 0.f, 0.f, 1.f );

            T = glm::vec4( glm::cross( Z, N ), 0.f );
            B = glm::vec4( glm::cross( N, glm::vec3( T ) ), 0.f );
        }

        result.tangent = glm::normalize( glm::vec3( transform.T() * T ) );
        result.bitangent = glm::normalize( glm::vec3( transform.T() * B ) );

        return result;
    }
    return result;
}
Esempio n. 11
0
Intersection Disc::GetSampledIntersection(float randX, float randY, const glm::vec3 &isx_normal)
{
    float r = sqrtf(randX);
    float theta = 2.f * M_PI * randY;
    glm::vec4 point = glm::vec4(
                        r*cosf(theta),
                        r*sinf(theta),
                        0.f,
                        1.f
                       );
    Intersection result;
    result.point = glm::vec3(transform.T() * point);
    result.normal = glm::normalize(glm::vec3(transform.invTransT() * glm::vec4(ComputeNormal(glm::vec3(point)), 0)));
    result.object_hit = this;
    result.texture_color = Material::GetImageColor(GetUVCoordinates(glm::vec3(point)), material->texture);
    return result;
}
Intersection Ring::SampleOnGeometrySurface(const float &u, const float &v, const glm::vec3 &point)
{
    float r =  0.5f + u * 0.5f;
    float theta = v * 2.0f * PI;

    glm::vec3 hitPoint(r * cos(theta),
                       r * sin(theta),
                       0.0f);

    Intersection result;
    result.point = glm::vec3(transform.T() * glm::vec4(hitPoint, 1.0f));
    result.object_hit = this;
    result.texture_color = Material::GetImageColorInterp(GetUVCoordinates(hitPoint), material->texture);

    //Store the tangent and bitangent
    SetNormalTangentBitangent(hitPoint,result);

    result.t = 1.0f;

    return result;
}
Esempio n. 13
0
Intersection Cube::GetIntersection(Ray r)
{
    //Transform the ray
    Ray r_loc = r.GetTransformedCopy(transform.invT());
    Intersection result;

    float t_n = -1000000.f;
    float t_f = 1000000.f;
    for(int i = 0; i < 3; i++){
        //Ray parallel to slab check
        if(r_loc.direction[i] == 0){
            if(r_loc.origin[i] < -0.5f || r_loc.origin[i] > 0.5f){
                return result;
            }
        }
        //If not parallel, do slab intersect check
        float t0 = (-0.5f - r_loc.origin[i])/r_loc.direction[i];
        float t1 = (0.5f - r_loc.origin[i])/r_loc.direction[i];
        if(t0 > t1){
            float temp = t1;
            t1 = t0;
            t0 = temp;
        }
        if(t0 > t_n){
            t_n = t0;
        }
        if(t1 < t_f){
            t_f = t1;
        }
    }
    float t_final = -1;
    if(t_n < t_f)
    {
        if(t_n >= 0)
        {
            t_final = t_n;
        }
        else if(t_f >= 0)
        {
            t_final = t_f;
        }
    }
    if(t_final >= 0)
    {
        //Lastly, transform the point found in object space by T
        glm::vec4 P = glm::vec4(r_loc.origin + t_final*r_loc.direction, 1);
        glm::vec4 N( glm::normalize( GetCubeNormal( P ) ) );
        result.point = glm::vec3(transform.T() * P);
        result.normal = glm::normalize(glm::vec3(transform.invTransT() * N));
        result.object_hit = this;
        result.t = glm::distance(result.point, r.origin);
        result.texture_color = Material::GetImageColorInterp(GetUVCoordinates(glm::vec3(P)), material->texture);
        //TODO: Store the tangent and bitangent

        glm::vec4 T( 0.f ), B( 0.f );

        if( N[ 0 ] < -.9f ){
            T = glm::vec4( 0.f, -1.f, 0.f, 0.f );
        }else if( N[ 0 ] > .9f ){
            T = glm::vec4( 0.f, 1.f, 0.f, 0.f );
        }else if( N[ 1 ] < -.9f ){
            T = glm::vec4( 0.f, 0.f, -1.f, 0.f );
        }else if( N[ 1 ] > .9f ){
            T = glm::vec4( 0.f, 0.f, 1.f, 0.f );
        }else if( N[ 2 ] < -.9f ){
            T = glm::vec4( -1.f, 0.f, 0.f, 0.f );
        }else{
            T = glm::vec4( 1.f, 0.f, 0.f, 0.f );
        }

        B = glm::vec4( glm::cross( glm::vec3( N ), glm::vec3( T ) ), 0.f );

        result.tangent = glm::normalize( glm::vec3( transform.T() * T ) );
        result.bitangent = glm::normalize( glm::vec3( transform.T() * B ) );

        return result;
    }
    else{
        return result;
    }
}
Esempio n. 14
0
Intersection Cube::GetIntersection(Ray r)
{
    //---Q5---
    //TODO
    Ray rInWorld( r );
    r = r.GetTransformedCopy( transform.invT() );

    static const float EPS = 1e-4;
    float t_near = -1e6;
    float t_far = 1e6;

    for( int i = 0; i < 3; ++i ){

        if( glm::abs( r.direction[ i ] ) < EPS ){
            if( r.origin[ i ] - EPS < -.5f || r.origin[ i ] + EPS > .5f ){
                return Intersection();
            }else{
                continue;
            }
        }

        float t0, t1;

        t0 = ( -.5f - r.origin[ i ] ) / r.direction[ i ];
        t1 = ( .5f - r.origin[ i ] ) / r.direction[ i ];

        if( t0 + EPS > t1 ){
            float tmp = t0;
            t0 = t1;
            t1 = tmp;
        }

        if( t0 + EPS > t_near ){
            t_near = t0;
        }

        if( t1 - EPS < t_far ){
            t_far = t1;
        }
    }

    if( t_near + EPS > t_far || t_far - EPS < 0.f ){
        return Intersection();
    }

    if( t_near - EPS < 0.f ){
        t_near = t_far;
    }

    int hit_face = -1;
    float least_distance = 1e6;
    glm::vec3 hit = r.origin + t_near * r.direction;

    if( glm::abs( hit[ 0 ] + .5f ) < least_distance ){
        hit_face = 0;
        least_distance = glm::abs( hit[ 0 ] + .5f );
    }
    if( glm::abs( hit[ 0 ] - .5f ) < least_distance ){
        hit_face = 1;
        least_distance = glm::abs( hit[ 0 ] - .5f );
    }
    if( glm::abs( hit[ 1 ] + .5f ) < least_distance ){
        hit_face = 2;
        least_distance = glm::abs( hit[ 1 ] + .5f );
    }
    if( glm::abs( hit[ 1 ] - .5f ) < least_distance ){
        hit_face = 3;
        least_distance = glm::abs( hit[ 1 ] - .5f );
    }
    if( glm::abs( hit[ 2 ] + .5f ) < least_distance ){
        hit_face = 4;
        least_distance = glm::abs( hit[ 2 ] + .5f );
    }
    if( glm::abs( hit[ 2 ] - .5f ) < least_distance ){
        hit_face = 5;
        least_distance = glm::abs( hit[ 2 ] - .5f );
    }

    Intersection result;

    result.point = glm::vec3( transform.T() * glm::vec4( hit, 1.f ) );
    switch( hit_face ){
    case 0:
        result.normal = glm::vec3( -1, 0, 0 );
        break;
    case 1:
        result.normal = glm::vec3( 1, 0, 0 );
        break;
    case 2:
        result.normal = glm::vec3( 0, -1, 0 );
        break;
    case 3:
        result.normal = glm::vec3( 0, 1, 0 );
        break;
    case 4:
        result.normal = glm::vec3( 0, 0, -1 );
        break;
    case 5:
        result.normal = glm::vec3( 0, 0, 1 );
        break;
    }

    result.normal = glm::normalize( glm::vec3( transform.invTransT() * glm::vec4( result.normal, 0.f ) ) );
    result.t = glm::distance( result.point, rInWorld.origin );
    result.object_hit = this;
    result.color = material->GetImageColor( GetUVCoordinates( hit ), material->texture ) * material->base_color;

    return result;
}