fixed Box::Extend(Vec3f&)
[MicroTrace.git] / SpotLight.cxx
index 8ec7cf6..0ccef8a 100644 (file)
@@ -4,15 +4,16 @@ SpotLight::SpotLight(Scene* scene,
                     const Vec3f& pos,
                     const Vec3f& dir,
                     const Vec3f& intensity,
-                    float alpha_min,
-                    float alpha_max)
+                    float alpha_min, // in degree
+                    float alpha_max) // in degree
   : Light(scene),
     m_pos(pos),
     m_dir(dir),
     m_intensity(intensity),
-    m_alpha_min(alpha_min),
+    m_alpha_min(alpha_min), 
     m_alpha_max(alpha_max)
 {
+  m_dir.normalize();
 }
 
 SpotLight::~SpotLight()
@@ -30,9 +31,47 @@ SpotLight::SpotLight()
 }
 
 bool
-SpotLight::Illuminate(Ray& ray, Vec3f& intensity)
+SpotLight::Illuminate(Ray& shadow_ray, Vec3f& intensity)
 {
-  return false;
+  // direction vector from light source to surface point
+  Vec3f D = shadow_ray.origin()-m_pos;
+  D.normalize();
+  // angle between light source dir and shadow ray dir
+  float phi = fabs(acos(D.dot(m_dir))*180/M_PI);
+  
+  // outside cone
+  if(phi > m_alpha_max) 
+    {
+      return false;
+    }
+  else 
+    {
+      Vec3f dir = m_pos-shadow_ray.origin();
+      float r = dir.norm()-Epsilon;
+      float falloff = 1.0f/(r*r); // falloff for distance
+      
+      // modify ray for shadow computation
+      shadow_ray.setHit(0);
+      // for shadow calculation
+      shadow_ray.setT(r);
+      // set direction to light source
+      dir.normalize();
+      shadow_ray.setDir(dir);
+
+      if(phi < m_alpha_min) 
+       {
+         intensity = m_intensity * falloff;
+       }
+      else 
+       {
+         // linear falloff from 1 at alpha_min to 0 at alpha_max 
+         float partial = 1.0f-(phi-m_alpha_min)/(m_alpha_max-m_alpha_min);
+         intensity = m_intensity * falloff * partial;
+         
+       }
+      return true;
+    }
+  return true;
 }
 
 const Vec3f&
@@ -46,3 +85,9 @@ SpotLight::direction() const
 {
   return m_dir;
 }
+
+bool
+SpotLight::IsArea()
+{
+  return false;
+}
This page took 0.026999 seconds and 4 git commands to generate.