Text archives Help
- From: cgribble@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r1075 - in trunk: Engine/Control Interface Model/Materials Model/Textures scenes
- Date: Thu, 18 May 2006 21:24:43 -0600 (MDT)
Author: cgribble
Date: Thu May 18 21:24:38 2006
New Revision: 1075
Removed:
trunk/Model/Textures/DynPLT.cc
trunk/Model/Textures/DynPLT.h
Modified:
trunk/Engine/Control/DynPLTWorker.cc
trunk/Engine/Control/DynPLTWorker.h
trunk/Interface/LightSet.cc
trunk/Interface/LightSet.h
trunk/Interface/RayPacket.h
trunk/Model/Materials/DynPLTMaterial.cc
trunk/Model/Materials/DynPLTMaterial.h
trunk/Model/Textures/CMakeLists.txt
trunk/scenes/dynplt.cc
Log:
Interface/LightSet.cc
Interface/LightSet.h
Made toString const (doesn't modify any members of the class)
Interface/RayPacket.h
Added accessor for grabbing 2D texture coordinates one at a time
Model/Materials/DynPLTMaterial.h
Model/Materials/DynPLTMaterial.cc
scenes/dynplt.cc
Corrected crappy design: currently one instance of DynPLTMaterial per
particle, no need for special DynPLT texture or DynPLTParticle primitive
Added statically allocated space for luminance texture, inside texture (for
dilation)
Moved textures flags from (now removed) DynPLTParticle primitive into the
material
Updated shading logic to reflect one instance of the material per particle
Added interpolation code (Steve's cleverness doesn't work; haven't figured
out
why, yet, because I haven't taken the time to figure out what it's
supposed
to be doing...)
Model/Textures/DynPLT.cc
Model/Textures/DynPLT.h
Model/Textures/CMakeLists.txt
Removed unnecessary DynPLT texture code
Engine/Control/DynPLTWorker.cc
Engine/Control/DynPLTWorker.h
Reflect changes to design
Direct lighting computation sort of works --> textures are too dark (IMHO)
Indirect lighting is broken (results in solid black, or nearly so, textures)
There's undoubtedly a much better way to handle direct/indirect lighting
NOTES: Still crashing on exit (occasionally), or not exiting at all without a
Fast Quit
Modified: trunk/Engine/Control/DynPLTWorker.cc
==============================================================================
--- trunk/Engine/Control/DynPLTWorker.cc (original)
+++ trunk/Engine/Control/DynPLTWorker.cc Thu May 18 21:24:38 2006
@@ -3,7 +3,10 @@
#include <Interface/Scene.h>
#include <Engine/Control/DynPLTWorker.h>
#include <Engine/Shadows/HardShadows.h>
+#include <Model/Materials/DynPLTMaterial.h>
+#include <Model/Primitives/Sphere.h>
#include <SCIRun/Core/Math/MiscMath.h>
+#include <SCIRun/Core/Thread/Semaphore.h>
#include <string>
@@ -11,10 +14,9 @@
using namespace std;
DynPLTContext::DynPLTContext(SCIRun::Mailbox<const Sphere*>* queue,
- Scene* scene, unsigned int res,
- unsigned int ngroups, unsigned int nsamples,
- unsigned int max_depth) :
- queue(queue), scene(scene), res(res), ngroups(ngroups), nsamples(nsamples),
+ Scene* scene, unsigned int ngroups,
+ unsigned int nsamples, unsigned int max_depth) :
+ queue(queue), scene(scene), ngroups(ngroups), nsamples(nsamples),
max_depth(max_depth)
{
// Ensure that the number of samples is a perfect square
@@ -25,7 +27,7 @@
}
DynPLTWorker::DynPLTWorker(const DynPLTContext* context, unsigned int id) :
- context(context), id(id)
+ context(context), id(id), exitSem(0)
{
// Seed the random number generator
rng.seed_rng(100 + id);
@@ -72,14 +74,20 @@
delete [] hidx;
}
-// #define TEMPORARY 1
-#if TEMPORARY
+// #define DEBUG 1
+#if DEBUG
#include <iostream>
-#include <unistd.h>
+using std::cerr;
#endif
void DynPLTWorker::run(void)
{
+ // Grab useful information from the DynPLT context
+ unsigned int ngroups=context->ngroups;
+ unsigned int nsamples=context->nsamples;
+ unsigned int max_depth=context->max_depth;
+ Real inv_nsamples=1/static_cast<Real>(nsamples);
+
// Create a render context for direct lighting computations
Scene* scene=context->scene;
vector<string> args;
@@ -91,43 +99,30 @@
const Sphere* particle;
while (particle=context->queue->receive()) {
-#if TEMPORARY
- cerr<<"DynPLTWorker["<<id<<"]::run - "<<context->queue->numItems()
- <<" left in queue\n";
-#endif
+ if (exitSem) {
+ exitSem->up();
+ return;
+ }
- const DynPLTMaterial* dynplt=particle->getMaterial();
- if (dynplt->valid)
+ DynPLTMaterial*
dynplt=dynamic_cast<DynPLTMaterial*>(particle->getMaterial());
+ if (!dynplt || dynplt->valid)
continue;
-#if 0
- unsigned int time=static_cast<unsigned int>(3*rng.gendrand());
- cerr<<"DynPLTWorker["<<id<<"]::run - sleeping for "<<time<<" seconds\n";
- sleep(time);
-#endif
-
- // Grab useful information from the DynPLT context
- unsigned int res=context->res;
- unsigned int ngroups=context->ngroups;
- unsigned int nsamples=context->nsamples;
- unsigned int max_depth=context->max_depth;
- Real inv_res=1/static_cast<Real>(res);
- Real inv_nsamples=1/static_cast<Real>(nsamples);
-
// Generate particle's texture
Vector center=particle->getCenter();
Real radius=particle->getRadius();
-#if TEMPORARY
- cerr<<"DynPLTWorker["<<id<<"]::run - particle(<"<<center<<">, "<<radius
- <<")\n";
-#endif
- for (unsigned int v=0; v<res; ++v) {
- for (unsigned int u=0; u<res; ++u) {
+ unsigned int xres=dynplt->getXRes();
+ unsigned int yres=dynplt->getYRes();
+ Real inv_xres=1/static_cast<Real>(xres);
+ Real inv_yres=1/static_cast<Real>(yres);
+
+ for (unsigned int v=0; v<yres; ++v) {
+ for (unsigned int u=0; u<xres; ++u) {
// Pick a random sample group for surface points
unsigned int sidx=static_cast<unsigned int>(ngroups*rng.gendrand());
- // Pick random sample groups for points on the hemisphere at each
depth
+ // Pick random sample group for points on the hemisphere at each
depth
for (int d=0; d<=max_depth; ++d)
hidx[d]=static_cast<unsigned int>(ngroups*rng.gendrand());
@@ -152,26 +147,27 @@
// Fill in the hit positions and surface normals at sample points
for (int i=rays.begin(); i<rays.end(); ++i) {
// Project surface sample point onto particle's surface
- Vector2D sample=sample_groups[sidx][i];
+ Vector2D sample=sample_groups[sidx][s + i];
- // Range of 2*M_PI*(u + sample.x)/res --> [0, 2*Pi]
- // Range of M_PI*(v + sample.y)/res --> [0, Pi]
- Real phi=2*M_PI*((u + sample.x()))*inv_res;
- Real theta=M_PI*((v + sample.y()))*inv_res;
+ // Range of 2*M_PI*(u + sample.x)/xres --> [0, 2*Pi]
+ // Range of M_PI*(v + sample.y)/yres --> [0, Pi]
+ Real phi=2*M_PI*((u + sample.x()))*inv_xres;
+ Real theta=M_PI*((v + sample.y()))*inv_yres;
Real x=cos(phi)*sin(theta);
- Real z=sin(phi)*sin(theta);
- Real y=cos(theta);
+ Real y=sin(phi)*sin(theta);
+ Real z=cos(theta);
Vector surface=center + radius*Vector(x, y, z);
- Vector normal=Vector(x, y, z).normal();
+ Vector normal=(surface - center).normal();
+ // Vector normal=Vector(x, y, z).normal();
rays.setHitPosition(i, surface);
rays.setNormal(i, normal);
}
// Iteratively trace the ray packet
- GrayValue result;
+ Real result=0;
for (unsigned int d=0; d<max_depth; ++d) {
// Compute direct lighting at current hit positions
ShadowAlgorithm::StateBuffer stateBuffer;
@@ -204,15 +200,16 @@
Vector shadowdir=shadowRays.getDirection(i);
ColorComponent cos_theta=Dot(shadowdir, normal);
Color light=shadowRays.getColor(i);
- // result += light.luminance()*cos_theta;
+ result += light.luminance()*cos_theta;
}
}
firstTime=false;
} while(!done);
- // Fill in the ray origins (computed above) and directions (by
- // generating random directions on the hemisphere)
+#if 0
+ // XXX: indirect is broken... results in solid black textures
+ // Fill in the ray origins and directions
for (int i=rays.begin(); i<rays.end(); ++i) {
Vector normal=rays.getNormal(i);
Vector v0(Cross(normal, Vector(1,0,0)));
@@ -260,7 +257,7 @@
sub.computeHitPositions();
sub.computeNormals(rctx);
- // Store hit positions, normals for only valid hits
+ // Store hit positions, normals for valid hits
for (unsigned int j=sub.begin(); j<sub.end(); ++j) {
Real dotprod=Dot(sub.getNormal(j), -sub.getDirection(j));
if (dotprod>0) {
@@ -279,7 +276,7 @@
//
// Either way, ignore the hit and mark the texel for
// dilation
- // inside(u, v) += 1;
+ dynplt->inside[u][v] += 1;
}
}
@@ -294,8 +291,7 @@
// Accumulate background color
for (unsigned int j=i; j<end; ++j)
- // result += rays.getColor(j).luminance();
- ;
+ result += rays.getColor(j).luminance();
i=end;
}
@@ -310,14 +306,15 @@
rays.resize(validRays);
rays.setAllFlags(0);
rays.setFlag(dlFlags);
+#endif
}
- // Store the result
- // dynplt(u, v) += result;
+ // Store the normalized result
+ dynplt->texture[u][v] += result;
}
// Normalize the texel
- // dynplt(u, v) *= inv_nsamples;
+ dynplt->texture[u][v] *= inv_nsamples;
}
}
@@ -325,6 +322,13 @@
dynplt->dilate(context);
dynplt->valid=true;
- dynplt->plt=texture;
}
+}
+
+void DynPLTWorker::terminate(MantaInterface*)
+{
+ SCIRun::Semaphore semaphore("DynPLTWorker Exit Semaphore", 0);
+ exitSem=&semaphore;
+ context->queue->send(0);
+ semaphore.down();
}
Modified: trunk/Engine/Control/DynPLTWorker.h
==============================================================================
--- trunk/Engine/Control/DynPLTWorker.h (original)
+++ trunk/Engine/Control/DynPLTWorker.h Thu May 18 21:24:38 2006
@@ -11,26 +11,27 @@
namespace Manta
{
- class DynPLTParticle;
+ class MantaInterface;
class RayPacket;
class Scene;
+ class Sphere;
+ class Semaphore;
class DynPLTContext
{
public:
- DynPLTContext(SCIRun::Mailbox<const DynPLTParticle*>* queue, Scene*
scene,
- unsigned int res, unsigned int ngroups, unsigned int
nsamples,
+ DynPLTContext(SCIRun::Mailbox<const Sphere*>* queue, Scene* scene,
+ unsigned int ngroups, unsigned int nsamples,
unsigned int max_depth);
~DynPLTContext(void) { }
// DynPLT work queue
- SCIRun::Mailbox<const DynPLTParticle*>* queue;
+ SCIRun::Mailbox<const Sphere*>* queue;
// Manta scene
Scene* scene;
// Texture generation parameters
- unsigned int res;
unsigned int ngroups;
unsigned int nsamples;
unsigned int nsamples_root;
@@ -51,12 +52,15 @@
virtual void run(void);
+ void terminate(MantaInterface*);
+
private:
const DynPLTContext* context;
unsigned int id;
MT_RNG rng;
SCIRun::Array1<SCIRun::Array1<Vector2D> > sample_groups;
int* hidx;
+ SCIRun::Semaphore* exitSem;
};
}
Modified: trunk/Interface/LightSet.cc
==============================================================================
--- trunk/Interface/LightSet.cc (original)
+++ trunk/Interface/LightSet.cc Thu May 18 21:24:38 2006
@@ -39,7 +39,7 @@
}
}
-string LightSet::toString() {
+string LightSet::toString() const {
ostringstream out;
out << "ambientLight = "<<ambientLight<<"\n";
if (ambientLight)
Modified: trunk/Interface/LightSet.h
==============================================================================
--- trunk/Interface/LightSet.h (original)
+++ trunk/Interface/LightSet.h Thu May 18 21:24:38 2006
@@ -41,7 +41,7 @@
// Calls preprocess on each light.
void preprocess(const PreprocessContext&);
- string toString();
+ string toString() const;
private:
LightSet(const LightSet&);
Modified: trunk/Interface/RayPacket.h
==============================================================================
--- trunk/Interface/RayPacket.h (original)
+++ trunk/Interface/RayPacket.h Thu May 18 21:24:38 2006
@@ -476,6 +476,11 @@
return VectorT<Real, 2>(data->texCoords[0][which],
data->texCoords[1][which]);
}
+ Real getTexCoords2(int which, int dim)
+ {
+ return data->texCoords[dim][which];
+ }
+
// These aren't right - the texture object may not be consecutive
void computeTextureCoordinates2(const RenderContext& context)
{
Modified: trunk/Model/Materials/DynPLTMaterial.cc
==============================================================================
--- trunk/Model/Materials/DynPLTMaterial.cc (original)
+++ trunk/Model/Materials/DynPLTMaterial.cc Thu May 18 21:24:38 2006
@@ -1,6 +1,7 @@
#include <Core/Exceptions/InternalError.h>
#include <Model/Materials/DynPLTMaterial.h>
+#include <Model/Primitives/Sphere.h>
#include <Model/Textures/Constant.h>
#include <Interface/Light.h>
#include <Interface/LightSet.h>
@@ -34,26 +35,92 @@
void DynPLTMaterial::shade(const RenderContext& context, RayPacket& rays)
const
{
if (valid) {
-#if 0
- // Compute diffuse colors
- Packet<Color> diffuse;
- colortex->mapValues(diffuse, context, rays);
-
- // Compute textured luminance
- Packet<GrayValue> luminance;
- plt->mapValues(luminance, context, rays);
-
- for (int i=rays.begin(); i<rays.end(); ++i) {
- rays.setColor(i, luminance[i]*diffuse[i]);
+ // Compute diffuse colors
+ Packet<Color> diffuse;
+ colortex->mapValues(diffuse, context, rays);
+
+ // Compute textured luminance
+ rays.computeTextureCoordinates2(context);
+
+ for (unsigned int i=rays.begin(); i < rays.end(); ++i) {
+#if 1
+ Real x=rays.getTexCoords2(i, 0)*XRES;
+ int x_low=static_cast<int>(x);
+ Real x_weight = x - x_low;
+ // If low is negative then we need to look right (negative) for the
high
+ // interpolant
+ int x_high;
+ if (x_low >= 0) {
+ x_high = x_low + 1;
+ } else {
+ x_high = x_low - 1;
+ // Here we get our negative index from [0..-size - 1]. Add size
back in
+ // and you get the right shift. You need to make sure you do the
%size
+ // afterwards, though. This will catch the case where
+ // low%size + size == size.
+ x_low = x_low%XRES + XRES;
+ x_high = x_high%XRES + XRES;
+
+ // If low was negative then weight will also be negative. We don't
+ // need a negative number for interpolation.
+ x_weight = -x_weight;
+ }
+
+ x_low %= XRES;
+ x_high %= XRES;
+
+ Real y=rays.getTexCoords2(i, 1)*YRES;
+ int y_low=static_cast<int>(y);
+ Real y_weight = y - y_low;
+ // If low is negative then we need to look right (negative) for the
high
+ // interpolant
+ int y_high;
+ if (y_low >= 0) {
+ y_high = y_low + 1;
+ } else {
+ y_high = y_low - 1;
+ // Here we get our negative index from [0..-size - 1]. Add size
back in
+ // and you get the right shift. You need to make sure you do the
%size
+ // afterwards, though. This will catch the case where
+ // low%size + size == size.
+ y_low = y_low%YRES + YRES;
+ y_high = y_high%YRES + YRES;
+
+ // If low was negative then weight will also be negative. We don't
+ // need a negative number for interpolation.
+ y_weight = -y_weight;
+ }
+
+ y_low %= YRES;
+ y_high %= YRES;
#else
- for (int i=rays.begin(); i<rays.end(); ++i) {
- rays.setColor(i, Color(RGB(1, 0, 0)));
+ // XXX: This is broken (i.e., doesn't interpolate correctly). Why?
+ Real x=rays.getTexCoords2(i, 0)*XRES;
+ int x_low=static_cast<int>(x) & (XRES - 1);
+ int x_high=x_low & (XRES-1);
+ Real x_weight=x - x_low;
+
+ Real y=rays.getTexCoords2(i, 1)*YRES;
+ int y_low=static_cast<int>(y) & (YRES - 1);
+ int y_high=y_low & (YRES - 1);
+ Real y_weight=y - y_low;
+ // end XXX
#endif
+
+ // Do the interpolation
+ Real a=(texture[x_low][y_low] * (1 - x_weight) +
+ texture[x_high][y_low] * x_weight);
+ Real b=(texture[x_low][y_high] * (1 - x_weight) +
+ texture[x_high][y_high] * x_weight);
+ Real luminance=a*(1 - y_weight) + b*y_weight;
+
+ rays.setColor(i, diffuse.get(i)*luminance);
}
} else {
// Request texture generation, if necessary
if (!requested) {
- if (queue->trySend(rays.getHitPrimitive(rays.begin())))
+ const Sphere* particle=dynamic_cast<const
Sphere*>(rays.getHitPrimitive(rays.begin()));
+ if (queue->trySend(particle))
requested=true;
}
@@ -121,7 +188,12 @@
for (int i=rays.begin(); i < rays.end(); ++i) {
Color result;
for (int j=0;j<Color::NumComponents; ++j)
- result[j]=totalLight[j][i] * diffuse.colordata[j][i];
+ result[j]=totalLight[j][i]*diffuse.colordata[j][i];
rays.setColor(i, result);
}
+}
+
+void DynPLTMaterial::dilate(const DynPLTContext* context)
+{
+ // Do nothing
}
Modified: trunk/Model/Materials/DynPLTMaterial.h
==============================================================================
--- trunk/Model/Materials/DynPLTMaterial.h (original)
+++ trunk/Model/Materials/DynPLTMaterial.h Thu May 18 21:24:38 2006
@@ -7,8 +7,12 @@
#include <Model/Materials/LitMaterial.h>
#include <SCIRun/Core/Thread/Mailbox.h>
+#define XRES 16
+#define YRES 16
+
namespace Manta
{
+ class DynPLTContext;
class Sphere;
class DynPLTMaterial : public LitMaterial
@@ -22,11 +26,19 @@
virtual void shade(const RenderContext& context, RayPacket& rays) const;
+
+ unsigned int getXRes(void) const { return XRES; }
+ unsigned int getYRes(void) const { return YRES; }
+
void dilate(const DynPLTContext* context);
-
+
+ // Luminance texture data
+ Real texture[XRES][YRES];
+ Real inside[XRES][YRES];
+
+ // Texture flags
+ bool valid;
mutable bool requested;
- mutable bool valid;
- mutable DynPLT* plt; // XXX: this should become a StaticArray2 or some
such...
private:
SCIRun::Mailbox<const Sphere*>* queue;
Modified: trunk/Model/Textures/CMakeLists.txt
==============================================================================
--- trunk/Model/Textures/CMakeLists.txt (original)
+++ trunk/Model/Textures/CMakeLists.txt Thu May 18 21:24:38 2006
@@ -20,12 +20,3 @@
Textures/WoodTexture.cc
Textures/WoodTexture.h
)
-
-
-IF(BUILD_DYNPLT)
- SET(Manta_Textures_SRCS
- ${Manta_Textures_SRCS}
- Textures/DynPLT.h
- Textures/DynPLT.cc
- )
-ENDIF(BUILD_DYNPLT)
Modified: trunk/scenes/dynplt.cc
==============================================================================
--- trunk/scenes/dynplt.cc (original)
+++ trunk/scenes/dynplt.cc Thu May 18 21:24:38 2006
@@ -11,6 +11,7 @@
#include <Model/Groups/Group.h>
#include <Model/Lights/PointLight.h>
#include <Model/Materials/DynPLTMaterial.h>
+#include <Model/Primitives/Sphere.h>
#include <Model/Readers/ParticleNRRD.h>
#include <SCIRun/Core/Thread/Mailbox.h>
#include <SCIRun/Core/Thread/Thread.h>
@@ -30,6 +31,7 @@
{
Group* world=0;
string fname="";
+ int max_depth=3;
int nthreads=1;
double radius=1.;
int ridx=-1;
@@ -42,6 +44,9 @@
if (!getStringArg(i, args, s))
throw IllegalArgument("scene dynplt -bv", i, args);
world=context.manta_interface->makeGroup(s);
+ } else if (arg=="-depth") {
+ if (!getIntArg(i, args, max_depth))
+ throw IllegalArgument("scene dynplt -depth", i, args);
} else if (arg=="-i") {
if (!getStringArg(i, args, fname))
throw IllegalArgument("scene dynplt -i", i, args);
@@ -57,6 +62,7 @@
} else {
cerr<<"Valid options for scene dynplt:\n";
cerr<<" -bv <string> bounding volume {bvh|grid|group}\n";
+ cerr<<" -depth <int> path trace depth\n";
cerr<<" -i <string> particle data filename\n";
cerr<<" -nthreads <int> number of dynplt workers\n";
cerr<<" -radius <float> particle radius\n";
@@ -76,23 +82,23 @@
Mailbox<const Sphere*>* queue=new Mailbox<const Sphere*>("DynPLT Work
Queue", size);
// Create DynPLTContext
- unsigned int res=16; // XXX: this should be a cmdln parameter
unsigned int ngroups=100; // XXX: this should be a cmdln parameter
unsigned int nsamples=49; // XXX: this should be a cmdln parameter
- unsigned int max_depth=3; // XXX: this should be a cmdln parameter
- DynPLTContext* dpltctx=new DynPLTContext(queue, scene, res, ngroups,
nsamples,
+ DynPLTContext* dpltctx=new DynPLTContext(queue, scene, ngroups, nsamples,
max_depth);
// Create DynPLTWorker threads
- // workers.resize(nthreads);
for (unsigned int i=0; i<nthreads; ++i) {
ostringstream name;
name<<"DynPLT Worker "<<i;
- Thread* thread=new Thread(new DynPLTWorker(dpltctx, i),
- name.str().c_str(), 0, Thread::NotActivated);
+ DynPLTWorker* worker=new DynPLTWorker(dpltctx, i);
+ Thread* thread=new Thread(worker, name.str().c_str(), 0,
+ Thread::NotActivated);
thread->setStackSize(RENDER_THREAD_STACKSIZE);
thread->activate(false);
- // workers[i]=thread;
+
+ // Register termination callback
+
context.manta_interface->registerTerminationCallback(Callback::create(worker,
&DynPLTWorker::terminate));
}
// Load particle data, add particles to group
@@ -107,12 +113,12 @@
if (ridx>=0)
radius=pdata[idx + ridx];
- Material* dynplt=new DynPLTMaterial(queue, Color(RGB(1, 1, 1)));
+ Material* dynplt=new DynPLTMaterial(queue, Color(RGB(1, 0, 0)));
world->add(new Sphere(dynplt, Vector(x, y, z), radius));
}
// Initialize the scene
- scene->setBackground(new ConstantBackground(Color(RGB(0, 0, 0))));
+ scene->setBackground(new ConstantBackground(Color(RGB(1, 1, 1))));
scene->setObject(world);
// Add lights
- [MANTA] r1075 - in trunk: Engine/Control Interface Model/Materials Model/Textures scenes, cgribble, 05/18/2006
Archive powered by MHonArc 2.6.16.