Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r1525 - in trunk: DynLT Model/Groups/private Model/Textures scenes


Chronological Thread 
  • From: brownlee@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r1525 - in trunk: DynLT Model/Groups/private Model/Textures scenes
  • Date: Fri, 20 Jul 2007 23:41:27 -0600 (MDT)

Author: brownlee
Date: Fri Jul 20 23:41:17 2007
New Revision: 1525

Added:
   trunk/DynLT/DynLTCGT.cc
   trunk/DynLT/DynLTCGT.cc~
   trunk/DynLT/DynLTCGT.h
   trunk/DynLT/DynLTCGT.h~
Modified:
   trunk/DynLT/CMakeLists.txt
   trunk/Model/Groups/private/ParticleCGT.cc
   trunk/Model/Groups/private/ParticleCGT.h
   trunk/Model/Textures/ColorMap.cc
   trunk/Model/Textures/ColorMap.h
   trunk/scenes/particleCGTTest.cc
   trunk/scenes/pcgt.cc
Log:
ColorMaps for ParticleCGT, skeleton file for DynLTCGT added

Modified: trunk/DynLT/CMakeLists.txt
==============================================================================
--- trunk/DynLT/CMakeLists.txt  (original)
+++ trunk/DynLT/CMakeLists.txt  Fri Jul 20 23:41:17 2007
@@ -12,6 +12,8 @@
     DynLTStatsCollector.cc
     DynLTWorker.h
     DynLTWorker.cc
+    DynLTCGT.h
+    DynLTCGT.cc
     )
 
 INCLUDE_DIRECTORIES(${FOUND_TEEM_INCLUDE})

Added: trunk/DynLT/DynLTCGT.cc
==============================================================================
--- (empty file)
+++ trunk/DynLT/DynLTCGT.cc     Fri Jul 20 23:41:17 2007
@@ -0,0 +1,281 @@
+
+#include <Core/Color/RegularColorMap.h>
+#include <DynLT/DynLTContext.h>
+#include <DynLT/DynLTCGT.h>
+#include <DynLT/DynLTQueue.h>
+#include <DynLT/DynLTWorker.h>
+#include <Interface/AmbientLight.h>
+#include <Interface/LightSet.h>
+#include <Interface/RayPacket.h>
+
+#include <iostream>
+using std::cerr;
+
+using namespace Manta;
+using namespace SCIRun;
+
+#define UPDATE_TIME 2.5
+
+DynLTCGT::DynLTCGT(DynLTQueue* queue,
+                                   float* spheres, int nspheres, int nvars,
+                                   int ncells, int depth, Real radius,
+                                   int ridx, RegularColorMap* cmap, int 
cidx) :
+  queue(queue), ParticleGrid(cidx)
+{
+  cerr<<"Initializing DynLTGridSpheres\n";
+  plts.resize(nspheres);
+  valid.resize(nspheres);
+  allocated.resize(nspheres);
+  requested.resize(nspheres);
+#ifdef USE_STATS_COLLECTOR
+  latency.resize(nspheres);
+  texgen.resize(nspheres);
+#endif
+  for (unsigned int i=0; i<nspheres; ++i) {
+    plts[i]=0;
+    requested[i]=0;
+    allocated[i]=false;
+    valid[i]=false;
+#ifdef USE_STATS_COLLECTOR
+    latency[i]=0;
+    texgen[i]=0;
+#endif
+  }
+
+  // XXX:  hard coded for now
+  // textureMode=AmbientOcclusion;
+  textureMode=GlobalIllumination;
+}
+
+DynLTCGT::~DynLTCGT(void)
+{
+  // Do nothing
+}
+
+void DynLTCGT::shade(const RenderContext& context,
+                             RayPacket& rays) const
+{
+  switch (textureMode) {
+  case AmbientOcclusion:
+    shadeAmbient(context, rays);
+    break;
+  case GlobalIllumination:
+  default:
+    shadeGlobal(context, rays);
+    break;
+  }
+}
+
+void DynLTCGT::shadeAmbient(const RenderContext& context,
+                                    RayPacket& rays) const
+{
+  ColorArray ambient;
+
+  for (unsigned int i=rays.begin(); i<rays.end(); ) {
+    // Find a run of rays that hit the same particle
+    int offset=rays.scratchpad<int>(i);
+    unsigned int end=i + 1;
+    while (end < rays.end() && rays.scratchpad<int>(end)==offset)
+      ++end;
+
+    int particle = offset/nvars;
+    //compute ambient light
+    RayPacket sub(rays, i , end);
+    if (valid[particle]) {
+      // Compute diffuse colors
+      Packet<Color> diffuse;
+      //mapDiffuseColors(diffuse, sub);
+
+      // Compute textured ambient luminance  // TODO:
+      sub.computeTextureCoordinates2(context);
+
+      for (unsigned int i=sub.begin(); i<sub.end(); ++i) {
+        Real luminance=computeLuminance(i, sub, particle);
+        for (int j=0; j < Color::NumComponents; ++j)
+          ambient[j][i]=luminance;
+      }
+    } else {
+      // Request texture generation, if necessary
+      if (requested[particle]==0.) {
+#ifdef USE_STATS_COLLECTOR
+        // Store request time
+        latency[particle]=Time::currentSeconds();
+
+        // Increment number of requests
+        DynLTStatsCollector::TexturesRequestedPerFrame.increment();
+
+        // Increment number of visible particles
+        DynLTStatsCollector::NumberVisiblePerFrame.increment();
+#endif
+
+        // Create and post message
+        double priority=computePriority(rays.getMinT(i));
+        //TODO: DynLTMessage msg(particle, priority, this);
+        ///TODO: if (queue->trySend(msg))
+        //  requested[particle]=priority;
+      } else {
+#ifdef UPDATE_TIME
+        if (Time::currentSeconds() - requested[particle] > UPDATE_TIME) {
+          // Update priority only after UPDATE_TIME seconds
+          requested[particle]=computePriority(rays.getMinT(i));
+          queue->updatePriority(particle, requested[particle]);
+
+#ifdef USE_STATS_COLLECTOR
+          // Update request time
+          latency[particle]=Time::currentSeconds();
+
+          // Updates count as a new request --> increment number of requests
+          DynLTStatsCollector::TexturesRequestedPerFrame.increment();
+#endif
+        }
+#else
+        // Update priority
+        requested[particle]=computePriority(rays.getMinT(i));
+        queue->updatePriority(particle, requested[particle]);
+
+#ifdef USE_STATS_COLLECTOR
+        // Update request time
+        latency[particle]=Time::currentSeconds();
+
+        // Updates count as a new request --> increment number of requests
+        DynLTStatsCollector::TexturesRequestedPerFrame.increment();
+#endif
+#endif // UPDATE_TIME
+      }
+
+      // Use default ambient light while texture is invalid
+      activeLights->getAmbientLight()->computeAmbient(context, sub, ambient);
+    }
+
+    i=end;
+  }
+
+  // Shade the rays
+  // TODO: GridSpheres::lambertianShade(context, rays, ambient);
+}
+
+void DynLTCGT::shadeGlobal(const RenderContext& context,
+                                   RayPacket& rays) const
+{
+  for (unsigned int i=rays.begin(); i<rays.end(); ) {
+    // Find a run of rays that hit the same particle
+    int offset=rays.scratchpad<int>(i);
+    unsigned int end=i + 1;
+    while (end < rays.end() && rays.scratchpad<int>(end)==offset)
+      ++end;
+
+    int particle=offset/nvars;
+
+    // Shade the rays
+    RayPacket sub(rays, i, end);
+    if (valid[particle]) {
+      // Compute diffuse colors
+      Packet<Color> diffuse;
+      //TODO: mapDiffuseColors(diffuse, rays);
+    
+      // Compute textured luminance
+      sub.computeTextureCoordinates2(context);
+
+      // XXX - Using the ambient may just be a hack; DynLTWorker might need 
to
+      //       account for it, or maybe it's just wrong given that we're
+      //       computing global illumination (except that the background 
doesn't
+      //       contributed)...  I don't know, and at this point, I don't 
really
+      //       care!
+#define USE_AMBIENT 1
+#ifdef USE_AMBIENT
+      ColorArray ambient;
+      activeLights->getAmbientLight()->computeAmbient(context, rays, 
ambient);
+#endif
+
+      for (unsigned int i=sub.begin(); i<sub.end(); ++i) {
+#ifdef USE_AMBIENT
+        Real luminance=computeLuminance(i, sub, particle);
+        luminance += 0.3*ambient[0][i] + 0.6*ambient[1][i] + 
0.1*ambient[2][i];
+
+        sub.setColor(i, diffuse.get(i)*luminance);
+#else
+        Real luminance=computeLuminance(i, sub, particle);
+        sub.setColor(i, diffuse.get(i)*luminance);
+#endif
+      }
+    } else {
+      // Request texture generation, if necessary
+      if (requested[particle]==0.) {
+#ifdef USE_STATS_COLLECTOR
+        // Store request time
+        latency[particle]=Time::currentSeconds();
+#endif
+
+        // Create and post message
+        double priority=computePriority(rays.getMinT(i));
+        //TODO: DynLTMessage msg(particle, priority, this);
+        //TODO: if (queue->trySend(msg))
+        //  requested[particle]=priority;
+
+#ifdef USE_STATS_COLLECTOR
+        // Increment number of requests
+        DynLTStatsCollector::TexturesRequestedPerFrame.increment();
+#endif
+      } else {
+#ifdef USE_STATS_COLLECTOR
+        // Update request time
+        latency[particle]=Time::currentSeconds();
+#endif
+
+#ifdef UPDATE_TIME
+        // Update priority only after UPDATE_TIME seconds
+        if (Time::currentSeconds() - requested[particle] > UPDATE_TIME) {
+          requested[particle]=computePriority(rays.getMinT(i));
+          queue->updatePriority(particle, requested[particle]);
+        }
+#else
+        requested[particle]=computePriority(rays.getMinT(i));
+        queue->updatePriority(particle, requested[particle]);
+#endif
+      }
+
+      // Use Lambertian shading while texture is invalid
+      //TODO: GridSpheres::shade(context, sub);
+    }
+
+    i=end;
+  }
+}
+
+Real DynLTCGT::computeLuminance(unsigned int ray_idx, RayPacket& rays,
+                                        unsigned int particle) const
+{
+  // Wrap in x (assumes xres is a power of two)
+  Real x=rays.getTexCoords2(ray_idx, 0)*XRES;
+  int lx=static_cast<int>(x) & (XRES - 1);
+  int hx=(lx + 1) & (XRES - 1);
+  Real wx=x - lx;
+
+  // Clamp in y
+  Real y=rays.getTexCoords2(ray_idx, 1);
+  int ly;
+  Real wy;
+  if (y < 0) {
+    ly=0;
+    wy=0;
+  } else {
+    y *= YRES - 1;
+    ly=static_cast<int>(y);
+    if (ly > YRES - 1) {
+      ly=YRES - 1;
+      wy=0;
+    } else {
+      wy=y - ly;
+    }
+  }
+
+  int hy=ly + 1;
+
+  // Bi-linearly interpolate
+  Real a=(plts[particle]->texture[lx][ly]*(1 - wx) +
+          plts[particle]->texture[hx][ly]*wx);
+  Real b=(plts[particle]->texture[lx][hy]*(1 - wx) +
+          plts[particle]->texture[hx][hy]*wx);
+
+  return a*(1 - wy) + b*wy;
+}

Added: trunk/DynLT/DynLTCGT.cc~
==============================================================================
--- (empty file)
+++ trunk/DynLT/DynLTCGT.cc~    Fri Jul 20 23:41:17 2007
@@ -0,0 +1,524 @@
+
+#include <Core/Color/RegularColorMap.h>
+#include <DynLT/DynLTContext.h>
+#include <DynLT/DynLTCGT.h>
+#include <DynLT/DynLTQueue.h>
+#include <DynLT/DynLTWorker.h>
+#include <Interface/AmbientLight.h>
+#include <Interface/LightSet.h>
+#include <Interface/RayPacket.h>
+
+#include <iostream>
+using std::cerr;
+
+using namespace Manta;
+using namespace SCIRun;
+
+#define UPDATE_TIME 2.5
+
+DynLTGridSpheres::DynLTGridSpheres(DynLTQueue* queue,
+                                   float* spheres, int nspheres, int nvars,
+                                   int ncells, int depth, Real radius,
+                                   int ridx, RegularColorMap* cmap, int 
cidx) :
+  queue(queue), ParticleGrid(cidx)
+{
+  cerr<<"Initializing DynLTGridSpheres\n";
+  plts.resize(nspheres);
+  valid.resize(nspheres);
+  allocated.resize(nspheres);
+  requested.resize(nspheres);
+#ifdef USE_STATS_COLLECTOR
+  latency.resize(nspheres);
+  texgen.resize(nspheres);
+#endif
+  for (unsigned int i=0; i<nspheres; ++i) {
+    plts[i]=0;
+    requested[i]=0;
+    allocated[i]=false;
+    valid[i]=false;
+#ifdef USE_STATS_COLLECTOR
+    latency[i]=0;
+    texgen[i]=0;
+#endif
+  }
+
+  // XXX:  hard coded for now
+  // textureMode=AmbientOcclusion;
+  textureMode=GlobalIllumination;
+}
+
+DynLTCGT::~DynLTCGT(void)
+{
+  // Do nothing
+}
+
+void DynLTCGT::shade(const RenderContext& context,
+                             RayPacket& rays) const
+{
+  switch (textureMode) {
+  case AmbientOcclusion:
+    shadeAmbient(context, rays);
+    break;
+  case GlobalIllumination:
+  default:
+    shadeGlobal(context, rays);
+    break;
+  }
+}
+
+void DynLTCGT::shadeAmbient(const RenderContext& context,
+                                    RayPacket& rays) const
+{
+  ColorArray ambient;
+
+  for (unsigned int i=rays.begin(); i<rays.end(); ) {
+    // Find a run of rays that hit the same particle
+    int offset=rays.scratchpad<int>(i);
+    unsigned int end=i + 1;
+    while (end < rays.end() && rays.scratchpad<int>(end)==offset)
+      ++end;
+
+    int particle=offset/nvars;
+
+    void preprocess(const PreprocessContext&);
+
+    void computeBounds(const PreprocessContext& context,
+                       BBox& bbox) const;
+    void intersect(const RenderContext& context, RayPacket& rays) const;
+    void computeNormal(const RenderContext& context, RayPacket& rays) const;
+
+    virtual void shade(const RenderContext& context, RayPacket& rays) const;
+
+    void computeTexCoords2(const RenderContext& context,
+                                  RayPacket& rays) const;
+    void computeTexCoords3(const RenderContext& context,
+                                  RayPacket& rays) const;
+
+  protected:
+#ifdef USE_OPTIMIZED_FCNS
+    typedef void (GridSpheres::*SphereIntersectFcn)(RayPacket&, int, int,
+                                                    const Vector&, float) 
const;
+#endif
+
+    struct MCell {
+      int nspheres;
+      float* max;
+      float* min;
+    };
+
+    void traverse(int i, RayPacket& rays, int depth,
+                  Real tnear,
+                  int ix, int iy, int iz,
+                  int idx,
+                  Real dt_dx, Real dt_dy, Real dt_dz,
+                  Real tnext_x, Real tnext_y, Real tnext_z,
+
+    // Compute ambient light for the rays
+    RayPacket sub(rays, i, end);
+    void preprocess(const PreprocessContext&);
+
+    void computeBounds(const PreprocessContext& context,
+                       BBox& bbox) const;
+    void intersect(const RenderContext& context, RayPacket& rays) const;
+    void computeNormal(const RenderContext& context, RayPacket& rays) const;
+
+    virtual void shade(const RenderContext& context, RayPacket& rays) const;
+
+    void computeTexCoords2(const RenderContext& context,
+                                  RayPacket& rays) const;
+    void computeTexCoords3(const RenderContext& context,
+                                  RayPacket& rays) const;
+
+  protected:
+#ifdef USE_OPTIMIZED_FCNS
+    typedef void (GridSpheres::*SphereIntersectFcn)(RayPacket&, int, int,
+                                                    const Vector&, float) 
const;
+#endif
+
+    struct MCell {
+      int nspheres;
+      float* max;
+      float* min;
+    };
+
+    void traverse(int i, RayPacket& rays, int depth,
+                  Real tnear,
+                  int ix, int iy, int iz,
+                  int idx,
+                  Real dt_dx, Real dt_dy, Real dt_dz,
+                  Real tnext_x, Real tnext_y, Real tnext_z,
+
+    if (valid[particle]) {
+      // Compute diffuse colors
+      Packet<Color> diffuse;
+      mapDiffuseColors(diffuse, sub);
+
+      // Compute textured ambient luminance
+      sub.computeTextureCoordinates2(context);
+
+      for (unsigned int i=sub.begin(); i<sub.end(); ++i) {
+        Real luminance=computeLuminance(i, sub, particle);
+        for (int j=0; j < Color::NumComponents; ++j)
+          ambient[j][i]=luminance;
+      }
+    } else {
+      // Request texture generation, if necessary
+      if (requested[particle]==0.) {
+#ifdef USE_STATS_COLLECTOR
+        // Store request time
+        latency[particle]=Time::currentSeconds();
+
+        // Increment number of requests
+        DynLTStatsCollector::TexturesRequestedPerFrame.increment();
+
+        // Increment number of visible particles
+        DynLTStatsCollector::NumberVisiblePerFrame.increment();
+#endif
+
+        // Create and post message
+        double priority=computePriority(rays.getMinT(i));
+        DynLTMessage msg(particle, priority, this);
+        if (queue->trySend(msg))
+          requested[particle]=priority;
+      } else {
+#ifdef UPDATE_TIME
+        if (Time::currentSeconds() - requested[particle] > UPDATE_TIME) {
+          // Update priority only after UPDATE_TIME seconds
+          requested[particle]=computePriority(rays.getMinT(i));
+          queue->updatePriority(particle, requested[particle]);
+
+#ifdef USE_STATS_COLLECTOR
+          // Update request time
+          latency[particle]=Time::currentSeconds();
+
+          // Updates count as a new request --> increment number of requests
+          DynLTStatsCollector::TexturesRequestedPerFrame.increment();
+#endif
+        }
+#else
+        // Update priority
+        requested[particle]=computePriority(rays.getMinT(i));
+        queue->updatePriority(particle, requested[particle]);
+
+#ifdef USE_STATS_COLLECTOR
+        // Update request time
+        latency[particle]=Time::currentSeconds();
+
+        // Updates count as a new request --> increment number of requests
+        DynLTStatsCollector::TexturesRequestedPerFrame.increment();
+#endif
+#endif // UPDATE_TIME
+      }
+
+      // Use default ambient light while texture is invalid
+      activeLights->getAmbientLight()->computeAmbient(context, sub, ambient);
+    }
+
+    i=end;
+  }
+
+  // Shade the rays
+  GridSpheres::lambertianShade(context, rays, ambient);
+}
+
+void DynLTCGT::shadeGlobal(const RenderContext& context,
+                                   RayPacket& rays) const
+{
+  for (unsigned int i=rays.begin(); i<rays.end(); ) {
+    // Find a run of rays that hit the same particle
+    int offset=rays.scratchpad<int>(i);
+    unsigned int end=i + 1;
+    while (end < rays.end() && rays.scratchpad<int>(end)==offset)
+      ++end;
+
+    int particle=offset/nvars;
+
+    // Shade the rays
+    RayPacket sub(rays, i, end);
+    if (valid[particle]) {
+      // Compute diffuse colors
+      Packet<Color> diffuse;
+      mapDiffuseColors(diffuse, rays);
+    
+      // Compute textured luminance
+      sub.computeTextureCoordinates2(context);
+
+      // XXX - Using the ambient may just be a hack; DynLTWorker might need 
to
+      //       account for it, or maybe it's just wrong given that we're
+      //       computing global illumination (except that the background 
doesn't
+      //       contributed)...  I don't know, and at this point, I don't 
really
+      //       care!
+#define USE_AMBIENT 1
+#ifdef USE_AMBIENT
+      ColorArray ambient;
+      activeLights->getAmbientLight()->computeAmbient(context, rays, 
ambient);
+#endif
+
+      for (unsigned int i=sub.begin(); i<sub.end(); ++i) {
+#ifdef USE_AMBIENT
+        Real luminance=computeLuminance(i, sub, particle);
+        luminance += 0.3*ambient[0][i] + 0.6*ambient[1][i] + 
0.1*ambient[2][i];
+
+        sub.setColor(i, diffuse.get(i)*luminance);
+#else
+        Real luminance=computeLuminance(i, sub, particle);
+        sub.setColor(i, diffuse.get(i)*luminance);
+    void preprocess(const PreprocessContext&);
+
+    void computeBounds(const PreprocessContext& context,
+                       BBox& bbox) const;
+    void intersect(const RenderContext& context, RayPacket& rays) const;
+    void computeNormal(const RenderContext& context, RayPacket& rays) const;
+
+    virtual void shade(const RenderContext& context, RayPacket& rays) const;
+
+    void computeTexCoords2(const RenderContext& context,
+                                  RayPacket& rays) const;
+    void computeTexCoords3(const RenderContext& context,
+                                  RayPacket& rays) const;
+
+  protected:
+#ifdef USE_OPTIMIZED_FCNS
+    typedef void (GridSpheres::*SphereIntersectFcn)(RayPacket&, int, int,
+                                                    const Vector&, float) 
const;
+#endif
+
+    struct MCell {
+      int nspheres;
+      float* max;
+      float* min;
+    };
+
+    void traverse(int i, RayPacket& rays, int depth,
+                  Real tnear,
+                  int ix, int iy, int iz,
+                  int idx,
+                  Real dt_dx, Real dt_dy, Real dt_dz,
+                  Real tnext_x, Real tnext_y, Real tnext_z,
+
+#endif
+      }
+    } else {
+      // Request texture generation, if necessary
+      if (requested[particle]==0.) {
+#ifdef USE_STATS_COLLECTOR
+        // Store request time
+        latency[particle]=Time::currentSeconds();
+#endif
+
+        // Create and post message
+        double priority=computePriority(rays.getMinT(i));
+        DynLTMessage msg(particle, priority, this);
+        if (queue->trySend(msg))
+          requested[particle]=priority;
+
+#ifdef USE_STATS_COLLECTOR
+        // Increment number of requests
+        DynLTStatsCollector::TexturesRequestedPerFrame.increment();
+#endif
+      } else {
+#ifdef USE_STATS_COLLECTOR
+        // Update request time
+        latency[particle]=Time::currentSeconds();
+#endif
+
+#ifdef UPDATE_TIME
+        // Update priority only after UPDATE_TIME seconds
+        if (Time::currentSeconds() - requested[particle] > UPDATE_TIME) {
+          requested[particle]=computePriority(rays.getMinT(i));
+          queue->updatePriority(particle, requested[particle]);
+        }
+#else
+        requested[particle]=computePriority(rays.getMinT(i));
+        queue->updatePriority(particle, requested[particle]);
+#endif
+      }
+
+      // Use Lambertian shading while texture is invalid
+      GridSpheres::shade(context, sub);
+    }
+
+    i=end;
+  }
+}
+
+Real DynLTCGT::computeLuminance(unsigned int ray_idx, RayPacket& rays,
+                                        unsigned int particle) const
+{
+  // Wrap in x (assumes xres is a power of two)
+  Real x=rays.getTexCoords2(ray_idx, 0)*XRES;
+  int lx=static_cast<int>(x) & (XRES - 1);
+  int hx=(lx + 1) & (XRES - 1);
+  Real wx=x - lx;
+
+  // Clamp in y
+  Real y=rays.getTexCoords2(ray_idx, 1);
+  int ly;
+  Real wy;
+  if (y < 0) {
+    ly=0;
+    wy=0;
+  } else {
+    y *= YRES - 1;
+    ly=static_cast<int>(y);
+    if (ly > YRES - 1) {
+      ly=YRES - 1;
+      wy=0;
+    } else {
+      wy=y - ly;
+    }
+  }
+
+  int hy=ly + 1;
+
+  // Bi-linearly interpolate
+  Real a=(plts[particle]->texture[lx][ly]*(1 - wx) +
+          plts[particle]->texture[hx][ly]*wx);
+  Real b=(plts[particle]->texture[lx][hy]*(1 - wx) +
+          plts[particle]->texture[hx][hy]*wx);
+
+  return a*(1 - wy) + b*wy;
+}
+
+void DynLT::dilate(const DynLTContext* context)
+{
+  // Compute the min and max of inside texture
+  unsigned int width=XRES;
+  unsigned int height=YRES;
+  Real min=inside[0][0];
+  Real max=inside[0][0];
+  for (unsigned int y=1; y<height; ++y) {
+    void preprocess(const PreprocessContext&);
+
+    void computeBounds(const PreprocessContext& context,
+                       BBox& bbox) const;
+    void intersect(const RenderContext& context, RayPacket& rays) const;
+    void computeNormal(const RenderContext& context, RayPacket& rays) const;
+
+    virtual void shade(const RenderContext& context, RayPacket& rays) const;
+
+    void computeTexCoords2(const RenderContext& context,
+                                  RayPacket& rays) const;
+    void computeTexCoords3(const RenderContext& context,
+                                  RayPacket& rays) const;
+
+  protected:
+#ifdef USE_OPTIMIZED_FCNS
+    typedef void (GridSpheres::*SphereIntersectFcn)(RayPacket&, int, int,
+                                                    const Vector&, float) 
const;
+#endif
+
+    struct MCell {
+      int nspheres;
+      float* max;
+    void preprocess(const PreprocessContext&);
+
+    void computeBounds(const PreprocessContext& context,
+                       BBox& bbox) const;
+    void intersect(const RenderContext& context, RayPacket& rays) const;
+    void computeNormal(const RenderContext& context, RayPacket& rays) const;
+
+    virtual void shade(const RenderContext& context, RayPacket& rays) const;
+
+    void computeTexCoords2(const RenderContext& context,
+                                  RayPacket& rays) const;
+    void computeTexCoords3(const RenderContext& context,
+                                  RayPacket& rays) const;
+
+  protected:
+#ifdef USE_OPTIMIZED_FCNS
+    typedef void (GridSpheres::*SphereIntersectFcn)(RayPacket&, int, int,
+                                                    const Vector&, float) 
const;
+#endif
+
+    struct MCell {
+      int nspheres;
+      float* max;
+      float* min;
+    };
+
+    void traverse(int i, RayPacket& rays, int depth,
+                  Real tnear,
+                  int ix, int iy, int iz,
+                  int idx,
+                  Real dt_dx, Real dt_dy, Real dt_dz,
+                  Real tnext_x, Real tnext_y, Real tnext_z,
+
+      float* min;
+    };
+
+    void traverse(int i, RayPacket& rays, int depth,
+                  Real tnear,
+                  int ix, int iy, int iz,
+                  int idx,
+                  Real dt_dx, Real dt_dy, Real dt_dz,
+                  Real tnext_x, Real tnext_y, Real tnext_z,
+
+    for (unsigned int x=1; x<width; ++x) {
+      Real tmp=inside[x][y];
+      if (tmp < min)
+       min=tmp;
+      if (tmp > max)
+       max=tmp;
+    }
+  }
+
+  // Normalize the inside texture
+  Real inv_maxmin=1/(max-min);
+  for (unsigned int y=0; y<height; ++y)
+    for (unsigned int x=0; x<width; ++x)
+      inside[x][y]=(inside[x][y] - min)*inv_maxmin;
+
+  // Initialize the dilated texture
+  Real dilated[XRES][YRES];
+  for (unsigned int y=0; y<height; ++y)
+    for (unsigned int x=0; x<width; ++x)
+      dilated[x][y]=texture[x][y];
+  
+  // Dilate any necessary pixels
+  unsigned int support=context->support;
+  unsigned int use_weighted_avg=context->use_weighted_avg;
+  Real threshold=context->threshold;
+  
+  for (unsigned int y=0; y < height;  ++y) {
+    for (unsigned int x=0; x < width;  ++x) {
+      // Determine if the pixel should be dilated
+      Real value=inside[x][y];
+      if (value<=0)
+        continue;
+      
+      // Loop over each neighbor
+      Real avg=0;
+      Real contribution_total=0;
+      for (unsigned int j=y-support; j <= y+support; j++) {
+        for (unsigned int i=x-support; i <= x+support; i++) {
+          // Check boundary conditions
+          unsigned int newi=i;
+          if (newi >= width)
+            newi=newi - width;
+
+          unsigned int newj=j;
+          if (newj >= height)
+            newj=height - 1;
+
+          // Determine neighbor's contribution
+          Real contributer=inside[newi][newj];
+          if (contributer < threshold) {
+            contributer *= use_weighted_avg;
+            avg += texture[newi][newj]*(1 - contributer);
+            contribution_total += (1 - contributer);
+          }
+        }
+      }
+
+      // Dilate the pixel
+      if (contribution_total > 0)
+        dilated[x][y]=avg/contribution_total;
+    }
+  }
+  
+  // Update texture with dilated results
+  for (unsigned int y=0; y<height; ++y)
+    for (unsigned int x=0; x<width; ++x)
+      texture[x][y]=dilated[x][y];
+}

Added: trunk/DynLT/DynLTCGT.h
==============================================================================
--- (empty file)
+++ trunk/DynLT/DynLTCGT.h      Fri Jul 20 23:41:17 2007
@@ -0,0 +1,168 @@

+#ifndef Manta_DynLT_DynLTCGT_h
+#define Manta_DynLT_DynLTCGT_h
+
+#include <UseStatsCollector.h>
+#include <DynLT/DynLTStatsCollector.h>
+#include <Model/Primitives/GridSpheres.h>
+#include <SCIRun/Core/Thread/Mailbox.h>
+#include <SCIRun/Core/Thread/Time.h>
+#include <Model/Groups/private/ParticleCGT.h>
+#include <Interface/Texture.h>
+#include <Model/Materials/LitMaterial.h>
+#include <Model/Primitives/PrimitiveCommon.h>
+#include <DynLT/DynLTGridSpheres.h>
+
+
+// XXX:  temporary
+#include <iostream>
+
+#include <vector>
+using std::vector;
+
+#include <float.h>
+
+using namespace SCIRun;
+
+#define XRES 16
+#define YRES 16
+
+namespace Manta {
+
+  class DynLTCGT : public ParticleGrid, public LitMaterial, public 
TexCoordMapper
+  {
+  public:
+    enum {
+      AmbientOcclusion,
+      GlobalIllumination
+    } TextureMode;
+
+    DynLTCGT(DynLTQueue* queue, float* spheres,
+                     int nspheres, int nvars, int ncells, int depth,
+                     Real radius, int ridx, RegularColorMap* cmap, int cidx);
+    ~DynLTCGT(void);
+
+    void shade(const RenderContext& context, RayPacket& rays) const;
+
+    unsigned int getNParticles(void) const { return nspheres; }
+
+    const LightSet* getActiveLights(void) const { return activeLights; }
+
+    unsigned int getTextureMode(void) const { return textureMode; }
+
+    void setTextureMode(unsigned int mode)
+    {
+      if (textureMode != mode) {
+        invalidateTextures();
+        textureMode=mode;
+      }
+    }
+
+    Vector getCenter(int particle) const
+    {
+      float* data=spheres + particle*nvars;
+      return Vector(data[0], data[1], data[2]);
+    }
+
+    Real getRadius(int particle) const
+    {
+      float* data=spheres + particle*nvars;
+      if (ridx>0) {
+        if (data[ridx] <= 0)
+          return radius;
+        else
+          return data[ridx];
+      }
+
+      return radius;
+    }
+
+    bool isValid(int idx) {
+      return valid[idx];
+    }
+
+    bool isAllocated(int idx) {
+      return allocated[idx];
+    }
+
+    void setValid(int idx) {
+      valid[idx]=true;
+
+#ifdef USE_STATS_COLLECTOR
+      // Compute latency and increment counter
+      latency[idx]=Time::currentSeconds() - latency[idx];
+      
DynLTStatsCollector::TexGenLatency.increment(static_cast<float>(latency[idx]));
+#endif
+    }
+
+    void allocate(int idx) {
+      plts[idx]=new DynLT();
+      allocated[idx]=true;
+    }
+
+    void dilate(const DynLTContext* context, int idx) {
+      plts[idx]->dilate(context);
+    }
+
+    DynLT* getTexture(int idx) {
+      return plts[idx];
+    }
+    
+    double computePriority(Real t) const {
+      // Time-stamp only
+      // return Time::currentSeconds();
+
+      // Distance only (closest first)
+      // return DBL_MAX - t;
+
+      // Weighted combination of time-stamp and distance
+      return 0.1*Time::currentSeconds() - 10.*t;
+    }
+
+    void resetRequested(int idx) {
+      requested[idx]=0.;
+    }
+
+#ifdef USE_STATS_COLLECTOR
+    void setTexGenTime(int idx, double time)
+    {
+      // Set texture generation time and increment counters
+      texgen[idx]=time;so
+      
DynLTStatsCollector::TexGenTime.increment(static_cast<float>(texgen[idx]));
+      DynLTStatsCollector::TexturesGeneratedPerFrame.increment();
+    }
+#endif
+
+  private:
+    void shadeAmbient(const RenderContext& context, RayPacket& rays) const;
+    void shadeGlobal(const RenderContext& context, RayPacket& rays) const;
+    Real computeLuminance(unsigned int ray_idx, RayPacket& rays,
+                          unsigned int particle) const;
+
+    void invalidateTextures(void)
+    {
+      for (unsigned int i=0; i<nspheres; ++i) {
+        requested[i]=0;
+        valid[i]=false;
+      }
+    }
+
+    DynLTQueue* queue;
+    mutable vector<double> requested;
+    vector<bool> allocated;
+    vector<bool> valid;
+    vector<DynLT*> plts;
+    int nspheres, nvars, ncells, depth, ridx, cidx;
+    Real radius;
+    float* spheres;
+
+    unsigned int textureMode;
+
+#ifdef USE_STATS_COLLECTOR
+    mutable vector<double> latency;
+    mutable vector<double> texgen;
+#endif
+  };
+}
+
+#endif // Manta_DynLT_DynLTGridSpheres_h

Added: trunk/DynLT/DynLTCGT.h~
==============================================================================
--- (empty file)
+++ trunk/DynLT/DynLTCGT.h~     Fri Jul 20 23:41:17 2007
@@ -0,0 +1,177 @@

+#ifndef Manta_DynLT_DynLTGridSpheres_h
+#define Manta_DynLT_DynLTGridSpheres_h
+
+#include <UseStatsCollector.h>
+#include <DynLT/DynLTStatsCollector.h>
+#include <Model/Primitives/GridSpheres.h>
+#include <SCIRun/Core/Thread/Mailbox.h>
+#include <SCIRun/Core/Thread/Time.h>
+
+// XXX:  temporary
+#include <iostream>
+
+#include <vector>
+using std::vector;
+
+#include <float.h>
+
+using namespace SCIRun;
+
+#define XRES 16
+#define YRES 16
+
+namespace Manta {
+  class DynLTContext;
+  class DynLTQueue;
+  class RegularColorMap;
+
+  class DynLT {
+  public:
+    DynLT(void) { }
+    ~DynLT(void) { }
+
+    unsigned int getXRes(void) const { return XRES; }
+    unsigned int getYRes(void) const { return YRES; }
+
+    void dilate(const DynLTContext* context);
+
+    // Luminance texture data    
+    Real texture[XRES][YRES];
+    Real inside[XRES][YRES];
+  };
+
+  class DynLTGridSpheres : public GridSpheres
+  {
+  public:
+    enum {
+      AmbientOcclusion,
+      GlobalIllumination
+    } TextureMode;
+
+    DynLTGridSpheres(DynLTQueue* queue, float* spheres,
+                     int nspheres, int nvars, int ncells, int depth,
+                     Real radius, int ridx, RegularColorMap* cmap, int cidx);
+    ~DynLTGridSpheres(void);
+
+    void shade(const RenderContext& context, RayPacket& rays) const;
+
+    unsigned int getNParticles(void) const { return nspheres; }
+
+    const LightSet* getActiveLights(void) const { return activeLights; }
+
+    unsigned int getTextureMode(void) const { return textureMode; }
+
+    void setTextureMode(unsigned int mode)
+    {
+      if (textureMode != mode) {
+        invalidateTextures();
+        textureMode=mode;
+      }
+    }
+
+    Vector getCenter(int particle) const
+    {
+      float* data=spheres + particle*nvars;
+      return Vector(data[0], data[1], data[2]);
+    }
+
+    Real getRadius(int particle) const
+    {
+      float* data=spheres + particle*nvars;
+      if (ridx>0) {
+        if (data[ridx] <= 0)
+          return radius;
+        else
+          return data[ridx];
+      }
+
+      return radius;
+    }
+
+    bool isValid(int idx) {
+      return valid[idx];
+    }
+
+    bool isAllocated(int idx) {
+      return allocated[idx];
+    }
+
+    void setValid(int idx) {
+      valid[idx]=true;
+
+#ifdef USE_STATS_COLLECTOR
+      // Compute latency and increment counter
+      latency[idx]=Time::currentSeconds() - latency[idx];
+      
DynLTStatsCollector::TexGenLatency.increment(static_cast<float>(latency[idx]));
+#endif
+    }
+
+    void allocate(int idx) {
+      plts[idx]=new DynLT();
+      allocated[idx]=true;
+    }
+
+    void dilate(const DynLTContext* context, int idx) {
+      plts[idx]->dilate(context);
+    }
+
+    DynLT* getTexture(int idx) {
+      return plts[idx];
+    }
+    
+    double computePriority(Real t) const {
+      // Time-stamp only
+      // return Time::currentSeconds();
+
+      // Distance only (closest first)
+      // return DBL_MAX - t;
+
+      // Weighted combination of time-stamp and distance
+      return 0.1*Time::currentSeconds() - 10.*t;
+    }
+
+    void resetRequested(int idx) {
+      requested[idx]=0.;
+    }
+
+#ifdef USE_STATS_COLLECTOR
+    void setTexGenTime(int idx, double time)
+    {
+      // Set texture generation time and increment counters
+      texgen[idx]=time;
+      
DynLTStatsCollector::TexGenTime.increment(static_cast<float>(texgen[idx]));
+      DynLTStatsCollector::TexturesGeneratedPerFrame.increment();
+    }
+#endif
+
+  private:
+    void shadeAmbient(const RenderContext& context, RayPacket& rays) const;
+    void shadeGlobal(const RenderContext& context, RayPacket& rays) const;
+    Real computeLuminance(unsigned int ray_idx, RayPacket& rays,
+                          unsigned int particle) const;
+
+    void invalidateTextures(void)
+    {
+      for (unsigned int i=0; i<nspheres; ++i) {
+        requested[i]=0;
+        valid[i]=false;
+      }
+    }
+
+    DynLTQueue* queue;
+    mutable vector<double> requested;
+    vector<bool> allocated;
+    vector<bool> valid;
+    vector<DynLT*> plts;
+
+    unsigned int textureMode;
+
+#ifdef USE_STATS_COLLECTOR
+    mutable vector<double> latency;
+    mutable vector<double> texgen;
+#endif
+  };
+}
+
+#endif // Manta_DynLT_DynLTGridSpheres_h

Modified: trunk/Model/Groups/private/ParticleCGT.cc
==============================================================================
--- trunk/Model/Groups/private/ParticleCGT.cc   (original)
+++ trunk/Model/Groups/private/ParticleCGT.cc   Fri Jul 20 23:41:17 2007
@@ -198,7 +198,7 @@
 
   static bool first_bounds_set = false;
 
-  //TODO: parallelize, bounds can just be computed from currGroup 
+  //TODO: parallelize
 //   if (!tsparticles)
 //   {
 //       const int startSphere = 0;
@@ -347,7 +347,7 @@
           cellVector_mc[ofs].minmax[1]=set4(FLT_MAX);
           cellVector_mc[ofs].minmax[2]=set4(-FLT_MAX);
           cellVector_mc[ofs].minmax[3]=set4(FLT_MAX);
-#endif // MCRANGE_CULLING-np 5 -scene "lib/libscene_pcgt.so (-i 
/usr/csafe/raid1/cgribble/particle/data/thunder/spheredata080-crop.nrrd)"
+#endif // MCRANGE_CULLING
 
         }
       }
@@ -1119,7 +1119,52 @@
                    // incrementCounter(isect_before);
                    //cout << "hitTest\n";
                    
currGroup->get(cell_particles[i].index)->intersect(context, ray);
-                   anyHit = true;
+
+#ifdef COLOR_MAPPING
+                   // Extract and normalize the data value to use for color 
mapping
+                   sse_union value;
+                   sse_t rmin4;
+                   sse_t inv_range;
+                   if (cidx<4) {
+                     value.sse = set4(((float*)&(idat))[cidx]);
+                     rmin4 = 
set4(((float*)&(tsparticles->bounds.min))[cidx]);
+                     
inv_range=set4(((float*)&(tsparticles->inv_prange))[cidx]);
+                   } else {
+                     value.sse = set4(((float*)&(ivar))[cidx-4]);
+                     rmin4 = 
set4(((float*)&(tsparticles->vars_min))[cidx-4]);
+                     
inv_range=set4(((float*)&(tsparticles->inv_vrange))[cidx-4]);
+                   }
+
+                   const sse_t diff = sub4(value.sse, rmin4);
+                   const sse_t norm_value = mul4(diff, inv_range);
+#endif // COLOR_MAPPING
+                   for( int j = ray.begin(); j < ray.end(); j++)
+                     {
+                       if (ray.wasHit(j))
+                         {
+                           float v = 0.0f;
+                           if (cidx < 3) // use position information for 
colormap
+                             {
+                               //TODO: use sphere postion instead of hit 
postioin?
+                               // THis explodes for some reason:
+                               //ray.computeHitPositions();
+                               //v = ray.data->hitPosition[0][j];
+                               //cout << "v: " << v << endl;
+                               v = ray.getMinT(j)*ray.getDirection(j, cidx) 
+ ray.getOrigin(j, cidx);
+                             }
+                           else // use data values 
+                             {
+                               //TODO: set v here
+                             }
+                             
+                           Real& val = ray.scratchpad<Real>(j);
+                           val = v;
+                         }
+                       anyHit = true;
+                     }
+
+
+                   //   anyHit = true; // TODO: actually set this based on 
hit?
 //                       anyHit += 
intersectSphere<SHADOWS_ONLY,COMMON_ORIGIN,true>(idat,
 // #ifdef COLOR_MAPPING
 //                                                                           
       ivar,

Modified: trunk/Model/Groups/private/ParticleCGT.h
==============================================================================
--- trunk/Model/Groups/private/ParticleCGT.h    (original)
+++ trunk/Model/Groups/private/ParticleCGT.h    Fri Jul 20 23:41:17 2007
@@ -24,6 +24,7 @@
 using namespace std;
 
 #define MAX_PARTICLES 5000000 
+#define COLOR_MAPPING
 
 #define MACRO_CELLS 6
 
@@ -123,13 +124,11 @@
     sse_t dmin, dmax;
     sse_t vmin, vmax;
     
-#ifdef COLOR_MAPPING
     int cidx;
     void setCidx(int new_cidx)
       {
        cidx = new_cidx;
       }
-#endif //COLOR_MAPPING
     mutable float max_radius;
 
     void extendBoundsBySphere(int i,Box4 &bounds) const
@@ -249,13 +248,6 @@
     max[6]=vf[2];
     max[7]=vf[3];
   }
-
- template<bool SHADOWS_ONLY, bool COMMON_ORIGIN, bool SQUARE_PACKETS>
-  inline bool intersectSphere(const sse_t& sphere,
-#ifdef COLOR_MAPPING
-                              const sse_t& data,
-#endif // COLOR_MAPPING
-                              RayPacket &ray) const;
     
 
     struct CellData {
@@ -377,12 +369,12 @@
       return cell;
     }
 
-    ParticleGrid() :
+    ParticleGrid(int cidxn = 0) :
       firstTime(true), mutex("generic build mutex"),
       barrier("CGT build barrier"),
       buildQueue_resize_mutex("build queue resize mutex"),
       buildQueue_was_resized(false),
-      currGroup(NULL)
+      currGroup(NULL), cidx(cidxn)
     {
 #ifdef MACRO_CELLS
       oldN_mc[0] = oldN_mc[1] = oldN_mc[2] = -1;

Modified: trunk/Model/Textures/ColorMap.cc
==============================================================================
--- trunk/Model/Textures/ColorMap.cc    (original)
+++ trunk/Model/Textures/ColorMap.cc    Fri Jul 20 23:41:17 2007
@@ -29,17 +29,27 @@
 
 #include <Model/Textures/ColorMap.h>
 #include <Interface/RayPacket.h>
+#include <assert.h>
 
+using namespace std;
 using namespace Manta;
 
 void ColorMap::mapValues(Packet<Color>& results,
                          const RenderContext& context,
                          RayPacket& rays) const
 {
+  if (baseMaterial)
+    baseMaterial->shade(context, rays);
   for (int i = rays.begin(); i < rays.end(); ++i) {
     const Real value = rays.scratchpad<Real>(i);
     const Real normalized = (value - min)*inv_range;
+    //if (!(normalized >= 0.0 && normalized <= 1.0))
+    //  cout << normalized << endl;
+    //assert(normalized >= 0.0 && normalized <= 1.0);
     const int idx = SCIRun::Clamp(static_cast<int>(ncolors*normalized), 0, 
ncolors);
-    results.set(i, cmap.blended[idx]);
+    if (baseMaterial)
+      results.set(i, rays.getColor(i)*cmap.blended[idx]);
+    else
+      results.set(i, cmap.blended[idx]);
   }
 }

Modified: trunk/Model/Textures/ColorMap.h
==============================================================================
--- trunk/Model/Textures/ColorMap.h     (original)
+++ trunk/Model/Textures/ColorMap.h     Fri Jul 20 23:41:17 2007
@@ -34,6 +34,7 @@
 #include <Interface/RayPacket.h>
 #include <Interface/Texture.h>
 #include <Model/Textures/Constant.h>
+#include <Model/Materials/Lambertian.h>
 
 namespace Manta {
 
@@ -43,8 +44,8 @@
   class ColorMap : public Texture<Color>
   {
   public:
-    ColorMap(const RegularColorMap& cmap_, Real min_, Real max_) :
-      cmap(cmap_)
+    ColorMap(const RegularColorMap& cmap_, Real min_, Real max_, Material* 
baseMaterialn = NULL) :
+      cmap(cmap_), baseMaterial(baseMaterialn)
     {
       setRange(min_, max_);
       ncolors = cmap.blended.size() - 1;
@@ -64,6 +65,7 @@
                            RayPacket& rays) const;
 
   private:
+    Material* baseMaterial;
     RegularColorMap cmap;
     Real min, max;
     Real inv_range;

Modified: trunk/scenes/particleCGTTest.cc
==============================================================================
--- trunk/scenes/particleCGTTest.cc     (original)
+++ trunk/scenes/particleCGTTest.cc     Fri Jul 20 23:41:17 2007
@@ -53,6 +53,8 @@
 #include <Model/Instances/InstanceRST.h>
 #include <Model/Instances/Instance.h>
 #include <Model/Cameras/PinholeCamera.h>
+#include <Model/Textures/ColorMap.h>
+#include <Model/Materials/CopyTextureMaterial.h>
 
 #include <Model/Groups/private/ParticleCGT.h>
 #include <Model/Readers/ParticleNRRD.h>
@@ -77,19 +79,34 @@
                                             Vector(0,1,0)));
 
        Material* lam = new Lambertian(Color(RGB(1,0,0)));
+       RegularColorMap* cmap = new 
RegularColorMap(RegularColorMap::parseType("InvRainbowIso"));
+       float radius = 0.001f;
+       
         Primitive* prim = new Cube(lam, Vector(-0.4, -0.3, 0.2), 
Vector(0.41, 0.3, 1.0));
        ParticleNRRD reader;
-               reader.readFile("/home/collab/brownlee/2300.nrrd");
+       reader.readFile("/home/collab/brownlee/2300.nrrd");
+        int nParticles = reader.getNParticles();
        cout << "NVars: " << reader.getNVars() << endl;
        int nvars = reader.getNVars();
+       Real min = FLT_MAX;
+       Real max = -FLT_MAX;
        cout << "num particles: " << reader.getNParticles() << endl;
-       for(int i = 0; i < reader.getNParticles(); i++)
+       for(int i = 0; i < nParticles; i++)
+       {
+         float* data = reader.getParticleData() + i*nvars;
+         min = std::min(min, data[0]);
+         max = std::max(max, data[0]);
+       }
+       min -= radius;
+       max += radius;
+ColorMap* colormap = new ColorMap(*cmap, min, max);
+       Material* colorMapMat = new CopyTextureMaterial(colormap);
+for(int i = 0; i < nParticles; i++)
        {
            float* data = reader.getParticleData() + i*nvars;
            Vector pos(data[0], data[1], data[2]);
-           pGroup->add(new Sphere(lam, pos, 0.001f));
+           pGroup->add(new Sphere(colorMapMat, pos, radius));
        }
-
        //world->add(prim);
        
        ParticleGrid* grid = new ParticleGrid();

Modified: trunk/scenes/pcgt.cc
==============================================================================
--- trunk/scenes/pcgt.cc        (original)
+++ trunk/scenes/pcgt.cc        Fri Jul 20 23:41:17 2007
@@ -92,6 +92,11 @@
     vmin = std::min(vmin, data[cidx]);
     vmax = std::max(vmax, data[cidx]);
   }
+  if (cidx < 3)
+    {
+    vmin -= radius;
+    vmax += radius;
+    }
 
   Material* material = new Lambertian(new ColorMap(cmap, vmin, vmax));
 
@@ -106,7 +111,7 @@
     particles->add(new Sphere(material, position, radius));
   }
 
-  ParticleGrid* grid = new ParticleGrid;
+  ParticleGrid* grid = new ParticleGrid(cidx);
   grid->rebuild(particles);
   scene->setObject(grid);
 




  • [MANTA] r1525 - in trunk: DynLT Model/Groups/private Model/Textures scenes, brownlee, 07/21/2007

Archive powered by MHonArc 2.6.16.

Top of page