Text archives Help
- From: boulos@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [Manta] r1668 - in trunk: Core/Util Engine/Control Engine/Renderers Interface Maya Model/Cameras Model/Groups Model/Groups/private Model/Instances Model/Materials Model/MiscObjects Model/Primitives scenes
- Date: Mon, 20 Aug 2007 17:26:43 -0600 (MDT)
Author: boulos
Date: Mon Aug 20 17:26:40 2007
New Revision: 1668
Modified:
trunk/Core/Util/Preprocessor.h
trunk/Engine/Control/RTRT.cc
trunk/Engine/Control/RTRT.h
trunk/Engine/Renderers/NullRenderer.cc
trunk/Interface/AccelerationStructure.h
trunk/Interface/CMakeLists.txt
trunk/Interface/Context.h
trunk/Interface/RayPacket.cc
trunk/Interface/RayPacket.h
trunk/Maya/MayaScene.cc
trunk/Model/Cameras/EnvironmentCamera.cc
trunk/Model/Cameras/FisheyeCamera.cc
trunk/Model/Cameras/OrthogonalCamera.cc
trunk/Model/Cameras/PinholeCamera.cc
trunk/Model/Groups/BVH.cc
trunk/Model/Groups/DynBVH.cc
trunk/Model/Groups/DynBVH.h
trunk/Model/Groups/GriddedGroup.cc
trunk/Model/Groups/Group.cc
trunk/Model/Groups/Mesh.cc
trunk/Model/Groups/RealisticBvh.cc
trunk/Model/Groups/private/CGT.cc
trunk/Model/Groups/private/CGT.h
trunk/Model/Instances/Instance.cc
trunk/Model/Materials/LitMaterial.cc
trunk/Model/MiscObjects/CuttingPlane.cc
trunk/Model/MiscObjects/KeyFrameAnimation.cc
trunk/Model/Primitives/GridSpheres.cc
trunk/Model/Primitives/ParticleBVH.cc
trunk/Model/Primitives/WaldTriangle.cc
trunk/scenes/primtest.cc
Log:
Core/Util/Preprocessor.h
Adding a MANTA_FUNC to help
Engine/Control/RTRT.cc
Engine/Control/RTRT.h
Engine/Renderers/NullRenderer.cc
Interface/AccelerationStructure.h
Interface/CMakeLists.txt
Interface/Context.h
Interface/RayPacket.cc
Interface/RayPacket.h
Model/Cameras/EnvironmentCamera.cc
Model/Cameras/FisheyeCamera.cc
Model/Cameras/OrthogonalCamera.cc
Model/Cameras/PinholeCamera.cc
Model/Groups/BVH.cc
Model/Groups/DynBVH.cc
Model/Groups/DynBVH.h
Model/Groups/GriddedGroup.cc
Model/Groups/Group.cc
Model/Groups/Mesh.cc
Model/Groups/RealisticBvh.cc
Model/Groups/private/CGT.cc
Model/Groups/private/CGT.h
Model/Instances/Instance.cc
Model/Materials/LitMaterial.cc
Model/MiscObjects/CuttingPlane.cc
Model/MiscObjects/KeyFrameAnimation.cc
Model/Primitives/GridSpheres.cc
Model/Primitives/ParticleBVH.cc
Model/Primitives/WaldTriangle.cc
Updating the preprocess context to eventually support parallelism.
We're going to need to make sure it's easy to use correctly.
AccelerationStructures also now have a setGroup instead of telling
rebuild to use a new group.
scenes/primtest.cc
Removing the manual WaldTriangle::update call as this should be taken
care of during a preprocess phase.
Modified: trunk/Core/Util/Preprocessor.h
==============================================================================
--- trunk/Core/Util/Preprocessor.h (original)
+++ trunk/Core/Util/Preprocessor.h Mon Aug 20 17:26:40 2007
@@ -1,8 +1,13 @@
#ifndef MANTA_CORE_UTIL_PREPROCESSOR_H_
#define MANTA_CORE_UTIL_PREPROCESSOR_H_
-// NOTE(boulos): ISO C99 defines _Pragma to let you do this.
+#if defined(__GNUC__)
+#define MANTA_FUNC __PRETTY_FUNCTION__
+#else
+#define MANTA_FUNC __func__
+#endif
+// NOTE(boulos): ISO C99 defines _Pragma to let you do this.
#define MANTA_PRAGMA(str) _Pragma (#str)
#if defined(__INTEL_COMPILER)
Modified: trunk/Engine/Control/RTRT.cc
==============================================================================
--- trunk/Engine/Control/RTRT.cc (original)
+++ trunk/Engine/Control/RTRT.cc Mon Aug 20 17:26:40 2007
@@ -207,7 +207,7 @@
if(whence == MantaInterface::Relative) {
frame += animFrameState.frameNumber;
- }
+ }
// #endif
oneShots.insert(OneShotMapType::value_type(frame, callback));
@@ -221,7 +221,7 @@
if(whence == MantaInterface::Relative) {
frame += animFrameState.frameNumber;
- }
+ }
parallelOneShots.insert(OneShotMapType::value_type(frame, callback));
callbackLock.writeUnlock();
@@ -381,7 +381,7 @@
NOT_FINISHED("RTRT::setTimeMode");
}
-#define MANTA_CHECK_POINTER(ptr) if (ptr == 0) throw SCIRun::InvalidState(
#ptr, __FILE__, __LINE__ );
+#define MANTA_CHECK_POINTER(ptr) if (ptr == 0) throw SCIRun::InvalidState(
#ptr, __FILE__, __LINE__ );
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@@ -398,38 +398,6 @@
running=true;
runningLock.unlock();
- // Preprocess
- MANTA_CHECK_POINTER(scene)
-
- LightSet* lights = scene->getLights();
- MANTA_CHECK_POINTER(lights)
-
-
- PreprocessContext context(this, lights);
- lights->preprocess(context);
-
- MANTA_CHECK_POINTER(scene->getBackground())
- scene->getBackground()->preprocess(context);
-
- MANTA_CHECK_POINTER(scene->getObject())
- scene->getObject()->preprocess(context);
-
- for(int index = 0;index < static_cast<int>(channels.size());index++){
- Channel* channel = channels[index];
- MANTA_CHECK_POINTER(channel)
-
- channel->camera->preprocess(context);
- MANTA_CHECK_POINTER(channel->camera)
- }
-
- // Check to see if an image creator has been specified.
- if(create_image==0)
- throw InvalidState("Image type was not selected", __FILE__, __LINE__ );
-
-#if NOTFINISHED
- check for existence of other components;
-#endif
-
if(workersWanted <= 0){
runningLock.unlock();
throw IllegalValue<int>("workersWanted should be positive",
workersWanted);
@@ -448,12 +416,12 @@
changedFlags.resize(workersWanted);
// Initialize random number generators.
- if (create_rng) {
+ if (create_rng) {
for (int i=0;i<workersWanted;++i) {
create_rng->call(rngs[i]);
- }
+ }
}
-
+
// Startup rendering threads.
for(int i=0;i<workersWanted;i++){
if(i>0 || !blockUntilFinished){
@@ -464,11 +432,11 @@
0, Thread::NotActivated);
t->setStackSize(RENDER_THREAD_STACKSIZE);
t->activate(false);
- }
+ }
}
// All rendering threads active.
-
+
// Block until finished is set while running in bin/manta
if(blockUntilFinished)
internalRenderLoop(0, false);
@@ -482,6 +450,32 @@
workers[0]->join();
}
+void RTRT::doPreprocess(int proc, int numProcs) {
+ // Preprocess
+ MANTA_CHECK_POINTER(scene)
+
+ LightSet* lights = scene->getLights();
+ MANTA_CHECK_POINTER(lights)
+
+ PreprocessContext context(this, proc, numProcs, lights);
+ lights->preprocess(context);
+
+ MANTA_CHECK_POINTER(scene->getBackground())
+ scene->getBackground()->preprocess(context);
+
+ cerr << "About to preprocess the scene (proc " << proc << ")...\n";
+ MANTA_CHECK_POINTER(scene->getObject())
+ scene->getObject()->preprocess(context);
+
+ for(int index = 0;index < static_cast<int>(channels.size());index++){
+ Channel* channel = channels[index];
+ MANTA_CHECK_POINTER(channel)
+
+ channel->camera->preprocess(context);
+ MANTA_CHECK_POINTER(channel->camera)
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// MAIN RENDERING LOOP
@@ -497,9 +491,9 @@
#endif
// Disables denormal handling and set flush to zero
- int oldMXCSR = _mm_getcsr(); //read the old MXCSR setting
- int newMXCSR = oldMXCSR | _MM_FLUSH_ZERO_ON | _MM_DENORM_ZERO_ON; // set
DAZ and FZ bits
- _mm_setcsr( newMXCSR ); //write the new MXCSR setting to the MXCSR
+ int oldMXCSR = _mm_getcsr(); //read the old MXCSR setting
+ int newMXCSR = oldMXCSR | _MM_FLUSH_ZERO_ON | _MM_DENORM_ZERO_ON; // set
DAZ and FZ bits
+ _mm_setcsr( newMXCSR ); //write the new MXCSR setting to the MXCSR
#endif
bool changed = true;
@@ -508,6 +502,22 @@
firstFrame = false;
goto skipToRendering;
}
+
+ // Check to see if an image creator has been specified.
+ if(create_image==0)
+ throw InvalidState("Image type was not selected", __FILE__, __LINE__ );
+
+#if NOTFINISHED
+ check for existence of other components;
+#endif
+
+ // TODO(boulos): Go through and ask each thread to preprocess the
+ // scene. For now, only thread 0 will do this and pretend there is
+ // only a single thread to emulate the old behavior until we can
+ // ensure everything is thread-safe throughout the tree.
+ if (proc == 0)
+ doPreprocess(proc, 1);
+
for(;;){
// P0 update frame number, time, etc.
if(proc == 0){
@@ -647,7 +657,7 @@
// Allocate thread local storage for each thread.
thread_storage->allocateStorage( proc );
-
+
for(size_t index = 0;index < channels.size();index++){
Channel* channel = channels[index];
RenderContext myContext(this, index, proc, workersAnimAndImage,
@@ -688,7 +698,7 @@
}
workers.resize(workersRendering == 0?1:workersRendering);
}
-
+
if(proc >= workersRendering) {
// If proc 0 is exiting invoke the termination callbacks.
@@ -700,7 +710,7 @@
running = false;
runningLock.unlock();
}
-
+
break;
}
}
@@ -745,7 +755,7 @@
#ifdef MANTA_SSE
// Restore floating point register flags
- _mm_setcsr( oldMXCSR ); //write the new MXCSR setting to the MXCSR
+ _mm_setcsr( oldMXCSR ); //write the new MXCSR setting to the MXCSR
#endif
}
@@ -755,7 +765,7 @@
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void RTRT::doParallelAnimationCallbacks(bool& changed, int proc, int
numProcs) {
-
+
// Parallel one shot callbacks.
ParallelOneShotMapType::iterator iter = parallelOneShots.begin();
while(iter != parallelOneShots.end() && iter->first <
animFrameState.frameNumber){
@@ -769,7 +779,7 @@
&RTRT::deleteParallelOneShot,
iter ) );
}
-
+
++iter;
}
@@ -832,7 +842,7 @@
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-// POST TRANSACTIONS
+// POST TRANSACTIONS
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void RTRT::postTransactions(bool& changed)
@@ -990,7 +1000,7 @@
if (thread_storage != 0)
delete thread_storage;
thread_storage = new ThreadStorage( numProcs );
-
+
// Setup each channel.
for(int index = 0;index < static_cast<int>(channels.size());index++){
Channel* channel = channels[index];
@@ -1068,7 +1078,7 @@
long which = frame%channel->pipelineDepth;
bool stereo;
int xres, yres;
-
+
if(channel->images[which])
channel->images[which]->getResolution(stereo, xres, yres);
if(!channel->images[which] || channel->stereo != stereo
@@ -1077,13 +1087,13 @@
// Delete the image if it already exists.
if(channel->images[which])
delete channel->images[which];
-
+
// Invoke the create image callback.
channel->create_image->call( channel->stereo,
channel->xres,
channel->yres,
channel->images[which] );
-
+
} else {
if (channel->pipelineDepth > 1)
channel->images[which]->setValid(false);
@@ -1108,7 +1118,7 @@
void RTRT::setImageDisplay( int channel, ImageDisplay *display ) {
channels[channel]->display = display;
-
+
// Setup the image display with the pipeline.
pipelineNeedsSetup = true;
}
@@ -1214,7 +1224,7 @@
currentShadowAlgorithm = shadows;
}
-ShadowAlgorithm* RTRT::getShadowAlgorithm(void) const
+ShadowAlgorithm* RTRT::getShadowAlgorithm(void) const
{
return currentShadowAlgorithm;
}
Modified: trunk/Engine/Control/RTRT.h
==============================================================================
--- trunk/Engine/Control/RTRT.h (original)
+++ trunk/Engine/Control/RTRT.h Mon Aug 20 17:26:40 2007
@@ -67,19 +67,19 @@
// Pipeline Components.
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-
+
// Image Modes (opengl, file, mpeg, etc.)
virtual int createChannel(ImageDisplay *image_display, Camera* camera,
bool stereo, int xres, int yres);
virtual ImageDisplay *getImageDisplay( int channel );
virtual void setImageDisplay( int channel, ImageDisplay *display );
-
+
virtual Camera* getCamera(int channel) const;
- virtual void setCamera(int channel, Camera *camera );
+ virtual void setCamera(int channel, Camera *camera );
virtual void getResolution(int channel, bool& stereo, int& xres, int&
yres);
virtual void changeResolution(int channel, int xres, int yres, bool
changePipeline);
-
+
// Image Traversers
virtual void setImageTraverser( ImageTraverser *image_traverser_ );
virtual ImageTraverser *getImageTraverser() const;
@@ -97,9 +97,9 @@
virtual LoadBalancer *getLoadBalancer() const;
// PixelSamplers
- virtual void setPixelSampler( PixelSampler *sampler_ );
+ virtual void setPixelSampler( PixelSampler *sampler_ );
virtual PixelSampler *getPixelSampler() const;
-
+
// Renderers
virtual void setRenderer( Renderer *renderer_ );
virtual Renderer* getRenderer() const;
@@ -111,10 +111,10 @@
// Idle modes
virtual IdleModeHandle addIdleMode( IdleMode *idle_mode );
virtual IdleMode *getIdleMode( IdleModeHandle i ) const;
-
+
// Scenes
virtual void setScene(Scene* scene);
- virtual Scene *getScene();
+ virtual Scene *getScene();
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
@@ -127,13 +127,13 @@
// Query functions
virtual int getCurrentFrame() const { return animFrameState.frameNumber;
};
-
+
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// Control
///////////////////////////////////////////////////////////////////////////
-
///////////////////////////////////////////////////////////////////////////
-
+
///////////////////////////////////////////////////////////////////////////
+
// Parallel processing
virtual void changeNumWorkers(int workers);
virtual TValue<int>& numWorkers();
@@ -142,13 +142,13 @@
virtual void beginRendering(bool blockUntilFinished) throw
(SCIRun::Exception &);
virtual void blockUntilFinished();
virtual void finish();
-
+
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// Transactions
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-
+
// Transactions
virtual void addTransaction(TransactionBase* );
@@ -157,10 +157,10 @@
// Callbacks.
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-
+
// Callbacks
virtual void addOneShotCallback(OneShotTime whence, FrameNumber frame,
CallbackBase_2Data<int, int>* callback);
- virtual void addParallelOneShotCallback(OneShotTime whence, FrameNumber
frame, CallbackBase_2Data<int, int>* callback);
+ virtual void addParallelOneShotCallback(OneShotTime whence, FrameNumber
frame, CallbackBase_2Data<int, int>* callback);
virtual CallbackHandle* registerSetupCallback(SetupCallback*);
virtual CallbackHandle*
registerSerialAnimationCallback(CallbackBase_3Data<int, int, bool&>*);
@@ -169,15 +169,15 @@
virtual CallbackHandle*
registerParallelPreRenderCallback(CallbackBase_2Data<int, int>*);
virtual CallbackHandle* registerTerminationCallback( CallbackBase_1Data<
MantaInterface *> *);
virtual void unregisterCallback(CallbackHandle*);
-
+
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// Debug
///////////////////////////////////////////////////////////////////////////
-
///////////////////////////////////////////////////////////////////////////
-
- // Debug:
- virtual void shootOneRay( Color &result_color, RayPacket
&result_rays, Real image_x, Real image_y, int channel_index );
+
///////////////////////////////////////////////////////////////////////////
+
+ // Debug:
+ virtual void shootOneRay( Color &result_color, RayPacket
&result_rays, Real image_x, Real image_y, int channel_index );
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
@@ -190,8 +190,8 @@
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
-
- protected:
+
+ protected:
void internalRenderLoop(int workerIndex, bool lateComerFlag);
///////////////////////////////////////////////////////////////////////////
@@ -215,7 +215,7 @@
};
typedef vector<Channel*> ChannelListType;
ChannelListType channels;
-
+
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
// Worker class for the RTRT Pipeline.
@@ -225,7 +225,7 @@
public:
Worker(RTRT* rtrt, int workerIndex, bool lateComerFlag);
virtual ~Worker();
-
+
virtual void run();
private:
RTRT* rtrt;
@@ -237,7 +237,7 @@
///////////////////////////////////////////////////////////////////////////
// Pipeline Configuration.
///////////////////////////////////////////////////////////////////////////
-
///////////////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////////////
ImageTraverser* currentImageTraverser;
LoadBalancer* currentLoadBalancer;
@@ -248,7 +248,7 @@
CreateImageCallback* create_image;
CreateRNGCallback* create_rng;
-
+
private:
RTRT(const RTRT&);
RTRT& operator=(const RTRT&);
@@ -256,13 +256,14 @@
// Callback Helpers.
void doParallelAnimationCallbacks(bool& changed, int proc, int numProcs);
void doSerialAnimationCallbacks(bool& changed, int proc, int numProcs);
-
+
+ void doPreprocess(int proc, int numProcs);
void doParallelPreRenderCallbacks(int proc, int numProcs);
void doSerialPreRenderCallbacks(int proc, int numProcs);
void doIdleModeCallbacks(bool changed, bool firstFrame, bool&
pipelineNeedsSetup, int proc, int numProcs);
void doTerminationCallbacks();
-
+
void resizeImages(long frameNumber);
void setupPipelines(int numProcs);
@@ -294,7 +295,7 @@
typedef multimap<long, CallbackBase_2Data<int, int>*, less<long> >
OneShotMapType;
typedef multimap<long, CallbackBase_2Data<int, int>*, less<long> >
ParallelOneShotMapType;
-
+
OneShotMapType oneShots;
ParallelOneShotMapType parallelOneShots;
@@ -344,7 +345,7 @@
// RandomNumberGenerator
vector<RandomNumberGenerator*> rngs;
-
+
Scene* scene;
SCIRun::Mutex channel_create_lock;
Modified: trunk/Engine/Renderers/NullRenderer.cc
==============================================================================
--- trunk/Engine/Renderers/NullRenderer.cc (original)
+++ trunk/Engine/Renderers/NullRenderer.cc Mon Aug 20 17:26:40 2007
@@ -53,7 +53,7 @@
int b = (rays.rayBegin + 3) & (~3);
int e = rays.rayEnd & (~3);
RayPacketData* data = rays.data;
- if(b == e){
+ if(b >= e){
for(int i=rays.begin();i<rays.end();i++){
rays.setColor(i, color);
}
@@ -78,7 +78,7 @@
data->color[2][i] = color[2];
}
}
-#else
+#else
for(int i=rays.begin();i<rays.end();i++){
rays.setColor(i, color);
}
Modified: trunk/Interface/AccelerationStructure.h
==============================================================================
--- trunk/Interface/AccelerationStructure.h (original)
+++ trunk/Interface/AccelerationStructure.h Mon Aug 20 17:26:40 2007
@@ -9,18 +9,26 @@
class AccelerationStructure : public Object {
public:
+ // Tell the acceleration structure that it's working on a new
+ // group. However, you should not actually perform any
+ // "construction" work yet as that is reserved for the update and
+ // rebuild functions which are called during the preprocess phases
+ // of Manta. setGroup can be called when "building" your scene.
+ virtual void setGroup(Group* new_group) = 0;
- //TODO: decide whether we want a seperate rebuild and update
- //function or let the acceleration structure decide which to use.
-
- // NOTE(boulos): Due to a deadline this won't be done correctly
- // requiring everyone to implement this until we get a chance to
- // come back to it.
- virtual void update(int proc=0, int numProcs=1) {}
-
- virtual void rebuild(Group *group, int proc=0, int numProcs=1) = 0;
- //virtual void update() = 0;
+ // update tells the acceleration structure that the underlying
+ // geometry has probably "moved" so that the bounds need to be
+ // updated. No actual changes in the amount of geometry has
+ // occurred (so do not call this function for that purpose). For
+ // some data structures (e.g. a BVH) this can be more efficient
+ // than rebuilding. By default, however, this will be a call to
+ // rebuild.
+ virtual void update(int proc=0, int numProcs=1) {
+ rebuild(proc, numProcs);
+ }
+ // rebuild the data structure over the current group.
+ virtual void rebuild(int proc=0, int numProcs=1) = 0;
};
}
#endif //Manta_Interface_AccelerationStructure_h
Modified: trunk/Interface/CMakeLists.txt
==============================================================================
--- trunk/Interface/CMakeLists.txt (original)
+++ trunk/Interface/CMakeLists.txt Mon Aug 20 17:26:40 2007
@@ -14,6 +14,7 @@
Camera.h
Clonable.h
Context.h
+ Context.cc
Fragment.h
IdleMode.cc
IdleMode.h
Modified: trunk/Interface/Context.h
==============================================================================
--- trunk/Interface/Context.h (original)
+++ trunk/Interface/Context.h Mon Aug 20 17:26:40 2007
@@ -2,6 +2,10 @@
#ifndef Manta_Interface_Context_h
#define Manta_Interface_Context_h
+namespace SCIRun {
+ class Barrier;
+};
+
namespace Manta {
class Camera;
class FrameState;
@@ -16,7 +20,7 @@
class XWindow;
class ThreadStorage;
class RandomNumberGenerator;
-
+
class ReadContext {
public:
ReadContext(MantaInterface* rtrt_int)
@@ -32,7 +36,7 @@
-
+
/////////////////////////////////////////////////////////////////////////////
// Setup context is used to configure rendering stack components.
@@ -46,7 +50,7 @@
LoadBalancer* loadBalancer, PixelSampler* pixelSampler,
Renderer* renderer,
ThreadStorage *storage_allocator_ )
-
+
: rtrt_int(rtrt_int),
channelIndex(channelIndex), numChannels(numChannels),
proc(proc), numProcs(numProcs),
@@ -82,7 +86,7 @@
LoadBalancer* loadBalancer;
PixelSampler* pixelSampler;
Renderer* renderer;
-
+
ThreadStorage *storage_allocator;
mutable XWindow* masterWindow;
@@ -179,27 +183,34 @@
const Scene* scene;
mutable ThreadStorage *storage_allocator;
-
+
RandomNumberGenerator* rng;
private:
RenderContext(const RenderContext&);
RenderContext& operator=(const RenderContext&);
};
+
class PreprocessContext {
public:
- PreprocessContext() {}
- PreprocessContext(MantaInterface* manta_interface, LightSet*
globalLights)
- : manta_interface(manta_interface), globalLights(globalLights)
- {
- }
- ~PreprocessContext()
- {
- }
+ PreprocessContext();
+ PreprocessContext(MantaInterface* manta_interface,
+ int proc,
+ int numProcs,
+ LightSet* globalLights);
+ ~PreprocessContext();
+
+ // Call this when you're done changing your state values during a
+ // preprocess call. It ensures that all the threads finish
+ // together.
+ void done() const;
MantaInterface* manta_interface;
+ int proc;
+ int numProcs;
LightSet* globalLights;
-
private:
+ mutable SCIRun::Barrier* barrier;
+
PreprocessContext(const PreprocessContext&);
PreprocessContext& operator=(const PreprocessContext&);
};
Modified: trunk/Interface/RayPacket.cc
==============================================================================
--- trunk/Interface/RayPacket.cc (original)
+++ trunk/Interface/RayPacket.cc Mon Aug 20 17:26:40 2007
@@ -2,6 +2,10 @@
#include <Interface/RayPacket.h>
#include <MantaSSE.h>
+#include <sgi_stl_warnings_off.h>
+#include <iostream>
+#include <sgi_stl_warnings_on.h>
+
using namespace Manta;
void RayPacket::actualNormalizeDirections()
@@ -9,7 +13,7 @@
#ifdef MANTA_SSE
int b = (rayBegin + 3) & (~3);
int e = rayEnd & (~3);
- if(b == e){
+ if(b >= e){
for(int i=rayBegin;i<rayEnd;i++){
Real sum = 0;
for(int j=0;j<3;j++)
@@ -81,7 +85,7 @@
#if MANTA_SSE
int b = (rayBegin + 3) & (~3);
int e = rayEnd & (~3);
- if (b == e) {
+ if (b >= e) {
for(int i=rayBegin;i<rayEnd;i++)
for(int j=0;j<3;j++)
data->inverseDirection[j][i] = (Real)1/data->direction[j][i];
@@ -113,35 +117,35 @@
void RayPacket::actualComputeHitPositions()
{
#ifdef MANTA_SSE
- int b = (rayBegin + 3) & (~3);
- int e = rayEnd & (~3);
- if(b == e){
- for(int i = begin(); i < end(); i++){
- for(int j=0;j<3;j++)
- data->hitPosition[j][i] = data->origin[j][i]
+ data->direction[j][i] * data->minT[i];
- }
- } else {
- int i = rayBegin;
- for(;i<b;i++){
- for(int j=0;j<3;j++)
- data->hitPosition[j][i] = data->origin[j][i]
+ data->direction[j][i] * data->minT[i];
- }
- for(;i<e;i+=4){
- __m128 minT = _mm_load_ps(&data->minT[i]);
- _mm_store_ps(&data->hitPosition[0][i],
_mm_add_ps(_mm_load_ps(&data->origin[0][i]),
_mm_mul_ps(_mm_load_ps(&data->direction[0][i]), minT)));
- _mm_store_ps(&data->hitPosition[1][i],
_mm_add_ps(_mm_load_ps(&data->origin[1][i]),
_mm_mul_ps(_mm_load_ps(&data->direction[1][i]), minT)));
- _mm_store_ps(&data->hitPosition[2][i],
_mm_add_ps(_mm_load_ps(&data->origin[2][i]),
_mm_mul_ps(_mm_load_ps(&data->direction[2][i]), minT)));
- }
- for(;i<rayEnd;i++){
- for(int j=0;j<3;j++)
- data->hitPosition[j][i] = data->origin[j][i]
+ data->direction[j][i] * data->minT[i];
- }
- }
+ int b = (rayBegin + 3) & (~3);
+ int e = rayEnd & (~3);
+ if(b >= e){
+ for(int i = begin(); i < end(); i++){
+ for(int j=0;j<3;j++)
+ data->hitPosition[j][i] = data->origin[j][i]
+ data->direction[j][i] * data->minT[i];
+ }
+ } else {
+ int i = rayBegin;
+ for(;i<b;i++){
+ for(int j=0;j<3;j++)
+ data->hitPosition[j][i] = data->origin[j][i]
+ data->direction[j][i] * data->minT[i];
+ }
+ for(;i<e;i+=4){
+ __m128 minT = _mm_load_ps(&data->minT[i]);
+ _mm_store_ps(&data->hitPosition[0][i],
_mm_add_ps(_mm_load_ps(&data->origin[0][i]),
_mm_mul_ps(_mm_load_ps(&data->direction[0][i]), minT)));
+ _mm_store_ps(&data->hitPosition[1][i],
_mm_add_ps(_mm_load_ps(&data->origin[1][i]),
_mm_mul_ps(_mm_load_ps(&data->direction[1][i]), minT)));
+ _mm_store_ps(&data->hitPosition[2][i],
_mm_add_ps(_mm_load_ps(&data->origin[2][i]),
_mm_mul_ps(_mm_load_ps(&data->direction[2][i]), minT)));
+ }
+ for(;i<rayEnd;i++){
+ for(int j=0;j<3;j++)
+ data->hitPosition[j][i] = data->origin[j][i]
+ data->direction[j][i] * data->minT[i];
+ }
+ }
#else
- for(int i = rayBegin; i < rayEnd; i++){
- for(int j=0;j<3;j++)
- data->hitPosition[j][i] = data->origin[j][i] +
data->direction[j][i] * data->minT[i];
- }
+ for(int i = rayBegin; i < rayEnd; i++){
+ for(int j=0;j<3;j++)
+ data->hitPosition[j][i] = data->origin[j][i] +
data->direction[j][i] * data->minT[i];
+ }
#endif
flags |= HaveHitPositions;
}
@@ -222,4 +226,15 @@
}
flags |= HaveTexture3;
+}
+namespace Manta {
+ std::ostream& operator<< (std::ostream& os, const RayPacket& rays) {
+ for (int i = rays.begin(); i < rays.end(); i++) {
+ os << "ray_index " << i << " depth " << rays.getDepth() << " origin";
+ os << " " << rays.getOrigin(i) << " direction " <<
rays.getDirection(i);
+ os << " minT " << rays.getMinT(i) << " matl " <<
rays.getHitMaterial(i);
+ os << std::endl;
+ }
+ return os;
+ }
}
Modified: trunk/Interface/RayPacket.h
==============================================================================
--- trunk/Interface/RayPacket.h (original)
+++ trunk/Interface/RayPacket.h Mon Aug 20 17:26:40 2007
@@ -48,9 +48,9 @@
#include <Core/Math/SSEDefs.h>
#endif
-// #include <sgi_stl_warnings_off.h>
-// #include <iostream>
-// #include <sgi_stl_warnings_on.h>
+#include <sgi_stl_warnings_off.h>
+#include <iosfwd>
+#include <sgi_stl_warnings_on.h>
namespace Manta {
class Material;
@@ -309,9 +309,9 @@
}
Real &getDirection(int which, int i)
- {
- return data->direction[i][which];
- }
+ {
+ return data->direction[i][which];
+ }
const Real &getDirection(int which, int i) const
{
return data->direction[i][which];
@@ -388,7 +388,7 @@
#ifdef MANTA_SSE
int b = (rayBegin + 3) & (~3);
int e = rayEnd & (~3);
- if(b == e){
+ if(b >= e){
for(int i = rayBegin; i < rayEnd; i++){
data->hitMatl[i] = 0;
data->minT[i] = MAXT;
@@ -572,7 +572,7 @@
}
// No mask
inline __m128 hit(int start, __m128 t, const Material* matl,
-
const Primitive* prim, const TexCoordMapper* tex) {
+
const Primitive* prim, const TexCoordMapper* tex) {
__m128 mask = _mm_cmpgt_ps(t, _mm_set1_ps(T_EPSILON));
return hitFinal(start, mask, t, matl, prim, tex);
}
@@ -635,15 +635,15 @@
{
data->hitTex[which] = tex;
}
- const Material* getHitMaterial(int which)
+ const Material* getHitMaterial(int which) const
{
return data->hitMatl[which];
}
- const Primitive* getHitPrimitive(int which)
+ const Primitive* getHitPrimitive(int which) const
{
return data->hitPrim[which];
}
- const TexCoordMapper* getHitTexCoordMapper(int which)
+ const TexCoordMapper* getHitTexCoordMapper(int which) const
{
return data->hitTex[which];
}
@@ -826,6 +826,7 @@
typedef MANTA_ALIGN(16) Color::ComponentType
ColorArray[Color::NumComponents][RayPacket::MaxSize];
+ std::ostream& operator<< (std::ostream& os, const RayPacket& rays);
} // end namespace Manta
#endif
Modified: trunk/Maya/MayaScene.cc
==============================================================================
--- trunk/Maya/MayaScene.cc (original)
+++ trunk/Maya/MayaScene.cc Mon Aug 20 17:26:40 2007
@@ -42,6 +42,7 @@
#include <Image/NRRDFile.h>
#include <Image/TGAFile.h>
#include <Interface/AccelerationStructure.h>
+#include <Interface/Context.h>
#include <Interface/LightSet.h>
#include <Interface/MantaInterface.h>
#include <Interface/Scene.h>
@@ -85,10 +86,10 @@
using namespace MantaPlugin;
#define USE_MANTA_MESH 1
-// Due to a current bug in Manta with instanced Meshes, we can't do
-// this yet
+// NOTE(boulos): Instances in Manta don't currently work quite right
+// (like normals and such...) so only use for debugging.
#define USE_INSTANCES 0
-
+#define USE_REAL_ACCEL 1
class MyMesh {
@@ -177,14 +178,22 @@
mesh.engine = engine;
Mesh* new_mesh = new Mesh();
+#if USE_REAL_ACCEL
AccelerationStructure* mesh_accel = new DynBVH();
+#else
+ Group* mesh_accel = new Group();
+#endif
status = mesh.setup(result, iter, new_mesh);
MANTA_CHECK_STATUS_RETURN( status, me+"::setup()");
mesh.processSets(result, new_mesh);
MANTA_CHECK_STATUS_RETURN( status, me+"::processSets()");
- mesh_accel->rebuild(new_mesh);
+#if USE_REAL_ACCEL
+ mesh_accel->setGroup(new_mesh);
+#else
+ mesh_accel->add(new_mesh);
+#endif
#if USE_INSTANCES
// TODO(boulos): Stick an instance around the mesh and use local
@@ -201,8 +210,7 @@
mesh_transform);
geometry->add(mesh_instance);
- cerr << "Mesh Transform is " << mesh_transform << endl;
- //geometry->add(mesh_accel);
+ cerr << "Mesh Transform is:\n " << mesh_transform << endl;
#else
geometry->add(mesh_accel);
#endif
@@ -234,7 +242,8 @@
scene->setLights( lights );
// Process the geometry
- toplevel_accel->rebuild(geometry);
+ cerr << "Assigning group to top level acceleration structure\n";
+ toplevel_accel->setGroup(geometry);
status = MayaCamera::GetCamera(result, scene, engine);
if (status.error()) {
@@ -293,7 +302,6 @@
for(unsigned int i = 0; i < vertices.length(); ++i) {
mesh->vertices.push_back(maya2manta(vertices[i]));
- cerr << "Vertex " << i << " = " << mesh->vertices[i] << endl;
}
for(unsigned int i = 0; i < fNormalArray.length(); ++i) {
mesh->vertexNormals.push_back(maya2manta(fNormalArray[i]));
Modified: trunk/Model/Cameras/EnvironmentCamera.cc
==============================================================================
--- trunk/Model/Cameras/EnvironmentCamera.cc (original)
+++ trunk/Model/Cameras/EnvironmentCamera.cc Mon Aug 20 17:26:40 2007
@@ -74,6 +74,11 @@
void EnvironmentCamera::preprocess(const PreprocessContext& context)
{
+ if (context.proc != 0) {
+ context.done();
+ return;
+ }
+
Scene* scene = context.manta_interface->getScene();
if(!haveCamera){
const BasicCameraData* bookmark = scene->currentBookmark();
@@ -87,6 +92,8 @@
}
haveCamera = true;
}
+
+ context.done();
}
void EnvironmentCamera::getBasicCameraData(BasicCameraData& cam) const
Modified: trunk/Model/Cameras/FisheyeCamera.cc
==============================================================================
--- trunk/Model/Cameras/FisheyeCamera.cc (original)
+++ trunk/Model/Cameras/FisheyeCamera.cc Mon Aug 20 17:26:40 2007
@@ -240,6 +240,11 @@
void FisheyeCamera::preprocess(const PreprocessContext& context)
{
+ if (context.proc != 0) {
+ context.done();
+ return;
+ }
+
Scene* scene = context.manta_interface->getScene();
if(!haveCamera){
const BasicCameraData* bookmark = scene->currentBookmark();
@@ -254,4 +259,6 @@
}
haveCamera = true;
}
+
+ context.done();
}
Modified: trunk/Model/Cameras/OrthogonalCamera.cc
==============================================================================
--- trunk/Model/Cameras/OrthogonalCamera.cc (original)
+++ trunk/Model/Cameras/OrthogonalCamera.cc Mon Aug 20 17:26:40 2007
@@ -225,6 +225,11 @@
void OrthogonalCamera::preprocess(const PreprocessContext& context)
{
+ if (context.proc != 0) {
+ context.done();
+ return;
+ }
+
Scene* scene = context.manta_interface->getScene();
if(!haveCamera){
const BasicCameraData* bookmark = scene->currentBookmark();
@@ -238,4 +243,6 @@
}
haveCamera = true;
}
+
+ context.done();
}
Modified: trunk/Model/Cameras/PinholeCamera.cc
==============================================================================
--- trunk/Model/Cameras/PinholeCamera.cc (original)
+++ trunk/Model/Cameras/PinholeCamera.cc Mon Aug 20 17:26:40 2007
@@ -439,6 +439,11 @@
void PinholeCamera::preprocess(const PreprocessContext& context)
{
+ if (context.proc != 0) {
+ context.done();
+ return;
+ }
+
Scene* scene = context.manta_interface->getScene();
if(!haveCamera){
const BasicCameraData* bookmark = scene->currentBookmark();
@@ -457,4 +462,6 @@
}
haveCamera = true;
}
+
+ context.done();
}
Modified: trunk/Model/Groups/BVH.cc
==============================================================================
--- trunk/Model/Groups/BVH.cc (original)
+++ trunk/Model/Groups/BVH.cc Mon Aug 20 17:26:40 2007
@@ -2,6 +2,7 @@
#include <Model/Groups/BVH.h>
#include <Core/Util/Args.h>
#include <Core/Exceptions/IllegalArgument.h>
+#include <Interface/Context.h>
#include <Interface/RayPacket.h>
#include <Core/Containers/StringUtil.h>
#include <Core/Exceptions/InternalError.h>
@@ -65,6 +66,7 @@
void BVH::preprocess(const PreprocessContext& context)
{
Group::preprocess(context);
+ if (context.proc != 0) { context.done(); return; }
double start_time = Time::currentSeconds();
int nprims = static_cast<int>(objs.size());
@@ -295,6 +297,7 @@
// throw InternalError("BVH tree corrupt");
double dt = Time::currentSeconds()-start_time;
stats << "BVH preprocessed " << nprims << " primitives in " << dt << "
seconds, build mode is " << buildMode << '\n';
+ context.done();
}
#if 0
Modified: trunk/Model/Groups/DynBVH.cc
==============================================================================
--- trunk/Model/Groups/DynBVH.cc (original)
+++ trunk/Model/Groups/DynBVH.cc Mon Aug 20 17:26:40 2007
@@ -17,43 +17,50 @@
void DynBVH::intersect(const RenderContext& context, RayPacket& rays) const
{
- rays.computeInverseDirections();
+ bool debugFlag = rays.getFlag(RayPacket::DebugPacket);
+ if (debugFlag) {
+ //cerr << __func__ << " called\n";
+ cerr << MANTA_FUNC << " called\n";
+ cerr << "Rays are : \n" << rays << endl;
+ }
+
+ rays.computeInverseDirections();
#if USE_DYNBVH_PORTS
- templatedTraverse(context, rays);
+ templatedTraverse(context, rays);
#else
- rays.computeSigns();
+ rays.computeSigns();
- // compute IntervalArithmetic Data
- IAData ia_data;
- for (int axis = 0; axis < 3; axis++ )
+ // compute IntervalArithmetic Data
+ IAData ia_data;
+ for (int axis = 0; axis < 3; axis++ )
{
- ia_data.min_rcp[axis] = std::numeric_limits<float>::max();
- ia_data.max_rcp[axis] = -std::numeric_limits<float>::max();
- ia_data.min_org[axis] = std::numeric_limits<float>::max();
- ia_data.max_org[axis] = -std::numeric_limits<float>::max();
- ia_data.min_org_rcp[axis] = std::numeric_limits<float>::max();
- ia_data.max_org_rcp[axis] = -std::numeric_limits<float>::max();
+ ia_data.min_rcp[axis] = std::numeric_limits<float>::max();
+ ia_data.max_rcp[axis] = -std::numeric_limits<float>::max();
+ ia_data.min_org[axis] = std::numeric_limits<float>::max();
+ ia_data.max_org[axis] = -std::numeric_limits<float>::max();
+ ia_data.min_org_rcp[axis] = std::numeric_limits<float>::max();
+ ia_data.max_org_rcp[axis] = -std::numeric_limits<float>::max();
}
- // TODO(boulos): provide an SSE version
- for (int ray = rays.begin(); ray < rays.end(); ray++ )
+ // TODO(boulos): provide an SSE version
+ for (int ray = rays.begin(); ray < rays.end(); ray++ )
{
- for (int axis = 0; axis < 3; axis++)
+ for (int axis = 0; axis < 3; axis++)
{
- const Real new_rcp = rays.getInverseDirection(ray, axis);
- const Real new_org = rays.getOrigin(ray,axis);
- const Real new_org_rcp = new_org * new_rcp;
-
- ia_data.min_rcp[axis] = (ia_data.min_rcp[axis] < new_rcp) ?
ia_data.min_rcp[axis] : new_rcp;
- ia_data.max_rcp[axis] = (ia_data.max_rcp[axis] < new_rcp) ?
new_rcp : ia_data.max_rcp[axis];
-
- ia_data.min_org[axis] = (ia_data.min_org[axis] < new_org) ?
ia_data.min_org[axis] : new_org;
- ia_data.max_org[axis] = (ia_data.max_org[axis] < new_org) ?
new_org : ia_data.max_org[axis];
-
- ia_data.min_org_rcp[axis] = (ia_data.min_org_rcp[axis] <
new_org_rcp) ?
- ia_data.min_org_rcp[axis] : new_org_rcp;
- ia_data.max_org_rcp[axis] = (ia_data.max_org_rcp[axis] <
new_org_rcp) ?
- new_org_rcp : ia_data.max_org_rcp[axis];
+ const Real new_rcp = rays.getInverseDirection(ray, axis);
+ const Real new_org = rays.getOrigin(ray,axis);
+ const Real new_org_rcp = new_org * new_rcp;
+
+ ia_data.min_rcp[axis] = (ia_data.min_rcp[axis] < new_rcp) ?
ia_data.min_rcp[axis] : new_rcp;
+ ia_data.max_rcp[axis] = (ia_data.max_rcp[axis] < new_rcp) ?
new_rcp : ia_data.max_rcp[axis];
+
+ ia_data.min_org[axis] = (ia_data.min_org[axis] < new_org) ?
ia_data.min_org[axis] : new_org;
+ ia_data.max_org[axis] = (ia_data.max_org[axis] < new_org) ?
new_org : ia_data.max_org[axis];
+
+ ia_data.min_org_rcp[axis] = (ia_data.min_org_rcp[axis] <
new_org_rcp) ?
+ ia_data.min_org_rcp[axis] : new_org_rcp;
+ ia_data.max_org_rcp[axis] = (ia_data.max_org_rcp[axis] <
new_org_rcp) ?
+ new_org_rcp : ia_data.max_org_rcp[axis];
}
}
@@ -61,27 +68,27 @@
#define USE_ASSERTED_PARENT 0
#if USE_ASSERTED_PARENT
- const BVHNode& root_node = nodes[0];
- float tmin;
- int firstActive = firstIntersects(root_node.bounds, rays, ia_data,
&tmin);
- if (firstActive != rays.end()) {
- if (root_node.isLeaf()) {
- int lastActive = lastIntersects(root_node.bounds, rays);
- // build a subpacket from firstActive to lastActive (inclusive,
hence +1)
- RayPacket subpacket(rays, firstActive, lastActive+1);
+ const BVHNode& root_node = nodes[0];
+ float tmin;
+ int firstActive = firstIntersects(root_node.bounds, rays, ia_data, &tmin);
+ if (firstActive != rays.end()) {
+ if (root_node.isLeaf()) {
+ int lastActive = lastIntersects(root_node.bounds, rays);
+ // build a subpacket from firstActive to lastActive (inclusive, hence
+1)
+ RayPacket subpacket(rays, firstActive, lastActive+1);
- for (int i = 0; i < root_node.children; i++ )
- {
- const int object_id = object_ids[root_node.child+i];
- currGroup->get(object_id)->intersect(context,subpacket);
- }
- } else {
- RayPacket subpacket(rays, firstActive, rays.end());
- intersectNode(root_node.child, context, subpacket, ia_data);
+ for (int i = 0; i < root_node.children; i++ )
+ {
+ const int object_id = object_ids[root_node.child+i];
+ currGroup->get(object_id)->intersect(context,subpacket);
}
+ } else {
+ RayPacket subpacket(rays, firstActive, rays.end());
+ intersectNode(root_node.child, context, subpacket, ia_data);
}
+ }
#else
- intersectNode(0,context,rays, ia_data);
+ intersectNode(0,context,rays, ia_data);
#endif // asserted parent or not
#endif // dynbvh port or not
@@ -89,78 +96,78 @@
#if USE_ASSERTED_PARENT
void DynBVH::intersectNode(int nodeID, const RenderContext& context,
RayPacket& rays, const IAData& ia_data) const {
- const BVHNode& left_node = nodes[nodeID+0];
- const BVHNode& right_node = nodes[nodeID+1];
- float left_tmin, right_tmin;
-
- int leftFirstActive = firstIntersects(left_node.bounds, rays, ia_data,
&left_tmin);
- int rightFirstActive = firstIntersects(right_node.bounds, rays, ia_data,
&right_tmin);
-
- const BVHNode* child_nodes[2] = { (left_tmin < right_tmin) ? &left_node
: &right_node,
- (left_tmin < right_tmin) ? &right_node
: &left_node };
- int firstActive[2] = { (left_tmin < right_tmin) ? leftFirstActive :
rightFirstActive,
- (left_tmin < right_tmin) ? rightFirstActive :
leftFirstActive };
-
- for (int which = 0; which < 2; ++which) {
- if (firstActive[which] != rays.end()) {
- const BVHNode* node = child_nodes[which];
- if (node->isLeaf()) {
- int lastActive = lastIntersects(node->bounds, rays);
-
- // build a subpacket from firstActive to lastActive
(inclusive, hence +1)
- RayPacket subpacket(rays, firstActive[which], lastActive+1);
-
- for (int i = 0; i < node->children; i++ )
- {
- const int object_id = object_ids[node->child+i];
- currGroup->get(object_id)->intersect(context,subpacket);
- }
- } else {
- RayPacket subpacket(rays, firstActive[which], rays.end());
- intersectNode(node->child, context, subpacket, ia_data);
- }
- }
+ const BVHNode& left_node = nodes[nodeID+0];
+ const BVHNode& right_node = nodes[nodeID+1];
+ float left_tmin, right_tmin;
+
+ int leftFirstActive = firstIntersects(left_node.bounds, rays, ia_data,
&left_tmin);
+ int rightFirstActive = firstIntersects(right_node.bounds, rays, ia_data,
&right_tmin);
+
+ const BVHNode* child_nodes[2] = { (left_tmin < right_tmin) ? &left_node :
&right_node,
+ (left_tmin < right_tmin) ? &right_node :
&left_node };
+ int firstActive[2] = { (left_tmin < right_tmin) ? leftFirstActive :
rightFirstActive,
+ (left_tmin < right_tmin) ? rightFirstActive :
leftFirstActive };
+
+ for (int which = 0; which < 2; ++which) {
+ if (firstActive[which] != rays.end()) {
+ const BVHNode* node = child_nodes[which];
+ if (node->isLeaf()) {
+ int lastActive = lastIntersects(node->bounds, rays);
+
+ // build a subpacket from firstActive to lastActive (inclusive,
hence +1)
+ RayPacket subpacket(rays, firstActive[which], lastActive+1);
+
+ for (int i = 0; i < node->children; i++ )
+ {
+ const int object_id = object_ids[node->child+i];
+ currGroup->get(object_id)->intersect(context,subpacket);
+ }
+ } else {
+ RayPacket subpacket(rays, firstActive[which], rays.end());
+ intersectNode(node->child, context, subpacket, ia_data);
+ }
}
+ }
}
#else
void DynBVH::intersectNode(int nodeID, const RenderContext& context,
RayPacket& rays, const IAData& ia_data) const
{
- const BVHNode& node = nodes[nodeID];
- float tmin;
- int firstActive = firstIntersects(node.bounds, rays, ia_data, &tmin);
+ const BVHNode& node = nodes[nodeID];
+ float tmin;
+ int firstActive = firstIntersects(node.bounds, rays, ia_data, &tmin);
- if (firstActive != rays.end())
+ if (firstActive != rays.end())
{
- if (node.isLeaf())
+ if (node.isLeaf())
{
- // we already know that one of the rays from begin to end
- // hits the object, so lastActive is going to find something
- // we need not create a subpacket to help it stop early
-
- // actually if we're just one ray it'll look more than it
- // needs to since it will reintersect the firstActive ray...
- int lastActive = lastIntersects(node.bounds, rays);
+ // we already know that one of the rays from begin to end
+ // hits the object, so lastActive is going to find something
+ // we need not create a subpacket to help it stop early
+
+ // actually if we're just one ray it'll look more than it
+ // needs to since it will reintersect the firstActive ray...
+ int lastActive = lastIntersects(node.bounds, rays);
- // build a subpacket from firstActive to lastActive (inclusive,
hence +1)
- RayPacket subpacket(rays, firstActive, lastActive+1);
+ // build a subpacket from firstActive to lastActive (inclusive,
hence +1)
+ RayPacket subpacket(rays, firstActive, lastActive+1);
- for (int i = 0; i < node.children; i++ )
+ for (int i = 0; i < node.children; i++ )
{
- const int object_id = object_ids[node.child+i];
+ const int object_id = object_ids[node.child+i];
- currGroup->get(object_id)->intersect(context,subpacket);
+ currGroup->get(object_id)->intersect(context,subpacket);
}
}
- else
+ else
{
- // make a subpacket from the (possibly) new firstActive to the
current end
- RayPacket subpacket(rays, firstActive, rays.end());
+ // make a subpacket from the (possibly) new firstActive to the
current end
+ RayPacket subpacket(rays, firstActive, rays.end());
- // recurse
- int front_son = subpacket.getDirection(subpacket.begin(),
-
static_cast<int>(node.axis)) > 0 ? 0 : 1;
- intersectNode(node.child+front_son, context, subpacket, ia_data);
- intersectNode(node.child+1-front_son, context, subpacket,
ia_data);
+ // recurse
+ int front_son = subpacket.getDirection(subpacket.begin(),
+
static_cast<int>(node.axis)) > 0 ? 0 : 1;
+ intersectNode(node.child+front_son, context, subpacket, ia_data);
+ intersectNode(node.child+1-front_son, context, subpacket, ia_data);
}
}
}
@@ -169,153 +176,30 @@
int DynBVH::firstIntersects(const BBox& box, const RayPacket& rays, const
IAData& ia_data, float* out_tmin) const
{
#ifdef MANTA_SSE
- int b = (rays.rayBegin + 3) & (~3);
- int e = rays.rayEnd & (~3);
- if (b >=e) {
- for (int i = rays.begin(); i < rays.end(); i++) {
- float tmin = 1e-5f;
- float tmax = rays.getMinT(i);
-
- for (int c = 0; c < 3; c++) {
- float t0 = (box[0][c] - rays.getOrigin(i,c)) *
rays.getInverseDirection(i,c);
- float t1 = (box[1][c] - rays.getOrigin(i,c)) *
rays.getInverseDirection(i,c);
-
- float near = (t0 < t1) ? t0 : t1;
- float far = (t0 < t1) ? t1 : t0;
- tmin = (tmin < near) ? near : tmin; // max of tmin, near
- tmax = (far < tmax) ? far : tmax; // min of tmax, far
- }
- if (tmin <= tmax) { // valid intersection
- *out_tmin = tmin;
- return i;
- }
- }
- } else {
- int i = rays.rayBegin;
- for(;i<b;i++) {
- float tmin = 1e-5f;
- float tmax = rays.getMinT(i);
-
- for (int c = 0; c < 3; c++) {
- float t0 = (box[0][c] - rays.getOrigin(i,c)) *
rays.getInverseDirection(i,c);
- float t1 = (box[1][c] - rays.getOrigin(i,c)) *
rays.getInverseDirection(i,c);
-
- float near = (t0 < t1) ? t0 : t1;
- float far = (t0 < t1) ? t1 : t0;
- tmin = (tmin < near) ? near : tmin; // max of tmin, near
- tmax = (far < tmax) ? far : tmax; // min of tmax, far
- }
- if (tmin <= tmax) { // valid intersection
- *out_tmin = tmin;
- return i;
- }
-
- if (i == rays.rayBegin) {
- // try a frustum miss
- float tmin_frustum = 1e-5;
- float tmax_frustum = FLT_MAX;
-
- for (int axis = 0; axis < 3; axis++) {
- // the subtraction is really (boxIA + -orgIA)
- // or boxIA + [-max_org, -min_org]
- // [box_min, box_max] + [-max_org, -min_org]
- float a = box[0][axis]-ia_data.max_org[axis];
- float b = box[1][axis]-ia_data.min_org[axis];
-
- // now for multiplication
- float ar0 = a * ia_data.min_rcp[axis];
- float ar1 = a * ia_data.max_rcp[axis];
- float br0 = b * ia_data.min_rcp[axis];
- float br1 = b * ia_data.max_rcp[axis];
-
- // [a,b] is valid intersection interval so a is min
- // and b is max t-value
-
- //a = std::min(ar0, std::min(ar1, std::min(br0, br1)));
- a = (br0 < br1) ? br0 : br1;
- a = (a < ar1) ? a : ar1;
- a = (a < ar0) ? a : ar0;
-
- //b = std::max(ar0, std::max(ar1, std::max(br0, br1)));
- b = (br0 < br1) ? br1 : br0;
- b = (b < ar1) ? ar1 : b;
- b = (b < ar0) ? ar0 : b;
-
- tmin_frustum = (tmin_frustum < a) ? a : tmin_frustum;
- tmax_frustum = (tmax_frustum > b) ? b : tmax_frustum;
- }
+ int b = (rays.rayBegin + 3) & (~3);
+ int e = rays.rayEnd & (~3);
+ if (b >=e) {
+ for (int i = rays.begin(); i < rays.end(); i++) {
+ float tmin = 1e-5f;
+ float tmax = rays.getMinT(i);
- // frustum exit
- if (tmin_frustum > tmax_frustum) {
- return rays.end();
- }
- }
- }
+ for (int c = 0; c < 3; c++) {
+ float t0 = (box[0][c] - rays.getOrigin(i,c)) *
rays.getInverseDirection(i,c);
+ float t1 = (box[1][c] - rays.getOrigin(i,c)) *
rays.getInverseDirection(i,c);
- RayPacketData* data = rays.data;
- __m128 box_x0 = _mm_set1_ps(box[0][0]);
- __m128 box_x1 = _mm_set1_ps(box[1][0]);
-
- __m128 box_y0 = _mm_set1_ps(box[0][1]);
- __m128 box_y1 = _mm_set1_ps(box[1][1]);
-
- __m128 box_z0 = _mm_set1_ps(box[0][2]);
- __m128 box_z1 = _mm_set1_ps(box[1][2]);
-
- for(;i<e;i+=4){
- __m128 x0 = _mm_mul_ps(_mm_sub_ps(box_x0,
_mm_load_ps(&data->origin[0][i])),
- _mm_load_ps(&data->inverseDirection[0][i]));
- __m128 x1 = _mm_mul_ps(_mm_sub_ps(box_x1,
_mm_load_ps(&data->origin[0][i])),
- _mm_load_ps(&data->inverseDirection[0][i]));
-
- __m128 xmin = _mm_min_ps(x0,x1);
- __m128 xmax = _mm_max_ps(x0,x1);
-
- __m128 y0 = _mm_mul_ps(_mm_sub_ps(box_y0,
_mm_load_ps(&data->origin[1][i])),
- _mm_load_ps(&data->inverseDirection[1][i]));
- __m128 y1 = _mm_mul_ps(_mm_sub_ps(box_y1,
_mm_load_ps(&data->origin[1][i])),
- _mm_load_ps(&data->inverseDirection[1][i]));
-
- __m128 ymin = _mm_min_ps(y0,y1);
- __m128 ymax = _mm_max_ps(y0,y1);
-
- __m128 z0 = _mm_mul_ps(_mm_sub_ps(box_z0,
_mm_load_ps(&data->origin[2][i])),
- _mm_load_ps(&data->inverseDirection[2][i]));
- __m128 z1 = _mm_mul_ps(_mm_sub_ps(box_z1,
_mm_load_ps(&data->origin[2][i])),
- _mm_load_ps(&data->inverseDirection[2][i]));
-
- __m128 zmin = _mm_min_ps(z0,z1);
- __m128 zmax = _mm_max_ps(z0,z1);
-
- __m128 maximum_minimum =
_mm_max_ps(xmin,_mm_max_ps(ymin,_mm_max_ps(zmin, _mm_set1_ps(1e-5f))));
- __m128 minimum_maximum =
_mm_min_ps(xmax,_mm_min_ps(ymax,_mm_min_ps(zmax,_mm_load_ps(&data->minT[i]))));
- __m128 valid_intersect =
_mm_cmple_ps(maximum_minimum,minimum_maximum);
- if (_mm_movemask_ps(valid_intersect) != 0x0)
- return i;
+ float near = (t0 < t1) ? t0 : t1;
+ float far = (t0 < t1) ? t1 : t0;
+ tmin = (tmin < near) ? near : tmin; // max of tmin, near
+ tmax = (far < tmax) ? far : tmax; // min of tmax, far
}
-
- for(;i<rays.rayEnd;i++) {
- float tmin = 1e-5f;
- float tmax = rays.getMinT(i);
-
- for (int c = 0; c < 3; c++) {
- float t0 = (box[0][c] - rays.getOrigin(i,c)) *
rays.getInverseDirection(i,c);
- float t1 = (box[1][c] - rays.getOrigin(i,c)) *
rays.getInverseDirection(i,c);
-
- float near = (t0 < t1) ? t0 : t1;
- float far = (t0 < t1) ? t1 : t0;
- tmin = (tmin < near) ? near : tmin; // max of tmin, near
- tmax = (far < tmax) ? far : tmax; // min of tmax, far
- }
- if (tmin <= tmax) { // valid intersection
- *out_tmin = tmin;
- return i;
- }
+ if (tmin <= tmax) { // valid intersection
+ *out_tmin = tmin;
+ return i;
}
}
- return rays.end();
-#else
- for (int i = rays.begin(); i < rays.end(); i++) {
+ } else {
+ int i = rays.rayBegin;
+ for(;i<b;i++) {
float tmin = 1e-5f;
float tmax = rays.getMinT(i);
@@ -333,7 +217,7 @@
return i;
}
- if (i == rays.begin()) {
+ if (i == rays.rayBegin) {
// try a frustum miss
float tmin_frustum = 1e-5;
float tmax_frustum = FLT_MAX;
@@ -374,113 +258,250 @@
}
}
}
- return rays.end();
+
+ RayPacketData* data = rays.data;
+ __m128 box_x0 = _mm_set1_ps(box[0][0]);
+ __m128 box_x1 = _mm_set1_ps(box[1][0]);
+
+ __m128 box_y0 = _mm_set1_ps(box[0][1]);
+ __m128 box_y1 = _mm_set1_ps(box[1][1]);
+
+ __m128 box_z0 = _mm_set1_ps(box[0][2]);
+ __m128 box_z1 = _mm_set1_ps(box[1][2]);
+
+ for(;i<e;i+=4){
+ __m128 x0 = _mm_mul_ps(_mm_sub_ps(box_x0,
_mm_load_ps(&data->origin[0][i])),
+ _mm_load_ps(&data->inverseDirection[0][i]));
+ __m128 x1 = _mm_mul_ps(_mm_sub_ps(box_x1,
_mm_load_ps(&data->origin[0][i])),
+ _mm_load_ps(&data->inverseDirection[0][i]));
+
+ __m128 xmin = _mm_min_ps(x0,x1);
+ __m128 xmax = _mm_max_ps(x0,x1);
+
+ __m128 y0 = _mm_mul_ps(_mm_sub_ps(box_y0,
_mm_load_ps(&data->origin[1][i])),
+ _mm_load_ps(&data->inverseDirection[1][i]));
+ __m128 y1 = _mm_mul_ps(_mm_sub_ps(box_y1,
_mm_load_ps(&data->origin[1][i])),
+ _mm_load_ps(&data->inverseDirection[1][i]));
+
+ __m128 ymin = _mm_min_ps(y0,y1);
+ __m128 ymax = _mm_max_ps(y0,y1);
+
+ __m128 z0 = _mm_mul_ps(_mm_sub_ps(box_z0,
_mm_load_ps(&data->origin[2][i])),
+ _mm_load_ps(&data->inverseDirection[2][i]));
+ __m128 z1 = _mm_mul_ps(_mm_sub_ps(box_z1,
_mm_load_ps(&data->origin[2][i])),
+ _mm_load_ps(&data->inverseDirection[2][i]));
+
+ __m128 zmin = _mm_min_ps(z0,z1);
+ __m128 zmax = _mm_max_ps(z0,z1);
+
+ __m128 maximum_minimum =
_mm_max_ps(xmin,_mm_max_ps(ymin,_mm_max_ps(zmin, _mm_set1_ps(1e-5f))));
+ __m128 minimum_maximum =
_mm_min_ps(xmax,_mm_min_ps(ymax,_mm_min_ps(zmax,_mm_load_ps(&data->minT[i]))));
+ __m128 valid_intersect = _mm_cmple_ps(maximum_minimum,minimum_maximum);
+ if (_mm_movemask_ps(valid_intersect) != 0x0)
+ return i;
+ }
+
+ for(;i<rays.rayEnd;i++) {
+ float tmin = 1e-5f;
+ float tmax = rays.getMinT(i);
+
+ for (int c = 0; c < 3; c++) {
+ float t0 = (box[0][c] - rays.getOrigin(i,c)) *
rays.getInverseDirection(i,c);
+ float t1 = (box[1][c] - rays.getOrigin(i,c)) *
rays.getInverseDirection(i,c);
+
+ float near = (t0 < t1) ? t0 : t1;
+ float far = (t0 < t1) ? t1 : t0;
+ tmin = (tmin < near) ? near : tmin; // max of tmin, near
+ tmax = (far < tmax) ? far : tmax; // min of tmax, far
+ }
+ if (tmin <= tmax) { // valid intersection
+ *out_tmin = tmin;
+ return i;
+ }
+ }
+ }
+ return rays.end();
+#else
+ for (int i = rays.begin(); i < rays.end(); i++) {
+ float tmin = 1e-5f;
+ float tmax = rays.getMinT(i);
+
+ for (int c = 0; c < 3; c++) {
+ float t0 = (box[0][c] - rays.getOrigin(i,c)) *
rays.getInverseDirection(i,c);
+ float t1 = (box[1][c] - rays.getOrigin(i,c)) *
rays.getInverseDirection(i,c);
+
+ float near = (t0 < t1) ? t0 : t1;
+ float far = (t0 < t1) ? t1 : t0;
+ tmin = (tmin < near) ? near : tmin; // max of tmin, near
+ tmax = (far < tmax) ? far : tmax; // min of tmax, far
+ }
+ if (tmin <= tmax) { // valid intersection
+ *out_tmin = tmin;
+ return i;
+ }
+
+ if (i == rays.begin()) {
+ // try a frustum miss
+ float tmin_frustum = 1e-5;
+ float tmax_frustum = FLT_MAX;
+
+ for (int axis = 0; axis < 3; axis++) {
+ // the subtraction is really (boxIA + -orgIA)
+ // or boxIA + [-max_org, -min_org]
+ // [box_min, box_max] + [-max_org, -min_org]
+ float a = box[0][axis]-ia_data.max_org[axis];
+ float b = box[1][axis]-ia_data.min_org[axis];
+
+ // now for multiplication
+ float ar0 = a * ia_data.min_rcp[axis];
+ float ar1 = a * ia_data.max_rcp[axis];
+ float br0 = b * ia_data.min_rcp[axis];
+ float br1 = b * ia_data.max_rcp[axis];
+
+ // [a,b] is valid intersection interval so a is min
+ // and b is max t-value
+
+ //a = std::min(ar0, std::min(ar1, std::min(br0, br1)));
+ a = (br0 < br1) ? br0 : br1;
+ a = (a < ar1) ? a : ar1;
+ a = (a < ar0) ? a : ar0;
+
+ //b = std::max(ar0, std::max(ar1, std::max(br0, br1)));
+ b = (br0 < br1) ? br1 : br0;
+ b = (b < ar1) ? ar1 : b;
+ b = (b < ar0) ? ar0 : b;
+
+ tmin_frustum = (tmin_frustum < a) ? a : tmin_frustum;
+ tmax_frustum = (tmax_frustum > b) ? b : tmax_frustum;
+ }
+
+ // frustum exit
+ if (tmin_frustum > tmax_frustum) {
+ return rays.end();
+ }
+ }
+ }
+ return rays.end();
#endif
}
// return the last index which hits the box
int DynBVH::lastIntersects(const BBox& box, const RayPacket& rays) const
{
- // TODO(boulos): Consider adding SIMD march here too
- for (int ray = rays.end() - 1; ray > rays.begin(); ray-- )
+ // TODO(boulos): Consider adding SIMD march here too
+ for (int ray = rays.end() - 1; ray > rays.begin(); ray-- )
{
- float maximum_minimum = 1e-5;
- float minimum_maximum = rays.getMinT(ray);
+ float maximum_minimum = 1e-5;
+ float minimum_maximum = rays.getMinT(ray);
+
+ float x_minimum = (box[rays.getSign(ray,0)][0] -
rays.getOrigin(ray,0)) * rays.getInverseDirection(ray,0);
+ float x_maximum = (box[1-rays.getSign(ray,0)][0] -
rays.getOrigin(ray,0)) * rays.getInverseDirection(ray,0);
- float x_minimum = (box[rays.getSign(ray,0)][0] -
rays.getOrigin(ray,0)) * rays.getInverseDirection(ray,0);
- float x_maximum = (box[1-rays.getSign(ray,0)][0] -
rays.getOrigin(ray,0)) * rays.getInverseDirection(ray,0);
+ float y_minimum = (box[rays.getSign(ray,1)][1] -
rays.getOrigin(ray,1)) * rays.getInverseDirection(ray,1);
+ float y_maximum = (box[1-rays.getSign(ray,1)][1] -
rays.getOrigin(ray,1)) * rays.getInverseDirection(ray,1);
- float y_minimum = (box[rays.getSign(ray,1)][1] -
rays.getOrigin(ray,1)) * rays.getInverseDirection(ray,1);
- float y_maximum = (box[1-rays.getSign(ray,1)][1] -
rays.getOrigin(ray,1)) * rays.getInverseDirection(ray,1);
+ float z_minimum = (box[rays.getSign(ray,2)][2] -
rays.getOrigin(ray,2)) * rays.getInverseDirection(ray,2);
+ float z_maximum = (box[1-rays.getSign(ray,2)][2] -
rays.getOrigin(ray,2)) * rays.getInverseDirection(ray,2);
- float z_minimum = (box[rays.getSign(ray,2)][2] -
rays.getOrigin(ray,2)) * rays.getInverseDirection(ray,2);
- float z_maximum = (box[1-rays.getSign(ray,2)][2] -
rays.getOrigin(ray,2)) * rays.getInverseDirection(ray,2);
-
- if ( minimum_maximum < x_minimum ||
- maximum_minimum > x_maximum )
- continue;
- if ( minimum_maximum > x_maximum )
- minimum_maximum = x_maximum;
- if ( maximum_minimum < x_minimum )
- maximum_minimum = x_minimum;
- if ( minimum_maximum < y_minimum ||
- maximum_minimum > y_maximum )
- continue;
- if ( minimum_maximum > y_maximum )
- minimum_maximum = y_maximum;
- if ( maximum_minimum < y_minimum )
- maximum_minimum = y_minimum;
-
- if ( minimum_maximum >= z_minimum &&
- maximum_minimum <= z_maximum )
- return ray; // found a hit
+ if ( minimum_maximum < x_minimum ||
+ maximum_minimum > x_maximum )
+ continue;
+ if ( minimum_maximum > x_maximum )
+ minimum_maximum = x_maximum;
+ if ( maximum_minimum < x_minimum )
+ maximum_minimum = x_minimum;
+ if ( minimum_maximum < y_minimum ||
+ maximum_minimum > y_maximum )
+ continue;
+ if ( minimum_maximum > y_maximum )
+ minimum_maximum = y_maximum;
+ if ( maximum_minimum < y_minimum )
+ maximum_minimum = y_minimum;
+
+ if ( minimum_maximum >= z_minimum &&
+ maximum_minimum <= z_maximum )
+ return ray; // found a hit
}
- return rays.begin();
+ return rays.begin();
+}
+
+void DynBVH::setGroup(Group* new_group) {
+ if (new_group != currGroup)
+ group_changed = true;
+ currGroup = new_group;
}
void DynBVH::preprocess(const PreprocessContext& context)
{
- if (currGroup)
+ //cerr << MANTA_FUNC << endl;
+ // First preprocess the underlying group (so for example the
+ // positions of underlying WaldTriangles are correct)
+ if (currGroup) {
currGroup->preprocess(context);
+
+ // Call rebuild (may call update underneath)
+ rebuild(context.proc, context.numProcs);
+
+ // NOTE(boulos): We allow rebuild to set the group_changed flag so
+ // that you're not required to call preprocess in order to do an
+ // update/rebuild.
+ }
}
void DynBVH::update(int proc, int numProcs) {
PreprocessContext context;
parallelUpdateBounds(context, proc, numProcs);
+ // TODO(boulos): Wait until everyone has gone through update to
+ // disable group_changed (requires another barrier)
+ if (proc == 0)
+ group_changed = false;
}
-void DynBVH::rebuild(Group *group, int proc, int numProcs)
+void DynBVH::rebuild(int proc, int numProcs)
{
- // if (proc > 0) return; //TODO: make this parallel (at least some of it).
-
- //for now we rebuild if the number of primitives is different and
- //update otherwise. This of course isn't always best, so if someone
- //wants to improve on that, go for it.
- PreprocessContext context;
-
- if(currGroup && currGroup->size() == group->size()) {
- currGroup = group;
- parallelUpdateBounds(context, proc, numProcs);
+ if (!group_changed) {
+ update(proc, numProcs);
+ return;
}
- else {
- if (proc > 0) return;
-
- cerr << "\nDynBVH::preprocess START\n";
- double start = SCIRun::Time::currentSeconds();
-
- if(group->size() > object_ids.size()) {
- nodes.resize(2*group->size());
- object_ids.resize(group->size());
- // TODO(boulos): Free these after construction? or keep around
- // for rebuild?
- obj_bounds.resize(group->size());
- obj_centroids.resize(group->size());
- }
-
-
- currGroup = group;
+ PreprocessContext context;
- for ( size_t i = 0; i < currGroup->size(); i++ ) {
- object_ids[i] = i;
- currGroup->get(i)->computeBounds(context, obj_bounds[i]);
- obj_centroids[i] = obj_bounds[i].center();
- }
+ // TODO(boulos/bigler/thiago/wald/sparker): Parallel rebuild ;)
+ if (proc > 0) return;
- num_nodes = 1; // root node
- int nextFree = 1;
- double build_start = SCIRun::Time::currentSeconds();
- build(context, 0, 0, currGroup->size(), nextFree);
- double updateBound_start = SCIRun::Time::currentSeconds();
- updateBounds(context, 0);
- double end = SCIRun::Time::currentSeconds();
- cerr << "\nDynBVH build time: Total ("<<end-start<<")\n"
- << "object_ids initialization ("<<build_start-start<<")\n"
- << "build ("<<updateBound_start-build_start<<")\n"
- << "updateBounds ("<<end-updateBound_start<<")\n"
- << "BBox = ("<<nodes[0].bounds.getMin()<<",
"<<nodes[0].bounds.getMax()<<"\n\n";
+ cerr << "\nDynBVH::preprocess START (" << currGroup->size() << "
objects)\n";
+ double start = SCIRun::Time::currentSeconds();
+ if(currGroup->size() > object_ids.size()) {
+ nodes.resize(2*currGroup->size());
+ object_ids.resize(currGroup->size());
+ // TODO(boulos): Free these after construction? or keep around
+ // for rebuild?
+ obj_bounds.resize(currGroup->size());
+ obj_centroids.resize(currGroup->size());
+ }
+ for ( size_t i = 0; i < currGroup->size(); i++ ) {
+ object_ids[i] = i;
+ currGroup->get(i)->computeBounds(context, obj_bounds[i]);
+ obj_centroids[i] = obj_bounds[i].center();
}
+
+ num_nodes = 1; // root node
+ int nextFree = 1;
+ double build_start = SCIRun::Time::currentSeconds();
+ build(context, 0, 0, currGroup->size(), nextFree);
+ double updateBound_start = SCIRun::Time::currentSeconds();
+ updateBounds(context, 0);
+ double end = SCIRun::Time::currentSeconds();
+ cerr << "\nDynBVH build time: Total ("<<end-start<<")\n"
+ << "object_ids initialization ("<<build_start-start<<")\n"
+ << "build ("<<updateBound_start-build_start<<")\n"
+ << "updateBounds ("<<end-updateBound_start<<")\n"
+ << "BBox = ("<<nodes[0].bounds.getMin()<<",
"<<nodes[0].bounds.getMax()<<")\n\n";
+
+ // NOTE(boulos): As of 17-Aug-2007 we don't have a parallel build so
+ // this is implicity proc0 anyway and requires no barrier.
+ group_changed = false;
}
void DynBVH::build(const PreprocessContext& context,
@@ -488,63 +509,58 @@
int& nextFree, int depth)
{
- if (objectEnd <= objectBegin)
- {
- printf("ERROR! Tried building BVH over
%d,%d\n",objectBegin,objectEnd);
- exit(-1);
- }
+ if (objectEnd <= objectBegin) {
+ printf("ERROR! Tried building BVH over %d,%d\n",objectBegin,objectEnd);
+ exit(-1);
+ }
- BVHNode& node = nodes[nodeID];
+ BVHNode& node = nodes[nodeID];
- int bestAxis = -1;
- int split = -1;
+ int bestAxis = -1;
+ int split = -1;
-#if USE_APPROXIMATE_BUILD // 30% slower for certain datasets.
- int num_objects = objectEnd - objectBegin;
- if (num_objects < 32) {
- split = partitionSAH(context, objectBegin,objectEnd,bestAxis);
- } else {
- split = partitionApproxSAH(context, objectBegin,objectEnd,bestAxis);
- }
-#else
+ // NOTE(abe): 30% slower rendering for a single CAD dataset.
+#if USE_APPROXIMATE_BUILD
+ int num_objects = objectEnd - objectBegin;
+ if (num_objects < 32) {
split = partitionSAH(context, objectBegin,objectEnd,bestAxis);
+ } else {
+ split = partitionApproxSAH(context, objectBegin,objectEnd,bestAxis);
+ }
+#else
+ split = partitionSAH(context, objectBegin,objectEnd,bestAxis);
#endif
- if (bestAxis == -1)
- {
- // make leaf
- node.makeLeaf(objectBegin, objectEnd-objectBegin);
-
-
std::sort(object_ids.begin()+objectBegin,object_ids.begin()+objectEnd);
+ if (bestAxis == -1) {
+ // make leaf
+ node.makeLeaf(objectBegin, objectEnd-objectBegin);
- num_nodes++;
- }
- else
- {
- // make internal node
- node.makeInternal(nextFree, bestAxis);
- num_nodes++;
- // allocate two spots
- nextFree += 2;
+ std::sort(object_ids.begin()+objectBegin,object_ids.begin()+objectEnd);
- build(context, node.child+0,objectBegin,split,nextFree,depth+1);
- build(context, node.child+1, split, objectEnd,nextFree,depth+1);
- }
+ num_nodes++;
+ } else {
+ // make internal node
+ node.makeInternal(nextFree, bestAxis);
+ num_nodes++;
+ // allocate two spots
+ nextFree += 2;
- if (depth == 0)
- {
- printf("DynBVH Build Complete\n");
- }
+ build(context, node.child+0,objectBegin,split,nextFree,depth+1);
+ build(context, node.child+1, split, objectEnd,nextFree,depth+1);
+ }
+ if (depth == 0) {
+ printf("DynBVH Build Complete (used %d nodes)\n", nextFree);
+ }
}
void DynBVH::parallelUpdateBounds(const PreprocessContext& context,
int proc, int numProcs)
{
//XXXX this is super naive hackish code! FIXME!
- if (numProcs == 1)
+ if (numProcs == 1) {
updateBounds(context, 0);
- else {
+ } else {
BVHNode& node = nodes[0];
int left_son = node.child;
int right_son = left_son + 1;
@@ -566,35 +582,31 @@
void DynBVH::updateBounds(const PreprocessContext& context, int ID)
{
- BVHNode& node = nodes[ID];
- if (node.isLeaf())
- {
- node.bounds.reset();
- for (int i = 0; i < node.children; i++ )
- {
- BBox temp;
- int obj_id = object_ids[node.child + i];
- currGroup->get(obj_id)->computeBounds(context,temp);
+ BVHNode& node = nodes[ID];
+ if (node.isLeaf()) {
+ node.bounds.reset();
+ for (int i = 0; i < node.children; i++ ) {
+ BBox temp;
+ int obj_id = object_ids[node.child + i];
+ currGroup->get(obj_id)->computeBounds(context,temp);
- node.bounds.extendByBox(temp);
- }
- node.axis = 0;
- node.axis_sign = 0;
+ node.bounds.extendByBox(temp);
}
- else
- {
- int left_son = node.child;
- int right_son = left_son + 1;
- updateBounds(context, left_son);
- updateBounds(context, right_son);
-
- node.bounds.reset();
- const BVHNode& left_node = nodes[left_son];
- const BVHNode& right_node = nodes[right_son];
+ node.axis = 0;
+ node.axis_sign = 0;
+ } else {
+ int left_son = node.child;
+ int right_son = left_son + 1;
+ updateBounds(context, left_son);
+ updateBounds(context, right_son);
- node.bounds.extendByBox(left_node.bounds);
- node.bounds.extendByBox(right_node.bounds);
- }
+ node.bounds.reset();
+ const BVHNode& left_node = nodes[left_son];
+ const BVHNode& right_node = nodes[right_son];
+
+ node.bounds.extendByBox(left_node.bounds);
+ node.bounds.extendByBox(right_node.bounds);
+ }
}
int DynBVH::partitionApproxSAH(const PreprocessContext& context,
@@ -753,73 +765,61 @@
int DynBVH::partitionSAH(const PreprocessContext& context,
int objBegin, int objEnd, int& output_axis)
{
- int num_objects = objEnd - objBegin;
- if ( num_objects == 1 )
- {
- output_axis = -1;
- return -1;
- }
+ int num_objects = objEnd - objBegin;
+ if ( num_objects == 1 ) {
+ output_axis = -1;
+ return -1;
+ }
- BVHCostEval best_cost;
- best_cost.cost = BVH_C_isec * num_objects;
- best_cost.axis = -1;
- best_cost.position = FLT_MAX;
- best_cost.event = -1;
+ BVHCostEval best_cost;
+ best_cost.cost = BVH_C_isec * num_objects;
+ best_cost.axis = -1;
+ best_cost.position = FLT_MAX;
+ best_cost.event = -1;
- for ( int axis = 0; axis < 3; axis++ )
- {
- BVHCostEval new_cost;
- if ( buildEvents(context, objBegin,objEnd,axis,new_cost) )
- {
- if ( new_cost.cost < best_cost.cost )
- {
- best_cost = new_cost;
- }
- }
+ for ( int axis = 0; axis < 3; axis++ ) {
+ BVHCostEval new_cost;
+ if ( buildEvents(context, objBegin,objEnd,axis,new_cost) ) {
+ if ( new_cost.cost < best_cost.cost ) {
+ best_cost = new_cost;
+ }
}
+ }
- output_axis = best_cost.axis;
- if ( output_axis != -1 )
- {
- // build the events and sort them
- std::vector<BVHSAHEvent> events;
- for ( int i = objBegin; i < objEnd; i++ )
- {
- BVHSAHEvent new_event;
- BBox tri_box;
- currGroup->get(object_ids[i])->computeBounds(context, tri_box);
- new_event.position = tri_box.center()[output_axis];
- new_event.obj_id = object_ids[i];
- events.push_back(new_event);
- }
+ output_axis = best_cost.axis;
+ if ( output_axis != -1 ) {
+ // build the events and sort them
+ std::vector<BVHSAHEvent> events;
+ for ( int i = objBegin; i < objEnd; i++ ) {
+ BVHSAHEvent new_event;
+ BBox tri_box;
+ currGroup->get(object_ids[i])->computeBounds(context, tri_box);
+ new_event.position = tri_box.center()[output_axis];
+ new_event.obj_id = object_ids[i];
+ events.push_back(new_event);
+ }
- std::sort(events.begin(), events.end(), CompareBVHSAHEvent());
+ std::sort(events.begin(), events.end(), CompareBVHSAHEvent());
- for ( int i = objBegin; i < objEnd; i++ )
- {
- object_ids[i] = events[i-objBegin].obj_id;
- }
+ for ( int i = objBegin; i < objEnd; i++ ) {
+ object_ids[i] = events[i-objBegin].obj_id;
+ }
- int result = objBegin + best_cost.event;
+ int result = objBegin + best_cost.event;
- if ( result == objBegin || result == objEnd )
- {
- if ( num_objects < 8 )
- {
- output_axis = -1;
- return 0;
- }
- result = objBegin + num_objects/2;
- return result;
- }
- else
- return result;
- }
- else
- {
- return 0; // making a leaf anyway
+ if ( result == objBegin || result == objEnd ) {
+ if ( num_objects < 8 ) {
+ output_axis = -1;
+ return 0;
+ }
+ result = objBegin + num_objects/2;
+ return result;
+ } else {
+ return result;
}
+ }
+ return 0; // making a leaf anyway
}
bool DynBVH::buildEvents(const PreprocessContext& context,
@@ -828,78 +828,72 @@
int axis,
BVHCostEval& best_eval)
{
- BBox overall_box;
- std::vector<BVHSAHEvent> events;
- for ( int i = first; i < last; i++ )
- {
- BVHSAHEvent new_event;
- BBox tri_box;
- currGroup->get(object_ids[i])->computeBounds(context, tri_box);
- new_event.position = tri_box.center()[axis];
- new_event.obj_id = object_ids[i];
- events.push_back(new_event);
-
- overall_box.extendByBox(tri_box);
- }
-
- std::sort(events.begin(),events.end(),CompareBVHSAHEvent());
-
- int num_events = int(events.size());
- BBox left_box;
-
- int num_left = 0;
- int num_right = num_events;
+ BBox overall_box;
+ std::vector<BVHSAHEvent> events;
+ for ( int i = first; i < last; i++ ) {
+ BVHSAHEvent new_event;
+ BBox tri_box;
+ currGroup->get(object_ids[i])->computeBounds(context, tri_box);
+ new_event.position = tri_box.center()[axis];
+ new_event.obj_id = object_ids[i];
+ events.push_back(new_event);
- for ( size_t i = 0; i < events.size(); i++ )
- {
- events[i].num_left = num_left;
- events[i].num_right = num_right;
- events[i].left_area = left_box.computeArea();
-
- BBox tri_box;
- currGroup->get(events[i].obj_id)->computeBounds(context, tri_box);
- left_box.extendByBox(tri_box);
+ overall_box.extendByBox(tri_box);
+ }
- num_left++;
- num_right--;
- }
+ std::sort(events.begin(),events.end(),CompareBVHSAHEvent());
- BBox right_box;
+ int num_events = int(events.size());
+ BBox left_box;
- best_eval.cost = FLT_MAX;
- best_eval.event = -1;
+ int num_left = 0;
+ int num_right = num_events;
- for ( int i = num_events - 1; i >= 0; i-- )
- {
- BBox tri_box;
- currGroup->get(events[i].obj_id)->computeBounds(context, tri_box);
+ for ( size_t i = 0; i < events.size(); i++ ) {
+ events[i].num_left = num_left;
+ events[i].num_right = num_right;
+ events[i].left_area = left_box.computeArea();
- right_box.extendByBox(tri_box);
+ BBox tri_box;
+ currGroup->get(events[i].obj_id)->computeBounds(context, tri_box);
+ left_box.extendByBox(tri_box);
- if ( events[i].num_left > 0 && events[i].num_right > 0 )
- {
- events[i].right_area = right_box.computeArea();
+ num_left++;
+ num_right--;
+ }
- float this_cost = (events[i].num_left * events[i].left_area +
- events[i].num_right * events[i].right_area);
- this_cost /= overall_box.computeArea();
- this_cost *= BVH_C_isec;
- this_cost += BVH_C_trav;
+ BBox right_box;
- events[i].cost = this_cost;
- if ( this_cost < best_eval.cost )
- {
- best_eval.cost = this_cost;
- best_eval.position = events[i].position;
- best_eval.axis = axis;
- best_eval.event = i;
- best_eval.num_left = events[i].num_left;
- best_eval.num_right = events[i].num_right;
+ best_eval.cost = FLT_MAX;
+ best_eval.event = -1;
- }
- }
+ for ( int i = num_events - 1; i >= 0; i-- ) {
+ BBox tri_box;
+ currGroup->get(events[i].obj_id)->computeBounds(context, tri_box);
+
+ right_box.extendByBox(tri_box);
+
+ if ( events[i].num_left > 0 && events[i].num_right > 0 ) {
+ events[i].right_area = right_box.computeArea();
+
+ float this_cost = (events[i].num_left * events[i].left_area +
+ events[i].num_right * events[i].right_area);
+ this_cost /= overall_box.computeArea();
+ this_cost *= BVH_C_isec;
+ this_cost += BVH_C_trav;
+
+ events[i].cost = this_cost;
+ if ( this_cost < best_eval.cost ) {
+ best_eval.cost = this_cost;
+ best_eval.position = events[i].position;
+ best_eval.axis = axis;
+ best_eval.event = i;
+ best_eval.num_left = events[i].num_left;
+ best_eval.num_right = events[i].num_right;
+ }
}
- return best_eval.event != -1;
+ }
+ return best_eval.event != -1;
}
@@ -1362,11 +1356,11 @@
}
const __m128 tBoxFarX =
_mm_mul_ps(_mm_load_ps(&data->inverseDirection[0][i]),
- far_minus_org_x);
+ far_minus_org_x);
const __m128 tBoxFarY =
_mm_mul_ps(_mm_load_ps(&data->inverseDirection[1][i]),
- far_minus_org_y);
+ far_minus_org_y);
const __m128 tBoxFarZ =
_mm_mul_ps(_mm_load_ps(&data->inverseDirection[2][i]),
- far_minus_org_z);
+ far_minus_org_z);
t1 = _mm_min_ps(t1, tBoxFarX);
t1 = _mm_min_ps(t1, tBoxFarY);
@@ -1430,11 +1424,11 @@
}
const __m128 tBoxFarX =
_mm_mul_ps(_mm_load_ps(&data->inverseDirection[0][i]),
- far_minus_org_x);
+ far_minus_org_x);
const __m128 tBoxFarY =
_mm_mul_ps(_mm_load_ps(&data->inverseDirection[1][i]),
- far_minus_org_y);
+ far_minus_org_y);
const __m128 tBoxFarZ =
_mm_mul_ps(_mm_load_ps(&data->inverseDirection[2][i]),
- far_minus_org_z);
+ far_minus_org_z);
t1 = _mm_min_ps(t1, tBoxFarX);
t1 = _mm_min_ps(t1, tBoxFarY);
Modified: trunk/Model/Groups/DynBVH.h
==============================================================================
--- trunk/Model/Groups/DynBVH.h (original)
+++ trunk/Model/Groups/DynBVH.h Mon Aug 20 17:26:40 2007
@@ -10,170 +10,173 @@
namespace Manta
{
- class DynBVH : public AccelerationStructure
+ class DynBVH : public AccelerationStructure
+ {
+ protected:
+ struct IAData
{
- protected:
- struct IAData
- {
- Real min_rcp[3];
- Real max_rcp[3];
- Real min_org[3];
- Real max_org[3];
- Real min_org_rcp[3];
- Real max_org_rcp[3];
- };
-
- struct BVHNode
- {
- BBox bounds;
- int child; // my child
- unsigned char axis; // 0 = x, 1 = y, 2 = z,
- unsigned char axis_sign; // 0 means left-right, 1 means
right-left
- short children; // num children
-
- // 24 bytes + 4 bytes + 1 + 1 + 2 = 32 bytes
-
- inline void makeLeaf(int first_child, short num_children)
- {
- child = first_child;
- children = num_children;
- axis = 0;
- axis_sign = 0;
- }
-
- inline void makeInternal(int first_child, unsigned char _axis)
- {
- child = first_child;
- children = 0;
- axis = _axis;
- axis_sign = 0; // for now
- }
-
- inline bool isLeaf() const
- {
- return children != 0;
- }
-
- };
-
- vector<BVHNode> nodes;
- vector<unsigned int> object_ids;
- unsigned int num_nodes;
- Group* currGroup;
- SCIRun::Barrier barrier;
-
- vector<BBox> obj_bounds;
- vector<Vector> obj_centroids;
-
-
- public:
- DynBVH() : currGroup(NULL), barrier("DynBVH barrier")
- {}
-
- void preprocess(const PreprocessContext&);
- void intersect(const RenderContext& context, RayPacket& rays) const;
- protected:
- void intersectNode(int nodeID, const RenderContext& context,
RayPacket& rays, const IAData& ia_data) const;
-
-
- // return the first index (between [rays.begin(),rays.end()]) which
hits the box
- int firstIntersects(const BBox& box, const RayPacket& rays, const
IAData& ia_data, float* out_tmin) const;
- // return the last index which hits the box
- int lastIntersects(const BBox& box, const RayPacket& rays) const;
-
- public:
- void computeBounds(const PreprocessContext&,
- BBox& bbox) const
- {
- if (num_nodes)
- bbox.extendByBox(nodes[0].bounds);
- }
-
- //Is this used by anyone?
-// static Group* create(const vector<string>&)
-// {
-// return new DynBVH();
-// }
- void update(int proc=0, int numProcs=1);
- void rebuild(Group *group, int proc=0, int numProcs=1);
-
- void build(const PreprocessContext& context,
- int nodeID, int objectBegin, int objectEnd,
- int &nextFree, int depth = 0);
-
- void parallelUpdateBounds(const PreprocessContext& context,
- int proc, int numProcs);
- void updateBounds(const PreprocessContext& context, int ID = 0);
-
-
- protected:
- int partitionSAH(const PreprocessContext& context,
- int objBegin, int objEnd, int& output_axis);
- int partitionApproxSAH(const PreprocessContext& context,
- int objBegin,
- int objEnd,
- int& output_axis);
-
- struct BVHCostEval
- {
- float position;
- float cost;
- int num_left;
- int num_right;
- int event;
- int axis;
- };
-
- struct BVHSAHEvent
- {
- float position;
- int obj_id;
- float left_area;
- float right_area;
- int num_left;
- int num_right;
- float cost;
- };
-
- struct CompareBVHSAHEvent
- {
- bool operator()(const BVHSAHEvent& x, const BVHSAHEvent& y)
- {
- // add obj_id sorting in here automatically?
- return x.position < y.position;
- }
- };
-
- bool buildEvents(const PreprocessContext& context,
- int first,
- int last,
- int axis,
- BVHCostEval& eval);
+ Real min_rcp[3];
+ Real max_rcp[3];
+ Real min_org[3];
+ Real max_org[3];
+ Real min_org_rcp[3];
+ Real max_org_rcp[3];
+ };
+
+ struct BVHNode
+ {
+ BBox bounds;
+ int child; // my child
+ unsigned char axis; // 0 = x, 1 = y, 2 = z,
+ unsigned char axis_sign; // 0 means left-right, 1 means right-left
+ short children; // num children
+
+ // 24 bytes + 4 bytes + 1 + 1 + 2 = 32 bytes
+
+ inline void makeLeaf(int first_child, short num_children)
+ {
+ child = first_child;
+ children = num_children;
+ axis = 0;
+ axis_sign = 0;
+ }
+
+ inline void makeInternal(int first_child, unsigned char _axis)
+ {
+ child = first_child;
+ children = 0;
+ axis = _axis;
+ axis_sign = 0; // for now
+ }
+
+ inline bool isLeaf() const
+ {
+ return children != 0;
+ }
+
+ };
+
+ vector<BVHNode> nodes;
+ vector<unsigned int> object_ids;
+ unsigned int num_nodes;
+ Group* currGroup;
+ bool group_changed;
+ SCIRun::Barrier barrier;
+
+ vector<BBox> obj_bounds;
+ vector<Vector> obj_centroids;
+
+
+ public:
+ DynBVH() : currGroup(NULL), group_changed(false), barrier("DynBVH
barrier")
+ {}
+
+ void setGroup(Group* new_group);
+
+ void preprocess(const PreprocessContext&);
+ void intersect(const RenderContext& context, RayPacket& rays) const;
+ protected:
+ void intersectNode(int nodeID, const RenderContext& context, RayPacket&
rays, const IAData& ia_data) const;
+
+
+ // return the first index (between [rays.begin(),rays.end()]) which hits
the box
+ int firstIntersects(const BBox& box, const RayPacket& rays, const
IAData& ia_data, float* out_tmin) const;
+ // return the last index which hits the box
+ int lastIntersects(const BBox& box, const RayPacket& rays) const;
+
+ public:
+ void computeBounds(const PreprocessContext&,
+ BBox& bbox) const
+ {
+ if (num_nodes)
+ bbox.extendByBox(nodes[0].bounds);
+ }
+
+ //Is this used by anyone?
+ // static Group* create(const vector<string>&)
+ // {
+ // return new DynBVH();
+ // }
+ void update(int proc=0, int numProcs=1);
+ void rebuild(int proc=0, int numProcs=1);
+
+ void build(const PreprocessContext& context,
+ int nodeID, int objectBegin, int objectEnd,
+ int &nextFree, int depth = 0);
+
+ void parallelUpdateBounds(const PreprocessContext& context,
+ int proc, int numProcs);
+ void updateBounds(const PreprocessContext& context, int ID = 0);
+
+
+ protected:
+ int partitionSAH(const PreprocessContext& context,
+ int objBegin, int objEnd, int& output_axis);
+ int partitionApproxSAH(const PreprocessContext& context,
+ int objBegin,
+ int objEnd,
+ int& output_axis);
+
+ struct BVHCostEval
+ {
+ float position;
+ float cost;
+ int num_left;
+ int num_right;
+ int event;
+ int axis;
+ };
+
+ struct BVHSAHEvent
+ {
+ float position;
+ int obj_id;
+ float left_area;
+ float right_area;
+ int num_left;
+ int num_right;
+ float cost;
+ };
+
+ struct CompareBVHSAHEvent
+ {
+ bool operator()(const BVHSAHEvent& x, const BVHSAHEvent& y)
+ {
+ // add obj_id sorting in here automatically?
+ return x.position < y.position;
+ }
+ };
+
+ bool buildEvents(const PreprocessContext& context,
+ int first,
+ int last,
+ int axis,
+ BVHCostEval& eval);
#ifdef MANTA_SSE
- // DynBVH ports
- void templatedTraverse(const RenderContext& context, RayPacket&
packet) const;
+ // DynBVH ports
+ void templatedTraverse(const RenderContext& context, RayPacket& packet)
const;
- int firstActivePort(RayPacket& packet, int firstActive, const BBox&
box) const;
- int lastActivePort(RayPacket& packet, int firstActive, const BBox&
box) const;
+ int firstActivePort(RayPacket& packet, int firstActive, const BBox& box)
const;
+ int lastActivePort(RayPacket& packet, int firstActive, const BBox& box)
const;
- int firstActiveSameSignFrustumPort(RayPacket& packet,
- const int firstActive,
- const BBox& bounds,
- const int signs[3],
- const __m128 sc_min_org[3],
- const __m128 sc_max_org[3],
- const __m128 sc_min_rcp[3],
- const __m128 sc_max_rcp[3],
- const __m128& max_t) const;
-
- int lastThatIntersectsSameSignPort(RayPacket& packet,
- const int firstActive,
- const BBox& box,
- const int signs[3]) const;
+ int firstActiveSameSignFrustumPort(RayPacket& packet,
+ const int firstActive,
+ const BBox& bounds,
+ const int signs[3],
+ const __m128 sc_min_org[3],
+ const __m128 sc_max_org[3],
+ const __m128 sc_min_rcp[3],
+ const __m128 sc_max_rcp[3],
+ const __m128& max_t) const;
+
+ int lastThatIntersectsSameSignPort(RayPacket& packet,
+ const int firstActive,
+ const BBox& box,
+ const int signs[3]) const;
#endif
- };
+ };
};
#endif
Modified: trunk/Model/Groups/GriddedGroup.cc
==============================================================================
--- trunk/Model/Groups/GriddedGroup.cc (original)
+++ trunk/Model/Groups/GriddedGroup.cc Mon Aug 20 17:26:40 2007
@@ -1,5 +1,6 @@
#include <Model/Groups/GriddedGroup.h>
+#include <Interface/Context.h>
#include <Interface/RayPacket.h>
#include <Core/Exceptions/IllegalArgument.h>
#include <Core/Exceptions/InternalError.h>
@@ -65,6 +66,9 @@
BBox bbox;
Group::computeBounds(context,bbox);
+ // NOTE(boulos): I think the computebounds could easily end up being
+ // parallel, so I'll let the threads get to here?
+ if (context.proc != 0) { context.done(); return; }
min = bbox.getMin();
max = bbox.getMax();
@@ -157,6 +161,7 @@
double dt = Time::currentSeconds()-start;
cerr << "GriddedGroup: " << numObjects << " objects, targeted cells: " <<
target_numcells << ", actual cells: " << totalcells << ", " << nx << "x" <<
ny << "x" << nz << ", built in " << dt << " seconds\n";
+ context.done();
}
void GriddedGroup::intersect( const RenderContext &context, RayPacket &rays
) const
Modified: trunk/Model/Groups/Group.cc
==============================================================================
--- trunk/Model/Groups/Group.cc (original)
+++ trunk/Model/Groups/Group.cc Mon Aug 20 17:26:40 2007
@@ -1,8 +1,12 @@
+#include <Core/Util/Preprocessor.h>
#include <Interface/Context.h>
#include <Model/Groups/Group.h>
#include <SCIRun/Core/Util/Assert.h>
#include <algorithm>
+#include <iostream>
+using std::cerr;
+using std::endl;
using namespace Manta;
@@ -153,11 +157,17 @@
void Group::preprocess(const PreprocessContext& context)
{
//partition so that objs are serial and then parallel
- parallelSplit = partition(objs.begin(), objs.end(), isSerial);
+ if (context.proc == 0)
+ parallelSplit = partition(objs.begin(), objs.end(), isSerial);
+ // NOTE(boulos): This is actually a barrier wait, and it's important
+ // to use that here since we don't want the objs changing underneath
+ // us for other threads
+ context.done();
for(vector<Object*>::iterator iter = objs.begin(); iter != objs.end();
++iter)
(*iter)->preprocess(context);
dirtybbox = true;
+ context.done();
}
void Group::computeBounds(const PreprocessContext& context, BBox& bbox) const
Modified: trunk/Model/Groups/Mesh.cc
==============================================================================
--- trunk/Model/Groups/Mesh.cc (original)
+++ trunk/Model/Groups/Mesh.cc Mon Aug 20 17:26:40 2007
@@ -1,5 +1,6 @@
#include <Model/Groups/Mesh.h>
#include <Model/Primitives/WaldTriangle.h>
+#include <Core/Util/Preprocessor.h>
#include <SCIRun/Core/Exceptions/InternalError.h>
using namespace Manta;
@@ -202,7 +203,7 @@
{
for (unsigned int i=0; i < materials.size(); ++i)
materials[i]->preprocess(context);
- Group::preprocess(context);
+ Group::preprocess(context);
}
void Mesh::interpolateNormals()
@@ -255,10 +256,10 @@
const Vector& a = vertices[index0];
const Vector& b = vertices[index1];
const Vector& c = vertices[index2];
-
+
//degenerate if triangle is collapsed onto a line or point.
if ( Cross(a-b, c-b) == Vector::zero() ) {
-
+
//this triangle is degenerate. Let's remove it.
vertex_indices[i+0] = vertex_indices[vertex_indices.size()-3];
vertex_indices[i+1] = vertex_indices[vertex_indices.size()-2];
Modified: trunk/Model/Groups/RealisticBvh.cc
==============================================================================
--- trunk/Model/Groups/RealisticBvh.cc (original)
+++ trunk/Model/Groups/RealisticBvh.cc Mon Aug 20 17:26:40 2007
@@ -2,12 +2,12 @@
/*
For more information, please see:
http://software.sci.utah.edu
-
+
The MIT License
-
+
Copyright (c) 2005
Silicon Graphics Inc. Mountain View California.
-
+
License for the specific language governing rights and limitations under
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -15,10 +15,10 @@
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
-
+
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
-
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
@@ -42,18 +42,18 @@
using namespace Manta;
-RealisticBvh::RealisticBvh( Object *child0, Object *child1 ) {
+RealisticBvh::RealisticBvh( Object *child0, Object *child1 ) {
+
+ child[0] = child0;
+ child[1] = child1;
- child[0] = child0;
- child[1] = child1;
-
- PreprocessContext context;
-
- // Update the bounding box of this node.
- child0->computeBounds( context, bounds );
- child1->computeBounds( context, bounds );
-
- split_axis = 0;
+ PreprocessContext context;
+
+ // Update the bounding box of this node.
+ child0->computeBounds( context, bounds );
+ child1->computeBounds( context, bounds );
+
+ split_axis = 0;
}
@@ -66,138 +66,139 @@
void
RealisticBvh::start_build( Object **array, int size ) {
- PreprocessContext context;
-
- // Compute the bounds of the array.
- for (int i=0;i<size;++i) {
- array[i]->computeBounds( context, bounds );
- }
-
- // Check to see if there is only one node.
- if (size == 1) {
- child[0] = child[1] = array[0];
- return;
- }
- if (size == 2) {
- child[0] = array[0];
- child[1] = array[1];
- return;
- }
-
- // Find a pivot point.
- Vector pivot((Vector(bounds[0]) + Vector(bounds[1])) * 0.5);
-
- // Split along the axis.
- int mid_point = qsplit( array, size, pivot[0], 0 );
-
- // Create new left and right children.
- child[0] = build_branch( array, mid_point, 1 );
- child[1] = build_branch( array+mid_point, size-mid_point, 1 );
-
+ PreprocessContext context;
+
+ // Compute the bounds of the array.
+ for (int i=0;i<size;++i) {
+ array[i]->computeBounds( context, bounds );
+ }
+
+ // Check to see if there is only one node.
+ if (size == 1) {
+ child[0] = child[1] = array[0];
+ return;
+ }
+ if (size == 2) {
+ child[0] = array[0];
+ child[1] = array[1];
+ return;
+ }
+
+ // Find a pivot point.
+ Vector pivot((Vector(bounds[0]) + Vector(bounds[1])) * 0.5);
+
+ // Split along the axis.
+ int mid_point = qsplit( array, size, pivot[0], 0 );
+
+ // Create new left and right children.
+ child[0] = build_branch( array, mid_point, 1 );
+ child[1] = build_branch( array+mid_point, size-mid_point, 1 );
+
}
// Rearrange the pointers in the input array around a pivot point.
int RealisticBvh::qsplit( Object **array, int size, Real pivot, int axis ) {
- PreprocessContext context;
+ PreprocessContext context;
+
+ int ret_val = 0;
+ for (int i=0; i<size;++i) {
+
+ // Get the bounds of the object.
+ BBox bounds;
+ array[i]->computeBounds( context, bounds );
+
+ // Find the centroid of those bounds.
+ Real centroid = (bounds[0][axis] + bounds[1][axis]) *
(Real)0.5;
+
+ if (centroid < pivot) {
+ Object *tmp = array[i];
+ array[i] = array[ret_val];
+ array[ret_val] = tmp;
+ ++ret_val;
+ }
+ }
- int ret_val = 0;
- for (int i=0; i<size;++i) {
-
- // Get the bounds of the object.
- BBox bounds;
- array[i]->computeBounds( context, bounds );
-
- // Find the centroid of those bounds.
- Real centroid = (bounds[0][axis] + bounds[1][axis]) *
(Real)0.5;
-
- if (centroid < pivot) {
- Object *tmp = array[i];
- array[i] = array[ret_val];
- array[ret_val] = tmp;
- ++ret_val;
- }
- }
-
- if ((ret_val == 0) || (ret_val == size))
- ret_val = size / 2;
-
- return ret_val;
+ if ((ret_val == 0) || (ret_val == size))
+ ret_val = size / 2;
+
+ return ret_val;
}
Object *RealisticBvh::build_branch( Object **array, int size, int axis ) {
-
- // Check two exit conditions.
- if (size == 1)
- return array[0];
- if (size == 2)
- return new RealisticBvh( array[0], array[1] );
-
- // Create a new node.
- RealisticBvh *new_node = new RealisticBvh();
-
- PreprocessContext context;
-
- // Compute the bounds of the array.
- for (int i=0;i<size;++i) {
- array[i]->computeBounds( context, new_node->bounds );
- }
-
- // Find a pivot point.
- Vector pivot((new_node->bounds[0] + new_node->bounds[1]) * (Real)0.5);
-
- // Split along the axis.
- int mid_point = qsplit( array, size, pivot[axis], axis );
-
- // save the split axis.
- new_node->split_axis = axis;
-
- // Create new left and right children.
- new_node->child[0] = build_branch( array, mid_point, (axis+1)%3 );
- new_node->child[1] = build_branch( array+mid_point, size-mid_point,
(axis+1)%3 );
-
- return new_node;
+
+ // Check two exit conditions.
+ if (size == 1)
+ return array[0];
+ if (size == 2)
+ return new RealisticBvh( array[0], array[1] );
+
+ // Create a new node.
+ RealisticBvh *new_node = new RealisticBvh();
+
+ PreprocessContext context;
+
+ // Compute the bounds of the array.
+ for (int i=0;i<size;++i) {
+ array[i]->computeBounds( context, new_node->bounds );
+ }
+
+ // Find a pivot point.
+ Vector pivot((new_node->bounds[0] + new_node->bounds[1]) *
(Real)0.5);
+
+ // Split along the axis.
+ int mid_point = qsplit( array, size, pivot[axis], axis );
+
+ // save the split axis.
+ new_node->split_axis = axis;
+
+ // Create new left and right children.
+ new_node->child[0] = build_branch( array, mid_point, (axis+1)%3 );
+ new_node->child[1] = build_branch( array+mid_point, size-mid_point,
(axis+1)%3 );
+
+ return new_node;
}
void RealisticBvh::preprocess(const PreprocessContext& context) {
+ // Build occurs in the constructor.
+ if (child[0])
+ child[0]->preprocess( context );
+
+ if (child[1])
+ child[1]->preprocess( context );
- // Build occurs in the constructor.
- if (child[0])
- child[0]->preprocess( context );
-
- if (child[1])
- child[1]->preprocess( context );
+ context.done();
}
void RealisticBvh::computeBounds(const PreprocessContext& /*context*/,
BBox& bbox) const {
- // Bound the bvh.
- bbox.extendByBox( bounds );
+ // Bound the bvh.
+ bbox.extendByBox( bounds );
}
void RealisticBvh::intersect(const RenderContext& context, RayPacket& rays)
const {
-
- rays.computeInverseDirections();
+
+ rays.computeInverseDirections();
rays.computeSigns();
- // Intersect the ray packet with the bounds of this node.
- bool bbox_intersect[RayPacket::MaxSize];
+ // Intersect the ray packet with the bounds of this node.
+ bool bbox_intersect[RayPacket::MaxSize];
- for(int i=rays.begin();i<rays.end();i++) {
- // Check to see if the ray hits this node's bounding box.
- Real min_t, max_t;
- bbox_intersect[i]
- = Intersection::intersectAaBox( bounds, min_t, max_t, rays.getRay(i),
+ for(int i=rays.begin();i<rays.end();i++) {
+ // Check to see if the ray hits this node's bounding box.
+ Real min_t, max_t;
+ bbox_intersect[i]
+ = Intersection::intersectAaBox( bounds, min_t, max_t, rays.getRay(i),
rays.getSigns(i),
rays.getInverseDirection(i),
(Real)0, rays.getMinT(i) );
- }
+ }
for(int begin=rays.begin(); begin < rays.end(); ){
- // Find the beginning of a run.
- while ((begin < rays.end()) && (!bbox_intersect[begin]))
- ++begin;
+ // Find the beginning of a run.
+ while ((begin < rays.end()) && (!bbox_intersect[begin]))
+ ++begin;
if (begin >= rays.end())
// No box intersections left
Modified: trunk/Model/Groups/private/CGT.cc
==============================================================================
--- trunk/Model/Groups/private/CGT.cc (original)
+++ trunk/Model/Groups/private/CGT.cc Mon Aug 20 17:26:40 2007
@@ -13,6 +13,10 @@
{
}
+void Grid::setGroup(Group* new_group) {
+ currGroup = new_group;
+}
+
void Grid::preprocess(const PreprocessContext& context)
{
context.manta_interface->registerSerialPreRenderCallback(
@@ -33,7 +37,7 @@
#ifdef MAILBOXING
//need to adjust mailboxes if number of threads or number of
//primitives changes
-
+
if (!currGroup) return;
//this could be called from rebuild and the serialPreRenderCallback
@@ -59,7 +63,7 @@
mutex.unlock();
#endif
-}
+}
void Grid::computeBounds(const PreprocessContext& context, BBox& bbox) const
{
@@ -70,10 +74,8 @@
currGroup->computeBounds(context, bbox);
}
-void Grid::rebuild(Group *group, int proc, int numProcs)
+void Grid::rebuild(int proc, int numProcs)
{
- currGroup = group;
-
if (proc == 0) {
startGlobalBuildTime = SCIRun::Time::currentSeconds();
preFrameSetup(proc, numProcs); //currGroup size might have changed
@@ -155,11 +157,11 @@
sse_N = set44(0,N[2],N[1],N[0]);
sse_M = set44(0,M[2],M[1],M[0]);
sse_one_over_N = accurateReciprocal(sse_N);
-
+
scale = accurateReciprocal(diam);
scaleN = mul4(sse_N,accurateReciprocal(diam));
scaleM = mul4(sse_M,accurateReciprocal(diam));
-
+
//If we have a packet wider than X cells we will probably want to split
it.
//lets assume that the values in scaleN are essentially all the same --
so use one.
#define MAX_CELLS_WIDTH 3.0f
@@ -173,7 +175,7 @@
cout << "building grid for " << currGroup->size() << " objects, res =
" << N[0] << "x" << N[1] << "x" << N[2] << endl << "bounds = " << bounds <<
endl;
if (firstTime || DISPLAY_BUILD_TIMES)
- cout << "first stage of grid build : "
+ cout << "first stage of grid build : "
<< (SCIRun::Time::currentSeconds() - startThreadBuildTime)*1e3 <<
"ms" << endl;
}
@@ -196,9 +198,9 @@
//that had objects and just clear those.
#if 1
const int oldlength = oldN_mc[1]*oldN_mc[2] - 1;
- const int start_z = oldlength*proc /
+ const int start_z = oldlength*proc /
(oldN_mc[1]*numProcs);
- const int end_z = oldlength*(proc+1) /
+ const int end_z = oldlength*(proc+1) /
(oldN_mc[1]*numProcs);
const int start_y = oldlength*proc / numProcs -
start_z*oldN_mc[1];
@@ -218,8 +220,8 @@
for (int x=0; x < oldN_mc[0]; x++) {
int ofs = x+oldN_mc[0]*(y+oldN_mc[1]*(z));
if (cellVector_mc[ofs] > 0) {
- int id = (x*MACRO_CELLS) +
- oldN[0]*( y*MACRO_CELLS +
+ int id = (x*MACRO_CELLS) +
+ oldN[0]*( y*MACRO_CELLS +
oldN[1]*z*MACRO_CELLS);
for (int mz=0;mz<MACRO_CELLS;mz++) {
for (int my=0;my<MACRO_CELLS;my++) {
@@ -227,7 +229,7 @@
myCell[id].ObjectIDs.resize(0);
id++;
}
- id += oldN[0] - MACRO_CELLS;
+ id += oldN[0] - MACRO_CELLS;
}
id += oldN[0] * (oldN[1] - MACRO_CELLS);
}
@@ -240,12 +242,12 @@
if (firstTime || DISPLAY_BUILD_TIMES)
{
char buf[128];
- sprintf(buf, "%d: time to clear old grid: %fms\n",
+ sprintf(buf, "%d: time to clear old grid: %fms\n",
proc, (SCIRun::Time::currentSeconds() - startClearTime)*1e3);
cout<<buf;
}
- buildQueue_resize_mutex.lock();
+ buildQueue_resize_mutex.lock();
if (buildQueues.size() < static_cast<size_t>(numProcs*numProcs)) {
buildQueues.resize(numProcs*numProcs);
}
@@ -265,7 +267,7 @@
//even though we don't really need a barrier here, this
//ends up, I think, not slowing down the code and it produces
//nicer more uniform and easier to understand timings.
- //Make sure to double check when getting overall best timings
+ //Make sure to double check when getting overall best timings
//whether this is slowing down the code...
barrier.wait(numProcs);
@@ -316,7 +318,7 @@
if (DISPLAY_BUILD_TIMES) {
char buf[128];
- sprintf(buf, "%d engriddingTimer time: %fms\n",
+ sprintf(buf, "%d engriddingTimer time: %fms\n",
proc, (SCIRun::Time::currentSeconds()-startSortTime)*1e3f);
cout<<buf;
}
@@ -327,7 +329,7 @@
for (int i=0; i < numProcs; i++) {
for (size_t k=0; k < buildQueues[i*numProcs +
proc].loc_primitives.size(); ++k) {
- const location_primitive &prim_lp =
+ const location_primitive &prim_lp =
buildQueues[i*numProcs + proc].loc_primitives[k];
myCell[prim_lp.gridLocation].ObjectIDs.push_back(prim_lp.which_primitive);
@@ -336,7 +338,7 @@
if (DISPLAY_BUILD_TIMES) {
char buf[128];
- sprintf(buf, "%d merge time: %fms\n",
+ sprintf(buf, "%d merge time: %fms\n",
proc, (SCIRun::Time::currentSeconds() - startMergeTime)*1e3);
cout<<buf;
}
@@ -352,9 +354,9 @@
double startMacroBuildTime = SCIRun::Time::currentSeconds();
const int length = N_mc[1]*N_mc[2] - 1;
- const int start_iz = length*proc /
+ const int start_iz = length*proc /
(N_mc[1]*numProcs);
- const int end_iz = length*(proc+1) /
+ const int end_iz = length*(proc+1) /
(N_mc[1]*numProcs);
const int start_iy = length*proc / numProcs -
start_iz*N_mc[1];
@@ -363,11 +365,11 @@
for (int iz = start_iz; iz<=end_iz; iz++)
for (int iy = ((iz==start_iz)? start_iy: 0);
- iy < ((iz==end_iz)? end_iy:N_mc[1]); iy++)
+ iy < ((iz==end_iz)? end_iy:N_mc[1]); iy++)
for (int ix = 0;ix<N_mc[0];ix++) {
int count = 0;
- int id = (ix*MACRO_CELLS) +
- N[0]*( iy*MACRO_CELLS +
+ int id = (ix*MACRO_CELLS) +
+ N[0]*( iy*MACRO_CELLS +
N[1]*iz*MACRO_CELLS);
for (int mz=0;mz<MACRO_CELLS;mz++) {
for (int my=0;my<MACRO_CELLS;my++) {
@@ -390,7 +392,7 @@
if (DISPLAY_BUILD_TIMES) {
char buf[128];
- sprintf(buf, "%d macro cell build time: %fms\n",
+ sprintf(buf, "%d macro cell build time: %fms\n",
proc, (SCIRun::Time::currentSeconds() -
startMacroBuildTime)*1e3);
cout<<buf;
}
@@ -410,7 +412,7 @@
}
if (firstTime|| DISPLAY_BUILD_TIMES)
- cout << "grid built in "
+ cout << "grid built in "
<< (SCIRun::Time::currentSeconds() - startGlobalBuildTime)*1e3 <<
"ms\n\n";
firstTime = false;
}
@@ -429,7 +431,7 @@
//grid, but later on maybe try checking more often (every macro cell
//or every grid cell?).
-
+
const float f_NK = N[K];
const float f_NU = N[U];
const float f_NV = N[V];
@@ -445,7 +447,7 @@
float maxUd;
float minVd;
float maxVd;
-
+
if (ray.getFlag(RayPacket::HaveCornerRays))
{
sse_t dir4[3];
@@ -456,7 +458,7 @@
// all rays in u space are u(k) = f_orgU + d_u/d_k * (k - f_orgK)
// i.e., u(k) = (f_orgU - d_u/d_k*f_orgK) + k * d_u/d_k
-
+
//------------------------------------------------------------------
// stretch all rays to have dir[k] == 1
//
@@ -473,16 +475,16 @@
minDv = min4f(dv);
maxDu = max4f(du);
maxDv = max4f(dv);
-
+
}
else {
//TODO: convert to SSE!
-
+
ray.computeInverseDirections();
bool setDir = false;
for (int i=ray.begin();i<ray.end();i++) {
-
+
//XXXX set it so that disabled rays do not contribute!
// if (ray.wasHit(i))
// continue;
@@ -501,20 +503,20 @@
minDv = min(minDv, dv);
maxDv = max(maxDv, dv);
}
-
+
const sse_t inv_scaleN = accurateReciprocal(scaleN);
-
+
minDu *= DK;
minDv *= DK;
maxDu *= DK;
maxDv *= DK;
-
+
//some intersecters, like WaldTriangle use corner rays, so get corners.
ray.data->corner_dir[K] = set4(DK);
ray.data->corner_dir[U] = set44(maxDu, maxDu, minDu, minDu);
ray.data->corner_dir[V] = set44(maxDv, minDv, maxDv, minDv);
ray.setFlag(RayPacket::HaveCornerRays);
-
+
float u_scale = ((float4&)scaleN)[U] * ((float4&)inv_scaleN)[K]*DK;
float v_scale = ((float4&)scaleN)[V] * ((float4&)inv_scaleN)[K]*DK;
minDu *= u_scale;
@@ -526,7 +528,7 @@
sse_t minMax_dudv = set44(maxDv,maxDu,minDv,minDu);
//printf("%f %f %f %f\n", maxDv,maxDu,minDv,minDu);
if (COMMON_ORIGIN) {
- sse_t org4 = set44(0.0f, ray.getOrigin(ray.begin(),2),
+ sse_t org4 = set44(0.0f, ray.getOrigin(ray.begin(),2),
ray.getOrigin(ray.begin(),1),
ray.getOrigin(ray.begin(),0));
sse_t s_org = mul4(scaleN,sub4(org4,bounds.min));
@@ -567,10 +569,10 @@
if (DK == +1) {
int b = (ray.begin() + 3) & (~3);
int e = ray.end() & (~3);
- if (b == e) {
+ if (b >= e) {
float curr_k = ((float4&)s_furthest_k)[0];
for(int i=ray.begin();i<ray.end();i++) {
- curr_k = max(curr_k, ray.getOrigin(i,K) +
+ curr_k = max(curr_k, ray.getOrigin(i,K) +
ray.getMinT(i)*ray.getDirection(i,K));
}
s_furthest_k = set4(curr_k);
@@ -580,7 +582,7 @@
// Do the non aligned in front
if (i < b) {
s_furthest_k = add4(load44(&ray.getOrigin(b-4,K)),
- mul4(load44(&ray.getMinT(b-4)),
+ mul4(load44(&ray.getMinT(b-4)),
load44(&ray.getDirection(b-4,K))));
for(int j=0; j<i&4; ++j)
((float4&)s_furthest_k)[j] = ((float4&)s_furthest_k)[3];
@@ -589,13 +591,13 @@
for(i=b; i<e; i+=4)
s_furthest_k = max4(s_furthest_k,
add4(load44(&ray.getOrigin(b,K)),
- mul4(load44(&ray.getMinT(i)),
+ mul4(load44(&ray.getMinT(i)),
load44(&ray.getDirection(i,K)))));
// Do the non aligned in end
if (i < ray.end()) {
float curr_k = ((float4&)s_furthest_k)[0];
for(; i<ray.end(); ++i) {
- curr_k = max(curr_k, ray.getOrigin(b,K) +
+ curr_k = max(curr_k, ray.getOrigin(b,K) +
ray.getMinT(i)*ray.getDirection(i,K));
}
((float4&)s_furthest_k)[0] = curr_k;
@@ -606,10 +608,10 @@
else {
int b = (ray.begin() + 3) & (~3);
int e = ray.end() & (~3);
- if (b == e) {
+ if (b >= e) {
float curr_k = ((float4&)s_furthest_k)[0];
for(int i=ray.begin();i<ray.end();i++) {
- curr_k = min(curr_k, ray.getOrigin(i,K) +
+ curr_k = min(curr_k, ray.getOrigin(i,K) +
ray.getMinT(i)*ray.getDirection(i,K));
}
s_furthest_k = set4(curr_k);
@@ -619,7 +621,7 @@
// Do the non aligned in front
if (i < b) {
s_furthest_k = add4(load44(&ray.getOrigin(b-4,K)),
- mul4(load44(&ray.getMinT(b-4)),
+ mul4(load44(&ray.getMinT(b-4)),
load44(&ray.getDirection(b-4,K))));
for(int j=0; j<i&4; ++j)
((float4&)s_furthest_k)[j] = ((float4&)s_furthest_k)[3];
@@ -628,13 +630,13 @@
for(i=b; i<e; i+=4)
s_furthest_k = min4(s_furthest_k,
add4(load44(&ray.getOrigin(b,K)),
- mul4(load44(&ray.getMinT(i)),
+ mul4(load44(&ray.getMinT(i)),
load44(&ray.getDirection(i,K)))));
// Do the non aligned in end
if (i < ray.end()) {
float curr_k = ((float4&)s_furthest_k)[0];
for(; i<ray.end(); ++i) {
- curr_k = min(curr_k, ray.getOrigin(b,K) +
+ curr_k = min(curr_k, ray.getOrigin(b,K) +
ray.getMinT(i)*ray.getDirection(i,K));
}
((float4&)s_furthest_k)[0] = curr_k;
@@ -647,7 +649,7 @@
for(int i=0; i<ray.end(); i+=4)
s_furthest_k = max4(s_furthest_k,
add4(load44(&ray.getOrigin(0,K)),
- mul4(load44(&ray.getMinT(i)),
+ mul4(load44(&ray.getMinT(i)),
load44(&ray.getDirection(i,K)))));
// for (int i=0;i<ray.end;i+=4)
// s_furthest_k =
max4(s_furthest_k,add4(ray.org0[K],mul4(ray.t[i],ray.dir[K][i])));
@@ -655,7 +657,7 @@
for(int i=0; i<ray.end(); i+=4)
s_furthest_k = min4(s_furthest_k,
add4(load44(&ray.getOrigin(0,K)),
- mul4(load44(&ray.getMinT(i)),
+ mul4(load44(&ray.getMinT(i)),
load44(&ray.getDirection(i,K)))));
// for (int i=0;i<ray.curr_packet_simds;i++)
// s_furthest_k =
min4(s_furthest_k,add4(ray.org0[K],mul4(ray.t[i],ray.dir[K][i])));
@@ -667,7 +669,7 @@
else
k1 = (min4f(s_furthest_k) - ((float4&)bounds.min)[K]) *
((float4&)scaleN)[K];
// transform to local:
-
+
// --------------------------------------------
// now, [k0,k1] is the k interval overlapped by the rays. (note: for
DK==-1, k1<k0!)
// next, clip to [0..N[K]] interval
@@ -683,9 +685,9 @@
// --------------------------------------------
// now, [k0,k1] is the k interval overlapped by the rays. (note: for
DK==-1, k1<k0!)
// both k0 and k1 are positive (must be in [0..Nk] range ...
- //
+ //
// now, clip in u dimension
- // know 'min' and 'max' planes:
+ // know 'min' and 'max' planes:
// u(k) = minUd + k * minDu
// u(k) = maxUd + k * maxDu
//
@@ -700,55 +702,55 @@
if (DK == +1) {
// min is lower plane, max is upper plane
if (minDu < 0.0f) {
- // lower plane goes downwards, defines entry point at Nu
- const float k = (f_NU - minUd) / minDu;
- k0 = max(k0,k);
- uMinOfs = 1.f;
- }
+ // lower plane goes downwards, defines entry point at Nu
+ const float k = (f_NU - minUd) / minDu;
+ k0 = max(k0,k);
+ uMinOfs = 1.f;
+ }
else {
- // lower plane goes up, defines exit point at Nu
- const float k = (f_NU - minUd) / minDu;
- k1 = min(k1,k);
- uMinOfs = 0.f;
- }
+ // lower plane goes up, defines exit point at Nu
+ const float k = (f_NU - minUd) / minDu;
+ k1 = min(k1,k);
+ uMinOfs = 0.f;
+ }
if (maxDu < 0.0f) {
- // upper plane goes downwards, defines exit point at 0
- const float k = (0.f - maxUd) / maxDu;
- k1 = min(k1,k);
- uMaxOfs = 0.f;
- }
+ // upper plane goes downwards, defines exit point at 0
+ const float k = (0.f - maxUd) / maxDu;
+ k1 = min(k1,k);
+ uMaxOfs = 0.f;
+ }
else {
- // upper plane goes up, defines exit point at 0
- const float k = (0.f - maxUd) / maxDu;
- k0 = max(k0,k);
- uMaxOfs = 1.f;
- }
+ // upper plane goes up, defines exit point at 0
+ const float k = (0.f - maxUd) / maxDu;
+ k0 = max(k0,k);
+ uMaxOfs = 1.f;
+ }
if (k0 > k1) return;
}
else {
// min is upper plane, max is lower plane
if (minDu < 0.0f) {
- // upper plane goes neg. downwards, defines entry point at 0
- const float k = (0.f - minUd) / minDu;
- k0 = min(k0,k);
- uMaxOfs = 0.f;
- }
+ // upper plane goes neg. downwards, defines entry point at 0
+ const float k = (0.f - minUd) / minDu;
+ k0 = min(k0,k);
+ uMaxOfs = 0.f;
+ }
else {
- // upper plane neg. goes up, defines exit point at Nu
- const float k = (0.f - minUd) / minDu;
- k1 = max(k1,k);
- uMaxOfs = 1.f;
- }
+ // upper plane neg. goes up, defines exit point at Nu
+ const float k = (0.f - minUd) / minDu;
+ k1 = max(k1,k);
+ uMaxOfs = 1.f;
+ }
if (maxDu < 0.0f) {
- const float k = (f_NU - maxUd) / maxDu;
- k1 = max(k1,k);
- uMinOfs = 1.f;
- }
+ const float k = (f_NU - maxUd) / maxDu;
+ k1 = max(k1,k);
+ uMinOfs = 1.f;
+ }
else {
- const float k = (f_NU - maxUd) / maxDu;
- k0 = min(k0,k);
- uMinOfs = 0.f;
- }
+ const float k = (f_NU - maxUd) / maxDu;
+ k0 = min(k0,k);
+ uMinOfs = 0.f;
+ }
if (k0 < k1) return;
}
@@ -756,55 +758,55 @@
if (DK == +1) {
// min is lower plane, max is vpper plane
if (minDv < 0.0f) {
- // lower plane goes downwards, defines entry point at Nv
- const float k = (f_NV - minVd) / minDv;
- k0 = max(k0,k);
- vMinOfs = 1.f;
- }
+ // lower plane goes downwards, defines entry point at Nv
+ const float k = (f_NV - minVd) / minDv;
+ k0 = max(k0,k);
+ vMinOfs = 1.f;
+ }
else {
- // lower plane goes vp, defines exit point at Nv
- const float k = (f_NV - minVd) / minDv;
- k1 = min(k1,k);
- vMinOfs = 0.f;
- }
+ // lower plane goes vp, defines exit point at Nv
+ const float k = (f_NV - minVd) / minDv;
+ k1 = min(k1,k);
+ vMinOfs = 0.f;
+ }
if (maxDv < 0.0f) {
- // vpper plane goes downwards, defines exit point at 0
- const float k = (0.f - maxVd) / maxDv;
- k1 = min(k1,k);
- vMaxOfs = 0.f;
- }
+ // vpper plane goes downwards, defines exit point at 0
+ const float k = (0.f - maxVd) / maxDv;
+ k1 = min(k1,k);
+ vMaxOfs = 0.f;
+ }
else {
- // vpper plane goes vp, defines exit point at 0
- const float k = (0.f - maxVd) / maxDv;
- k0 = max(k0,k);
- vMaxOfs = 1.f;
- }
+ // vpper plane goes vp, defines exit point at 0
+ const float k = (0.f - maxVd) / maxDv;
+ k0 = max(k0,k);
+ vMaxOfs = 1.f;
+ }
if (k0 > k1) return;
}
else {
// min is vpper plane, max is lower plane
if (minDv < 0.0f) {
- // vpper plane goes neg. downwards, defines entry point at 0
- const float k = (0.f - minVd) / minDv;
- k0 = min(k0,k);
- vMaxOfs = 0.f;
- }
+ // vpper plane goes neg. downwards, defines entry point at 0
+ const float k = (0.f - minVd) / minDv;
+ k0 = min(k0,k);
+ vMaxOfs = 0.f;
+ }
else {
- // vpper plane neg. goes vp, defines exit point at Nv
- const float k = (0.f - minVd) / minDv;
- k1 = max(k1,k);
- vMaxOfs = 1.f;
- }
+ // vpper plane neg. goes vp, defines exit point at Nv
+ const float k = (0.f - minVd) / minDv;
+ k1 = max(k1,k);
+ vMaxOfs = 1.f;
+ }
if (maxDv < 0.0f) {
- const float k = (f_NV - maxVd) / maxDv;
- k1 = max(k1,k);
- vMinOfs = 1.f;
- }
+ const float k = (f_NV - maxVd) / maxDv;
+ k1 = max(k1,k);
+ vMinOfs = 1.f;
+ }
else {
- const float k = (f_NV - maxVd) / maxDv;
- k0 = min(k0,k);
- vMinOfs = 0.f;
- }
+ const float k = (f_NV - maxVd) / maxDv;
+ k0 = min(k0,k);
+ vMinOfs = 0.f;
+ }
if (k0 < k1) return;
}
@@ -816,7 +818,7 @@
int startSlice;
if (DK == +1)
startSlice = int(k0);
- else
+ else
startSlice = int(k0);
const float f_startSlice = startSlice;
@@ -831,12 +833,12 @@
uv01k0 = set44(minVd, minUd, maxVd, maxUd);
}
const sse_t minMax_Ofs = set44(vMaxOfs, uMaxOfs, vMinOfs, uMinOfs);
- sse_t minMax_uv = add4( mul4(uv01duv,
+ sse_t minMax_uv = add4( mul4(uv01duv,
add4(set4(f_startSlice), minMax_Ofs)),
uv01k0);
- // -------------------------------------------------------
- // now, for the macrocells:
+ // -------------------------------------------------------
+ // now, for the macrocells:
//
// since the macrocells have exactly the same planes, we can just
// compute the new values for the new start slice
@@ -847,7 +849,7 @@
const float f_startSlice_mc = startSlice_mc;
sse_t minMax_uv_mc;
- minMax_uv_mc = add4( mul4(uv01duv,
+ minMax_uv_mc = add4( mul4(uv01duv,
add4(set4(f_startSlice_mc), minMax_Ofs)),
mul4(uv01k0, set4(1./MACRO_CELLS)));
#endif
@@ -863,12 +865,12 @@
else
next_mc_slice = slice_mc*MACRO_CELLS - 1;
#endif
-
+
int cellID[3];
int ik1 = int(k1);
assert(slice >= 0);
assert(slice < N[K]);
-
+
#ifdef MACRO_CELLS
const sse_t sse_N_mc = set44(N_mc[V]-1,N_mc[U]-1,N_mc[V]-1,N_mc[U]-1);
#endif
@@ -939,7 +941,7 @@
} range;
range.clampedAsInt = convert4_f2i(clamped);
- cellID[K] = slice;
+ cellID[K] = slice;
cellID[U] = range.uv01[0];
cellID[V] = range.uv01[1];
@@ -952,11 +954,11 @@
const int items = object.size();
for (int i=0;i<items;i++) {
#ifdef MAILBOXING
- if (mailboxes[context.proc].mailbox[object[i]] ==
+ if (mailboxes[context.proc].mailbox[object[i]] ==
mailboxes[context.proc].rayID) {
continue;
}
- mailboxes[context.proc].mailbox[object[i]] =
+ mailboxes[context.proc].mailbox[object[i]] =
mailboxes[context.proc].rayID;
#endif
//it appears that always setting anyHit to true only causes a
couple
@@ -978,8 +980,8 @@
else //K == 2 and U is X and V is Y
id += N[0] - (range.uv01[2]-range.uv01[0]+1);
}
-
- if (anyHit) {
+
+ if (anyHit) {
if (DK == +1)
s_furthest_k = _mm_minus_infty;
else
@@ -988,10 +990,10 @@
if (DK == +1) {
int b = (ray.begin() + 3) & (~3);
int e = ray.end() & (~3);
- if (b == e) {
+ if (b >= e) {
float curr_k = ((float4&)s_furthest_k)[0];
for(int i=ray.begin();i<ray.end();i++) {
- curr_k = max(curr_k, ray.getOrigin(i,K) +
+ curr_k = max(curr_k, ray.getOrigin(i,K) +
ray.getMinT(i)*ray.getDirection(i,K));
}
s_furthest_k = set4(curr_k);
@@ -1001,7 +1003,7 @@
// Do the non aligned in front
if (i < b) {
s_furthest_k = add4(load44(&ray.getOrigin(b-4,K)),
- mul4(load44(&ray.getMinT(b-4)),
+ mul4(load44(&ray.getMinT(b-4)),
load44(&ray.getDirection(b-4,K))));
for(int j=0; j<i&4; ++j)
((float4&)s_furthest_k)[j] = ((float4&)s_furthest_k)[3];
@@ -1010,13 +1012,13 @@
for(i=b; i<e; i+=4)
s_furthest_k = max4(s_furthest_k,
add4(load44(&ray.getOrigin(b,K)),
- mul4(load44(&ray.getMinT(i)),
+ mul4(load44(&ray.getMinT(i)),
load44(&ray.getDirection(i,K)))));
// Do the non aligned in end
if (i < ray.end()) {
float curr_k = ((float4&)s_furthest_k)[0];
for(; i<ray.end(); ++i) {
- curr_k = max(curr_k, ray.getOrigin(b,K) +
+ curr_k = max(curr_k, ray.getOrigin(b,K) +
ray.getMinT(i)*ray.getDirection(i,K));
}
((float4&)s_furthest_k)[0] = curr_k;
@@ -1026,10 +1028,10 @@
else {
int b = (ray.begin() + 3) & (~3);
int e = ray.end() & (~3);
- if (b == e) {
+ if (b >= e) {
float curr_k = ((float4&)s_furthest_k)[0];
for(int i=ray.begin();i<ray.end();i++) {
- curr_k = min(curr_k, ray.getOrigin(i,K) +
+ curr_k = min(curr_k, ray.getOrigin(i,K) +
ray.getMinT(i)*ray.getDirection(i,K));
}
s_furthest_k = set4(curr_k);
@@ -1039,7 +1041,7 @@
// Do the non aligned in front
if (i < b) {
s_furthest_k = add4(load44(&ray.getOrigin(b-4,K)),
- mul4(load44(&ray.getMinT(b-4)),
+ mul4(load44(&ray.getMinT(b-4)),
load44(&ray.getDirection(b-4,K))));
for(int j=0; j<i&4; ++j)
((float4&)s_furthest_k)[j] = ((float4&)s_furthest_k)[3];
@@ -1048,13 +1050,13 @@
for(i=b; i<e; i+=4)
s_furthest_k = min4(s_furthest_k,
add4(load44(&ray.getOrigin(b,K)),
- mul4(load44(&ray.getMinT(i)),
+ mul4(load44(&ray.getMinT(i)),
load44(&ray.getDirection(i,K)))));
// Do the non aligned in end
if (i < ray.end()) {
float curr_k = ((float4&)s_furthest_k)[0];
for(; i<ray.end(); ++i) {
- curr_k = min(curr_k, ray.getOrigin(b,K) +
+ curr_k = min(curr_k, ray.getOrigin(b,K) +
ray.getMinT(i)*ray.getDirection(i,K));
}
((float4&)s_furthest_k)[0] = curr_k;
@@ -1066,13 +1068,13 @@
for(int i=0; i<ray.end(); i+=4)
s_furthest_k = max4(s_furthest_k,
add4(load44(&ray.getOrigin(0,K)),
- mul4(load44(&ray.getMinT(i)),
+ mul4(load44(&ray.getMinT(i)),
load44(&ray.getDirection(i,K)))));
else
for(int i=0; i<ray.end(); i+=4)
s_furthest_k = min4(s_furthest_k,
add4(load44(&ray.getOrigin(0,K)),
- mul4(load44(&ray.getMinT(i)),
+ mul4(load44(&ray.getMinT(i)),
load44(&ray.getDirection(i,K)))));
#endif
@@ -1080,24 +1082,24 @@
k1 = min(k1,(max4f(s_furthest_k) - ((float4&)bounds.min)[K]) *
((float4&)scaleN)[K]);
else
k1 = max(k1,(min4f(s_furthest_k) - ((float4&)bounds.min)[K]) *
((float4&)scaleN)[K]);
-
+
ik1 = int(k1);
if (DK == +1)
{ if (slice > ik1) return; }
else
{ if (slice < ik1) return; }
}
-
- if (DK == +1) {
+
+ if (DK == +1) {
minMax_uv = add4(minMax_uv, uv01duv);
slice ++;
}
- else {
+ else {
minMax_uv = sub4(minMax_uv, uv01duv);
slice --;
}
#ifdef MACRO_CELLS
- }
+ }
while (slice != next_mc_slice);
// done doing the micro-slices, finish the macrocell stepping
@@ -1112,7 +1114,7 @@
template<bool SHADOWS_ONLY, bool COMMON_ORIGIN, bool SQUARE_PACKETS>
void Grid::traverse(RayPacket &packet, const RenderContext& context) const
-{
+{
// apparently, this is faster than via the sse_t ops below...
const float dirX = packet.getDirection(packet.begin(),0);
const float dirY = packet.getDirection(packet.begin(),1);
Modified: trunk/Model/Groups/private/CGT.h
==============================================================================
--- trunk/Model/Groups/private/CGT.h (original)
+++ trunk/Model/Groups/private/CGT.h Mon Aug 20 17:26:40 2007
@@ -68,13 +68,13 @@
struct location_primitive {
int gridLocation;
int which_primitive;
- location_primitive(int g, int w) :
+ location_primitive(int g, int w) :
gridLocation(g), which_primitive(w){ }
location_primitive() { }
};
struct vector_of_location_primitive {
vector<location_primitive> loc_primitives;
- char false_sharing_buffer[128-sizeof(vector<location_primitive>)];
+ char false_sharing_buffer[128-sizeof(vector<location_primitive>)];
};
vector< vector_of_location_primitive > buildQueues;
@@ -88,7 +88,7 @@
};
mutable vector <mailbox_struct> mailboxes;
#endif //MAILBOXING
-
+
static void newFrame();
#ifdef MACRO_CELLS
vector<int> cellVector_mc;
@@ -152,7 +152,7 @@
return cell;
}
- Grid() : resolutionFactor(5),
+ Grid() : resolutionFactor(5),
firstTime(true), mutex("generic build mutex"),
barrier("CGT build barrier"),
buildQueue_resize_mutex("build queue resize mutex"),
@@ -167,18 +167,19 @@
void computeBounds(const PreprocessContext& context, BBox& bbox) const;
+ void setGroup(Group* new_group);
void preprocess(const PreprocessContext&);
void build(int proc, int numProcs, bool &);
void preFrameSetup(int proc, int numProcs);
- void rebuild(Group *group, int proc=0, int numProcs=1);
+ void rebuild(int proc=0, int numProcs=1);
template<bool SHADOWS_ONLY, bool COMMON_ORIGIN, bool SQUARE_PACKETS>
void traverse(RayPacket &packet, const RenderContext& context) const;
template<bool SHADOWS_ONLY, bool COMMON_ORIGIN, bool SQUARE_PACKETS, int
K, int U, int V, int DK>
void TrvMajor(RayPacket &ray, const RenderContext& context) const;
-
+
void intersect(const RenderContext& context, RayPacket& rays) const;
protected:
Modified: trunk/Model/Instances/Instance.cc
==============================================================================
--- trunk/Model/Instances/Instance.cc (original)
+++ trunk/Model/Instances/Instance.cc Mon Aug 20 17:26:40 2007
@@ -28,10 +28,12 @@
#include <Model/Instances/Instance.h>
#include <Model/Instances/MPT.h>
+#include <Interface/Context.h>
#include <Interface/RayPacket.h>
#include <Core/Exceptions/BadPrimitive.h>
#include <Core/Geometry/BBox.h>
#include <Core/Math/MiscMath.h>
+#include <Core/Util/Preprocessor.h>
#include <sgi_stl_warnings_off.h>
#include <sstream>
@@ -59,7 +61,10 @@
void Instance::preprocess(const PreprocessContext& context)
{
+ //cerr << MANTA_FUNC << endl;
+ //cerr << " Before instance->preprocess (thread " << context.proc << " of
" << context.numProcs << ")\n";
instance->preprocess(context);
+ //cerr << " After instance->preprocess (thread " << context.proc << " of "
<< context.numProcs << ")\n";
}
void Instance::computeBounds(const PreprocessContext& context, BBox& bbox)
const
@@ -74,18 +79,33 @@
void Instance::intersect(const RenderContext& context, RayPacket& rays) const
{
+ bool debugFlag = rays.getFlag(RayPacket::DebugPacket);
+ if (debugFlag) {
+ cerr << MANTA_FUNC << " called\n";
+ }
RayPacketData raydata;
RayPacket instance_rays(raydata, RayPacket::UnknownShape, rays.begin(),
rays.end(),
rays.getDepth(), rays.getAllFlags());
+ // TODO(boulos): Make this a lot cleaner and try to easily maintain
+ // ray packet properties (probably best to just do so in specialized
+ // instance classes though)
+
+ // We don't know if we have a constant scale
+ instance_rays.resetFlag(RayPacket::NormalizedDirections |
+ RayPacket::HaveInverseDirections |
+ RayPacket::HaveSigns |
+ RayPacket::ConstantSigns |
+ RayPacket::HaveCornerRays);
+
Real scales[RayPacket::MaxSize];
Real inv_scales[RayPacket::MaxSize];
if(rays.getFlag(RayPacket::ConstantOrigin)){
Vector o = transform_inv.multiply_point(rays.getOrigin(rays.begin()));
-
+
for(int i = rays.begin();i<rays.end();i++){
Vector dir = transform_inv.multiply_vector(rays.getDirection(i));
-
+
Real length = dir.length();
inv_scales[i] = length;
Real ilength = 1/length;
@@ -106,6 +126,14 @@
instance_rays.resetHit(i, rays.getMinT(i)*length);
}
}
+
+ if (debugFlag) {
+ cerr << "After transforming the incoming rays:" << endl;
+ cerr << rays << endl;
+ cerr << "We get this: " << endl;
+ cerr << instance_rays << endl << endl;
+ }
+
instance->intersect(context, instance_rays);
for(int i=rays.begin();i<rays.end();i++){
if(instance_rays.wasHit(i)){
@@ -170,7 +198,7 @@
}
void Instance::computeTexCoords2(const RenderContext& context,
- RayPacket& rays) const
+ RayPacket& rays) const
{
Real old_minT[RayPacket::MaxSize];
Ray old_rays[RayPacket::MaxSize];
@@ -209,7 +237,7 @@
}
void Instance::computeTexCoords3(const RenderContext& context,
- RayPacket& rays) const
+ RayPacket& rays) const
{
Real old_minT[RayPacket::MaxSize];
Ray old_rays[RayPacket::MaxSize];
Modified: trunk/Model/Materials/LitMaterial.cc
==============================================================================
--- trunk/Model/Materials/LitMaterial.cc (original)
+++ trunk/Model/Materials/LitMaterial.cc Mon Aug 20 17:26:40 2007
@@ -16,6 +16,11 @@
void LitMaterial::preprocess(const PreprocessContext& context)
{
+ if (context.proc != 0) {
+ context.done();
+ return;
+ }
+
if(localLights){
localLights->preprocess(context);
if(localLightsOverrideGlobal){
@@ -26,4 +31,5 @@
} else {
activeLights = context.globalLights;
}
+ context.done();
}
Modified: trunk/Model/MiscObjects/CuttingPlane.cc
==============================================================================
--- trunk/Model/MiscObjects/CuttingPlane.cc (original)
+++ trunk/Model/MiscObjects/CuttingPlane.cc Mon Aug 20 17:26:40 2007
@@ -1,4 +1,5 @@
+#include <Interface/Context.h>
#include <Model/MiscObjects/CuttingPlane.h>
#include <Model/Intersections/AxisAlignedBox.h>
#include <Model/Intersections/Plane.h>
@@ -7,6 +8,7 @@
#include <iostream>
#include <sgi_stl_warnings_on.h>
+
using namespace Manta;
CuttingPlane::CuttingPlane( const Vector &point_, const Vector &normal_,
@@ -29,13 +31,16 @@
{
// Call preprocess on the object.
internal_object->preprocess( context );
-
+
// Compute its bounds.
internal_object->computeBounds( context, bounds );
- // Determine how far away the edges of the bounding box are from the
+ // Determine how far away the edges of the bounding box are from the
// initial point.
- movement_scale = bounds.diagonal().length() * (Real)0.5;
+ if (context.proc == 0)
+ movement_scale = bounds.diagonal().length() * (Real)0.5;
+
+ context.done();
}
void CuttingPlane::intersect(const RenderContext& context, RayPacket& rays)
const {
@@ -44,20 +49,20 @@
RayPacketData new_data;
RayPacket new_rays( new_data, RayPacket::UnknownShape, rays.begin(),
rays.end(),
rays.getDepth(), rays.getAllFlags());
-
+
rays.normalizeDirections();
rays.computeInverseDirections();
rays.computeSigns();
-
+
// Map between rays in original packet and new packet in case some rays
are skipped.
int packet_map[RayPacket::MaxSize];
-
+
// Keep track of which new rays intersect the front face of the plane.
bool front_facing[RayPacket::MaxSize];
-
+
// Keep track of the plane_t offset for each ray.
Real plane_t[RayPacket::MaxSize];
-
+
/////////////////////////////////////////////////////////////////////////////
// Create the new rays.
int new_i = 0;
@@ -69,75 +74,75 @@
if (Intersection::intersectAaBox( bounds, box_min, box_max,
ray, rays.getSigns(i),
rays.getInverseDirection(i) )) {
-
+
// Intersect the ray with the plane.
Intersection::intersectPlane( plane_point, plane_normal,
plane_t[new_i],
ray );
-
+
// Record which original ray this new ray maps to.
packet_map[new_i] = i;
-
+
// Check to see if the ray origin is on the front or back facing side
of
// the cutting plane (the front facing side is cut away).
front_facing[new_i] = Dot(plane_normal, (ray.origin()-plane_point)) >
0;
if (front_facing[new_i]) {
-
+
// If plane_t is negative, the ray can't possibly hit the cut model.
// because the ray is pointing away from the plane.
if (plane_t[new_i] > 0) {
-
+
// If front facing, move the new ray to the cutting plane.
new_rays.setRay(new_i,
ray.origin()+(ray.direction()*plane_t[new_i]),
ray.direction());
new_rays.resetFlag(RayPacket::ConstantOrigin);
-
-
+
+
// Subtract the distance from the hit t.
new_rays.resetHit( new_i, rays.getMinT(i) - plane_t[new_i] );
-
+
++new_i;
}
}
else {
-
+
// Otherwise if back facing, move the hit t in the hit record
// to the plane (it will need to be moved back afterwards)
new_rays.setRay(new_i, ray);
new_rays.resetHit( new_i, rays.getMinT(i) );
-
- ++new_i;
+
+ ++new_i;
}
-
-
+
+
}
}
-
+
// Check to see if all of the rays miss the bounds.
if (new_i == 0) {
return;
}
-
+
// Specify the number of new rays.
new_rays.resize( new_i );
-
+
/////////////////////////////////////////////////////////////////////////////
// Intersect the new ray packet with the internal object.
internal_object->intersect( context, new_rays );
-
+
/////////////////////////////////////////////////////////////////////////////
// Map the results back to the old rays.
for (new_i=new_rays.begin(); new_i<new_rays.end(); ++new_i) {
-
+
// Check to see if the new ray hit something.
if (new_rays.wasHit(new_i)) {
-
+
// Determine which old ray this maps to.
int old_i = packet_map[new_i];
-
+
// Check to see if the old ray is front or back facing.
if (front_facing[new_i]) {
// If so, then translate the hit t back into the old hit record.
- if (rays.hit( old_i, new_rays.getMinT(new_i)+plane_t[new_i],
+ if (rays.hit( old_i, new_rays.getMinT(new_i)+plane_t[new_i],
new_rays.getHitMaterial(new_i),
new_rays.getHitPrimitive(new_i),
new_rays.getHitTexCoordMapper(new_i) ))
Modified: trunk/Model/MiscObjects/KeyFrameAnimation.cc
==============================================================================
--- trunk/Model/MiscObjects/KeyFrameAnimation.cc (original)
+++ trunk/Model/MiscObjects/KeyFrameAnimation.cc Mon Aug 20 17:26:40
2007
@@ -9,9 +9,9 @@
using namespace Manta;
using namespace std;
-KeyFrameAnimation::KeyFrameAnimation(InterpolationMode interpolation) :
- as(NULL), interpolation(interpolation), spareGroup(NULL),
- currGroup(NULL), currTime(-1), updateToCurrTime(false),
+KeyFrameAnimation::KeyFrameAnimation(InterpolationMode interpolation) :
+ as(NULL), interpolation(interpolation), spareGroup(NULL),
+ currGroup(NULL), currTime(-1), updateToCurrTime(false),
paused(false), barrier("keyframe animation barrier"), duration(1)
{
}
@@ -110,16 +110,30 @@
keyframes[1].keyframe = frames[end];
keyframes[1].t = t;
- InterpErr errCode = currGroup->parallelInterpolate(keyframes,
+ // NOTE(boulos): This doesn't actually change the group pointer,
+ // so we don't need to inform the AccelStruct to do a setGroup
+ InterpErr errCode = currGroup->parallelInterpolate(keyframes,
context.proc,
context.numProcs);
if (errCode != success)
printf("KeyFrameAnimation had trouble interpolating!\n");
}
else if (interpolation == truncate) {
+ // NOTE(boulos): Only proc 0 should change the currGroup pointer
+ if (context.proc == 0) {
currGroup = frames[(int) frame];
+ // TODO(boulos): Who should check for identical pointers?
+ if (as) as->setGroup(currGroup);
+ }
}
+
+ // NOTE(boulos): We have to wait until the group is properly
+ // interpolated before proceeding to the acceleration structure
+ // update (there's no way to ensure that all the geometry will be
+ // ready before someone starts touching it in update otherwise).
+ barrier.wait(context.numProcs);
+
if (as)
- as->rebuild(currGroup, context.proc, context.numProcs);
+ as->update(context.proc, context.numProcs);
}
}
@@ -200,9 +214,12 @@
if (as)
as->preprocess(context);
- context.manta_interface->registerParallelAnimationCallback(
- Callback::create(this, &KeyFrameAnimation::temporaryUpdate));
+ if (context.proc == 0) {
+ context.manta_interface->registerParallelAnimationCallback
+ (Callback::create(this, &KeyFrameAnimation::temporaryUpdate));
+ }
+ context.done();
}
void KeyFrameAnimation::computeBounds(const PreprocessContext& context,
BBox& bbox) const
Modified: trunk/Model/Primitives/GridSpheres.cc
==============================================================================
--- trunk/Model/Primitives/GridSpheres.cc (original)
+++ trunk/Model/Primitives/GridSpheres.cc Mon Aug 20 17:26:40 2007
@@ -94,6 +94,10 @@
// Preprocess material
LitMaterial::preprocess(context);
+ if (context.proc != 0) {
+ context.done();
+ return;
+ }
// Build grid
cerr<<"Building GridSpheres\n";
@@ -328,6 +332,7 @@
}
cerr<<"Done building GridSpheres\n";
+ context.done();
}
void GridSpheres::computeBounds(const PreprocessContext& context,
Modified: trunk/Model/Primitives/ParticleBVH.cc
==============================================================================
--- trunk/Model/Primitives/ParticleBVH.cc (original)
+++ trunk/Model/Primitives/ParticleBVH.cc Mon Aug 20 17:26:40 2007
@@ -1,5 +1,6 @@
#include <Model/Primitives/ParticleBVH.h>
+#include <Interface/Context.h>
#include <Interface/RayPacket.h>
#include <SCIRun/Core/Math/MiscMath.h>
@@ -96,7 +97,10 @@
PreprocessContext const &context )
{
PrimitiveCommon::preprocess( context );
- build( 0, 0, number_of_particles, 1 );
+ if (context.proc == 0) {
+ build( 0, 0, number_of_particles, 1 );
+ }
+ context.done();
}
void ParticleBVH::computeBounds(
Modified: trunk/Model/Primitives/WaldTriangle.cc
==============================================================================
--- trunk/Model/Primitives/WaldTriangle.cc (original)
+++ trunk/Model/Primitives/WaldTriangle.cc Mon Aug 20 17:26:40 2007
@@ -1,6 +1,8 @@
#include <Model/Primitives/WaldTriangle.h>
+#include <Interface/Context.h>
#include <Interface/RayPacket.h>
#include <Core/Geometry/BBox.h>
+#include <Core/Util/Preprocessor.h>
#include <SCIRun/Core/Util/Assert.h>
#include <sgi_stl_warnings_off.h>
#include <iostream>
@@ -81,6 +83,7 @@
void WaldTriangle::preprocess(const PreprocessContext& context)
{
+ if (context.proc != 0) { context.done(); return; }
//TODO: this materials->preprocess might end up getting called lots
//of times (imagine all the triangles share the same
//material). Would be nice to have the preprocess for this in the
@@ -88,6 +91,7 @@
//that, so we will do extra work for now.
mesh->materials[mesh->face_material[myID]]->preprocess(context);
update();
+ context.done();
}
void WaldTriangle::setPoints(const Vector& _p1, const Vector& _p2, const
Vector& _p3)
@@ -206,6 +210,12 @@
void WaldTriangle::intersect(const RenderContext& context, RayPacket& rays)
const {
+ bool debugFlag = rays.getFlag(RayPacket::DebugPacket);
+ if (debugFlag) {
+ cerr << MANTA_FUNC << " called\n";
+ cerr << "Rays are: \n" << rays << endl;
+ }
+
const int axis = k;
const int ku = (k==2)?0:k+1;
const int kv = (k==0)?2:k-1;
Modified: trunk/scenes/primtest.cc
==============================================================================
--- trunk/scenes/primtest.cc (original)
+++ trunk/scenes/primtest.cc Mon Aug 20 17:26:40 2007
@@ -439,7 +439,7 @@
mesh->face_material.push_back(0);
mesh->addTriangle(prim);
- prim->update();
+ //prim->update();
if ( mapr )
prim->setTexCoordMapper( mapr );
spinprim = prim;
- [Manta] r1668 - in trunk: Core/Util Engine/Control Engine/Renderers Interface Maya Model/Cameras Model/Groups Model/Groups/private Model/Instances Model/Materials Model/MiscObjects Model/Primitives scenes, boulos, 08/20/2007
Archive powered by MHonArc 2.6.16.