Scene.cc

Go to the documentation of this file.
00001 
00005 #include "Scene.h"
00006 #include "Background.h"
00007 #include "Camera.h"
00008 #include "HitRecord.h"
00009 #include "Image.h"
00010 #include "Light.h"
00011 #include "Material.h"
00012 #include "Object.h"
00013 #include "Ray.h"
00014 #include "RenderContext.h"
00015 #include <float.h>
00016 #include <iostream>
00017 #include <stdlib.h>
00018 using namespace std;
00019 
00020 Scene::Scene()
00021 {
00022     object = 0;
00023     background = 0;
00024     camera = 0;
00025     ambient = Color(0, 0, 0);
00026     image = 0;
00027     minAttenuation = 0;
00028 }
00029 
00030 Scene::~Scene()
00031 {
00032     delete object;
00033     delete background;
00034     delete camera;
00035     delete image;
00036     for(int i=0;i<static_cast<int>(lights.size());i++){
00037         Light* light = lights[i];
00038         delete light;
00039     }
00040 }
00041 
00042 void Scene::preprocess()
00043 {
00044     background->preprocess();
00045     for(int i=0;i<static_cast<int>(lights.size());i++){
00046         Light* light = lights[i];
00047         light->preprocess();
00048     }
00049     double aspect_ratio = image->aspect_ratio();
00050     camera->preprocess(aspect_ratio);
00051     object->preprocess();
00052 }
00053 
00054 void Scene::render()
00055 {
00056     extern bool one_only;       // specter.cc
00057     extern int xpixel;          // specter.cc
00058     extern int ypixel;          // specter.cc
00059 
00060 
00061     if(!object || !background || !camera || !image){
00062         cerr << "Incomplete scene, cannot render!\n";
00063         exit(1);
00064     }
00065     int xres = image->getXresolution();
00066     int yres = image->getYresolution();
00067     RenderContext context(this);
00068     double dx = 2./xres;
00069     double xmin = -1. + dx/2.;
00070     double dy = 2./yres;
00071     double ymin = -1. + dy/2.;
00072     Color atten(1,1,1);
00073     if (one_only) {
00074 
00075         double y = ymin + ypixel*dy;
00076         double x = xmin + xpixel*dx;
00077 
00078         Ray ray;
00079         camera->makeRay(ray, context, x, y);
00080         HitRecord hit(DBL_MAX);
00081         object->intersect(hit, context, ray);
00082         Color result;
00083         if(hit.getPrimitive()){
00084             // Ray hit something...
00085             const Material* matl = hit.getMaterial();
00086             matl->shade(result, context, ray, hit, atten, 0);
00087         } else {
00088             background->getBackgroundColor(result, context, ray);
00089         }
00090         image->set(xpixel, ypixel, result);
00091     } else {
00092         for(int i=0 ; i<yres ; i++){
00093             //cerr << "y=" << i << '\n';
00094             double y = ymin + i*dy;
00095             for(int j=0;j<xres;j++){
00096                 double x = xmin + j*dx;
00097                 //cerr << "x=" << j << ", y=" << i << '\n';
00098                 Ray ray;
00099                 camera->makeRay(ray, context, x, y);
00100                 HitRecord hit(DBL_MAX);
00101                 object->intersect(hit, context, ray);
00102                 Color result;
00103                 if(hit.getPrimitive()){
00104                     // Ray hit something...
00105                     const Material* matl = hit.getMaterial();
00106                     matl->shade(result, context, ray, hit, atten, 0);
00107                 } else {
00108                     background->getBackgroundColor(result, context, ray);
00109                 }
00110                 image->set(j, i, result);
00111             }
00112         }
00113     }
00114 }
00115 double Scene::traceRay(Color& result, const RenderContext& context, const Ray& ray, const Color& atten, int depth) const
00116 {
00117     if(depth >= maxRayDepth || atten.maxComponent() < minAttenuation){
00118         result = Color(0, 0, 0);
00119         return 0;
00120     } else {
00121         HitRecord hit(DBL_MAX);
00122         object->intersect(hit, context, ray);
00123         if(hit.getPrimitive()){
00124             // Ray hit something...
00125             const Material* matl = hit.getMaterial();
00126             matl->shade(result, context, ray, hit, atten, depth);
00127             return hit.minT();
00128         } else {
00129             background->getBackgroundColor(result, context, ray);
00130             return DBL_MAX;
00131         }
00132     }
00133 }
00134 
00135 double Scene::traceRay(Color& result, const RenderContext& context, const Object* obj, const Ray& ray, const Color& atten, int depth) const
00136 {
00137     if(depth >= maxRayDepth || atten.maxComponent() < minAttenuation){
00138         result = Color(0, 0, 0);
00139         return 0;
00140     } else {
00141         HitRecord hit(DBL_MAX);
00142         obj->intersect(hit, context, ray);
00143         if(hit.getPrimitive()){
00144             // Ray hit something...
00145             const Material* matl = hit.getMaterial();
00146             matl->shade(result, context, ray, hit, atten, depth);
00147             return hit.minT();
00148         } else {
00149             background->getBackgroundColor(result, context, ray);
00150             return DBL_MAX;
00151         }
00152     }
00153 }

Generated on Tue Jan 29 21:34:54 2008 for specter by  doxygen 1.4.6