Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r429 - in trunk: Model/Primitives scenes


Chronological Thread 
  • From: aek@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r429 - in trunk: Model/Primitives scenes
  • Date: Tue, 12 Jul 2005 12:22:39 -0600 (MDT)

Author: aek
Date: Tue Jul 12 12:22:38 2005
New Revision: 429

Modified:
   trunk/Model/Primitives/SuperEllipsoid.cc
   trunk/Model/Primitives/SuperEllipsoid.h
   trunk/scenes/primtest.cc
Log:
M    scenes/primtest.cc
    - Changed to match changes to SuperEllipsoid.cc/h
    - Changed to allow a single prim (-num 1x1) 

M    Model/Primitives/SuperEllipsoid.cc
M    Model/Primitives/SuperEllipsoid.h
    - Fixed and sped up.  Still a bit of self-shadowing though



Modified: trunk/Model/Primitives/SuperEllipsoid.cc
==============================================================================
--- trunk/Model/Primitives/SuperEllipsoid.cc    (original)
+++ trunk/Model/Primitives/SuperEllipsoid.cc    Tue Jul 12 12:22:38 2005
@@ -1,31 +1,28 @@
+#include <iostream>
+
 #include <Model/Primitives/SuperEllipsoid.h>
 #include <Interface/RayPacket.h>
 #include <Core/Geometry/BBox.h>
 #include <Core/Math/MinMax.h>
 #include <Core/Math/MiscMath.h>
 
-using namespace Manta;
 using namespace std;
-using SCIRun::Clamp;
+using namespace SCIRun;
+using namespace Manta;
 
 #define GOLDENMEAN 0.61803398874989484820
-#define BRACKETWIDTH 1.e-6
-#define MAXNEWTONITER 25
+#define BRACKETWIDTH 1.e-3
+#define MAXNEWTONITER 10
 
 SuperEllipsoid::SuperEllipsoid(
   Material *material,
-  Point const &center,
-  double radius,
   double alpha,
   double beta )
   : PrimitiveCommon( material, this ),
-    center( center ),
-    radius( radius )
+    two_over_alpha( 2. / alpha ),
+    two_over_beta( 2. / beta ),
+    alpha_over_beta( alpha / beta )
 {
-  inv_radius = 1. / radius;
-  two_over_alpha = 2. / alpha;
-  two_over_beta = 2. / beta;
-  alpha_over_beta = alpha / beta;
 }
 
 SuperEllipsoid::~SuperEllipsoid()
@@ -33,7 +30,7 @@
 }
 
 inline double SuperEllipsoid::functionValue(
-  Vector const &location ) const
+  Point const &location ) const
 {
   double x_power = pow( fabs( location.x() ), two_over_alpha );
   double y_power = pow( fabs( location.y() ), two_over_alpha );
@@ -42,7 +39,7 @@
 }
 
 inline Vector const SuperEllipsoid::functionGradient(
-  Vector const &location,
+  Point const &location,
   double &value ) const
 {
   double x_power = pow( fabs(location.x() ), two_over_alpha );
@@ -56,7 +53,7 @@
 }
 
 inline Vector const SuperEllipsoid::logarithmFunctionGradient(
-  Vector const &location,
+  Point const &location,
   double &value ) const
 {
   double x_power = pow( fabs(location.x() ), two_over_alpha );
@@ -73,64 +70,49 @@
     PreprocessContext const &,
     BBox &bbox ) const
 {
-  bbox.extendBySphere( center, radius );
+    bbox.extendByPoint( Point( -1., -1., -1. ) );
+    bbox.extendByPoint( Point( 1., 1., 1. ) );
 }
 
 void SuperEllipsoid::intersect(const RenderContext&, RayPacket& rays) const
 {
 
-  rays.normalizeDirections();
   rays.computeInverseDirections();
-  for ( int i = 0; i < rays.getSize(); ++i )
-  {
-    RayPacket::Element &e( rays.get( i ) );
-    Vector offset_center = e.ray.origin() - center;
+  for( int i = 0; i < rays.getSize(); ++i ) {
+    RayPacket::Element& e( rays.get(i) );
 
     // First check if the ray hits the bounding box and whether it could
     // remotely produce a hit of interest.
     // TODO: Maybe factor this out into a common routine?
-    double tnear, tfar, t1, t2;
-    t1 = ( -radius - offset_center.x() ) * e.inverseDirection.x();
-    t2 = ( radius - offset_center.x() ) * e.inverseDirection.x();
-    if( t1 > t2 ) {
-      double temp = t1;
-      t1 = t2;
-      t2 = temp;
-    }
-    tnear = t1;
-    tfar = t2;
-    t1 = ( -radius - offset_center.y() ) * e.inverseDirection.y();
-    t2 = ( radius - offset_center.y() ) * e.inverseDirection.y();
-    if( t1 > t2 ) {
-      double temp = t1;
-      t1 = t2;
-      t2 = temp;
-    }
-    using SCIRun::Max;
-    using SCIRun::Min;
-    tnear = Max( t1, tnear );
-    tfar = Min( t2, tfar );
-    t1 = ( -radius - offset_center.z() ) * e.inverseDirection.z();
-    t2 = ( radius - offset_center.z() ) * e.inverseDirection.z();
-    if( t1 > t2 ) {
-      double temp = t1;
-      t1 = t2;
-      t2 = temp;
-    }
-    tnear = Max( Max( t1, tnear ), T_EPSILON );
-    tfar = Min( Min( t2, tfar ), e.hitInfo.minT() );
-
-    if ( tfar < T_EPSILON || tnear >= e.hitInfo.minT() )
+    double t1 = ( -1.01 - e.ray.origin().x() ) * e.inverseDirection.x();
+    double t2 = ( 1.01 - e.ray.origin().x() ) * e.inverseDirection.x();
+    if ( t1 > t2 )
+      SWAP( t1, t2 );
+    double tnear = t1;
+    double tfar = t2;
+    t1 = ( -1.01 - e.ray.origin().y() ) * e.inverseDirection.y();
+    t2 = ( 1.01 - e.ray.origin().y() ) * e.inverseDirection.y();
+    if ( t1 > t2 )
+      SWAP( t1, t2 );
+    tnear = SCIRun::Max( t1, tnear );
+    tfar = SCIRun::Min( t2, tfar );
+    t1 = ( -1.01 - e.ray.origin().z() ) * e.inverseDirection.z();
+    t2 = ( 1.01 - e.ray.origin().z() ) * e.inverseDirection.z();
+    if ( t1 > t2 )
+      SWAP( t1, t2 );
+    tnear = SCIRun::Max( SCIRun::Max( t1, tnear ), T_EPSILON );
+    tfar = SCIRun::Min( SCIRun::Min( t2, tfar ), e.hitInfo.minT() );
+    if ( tnear > tfar || tfar <= T_EPSILON || tnear >= e.hitInfo.minT() )
       continue;
 
     // A few preliminary early exit tests...
     double near_value, far_value;
     double near_deriv = Dot( functionGradient(
-                                 ( offset_center + tnear * e.ray.direction() 
) * inv_radius,
+                                 ( e.ray.origin() + tnear * 
e.ray.direction() ),
                                  near_value ),
                              e.ray.direction() );
     double far_deriv = Dot( functionGradient(
-                                ( offset_center + tfar * e.ray.direction() ) 
* inv_radius,
+                                ( e.ray.origin() + tfar * e.ray.direction() 
),
                                 far_value ),
                             e.ray.direction() );
     if ( ( near_value < T_EPSILON && far_value < T_EPSILON ) ||
@@ -143,32 +125,28 @@
       double a_bracket = tnear;
       double b_bracket = tfar;
       double left = GOLDENMEAN * a_bracket + ( 1. - GOLDENMEAN ) * b_bracket;
-      double left_value = functionValue(
-        ( offset_center + left * e.ray.direction() ) * inv_radius );
+      double left_value = functionValue( e.ray.origin() + left * 
e.ray.direction() );
       double right = ( 1. - GOLDENMEAN ) * a_bracket + GOLDENMEAN * 
b_bracket;
-      double right_value = functionValue(
-        ( offset_center + right * e.ray.direction() ) * inv_radius );
+      double right_value = functionValue( e.ray.origin() + right * 
e.ray.direction() );
       while( fabs( b_bracket - a_bracket ) > BRACKETWIDTH ) {
         if ( left_value < right_value ) {
           b_bracket = right;
           right = left;
           right_value = left_value;
           left = GOLDENMEAN * a_bracket + ( 1. - GOLDENMEAN ) * b_bracket;
-          left_value = functionValue(
-            ( offset_center + left * e.ray.direction() ) * inv_radius );
+          left_value = functionValue( e.ray.origin() + left * 
e.ray.direction() );
         } else {
           a_bracket = left;
           left = right;
           left_value = right_value;
           right = ( 1. - GOLDENMEAN ) * a_bracket + GOLDENMEAN * b_bracket;
-          right_value = functionValue(
-            ( offset_center + right * e.ray.direction() ) * inv_radius );
+          right_value = functionValue( e.ray.origin() + right * 
e.ray.direction() );
         }
       }
 
       // If our minimum is positive, we missed the superquadric - it
       // couldn't have crossed zero.
-      if ( right_value >= T_EPSILON )
+      if ( right_value >= -T_EPSILON )
         continue;
 
       // Narrow the range with the location of the minimum found
@@ -191,7 +169,7 @@
     double troot = ( tnear + tfar ) * 0.5;
     double root_value;
     double root_deriv = Dot( logarithmFunctionGradient(
-                                 ( offset_center + troot * e.ray.direction() 
) * inv_radius,
+                                 e.ray.origin() + troot * e.ray.direction(),
                                  root_value ),
                              e.ray.direction() );
     int iterations = 0;
@@ -205,11 +183,11 @@
         tnear = troot;
         near_value = root_value;
       }
-      troot = troot - root_value / root_deriv;
+      troot -= root_value / root_deriv;
       if ( troot <= tnear || troot >= tfar )
         troot = ( tnear + tfar ) * 0.5;
       root_deriv = Dot( logarithmFunctionGradient(
-                            ( offset_center + troot * e.ray.direction() ) * 
inv_radius,
+                            e.ray.origin() + troot * e.ray.direction(),
                             root_value ),
                         e.ray.direction() );
     }
@@ -225,14 +203,14 @@
   RenderContext const &,
   RayPacket &rays ) const
 {
-  // FIXME: Calculate proper normal once intersection code works - sphere
-  // normal close enough for now...
   double ignored;
   rays.computeHitPositions();
   for( int i = 0; i < rays.getSize(); i++ ) {
     RayPacket::Element &e( rays.get( i ) );
-    e.normal = functionGradient( ( e.hitPosition - center ) * inv_radius, 
ignored );
+    e.normal = functionGradient( e.hitPosition, ignored );
+    e.normal.normalize();
   }
+  rays.setFlag(RayPacket::HaveNormals | RayPacket::HaveUnitNormals);
 }
 
 void SuperEllipsoid::computeTexCoords2(
@@ -242,13 +220,12 @@
   rays.computeHitPositions();
   for( int i = 0; i < rays.getSize(); i++ ) {
     RayPacket::Element &e( rays.get( i ) );
-    Vector n = ( e.hitPosition - center ) * inv_radius;
-    double angle = Clamp( n.z(), -1.0, 1.0 );
+    double angle = Clamp( e.hitPosition.z(), -1.0, 1.0 );
     double theta = acos( angle );
-    double phi = atan2( n.x(), n.y() );
+    double phi = atan2( e.hitPosition.x(), e.hitPosition.y() );
     e.texCoords = Point( ( phi + M_PI ) * ( 1. / ( 2 * M_PI ) ),
                          theta * ( 1. / M_PI ),
-                         0 );
+                         0. );
   }
   rays.setFlag( RayPacket::HaveTexture2 | RayPacket::HaveTexture3 );
 }
@@ -260,13 +237,12 @@
   rays.computeHitPositions();
   for( int i = 0; i < rays.getSize(); i++ ) {
     RayPacket::Element &e = rays.get( i );
-    Vector n = ( e.hitPosition - center ) * inv_radius;
-    double angle = Clamp( n.z(), -1.0, 1.0 );
+    double angle = Clamp( e.hitPosition.z(), -1.0, 1.0 );
     double theta = acos( angle );
-    double phi = atan2( n.x(), n.y() );
+    double phi = atan2( e.hitPosition.x(), e.hitPosition.y() );
     e.texCoords = Point( ( phi + M_PI ) * ( 1. / ( 2 * M_PI ) ),
                          theta * ( 1. / M_PI ),
-                         0 );
+                         0. );
   }
   rays.setFlag( RayPacket::HaveTexture2 | RayPacket::HaveTexture3 );
 }

Modified: trunk/Model/Primitives/SuperEllipsoid.h
==============================================================================
--- trunk/Model/Primitives/SuperEllipsoid.h     (original)
+++ trunk/Model/Primitives/SuperEllipsoid.h     Tue Jul 12 12:22:38 2005
@@ -9,7 +9,7 @@
 namespace Manta {
   class SuperEllipsoid : public PrimitiveCommon, public TexCoordMapper {
   public:
-    SuperEllipsoid(Material* material, const Point& center, double radius, 
double alpha, double beta);
+    SuperEllipsoid(Material* material, double alpha, double beta);
     virtual ~SuperEllipsoid();
 
     virtual void computeBounds(const PreprocessContext& context,
@@ -21,12 +21,9 @@
     virtual void computeTexCoords3(const RenderContext& context,
                                    RayPacket& rays) const;
   private:
-    double functionValue(const Vector& location) const;
-    Vector const functionGradient(const Vector& location, double& value ) 
const;
-    Vector const logarithmFunctionGradient(const Vector& location, double& 
value ) const;
-    Point center;
-    double radius;
-    double inv_radius;
+    double functionValue(const Point& location) const;
+    Vector const functionGradient(const Point& location, double& value ) 
const;
+    Vector const logarithmFunctionGradient(const Point& location, double& 
value ) const;
     double two_over_alpha;
     double two_over_beta;
     double alpha_over_beta;

Modified: trunk/scenes/primtest.cc
==============================================================================
--- trunk/scenes/primtest.cc    (original)
+++ trunk/scenes/primtest.cc    Tue Jul 12 12:22:38 2005
@@ -174,8 +174,8 @@
       for(int j=0;j<numy;j++){
         int idx = j*numx+i;
         double radius = (idx+1)/static_cast<double>(numx*numy)*scale/max;
-        Point p((i/static_cast<double>(numx-1) - 0.5)*scale*2,
-                (j/static_cast<double>(numy-1) - 0.5)*scale*2,
+        Point p((numx>1 ? i/static_cast<double>(numx-1) - 0.5 : 0.)*scale*2,
+                (numy>1 ? j/static_cast<double>(numy-1) - 0.5 : 0.)*scale*2,
                 0);
   Primitive* prim = new Sphere( matl, p, radius );
   if ( mapr )
@@ -183,28 +183,12 @@
         group->add( prim );
       }
     }
-  } else if (primtype == "simplesuperellipsoid"){
-    for(int i=0;i<numx;i++){
-      for(int j=0;j<numy;j++){
-        int idx = j*numx+i;
-        double radius = (idx+1)/static_cast<double>(numx*numy)*scale/max;
-        double alpha = (i+1)/static_cast<double>(numx)*2.;
-        double beta = (j+1)/static_cast<double>(numy)*2.;
-        Point p((i/static_cast<double>(numx-1) - 0.5)*scale*2,
-                (j/static_cast<double>(numy-1) - 0.5)*scale*2,
-                0);
-        Primitive* prim = new SuperEllipsoid( matl, p, radius, alpha, beta );
-        if ( mapr )
-            prim->setTexCoordMapper( mapr );
-        group->add( prim );
-      }
-    }
   } else if(primtype == "simplebox"){
     Vector p2(scale/max, scale/max, scale/max);
     for(int i=0;i<numx;i++){
       for(int j=0;j<numy;j++){
-        Point p((i/static_cast<double>(numx-1) - 0.5)*scale*2,
-                (j/static_cast<double>(numy-1) - 0.5)*scale*2,
+        Point p((numx>1 ? i/static_cast<double>(numx-1) - 0.5 : 0.)*scale*2,
+                (numy>1 ? j/static_cast<double>(numy-1) - 0.5 : 0.)*scale*2,
                 0);
   Primitive* prim = new Cube( matl, p-p2, p2.x()*1.156, p2.y()*1.156, 
p2.z()*1.156 );
   if ( mapr )
@@ -253,6 +237,11 @@
     if ( mapr )
         prim->setTexCoordMapper( mapr );
     spinprim = prim;
+  } else if (primtype == "superellipsoid"){
+    Primitive* prim = new SuperEllipsoid(matl, 0.5, 1.5);
+    if ( mapr )
+        prim->setTexCoordMapper( mapr );
+    spinprim = prim;
   } else if(primtype == "ply"){
     AffineTransform t;
     t.initWithScale(Vector(scale/max*30, scale/max*30, scale/max*30));
@@ -273,11 +262,11 @@
     if(arraytype == "spin"){
       for(int i=0;i<numx;i++){
         for(int j=0;j<numy;j++){
-          Vector p((i/static_cast<double>(numx-1) - 0.5)*scale*2,
-                   (j/static_cast<double>(numy-1) - 0.5)*scale*2,
+          Vector p((numx>1 ? i/static_cast<double>(numx-1) - 0.5 : 
0.)*scale*2,
+                   (numy>1 ? j/static_cast<double>(numy-1) - 0.5 : 
0.)*scale*2,
                    0);
-          double a1 = i/static_cast<double>(numx-1)*M_PI*2;
-          double a2 = j/static_cast<double>(numy-1)*M_PI*2;
+          double a1 = i/static_cast<double>(numx)*M_PI*2;
+          double a2 = j/static_cast<double>(numy)*M_PI*2;
           AffineTransform t;
           t.initWithIdentity();
           t.rotate(Vector(0,1,0), a1);
@@ -289,8 +278,8 @@
     } else if(arraytype == "shift"){
       for(int i=0;i<numx;i++){
         for(int j=0;j<numy;j++){
-          Vector p((i/static_cast<double>(numx-1) - 0.5)*scale*2,
-                   (j/static_cast<double>(numy-1) - 0.5)*scale*2,
+          Vector p((numx>1 ? i/static_cast<double>(numx-1) - 0.5 : 
0.)*scale*2,
+                   (numy>1 ? j/static_cast<double>(numy-1) - 0.5 : 
0.)*scale*2,
                    0);
           group->add(new InstanceT(spinprim, p));
         }
@@ -298,8 +287,8 @@
     } else if(arraytype == "scale"){
       for(int i=0;i<numx;i++){
         for(int j=0;j<numy;j++){
-          Vector p((i/static_cast<double>(numx-1) - 0.5)*scale*2,
-                   (j/static_cast<double>(numy-1) - 0.5)*scale*2,
+          Vector p((numx>1 ? i/static_cast<double>(numx-1) - 0.5 : 
0.)*scale*2,
+                   (numy>1 ? j/static_cast<double>(numy-1) - 0.5 : 
0.)*scale*2,
                    0);
           int idx = j*numx+i;
           double scale = (idx+1)/static_cast<double>(numx*numy);
@@ -309,8 +298,8 @@
     } else if(arraytype == "nuscale"){
       for(int i=0;i<numx;i++){
         for(int j=0;j<numy;j++){
-          Vector p((i/static_cast<double>(numx-1) - 0.5)*scale*2,
-                   (j/static_cast<double>(numy-1) - 0.5)*scale*2,
+          Vector p((numx>1 ? i/static_cast<double>(numx-1) - 0.5 : 
0.)*scale*2,
+                   (numy>1 ? j/static_cast<double>(numy-1) - 0.5 : 
0.)*scale*2,
                    0);
           double xscale = (i+1)/static_cast<double>(numx);
           double yscale = (j+1)/static_cast<double>(numy);
@@ -320,11 +309,11 @@
     } else if(arraytype == "spinscale"){
       for(int i=0;i<numx;i++){
         for(int j=0;j<numy;j++){
-          Vector p((i/static_cast<double>(numx-1) - 0.5)*scale*2,
-                   (j/static_cast<double>(numy-1) - 0.5)*scale*2,
+          Vector p((numx>1 ? i/static_cast<double>(numx-1) - 0.5 : 
0.)*scale*2,
+                   (numy>1 ? j/static_cast<double>(numy-1) - 0.5 : 
0.)*scale*2,
                    0);
-          double a1 = i/static_cast<double>(numx-1)*M_PI*2;
-          double a2 = j/static_cast<double>(numy-1)*M_PI*2;
+          double a1 = i/static_cast<double>(numx)*M_PI*2;
+          double a2 = j/static_cast<double>(numy)*M_PI*2;
           int idx = j*numx+i;
           double scale = (idx+1)/static_cast<double>(numx*numy);
           AffineTransform t;
@@ -339,11 +328,11 @@
     } else if(arraytype == "spinscale2"){
       for(int i=0;i<numx;i++){
         for(int j=0;j<numy;j++){
-          Vector p((i/static_cast<double>(numx-1) - 0.5)*scale*2,
-                   (j/static_cast<double>(numy-1) - 0.5)*scale*2,
+          Vector p((numx>1 ? i/static_cast<double>(numx-1) - 0.5 : 
0.)*scale*2,
+                   (numy>1 ? j/static_cast<double>(numy-1) - 0.5 : 
0.)*scale*2,
                    0);
-          double a1 = i/static_cast<double>(numx-1)*M_PI*2;
-          double a2 = j/static_cast<double>(numy-1)*M_PI*2;
+          double a1 = i/static_cast<double>(numx)*M_PI*2;
+          double a2 = j/static_cast<double>(numy)*M_PI*2;
           int idx = j*numx+i;
           double scale = (idx+1)/static_cast<double>(numx*numy);
           AffineTransform t;




  • [MANTA] r429 - in trunk: Model/Primitives scenes, aek, 07/12/2005

Archive powered by MHonArc 2.6.16.

Top of page