Text archives Help
- 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.