Color hitScene(struct Scene* scene, struct HitRecord* record, Ray ray, int depth){ Color result = {0, 0, 0}; for(int k = 0; k < scene->num_triangles; k++){ hitTriangle(&scene->triangles[k], record, ray); } if(record->has_hit){ result = addColors(result, shadeWithMaterial(scene, record, ray, depth)); } return result; }
//Loop for going over the set of triangles triangle* figureIntersection ( node* currNode, scene *myScene, coord* t ) { int intersect = 0; //flag for intersection occurrence coord limit = 2; //space max bound triangle* current = NULL; kdTreeNode* currPacket = currNode->currentPacket; coord u; //multiplication factor. The closest triangle has the smallest u //printf("intersection verification process\n"); while( 1 ) { TrigRefList* currTrigRef = currNode->currentPacket->trig; while( currTrigRef != NULL ) { if ( hitTriangle( &( currNode->v ), currTrigRef->ref, &u ) == 1 ) { //avoids self intersection if( currTrigRef->ref != currNode->lastIntercepted ) { if ( u < limit ) { current = currTrigRef->ref; limit = u; intersect = 1; //cout << "intersect! " << currTrigRef->ref->index // << endl; } } } // cout << "u: " << u << " limit " << limit // << " index " << currTrigRef->ref->index << endl; currTrigRef = currTrigRef->next; } if( intersect == 1 ) { //this avoids self intersection currNode->lastIntercepted = current; // printf( "Intersection found - Trig Index: %d\n\n", // current->index ); // cout << "current V1: x" << current->V1.x // << " y " << current->V1.y // << " z " << current->V1.z << endl; // cout << "current V1: x" << current->V2.x // << " y " << current->V2.y // << " z " << current->V2.z << endl; // cout << "current V1: x" << current->V3.x // << " y " << current->V3.y // << " z " << current->V3.z << endl; // cout << "packet: x0 " << currNode->currentPacket->x0 // << " y0 " << currNode->currentPacket->y0 // << " z0 " << currNode->currentPacket->z0 << endl; // cout << "packet: x1 " << currNode->currentPacket->x1 // << " y1 " << currNode->currentPacket->y1 // << " z0 " << currNode->currentPacket->z1 << endl; // exit(0); break; //intersection found } else { //printf( "getting next packet\n" ); currPacket = getTrianguleList( &( currNode->v ) , currNode->currentPacket, myScene->tree ); if( currPacket != NULL && currPacket != currNode->currentPacket ) { // currTrigRef = currPacket->trig; // for( int i = 0; i < currPacket->pnum; i++ ) // { // cout << "index: " << currTrigRef->ref->index << endl; // cout << "v1 - x: " << currTrigRef->ref->V1.x // << " y: " << currTrigRef->ref->V1.y // << " z: " << currTrigRef->ref->V1.z << endl; // cout << "v2 - x: " << currTrigRef->ref->V2.x // << " y: " << currTrigRef->ref->V2.y // << " z: " << currTrigRef->ref->V2.z << endl; // cout << "v3 - x: " << currTrigRef->ref->V3.x // << " y: " << currTrigRef->ref->V3.y // << " z: " << currTrigRef->ref->V3.z << endl; // cout << endl; // currTrigRef = currTrigRef->next; // } } else { //printf( "no more triangles\n" ); break; } currNode->currentPacket = currPacket; } } if ( current != NULL ) { *t = limit; } return current; }
//Function to calculate the color contribution of each ray color_fixed lightContribution ( node* currNode, scene *myScene ) { color_fixed c1 = { 0, 0, 0 }; coord t = currNode->t; triangle* intersection = currNode->lastIntercepted; if ( intersection == NULL ) { //printf( "no intersection \n" ); return c1; } point_fixed intersectionPoint = currNode->v.start + t * currNode->v.dir; vect_fixed normal = normalTriangle( intersection, myScene ); material intersectMat = myScene->materials[ intersection->materialId ]; for( unsigned int j = 0; j < myScene->NbLights; ++j ) { coord n1, n2; light currentl = myScene->lights[j]; // vector length from the intersection point to the l vect_fixed dist = currentl.pos - intersectionPoint; n1 = currNode->v.dir * normal; //root->v.dir.x * normal.x + root->v.dir.y * normal.y + root->v.dir.z // * normal.z ; if (n1 > 0) { normal.x = -normal.x; normal.y = -normal.y; normal.z = -normal.z; } n1 = currNode->v.dir * normal; n2 = dist * normal; if( n1 < 0 && n2 > 0 ) { //now let's create a ray from the intersection point to //the light source ray lightRay; lightRay.start = intersectionPoint; lightRay.dir = ( 1 / square_root( dist * dist ) ) * dist; //let's see if there are objects in the middle of the road that can // cause reflection or shadow // light ray and ray have to be in the same direction so proyection // from the light ray in the ray has to have the // same direction so cosI positive int shadow = 0; kdTreeNode* shadowPack = currNode->currentPacket; kdTreeNode* newShadowPack = NULL; //incrementing the ray starting point for avoiding self intersection //printf( "shadow verification process\n" ); while( 1 ) { TrigRefList* currTrigRef = shadowPack->trig; while( currTrigRef != NULL ) { coord u = 0; if ( hitTriangle( &lightRay, currTrigRef->ref, &u ) == 1 ) { if( u == 0 ) { //not self intersection in the same packet currTrigRef = currTrigRef->next; continue; } if ( currTrigRef->ref != currNode->lastIntercepted ) { //not self intersection in different packets //is it really necessary ? printf( "Intersection found - Trig Index: %d" \ "- shadow region for light %d\n\n ", currTrigRef->ref->index, j ); cout << "shadow ray start x: " << lightRay.start.x << " y: " << lightRay.start.y << " z: " << lightRay.start.z << endl; cout << "shadow ray dir x : " << lightRay.dir.x << " y: " << lightRay.dir.y << " z: " << lightRay.dir.z << endl; cout << "u: " << u; shadow = 1; break; } else { printf( "yes! It is necessary\n " ); //exit(0); } } currTrigRef = currTrigRef->next; } if( shadow == 1 ) { break; //shadow found } else { //printf( "getting next packet\n" ); newShadowPack = getTrianguleList( &lightRay, shadowPack, myScene->tree ); if( newShadowPack != NULL && newShadowPack != shadowPack ) { currTrigRef = newShadowPack->trig; // for( int i = 0; i < newShadowPack->pnum; i++ ) // { // cout << "index: " << currTrigRef->ref->index // << endl; // cout << "v1 - x: " << currTrigRef->ref->V1.x // << " y: " << currTrigRef->ref->V1.y << " z: " // << currTrigRef->ref->V1.z << endl; // cout << "v2 - x: " << currTrigRef->ref->V2.x // << " y: " << currTrigRef->ref->V2.y // << " z: " << currTrigRef->ref->V2.z << endl; // cout << "v3 - x: " << currTrigRef->ref->V3.x // << " y: " << currTrigRef->ref->V3.y // << " z: " << currTrigRef->ref->V3.z << endl; // cout << endl; // currTrigRef = currTrigRef->next; // } } else { //cout << "no more triangles" << endl; break; } shadowPack = newShadowPack; } } //we considered the objects as lambert-surface ones so this means // that the Intensity from the incoming ray // depends on the angle between the normal //if there's no shadow, we considered the current light source // effect : Io=In*cos(0); if ( shadow == 0 ) { mfp coef=1; for(unsigned int q=0; q<= (unsigned int)(currNode->level); ++q) { coef*=intersectMat.reflection; } if ((currNode->type==REFLECTED_RAY) || (currNode->type==ROOT_RAY) || (currNode->type==TOTAL_REFLECTED_RAY)) { // lambert // cout << " coef: " << coef // << " level: " << root->level << endl; // intensity from objects material mfp lambert = (lightRay.dir * normal) * coef; // cout << " lambert: " << lambert << endl; c1.red = c1.red + lambert * currentl.red * intersectMat.red; c1.green = (c1.green + lambert * currentl.green * intersectMat.green); c1.blue = (c1.blue + lambert * currentl.blue * intersectMat.blue); // cout << "color r2 R " << c1.red // << " g " << c1.green // << " b " << c1.blue << endl; } else if (currNode->type==REFRACTED_RAY) { //pseudo beer c1.red = c1.red + coef * intersectMat.red; c1.green = c1.green + coef * intersectMat.green; c1.blue = c1.blue + coef * intersectMat.blue; } } } else { //cout << "FFFUUUU" << endl; } } return c1; }