Vector4* findViewDirection(double xS, double yS, double zS){ Vector4* V = new Vector4(); V->SetVector4(eX-xS, eY-yS, eZ-zS,1.0); V->ConvertToUnit(); return V; }
Vector4* findNormalToSphere(double xS, double yS, double zS, Sphere& sphere){ //Coordinates of the centre of the sphere. double x_c = sphere.position[0]; double y_c = sphere.position[1]; double z_c = sphere.position[2]; //radius of the sphere. double S_r = sphere.radius; Vector4* normal = new Vector4(); normal->SetVector4(xS-x_c, yS-y_c, zS-z_c, 1.0); normal->ConvertToUnit(); return normal; }
Vector4* findNormalToTriangle(double xS, double yS, double zS, Triangle& triangle){ double x0 = triangle.v[0].position[0]; double y0 = triangle.v[0].position[1]; double z0 = triangle.v[0].position[2]; double x1 = triangle.v[1].position[0]; double y1 = triangle.v[1].position[1]; double z1 = triangle.v[1].position[2]; double x2 = triangle.v[2].position[0]; double y2 = triangle.v[2].position[1]; double z2 = triangle.v[2].position[2]; //Calculate the vertices of the triangle. auto_ptr<Vector4> P0(new Vector4()); P0->SetVector4(x0,y0,z0,1.0f); auto_ptr<Vector4> P1(new Vector4()); P1->SetVector4((float)x1,(float)y1,(float)z1,1.0f); auto_ptr<Vector4> P2(new Vector4()); P2->SetVector4((float)x2,(float)y2,(float)z2,1.0f); auto_ptr<Vector4> P(new Vector4()); P->SetVector4((float)xS,(float)yS,(float)zS,1.0f); //Vector from one vertex to other vertex. auto_ptr<Vector4> Edge01(P0->Subtract(*P1, *P0)); auto_ptr<Vector4> Edge12(P1->Subtract(*P2, *P1)); auto_ptr<Vector4> Edge20(P2->Subtract(*P0, *P2)); //Area of the complete triangle. double area_P0P1P2 = (0.5*Edge01->CrossProduct(*Edge01, *Edge20)->GetMagnitude()); assert(area_P0P1P2 > 0); //Area of PP0P2 auto_ptr<Vector4> EdgePP2(new Vector4()); EdgePP2->SetVector4(xS-x2, yS-y2, zS-z2,1); double area_PP0P2 = (0.5*Edge20->CrossProduct(*Edge20, *EdgePP2)->GetMagnitude()); assert(area_PP0P2 >= 0.0); //Area of PP1P2 double area_PP1P2 = (0.5 * EdgePP2->CrossProduct(*EdgePP2, *Edge12)->GetMagnitude()); assert(area_PP1P2 >= 0); //Area of PP0P1 auto_ptr<Vector4> EdgePP0(new Vector4()); EdgePP0->SetVector4(xS-x0, yS-y0, zS-z0,1); double area_PP0P1 = (0.5*Edge01->CrossProduct(*Edge01, *EdgePP0)->GetMagnitude()); assert(area_PP0P1 >= 0);//I am here double alpha = area_PP1P2/area_P0P1P2; double beta = area_PP0P2/area_P0P1P2; double gamma = area_PP0P1/area_P0P1P2; double n0_x = triangle.v[0].normal[0]; double n0_y = triangle.v[0].normal[1]; double n0_z = triangle.v[0].normal[2]; auto_ptr<Vector4> N0(new Vector4()); N0->SetVector4(n0_x, n0_y, n0_z, 1); double n1_x = triangle.v[1].normal[0]; double n1_y = triangle.v[1].normal[1]; double n1_z = triangle.v[1].normal[2]; auto_ptr<Vector4> N1(new Vector4()); N1->SetVector4(n1_x, n1_y, n1_z, 1); double n2_x = triangle.v[2].normal[0]; double n2_y = triangle.v[2].normal[1]; double n2_z = triangle.v[2].normal[2]; auto_ptr<Vector4> N2(new Vector4()); N2->SetVector4(n2_x, n2_y, n2_z, 1); N0->Elongate(alpha); N1->Elongate(beta); N2->Elongate(gamma); Vector4* normalTemp = N0->Add(*N0, *N1); Vector4* normal = N0->Add(*normalTemp, *N2); delete normalTemp; normal->ConvertToUnit(); return normal; }
Color* getColor(Vector4& viewVector, double x, double y, double z, int depth){ Color* color = new Color(0,0,0); int red = 0; int green = 0; int blue = 0; double ka_red = 0.0; double ka_green = 0.0; double ka_blue = 0.0; double kd_red = 0.0; double kd_green = 0.0; double kd_blue = 0.0; double ks_red = 0.0; double ks_green= 0.0; double ks_blue = 0.0; double shininess = 0.0; //The view vector from the point of intersection to where the user is standing. Vector4* V = findViewDirection(x,y,z); V->ConvertToUnit(); //The normal vector to the surface obtained by interpolating the normals. Vector4* N = new Vector4(); N->SetVector4(0,0,0,1); if(iType == SPHERE){ N->GetCopyOf( *findNormalToSphere(x,y,z,spheres[index_sphere]) ); N->ConvertToUnit(); kd_red = spheres[index_sphere].color_diffuse[0]; kd_green = spheres[index_sphere].color_diffuse[1]; kd_blue = spheres[index_sphere].color_diffuse[2]; ks_red = spheres[index_sphere].color_specular[0]; ks_green = spheres[index_sphere].color_specular[1]; ks_blue = spheres[index_sphere].color_specular[2]; shininess = spheres[index_sphere].shininess; } if(iType == TRIANGLE){ N->GetCopyOf( *findNormalToTriangle(x,y,z,triangles[index_triangle]) ); N->ConvertToUnit(); Vector4* Kd = interpolateKd(x,y,z, triangles[index_triangle]); Vector4* Ks = interpolateKs(x,y,z, triangles[index_triangle]); kd_red = Kd->getX(); kd_green = Kd->getY(); kd_blue = Kd->getZ(); ks_red = Ks->getX(); ks_green = Ks->getY(); ks_blue = Ks->getZ(); shininess = interpolateShininess(x,y,z, triangles[index_triangle]); delete Kd; delete Ks; } ka_red = kd_red; ka_green = kd_green; ka_blue = kd_blue; color->addMoreRed((int)getAmbientRed(ka_red)); color->addMoreGreen((int)getAmbientGreen(ka_green)); color->addMoreBlue((int)getAmbientBlue(ka_blue)); int i =0; for(i = 0; i<num_lights; i++){ //Light Vector (From the point of intersection to the light source) auto_ptr<Vector4> L(findLightDirection(x,y,z,lights[i])); L->ConvertToUnit(); //Reflected Ray Vector auto_ptr<Vector4> R(findReflectedRayDirection(*N, *L)); R->ConvertToUnit(); double LN = L->DotProduct(*L, *N); double RV = R->DotProduct(*R, *V); // if(isShadowed(x,y,z,lights[i]) and LN>=0){ if(isShadowed(x,y,z,lights[i])){ red = 0; green = 0; blue = 0; }else{ red = getRed(lights[i].color[0], ka_red, kd_red, ks_red, LN, RV, shininess); green = getGreen(lights[i].color[1], ka_green, kd_green, ks_green, LN, RV, shininess); blue = getBlue(lights[i].color[2], ka_blue, kd_blue, ks_green, LN, RV, shininess); } // cout << "more Red "<<red<<", ";///////////////////////////////////////////////////////// // cout << "more Green "<<green<<", "; // cout << "more Blue "<<blue<<endl; color->addMoreRed(red); color->addMoreGreen(green); color->addMoreBlue(blue); // if(depth < MAX_DEPTH){ // auto_ptr<Ray> reflRay(new Ray(x,y,z,R->getX(), R->getY(), R->getZ())); // Color* newColor = traceRay(*reflRay, depth+1); // // int newRed = (int)ks_red*newColor->getRed(); // int newGreen = (int)ks_green*newColor->getGreen(); // int newBlue = (int)ks_blue*newColor->getBlue(); // // color->addMoreRed(newRed); // color->addMoreGreen(newGreen); // color->addMoreBlue(newBlue); // // delete newColor; // } } if(depth < MAX_DEPTH){ auto_ptr<Vector4> reflVector(findReflectedRayDirection(*N, viewVector)); reflVector->ConvertToUnit(); auto_ptr<Ray> reflRay(new Ray(x,y,z,-1,-1,-1)); reflRay->setXd(reflVector->getX()); reflRay->setYd(reflVector->getY()); reflRay->setZd(reflVector->getZ()); double t_new = findIntersect(*reflRay); if(t_new != NO_INTERSECTION){ double new_x_boom = getXIntersect(*reflRay, t_new); double new_y_boom = getYIntersect(*reflRay, t_new); double new_z_boom = getZIntersect(*reflRay, t_new); Color* newColor = getColor(*reflVector, new_x_boom, new_y_boom, new_z_boom, depth+1); int newRed = (int)(ks_red*newColor->getRed()); int newGreen = (int)(ks_green*newColor->getGreen()); int newBlue = (int)(ks_blue*newColor->getBlue()); //cout<<"new colors"<<newRed<<", "<<newGreen<<", "<<newBlue<<endl; color->addMoreRed(newRed); color->addMoreGreen(newGreen); color->addMoreBlue(newBlue); delete newColor; } } delete N; iType = NONE; return color; }