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
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
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
00072 Ray r = cam->getRay(Point2D(x,y));
00073
00074
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
00098 RGBColor fr = mat->sample(r.dir()*-1,dirFromLight, is);
00099
00100 float angle = dirFromLight*is.getSNormalW();
00101 if(angle > 0)
00102 Lr = Lr + sample.power() * fr * angle * sample.weight();
00103 }
00104
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 }