Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r568 - in trunk: Core/Geometry Interface Model Model/Primitives scenes


Chronological Thread 
  • From: aek@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r568 - in trunk: Core/Geometry Interface Model Model/Primitives scenes
  • Date: Mon, 26 Sep 2005 11:45:59 -0600 (MDT)

Author: aek
Date: Mon Sep 26 11:45:58 2005
New Revision: 568

Added:
   trunk/Model/Primitives/ParticleBVH.cc
   trunk/Model/Primitives/ParticleBVH.h
   trunk/scenes/ParticleBVHTest.cc
Modified:
   trunk/Core/Geometry/BBox.h
   trunk/Interface/RayPacket.h
   trunk/Model/CMakeLists.txt
   trunk/Model/Primitives/CMakeLists.txt
   trunk/Model/Primitives/Sphere.cc
   trunk/scenes/CMakeLists.txt
Log:
A    Model/Primitives/ParticleBVH.cc
A    Model/Primitives/ParticleBVH.h
M    Model/Primitives/CMakeLists.txt
        - Added a "primitive" to display large sets of spherical particles
          using an internal BVH acceleration structure.

A    scenes/ParticleBVHTest.cc
M    scenes/CMakeLists.txt
        - Added a scene to create a ParticleBVH for testing.

M    Core/Geometry/BBox.h
        - Added a longestAxis() method to help with BVH construction.

M    Interface/RayPacket.h
        - Added sign[] to element to hold the sign of each component of the
          direction vector, added HaveSigns flag to accompany it.
        - ConstantSigns flag to indicate whether all rays point in the same
          octant.
        - Added computeSigns() method.  This will set or clear
          ConstantSigns automatically depending on whether it applies.
        - Converted tabs to spaces

M    Model/Primitives/Sphere.cc
M    Model/CMakeLists.txt
        - Converted tabs to spaces



Modified: trunk/Core/Geometry/BBox.h
==============================================================================
--- trunk/Core/Geometry/BBox.h  (original)
+++ trunk/Core/Geometry/BBox.h  Mon Sep 26 11:45:58 2005
@@ -88,6 +88,17 @@
       return (2.0*((lenx*leny) + (leny*lenz) + (lenx*lenz)));
     }
 
+    int longestAxis() const
+    {
+      double lenx = max.x() - min.x();
+      double leny = max.y() - min.y();
+      double lenz = max.z() - min.z();
+      if ( lenx > leny )
+          return lenx > lenz ? 0 : 2;
+      else
+          return lenx > lenz ? 1 : 2;
+    }
+
   private:
     BBox(const BBox&);
     BBox& operator=(const BBox&);

Modified: trunk/Interface/RayPacket.h
==============================================================================
--- trunk/Interface/RayPacket.h (original)
+++ trunk/Interface/RayPacket.h Mon Sep 26 11:45:58 2005
@@ -28,12 +28,14 @@
     static const int HaveNormals = 0x200;
     static const int HaveUnitNormals = 0x300;
     static const int HaveInverseDirections = 0x800;
+    static const int HaveSigns = 0x1000;
+    static const int ConstantSigns = 0x2000;
     inline RayPacket(RayPacketData& data, int size, int depth, int flags);
 
     // Create a subset of another raypacket
     RayPacket(RayPacket& parent, int start, int end)
       : data(parent.data+start), size(end-start), depth(parent.depth),
-       flags(parent.flags)
+        flags(parent.flags)
     {
     }
 
@@ -41,48 +43,6 @@
     {
     }
 
-    /**
-     * Split the packet based on a mask of booleans.  The current packet
-     * will be modified to be reduced to just those elements for which the
-     * mask is false, while the elements for which it is true will be
-     * returned in a new packet.  Elements in each new packet may be
-     * reordered.  This does the minimum copying possible - it is most
-     * efficient if the mask has all false before all true.
-     *
-     * @param mask  an array of booleans controlling the split
-     * @return  a ray packet with all of the "true" elements
-     */
-    RayPacket split(
-        bool *mask )
-    {
-        int low = -1;
-        int high = size;
-        for ( ; ; )
-        {
-            for ( ++low; low < high && !mask[ low ]; ++low );
-            for ( --high; low < high && mask[ high ]; --high );
-            if ( low >= high )
-                break;
-            std::swap( data[ low ].localColor, data[ high ].localColor );
-            std::swap( data[ low ].color, data[ high ].color );
-            std::swap( data[ low ].imageX, data[ high ].imageX );
-            std::swap( data[ low ].imageY, data[ high ].imageY );
-            std::swap( data[ low ].whichEye, data[ high ].whichEye );
-            std::swap( data[ low ].ray, data[ high ].ray );
-            data[ low ].hitInfo.swap( data[ high ].hitInfo );
-            std::swap( data[ low ].normal, data[ high ].normal );
-            std::swap( data[ low ].hitPosition, data[ high ].hitPosition );
-            std::swap( data[ low ].texCoords, data[ high ].texCoords );
-            std::swap( data[ low ].inverseDirection, data[ high 
].inverseDirection );
-            std::swap( data[ low ].ambientLight, data[ high ].ambientLight );
-            std::swap( data[ low ].shadowBegin, data[ high ].shadowBegin );
-            std::swap( data[ low ].shadowEnd, data[ high ].shadowEnd );
-        }
-        int old_size = low;
-        size = low;
-        return RayPacket( *this, low, old_size - low );
-    }
-
     int getFlags() const {
       return flags;
     }
@@ -100,7 +60,7 @@
     }
     void resetHit() {
       for(int i=0;i<size;i++)
-       data[i].hitInfo.reset();
+        data[i].hitInfo.reset();
       flags |= HaveHitRecords;
     }
 
@@ -122,7 +82,7 @@
       Point hitPosition;
       Point texCoords;
       Vector inverseDirection;
-
+      int sign[3];
       Color ambientLight;
       int shadowBegin, shadowEnd;
       Color light;
@@ -137,7 +97,7 @@
 #endif // SWIG
 
     void setPixel(int which, int whichEye, double imageX, double imageY,
-                 Color* color) {
+                  Color* color) {
       data[which].color = color;
       data[which].imageX = imageX;
       data[which].imageY = imageY;
@@ -145,7 +105,7 @@
     }
     void useLocalColors() {
       for(int i=0;i<size;i++)
-       data[i].color = &data[i].localColor;
+        data[i].color = &data[i].localColor;
     }
     HitInfo& hitInfo(int which) {
       return data[which].hitInfo;
@@ -159,15 +119,15 @@
     void normalizeDirections()
     {
       if(flags & NormalizedDirections)
-       return;
+        return;
       if(flags & HaveHitRecords){
-       for(int i=0;i<size;i++){
-         double length = data[i].ray.normalizeDirection();
-         data[i].hitInfo.scaleT(length);
-       }
+        for(int i=0;i<size;i++){
+          double length = data[i].ray.normalizeDirection();
+          data[i].hitInfo.scaleT(length);
+        }
       } else {
-       for(int i=0;i<size;i++)
-         data[i].ray.normalizeDirection();
+        for(int i=0;i<size;i++)
+          data[i].ray.normalizeDirection();
       }
       flags |= NormalizedDirections;
       flags &= ~HaveInverseDirections;
@@ -175,25 +135,44 @@
     void computeHitPositions()
     {
       if(flags & HaveHitPositions)
-       return;
+        return;
       for(int i=0;i<size;i++)
-       data[i].hitPosition = data[i].ray.origin() + data[i].ray.direction() 
* data[i].hitInfo.minT();
+        data[i].hitPosition = data[i].ray.origin() + data[i].ray.direction() 
* data[i].hitInfo.minT();
       flags |= HaveHitPositions;
     }
     void computeInverseDirections()
     {
       if(flags & HaveInverseDirections)
-       return;
+        return;
       for(int i=0;i<size;i++)
-       data[i].inverseDirection = Vector(1./data[i].ray.direction().x(),
+        data[i].inverseDirection = Vector(1./data[i].ray.direction().x(),
                                           1./data[i].ray.direction().y(),
                                           1./data[i].ray.direction().z());
       flags |= HaveInverseDirections;
     }
+    void computeSigns()
+    {
+      if(flags & HaveSigns)
+        return;
+      for(int i=0;i<size;i++)
+      {
+        data[i].sign[0] = data[i].ray.direction().x()<0.0;
+        data[i].sign[1] = data[i].ray.direction().y()<0.0;
+        data[i].sign[2] = data[i].ray.direction().z()<0.0;
+      }
+      flags |= HaveInverseDirections;
+      flags &= ~ConstantSigns;
+      for(int i=1;i<size;i++)
+          if (data[i].sign[0]!=data[i-1].sign[0]||
+              data[i].sign[1]!=data[i-1].sign[1]||
+              data[i].sign[2]!=data[i-1].sign[2])
+              return;
+      flags |= ConstantSigns;
+    }
     void computeTextureCoordinates2(const RenderContext& context)
     {
       if(flags & (HaveTexture2|HaveTexture3))
-       return;
+        return;
       Element& e0 = data[0];
       const TexCoordMapper* tex = e0.hitInfo.hitTexCoordMapper();
       tex->computeTexCoords2(context, *this);
@@ -202,7 +181,7 @@
     void computeTextureCoordinates3(const RenderContext& context)
     {
       if(flags & HaveTexture3)
-       return;
+        return;
       Element& e0 = data[0];
       const TexCoordMapper* tex = e0.hitInfo.hitTexCoordMapper();
       tex->computeTexCoords3(context, *this);
@@ -212,7 +191,7 @@
     void computeFrame(const RenderContext& context)
     {
       if(flags & HaveFrame)
-       return;
+        return;
       Element& e0 = data[0];
       const UVMapping* uv = e0.hitInfo.hitPrimitive()->getUVMapping();
       uv->computeFrame(context, *this);
@@ -223,17 +202,17 @@
     void computeNormals(const RenderContext& context)
     {
       if(flags & HaveNormals)
-       return;
+        return;
       // Compute normals
       for(int i=0;i<size;){
-       RayPacket::Element& e = data[i];
-       const Primitive* prim = e.hitInfo.hitPrimitive();
-       int end = i+1;
-       while(end < size && data[end].hitInfo.hitPrimitive() == prim)
-         end++;
-       RayPacket subPacket(*this, i, end);
-       prim->computeNormal(context, subPacket);
-       i=end;
+        RayPacket::Element& e = data[i];
+        const Primitive* prim = e.hitInfo.hitPrimitive();
+        int end = i+1;
+        while(end < size && data[end].hitInfo.hitPrimitive() == prim)
+          end++;
+        RayPacket subPacket(*this, i, end);
+        prim->computeNormal(context, subPacket);
+        i=end;
       }
       flags |= HaveNormals;
     }
@@ -267,7 +246,7 @@
   };
 
   inline RayPacket::RayPacket(RayPacketData& data, int size,
-                             int depth, int flags)
+                              int depth, int flags)
     : data(&data.data[0]), size(size), depth(depth), flags(flags)
   {
   }

Modified: trunk/Model/CMakeLists.txt
==============================================================================
--- trunk/Model/CMakeLists.txt  (original)
+++ trunk/Model/CMakeLists.txt  Mon Sep 26 11:45:58 2005
@@ -24,11 +24,11 @@
              ${Manta_Lights_SRCS}
              ${Manta_Materials_SRCS}
              ${Manta_Primitives_SRCS}
-                                ${Manta_Primitives_Volume_SRCS}
+             ${Manta_Primitives_Volume_SRCS}
              ${Manta_TexCoordMappers_SRCS}
              ${Manta_Instances_SRCS}
              ${Manta_MiscObjects_SRCS}
-            ${Manta_Readers_SRCS}
+             ${Manta_Readers_SRCS}
              )
 
 TARGET_LINK_LIBRARIES(Manta_Model Manta_Interface Manta_Core)

Modified: trunk/Model/Primitives/CMakeLists.txt
==============================================================================
--- trunk/Model/Primitives/CMakeLists.txt       (original)
+++ trunk/Model/Primitives/CMakeLists.txt       Mon Sep 26 11:45:58 2005
@@ -13,6 +13,7 @@
      Primitives/Disk.cc
      Primitives/Hemisphere.cc
      Primitives/Heightfield.cc
+     Primitives/ParticleBVH.cc
 )
 
 # Should be include known broken objects?

Added: trunk/Model/Primitives/ParticleBVH.cc
==============================================================================
--- (empty file)
+++ trunk/Model/Primitives/ParticleBVH.cc       Mon Sep 26 11:45:58 2005
@@ -0,0 +1,248 @@
+
+#include <Model/Primitives/ParticleBVH.h>
+#include <Interface/RayPacket.h>
+#include <SCIRun/Core/Math/MiscMath.h>
+
+using namespace Manta;
+using namespace SCIRun;
+
+ParticleBVH::ParticleBVH(
+  Material *material,
+  int const number_of_particles )
+  : PrimitiveCommon( material, this ),
+    number_of_particles( number_of_particles ),
+    particles( new Particle[ number_of_particles ] ),
+    nodes( new Node[ number_of_particles * 2 ] )
+{
+}
+
+ParticleBVH::~ParticleBVH()
+{
+  delete[] particles;
+  delete[] nodes;
+}
+
+void ParticleBVH::setParticle(
+  int const which_one,
+  Point const &center,
+  double const radius )
+{
+  particles[ which_one ].center = center;
+  particles[ which_one ].radius = radius;
+  particles[ which_one ].inverse_radius = 1.0 / radius;
+}
+
+int ParticleBVH::partition(
+  int first,
+  int last,
+  int const axis,
+  float const position )
+{
+  --first;
+  for ( ; ; ) {
+    ++first;
+    while ( particles[ first ].center[ axis ] <= position && first < last )
+      ++first;
+    --last;
+    while ( particles[ first ].center[ axis ] >= position && first < last )
+      --last;
+    if ( first < last )
+      SWAP( particles[ first ], particles[ last ] );
+    else
+      return first;
+  }
+}
+
+int ParticleBVH::build(
+  int const index,
+  int const first,
+  int const last,
+  int const size )
+{
+  Node &node( nodes[ index ] );
+  node.bound.reset();
+  for ( int current = first; current < last; ++current )
+    node.bound.extendBySphere( particles[ current ].center, particles[ 
current ].radius );
+  if ( last - first < maximum_objects_per_leaf ) {
+    node.index = first;
+    node.length = last - first;
+    node.axis = 0;
+    node.leaf = true;
+    return size;
+  }
+  int axis = node.bound.longestAxis();
+  float position = ( node.bound.getMin()[ axis ] + node.bound.getMax()[ axis 
] ) * 0.5f;
+  int split = partition( first, last, axis, position );
+  if ( split == first || split == last ) {
+    node.index = first;
+    node.length = last - first;
+    node.axis = 0;
+    node.leaf = true;
+    return size;
+  }
+  node.index = size;
+  node.length = 0;
+  node.axis = axis;
+  node.leaf = false;
+  int new_size = build( size, first, split, size + 2 );
+  new_size = build( size + 1, split, last, new_size );
+  return new_size;
+}
+
+void ParticleBVH::preprocess(
+  PreprocessContext const &context )
+{
+  build( 0, 0, number_of_particles, 1 );
+}
+
+void ParticleBVH::computeBounds(
+  PreprocessContext const &context,
+  BBox &box ) const
+{
+  for ( int current = 0; current < number_of_particles; ++current )
+    box.extendBySphere( particles[ current ].center, particles[ current 
].radius );
+}
+
+bool ParticleBVH::testBox(
+  RayPacket &rays,
+  BBox const &box ) const
+{
+  float bound[ 6 ];
+  bound[ 0 ] = box.getMin().x(); bound[ 1 ] = box.getMax().x();
+  bound[ 2 ] = box.getMin().y(); bound[ 3 ] = box.getMax().y();
+  bound[ 4 ] = box.getMin().z(); bound[ 5 ] = box.getMax().z();
+  for ( int ray = 0; ray < rays.getSize(); ++ray ) {
+    RayPacket::Element &element( rays.get( ray ) );
+    float maximum_minimum = T_EPSILON;
+    float minimum_maximum = element.hitInfo.minT();
+    float x_minimum = ( bound[     element.sign[ 0 ] ] - 
element.ray.origin().x() ) * element.inverseDirection.x();
+    float x_maximum = ( bound[ 1 - element.sign[ 0 ] ] - 
element.ray.origin().x() ) * element.inverseDirection.x();
+    float y_minimum = ( bound[ 2 + element.sign[ 1 ] ] - 
element.ray.origin().y() ) * element.inverseDirection.y();
+    float y_maximum = ( bound[ 3 - element.sign[ 1 ] ] - 
element.ray.origin().y() ) * element.inverseDirection.y();
+    float z_minimum = ( bound[ 4 + element.sign[ 2 ] ] - 
element.ray.origin().z() ) * element.inverseDirection.z();
+    float z_maximum = ( bound[ 5 - element.sign[ 2 ] ] - 
element.ray.origin().z() ) * element.inverseDirection.z();
+    if ( minimum_maximum < x_minimum ||
+         maximum_minimum > x_maximum )
+      continue;
+    if ( minimum_maximum > x_maximum )
+      minimum_maximum = x_maximum;
+    if ( maximum_minimum < x_minimum )
+      maximum_minimum = x_minimum;
+    if ( minimum_maximum < y_minimum ||
+         maximum_minimum > y_maximum )
+      continue;
+    if ( minimum_maximum > y_maximum )
+      minimum_maximum = y_maximum;
+    if ( maximum_minimum < y_minimum )
+      maximum_minimum = y_minimum;
+    if ( minimum_maximum >= z_minimum &&
+         maximum_minimum <= z_maximum )
+      return true;
+  }
+  return false;
+}
+
+bool ParticleBVH::intersectParticles(
+  RayPacket &rays,
+  int const first,
+  int const last ) const
+{
+  for ( int current = first; current < last; ++current ) {
+    Particle &particle( particles[ current ] );
+    for ( int ray = 0; ray < rays.getSize(); ray++ ) {
+      RayPacket::Element &element( rays.get( ray ) );
+      Vector offset( element.ray.origin() - particle.center );
+      double B = Dot( offset, element.ray.direction() );
+      double C = Dot( offset, offset ) - particle.radius * particle.radius;
+      double discriminant = B * B - C;
+      if ( discriminant >= 0.0 ) {
+        double r = sqrt( discriminant );
+        double t0 = -r - B;
+        if( t0 > 0.0 ) {
+          if ( element.hitInfo.hit( t0, material, this, tex ) )
+            element.hitInfo.scratchpad< ParticleHit >().particle = current;
+        } else {
+          double t1 = r - B;
+          element.hitInfo.hit( t1, material, this, tex );
+          if ( element.hitInfo.hit( t0, material, this, tex ) )
+            element.hitInfo.scratchpad< ParticleHit >().particle = current;
+        }
+      }
+    }
+  }
+}
+
+void ParticleBVH::intersect(
+  RenderContext const &context,
+  RayPacket &rays ) const
+{
+  rays.normalizeDirections();
+  rays.computeInverseDirections();
+  rays.computeSigns();
+  int stack[ maximum_depth ];
+  int stack_position = 0;
+  int current = 0;
+  RayPacket::Element& element_0( rays.get( 0 ) );
+  for ( ; ; ) {
+    Node &node( nodes[ current ] );
+    if ( testBox( rays, node.bound ) ) {
+      if ( node.leaf ) 
+        intersectParticles( rays, node.index, node.index + node.length );
+      else {
+        stack[ stack_position++ ] = node.index + 1 - element_0.sign[ 
node.axis ];
+        current = node.index + element_0.sign[ node.axis ];
+        continue;
+      }
+    }
+    if ( --stack_position < 0 )
+      break;
+    current = stack[ stack_position ];
+  }
+}
+
+void ParticleBVH::computeNormal(
+  const RenderContext &/*context*/,
+  RayPacket &rays ) const
+{
+  rays.computeHitPositions();
+  for ( int ray = 0; ray < rays.getSize(); ++ray ) {
+    RayPacket::Element &element( rays.get( ray ) );
+    Particle &particle( particles[ element.hitInfo.scratchpad< ParticleHit 
>().particle ] );
+    element.normal = ( element.hitPosition - particle.center ) * 
particle.inverse_radius;
+  }
+  rays.setFlag( RayPacket::HaveUnitNormals );
+}
+
+void ParticleBVH::computeTexCoords2(
+  RenderContext const &/*context*/,
+  RayPacket &rays ) const
+{
+  rays.computeHitPositions();
+  for ( int ray = 0; ray < rays.getSize(); ++ray ) {
+    RayPacket::Element &element( rays.get( ray ) );
+    Particle &particle( particles[ element.hitInfo.scratchpad< ParticleHit 
>().particle ] );
+    Vector n = ( element.hitPosition - particle.center ) * 
particle.inverse_radius;
+    double angle = Clamp( n.z(), -1.0, 1.0 );
+    double theta = acos( angle );
+    double phi = atan2( n.x(), n.y() );
+    element.texCoords = Point( ( phi + M_PI ) * ( 1.0 / ( 2.0 * M_PI ) ), 
theta * ( 1.0 / M_PI ), 0.0 );
+  }
+  rays.setFlag( RayPacket::HaveTexture2 | RayPacket::HaveTexture3 );
+}
+
+void ParticleBVH::computeTexCoords3(
+  const RenderContext &/*context*/,
+  RayPacket &rays ) const
+{
+  rays.computeHitPositions();
+  for ( int ray = 0; ray < rays.getSize(); ++ray ) {
+    RayPacket::Element &element( rays.get( ray ) );
+    Particle &particle( particles[ element.hitInfo.scratchpad< ParticleHit 
>().particle ] );
+    Vector n = ( element.hitPosition - particle.center ) * 
particle.inverse_radius;
+    double angle = Clamp( n.z(), -1.0, 1.0 );
+    double theta = acos( angle );
+    double phi = atan2( n.x(), n.y() );
+    element.texCoords = Point( ( phi + M_PI ) * ( 1.0 / ( 2.0 * M_PI ) ), 
theta * ( 1.0 / M_PI ), 0.0 );
+  }
+  rays.setFlag( RayPacket::HaveTexture2 | RayPacket::HaveTexture3 );
+}

Added: trunk/Model/Primitives/ParticleBVH.h
==============================================================================
--- (empty file)
+++ trunk/Model/Primitives/ParticleBVH.h        Mon Sep 26 11:45:58 2005
@@ -0,0 +1,53 @@
+#ifndef Manta_Particle_BVH_h
+#define Manta_Particle_BVH_h
+
+#include <Model/Primitives/PrimitiveCommon.h>
+#include <Interface/TexCoordMapper.h>
+#include <Core/Geometry/PointVector.h>
+#include <Core/Geometry/BBox.h>
+
+namespace Manta {
+  class ParticleBVH : public PrimitiveCommon, public TexCoordMapper {
+
+  public:
+    ParticleBVH( Material *material, int const number_of_particles );
+    virtual ~ParticleBVH();
+
+    virtual void setParticle( int const which_one, Point const &center, 
double const radius );
+    virtual void preprocess( PreprocessContext const &context );
+    virtual void computeBounds( PreprocessContext const &context, BBox &box 
) const;
+    virtual void intersect( RenderContext const &context, RayPacket &rays ) 
const;
+    virtual void computeNormal( RenderContext const &context, RayPacket 
&rays ) const;
+    virtual void computeTexCoords2( RenderContext const &context, RayPacket 
&rays ) const;
+    virtual void computeTexCoords3( RenderContext const &context, RayPacket 
&rays ) const;
+
+  protected:
+    static const int maximum_objects_per_leaf = 4;
+    static const int maximum_depth = 128;
+
+    int number_of_particles;
+    struct Particle {
+      Point center;
+      double radius;
+      double inverse_radius;
+    } *particles;
+    struct Node {
+      BBox bound;
+      unsigned int index;
+      unsigned int length : 29;
+      unsigned int axis : 2;
+      bool leaf : 1;
+    } *nodes;
+    struct ParticleHit{
+      int particle;
+    };
+
+    int partition( int first, int last, int const axis, float const position 
);
+    int build( int const index, int const first, int const last, int const 
size );
+    bool testBox( RayPacket &rays, BBox const &box ) const;
+    bool intersectParticles( RayPacket &rays, int const first, int const 
last ) const;
+
+  };
+}
+
+#endif

Modified: trunk/Model/Primitives/Sphere.cc
==============================================================================
--- trunk/Model/Primitives/Sphere.cc    (original)
+++ trunk/Model/Primitives/Sphere.cc    Mon Sep 26 11:45:58 2005
@@ -41,16 +41,16 @@
       e.hitInfo.hit(material, this, t);
     } else {
       if(tca < 0.0){
-       // Behind ray, no intersections...
+        // Behind ray, no intersections...
       } else {
-       double t2hc=rad2-l2oc+tca*tca;
-       if(t2hc <= 0.0){
-         // Ray misses, no intersections
-       } else {
-         double thc=sqrt(t2hc);
-         e.hitInfo.hit(material, this, tca-thc);
-         e.hitInfo.hit(material, this, tca+thc);
-       }
+        double t2hc=rad2-l2oc+tca*tca;
+        if(t2hc <= 0.0){
+          // Ray misses, no intersections
+        } else {
+          double thc=sqrt(t2hc);
+          e.hitInfo.hit(material, this, tca-thc);
+          e.hitInfo.hit(material, this, tca+thc);
+        }
       }
     }
   }
@@ -63,20 +63,20 @@
       Vector O(e0.ray.origin()-center);
       double C = Dot(O, O) - radius*radius;
       for(int i = 0;i<rays.getSize();i++){
-       RayPacket::Element& e = rays.get(i);
-       const Vector& D(e.ray.direction());
-       double B = Dot(O, D);
-       double disc = B*B-C;
-       if(disc >= 0){
-         double r = sqrt(disc);
-         double t0 = -(r+B);
-         if(t0 > 0){
-           e.hitInfo.hit(t0, material, this, tex);
-         } else {
-           double t1 = r-B;
-           e.hitInfo.hit(t1, material, this, tex);
-         }
-       }
+        RayPacket::Element& e = rays.get(i);
+        const Vector& D(e.ray.direction());
+        double B = Dot(O, D);
+        double disc = B*B-C;
+        if(disc >= 0){
+          double r = sqrt(disc);
+          double t0 = -(r+B);
+          if(t0 > 0){
+            e.hitInfo.hit(t0, material, this, tex);
+          } else {
+            double t1 = r-B;
+            e.hitInfo.hit(t1, material, this, tex);
+          }
+        }
       }
     }
   break;
@@ -87,21 +87,21 @@
       Vector O(e0.ray.origin()-center);
       double C = Dot(O, O) - radius*radius;
       for(int i = 0;i<rays.getSize();i++){
-       RayPacket::Element& e = rays.get(i);
-       const Vector& D(e.ray.direction());
-       double A = Dot(D, D);
-       double B = Dot(O, D);
-       double disc = B*B-A*C;
-       if(disc >= 0){
-         double r = sqrt(disc);
-         double t0 = -(r+B)/A;
-         if(t0 > 0){
-           e.hitInfo.hit(t0, material, this, tex);
-         } else {
-           double t1 = (r-B)/A;
-           e.hitInfo.hit(t1, material, this, tex);
-         }
-       }
+        RayPacket::Element& e = rays.get(i);
+        const Vector& D(e.ray.direction());
+        double A = Dot(D, D);
+        double B = Dot(O, D);
+        double disc = B*B-A*C;
+        if(disc >= 0){
+          double r = sqrt(disc);
+          double t0 = -(r+B)/A;
+          if(t0 > 0){
+            e.hitInfo.hit(t0, material, this, tex);
+          } else {
+            double t1 = (r-B)/A;
+            e.hitInfo.hit(t1, material, this, tex);
+          }
+        }
       }
     }
     break;
@@ -109,22 +109,22 @@
     {
       // Rays of non-constant origin and normalized directions
       for(int i = 0;i<rays.getSize();i++){
-       RayPacket::Element& e = rays.get(i);
-       Vector O(e.ray.origin()-center);
-       const Vector& D(e.ray.direction());
-       double B = Dot(O, D);
-       double C = Dot(O, O) - radius*radius;
-       double disc = B*B-C;
-       if(disc >= 0){
-         double r = sqrt(disc);
-         double t0 = -(r+B);
-         if(t0 > 0){
-           e.hitInfo.hit(t0, material, this, tex);
-         } else {
-           double t1 = r-B;
-           e.hitInfo.hit(t1, material, this, tex);
-         }
-       }
+        RayPacket::Element& e = rays.get(i);
+        Vector O(e.ray.origin()-center);
+        const Vector& D(e.ray.direction());
+        double B = Dot(O, D);
+        double C = Dot(O, O) - radius*radius;
+        double disc = B*B-C;
+        if(disc >= 0){
+          double r = sqrt(disc);
+          double t0 = -(r+B);
+          if(t0 > 0){
+            e.hitInfo.hit(t0, material, this, tex);
+          } else {
+            double t1 = r-B;
+            e.hitInfo.hit(t1, material, this, tex);
+          }
+        }
       }
     }
     break;
@@ -132,23 +132,23 @@
     {
       // Rays of non-constant origin and non-normalized directions
       for(int i = 0;i<rays.getSize();i++){
-       RayPacket::Element& e = rays.get(i);
-       Vector O(e.ray.origin()-center);
-       const Vector& D(e.ray.direction());
-       double A = Dot(D, D);
-       double B = Dot(O, D);
-       double C = Dot(O, O) - radius*radius;
-       double disc = B*B-A*C;
-       if(disc >= 0){
-         double r = sqrt(disc);
-         double t0 = -(r+B)/A;
-         if(t0 > 0){
-           e.hitInfo.hit(t0, material, this, tex);
-         } else {
-           double t1 = (r-B)/A;
-           e.hitInfo.hit(t1, material, this, tex);
-         }
-       }
+        RayPacket::Element& e = rays.get(i);
+        Vector O(e.ray.origin()-center);
+        const Vector& D(e.ray.direction());
+        double A = Dot(D, D);
+        double B = Dot(O, D);
+        double C = Dot(O, O) - radius*radius;
+        double disc = B*B-A*C;
+        if(disc >= 0){
+          double r = sqrt(disc);
+          double t0 = -(r+B)/A;
+          if(t0 > 0){
+            e.hitInfo.hit(t0, material, this, tex);
+          } else {
+            double t1 = (r-B)/A;
+            e.hitInfo.hit(t1, material, this, tex);
+          }
+        }
       }
     }
     break;
@@ -163,10 +163,11 @@
     e.normal = e.hitPosition-center;
     e.normal*=inv_radius;
   }
+  rays.setFlag(RayPacket::HaveUnitNormals);
 }
 
 void Sphere::computeTexCoords2(const RenderContext&,
-                              RayPacket& rays) const
+                               RayPacket& rays) const
 {
   rays.computeHitPositions();
   for(int i = 0;i<rays.getSize();i++){
@@ -181,7 +182,7 @@
 }
 
 void Sphere::computeTexCoords3(const RenderContext&,
-                              RayPacket& rays) const
+                               RayPacket& rays) const
 {
   rays.computeHitPositions();
   for(int i = 0;i<rays.getSize();i++){

Modified: trunk/scenes/CMakeLists.txt
==============================================================================
--- trunk/scenes/CMakeLists.txt (original)
+++ trunk/scenes/CMakeLists.txt Mon Sep 26 11:45:58 2005
@@ -43,5 +43,12 @@
    TARGET_LINK_LIBRARIES(scene_acceltest ${manta_scene_link})
 ENDIF(SCENE_ACCELTEST)
 
+# Test different acceleration structures.
+SET(SCENE_PARTICLEBVHTEST 0 CACHE BOOL "Particle BVH Test")
+IF(SCENE_PARTICLEBVHTEST)
+   ADD_LIBRARY(scene_ParticleBVHTest ParticleBVHTest.cc)
+   TARGET_LINK_LIBRARIES(scene_ParticleBVHTest ${manta_scene_link})
+ENDIF(SCENE_PARTICLEBVHTEST)
+
 ############################################################
 

Added: trunk/scenes/ParticleBVHTest.cc
==============================================================================
--- (empty file)
+++ trunk/scenes/ParticleBVHTest.cc     Mon Sep 26 11:45:58 2005
@@ -0,0 +1,71 @@
+
+#include <Core/Exceptions/IllegalArgument.h>
+#include <Core/Util/Args.h>
+#include <Interface/Context.h>
+#include <Interface/LightSet.h>
+#include <Interface/RTRTInterface.h>
+#include <Interface/Scene.h>
+#include <Model/AmbientLights/ArcAmbient.h>
+#include <Model/Backgrounds/LinearBackground.h>
+#include <Model/Lights/PointLight.h>
+#include <Model/Materials/Phong.h>
+#include <Model/Primitives/ParticleBVH.h>
+
+#include <Core/Math/MinMax.h>
+#include <sgi_stl_warnings_off.h>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <sgi_stl_warnings_on.h>
+
+using namespace Manta;
+using namespace std;
+
+extern "C"
+Scene* make_scene(
+    const ReadContext &context,
+    const vector< string > &args )
+{
+  string model_name = "/usr/sci/data/Geometry/particle/sd022-crop.mpm";
+  int argc = static_cast< int >( args.size() );
+  for ( int i = 0; i < argc; i++ ) {
+    string arg = args[ i ];
+    if ( arg == "-model" ) {
+      if ( !getStringArg( i, args, model_name ) )
+        throw IllegalArgument( "scene particlebvhtest -model", i, args );
+    } else {
+      cerr << "Valid options for scene particlebvhtest:" << endl
+           << " -model file - MPM particle set model to show" << endl;
+      throw IllegalArgument( "scene particlebvhtest", i, args );
+    }
+  }
+  Material *material = new Phong( Color( RGB( 0.6, 0.0, 0.0 ) ),
+                                  Color( RGB( 0.6, 0.6, 0.6 ) ), 32, 0.4 );
+  ifstream in( model_name.c_str() );
+  if ( !in.is_open() )
+    throw IllegalArgument( "Couldn't load model: " + model_name, 0, args );
+  int number_of_particles, number_of_variables, radius_index;
+  in >> number_of_particles >> number_of_variables >> radius_index;
+  ParticleBVH *bvh = new ParticleBVH( material, number_of_particles );
+  float data[ number_of_variables ];
+  for ( int particle = 0; particle < number_of_particles; ++particle ) {
+    for ( int variable = 0; variable < number_of_variables; ++variable )
+      in >> data[ variable ];
+    bvh->setParticle( particle,
+                      Point( data[ 0 ], data[ 1 ], data[ 2 ] ),
+                      radius_index > 0 ? data[ radius_index ] : 1.0 );
+  }
+  Scene *scene = new Scene();
+  scene->setBackground( new LinearBackground( Color( RGB( 0.2, 0.4, 0.9 ) ),
+                                              Color( RGB( 0.0, 0.0, 0.0 ) ),
+                                              Vector( 0.0, 1.0, 0.0 ) ) );
+  scene->setObject( bvh );
+  LightSet *lights = new LightSet();
+  lights->add( new PointLight( Point( 5.0, 5.0, 8.0), Color( RGB( 2.0, 2.0 , 
2.0 ) ) ) );
+  lights->setAmbientLight( new ArcAmbient( Color( RGB( 0.1, 0.3, 0.8 ) ),
+                                           Color( RGB( 0.8, 0.6, 0.6 ) ),
+                                           Vector( 0.0, 1.0, 0.0 ) ) );
+  scene->setLights( lights );
+  return scene;
+}




  • [MANTA] r568 - in trunk: Core/Geometry Interface Model Model/Primitives scenes, aek, 09/26/2005

Archive powered by MHonArc 2.6.16.

Top of page