Text archives Help
- From: aek@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r568 - in trunk: Core/Geometry Interface Model Model/Primitives scenes
- Date: Mon, 26 Sep 2005 11:45:59 -0600 (MDT)
Author: aek
Date: Mon Sep 26 11:45:58 2005
New Revision: 568
Added:
trunk/Model/Primitives/ParticleBVH.cc
trunk/Model/Primitives/ParticleBVH.h
trunk/scenes/ParticleBVHTest.cc
Modified:
trunk/Core/Geometry/BBox.h
trunk/Interface/RayPacket.h
trunk/Model/CMakeLists.txt
trunk/Model/Primitives/CMakeLists.txt
trunk/Model/Primitives/Sphere.cc
trunk/scenes/CMakeLists.txt
Log:
A Model/Primitives/ParticleBVH.cc
A Model/Primitives/ParticleBVH.h
M Model/Primitives/CMakeLists.txt
- Added a "primitive" to display large sets of spherical particles
using an internal BVH acceleration structure.
A scenes/ParticleBVHTest.cc
M scenes/CMakeLists.txt
- Added a scene to create a ParticleBVH for testing.
M Core/Geometry/BBox.h
- Added a longestAxis() method to help with BVH construction.
M Interface/RayPacket.h
- Added sign[] to element to hold the sign of each component of the
direction vector, added HaveSigns flag to accompany it.
- ConstantSigns flag to indicate whether all rays point in the same
octant.
- Added computeSigns() method. This will set or clear
ConstantSigns automatically depending on whether it applies.
- Converted tabs to spaces
M Model/Primitives/Sphere.cc
M Model/CMakeLists.txt
- Converted tabs to spaces
Modified: trunk/Core/Geometry/BBox.h
==============================================================================
--- trunk/Core/Geometry/BBox.h (original)
+++ trunk/Core/Geometry/BBox.h Mon Sep 26 11:45:58 2005
@@ -88,6 +88,17 @@
return (2.0*((lenx*leny) + (leny*lenz) + (lenx*lenz)));
}
+ int longestAxis() const
+ {
+ double lenx = max.x() - min.x();
+ double leny = max.y() - min.y();
+ double lenz = max.z() - min.z();
+ if ( lenx > leny )
+ return lenx > lenz ? 0 : 2;
+ else
+ return lenx > lenz ? 1 : 2;
+ }
+
private:
BBox(const BBox&);
BBox& operator=(const BBox&);
Modified: trunk/Interface/RayPacket.h
==============================================================================
--- trunk/Interface/RayPacket.h (original)
+++ trunk/Interface/RayPacket.h Mon Sep 26 11:45:58 2005
@@ -28,12 +28,14 @@
static const int HaveNormals = 0x200;
static const int HaveUnitNormals = 0x300;
static const int HaveInverseDirections = 0x800;
+ static const int HaveSigns = 0x1000;
+ static const int ConstantSigns = 0x2000;
inline RayPacket(RayPacketData& data, int size, int depth, int flags);
// Create a subset of another raypacket
RayPacket(RayPacket& parent, int start, int end)
: data(parent.data+start), size(end-start), depth(parent.depth),
- flags(parent.flags)
+ flags(parent.flags)
{
}
@@ -41,48 +43,6 @@
{
}
- /**
- * Split the packet based on a mask of booleans. The current packet
- * will be modified to be reduced to just those elements for which the
- * mask is false, while the elements for which it is true will be
- * returned in a new packet. Elements in each new packet may be
- * reordered. This does the minimum copying possible - it is most
- * efficient if the mask has all false before all true.
- *
- * @param mask an array of booleans controlling the split
- * @return a ray packet with all of the "true" elements
- */
- RayPacket split(
- bool *mask )
- {
- int low = -1;
- int high = size;
- for ( ; ; )
- {
- for ( ++low; low < high && !mask[ low ]; ++low );
- for ( --high; low < high && mask[ high ]; --high );
- if ( low >= high )
- break;
- std::swap( data[ low ].localColor, data[ high ].localColor );
- std::swap( data[ low ].color, data[ high ].color );
- std::swap( data[ low ].imageX, data[ high ].imageX );
- std::swap( data[ low ].imageY, data[ high ].imageY );
- std::swap( data[ low ].whichEye, data[ high ].whichEye );
- std::swap( data[ low ].ray, data[ high ].ray );
- data[ low ].hitInfo.swap( data[ high ].hitInfo );
- std::swap( data[ low ].normal, data[ high ].normal );
- std::swap( data[ low ].hitPosition, data[ high ].hitPosition );
- std::swap( data[ low ].texCoords, data[ high ].texCoords );
- std::swap( data[ low ].inverseDirection, data[ high
].inverseDirection );
- std::swap( data[ low ].ambientLight, data[ high ].ambientLight );
- std::swap( data[ low ].shadowBegin, data[ high ].shadowBegin );
- std::swap( data[ low ].shadowEnd, data[ high ].shadowEnd );
- }
- int old_size = low;
- size = low;
- return RayPacket( *this, low, old_size - low );
- }
-
int getFlags() const {
return flags;
}
@@ -100,7 +60,7 @@
}
void resetHit() {
for(int i=0;i<size;i++)
- data[i].hitInfo.reset();
+ data[i].hitInfo.reset();
flags |= HaveHitRecords;
}
@@ -122,7 +82,7 @@
Point hitPosition;
Point texCoords;
Vector inverseDirection;
-
+ int sign[3];
Color ambientLight;
int shadowBegin, shadowEnd;
Color light;
@@ -137,7 +97,7 @@
#endif // SWIG
void setPixel(int which, int whichEye, double imageX, double imageY,
- Color* color) {
+ Color* color) {
data[which].color = color;
data[which].imageX = imageX;
data[which].imageY = imageY;
@@ -145,7 +105,7 @@
}
void useLocalColors() {
for(int i=0;i<size;i++)
- data[i].color = &data[i].localColor;
+ data[i].color = &data[i].localColor;
}
HitInfo& hitInfo(int which) {
return data[which].hitInfo;
@@ -159,15 +119,15 @@
void normalizeDirections()
{
if(flags & NormalizedDirections)
- return;
+ return;
if(flags & HaveHitRecords){
- for(int i=0;i<size;i++){
- double length = data[i].ray.normalizeDirection();
- data[i].hitInfo.scaleT(length);
- }
+ for(int i=0;i<size;i++){
+ double length = data[i].ray.normalizeDirection();
+ data[i].hitInfo.scaleT(length);
+ }
} else {
- for(int i=0;i<size;i++)
- data[i].ray.normalizeDirection();
+ for(int i=0;i<size;i++)
+ data[i].ray.normalizeDirection();
}
flags |= NormalizedDirections;
flags &= ~HaveInverseDirections;
@@ -175,25 +135,44 @@
void computeHitPositions()
{
if(flags & HaveHitPositions)
- return;
+ return;
for(int i=0;i<size;i++)
- data[i].hitPosition = data[i].ray.origin() + data[i].ray.direction()
* data[i].hitInfo.minT();
+ data[i].hitPosition = data[i].ray.origin() + data[i].ray.direction()
* data[i].hitInfo.minT();
flags |= HaveHitPositions;
}
void computeInverseDirections()
{
if(flags & HaveInverseDirections)
- return;
+ return;
for(int i=0;i<size;i++)
- data[i].inverseDirection = Vector(1./data[i].ray.direction().x(),
+ data[i].inverseDirection = Vector(1./data[i].ray.direction().x(),
1./data[i].ray.direction().y(),
1./data[i].ray.direction().z());
flags |= HaveInverseDirections;
}
+ void computeSigns()
+ {
+ if(flags & HaveSigns)
+ return;
+ for(int i=0;i<size;i++)
+ {
+ data[i].sign[0] = data[i].ray.direction().x()<0.0;
+ data[i].sign[1] = data[i].ray.direction().y()<0.0;
+ data[i].sign[2] = data[i].ray.direction().z()<0.0;
+ }
+ flags |= HaveInverseDirections;
+ flags &= ~ConstantSigns;
+ for(int i=1;i<size;i++)
+ if (data[i].sign[0]!=data[i-1].sign[0]||
+ data[i].sign[1]!=data[i-1].sign[1]||
+ data[i].sign[2]!=data[i-1].sign[2])
+ return;
+ flags |= ConstantSigns;
+ }
void computeTextureCoordinates2(const RenderContext& context)
{
if(flags & (HaveTexture2|HaveTexture3))
- return;
+ return;
Element& e0 = data[0];
const TexCoordMapper* tex = e0.hitInfo.hitTexCoordMapper();
tex->computeTexCoords2(context, *this);
@@ -202,7 +181,7 @@
void computeTextureCoordinates3(const RenderContext& context)
{
if(flags & HaveTexture3)
- return;
+ return;
Element& e0 = data[0];
const TexCoordMapper* tex = e0.hitInfo.hitTexCoordMapper();
tex->computeTexCoords3(context, *this);
@@ -212,7 +191,7 @@
void computeFrame(const RenderContext& context)
{
if(flags & HaveFrame)
- return;
+ return;
Element& e0 = data[0];
const UVMapping* uv = e0.hitInfo.hitPrimitive()->getUVMapping();
uv->computeFrame(context, *this);
@@ -223,17 +202,17 @@
void computeNormals(const RenderContext& context)
{
if(flags & HaveNormals)
- return;
+ return;
// Compute normals
for(int i=0;i<size;){
- RayPacket::Element& e = data[i];
- const Primitive* prim = e.hitInfo.hitPrimitive();
- int end = i+1;
- while(end < size && data[end].hitInfo.hitPrimitive() == prim)
- end++;
- RayPacket subPacket(*this, i, end);
- prim->computeNormal(context, subPacket);
- i=end;
+ RayPacket::Element& e = data[i];
+ const Primitive* prim = e.hitInfo.hitPrimitive();
+ int end = i+1;
+ while(end < size && data[end].hitInfo.hitPrimitive() == prim)
+ end++;
+ RayPacket subPacket(*this, i, end);
+ prim->computeNormal(context, subPacket);
+ i=end;
}
flags |= HaveNormals;
}
@@ -267,7 +246,7 @@
};
inline RayPacket::RayPacket(RayPacketData& data, int size,
- int depth, int flags)
+ int depth, int flags)
: data(&data.data[0]), size(size), depth(depth), flags(flags)
{
}
Modified: trunk/Model/CMakeLists.txt
==============================================================================
--- trunk/Model/CMakeLists.txt (original)
+++ trunk/Model/CMakeLists.txt Mon Sep 26 11:45:58 2005
@@ -24,11 +24,11 @@
${Manta_Lights_SRCS}
${Manta_Materials_SRCS}
${Manta_Primitives_SRCS}
- ${Manta_Primitives_Volume_SRCS}
+ ${Manta_Primitives_Volume_SRCS}
${Manta_TexCoordMappers_SRCS}
${Manta_Instances_SRCS}
${Manta_MiscObjects_SRCS}
- ${Manta_Readers_SRCS}
+ ${Manta_Readers_SRCS}
)
TARGET_LINK_LIBRARIES(Manta_Model Manta_Interface Manta_Core)
Modified: trunk/Model/Primitives/CMakeLists.txt
==============================================================================
--- trunk/Model/Primitives/CMakeLists.txt (original)
+++ trunk/Model/Primitives/CMakeLists.txt Mon Sep 26 11:45:58 2005
@@ -13,6 +13,7 @@
Primitives/Disk.cc
Primitives/Hemisphere.cc
Primitives/Heightfield.cc
+ Primitives/ParticleBVH.cc
)
# Should be include known broken objects?
Added: trunk/Model/Primitives/ParticleBVH.cc
==============================================================================
--- (empty file)
+++ trunk/Model/Primitives/ParticleBVH.cc Mon Sep 26 11:45:58 2005
@@ -0,0 +1,248 @@
+
+#include <Model/Primitives/ParticleBVH.h>
+#include <Interface/RayPacket.h>
+#include <SCIRun/Core/Math/MiscMath.h>
+
+using namespace Manta;
+using namespace SCIRun;
+
+ParticleBVH::ParticleBVH(
+ Material *material,
+ int const number_of_particles )
+ : PrimitiveCommon( material, this ),
+ number_of_particles( number_of_particles ),
+ particles( new Particle[ number_of_particles ] ),
+ nodes( new Node[ number_of_particles * 2 ] )
+{
+}
+
+ParticleBVH::~ParticleBVH()
+{
+ delete[] particles;
+ delete[] nodes;
+}
+
+void ParticleBVH::setParticle(
+ int const which_one,
+ Point const ¢er,
+ double const radius )
+{
+ particles[ which_one ].center = center;
+ particles[ which_one ].radius = radius;
+ particles[ which_one ].inverse_radius = 1.0 / radius;
+}
+
+int ParticleBVH::partition(
+ int first,
+ int last,
+ int const axis,
+ float const position )
+{
+ --first;
+ for ( ; ; ) {
+ ++first;
+ while ( particles[ first ].center[ axis ] <= position && first < last )
+ ++first;
+ --last;
+ while ( particles[ first ].center[ axis ] >= position && first < last )
+ --last;
+ if ( first < last )
+ SWAP( particles[ first ], particles[ last ] );
+ else
+ return first;
+ }
+}
+
+int ParticleBVH::build(
+ int const index,
+ int const first,
+ int const last,
+ int const size )
+{
+ Node &node( nodes[ index ] );
+ node.bound.reset();
+ for ( int current = first; current < last; ++current )
+ node.bound.extendBySphere( particles[ current ].center, particles[
current ].radius );
+ if ( last - first < maximum_objects_per_leaf ) {
+ node.index = first;
+ node.length = last - first;
+ node.axis = 0;
+ node.leaf = true;
+ return size;
+ }
+ int axis = node.bound.longestAxis();
+ float position = ( node.bound.getMin()[ axis ] + node.bound.getMax()[ axis
] ) * 0.5f;
+ int split = partition( first, last, axis, position );
+ if ( split == first || split == last ) {
+ node.index = first;
+ node.length = last - first;
+ node.axis = 0;
+ node.leaf = true;
+ return size;
+ }
+ node.index = size;
+ node.length = 0;
+ node.axis = axis;
+ node.leaf = false;
+ int new_size = build( size, first, split, size + 2 );
+ new_size = build( size + 1, split, last, new_size );
+ return new_size;
+}
+
+void ParticleBVH::preprocess(
+ PreprocessContext const &context )
+{
+ build( 0, 0, number_of_particles, 1 );
+}
+
+void ParticleBVH::computeBounds(
+ PreprocessContext const &context,
+ BBox &box ) const
+{
+ for ( int current = 0; current < number_of_particles; ++current )
+ box.extendBySphere( particles[ current ].center, particles[ current
].radius );
+}
+
+bool ParticleBVH::testBox(
+ RayPacket &rays,
+ BBox const &box ) const
+{
+ float bound[ 6 ];
+ bound[ 0 ] = box.getMin().x(); bound[ 1 ] = box.getMax().x();
+ bound[ 2 ] = box.getMin().y(); bound[ 3 ] = box.getMax().y();
+ bound[ 4 ] = box.getMin().z(); bound[ 5 ] = box.getMax().z();
+ for ( int ray = 0; ray < rays.getSize(); ++ray ) {
+ RayPacket::Element &element( rays.get( ray ) );
+ float maximum_minimum = T_EPSILON;
+ float minimum_maximum = element.hitInfo.minT();
+ float x_minimum = ( bound[ element.sign[ 0 ] ] -
element.ray.origin().x() ) * element.inverseDirection.x();
+ float x_maximum = ( bound[ 1 - element.sign[ 0 ] ] -
element.ray.origin().x() ) * element.inverseDirection.x();
+ float y_minimum = ( bound[ 2 + element.sign[ 1 ] ] -
element.ray.origin().y() ) * element.inverseDirection.y();
+ float y_maximum = ( bound[ 3 - element.sign[ 1 ] ] -
element.ray.origin().y() ) * element.inverseDirection.y();
+ float z_minimum = ( bound[ 4 + element.sign[ 2 ] ] -
element.ray.origin().z() ) * element.inverseDirection.z();
+ float z_maximum = ( bound[ 5 - element.sign[ 2 ] ] -
element.ray.origin().z() ) * element.inverseDirection.z();
+ if ( minimum_maximum < x_minimum ||
+ maximum_minimum > x_maximum )
+ continue;
+ if ( minimum_maximum > x_maximum )
+ minimum_maximum = x_maximum;
+ if ( maximum_minimum < x_minimum )
+ maximum_minimum = x_minimum;
+ if ( minimum_maximum < y_minimum ||
+ maximum_minimum > y_maximum )
+ continue;
+ if ( minimum_maximum > y_maximum )
+ minimum_maximum = y_maximum;
+ if ( maximum_minimum < y_minimum )
+ maximum_minimum = y_minimum;
+ if ( minimum_maximum >= z_minimum &&
+ maximum_minimum <= z_maximum )
+ return true;
+ }
+ return false;
+}
+
+bool ParticleBVH::intersectParticles(
+ RayPacket &rays,
+ int const first,
+ int const last ) const
+{
+ for ( int current = first; current < last; ++current ) {
+ Particle &particle( particles[ current ] );
+ for ( int ray = 0; ray < rays.getSize(); ray++ ) {
+ RayPacket::Element &element( rays.get( ray ) );
+ Vector offset( element.ray.origin() - particle.center );
+ double B = Dot( offset, element.ray.direction() );
+ double C = Dot( offset, offset ) - particle.radius * particle.radius;
+ double discriminant = B * B - C;
+ if ( discriminant >= 0.0 ) {
+ double r = sqrt( discriminant );
+ double t0 = -r - B;
+ if( t0 > 0.0 ) {
+ if ( element.hitInfo.hit( t0, material, this, tex ) )
+ element.hitInfo.scratchpad< ParticleHit >().particle = current;
+ } else {
+ double t1 = r - B;
+ element.hitInfo.hit( t1, material, this, tex );
+ if ( element.hitInfo.hit( t0, material, this, tex ) )
+ element.hitInfo.scratchpad< ParticleHit >().particle = current;
+ }
+ }
+ }
+ }
+}
+
+void ParticleBVH::intersect(
+ RenderContext const &context,
+ RayPacket &rays ) const
+{
+ rays.normalizeDirections();
+ rays.computeInverseDirections();
+ rays.computeSigns();
+ int stack[ maximum_depth ];
+ int stack_position = 0;
+ int current = 0;
+ RayPacket::Element& element_0( rays.get( 0 ) );
+ for ( ; ; ) {
+ Node &node( nodes[ current ] );
+ if ( testBox( rays, node.bound ) ) {
+ if ( node.leaf )
+ intersectParticles( rays, node.index, node.index + node.length );
+ else {
+ stack[ stack_position++ ] = node.index + 1 - element_0.sign[
node.axis ];
+ current = node.index + element_0.sign[ node.axis ];
+ continue;
+ }
+ }
+ if ( --stack_position < 0 )
+ break;
+ current = stack[ stack_position ];
+ }
+}
+
+void ParticleBVH::computeNormal(
+ const RenderContext &/*context*/,
+ RayPacket &rays ) const
+{
+ rays.computeHitPositions();
+ for ( int ray = 0; ray < rays.getSize(); ++ray ) {
+ RayPacket::Element &element( rays.get( ray ) );
+ Particle &particle( particles[ element.hitInfo.scratchpad< ParticleHit
>
().particle ] );
+ element.normal = ( element.hitPosition - particle.center ) *
particle.inverse_radius;
+ }
+ rays.setFlag( RayPacket::HaveUnitNormals );
+}
+
+void ParticleBVH::computeTexCoords2(
+ RenderContext const &/*context*/,
+ RayPacket &rays ) const
+{
+ rays.computeHitPositions();
+ for ( int ray = 0; ray < rays.getSize(); ++ray ) {
+ RayPacket::Element &element( rays.get( ray ) );
+ Particle &particle( particles[ element.hitInfo.scratchpad< ParticleHit
>
().particle ] );
+ Vector n = ( element.hitPosition - particle.center ) *
particle.inverse_radius;
+ double angle = Clamp( n.z(), -1.0, 1.0 );
+ double theta = acos( angle );
+ double phi = atan2( n.x(), n.y() );
+ element.texCoords = Point( ( phi + M_PI ) * ( 1.0 / ( 2.0 * M_PI ) ),
theta * ( 1.0 / M_PI ), 0.0 );
+ }
+ rays.setFlag( RayPacket::HaveTexture2 | RayPacket::HaveTexture3 );
+}
+
+void ParticleBVH::computeTexCoords3(
+ const RenderContext &/*context*/,
+ RayPacket &rays ) const
+{
+ rays.computeHitPositions();
+ for ( int ray = 0; ray < rays.getSize(); ++ray ) {
+ RayPacket::Element &element( rays.get( ray ) );
+ Particle &particle( particles[ element.hitInfo.scratchpad< ParticleHit
>
().particle ] );
+ Vector n = ( element.hitPosition - particle.center ) *
particle.inverse_radius;
+ double angle = Clamp( n.z(), -1.0, 1.0 );
+ double theta = acos( angle );
+ double phi = atan2( n.x(), n.y() );
+ element.texCoords = Point( ( phi + M_PI ) * ( 1.0 / ( 2.0 * M_PI ) ),
theta * ( 1.0 / M_PI ), 0.0 );
+ }
+ rays.setFlag( RayPacket::HaveTexture2 | RayPacket::HaveTexture3 );
+}
Added: trunk/Model/Primitives/ParticleBVH.h
==============================================================================
--- (empty file)
+++ trunk/Model/Primitives/ParticleBVH.h Mon Sep 26 11:45:58 2005
@@ -0,0 +1,53 @@
+#ifndef Manta_Particle_BVH_h
+#define Manta_Particle_BVH_h
+
+#include <Model/Primitives/PrimitiveCommon.h>
+#include <Interface/TexCoordMapper.h>
+#include <Core/Geometry/PointVector.h>
+#include <Core/Geometry/BBox.h>
+
+namespace Manta {
+ class ParticleBVH : public PrimitiveCommon, public TexCoordMapper {
+
+ public:
+ ParticleBVH( Material *material, int const number_of_particles );
+ virtual ~ParticleBVH();
+
+ virtual void setParticle( int const which_one, Point const ¢er,
double const radius );
+ virtual void preprocess( PreprocessContext const &context );
+ virtual void computeBounds( PreprocessContext const &context, BBox &box
) const;
+ virtual void intersect( RenderContext const &context, RayPacket &rays )
const;
+ virtual void computeNormal( RenderContext const &context, RayPacket
&rays ) const;
+ virtual void computeTexCoords2( RenderContext const &context, RayPacket
&rays ) const;
+ virtual void computeTexCoords3( RenderContext const &context, RayPacket
&rays ) const;
+
+ protected:
+ static const int maximum_objects_per_leaf = 4;
+ static const int maximum_depth = 128;
+
+ int number_of_particles;
+ struct Particle {
+ Point center;
+ double radius;
+ double inverse_radius;
+ } *particles;
+ struct Node {
+ BBox bound;
+ unsigned int index;
+ unsigned int length : 29;
+ unsigned int axis : 2;
+ bool leaf : 1;
+ } *nodes;
+ struct ParticleHit{
+ int particle;
+ };
+
+ int partition( int first, int last, int const axis, float const position
);
+ int build( int const index, int const first, int const last, int const
size );
+ bool testBox( RayPacket &rays, BBox const &box ) const;
+ bool intersectParticles( RayPacket &rays, int const first, int const
last ) const;
+
+ };
+}
+
+#endif
Modified: trunk/Model/Primitives/Sphere.cc
==============================================================================
--- trunk/Model/Primitives/Sphere.cc (original)
+++ trunk/Model/Primitives/Sphere.cc Mon Sep 26 11:45:58 2005
@@ -41,16 +41,16 @@
e.hitInfo.hit(material, this, t);
} else {
if(tca < 0.0){
- // Behind ray, no intersections...
+ // Behind ray, no intersections...
} else {
- double t2hc=rad2-l2oc+tca*tca;
- if(t2hc <= 0.0){
- // Ray misses, no intersections
- } else {
- double thc=sqrt(t2hc);
- e.hitInfo.hit(material, this, tca-thc);
- e.hitInfo.hit(material, this, tca+thc);
- }
+ double t2hc=rad2-l2oc+tca*tca;
+ if(t2hc <= 0.0){
+ // Ray misses, no intersections
+ } else {
+ double thc=sqrt(t2hc);
+ e.hitInfo.hit(material, this, tca-thc);
+ e.hitInfo.hit(material, this, tca+thc);
+ }
}
}
}
@@ -63,20 +63,20 @@
Vector O(e0.ray.origin()-center);
double C = Dot(O, O) - radius*radius;
for(int i = 0;i<rays.getSize();i++){
- RayPacket::Element& e = rays.get(i);
- const Vector& D(e.ray.direction());
- double B = Dot(O, D);
- double disc = B*B-C;
- if(disc >= 0){
- double r = sqrt(disc);
- double t0 = -(r+B);
- if(t0 > 0){
- e.hitInfo.hit(t0, material, this, tex);
- } else {
- double t1 = r-B;
- e.hitInfo.hit(t1, material, this, tex);
- }
- }
+ RayPacket::Element& e = rays.get(i);
+ const Vector& D(e.ray.direction());
+ double B = Dot(O, D);
+ double disc = B*B-C;
+ if(disc >= 0){
+ double r = sqrt(disc);
+ double t0 = -(r+B);
+ if(t0 > 0){
+ e.hitInfo.hit(t0, material, this, tex);
+ } else {
+ double t1 = r-B;
+ e.hitInfo.hit(t1, material, this, tex);
+ }
+ }
}
}
break;
@@ -87,21 +87,21 @@
Vector O(e0.ray.origin()-center);
double C = Dot(O, O) - radius*radius;
for(int i = 0;i<rays.getSize();i++){
- RayPacket::Element& e = rays.get(i);
- const Vector& D(e.ray.direction());
- double A = Dot(D, D);
- double B = Dot(O, D);
- double disc = B*B-A*C;
- if(disc >= 0){
- double r = sqrt(disc);
- double t0 = -(r+B)/A;
- if(t0 > 0){
- e.hitInfo.hit(t0, material, this, tex);
- } else {
- double t1 = (r-B)/A;
- e.hitInfo.hit(t1, material, this, tex);
- }
- }
+ RayPacket::Element& e = rays.get(i);
+ const Vector& D(e.ray.direction());
+ double A = Dot(D, D);
+ double B = Dot(O, D);
+ double disc = B*B-A*C;
+ if(disc >= 0){
+ double r = sqrt(disc);
+ double t0 = -(r+B)/A;
+ if(t0 > 0){
+ e.hitInfo.hit(t0, material, this, tex);
+ } else {
+ double t1 = (r-B)/A;
+ e.hitInfo.hit(t1, material, this, tex);
+ }
+ }
}
}
break;
@@ -109,22 +109,22 @@
{
// Rays of non-constant origin and normalized directions
for(int i = 0;i<rays.getSize();i++){
- RayPacket::Element& e = rays.get(i);
- Vector O(e.ray.origin()-center);
- const Vector& D(e.ray.direction());
- double B = Dot(O, D);
- double C = Dot(O, O) - radius*radius;
- double disc = B*B-C;
- if(disc >= 0){
- double r = sqrt(disc);
- double t0 = -(r+B);
- if(t0 > 0){
- e.hitInfo.hit(t0, material, this, tex);
- } else {
- double t1 = r-B;
- e.hitInfo.hit(t1, material, this, tex);
- }
- }
+ RayPacket::Element& e = rays.get(i);
+ Vector O(e.ray.origin()-center);
+ const Vector& D(e.ray.direction());
+ double B = Dot(O, D);
+ double C = Dot(O, O) - radius*radius;
+ double disc = B*B-C;
+ if(disc >= 0){
+ double r = sqrt(disc);
+ double t0 = -(r+B);
+ if(t0 > 0){
+ e.hitInfo.hit(t0, material, this, tex);
+ } else {
+ double t1 = r-B;
+ e.hitInfo.hit(t1, material, this, tex);
+ }
+ }
}
}
break;
@@ -132,23 +132,23 @@
{
// Rays of non-constant origin and non-normalized directions
for(int i = 0;i<rays.getSize();i++){
- RayPacket::Element& e = rays.get(i);
- Vector O(e.ray.origin()-center);
- const Vector& D(e.ray.direction());
- double A = Dot(D, D);
- double B = Dot(O, D);
- double C = Dot(O, O) - radius*radius;
- double disc = B*B-A*C;
- if(disc >= 0){
- double r = sqrt(disc);
- double t0 = -(r+B)/A;
- if(t0 > 0){
- e.hitInfo.hit(t0, material, this, tex);
- } else {
- double t1 = (r-B)/A;
- e.hitInfo.hit(t1, material, this, tex);
- }
- }
+ RayPacket::Element& e = rays.get(i);
+ Vector O(e.ray.origin()-center);
+ const Vector& D(e.ray.direction());
+ double A = Dot(D, D);
+ double B = Dot(O, D);
+ double C = Dot(O, O) - radius*radius;
+ double disc = B*B-A*C;
+ if(disc >= 0){
+ double r = sqrt(disc);
+ double t0 = -(r+B)/A;
+ if(t0 > 0){
+ e.hitInfo.hit(t0, material, this, tex);
+ } else {
+ double t1 = (r-B)/A;
+ e.hitInfo.hit(t1, material, this, tex);
+ }
+ }
}
}
break;
@@ -163,10 +163,11 @@
e.normal = e.hitPosition-center;
e.normal*=inv_radius;
}
+ rays.setFlag(RayPacket::HaveUnitNormals);
}
void Sphere::computeTexCoords2(const RenderContext&,
- RayPacket& rays) const
+ RayPacket& rays) const
{
rays.computeHitPositions();
for(int i = 0;i<rays.getSize();i++){
@@ -181,7 +182,7 @@
}
void Sphere::computeTexCoords3(const RenderContext&,
- RayPacket& rays) const
+ RayPacket& rays) const
{
rays.computeHitPositions();
for(int i = 0;i<rays.getSize();i++){
Modified: trunk/scenes/CMakeLists.txt
==============================================================================
--- trunk/scenes/CMakeLists.txt (original)
+++ trunk/scenes/CMakeLists.txt Mon Sep 26 11:45:58 2005
@@ -43,5 +43,12 @@
TARGET_LINK_LIBRARIES(scene_acceltest ${manta_scene_link})
ENDIF(SCENE_ACCELTEST)
+# Test different acceleration structures.
+SET(SCENE_PARTICLEBVHTEST 0 CACHE BOOL "Particle BVH Test")
+IF(SCENE_PARTICLEBVHTEST)
+ ADD_LIBRARY(scene_ParticleBVHTest ParticleBVHTest.cc)
+ TARGET_LINK_LIBRARIES(scene_ParticleBVHTest ${manta_scene_link})
+ENDIF(SCENE_PARTICLEBVHTEST)
+
############################################################
Added: trunk/scenes/ParticleBVHTest.cc
==============================================================================
--- (empty file)
+++ trunk/scenes/ParticleBVHTest.cc Mon Sep 26 11:45:58 2005
@@ -0,0 +1,71 @@
+
+#include <Core/Exceptions/IllegalArgument.h>
+#include <Core/Util/Args.h>
+#include <Interface/Context.h>
+#include <Interface/LightSet.h>
+#include <Interface/RTRTInterface.h>
+#include <Interface/Scene.h>
+#include <Model/AmbientLights/ArcAmbient.h>
+#include <Model/Backgrounds/LinearBackground.h>
+#include <Model/Lights/PointLight.h>
+#include <Model/Materials/Phong.h>
+#include <Model/Primitives/ParticleBVH.h>
+
+#include <Core/Math/MinMax.h>
+#include <sgi_stl_warnings_off.h>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <fstream>
+#include <sgi_stl_warnings_on.h>
+
+using namespace Manta;
+using namespace std;
+
+extern "C"
+Scene* make_scene(
+ const ReadContext &context,
+ const vector< string > &args )
+{
+ string model_name = "/usr/sci/data/Geometry/particle/sd022-crop.mpm";
+ int argc = static_cast< int >( args.size() );
+ for ( int i = 0; i < argc; i++ ) {
+ string arg = args[ i ];
+ if ( arg == "-model" ) {
+ if ( !getStringArg( i, args, model_name ) )
+ throw IllegalArgument( "scene particlebvhtest -model", i, args );
+ } else {
+ cerr << "Valid options for scene particlebvhtest:" << endl
+ << " -model file - MPM particle set model to show" << endl;
+ throw IllegalArgument( "scene particlebvhtest", i, args );
+ }
+ }
+ Material *material = new Phong( Color( RGB( 0.6, 0.0, 0.0 ) ),
+ Color( RGB( 0.6, 0.6, 0.6 ) ), 32, 0.4 );
+ ifstream in( model_name.c_str() );
+ if ( !in.is_open() )
+ throw IllegalArgument( "Couldn't load model: " + model_name, 0, args );
+ int number_of_particles, number_of_variables, radius_index;
+ in >> number_of_particles >> number_of_variables >> radius_index;
+ ParticleBVH *bvh = new ParticleBVH( material, number_of_particles );
+ float data[ number_of_variables ];
+ for ( int particle = 0; particle < number_of_particles; ++particle ) {
+ for ( int variable = 0; variable < number_of_variables; ++variable )
+ in >> data[ variable ];
+ bvh->setParticle( particle,
+ Point( data[ 0 ], data[ 1 ], data[ 2 ] ),
+ radius_index > 0 ? data[ radius_index ] : 1.0 );
+ }
+ Scene *scene = new Scene();
+ scene->setBackground( new LinearBackground( Color( RGB( 0.2, 0.4, 0.9 ) ),
+ Color( RGB( 0.0, 0.0, 0.0 ) ),
+ Vector( 0.0, 1.0, 0.0 ) ) );
+ scene->setObject( bvh );
+ LightSet *lights = new LightSet();
+ lights->add( new PointLight( Point( 5.0, 5.0, 8.0), Color( RGB( 2.0, 2.0 ,
2.0 ) ) ) );
+ lights->setAmbientLight( new ArcAmbient( Color( RGB( 0.1, 0.3, 0.8 ) ),
+ Color( RGB( 0.8, 0.6, 0.6 ) ),
+ Vector( 0.0, 1.0, 0.0 ) ) );
+ scene->setLights( lights );
+ return scene;
+}
- [MANTA] r568 - in trunk: Core/Geometry Interface Model Model/Primitives scenes, aek, 09/26/2005
Archive powered by MHonArc 2.6.16.