00001
00005 #include "LambertianMaterial.h"
00006 #include "HitRecord.h"
00007 #include "Light.h"
00008 #include "Point.h"
00009 #include "Primitive.h"
00010 #include "Ray.h"
00011 #include "RenderContext.h"
00012 #include "Scene.h"
00013 #include "Vector.h"
00014 #include "Math.h"
00015 using namespace std;
00016
00017 LambertianMaterial::LambertianMaterial(const Color& color, float Kd, float Ka)
00018 :color(color), Kd(Kd), Ka(Ka)
00019 {
00020 }
00021
00022 LambertianMaterial::~LambertianMaterial()
00023 {
00024 }
00025
00026 void LambertianMaterial::shade(Color& result, const RenderContext& context,
00027 const Ray& ray, const HitRecord& hit, const Color&, int) const
00028 {
00029 const Scene* scene = context.getScene();
00030 const vector<Light*>& lights = scene->getLights();
00031 Point hitpos = ray.origin()+ray.direction()*hit.minT();
00032 Vector normal;
00033 hit.getPrimitive()->normal(normal, context, hitpos, ray, hit);
00034 double costheta = Dot(normal, ray.direction());
00035 if(costheta > 0)
00036 normal = -normal;
00037
00038 const Object* world = scene->getObject();
00039
00040 Color light = scene->getAmbient()*Ka;
00041
00042 #if 0
00043 for(vector<Light*>::const_iterator iter = lights.begin(); iter != lights.end(); iter++){
00044 #else
00045 Light * const * begin = &lights[0];
00046 Light*const* end = &lights[0]+lights.size();
00047 while(begin != end){
00048 #endif
00049 Color light_color;
00050 Vector light_direction;
00051 double dist = (*begin++)->getLight(light_color, light_direction, context, hitpos);
00052
00053 Vector unit_dir = light_direction;
00054 unit_dir.normalize();
00055 double cosphi = Dot(normal, light_direction);
00056 if(cosphi > 0){
00057
00058 #if 0
00059 HitRecord shadowhit(dist);
00060 Point new_origin = hitpos + light_direction * 1e-3;
00061 Ray shadowray(new_origin, light_direction);
00062 #else
00063 HitRecord shadowhit(dist, 1e-5);
00064 Ray shadowray(hitpos, light_direction);
00065 #endif
00066 world->intersect(shadowhit, context, shadowray);
00067 if(!shadowhit.getPrimitive())
00068
00069 light += light_color*(Kd*cosphi);
00070 }
00071 }
00072 result = light*color;
00073 }