Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r334 - in trunk: Engine/Control Engine/Shadows Model/Cameras


Chronological Thread 
  • From: aek@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r334 - in trunk: Engine/Control Engine/Shadows Model/Cameras
  • Date: Sun, 22 May 2005 18:00:24 -0600 (MDT)

Author: aek
Date: Sun May 22 18:00:23 2005
New Revision: 334

Added:
   trunk/Model/Cameras/FisheyeCamera.cc
   trunk/Model/Cameras/FisheyeCamera.h
Modified:
   trunk/Engine/Control/RTRT_register.cc
   trunk/Engine/Shadows/BeamShadows.cc
   trunk/Engine/Shadows/BeamShadows.h
   trunk/Model/Cameras/CMakeLists.txt
Log:
* Got the 4-sample "beam" shadows working properly.  Each light source uses
  4 shadow samples, taken to points aranged in a tetrahedron around the light
  source.  This comes in 3 styles.  Style 0 is just a fixed tetrahedron.
  Style 1 orients the tetrahedron so that one of the vertices are always
  co-linear with the original lightsource position and the shadow position.
  Style 2 is like style 0, but uses Perlin noise with a given frequency and
  amplitude to jitter the sample points.  

  Example: ./manta -shadows "beam(radius 0.1 -style 2 -noisefreq 50.0 
-noiseamp 5.0)"

* Added a fisheye camera view.  This is capable of showing an entire 360
  degree field of view, and thus should be suitable for generating spherical
  environment maps (though this may require a bit of tweaking for the
  alignment.)  This camera's quite fun to play with.

  Example: ./manta -camera "fisheye(-eye 3 3 2 -lookat 0 0 1 -up 0 0 1 -fov 
270)"



Modified: trunk/Engine/Control/RTRT_register.cc
==============================================================================
--- trunk/Engine/Control/RTRT_register.cc       (original)
+++ trunk/Engine/Control/RTRT_register.cc       Sun May 22 18:00:23 2005
@@ -29,6 +29,7 @@
 #include <Model/Cameras/EnvironmentCamera.h>
 #include <Model/Cameras/PinholeCamera.h>
 #include <Model/Cameras/OrthogonalCamera.h>
+#include <Model/Cameras/FisheyeCamera.h>
 #include <Model/Groups/BVH.h>
 #include <Model/Groups/Group.h>
 #include <UserInterface/PromptUI.h>
@@ -45,9 +46,7 @@
 
     // Register image traversers
     rtrt->registerComponent("null", &NullImageTraverser::create);
-   
     rtrt->registerComponent("tiled", &TiledImageTraverser::create);
-         
     rtrt->registerComponent("frameless", &FramelessImageTraverser::create);
 
     // Register image types
@@ -83,6 +82,7 @@
     rtrt->registerComponent("environment", &EnvironmentCamera::create);
     rtrt->registerComponent("pinhole", &PinholeCamera::create);
     rtrt->registerComponent("orthogonal", &OrthogonalCamera::create);
+    rtrt->registerComponent("fisheye", &FisheyeCamera::create);
 
     // Register shadow algorithms
     rtrt->registerComponent("noshadows", &NoShadows::create);

Modified: trunk/Engine/Shadows/BeamShadows.cc
==============================================================================
--- trunk/Engine/Shadows/BeamShadows.cc (original)
+++ trunk/Engine/Shadows/BeamShadows.cc Sun May 22 18:00:23 2005
@@ -8,9 +8,12 @@
 #include <Interface/Scene.h>
 #include <Core/Util/Args.h>
 #include <Core/Exceptions/IllegalArgument.h>
+#include <Core/Math/Noise.h>
 
 using namespace Manta;
 
+static const double sqrt_two = 1.414213562373095;
+
 ShadowAlgorithm* BeamShadows::create(const vector<string>& args)
 {
   return new BeamShadows(args);
@@ -19,6 +22,8 @@
 BeamShadows::BeamShadows(const vector<string>& args)
 {
   bool gotRadius = false;
+  bool gotNoiseFreq = false;
+  bool gotNoiseAmp = false;
   int argc = static_cast<int>(args.size());
   for(int i=0; i< argc; i++){
     string arg = args[i];
@@ -26,12 +31,26 @@
       if(!getDoubleArg(i, args, radius))
         throw IllegalArgument("BeamShadows -radius", i, args);
       gotRadius = true;
+    } else if(arg == "-style") {
+      if(!getIntArg(i, args, style))
+        throw IllegalArgument("BeamShadows -style", i, args);
+    } else if(arg == "-noisefreq") {
+      if(!getDoubleArg(i, args, noisefreq))
+        throw IllegalArgument("BeamShadows -noisefreq", i, args);
+      gotNoiseFreq = true;
+    } else if(arg == "-noiseamp") {
+      if(!getDoubleArg(i, args, noiseamp))
+        throw IllegalArgument("BeamShadows -noiseamp", i, args);
+      gotNoiseAmp = true;
     } else {
       throw IllegalArgument("BeamShadows", i, args);
     }
   }
   if(!gotRadius)
     throw IllegalArgument("BeamShadows needs -radius", 0, args);
+  if(style==2&&!gotNoiseFreq&&!gotNoiseAmp)
+    throw IllegalArgument("BeamShadows style 2 needs -noisefreq and 
-noiseamp", 0, args);
+  noiseamp*=radius;
 }
 
 BeamShadows::~BeamShadows()
@@ -44,54 +63,155 @@
 {
   int nlights = lights->numLights();
   rays.computeHitPositions();
-
   int sidx = 0;
   int end = start;
-  while(end < rays.getSize() && sidx+nlights*4 <= RayPacket::MaxSize){
-    RayPacket::Element& e = rays.get(end++);
-    e.shadowBegin = sidx;
-    for(int l = 0;l<nlights;l++){
-
-      Vector dir(lights->centers[l]+Vector(0,0,radius*0.75)-e.hitPosition);
-      if(Dot(dir, e.normal) > 0){
-        RayPacket::Element& s = shadowRays.get(sidx++);
-        double length = dir.normalize();
-        s.ray.set(e.hitPosition, dir);
-        s.light = lights->colors[l] * 0.25;
-        s.hitInfo.reset(length);
+  switch( style ) {
+    case 0:                     // Static tetrahedron
+      while(end < rays.getSize() && sidx+nlights*4 <= RayPacket::MaxSize){
+        RayPacket::Element& e = rays.get(end++);
+        e.shadowBegin = sidx;
+        for(int l = 0;l<nlights;l++){
+          Vector dir( lights->centers[l]+Vector(0,0,radius)-e.hitPosition );
+          if(Dot(dir, e.normal) > 0){
+            RayPacket::Element& s = shadowRays.get(sidx++);
+            double length = dir.normalize();
+            s.ray.set(e.hitPosition, dir);
+            s.light = lights->colors[l] * 0.25;
+            s.hitInfo.reset(length);
+          }
+          dir = 
lights->centers[l]+Vector(-2.0/3.0/sqrt_two*radius,-6.0/sqrt_two*radius,-1.0/3.0*radius)-e.hitPosition;
+          if(Dot(dir, e.normal) > 0){
+            RayPacket::Element& s = shadowRays.get(sidx++);
+            double length = dir.normalize();
+            s.ray.set(e.hitPosition, dir);
+            s.light = lights->colors[l] * 0.25;
+            s.hitInfo.reset(length);
+          }
+          dir = 
lights->centers[l]+Vector(-2.0/3.0/sqrt_two*radius,6.0/sqrt_two*radius,-1.0/3.0*radius)-e.hitPosition;
+          if(Dot(dir, e.normal) > 0){
+            RayPacket::Element& s = shadowRays.get(sidx++);
+            double length = dir.normalize();
+            s.ray.set(e.hitPosition, dir);
+            s.light = lights->colors[l] * 0.25;
+            s.hitInfo.reset(length);
+          }
+          dir = 
lights->centers[l]+Vector(4.0/3.0/sqrt_two*radius,0,-1.0/3.0*radius)-e.hitPosition;
+          if(Dot(dir, e.normal) > 0){
+            RayPacket::Element& s = shadowRays.get(sidx++);
+            double length = dir.normalize();
+            s.ray.set(e.hitPosition, dir);
+            s.light = lights->colors[l] * 0.25;
+            s.hitInfo.reset(length);
+          }
+        }
+        e.shadowEnd = sidx;
       }
-
-      dir = lights->centers[l]+Vector(0,0,radius*0.25)-e.hitPosition;
-      if(Dot(dir, e.normal) > 0){
-        RayPacket::Element& s = shadowRays.get(sidx++);
-        double length = dir.normalize();
-        s.ray.set(e.hitPosition, dir);
-        s.light = lights->colors[l] * 0.25;
-        s.hitInfo.reset(length);
+      break;
+    case 1:                     // Tetrahedron orients to illuminated spot
+      while(end < rays.getSize() && sidx+nlights*4 <= RayPacket::MaxSize){
+        RayPacket::Element& e = rays.get(end++);
+        e.shadowBegin = sidx;
+        for(int l = 0;l<nlights;l++){
+          Vector axis_z( e.hitPosition - lights->centers[l] );
+          axis_z.normalize();
+          Vector axis_y( Cross( axis_z, Vector( 0.0, 0.0, 1.0 ) ) );
+          axis_y.normalize();
+          Vector axis_x( Cross( axis_y, axis_z ) );
+          axis_x.normalize();
+          axis_x*=radius;
+          axis_y*=radius;
+          axis_z*=radius;
+          Vector dir( lights->centers[l] - e.hitPosition +
+                      axis_z );
+          if(Dot(dir, e.normal) > 0){
+            RayPacket::Element& s = shadowRays.get(sidx++);
+            double length = dir.normalize();
+            s.ray.set(e.hitPosition, dir);
+            s.light = lights->colors[l] * 0.25;
+            s.hitInfo.reset(length);
+          }
+          dir = ( lights->centers[l] - e.hitPosition +
+                  (-6.0/sqrt_two) * axis_y +
+                  (-2.0/3.0/sqrt_two) * axis_x +
+                  (-1.0/3.0) * axis_z );
+          if(Dot(dir, e.normal) > 0){
+            RayPacket::Element& s = shadowRays.get(sidx++);
+            double length = dir.normalize();
+            s.ray.set(e.hitPosition, dir);
+            s.light = lights->colors[l] * 0.25;
+            s.hitInfo.reset(length);
+          }
+          dir = ( lights->centers[l] - e.hitPosition +
+                  (6.0/sqrt_two) * axis_y +
+                  (-2.0/3.0/sqrt_two) * axis_x +
+                  (-1.0/3.0) * axis_z );
+          if(Dot(dir, e.normal) > 0){
+            RayPacket::Element& s = shadowRays.get(sidx++);
+            double length = dir.normalize();
+            s.ray.set(e.hitPosition, dir);
+            s.light = lights->colors[l] * 0.25;
+            s.hitInfo.reset(length);
+          }
+          dir = ( lights->centers[l] - e.hitPosition +
+                  (-4.0/3.0/sqrt_two) * axis_x +
+                  (-1.0/3.0) * axis_z );
+          if(Dot(dir, e.normal) > 0){
+            RayPacket::Element& s = shadowRays.get(sidx++);
+            double length = dir.normalize();
+            s.ray.set(e.hitPosition, dir);
+            s.light = lights->colors[l] * 0.25;
+            s.hitInfo.reset(length);
+          }
+        }
+        e.shadowEnd = sidx;
       }
-
-      dir = lights->centers[l]+Vector(0,0,radius*-0.25)-e.hitPosition;
-      if(Dot(dir, e.normal) > 0){
-        RayPacket::Element& s = shadowRays.get(sidx++);
-        double length = dir.normalize();
-        s.ray.set(e.hitPosition, dir);
-        s.light = lights->colors[l] * 0.25;
-        s.hitInfo.reset(length);
+      break;
+    case 2:                     // Noised samples
+      while(end < rays.getSize() && sidx+nlights*4 <= RayPacket::MaxSize){
+        RayPacket::Element& e = rays.get(end++);
+        e.shadowBegin = sidx;
+        for(int l = 0;l<nlights;l++){
+          Vector dir( lights->centers[l]+Vector(0,0,radius)-e.hitPosition );
+          dir+=VectorNoise(Point(dir*noisefreq))*noiseamp;
+          if(Dot(dir, e.normal) > 0){
+            RayPacket::Element& s = shadowRays.get(sidx++);
+            double length = dir.normalize();
+            s.ray.set(e.hitPosition, dir);
+            s.light = lights->colors[l] * 0.25;
+            s.hitInfo.reset(length);
+          }
+          dir = 
lights->centers[l]+Vector(-2.0/3.0/sqrt_two*radius,-6.0/sqrt_two*radius,-1.0/3.0*radius)-e.hitPosition;
+          
dir+=VectorNoise(Point((dir+Vector(0,0,31.4159))*noisefreq))*noiseamp;
+          if(Dot(dir, e.normal) > 0){
+            RayPacket::Element& s = shadowRays.get(sidx++);
+            double length = dir.normalize();
+            s.ray.set(e.hitPosition, dir);
+            s.light = lights->colors[l] * 0.25;
+            s.hitInfo.reset(length);
+          }
+          dir = 
lights->centers[l]+Vector(-2.0/3.0/sqrt_two*radius,6.0/sqrt_two*radius,-1.0/3.0*radius)-e.hitPosition;
+          
dir+=VectorNoise(Point((dir+Vector(0,31.4159,0))*noisefreq))*noiseamp;
+          if(Dot(dir, e.normal) > 0){
+            RayPacket::Element& s = shadowRays.get(sidx++);
+            double length = dir.normalize();
+            s.ray.set(e.hitPosition, dir);
+            s.light = lights->colors[l] * 0.25;
+            s.hitInfo.reset(length);
+          }
+          dir = 
lights->centers[l]+Vector(4.0/3.0/sqrt_two*radius,0,-1.0/3.0*radius)-e.hitPosition;
+          
dir+=VectorNoise(Point((dir+Vector(31.4159,0,0))*noisefreq))*noiseamp;
+          if(Dot(dir, e.normal) > 0){
+            RayPacket::Element& s = shadowRays.get(sidx++);
+            double length = dir.normalize();
+            s.ray.set(e.hitPosition, dir);
+            s.light = lights->colors[l] * 0.25;
+            s.hitInfo.reset(length);
+          }
+        }
+        e.shadowEnd = sidx;
       }
-
-      dir = lights->centers[l]+Vector(0,0,radius*-0.75)-e.hitPosition;
-      if(Dot(dir, e.normal) > 0){
-        RayPacket::Element& s = shadowRays.get(sidx++);
-        double length = dir.normalize();
-        s.ray.set(e.hitPosition, dir);
-        s.light = lights->colors[l] * 0.25;
-        s.hitInfo.reset(length);
-      }
-
-    }
-    e.shadowEnd = sidx;
+      break;
   }
-
   
shadowRays.setFlag(RayPacket::NormalizedDirections|RayPacket::HaveHitRecords);
   shadowRays.resize(sidx);
   if(end == start+1)

Modified: trunk/Engine/Shadows/BeamShadows.h
==============================================================================
--- trunk/Engine/Shadows/BeamShadows.h  (original)
+++ trunk/Engine/Shadows/BeamShadows.h  Sun May 22 18:00:23 2005
@@ -28,6 +28,9 @@
     BeamShadows& operator=(const BeamShadows&);
 
     double radius;
+    int style;
+    double noisefreq;
+    double noiseamp;
   };
 }
 

Modified: trunk/Model/Cameras/CMakeLists.txt
==============================================================================
--- trunk/Model/Cameras/CMakeLists.txt  (original)
+++ trunk/Model/Cameras/CMakeLists.txt  Sun May 22 18:00:23 2005
@@ -2,4 +2,5 @@
 SET (Manta_Cameras_SRCS
      Cameras/EnvironmentCamera.cc
      Cameras/PinholeCamera.cc
-     Cameras/OrthogonalCamera.cc)
+     Cameras/OrthogonalCamera.cc
+     Cameras/FisheyeCamera.cc)

Added: trunk/Model/Cameras/FisheyeCamera.cc
==============================================================================
--- (empty file)
+++ trunk/Model/Cameras/FisheyeCamera.cc        Sun May 22 18:00:23 2005
@@ -0,0 +1,187 @@
+
+#include <MantaTypes.h>
+#include <Model/Cameras/FisheyeCamera.h>
+#include <Core/Util/Args.h>
+#include <Core/Exceptions/IllegalArgument.h>
+#include <Interface/RayPacket.h>
+#include <Core/Geometry/BBox.h>
+#include <Core/Geometry/AffineTransform.h>
+#include <Core/Math/MiscMath.h>
+#include <Core/Math/Trig.h>
+#include <Core/Util/Assert.h>
+#include <iostream>
+
+using namespace Manta;
+using namespace std;
+using SCIRun::Clamp;
+
+static const double sqrt_two = 1.4142135623730951;
+
+FisheyeCamera::FisheyeCamera(const vector<string>& args)
+{
+  bool gotEye = false;
+  bool gotLookat = false;
+  bool gotFov = false;
+  bool gotUp = false;
+  int argc = static_cast<int>(args.size());
+  for(int i=0; i< argc; i++){
+    string arg = args[i];
+    if(arg == "-eye"){
+      if(!getPointArg(i, args, eye))
+       throw IllegalArgument("FisheyeCamera -eye", i, args);
+      gotEye = true;
+    } else if(arg == "-lookat"){
+      if(!getPointArg(i, args, lookat))
+       throw IllegalArgument("FisheyeCamera -lookat", i, args);
+      gotLookat = true;
+    } else if(arg == "-up"){
+      if(!getVectorArg(i, args, up))
+       throw IllegalArgument("FisheyeCamera -up", i, args);
+      gotUp = true;
+    } else if(arg == "-fov"){
+      if(!getDoubleArg(i, args, hfov))
+       throw IllegalArgument("FisheyeCamera -fov", i, args);
+      gotFov = true;
+    } else {
+      throw IllegalArgument("FisheyeCamera", i, args);
+    }
+  }
+  if(!gotEye || !gotLookat || !gotUp || !gotFov)
+    throw IllegalArgument("FisheyeCamera needs -eye -lookat -up and -fov", 
0, args);
+  setup();
+  hfov = hfov / 90.0;
+}
+
+FisheyeCamera::~FisheyeCamera()
+{
+}
+
+Camera* FisheyeCamera::create(const vector<string>& args)
+{
+  return new FisheyeCamera(args);
+}
+
+void FisheyeCamera::setup()
+{
+  int i;
+  vfov = hfov;
+  direction=lookat-eye;
+  nearZ=direction.length();
+
+  n = direction;
+  n.normalize();
+
+  for(i=0; i<3; i++)
+    uvn[2][i] = n[i];
+
+  v=Cross(direction, up);
+  if(v.length2() == 0.0){
+    std::cerr << __FILE__ << " line: " << __LINE__ << " Ambiguous up 
direciton...\n";
+  }
+  v.normalize();
+
+  for(i=0; i<3; i++)
+    uvn[1][i] = v[i];
+
+  u=Cross(v, direction);
+  u.normalize();
+
+  for(i=0; i<3; i++)
+    uvn[0][i] = u[i];
+}
+
+void FisheyeCamera::makeRays(RayPacket& rays) const
+{
+  ASSERT(rays.getFlags() & RayPacket::HaveImageCoordinates);
+  rays.setFlag(RayPacket::ConstantOrigin|RayPacket::NormalizedDirections);
+  for(int i=0;i<rays.getSize();i++){
+    RayPacket::Element& e = rays.get(i);
+    double z = sqrt( 2.0 - e.imageX * e.imageX - e.imageY * e.imageY );
+    double theta = atan2( e.imageY, e.imageX );
+    double phi = acos( z / sqrt_two ) * hfov;
+    double x = cos( theta ) * sin( phi );
+    double y = sin( theta ) * sin( phi );
+    z = cos( phi );
+    e.ray.set(eye, v*x+u*y+n*z);
+  }
+}
+
+void FisheyeCamera::scaleFOV(double scale)
+{
+  double fov_min = 0;
+  double fov_max = 4.0;
+  hfov = scale*hfov;
+  hfov = Clamp(hfov, fov_min, fov_max);
+  vfov = scale*vfov;
+  vfov = Clamp(vfov, fov_min, fov_max);
+}
+
+void FisheyeCamera::translate(Vector t)
+{
+  Vector trans(u*t.y()+v*t.x());
+
+  eye += trans;
+  lookat += trans;
+  setup();
+}
+
+void FisheyeCamera::dolly(double scale)
+{
+  Vector dir = lookat - eye;
+  eye += dir*scale;
+  setup();
+}
+
+void FisheyeCamera::transform(AffineTransform t, TransformCenter center)
+{
+  Point cen;
+  switch(center){
+  case Eye:
+    cen = eye;
+    break;
+  case LookAt:
+    cen = lookat;
+    break;
+  case Origin:
+    cen = Point(0,0,0);
+    break;
+  }
+
+  Vector lookdir(eye-lookat);
+  double length = lookdir.length();
+
+  AffineTransform frame;
+  frame.initWithBasis(v.normal(), u.normal(), lookdir.normal(), cen);
+
+  AffineTransform frame_inv = frame;
+  frame_inv.invert();
+
+  AffineTransform t2        = frame * t * frame_inv;
+  up     = t2 * up;
+  eye    = t2 * eye;
+  lookat = t2 * lookat;
+  setup();
+}
+
+void FisheyeCamera::autoview(double new_fov)
+{
+  BBox bbox(Point(-1,-1,0.2), Point(1,1,2.2));
+  //  double ratio = tan(DtoR(vfov/2))/tan(DtoR(hfov/2));
+  hfov = new_fov;
+  vfov = new_fov;
+  Vector diag(bbox.diagonal());
+  double w=diag.length();
+  Vector lookdir(eye-lookat);
+  lookdir.normalize();
+  double scale = 1.0/(2*tan(DtoR(hfov/2.0)));
+  double length = w*scale;
+  lookat = bbox.center();
+  eye = lookat+lookdir*length;
+  setup();
+}
+
+Point FisheyeCamera::project(const Point &point)
+{
+  // NOT FINISHED
+  return Point(0,0,0); // just a placeholder
+}

Added: trunk/Model/Cameras/FisheyeCamera.h
==============================================================================
--- (empty file)
+++ trunk/Model/Cameras/FisheyeCamera.h Sun May 22 18:00:23 2005
@@ -0,0 +1,46 @@
+
+#ifndef Manta_Model_FisheyeCamera_h
+#define Manta_Model_FisheyeCamera_h
+
+#include <Interface/Camera.h>
+#include <Core/Geometry/PointVector.h>
+#include <sgi_stl_warnings_off.h>
+#include <string>
+#include <vector>
+#include <sgi_stl_warnings_on.h>
+
+namespace Manta {
+  using namespace std;
+
+  class FisheyeCamera : public Camera {
+  public:
+    FisheyeCamera(const vector<string>& args);
+    virtual ~FisheyeCamera();
+    virtual void makeRays(RayPacket&) const;
+
+    // Camera manipulation
+    virtual void scaleFOV(double);
+    virtual void translate(Vector);
+    virtual void dolly(double);
+    virtual void transform(AffineTransform t, TransformCenter);
+    virtual void autoview(double fov);
+         virtual Point project(const Point &point);  // project a 3D point 
to the camera image plane
+    static Camera* create(const vector<string>& args);
+  private:
+    void setup();
+    Point  eye;
+    Point  lookat;
+    Vector up;
+    double hfov, vfov, width, height, nearZ; // x and y field of view,
+                                            // width and height of image 
plane
+                                            // distance from eye to image 
plane
+
+    Vector direction;
+    Vector u,v,n;
+
+       // for projection we maintain a uvn rotation matrix
+    double uvn[3][3];
+  };
+}
+
+#endif




  • [MANTA] r334 - in trunk: Engine/Control Engine/Shadows Model/Cameras, aek, 05/22/2005

Archive powered by MHonArc 2.6.16.

Top of page