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