src/rcrt/tracing/RayCaster.cpp

Go to the documentation of this file.
00001 #include "RayCaster.h"
00002 #include "../Intersection.h"
00003 #include "../objects/SolidObject.h"
00004 #include "../lights/Light.h"
00005 #include "../lights/LightSample.h"
00006 #include "../materials/Material.h"
00007 #include <vector>
00008 #include <algorithm>
00009 
00010 using namespace std;
00011 
00012 namespace rcrt
00013 {
00014 
00015 RayCaster::RayCaster(Scene* s):TracingStrategy(s)
00016 {
00017 }
00018 
00019 RayCaster::~RayCaster()
00020 {
00021 }
00022 
00023 RGBColor RayCaster::trace(Ray& r) const
00024 {
00025         Intersection is = scene->intersect(r);
00026         if(is.isValid()){
00027                 vector<Light*>* const lights = scene->getLights();
00028                 Material* mat = is.getPrimitive()->getParent()->getMaterial();
00029                 RGBColor result(0);
00030                 for(unsigned int i = 0; i < lights->size(); i++){
00031                         Light* const light = lights->at(i);
00032                         RGBColor Lr(0);
00033                         std::vector<LightSample> samples;
00034                         if(light->hasSampler()){
00035                                 light->getSampler()->sample(is.getPosition(), is.getSNormalW(), samples, light->getMinSamples(), scene);
00036                         }else
00037                                 light->illuminate(is.getPosition(), is.getSNormalW(), samples, light->getMinSamples(), scene);
00038                         
00039                         for(unsigned int s = 0; s < samples.size(); s++){
00040                                 const LightSample& sample = samples[s];
00041                                 //only cast shadows for manually sampled lights
00042                                 if(!light->hasSampler() && scene->castShadows() &&
00043                                                 scene->isOccluded(is.getPosition(), sample.dirToLight(), sample.dist())){
00044                                         continue;
00045                                 }
00046                                 const Vec3D dirFromLight = (sample.dirToLight() * -1).normalize();
00047                                 RGBColor fr = mat->sample(r.dir()*-1,dirFromLight, is);
00048                                 float angle = dirFromLight*is.getSNormalW();
00049                                 Lr = Lr + sample.power() * fr * fabs(angle) * sample.weight();
00050                         }
00051                         //cout << "[RayCaster]: contribution of source "<< i <<" = "<<Lr<<endl;
00052                          
00053                         result = result + Lr;
00054                 }
00055                 return result;
00056                 
00057         }
00058         return RGBColor::BLACK;
00059 }
00060 
00061 Image RayCaster::trace(Camera* cam, std::vector<Primitive*>* trList) const
00062 {
00063         const int& resX = cam->getResolutionX();
00064         const int& resY = cam->getResolutionY();
00065         float triangles = 0;
00066         Image img(resX, resY);
00067         clock_t start = clock();
00068         double dif;
00069         for(int x=0; x < resX; x++){
00070                 for(int y=0; y < resY; y++){
00071                         // primary ray to trace
00072             Ray r = cam->getRay(Point2D(x,y));
00073             
00074             // ray trace the list
00075             Intersection is;
00076             for(unsigned int i=0; i< trList->size(); i++){
00077                 Intersection curr = trList->at(i)->intersect(r);
00078                 if(curr.isValid() && curr.getDistance() <= is.getDistance()){
00079                                         is = curr;
00080                                 }
00081             }
00082             
00083             if(is.isValid()){
00084                 vector<Light*>* const lights = scene->getLights();
00085                         Material* mat = is.getPrimitive()->getParent()->getMaterial();
00086                         RGBColor result(0);
00087                         for(unsigned int i = 0; i < lights->size(); i++){
00088                                 Light* const light = lights->at(i);
00089                                         RGBColor Lr(0);
00090                                         std::vector<LightSample> samples;
00091                                         light->illuminate(is.getPosition(), is.getSNormalW(), samples, light->getMinSamples(), 0);
00092                                         for(unsigned int s = 0; s < samples.size(); s++){
00093                                                 const LightSample& sample = samples[i];
00094                                                 if(scene->castShadows() && scene->isOccluded(is.getPosition(), sample.dirToLight(), sample.dist()))
00095                                                         continue;                               
00096                                                 const Vec3D dirFromLight = (sample.dirToLight() * -1).normalize();
00097                                                 //cout << "[RayCaster]: Incident light: " << col << endl; 
00098                                                 RGBColor fr = mat->sample(r.dir()*-1,dirFromLight, is);
00099                                                 //cout << "[RayCaster]: -reflectance: " << fr << endl;
00100                                                 float angle = dirFromLight*is.getSNormalW();
00101                                                 if(angle > 0)
00102                                                         Lr = Lr + sample.power() * fr * angle * sample.weight();
00103                                         }
00104                                 //cout << "[RayCaster]: contribution of source "<< i <<" = "<<Lr<<endl;
00105                                  
00106                                 result = result + Lr;
00107                         }
00108                         RGBColor resC(min(1.0f,result.r()),min(1.0f,result.g()),min(1.0f,result.b()));
00109                 img.setPixel(resC, x, y);
00110             } else {
00111                 img.setPixel(RGBAColor(0), x, y);
00112             }
00113             
00114 
00115             triangles += r.tris;
00116         }
00117         }
00118         clock_t end = clock();
00119         dif = end-start;
00120         float triPray = triangles/(resX*resY);
00121         std::cout << "Average Triangle-Intersections per ray: " << triPray << "Triangles intersected: " << triangles << " Time for tracing: "<< dif/CLOCKS_PER_SEC << std::endl;
00122     return img;
00123 }
00124 
00125 }

Generated on Thu Jan 31 19:26:20 2008 for RenderingCompetitionRayTracer by  doxygen 1.5.3