Text archives Help
- From: abe@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r860 - in trunk: Core/Geometry Interface Model/Groups scenes
- Date: Mon, 23 Jan 2006 03:08:55 -0700 (MST)
Author: abe
Date: Mon Jan 23 03:08:54 2006
New Revision: 860
Added:
trunk/Model/Groups/VerticalKDTree-stub.cc
trunk/Model/Groups/VerticalKDTree.cc
- copied, changed from r858, trunk/Model/Groups/KDTree.cc
trunk/Model/Groups/VerticalKDTree.h
- copied, changed from r858, trunk/Model/Groups/KDTree.h
Modified:
trunk/Core/Geometry/BBox.h
trunk/Interface/RayPacket.h
trunk/Model/Groups/CMakeLists.txt
trunk/Model/Groups/KDTree.cc
trunk/Model/Groups/KDTree.h
trunk/scenes/boeing777.cc
Log:
Fixed Real float/double conflict.
M Core/Geometry/BBox.h
Added methods to access individual vertical components of direction, origin
etc.
M Interface/RayPacket.h
Added VerticalKDTree traversal implementation. The code compiles but doesn't
work yet.
VerticalKDTree contains a vertical implementation of the traversal (and
eventually the triangle intersection). After this implementation is finished
we will add a SSE implementation based on the vertical implementation.
The code currently requires that Real==float. The stub implementation will be
used in cases where Real==double.
Currently the size of the vertical "traversal packet" is configurable in
CMake. For sse it would be 4 but this will allow us to experiment with
different sizes. The parameter is configured by
KdtreeParameters.h.CMakeTemplate
A Model/Groups/VerticalKDTree.cc
A Model/Groups/VerticalKDTree.h
M Model/Groups/KDTree.cc
M Model/Groups/KDTree.h
A Model/Groups/VerticalKDTree-stub.cc
M Model/Groups/CMakeLists.txt
Added -vertical command line option to scene.
M scenes/boeing777.cc
Modified: trunk/Core/Geometry/BBox.h
==============================================================================
--- trunk/Core/Geometry/BBox.h (original)
+++ trunk/Core/Geometry/BBox.h Mon Jan 23 03:08:54 2006
@@ -56,7 +56,7 @@
return bounds[1] - bounds[0];
}
Point center() const {
- return Interpolate(bounds[0], bounds[1], 0.5);
+ return Interpolate(bounds[0], bounds[1], (Real)0.5);
}
template< typename T >
Modified: trunk/Interface/RayPacket.h
==============================================================================
--- trunk/Interface/RayPacket.h (original)
+++ trunk/Interface/RayPacket.h Mon Jan 23 03:08:54 2006
@@ -183,6 +183,7 @@
return Ray(Point(data->origin[0][which], data->origin[1][which],
data->origin[2][which]),
Vector(data->direction[0][which],
data->direction[1][which], data->direction[2][which]));
}
+
void setOrigin(int which, const Point& origin)
{
for(int i=0;i<3;i++)
@@ -193,18 +194,56 @@
for(int i=0;i<3;i++)
data->direction[i][which] = direction[i];
}
+
+
///////////////////////////////////////////////////////////////////////////
+ // GET ORIGIN
Point getOrigin(int which) const
{
return Point(data->origin[0][which], data->origin[1][which],
data->origin[2][which]);
}
+
+ Real &getOrigin(int which, int i)
+ {
+ return data->origin[i][which];
+ }
+ const Real &getOrigin(int which, int i) const
+ {
+ return data->origin[i][which];
+ }
+
+
///////////////////////////////////////////////////////////////////////////
+ // GET DIRECTION
Vector getDirection(int which) const
{
return Vector(data->direction[0][which], data->direction[1][which],
data->direction[2][which]);
}
+
+ Real &getDirection(int which, int i)
+ {
+ return data->direction[i][which];
+ }
+ const Real &getDirection(int which, int i) const
+ {
+ return data->direction[i][which];
+ }
+
+
///////////////////////////////////////////////////////////////////////////
+ // GET INVERSE DIRECTION
Vector getInverseDirection(int which) const
{
return Vector(data->inverseDirection[0][which],
data->inverseDirection[1][which], data->inverseDirection[2][which]);
}
+
+ Real &getInverseDirection(int which, int i)
+ {
+ return data->inverseDirection[i][which];
+ }
+
+ const Real &getInverseDirection(int which, int i) const
+ {
+ return data->inverseDirection[i][which];
+ }
+
void normalizeDirections()
{
if(flags & NormalizedDirections)
@@ -283,7 +322,7 @@
data->hitMatl[which] = 0;
data->minT[which] = maxt;
}
- Real getMinT(int which) const
+ Real &getMinT(int which) const
{
return data->minT[which];
}
Modified: trunk/Model/Groups/CMakeLists.txt
==============================================================================
--- trunk/Model/Groups/CMakeLists.txt (original)
+++ trunk/Model/Groups/CMakeLists.txt Mon Jan 23 03:08:54 2006
@@ -1,23 +1,49 @@
+# Configure the parameters for the KDTrees
+SET(MANTA_TRAVERSALPACKET_SIZE 4 CACHE STRING "Size to use for vertical
kdtree traversal packets.")
+CONFIGURE_FILE(
+ ${CMAKE_SOURCE_DIR}/Model/Groups/KdtreeParameters.h.CMakeTemplate
+ ${CMAKE_SOURCE_DIR}/Model/Groups/KdtreeParameters.h
+ )
+
+
SET (Manta_Groups_SRCS
- Groups/BVH.h
Groups/BVH.cc
- Groups/GriddedGroup.h
+ Groups/BVH.h
Groups/GriddedGroup.cc
- Groups/Group.h
+ Groups/GriddedGroup.h
Groups/Group.cc
- Groups/KDTree.h
+ Groups/Group.h
Groups/KDTree.cc
- Groups/TransparentKDTree.h
- Groups/TransparentKDTree.cc
- Groups/KDTreeLoader.h
+ Groups/KDTree.h
Groups/KDTreeLoader.cc
- #Groups/FrustumKDTree.h
- #Groups/FrustumKDTree.cc
+ Groups/KDTreeLoader.h
+ Groups/KdtreeParameters.h
Groups/PsiGammaTable.cc
Groups/PsiGammaTable.h
- Groups/RealisticBvh.h
Groups/RealisticBvh.cc
+ Groups/RealisticBvh.h
+ Groups/TransparentKDTree.cc
+ Groups/TransparentKDTree.h
Groups/VolumeGrid.h
Groups/varray.h
)
+
+# Determine if VerticalKDTree can be included
+IF(${MANTA_REAL} MATCHES float)
+ SET(Manta_Groups_SRCS
+ ${Manta_Groups_SRCS}
+ Groups/VerticalKDTree.h
+ Groups/VerticalKDTree.cc
+ )
+
+# Otherwise include a stub implementation.
+ELSE(${MANTA_REAL} MATCHES float)
+ SET(Manta_Groups_SRCS
+ ${Manta_Groups_SRCS}
+ Groups/VerticalKDTree.h
+ Groups/VerticalKDTree-stub.cc
+ )
+ENDIF(${MANTA_REAL} MATCHES float)
+
+
Modified: trunk/Model/Groups/KDTree.cc
==============================================================================
--- trunk/Model/Groups/KDTree.cc (original)
+++ trunk/Model/Groups/KDTree.cc Mon Jan 23 03:08:54 2006
@@ -289,9 +289,13 @@
travStack[exitPos].prev = tmp;
}
+
///////////////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////////////
// Check to see if we found a non-empty leaf node.
if (nearNode) {
+
/////////////////////////////////////////////////////////////////////////
+
/////////////////////////////////////////////////////////////////////////
// Intersect the ray with a list of triangles.
if (intersectTriangles(origin, direction,
nearNode->listBegin(), nearNode->listSize(),
@@ -317,16 +321,11 @@
triFlags->set(i, pickedFlag);
}
- // Check against the hit record, Note that tex coord mapper is null.
+
///////////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////////
+ // Check against the hit record.
if (rays.hit(which, isectData.rayHit.t, getMaterial(), this, 0 )) {
- // if (isectData.rayHit.t > t_epsilon) {
- // e.hitInfo.set_hit(isectData.rayHit.t, material, this, 0 );
-
- // e.normal = normals[isectData.rayHitTriIndex];
-
- //e.hitInfo.scratchpad<ScratchPadInfo>().normal =
normals[isectData.rayHitTriIndex];
-
// Interpolate between the three vertices.
Vectorf &n0 = normals[isectData.rayHitTriIndex][0];
Vectorf &n1 = normals[isectData.rayHitTriIndex][1];
@@ -368,9 +367,6 @@
} else
scratch_pad.payload =
tris->get(isectData.rayHitTriIndex).payload;
#endif
- // Check to make sure the found hit is inside the current cell.
- // if ((isectData.rayHit.t <= travStack[exitPos].t)/* &&
(isectData.rayHit.t > travStack[entryPos].t)*/)
- // break;
}
}
}
Modified: trunk/Model/Groups/KDTree.h
==============================================================================
--- trunk/Model/Groups/KDTree.h (original)
+++ trunk/Model/Groups/KDTree.h Mon Jan 23 03:08:54 2006
@@ -286,6 +286,7 @@
// Transparent KDTree will use data owned by this kdtree.
friend class TransparentKDTree;
+ friend class VerticalKDTree;
// The Kdtree::load(...) function is used to load data into the kdtree.
friend int Manta::Kdtree::load( KDTree *kdtree, const char *filename,
Added: trunk/Model/Groups/VerticalKDTree-stub.cc
==============================================================================
--- (empty file)
+++ trunk/Model/Groups/VerticalKDTree-stub.cc Mon Jan 23 03:08:54 2006
@@ -0,0 +1,65 @@
+
+
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2006
+ Scientific Computing and Imaging Institute, University of Utah
+
+
+ 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"),
+ to deal in the Software without restriction, including without limitation
+ 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
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ DEALINGS IN THE SOFTWARE.
+*/
+
+#include <Model/Groups/VerticalKDTree.h>
+
+#include <SCIRun/Core/Exceptions/InternalError.h>
+
+using namespace Manta;
+using namespace Manta::Kdtree;
+using namespace SCIRun;
+
+// This is the Manta interface method.
+void VerticalKDTree::intersect(const RenderContext& context, RayPacket&
rays) const { }
+
+///////////////////////////////////////////////////////////////////////////////
+// Simple kdtree functions.
+///////////////////////////////////////////////////////////////////////////////
+
+VerticalKDTree::VerticalKDTree( KDTree *kdtree_, Material *material_ )
+ : PrimitiveCommon( material_ ),
+ rootNode( kdtree_->rootNode ),
+ triIndices( kdtree_->triIndices ),
+ tris( kdtree_->tris ),
+ normals( kdtree_->normals )
+{
+ throw InternalError( "Manta::Real == float required for VerticalKDTree",
__FILE__, __LINE__ );
+}
+VerticalKDTree::~VerticalKDTree() { };
+
+void VerticalKDTree::computeNormal(const RenderContext& /*context*/,
+ RayPacket& rays) const { }
+
+void VerticalKDTree::computeBounds(const PreprocessContext&, BBox &box_ )
const { }
+
+void VerticalKDTree::computeBounds( BBox &box_ ) const { }
+
+
Copied: trunk/Model/Groups/VerticalKDTree.cc (from r858,
trunk/Model/Groups/KDTree.cc)
==============================================================================
--- trunk/Model/Groups/KDTree.cc (original)
+++ trunk/Model/Groups/VerticalKDTree.cc Mon Jan 23 03:08:54 2006
@@ -6,7 +6,7 @@
The MIT License
Copyright (c) 2005
- Silicon Graphics Inc. Mountain View California.
+ Scientific Computing and Imaging Institute, University of Utah
License for the specific language governing rights and limitations under
Permission is hereby granted, free of charge, to any person obtaining a
@@ -28,7 +28,7 @@
DEALINGS IN THE SOFTWARE.
*/
-#include <Model/Groups/KDTree.h>
+#include <Model/Groups/VerticalKDTree.h>
#include <Model/Groups/varray.h>
#include <Model/Intersections/AxisAlignedBox.h>
@@ -88,50 +88,57 @@
// INTERSECT TRIANGLES INTERSECT TRIANGLES INTERSECT TRIANGLES INTERSECT
TRI
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-int KDTree::intersectTriangles(const Pointf& origin, const Vectorf&
direction,
- unsigned int listBegin, unsigned int listSize,
- float maxDist,
- RayTriIntersectUserData& isectData) const
-{
- float nearest_u, nearest_v;
- int nearest_tri = -1;
- // Intersect the ray with all the triangles.
- unsigned int listEnd = listBegin+listSize;
+void VerticalKDTree::intersectTriangles(IntersectPacket &intersect_packet,
+ const RayPacket &rays,
+ int which,
+ unsigned int listBegin,
+ unsigned int listSize ) const {
+
+ // Keep track of the max value of a possible intersection.
+ float maxDist[TraversalPacketSize];
+
+ // Initialize nearset variables.
+ for (int p=0;p<TraversalPacketSize;++p) {
+ maxDist[p] = rays.getMinT(which+p);
+ }
-#ifndef __sgi
+ // Iterate over all of the triangles.
+ unsigned int listEnd = listBegin+listSize;
#pragma swp
-#endif
- for (unsigned int i = listBegin; i < listEnd; ++i) {
- int triIdx = triIndices->get(i);
+ for (unsigned int i = listBegin; i<listEnd; ++i) {
+
+ int triIdx = triIndices->get(i);
Triangle &tri = tris->get(triIdx);
- float t, u, v;
- if(intersect_triangle3_edge( origin.getDataPtr(), direction.getDataPtr(),
- &tri[0][0],
- &t, &u, &v,
- tri.edge1.getDataPtr(),
- tri.edge2.getDataPtr() ))
- {
+ // Use horizontal intersection for now...
+ for (int p=0;p<TraversalPacketSize;++p) {
+
+ // Convert origin and direction to float
+ Pointf origin = rays.getOrigin(which+p);
+ Vectorf direction = rays.getDirection(which+p);
+
+ float t, u, v;
+ if(intersect_packet.active_mask[p] &&
+ intersect_triangle3_edge( origin.getDataPtr(),
+ direction.getDataPtr(),
+ &tri[0][0],
+ &t, &u, &v,
+ tri.edge1.getDataPtr(),
+ tri.edge2.getDataPtr() )) {
+
// Check to see if the t value is closer.
- if (t < maxDist) {
- maxDist = t;
- nearest_u = u;
- nearest_v = v;
- nearest_tri = triIdx;
+ if (t < maxDist[p]) {
+ intersect_packet.t[p] = t;
+ intersect_packet.u[p] = u;
+ intersect_packet.v[p] = v;
+ intersect_packet.hit_index[p] = triIdx;
+
+ // Specify that a valid hit was found.
+ intersect_packet.hit_mask[p] = Mask::True;
}
}
- }
-
- if (nearest_tri >= 0) {
- isectData.rayHit.t = maxDist;
- isectData.rayHit.u = nearest_u;
- isectData.rayHit.v = nearest_v;
- isectData.rayHitTriIndex = nearest_tri;
- return 1;
-
- } else {
- return 0;
+ }
}
}
@@ -140,47 +147,46 @@
// This is the Manta interface method.
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-void KDTree::intersect(const RenderContext& context, RayPacket& rays) const
+
+void VerticalKDTree::intersect(const RenderContext& context, RayPacket&
rays) const
{
rays.normalizeDirections();
rays.computeInverseDirections();
rays.computeSigns();
- RayTriIntersectUserData isectData;
-
- for(int i=rays.begin();i<rays.end();i++) {
-
- Real minDist, maxDist;
-
- // Intersect the ray with the bounding box for the group.
- if (Intersection::intersectAaBox( bbox,
- minDist, maxDist,
- rays.getRay(i),
- rays.getSigns(i),
- rays.getInverseDirection(i)))
- {
- // Determine the actual minimum distance.
- minDist = SCIRun::Max( minDist, T_EPSILON );
- maxDist = SCIRun::Min( maxDist, rays.getMinT(i) );
-
- // Send the ray to the _intersect function.
- isectData.rayHitTriIndex = -1;
- isectData.duplicate = 0;
- intersect_node( rootNode, rays, i, isectData, context,
(float)minDist, (float)maxDist);
-
- }
- }
-}
+ // Mask to keep track of which rays are valid.
+ Mask valid_mask( Mask::False );
+
+ // Iterate over sub groups of rays.
+ for(int which=rays.begin();which<rays.end();which+=TraversalPacketSize) {
+
+ float minDist[TraversalPacketSize];
+ float maxDist[TraversalPacketSize];
+
+ // Compute min and max distance for the kdtree.
+ for (int p=0;(p<TraversalPacketSize)&&((which+p)<rays.end());++p) {
+
+ // Intersect the ray with the bounding box for the group.
+ valid_mask[p] = Intersection::intersectAaBox( bbox,
+ minDist[p],
+ maxDist[p],
+ rays.getRay(which+p),
+ rays.getSigns(which+p),
+
rays.getInverseDirection(which+p));
+
+
+
+ // Determine the actual minimum distance.
+ minDist[p] = SCIRun::Max( minDist[p], (float)T_EPSILON );
+ maxDist[p] = SCIRun::Min( maxDist[p], (float)rays.getMinT(which+p) );
+ }
-///////////////////////////////////////////////////////////////////////////////
-// This function performs the KD-Tree Traversal.
-///////////////////////////////////////////////////////////////////////////////
-void KDTree::computeNormal(const RenderContext& /*context*/,
- RayPacket& rays) const {
+ // Check to see if a traversal is necessary.
+ if (any(valid_mask)) {
- // Copy the normal out of the KDTree::ScratchPadInfo structure.
- for (int i=rays.begin();i<rays.end();++i) {
- rays.setNormal(i, rays.scratchpad<ScratchPadInfo>(i).normal);
+ // Intersect the subpacket with the tree.
+ intersect_node( context, valid_mask, rays, which, minDist, maxDist );
+ }
}
}
@@ -192,43 +198,53 @@
// Traversal Stack Entry.
struct TravStackEntry {
+ float t[TraversalPacketSize];
KDTreeNode* node; // 8 bytes(64 bit builds), 4 bytes(32 bit builds)
- float t; // 4 bytes
- int prev; // 4 bytes
+ int prev; // 4 bytes
+ int padding;
+
};
-void KDTree::intersect_node( KDTreeNode *startNode,
- RayPacket& rays, int which,
- RayTriIntersectUserData &isectData,
- const RenderContext &context,
- float minDist, float maxDist) const
+void VerticalKDTree::intersect_node( const RenderContext &context,
+ const Mask &valid_mask,
+ RayPacket &rays,
+ int which,
+ float minDist[TraversalPacketSize],
+ float maxDist[TraversalPacketSize] )
const
{
- KDTreeNode *nearNode = startNode;
+
+
/////////////////////////////////////////////////////////////////////////////
+ // Stack pointers.
+ KDTreeNode *nearNode = rootNode;
KDTreeNode *farNode;
int entryPos = 0;
int exitPos = 1;
+
/////////////////////////////////////////////////////////////////////////////
// Keep a stack of entry and exit positions into the traversal nodes.
-#ifdef __ia64__
- // __declspec(align(128))
-#endif
- TravStackEntry travStack[128];
+ __declspec(align(128)) TravStackEntry travStack[128];
// Initialize the first two entries on the stack.
- travStack[entryPos].node = startNode;
+ travStack[entryPos].node = rootNode;
+ travStack[entryPos].prev = 1;
+
// Check for the case that the minimum intersection point is behind
// the origin.
- travStack[entryPos].t = minDist < 0 ? 0 : minDist;
- travStack[entryPos].prev = 1;
-
+ for (int p=0;p<TraversalPacketSize;++p) {
+ travStack[entryPos].t[p] = SCIRun::Max( 0.0f, minDist[p] );
+ }
+
travStack[exitPos].node = NULL;
- travStack[exitPos].t = maxDist;
travStack[exitPos].prev = 0;
+
+ for (int p=0;p<TraversalPacketSize;++p) {
+ travStack[exitPos].t[p] = maxDist[p];
+ }
- Pointf origin = rays.getOrigin(which);
- Vectorf direction = rays.getDirection(which);
- Vectorf invDirection = rays.getInverseDirection(which);
-
+
/////////////////////////////////////////////////////////////////////////////
+ // Mask to keep track of rays that still need to find closest
intersections.
+ Mask active_mask = valid_mask;
+
while (travStack[entryPos].prev) {
// Traverse down until we find a leaf node.
@@ -240,42 +256,78 @@
// Determine the axis and the split point.
int axis = nearNode->axis();
float split = nearNode->split();
-
+
// Find where along the axis the ray enters and exits.
- float entryPos_coord_on_axis =
- travStack[entryPos].t*direction[axis] + origin[axis];
- float exitPos_coord_on_axis =
- travStack[exitPos].t*direction[axis] + origin[axis];
-
+ float entry_axis[TraversalPacketSize];
+ float exit_axis [TraversalPacketSize];
+
+ for (int p=0;p<TraversalPacketSize;++p) {
+ if (active_mask[p]) {
+ entry_axis[p] =
+ travStack[entryPos].t[p] *
+ rays.getDirection(which+p,axis) +
+ rays.getOrigin (which+p,axis);
+
+ exit_axis[p] =
+ travStack[exitPos].t[p] *
+ rays.getDirection(which+p,axis) +
+ rays.getOrigin (which+p,axis);
+ }
+ }
+
+
/////////////////////////////////////////////////////////////////////////
// Check to see which side of the split the ray enters first.
- if (entryPos_coord_on_axis <= split) {
+ // if (entryPos_coord_on_axis <= split) {
+ Mask cmp_result;
+ set_lte( cmp_result, entry_axis, split );
+ if (all( active_mask, cmp_result )) {
+
///////////////////////////////////////////////////////////////////////
// Check to see if entry and exit are on the
// same side of the split.
- if (exitPos_coord_on_axis <= split) {
+ // if (exitPos_coord_on_axis <= split) {
+ set_lte( cmp_result, exit_axis, split );
+ if (all( active_mask, cmp_result )) {
+
+
/////////////////////////////////////////////////////////////////////
+ // Case "A"
// Same side of the split, so the original interval is ok.
nearNode = nearNode->left();
continue;
}
+
///////////////////////////////////////////////////////////////////////
+ // Case "B"
+
// Otherwise update the near and far nodes, and then update
// the interval below.
farNode = nearNode->right();
nearNode = nearNode->left();
}
else {
+
// Check to see if entry and exit are on the same side.
- if (exitPos_coord_on_axis >= split) {
+ // if (exitPos_coord_on_axis >= split) {
+ set_gte( cmp_result, exit_axis, split );
+ if (all(active_mask, cmp_result)) {
+
+
/////////////////////////////////////////////////////////////////////
+ // Case "C"
+
nearNode = nearNode->right();
continue;
}
+
/////////////////////////////////////////////////////////////////////..
+ // Case "D"
+
// Update otherwise.
farNode = nearNode->left();
nearNode = nearNode->right();
}
+
/////////////////////////////////////////////////////////////////////////
// Update location on the traversal stack.
int tmp = exitPos;
@@ -285,99 +337,86 @@
// Update the far node.
// Specify a new exit node.
travStack[exitPos].node = farNode;
- travStack[exitPos].t = (split - origin[axis])* invDirection[axis];
travStack[exitPos].prev = tmp;
+
+ // Compute t value for exit position.
+ for (int p=0;p<TraversalPacketSize;++p) {
+ travStack[exitPos].t[p] =
+ (split - rays.getOrigin(which+p,axis)) *
+ rays.getInverseDirection(which+p,axis);
+ }
}
+
///////////////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////////////
// Check to see if we found a non-empty leaf node.
if (nearNode) {
- // Intersect the ray with a list of triangles.
- if (intersectTriangles(origin, direction,
- nearNode->listBegin(), nearNode->listSize(),
- rays.getMinT(which), isectData)
- && (isectData.rayHitTriIndex >= 0)) {
-
- if (isPickingEnabled()) {
- pickedTri = isectData.rayHitTriIndex;
- // cerr << "picked " << pickedTri << "\n";
- pickedBeginIndex = pickedEndIndex = pickedTri;
- while (pickedBeginIndex > 0 &&
- triToGroupMap->get(pickedBeginIndex-1)
- == triToGroupMap->get(pickedBeginIndex))
- pickedBeginIndex --;
- while (pickedEndIndex < tris->getLen()-1 &&
- triToGroupMap->get(pickedEndIndex+1)
- == triToGroupMap->get(pickedEndIndex))
- pickedEndIndex ++;
- // cerr << "picked begin " << pickedBeginIndex << " end " <<
pickedEndIndex << "\n";
-
- // cerr << "picked flag: " << (int)pickedFlag << std::endl;
- for (int i=pickedBeginIndex; i<=pickedEndIndex; i++)
- triFlags->set(i, pickedFlag);
+
/////////////////////////////////////////////////////////////////////////
+
/////////////////////////////////////////////////////////////////////////
+ // Intersect the rays with a list of triangles.
+ IntersectPacket intersect_packet( active_mask );
+ intersectTriangles(intersect_packet,
+ rays,
+ which,
+ nearNode->listBegin(),
+ nearNode->listSize());
+
+
+ // IntersectPacket::hit_mask[p] must reflect triangleindex >= 0
+
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ // Check against the hit record.
+ for (int p=0;p<TraversalPacketSize;++p) {
+ if (intersect_packet.hit_mask[p]) {
+
+ // Check the hit t against the ray packet min t.
+ intersect_packet.hit_mask[p] = rays.hit( which+p,
+ intersect_packet.t[p],
+ getMaterial(), this, 0 );
}
+ }
- // Check against the hit record, Note that tex coord mapper is null.
- if (rays.hit(which, isectData.rayHit.t, getMaterial(), this, 0 )) {
-
- // if (isectData.rayHit.t > t_epsilon) {
- // e.hitInfo.set_hit(isectData.rayHit.t, material, this, 0 );
-
- // e.normal = normals[isectData.rayHitTriIndex];
-
- //e.hitInfo.scratchpad<ScratchPadInfo>().normal =
normals[isectData.rayHitTriIndex];
+
/////////////////////////////////////////////////////////////////////////
+ // Interpolate normals for successful hits.
+ // normal = (n1 * u) + (n2 * v) + (n0 * (1 - u - v));
+ for (int p=0;p<TraversalPacketSize;++p) {
+ if (intersect_packet.hit_mask[p]) {
+
// Interpolate between the three vertices.
- Vectorf &n0 = normals[isectData.rayHitTriIndex][0];
- Vectorf &n1 = normals[isectData.rayHitTriIndex][1];
- Vectorf &n2 = normals[isectData.rayHitTriIndex][2];
-
- float u = isectData.rayHit.u;
- float v = isectData.rayHit.v;
-
- ScratchPadInfo& scratch_pad =
rays.scratchpad<ScratchPadInfo>(which);
+ Vectorf &n0 = normals[intersect_packet.hit_index[p]][0];
+ Vectorf &n1 = normals[intersect_packet.hit_index[p]][1];
+ Vectorf &n2 = normals[intersect_packet.hit_index[p]][2];
+
+ float u = intersect_packet.u[p];
+ float v = intersect_packet.v[p];
+
+ ScratchPadInfo& scratch_pad =
rays.scratchpad<ScratchPadInfo>(which+p);
scratch_pad.normal = (n1 * u) + (n2 * v) + (n0 * (1 - u - v));
-
-#if SHOW_DUPLICATES
- if (isectData.duplicate == 0)
- scratch_pad.payload = Color(RGB(1.0,1.0,1.0));
- else if (isectData.duplicate > 16)
- scratch_pad.payload = Color(RGB(1.0,0.0,1.0));
- else if (isectData.duplicate > 8)
- scratch_pad.payload = Color(RGB(1.0,0.0,0.0));
- else if (isectData.duplicate > 4)
- scratch_pad.payload = Color(RGB(1.0,1.0,0.0));
- else
- scratch_pad.payload = Color(RGB(0.0,0.0,1.0));
-#else
- unsigned char flag;
- if ( pickedTri > 0 &&
- /*pickedBeginIndex <= isectData.rayHitTriIndex &&
- isectData.rayHitTriIndex <= pickedEndIndex*/
- (flag=triFlags->get(isectData.rayHitTriIndex))!=0)
- {
- switch(flag) {
- case PICK_HIGHLIGHT:
- scratch_pad.payload = Color(RGB(1,1,1))-
- tris->get(isectData.rayHitTriIndex).payload;
- break;
- case PICK_REMOVE:
- scratch_pad.payload = Color(RGB(0,0,0));
- break;
- }
- } else
- scratch_pad.payload =
tris->get(isectData.rayHitTriIndex).payload;
-#endif
- // Check to make sure the found hit is inside the current cell.
- // if ((isectData.rayHit.t <= travStack[exitPos].t)/* &&
(isectData.rayHit.t > travStack[entryPos].t)*/)
- // break;
- }
+ scratch_pad.payload =
tris->get(intersect_packet.hit_index[p]).payload;
+ }
}
}
+ /////////////////////////////////////////////////////////////////////
// Check to see if the hit is inside the current cell.
- if (rays.getMinT(which) <= travStack[exitPos].t)
+ // if (rays.getMinT(which) <= travStack[exitPos].t)
+ // break
+
+ // Update the active_mask.
+ Mask cmp_result;
+ set_gt( cmp_result, &rays.getMinT(which), travStack[exitPos].t );
+
+ // And the active mask with the result of the comparsion.
+ // (only pay attention to bits which are both active and passed the
comparsion )
+ set_and( active_mask, active_mask, cmp_result );
+
+ // Check to see if any rays are active any longer.
+ if (none(active_mask)) {
break;
+ }
// Move to the next
entryPos = exitPos;
@@ -386,6 +425,41 @@
}
}
+
+///////////////////////////////////////////////////////////////////////////////
+// Simple kdtree functions.
+///////////////////////////////////////////////////////////////////////////////
+
+VerticalKDTree::VerticalKDTree( KDTree *kdtree_, Material *material_ )
+ : PrimitiveCommon( material_ ),
+ rootNode( kdtree_->rootNode ),
+ triIndices( kdtree_->triIndices ),
+ tris( kdtree_->tris ),
+ normals( kdtree_->normals )
+{
+ bbox.extendByBox( bbox );
+}
+VerticalKDTree::~VerticalKDTree() { };
+
+void VerticalKDTree::computeNormal(const RenderContext& /*context*/,
+ RayPacket& rays) const {
+
+ // Copy the normal out of the KDTree::ScratchPadInfo structure.
+ for (int i=rays.begin();i<rays.end();++i) {
+ rays.setNormal(i, rays.scratchpad<ScratchPadInfo>(i).normal);
+ }
+}
+
+void VerticalKDTree::computeBounds(const PreprocessContext&, BBox &box_ )
const {
+
+ box_.extendByBox( bbox );
+}
+
+void VerticalKDTree::computeBounds( BBox &box_ ) const {
+
+ box_.extendByBox( bbox );
+}
+
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@@ -607,18 +681,6 @@
return 1;
}
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-// KDTree Texture.
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-void KDTreeTexture::mapValues(const RenderContext& /*context*/,
- RayPacket& rays, Color results[]) const {
-
- for (int i=rays.begin();i<rays.end();++i) {
- results[i] = rays.scratchpad<Kdtree::KDTree::ScratchPadInfo>(i).payload;
- }
-}
Copied: trunk/Model/Groups/VerticalKDTree.h (from r858,
trunk/Model/Groups/KDTree.h)
==============================================================================
--- trunk/Model/Groups/KDTree.h (original)
+++ trunk/Model/Groups/VerticalKDTree.h Mon Jan 23 03:08:54 2006
@@ -3,8 +3,8 @@
The MIT License
- Copyright (c) 2005
- Silicon Graphics Inc. Mountain View California.
+ Copyright (c) 2006
+ Scientific Computing and Imaging Institute, Univeristy of Utah
License for the specific language governing rights and limitations under
Permission is hereby granted, free of charge, to any person obtaining a
@@ -26,276 +26,162 @@
DEALINGS IN THE SOFTWARE.
*/
-#ifndef __KD_TREE_H__
-#define __KD_TREE_H__
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// NOTE: Manta::Real must be "float" in order for CMake to include this code.
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+// Abe Stephens
+
+#ifndef __VERTICAL_KD_TREE_H__
+#define __VERTICAL_KD_TREE_H__
+
-#include <Model/Groups/Group.h>
#include <Core/Geometry/PointVector.h>
#include <Core/Geometry/BBox.h>
#include <Interface/RayPacket.h>
-
-#include <Model/Primitives/PrimitiveCommon.h>
-
#include <Interface/Texture.h>
-#include <Model/Groups/KDTreeLoader.h>
+#include <Model/Groups/KDTree.h>
#include <Model/Groups/varray.h>
+#include <Model/Groups/KdtreeParameters.h>
namespace Manta {
- // Note: Kdtree is the namespace: KDTree, KDTreeTransparent are classes
+ // Note: Kdtree is the namespace: KDTree, VerticalKDTree are classes
// in the namespace.
namespace Kdtree {
- // These values are used by both the KDTree and the TransparentKDTree
- enum { KDNODE_AXIS_MASK = 0x0003,
- KDNODE_LEFT_CHILD_MASK = 0x0008,
- KDNODE_RIGHT_CHILD_MASK = 0x0010,
- KDNODE_INTERNAL_MASK = ( KDNODE_LEFT_CHILD_MASK |
- KDNODE_RIGHT_CHILD_MASK )
- };
-
- // Data is stored in 32 bit floats.
- typedef VectorT<float,3> Vectorf;
- typedef PointT <float,3> Pointf;
-
///////////////////////////////////////////////////////////////////////////
- // TRIANGLE TRIANGLE TRIANGLE TRIANGLE TRIANGLE TRIANGLE TRIANGLE
TR
///////////////////////////////////////////////////////////////////////////
- class Triangle/*: public Geometry*/ {
+ // MASK MASK MASK MASK MASK MASK MASK MASK MASK MASK MASK MASK
+
///////////////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////////////
+ class Mask {
public:
- Pointf v[3]; // 3*3 floats = 9*4 bytes = 36 bytes
- Color payload; //
- Vectorf edge1, edge2; // 2*3 floats = 6*4 bytes = 24 bytes
- // the above are exactly 64 bytes
-
- Triangle()/* : Geometry()*/ { }
-
- Triangle(const float *tri, const Color &p) {
- v[0] = *(Pointf*)tri;
- v[1] = *(Pointf*)(tri+3);
- v[2] = *(Pointf*)(tri+6);
- payload = p;
- }
- Triangle(const Pointf *v_, const Color &p) {
- v[0] = v_[0]; v[1] = v_[1]; v[2] = v_[2];
- payload = p;
- }
- Triangle(const Pointf &v0_, const Pointf &v1_, const Pointf &v2_,
- const Color &p) {
- v[0] = v0_; v[1] = v1_; v[2] = v2_;
- payload = p;
- }
+ // Mask values.
+ typedef int Bool;
+ enum { True = 1,
+ False = 0 };
+
+ // Accessors.
+ Bool &operator[] (int i) { return data[i]; }
+ const Bool &operator[] (int i) const { return data[i]; }
- // Access an individual vertex.
- Pointf &operator[] (int i) { return v[i]; }
- const Pointf &operator[] (int i) const { return v[i]; }
-
- void getBound(BBox &bounds_) {
- bounds_.extendByPoint( v[0] );
- bounds_.extendByPoint( v[1] );
- bounds_.extendByPoint( v[2] );
+ // Constructor.
+ Mask() { };
+ Mask( Bool bool_ ) {
+ for (int p=0;p<TraversalPacketSize;++p) {
+ data[p] = bool_;
+ }
}
- };
-
-
///////////////////////////////////////////////////////////////////////////
- // TRIANGLE NORMALS TRIANGLE NORMALS TRIANGLE NORMALS TRIANGLE
NORMALS
-
///////////////////////////////////////////////////////////////////////////
- class TriangleNormal {
+
private:
- Vectorf normal[3];
- public:
- Vectorf &operator[] ( int i ) { return normal[i]; };
- const Vectorf &operator[] ( int i ) const { return normal[i]; };
+ // Actual stored values.
+ int data[TraversalPacketSize];
};
-
+
///////////////////////////////////////////////////////////////////////////
- // PACKED TRIANGLES PACKED TRIANGLES PACKED TRIANGLES PACKED TRIANGLES
///////////////////////////////////////////////////////////////////////////
- class PackedTriangles {
- VArray<Pointf> *_v0;
- VArray<Pointf> *_v1;
- VArray<Pointf> *_v2;
- VArray<int> *_payload;
- public:
- void pack(VArray<Triangle> *tris);
- Pointf& getV0(int i) { return _v0->_get(i); }
- Pointf& getV1(int i) { return _v1->_get(i); }
- Pointf& getV2(int i) { return _v2->_get(i); }
- int& getPayload(int i) { return _payload->_get(i); }
- };
-
-
+ // MASK OPERATORS MASK OPERATORS MASK OPERATORS MASK OPERATORS MASK
OPE
///////////////////////////////////////////////////////////////////////////
- // Swap the endianness of a variable.
- template< typename T >
- T endian_swap( T in ) {
- T out;
- char *pin = (char *)∈
- char *pout = (char *)&out;
-
- for (int i=0;i<sizeof(T);++i) {
- pout[i] = pin[sizeof(T)-1-i];
+
///////////////////////////////////////////////////////////////////////////
+
+ static inline void set_lte( Mask &result, float
vec[TraversalPacketSize], float scalar ) {
+ for (int p=0;p<TraversalPacketSize;++p) {
+ result[p] = (vec[p] <= scalar);
}
-
- return out;
}
- // Check the endianness of this machine.
- inline bool is_big_endian() {
-
- unsigned int x = 0x00112233;
- char *p = (char *)&x;
-
- return (p[0] == 0x00);
+ static inline void set_gte( Mask &result, float
vec[TraversalPacketSize], float scalar ) {
+ for (int p=0;p<TraversalPacketSize;++p) {
+ result[p] = (vec[p] >= scalar);
+ }
}
-
///////////////////////////////////////////////////////////////////////////
- // KDTREE INTERNAL NODE
-
///////////////////////////////////////////////////////////////////////////
- struct KDTreeInternalNode {
- unsigned char flags;
- unsigned int left;
- float split;
-
- void endian_swap() {
- left = Manta::Kdtree::endian_swap( left );
- split = Manta::Kdtree::endian_swap( split );
+ static inline void set_gt( Mask &result, float
vec0[TraversalPacketSize], float vec1[TraversalPacketSize] ) {
+ for (int p=0;p<TraversalPacketSize;++p) {
+ result[p] = (vec0[p] > vec1[p]);
}
- };
+ }
-
///////////////////////////////////////////////////////////////////////////
- // KDTREE LEAF NODE
-
///////////////////////////////////////////////////////////////////////////
- struct KDTreeLeafNode {
- unsigned char flags;
- unsigned int listBegin;
- unsigned int listLen;
-
- void endian_swap() {
- listBegin = Manta::Kdtree::endian_swap( listBegin );
- listLen = Manta::Kdtree::endian_swap( listLen );
+ static inline void set_and( Mask &result, const Mask &vec0, const Mask
&vec1 ) {
+ for (int p=0;p<TraversalPacketSize;++p) {
+ result[p] = (vec0[p] && vec1[p]);
}
- };
-
-
///////////////////////////////////////////////////////////////////////////
- // KDTREE NODE
-
///////////////////////////////////////////////////////////////////////////
- union KDTreeNode {
- KDTreeInternalNode internal;
- KDTreeLeafNode leaf;
+ }
- bool hasLeftChild() const {
- return internal.flags & KDNODE_LEFT_CHILD_MASK;
- }
- bool hasRightChild() const {
- return internal.flags & KDNODE_RIGHT_CHILD_MASK;
- }
- KDTreeNode* left() { return hasLeftChild()?this+internal.left :
NULL; }
- KDTreeNode* right() {
- return hasRightChild()?
- (hasLeftChild()?this+internal.left+1:this+internal.left) : 0;
+ static inline bool all( const Mask &active, const Mask &mask ) {
+ bool result = mask[0];
+ for (int p=1;p<TraversalPacketSize;++p) {
+ result = result && (mask[p] || (!active[p]));
}
+ return result;
+ }
- KDTreeNode *getChild( short int i ) {
- return this + internal.left +
- (i & ((internal.flags&KDNODE_LEFT_CHILD_MASK) >> 3));
- };
-
- float split() const { return internal.split; }
- bool isInternal() const {
- return internal.flags & KDNODE_INTERNAL_MASK;
+ static inline bool any( const Mask &mask ) {
+ bool result = mask[0];
+ for (int p=1;p<TraversalPacketSize;++p) {
+ result = (result || mask[p]);
}
- unsigned int axis() const { return internal.flags & KDNODE_AXIS_MASK;
}
-
- unsigned int listBegin() { return leaf.listBegin; }
- unsigned int listSize() { return leaf.listLen; }
-
- void endian_swap() {
-
- internal.endian_swap();
+ }
- if (hasLeftChild())
- left()->endian_swap();
- if (hasRightChild())
- right()->endian_swap();
- }
- };
+ static inline bool none( const Mask &mask ) {
+ return !any( mask );
+ }
///////////////////////////////////////////////////////////////////////////
- // RAY HIT TRIANGLE
///////////////////////////////////////////////////////////////////////////
- class RayHit_Triangle {
+ // INTERSECT PACKET INTERSECT PACKET INTERSECT PACKET INTERSECT
PACKET
+
///////////////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////////////
+ class IntersectPacket {
public:
+ Mask active_mask;
+ Mask hit_mask;
- Real t, u, v;
-
- RayHit_Triangle() {
- }
-
- RayHit_Triangle(Real tt, Real uu, Real vv) {
- t = tt; u = uu; v = vv;
- }
- void computeHitPoint(Point &hitP,
- const Point &v0, const Point &v1, const Point &v2)
- {
- hitP = Point( Vector(v0)*((Real)1.0 - u - v) +
- Vector(v1)*u +
- Vector(v2)*v );
- }
-
- Real computeDistance2(const Ray &ray,
- const Point &v0, const Point &v1, const Point
&v2)
- {
- Point hitP;
- computeHitPoint( hitP, v0, v1, v2 );
-
- Vector distance = (hitP - ray.origin());
- return Dot(distance,distance);
- }
+ int hit_index[TraversalPacketSize];
- Real computeDistance2(const Point &point,
- Point &v0, const Point &v1, const Point &v2)
- {
- Point hitP;
- computeHitPoint(hitP, v0, v1, v2);
+ float t[TraversalPacketSize];
+ float u[TraversalPacketSize];
+ float v[TraversalPacketSize];
- Vector distance = (hitP - point);
- return Dot(distance,distance);
- }
- };
-
-
-
///////////////////////////////////////////////////////////////////////////
- // RAY TRIANGLE INTERSECT USER DATA
-
///////////////////////////////////////////////////////////////////////////
- struct RayTriIntersectUserData {
- int rayHitTriIndex;
- RayHit_Triangle rayHit;
- float eyeToHitDist2;
- int duplicate;
+ IntersectPacket( const Mask &active_mask_ )
+ : active_mask( active_mask_ ) { };
};
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
- // KDTREE CLASS PROPER
+ // VERTICAL KDTREE CLASS PROPER
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
- class KDTree : public PrimitiveCommon {
+ class VerticalKDTree : public PrimitiveCommon {
+ public:
+ typedef KDTree::ScratchPadInfo ScratchPadInfo;
- // Transparent KDTree will use data owned by this kdtree.
- friend class TransparentKDTree;
+
/////////////////////////////////////////////////////////////////////////
+ // Constructor.
+ VerticalKDTree( KDTree *kdtree_, Material *material_ );
+ virtual ~VerticalKDTree();
- // The Kdtree::load(...) function is used to load data into the kdtree.
- friend int Manta::Kdtree::load( KDTree *kdtree, const char *filename,
- int np );
+
/////////////////////////////////////////////////////////////////////////
+ // Primitive Interface.
+ virtual void intersect(const RenderContext& context, RayPacket& rays)
const;
+ void computeNormal (const RenderContext& context, RayPacket& rays)
const;
+ void computeBounds (const PreprocessContext&, BBox &box_ ) const;
+ void computeBounds ( BBox &box_ ) const;
- protected:
+
/////////////////////////////////////////////////////////////////////////
+ // Accessors.
+ void setRootNode( KDTreeNode *node ) { rootNode = node; };
+ KDTreeNode *getRootNode() { return rootNode; };
+
+ private:
BBox bbox;
KDTreeNode *rootNode;
- private:
VArray<int> *triIndices;
VArray<Triangle> *tris;
TriangleNormal *normals;
@@ -303,106 +189,29 @@
VArray<int> *triToGroupMap;
VArray<int> *groupToNameMap;
VArray<char> *groupNames;
- bool __pickingEnabled;
- bool pickingEnabled;
- mutable long long pickedTri;
- mutable int pickedBeginIndex, pickedEndIndex;
- VArray<Color> pickedSavedColors;
VArray<unsigned char> *triFlags;
- unsigned char pickedFlag;
- public:
- enum {
- PICK_HIGHLIGHT = 1,
- PICK_REMOVE = 2,
- };
-
- void enablePicking() {
- if (__pickingEnabled)
- pickingEnabled = true;
- }
- void disablePicking() { pickingEnabled = false; }
- bool isPickingEnabled() const { return
pickingEnabled&&__pickingEnabled; }
- void resetPicking() {
- pickedTri = -1;
- triFlags->clear();
- }
- void __setPicking(bool flag) { __pickingEnabled =
flag; }
-
- void setPickedFlag(unsigned char flag) { pickedFlag =
flag; }
- unsigned char getPickedFlag() { return pickedFlag; }
-
- protected:
- // Copy data pointers from another kdtree. (Used by derived classes.)
- KDTree( KDTree *kdtree_, Material *material_ ) :
- PrimitiveCommon( material_ ),
- rootNode( kdtree_->rootNode ), triIndices( kdtree_->triIndices ),
- tris( kdtree_->tris ), normals( kdtree_->normals )
- {
- bbox.extendByBox( bbox );
- pickedFlag = PICK_HIGHLIGHT;
- }
- // This method intersects a list of triangles with the ray.
- int intersectTriangles(const Pointf& origin, const Vectorf& direction,
- unsigned int listBegin, unsigned int listSize,
- float maxDist,
- RayTriIntersectUserData &isectData) const;
+ // This method intersects a list of triangles with the rays.
+ void intersectTriangles(IntersectPacket &intersect_packet,
+ const RayPacket &rays,
+ int which,
+ unsigned int listBegin,
+ unsigned int listSize ) const;
// This method is called to intersect a single ray with the kdtree.
+ void intersect_node( const RenderContext &context,
+ const Mask &valid_mask,
+ RayPacket &rays,
+ int which,
+ float minDist[TraversalPacketSize],
+ float maxDist[TraversalPacketSize] ) const;
+
void intersect_node( KDTreeNode *startNode,
RayPacket& rays, int which,
RayTriIntersectUserData &isectData,
const RenderContext &context,
float minDist, float maxDist) const;
- public:
- // Constructor.
- KDTree( Material *material_ ) : PrimitiveCommon( material_ ) {
- __pickingEnabled = true;
- pickingEnabled = false;
- pickedTri = -1;
- pickedFlag = PICK_HIGHLIGHT;
- };
-
- // This structure is used to record info about the hit.
- struct ScratchPadInfo {
- Vector normal; // Normal of the intersected face.
- Color payload; // Payload of the intersected face.
- Real a, b, c;
- };
-
- virtual ~KDTree() {}
-
- // Primitive Interface.
- virtual void intersect(const RenderContext& context, RayPacket& rays)
const;
- void computeNormal (const RenderContext& context, RayPacket& rays)
const;
- void computeBounds (const PreprocessContext& /*context*/,
- BBox &box_ ) const
- {
- box_.extendByBox( bbox );
- }
- void computeBounds ( BBox &box_ ) const { box_.extendByBox( bbox ); }
-
- // This function is called to load the data.
- // np specifies the number of workers, for certain loading functions.
- int load( const char *fn, int np );
-
- // Accessors (used by gui to examine kdtree).
- void setRootNode( KDTreeNode *node ) { rootNode = node; };
- KDTreeNode *getRootNode() { return rootNode; };
-
- };
-
-
///////////////////////////////////////////////////////////////////////////
-
///////////////////////////////////////////////////////////////////////////
- // KDTREE TEXTURE (For extracting color information from the kdtree
- // scratch pad.
-
///////////////////////////////////////////////////////////////////////////
-
///////////////////////////////////////////////////////////////////////////
- class KDTreeTexture : public Texture<Color> {
- public:
- virtual void mapValues(const RenderContext& context, RayPacket& rays,
- Color results[]) const;
};
} // end namespace Kdtree
Modified: trunk/scenes/boeing777.cc
==============================================================================
--- trunk/scenes/boeing777.cc (original)
+++ trunk/scenes/boeing777.cc Mon Jan 23 03:08:54 2006
@@ -5,7 +5,7 @@
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"),
@@ -46,6 +46,7 @@
#include <Model/Groups/Group.h>
#include <Model/Groups/KDTree.h>
#include <Model/Groups/TransparentKDTree.h>
+#include <Model/Groups/VerticalKDTree.h>
#include <Model/Lights/PointLight.h>
#include <Model/Lights/HeadLight.h>
#include <Model/Materials/Lambertian.h>
@@ -75,6 +76,7 @@
enum CuttingPlaneType { CUTTING_NONE, CUTTING_DEFAULT, CUTTING_SPECIFIED };
enum MtlType { MTL_PHONG, MTL_AMBIENT, MTL_FLAT };
+enum TraversalType { TRAVERSAL_SINGLE, TRAVERSAL_VERTICAL };
///////////////////////////////////////////////////////////////////////////
// This function constructs the Boeing 777 Test Scene using a KdTree.
@@ -90,6 +92,8 @@
int workers_np = 1;
MtlType material_type = MTL_PHONG;
+
+ TraversalType traversal = TRAVERSAL_SINGLE;
Real alpha = 1;
Real ambient_dist = 5;
@@ -115,7 +119,6 @@
else if (args[i] == "-alpha") {
// Note this just specifies that a TransparentKDTree should be created
as well.
-
use_transparency = true;
if (!getArg<Real>(i, args, alpha ))
throw IllegalArgument("boeing777 -alpha
<alpha>", i, args);
@@ -150,16 +153,20 @@
else if (args[i] == "-bg") {
bg_method = args[++i];
}
+ else if (args[i] == "-vertical") {
+ traversal = TRAVERSAL_VERTICAL;
+ }
else {
cerr << "Valid options for boeing777:" << endl;
cerr << "-file <filename>" << endl;
cerr << "-np <num build workers>" << endl;
cerr << "-cutting [<point> <normal>]" << endl;
cerr << "-alpha <alpha>" << endl;
- cerr << "-lambertianalt (alpha=1.0 without transparent traversal)" <<
endl;
cerr << "-phong <exp> <reflection> **default**" << endl;
cerr << "-ambient <max dist> <secondary rays>" << endl;
cerr << "-bg marble Currently only marble is supported.\n";
+ cerr << "-flat\n";
+ cerr << "-vertical -- Use vertical traversal code.\n";
throw IllegalArgument( "boeing777", i, args );
}
@@ -209,16 +216,21 @@
// Determine if we should start with a transparent kdtree or not.
Primitive *kd_primitive = kdtree;
- if (use_transparency) {
- TransparentKDTree *transparent = new TransparentKDTree(
kdtree,
- // Just copy the
color out of the
- // hit info.
- new Flat( new
KDTreeTexture ) );
- transparent->setAlpha( alpha );
- kd_primitive = transparent;
- }
-
-
+ if (traversal == TRAVERSAL_SINGLE) {
+ if (use_transparency) {
+ TransparentKDTree *transparent = new TransparentKDTree( kdtree,
+ // Just copy
the color out of the
+ // hit info.
+ new Flat( new
KDTreeTexture ) );
+ transparent->setAlpha( alpha );
+ kd_primitive = transparent;
+ }
+ }
+ else if (traversal == TRAVERSAL_VERTICAL) {
+ // Create a vertical kdtree.
+ kd_primitive = new VerticalKDTree( kdtree, kd_material );
+ }
+
////////////////////////////////////////////////////////////////////////////
// Compute the middle of the model for a cutting plane.
if (cutting_type == CUTTING_DEFAULT) {
- [MANTA] r860 - in trunk: Core/Geometry Interface Model/Groups scenes, abe, 01/23/2006
Archive powered by MHonArc 2.6.16.