Text archives Help
- From: abe@sci.utah.edu
- To: manta@sci.utah.edu
- Subject: [MANTA] r873 - in trunk: Core/Util Interface Model/Groups fox/FManta scenes
- Date: Sun, 29 Jan 2006 01:24:56 -0700 (MST)
Author: abe
Date: Sun Jan 29 01:24:55 2006
New Revision: 873
Added:
trunk/Core/Util/Align.h
trunk/Model/Groups/SSEKDTree.cc
trunk/Model/Groups/SSEKDTree.h
Modified:
trunk/Interface/RayPacket.h
trunk/Model/Groups/CMakeLists.txt
trunk/Model/Groups/KDTree.h
trunk/Model/Groups/VerticalKDTree.cc
trunk/Model/Groups/VerticalKDTree.h
trunk/fox/FManta/FMantaWindow.cc
trunk/fox/FManta/FMantaWindow.h
trunk/scenes/boeing777.cc
Log:
Modified command line args for debugging
M scenes/boeing777.cc
Added macro which may be redefined for different compilers to specify
alignment.
A Core/Util/Align.h
Added initial working version of SSE kdtree traversal.
A Model/Groups/SSEKDTree.h
A Model/Groups/SSEKDTree.cc
M Model/Groups/VerticalKDTree.cc
M Model/Groups/VerticalKDTree.h
M Model/Groups/KDTree.h
M Model/Groups/CMakeLists.txt
M Interface/RayPacket.h
Added ability to enter pixel coordinates to shoot debugging ray
M fox/FManta/FMantaWindow.cc
M fox/FManta/FMantaWindow.h
Added: trunk/Core/Util/Align.h
==============================================================================
--- (empty file)
+++ trunk/Core/Util/Align.h Sun Jan 29 01:24:55 2006
@@ -0,0 +1,41 @@
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2005-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.
+*/
+
+#ifndef _CORE_UTIL_ALIGN__H
+#define _CORE_UTIL_ALIGN__H
+
+
+#define MANTA_ALIGN(size) \
+ __declspec( align( (size) ) )
+
+#define MANTA_IS_ALIGNED(addr,size) \
+ ((((size_t)(addr))%(size))==0)
+
+
+#endif
+
Modified: trunk/Interface/RayPacket.h
==============================================================================
--- trunk/Interface/RayPacket.h (original)
+++ trunk/Interface/RayPacket.h Sun Jan 29 01:24:55 2006
@@ -6,6 +6,7 @@
#include <Core/Geometry/Ray.h>
#include <Core/Math/Expon.h>
#include <Core/Util/Assert.h>
+#include <Core/Util/Align.h>
#include <Interface/Parameters.h>
#include <Interface/Primitive.h>
#include <Interface/TexCoordMapper.h>
@@ -14,6 +15,8 @@
namespace Manta {
class Material;
class RenderContext;
+
+ MANTA_ALIGN(16)
class RayPacketData {
public:
enum {
@@ -41,14 +44,16 @@
TexCoordMapperCP hitTex[Size];
// Real-based arrays
+ MANTA_ALIGN(16) Real origin[3][Size];
+ MANTA_ALIGN(16) Real direction[3][Size];
+ MANTA_ALIGN(16) Real inverseDirection[3][Size];
+ MANTA_ALIGN(16) Real minT[Size];
+
Real image[2][Size];
- Real origin[3][Size];
- Real direction[3][Size];
Real normal[3][Size];
Real hitPosition[3][Size];
- Real minT[Size];
Real texCoords[3][Size];
- Real inverseDirection[3][Size];
+
// Color-based arrays
Color::ComponentType color[Manta::Color::NumComponents][Size];
Modified: trunk/Model/Groups/CMakeLists.txt
==============================================================================
--- trunk/Model/Groups/CMakeLists.txt (original)
+++ trunk/Model/Groups/CMakeLists.txt Sun Jan 29 01:24:55 2006
@@ -35,6 +35,9 @@
${Manta_Groups_SRCS}
Groups/VerticalKDTree.h
Groups/VerticalKDTree.cc
+
+ Groups/SSEKDTree.cc
+ Groups/SSEKDTree.h
)
# Otherwise include a stub implementation.
Modified: trunk/Model/Groups/KDTree.h
==============================================================================
--- trunk/Model/Groups/KDTree.h (original)
+++ trunk/Model/Groups/KDTree.h Sun Jan 29 01:24:55 2006
@@ -296,6 +296,7 @@
// Transparent KDTree will use data owned by this kdtree.
friend class TransparentKDTree;
friend class VerticalKDTree;
+ friend class SSEKDTree;
// 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/SSEKDTree.cc
==============================================================================
--- (empty file)
+++ trunk/Model/Groups/SSEKDTree.cc Sun Jan 29 01:24:55 2006
@@ -0,0 +1,758 @@
+
+
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ Copyright (c) 2005
+ 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/SSEKDTree.h>
+#include <Model/Groups/varray.h>
+
+#include <Model/Intersections/AxisAlignedBox.h>
+#include <Interface/Context.h>
+
+#include <SCIRun/Core/Thread/Time.h>
+#include <SCIRun/Core/Thread/Thread.h>
+#include <SCIRun/Core/Thread/Runnable.h>
+#include <SCIRun/Core/Thread/Barrier.h>
+
+#include <sgi_stl_warnings_off.h>
+#include <iostream>
+#include <sgi_stl_warnings_off.h>
+
+#include <stdio.h>
+
+using namespace Manta;
+using namespace Manta::Kdtree;
+using namespace SCIRun;
+using std::cerr;
+using std::endl;
+
+#define SHOW_DUPLICATES 0
+
+//static unsigned long global_counter = 0;
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// Triangle Intersection routines.
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+inline void intersectTriangleEdgeSSE( IntersectPacket *result,
+ const RayPacket &rays,
+ const int which,
+ const int tri_index,
+ const Vector &edge1,
+ const Vector &edge2,
+ const Point &p0 );
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// INTERSECT TRIANGLES INTERSECT TRIANGLES INTERSECT TRIANGLES INTERSECT
TRI
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+namespace Manta {
+ namespace Kdtree {
+ MANTA_ALIGN(16)
+ struct IntersectPacket {
+ union { int active_mask[4]; __m128 active_mask4; };
+ union { int hit_mask[4]; __m128 hit_mask4; };
+ union { float t[4]; __m128 t4; };
+ union { float u[4]; __m128 u4; };
+ union { float v[4]; __m128 v4; };
+
+ int hit_index[TraversalPacketSize];
+ };
+ };
+};
+
+void SSEKDTree::intersectTriangles(IntersectPacket *intersect_packet,
+ const RayPacket &rays,
+ int which,
+ unsigned int listBegin,
+ unsigned int listSize ) const {
+
+
+ // Initialize nearset variables.
+ intersect_packet->hit_mask4 = _mm_set1_ps( 0.0 );
+ intersect_packet->t4 = _mm_load_ps( &rays.getMinT(which) );
+
+ // Iterate over all of the triangles.
+ unsigned int listEnd = listBegin+listSize;
+
+#pragma swp
+ for (unsigned int i = listBegin; i<listEnd; ++i) {
+
+ const int index = triIndices->get( i );
+ const Triangle &tri = tris->get( index );
+
+ // Intersect the packet with one triangle.
+ intersectTriangleEdgeSSE( intersect_packet,
+ rays,
+ which,
+ index,
+ tri.edge1,
+ tri.edge2,
+ tri[0] );
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// This is the Manta interface method.
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+void SSEKDTree::intersect(const RenderContext& context, RayPacket& rays)
const
+{
+ rays.normalizeDirections();
+ rays.computeInverseDirections();
+ rays.computeSigns();
+
+ // Find runs of rays with the same direction signs.
+ for(int i = rays.begin();i<rays.end();){
+
+ int sign = rays.getSignMask( i );
+ int end = i+1;
+
+ // Find the end of the run.
+ while(end < rays.end() && (rays.getSignMask(end)==sign))
+ end++;
+
+ // Create a sub packet.
+ RayPacket subPacket(rays, i, end);
+
+ // Set the constant sign flag.
+ subPacket.resetFlag( RayPacket::HaveSigns );
+
+ subPacket.computeSigns();
+ assert( subPacket.getFlag( RayPacket::ConstantSigns ) );
+
+
///////////////////////////////////////////////////////////////////////////
+ // Make sure that the traversal packet starts with an index that is
+ // TraversalPacketSize aligned.
+ int which = subPacket.begin();
+ int p_start = (which % TraversalPacketSize);
+
+ // Set which to be TraversalPacketSize aligned.
+ // The un-used rays are already set to false.
+ which -= p_start;
+
+
////////////////////////////////////////////////////////////////////////////
+ // Iterate over sub groups of rays.
+ for(;which<subPacket.end();which+=TraversalPacketSize) {
+
+ Real minDist[TraversalPacketSize];
+ Real maxDist[TraversalPacketSize];
+
+ Mask valid_mask( Mask::False );
+
+ // Compute min and max distance for the kdtree.
+ for (int
p=p_start;(p<TraversalPacketSize)&&((which+p)<subPacket.end());++p) {
+
+ assert(getMaterial());
+
+ // Intersect the ray with the bounding box for the group.
+ valid_mask[p] = Intersection::intersectAaBox( bbox,
+ minDist[p],
+ maxDist[p],
+
subPacket.getRay(which+p),
+
subPacket.getSigns(which+p),
+
subPacket.getInverseDirection(which+p));
+#if 0
+ if (p_start && valid_mask[p]) {
+ subPacket.scratchpad<ScratchPadInfo>(which+p).payload =
Color(RGB(1,0,0));
+
assert(rays.hit(which+p,T_EPSILON*8,getMaterial(),this,(TexCoordMapper *)1));
+ }
+#endif
+
+ // Determine the actual minimum distance.
+ minDist[p] = SCIRun::Max( minDist[p], T_EPSILON );
+ maxDist[p] = SCIRun::Min( maxDist[p], subPacket.getMinT(which+p) );
+ }
+
+ // Check to see if a traversal is necessary.
+ if (any(valid_mask)) {
+
+ // Make sure that the vector operations won't overflow the ray
packet.
+ assert( (which+TraversalPacketSize) <= RayPacket::MaxSize );
+
+ // Intersect the subpacket with the tree.
+ intersect_node( context, valid_mask, subPacket, which, p_start,
minDist, maxDist );
+ }
+
+ // Returned to alignment for additional rays in the packet.
+ p_start = 0;
+
+ }
+
+
///////////////////////////////////////////////////////////////////////////
+ // Find the next run.
+ i=end;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// This function performs the KD-Tree Traversal.
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+// Traversal Stack Entry.
+MANTA_ALIGN(16) struct Stack {
+ union {
+ float t_near[TraversalPacketSize];
+ __m128 t_near4;
+ };
+ union {
+ float t_far [TraversalPacketSize];
+ __m128 t_far4;
+ };
+ __m128 mask;
+ KDTreeNode* node;
+ char padding[8];
+};
+
+void SSEKDTree::intersect_node( const RenderContext &context,
+ const Mask &valid_mask,
+ RayPacket &rays,
+ int which,
+ int p_start,
+ float minDist[TraversalPacketSize],
+ float maxDist[TraversalPacketSize] )
const
+{
+
+
/////////////////////////////////////////////////////////////////////////////
+ // Stack pointers.
+ KDTreeNode *nearNode = rootNode;
+ KDTreeNode *farNode;
+
+
/////////////////////////////////////////////////////////////////////////////
+ // Keep a stack of entry and exit positions into the traversal nodes.
+ MANTA_ALIGN(16) Stack stack[128];
+ int stack_index = 1;
+
+ // Initialize the stack.
+ for (int p=0;p<TraversalPacketSize;++p) {
+ stack[1].t_near[p] = minDist[p];
+ stack[1].t_far [p] = maxDist[p];
+ }
+
+ // Start at the root.
+ stack[1].node = rootNode;
+
+
/////////////////////////////////////////////////////////////////////////////
+ // Mask to keep track of rays that still need to find closest
intersections.
+ __m128 live_mask;
+ for (int p=0;p<TraversalPacketSize;++p) {
+ ((int *)(&live_mask))[p] = (valid_mask[p]) ? 0xffffffff : 0x0;
+ }
+ stack[1].mask = live_mask;
+
+ // if (rays.getFlag( RayPacket::DebugPacket )) std::cerr << "valid_mask: "
<< valid_mask << "\n";
+
+
/////////////////////////////////////////////////////////////////////////////
+ // Load the ray origins and directions into registers.
+ const __m128 origin4[3] = {
+ _mm_load_ps( &rays.getOrigin(which,0) ),
+ _mm_load_ps( &rays.getOrigin(which,1) ),
+ _mm_load_ps( &rays.getOrigin(which,2) ) };
+
+ const __m128 inv_direction4[3] = {
+ _mm_load_ps( &rays.getInverseDirection(which,0) ),
+ _mm_load_ps( &rays.getInverseDirection(which,1) ),
+ _mm_load_ps( &rays.getInverseDirection(which,2) ) };
+
+ // Process nodes on the stack.
+ while (stack_index) {
+
+
///////////////////////////////////////////////////////////////////////////
+ // Pop off the node on top of the stack.
+ KDTreeNode *node = stack[stack_index].node;
+
+ // Copy t_near and t_far from the stack.
+ __m128 t_near = stack[stack_index].t_near4;
+ __m128 t_far = stack[stack_index].t_far4;
+
+ // Obtain the active mask for this subtree.
+ __m128 active_mask = stack[stack_index].mask;
+
+#if 0
+ if (rays.getFlag( RayPacket::DebugPacket )) {
+ std::cerr << "P " << stack_index << " ";
+ std::cerr << "\t"; M128_DEBUG(rays,active_mask);
+ std::cerr << "\t"; M128_DEBUG(rays,t_near);
+ std::cerr << "\t"; M128_DEBUG(rays,t_far);
+ }
+#endif
+
+ // Pop stack.
+ stack_index--;
+
+ /////////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////////////
+ // Traverse down to a leaf.
+ while (node && node->isInternal()) {
+
+ // Obtain axis and split point.
+ const int axis = node->axis();
+ const __m128 split = _mm_set1_ps( node->split() );
+
+ // Identify near_index and far_index.
+ assert( rays.getFlag( RayPacket::ConstantSigns ) );
+
+ const int near_index = rays.getSign(which+p_start,axis);
+ const int far_index = (1 - near_index);
+
+
/////////////////////////////////////////////////////////////////////////
+ // Compute t_split.
+ __m128 t_split = _mm_mul_ps( _mm_sub_ps( split,
+ origin4[axis] ),
+ inv_direction4[axis] );
+
+#define SSE_XOR( A, B ) \
+ _mm_or_ps( _mm_andnot_ps( (B), (A) ), \
+ _mm_andnot_ps( (A), (B) ) )
+
+#define SSE_ALL( mask, cmp ) \
+ _mm_movemask_ps( SSE_XOR( _mm_and_ps( (mask), \
+ (cmp) ), \
+ (mask) ) ) == 0
+
+
/////////////////////////////////////////////////////////////////////////
+ // Classify the case.
+ // Mask cmp_result;
+ // set_lte( cmp_result, t_split, t_near );
+// #if 0
+ __m128 cmp_result = _mm_cmple_ps( t_split, t_near );
+ if (SSE_ALL( active_mask, cmp_result)) {
+
+
///////////////////////////////////////////////////////////////////////
+ // Case I: "Near Only"
+
+ // if (rays.getFlag( RayPacket::DebugPacket )) { std::cerr << "A\n";
}
+
+ // Update the current node.
+ node = node->getChild( far_index );
+
+ // No stack operations.
+ continue;
+ }
+
+ // set_gte( cmp_result, t_split, t_far );
+ cmp_result = _mm_cmpge_ps( t_split, t_far );
+ if (SSE_ALL( active_mask, cmp_result)) {
+
+
///////////////////////////////////////////////////////////////////////
+ // Case II: "Far Only"
+
+ // if (rays.getFlag( RayPacket::DebugPacket )) { std::cerr << "B\n";
}
+
+ // Update the current node.
+ node = node->getChild( near_index );
+
+ // No stack operations.
+ continue;
+ }
+// #endif
+
/////////////////////////////////////////////////////////////////////////
+ // Otherwise:
+
+ // Case III "Both" -- Push far node on stack.
+#if 0
+ if (rays.getFlag( RayPacket::DebugPacket )) {
+ std::cerr << "C\n";
+ }
+#endif
+ // Check to make sure some rays hit the far child.
+ cmp_result = _mm_and_ps( active_mask,
+ _mm_cmple_ps( t_split, t_far ) );
+ if (_mm_movemask_ps( cmp_result )) {
+ stack_index++;
+ stack[stack_index].node = node->getChild( far_index );
+ stack[stack_index].mask = cmp_result;
+
+ // Copy t_split and t_far to the stack.
+ stack[stack_index].t_near4 = t_split;
+ stack[stack_index].t_far4 = t_far;
+#if 0
+ if (rays.getFlag( RayPacket::DebugPacket )) {
+ std::cerr << "\tPush node: " << stack_index << " ";
+ M128_DEBUG(rays,stack[stack_index].mask);
+ }
+#endif
+ }
+#if 0
+ else {
+ if (rays.getFlag( RayPacket::DebugPacket )) {
+ std::cerr << "\tPush node: <skipped> ";
+ M128_DEBUG(rays,cmp_result);
+ }
+ }
+#endif
+
+ // Check to make sure something hits the near node.
+ cmp_result = _mm_and_ps( active_mask,
+ _mm_cmple_ps( t_near, t_far ) );
+ if (_mm_movemask_ps( cmp_result )) {
+
+ // Update the current node.
+ node = node->getChild( near_index );
+ active_mask = cmp_result;
+
+ // Copy t_split to t_far.
+ t_far = t_split;
+#if 0
+ if (rays.getFlag( RayPacket::DebugPacket )) {
+ std::cerr << "\tNear node: ";
+ M128_DEBUG(rays,active_mask);
+ }
+#endif
+ }
+ else {
+ node = 0;
+#if 0
+ if (rays.getFlag( RayPacket::DebugPacket )) {
+ std::cerr << "\tNear node: <skipped> ";
+ M128_DEBUG(rays,cmp_result);
+ }
+#endif
+ }
+
+
+ }
+
+
///////////////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////////////
+ // Check to see if we found a non-empty leaf node.
+ if (node) {
+
+
/////////////////////////////////////////////////////////////////////////
+
/////////////////////////////////////////////////////////////////////////
+ // Intersect the rays with a list of triangles.
+
+# if 0
+ if (rays.getFlag( RayPacket::DebugPacket )) {
+ std::cerr << "Leaf Intersect: " << active << "\n";
+ std::cerr << " leaf: "; M128_DEBUG(rays,active_mask);
+ std::cerr << " leaf: "; M128_DEBUG(rays,live_mask);
+ }
+#endif
+ IntersectPacket intersect_packet;
+ intersect_packet.active_mask4 = active_mask;
+
+ intersectTriangles(&intersect_packet,
+ rays,
+ which,
+ node->listBegin(),
+ node->listSize());
+
+ ///////////////////////////////////////////////////////////////////////
+ ///////////////////////////////////////////////////////////////////////
+ // 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 );
+ }
+ }
+
+
/////////////////////////////////////////////////////////////////////////
+ // Interpolate normals for successful hits.
+ // normal = (n1 * u) + (n2 * v) + (n0 * (1 - u - v));
+ for (int p=0;p<TraversalPacketSize;++p) {
+
+
+ // Note that hit_mask[p] is only set to true when a hit occurs and
+ // active_mask[p] is true.
+ if (intersect_packet.hit_mask[p]) {
+
+ assert( intersect_packet.hit_index[p] < tris->getLen() );
+
+ // Interpolate between the three vertices.
+ 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];
+
+ // Copy values to the scratchpad.
+ ScratchPadInfo& scratch_pad =
rays.scratchpad<ScratchPadInfo>(which+p);
+ scratch_pad.normal = (n1 * u) + (n2 * v) + (n0 * (1 - u - v));
+ scratch_pad.payload =
tris->get(intersect_packet.hit_index[p]).payload;
+ scratch_pad.a = u;
+ scratch_pad.b = v;
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /////////////////////////////////////////////////////////////////////
+ // Check to see if the hit is inside the current cell.
+// # if 0
+
+ __m128 min_t = _mm_load_ps( &rays.getMinT(which) );
+
+ // Only turn off active rays which terminate in the current node.
+ static const __m128 nan = _mm_set1_ps( (float)0xffffffff );
+ live_mask = _mm_and_ps( live_mask,
+ _mm_or_ps ( _mm_cmpgt_ps( min_t, t_far ),
+ _mm_sub_ps ( nan, active_mask )));
+
+ // Check to see if any rays are active any longer.
+ // if (none(active_mask)) {
+ if (_mm_movemask_ps( live_mask ) == 0) {
+
+ // Done with this packet.
+ break;
+ }
+// #endif
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Simple kdtree functions.
+///////////////////////////////////////////////////////////////////////////////
+
+SSEKDTree::SSEKDTree( KDTree *kdtree_, Material *material_ )
+ : PrimitiveCommon( material_ ),
+ rootNode( kdtree_->rootNode ),
+ triIndices( kdtree_->triIndices ),
+ tris( kdtree_->tris ),
+ normals( kdtree_->normals )
+{
+ bbox.extendByBox( kdtree_->bbox );
+}
+SSEKDTree::~SSEKDTree() { };
+
+void SSEKDTree::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 SSEKDTree::computeBounds(const PreprocessContext&, BBox &box_ ) const {
+
+ box_.extendByBox( bbox );
+}
+
+void SSEKDTree::computeBounds( BBox &box_ ) const {
+
+ box_.extendByBox( bbox );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+#define MANTA_SSE_DOT(out, x1, y1, z1, x2, y2, z2) \
+{ \
+ out = _mm_add_ps(_mm_mul_ps(x1, x2), _mm_mul_ps(y1, y2)); \
+ out = _mm_add_ps(_mm_mul_ps(z1, z2), out); \
+}
+#define MANTA_SSE_CROSS(xout, yout, zout, x1, y1, z1, x2, y2, z2) \
+{ \
+ xout = _mm_sub_ps(_mm_mul_ps(y1, z2), _mm_mul_ps(z1, y2)); \
+ yout = _mm_sub_ps(_mm_mul_ps(z1, x2), _mm_mul_ps(x1, z2)); \
+ zout = _mm_sub_ps(_mm_mul_ps(x1, y2), _mm_mul_ps(y1, x2)); \
+}
+
+// Newton-Raphson Iteration for 1/x
+inline __m128 accurateReciprocal(const __m128& v) {
+
+ const __m128 rcp = _mm_rcp_ps(v);
+ return _mm_sub_ps(_mm_add_ps(rcp, rcp),_mm_mul_ps(_mm_mul_ps(rcp,rcp),v));
+}
+
+void intersectTriangleEdgeSSE( IntersectPacket *result,
+
+ const RayPacket &rays,
+ const int which,
+ const int tri_index,
+ const Vector &edge0,
+ const Vector &edge1,
+ const Point &p0 )
+{
+ __m128 xdir, ydir, zdir;
+ __m128 xnorm, ynorm, znorm;
+ __m128 xorig, yorig, zorig;
+ __m128 xoffset, yoffset, zoffset;
+ __m128 xcorner, ycorner, zcorner;
+ __m128 xcross, ycross, zcross;
+ __m128 xedge, yedge, zedge;
+ __m128 reciprocal;
+ __m128 determinant;
+ __m128 udet, vdet;
+ __m128 absu, absdet, absuv;
+ __m128 odn, t, u, v;
+ __m128 umask, vmask, uvmask;
+ int res;
+
+ // Calculate the normal based on the triangle edges.
+ Vector normal = Cross( edge0, edge1 );
+
+ xnorm = _mm_set1_ps( normal[0] );
+ ynorm = _mm_set1_ps( normal[1] );
+ znorm = _mm_set1_ps( normal[2] );
+
+ // Load the ray direction.
+ xdir = _mm_load_ps( &rays.getDirection(which,0) );
+ ydir = _mm_load_ps( &rays.getDirection(which,1) );
+ zdir = _mm_load_ps( &rays.getDirection(which,2) );
+
+ // Compute determinant = N . D
+ MANTA_SSE_DOT( determinant,
+ xdir, ydir, zdir,
+ xnorm, ynorm, znorm );
+
+ // Load ray origin.
+ xorig = _mm_load_ps( &rays.getOrigin(which,0) );
+ yorig = _mm_load_ps( &rays.getOrigin(which,1) );
+ zorig = _mm_load_ps( &rays.getOrigin(which,2) );
+
+ // Load vertex0
+ xcorner = _mm_set1_ps( p0[0] );
+ ycorner = _mm_set1_ps( p0[1] );
+ zcorner = _mm_set1_ps( p0[2] );
+
+ // Compute origin - vertex0
+ xoffset = _mm_sub_ps( xorig, xcorner );
+ yoffset = _mm_sub_ps( yorig, ycorner );
+ zoffset = _mm_sub_ps( zorig, zcorner );
+
+ // Cross direction w/ offset.
+ MANTA_SSE_CROSS( xcross, ycross, zcross,
+ xdir, ydir, zdir,
+ xoffset, yoffset, zoffset );
+
+ // Load edge1
+ xedge = _mm_set1_ps( edge1[0] );
+ yedge = _mm_set1_ps( edge1[1] );
+ zedge = _mm_set1_ps( edge1[2] );
+
+ // Dot
+ MANTA_SSE_DOT( u,
+ xedge, yedge, zedge,
+ xcross, ycross, zcross );
+
+ // Absolute value of u.
+ absu = _mm_andnot_ps( _mm_set1_ps(-0.0f), u );
+
+ // Absolute value of det
+ absdet = _mm_andnot_ps( _mm_set1_ps(-0.0f), determinant );
+
+ udet = _mm_mul_ps ( u, determinant );
+
+ // Compute () && (u*det >= 0)
+ umask = _mm_and_ps ( _mm_cmple_ps( absu, absdet ),
+ _mm_cmpge_ps( udet, _mm_setzero_ps() ) );
+
+ // Load edge0
+ xedge = _mm_set1_ps( edge0[0] );
+ yedge = _mm_set1_ps( edge0[1] );
+ zedge = _mm_set1_ps( edge0[2] );
+
+ MANTA_SSE_DOT( v,
+ xedge, yedge, zedge,
+ xcross, ycross, zcross );
+
+ // Absolute value u - v.
+ absuv = _mm_andnot_ps( _mm_set1_ps(-0.0f),
+ _mm_sub_ps(u, v) );
+ vdet = _mm_mul_ps ( v, determinant );
+ vmask = _mm_and_ps( _mm_cmple_ps( absuv, absdet ),
+ _mm_cmple_ps( vdet, _mm_setzero_ps() ) );
+
+ // Determine which rays intersect the triangle.
+ uvmask = _mm_and_ps( umask, vmask );
+
+ res = _mm_movemask_ps( uvmask );
+ if (res == 0)
+ return;
+
+ // Compute inverse det.
+ //reciprocal = _mm_rcp_ps(determinant);
+ reciprocal = accurateReciprocal(determinant);
+
+ MANTA_SSE_DOT( odn,
+ xoffset, yoffset, zoffset,
+ xnorm, ynorm, znorm );
+
+
/////////////////////////////////////////////////////////////////////////////
+ // Compute t, u, v
+
+ // odn * (-1/det)
+ t = _mm_mul_ps( odn, _mm_sub_ps( _mm_setzero_ps(), reciprocal));
+
+ // u * (1/det)
+ u = _mm_mul_ps( u, reciprocal );
+
+ // v * (-1/det)
+ v = _mm_mul_ps( v, _mm_sub_ps( _mm_setzero_ps(), reciprocal ) );
+
+ // Check the hit t against the current value in the result.
+ // (active_mask && uv_mask) && (t < result->t) && (t > T_EPSILON);
+ /*
+ static const __m128 epsilon = _mm_set1_ps( T_EPSILON );
+ result->hit_mask4 = _mm_and_ps( _mm_and_ps(result->active_mask, uvmask),
+ _mm_and_ps( _mm_cmplt_ps( t, result->t4 ),
+ _mm_cmpgt_ps( t, epsilon) ));
+ */
+ // Copy out individual results for rays which generated value hits.
+ for (int p=0; p<TraversalPacketSize; p++) {
+ int hit = ((const int *)&uvmask)[p];
+ if (result->active_mask[p] && hit) {
+ float scalar = ((const float *)&t)[p];
+ if ( (hit) &&
+ (scalar < result->t[p]) &&
+ (scalar > T_EPSILON)) {
+
+ // Copy the results for this ray.
+ result->t[p] = scalar;
+ result->u[p] = ((const float *)&u)[p];
+ result->v[p] = ((const float *)&v)[p];
+ result->hit_mask[p] = 0xffffffff;
+ result->hit_index[p] = tri_index;
+ }
+ }
+ }
+}
+
+
+
+
+
Added: trunk/Model/Groups/SSEKDTree.h
==============================================================================
--- (empty file)
+++ trunk/Model/Groups/SSEKDTree.h Sun Jan 29 01:24:55 2006
@@ -0,0 +1,126 @@
+/*
+ For more information, please see:
http://software.sci.utah.edu
+
+ The MIT License
+
+ 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
+ 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.
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// NOTE: Manta::Real must be "float" in order for CMake to include this code.
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+// Abe Stephens
+
+#ifndef __SSE_KD_TREE_H__
+#define __SSE_KD_TREE_H__
+
+
+#include <Core/Geometry/PointVector.h>
+#include <Core/Geometry/BBox.h>
+
+#include <Interface/RayPacket.h>
+#include <Interface/Texture.h>
+
+#include <Model/Groups/KDTree.h>
+#include <Model/Groups/varray.h>
+#include <Model/Groups/KdtreeParameters.h>
+#include <Model/Groups/VerticalKDTree.h>
+
+#include <iostream>
+
+#include <xmmintrin.h>
+#include <Core/Util/Align.h>
+
+namespace Manta {
+
+ // Note: Kdtree is the namespace: KDTree, VerticalKDTree are classes
+ // in the namespace.
+ namespace Kdtree {
+
+
///////////////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////////////
+ // SSE KDTREE CLASS PROPER
+
///////////////////////////////////////////////////////////////////////////
+
///////////////////////////////////////////////////////////////////////////
+ class SSEKDTree : public PrimitiveCommon, public KDTreeDebug {
+ public:
+ typedef KDTree::ScratchPadInfo ScratchPadInfo;
+
+
/////////////////////////////////////////////////////////////////////////
+ // Constructor.
+ SSEKDTree( KDTree *kdtree_, Material *material_ );
+ virtual ~SSEKDTree();
+
+
/////////////////////////////////////////////////////////////////////////
+ // 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;
+
+
/////////////////////////////////////////////////////////////////////////
+ // Accessors.
+ virtual void setRootNode( KDTreeNode *node ) { rootNode = node;
};
+ virtual KDTreeNode *getRootNode() { return rootNode;
};
+
+ private:
+ BBox bbox;
+ KDTreeNode *rootNode;
+
+ VArray<int> *triIndices;
+ VArray<Triangle> *tris;
+ TriangleNormal *normals;
+
+ VArray<int> *triToGroupMap;
+ VArray<int> *groupToNameMap;
+ VArray<char> *groupNames;
+ VArray<unsigned char> *triFlags;
+
+ // 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,
+ int p_start,
+ float minDist[TraversalPacketSize],
+ float maxDist[TraversalPacketSize] ) const;
+
+
+ };
+
+ } // end namespace Kdtree
+
+} // end namespace Manta
+
+
+#endif
Modified: trunk/Model/Groups/VerticalKDTree.cc
==============================================================================
--- trunk/Model/Groups/VerticalKDTree.cc (original)
+++ trunk/Model/Groups/VerticalKDTree.cc Sun Jan 29 01:24:55 2006
@@ -61,12 +61,6 @@
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
-static int
-intersect_triangle3(const float orig[3],
- const float dir[3],
- const float vert0[3], const float vert1[3], const float
vert2[3],
- float *t, float *u, float *v );
-
// Currently this routine is the fastest.
// This is a C version of the ray triangle intersection edge form.
static inline int
@@ -76,12 +70,6 @@
float *t, float *u, float *v,
const float *edge1, const float *edge2);
-// This is a C++ version of the above routine.
-static int
-intersectTriangle3Edge(const Vectorf &direction, const Pointf &origin,
- const Vectorf &edge1, Vectorf &edge2, Pointf &p0,
- float &t, float &u, float &v );
-
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
@@ -89,6 +77,26 @@
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
+namespace Manta {
+ namespace Kdtree {
+ class IntersectPacket {
+ public:
+ const Mask active_mask;
+ Mask hit_mask;
+
+ int hit_index[TraversalPacketSize];
+
+ float t[TraversalPacketSize];
+ float u[TraversalPacketSize];
+ float v[TraversalPacketSize];
+
+ IntersectPacket( const Mask &active_mask_ )
+ : active_mask( active_mask_ ) { };
+ };
+ };
+};
+
+
void VerticalKDTree::intersectTriangles(IntersectPacket &intersect_packet,
const RayPacket &rays,
int which,
@@ -334,8 +342,6 @@
const float split = node->split();
// Identify near_index and far_index.
- assert( rays.getFlag( RayPacket::ConstantSigns ) );
-
const int near_index = rays.getSign(which+p_start,axis);
const int far_index = (1 - near_index);
@@ -386,31 +392,44 @@
// if (rays.getFlag( RayPacket::DebugPacket )) { std::cerr <<
"C\n"; }
// Case III "Both" -- Push far node on stack.
- stack_index++;
- stack[stack_index].node = node->getChild( far_index );
-
- // Copy t_split and t_far to the stack.
- for (int p=0;p<TraversalPacketSize;++p) {
- stack[stack_index].t_near[p] = t_split[p];
- stack[stack_index].t_far [p] = t_far[p];
- }
// Determine the valid mask for the far subtree.
set_lte( cmp_result, t_split, t_far );
- set_and( stack[stack_index].mask, cmp_result, active_mask );
- // stack[stack_index].mask = active_mask;
-
- // Update the current node.
- node = node->getChild( near_index );
+ set_and( cmp_result, cmp_result, active_mask );
- // Copy t_split to t_far.
- for (int p=0;p<TraversalPacketSize;++p) {
- t_far[p] = t_split[p];
+ // Check to see if any rays enter the far node.
+ if (any(cmp_result)) {
+
+ stack_index++;
+ stack[stack_index].node = node->getChild( far_index );
+ stack[stack_index].mask = cmp_result;
+
+ // Copy t_split and t_far to the stack.
+ for (int p=0;p<TraversalPacketSize;++p) {
+ stack[stack_index].t_near[p] = t_split[p];
+ stack[stack_index].t_far [p] = t_far[p];
+ }
}
// Update the active mask.
set_lte( cmp_result, t_near, t_far );
- set_and( active_mask, active_mask, cmp_result );
+ set_and( cmp_result, active_mask, cmp_result );
+
+ // Check to see if any rays hit the near node.
+ if (any( cmp_result )) {
+ // Update the current node.
+ node = node->getChild( near_index );
+ active_mask = cmp_result;
+
+ // Copy t_split to t_far.
+ for (int p=0;p<TraversalPacketSize;++p) {
+ t_far[p] = t_split[p];
+ }
+ }
+ else {
+ // Otherwise done with this subtree.
+ node = 0;
+ }
}
///////////////////////////////////////////////////////////////////////////
Modified: trunk/Model/Groups/VerticalKDTree.h
==============================================================================
--- trunk/Model/Groups/VerticalKDTree.h (original)
+++ trunk/Model/Groups/VerticalKDTree.h Sun Jan 29 01:24:55 2006
@@ -170,20 +170,7 @@
// INTERSECT PACKET INTERSECT PACKET INTERSECT PACKET INTERSECT
PACKET
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
- class IntersectPacket {
- public:
- const Mask active_mask;
- Mask hit_mask;
-
- int hit_index[TraversalPacketSize];
-
- float t[TraversalPacketSize];
- float u[TraversalPacketSize];
- float v[TraversalPacketSize];
-
- IntersectPacket( const Mask &active_mask_ )
- : active_mask( active_mask_ ) { };
- };
+ class IntersectPacket;
inline std::ostream &operator<< (std::ostream &out, const Mask &mask) {
Modified: trunk/fox/FManta/FMantaWindow.cc
==============================================================================
--- trunk/fox/FManta/FMantaWindow.cc (original)
+++ trunk/fox/FManta/FMantaWindow.cc Sun Jan 29 01:24:55 2006
@@ -84,8 +84,9 @@
FXMAPFUNC(SEL_COMMAND, FMantaWindow::ID_UNHIDE_ALL,
FMantaWindow::onUnHideAll ),
FXMAPFUNC(SEL_COMMAND, FMantaWindow::ID_POSITIVEZ_UP,
FMantaWindow::onCoordSystemUp ),
- FXMAPFUNC(SEL_COMMAND, FMantaWindow::ID_POSITIVEY_UP,
FMantaWindow::onCoordSystemUp )
-
+ FXMAPFUNC(SEL_COMMAND, FMantaWindow::ID_POSITIVEY_UP,
FMantaWindow::onCoordSystemUp ),
+
+ FXMAPFUNC(SEL_COMMAND, FMantaWindow::ID_DEBUG_RAY_DIALOG,
FMantaWindow::onDebugRayDialog )
};
FXIMPLEMENT(FMantaWindow,FXMainWindow,FMantaWindowMap,ARRAYNUMBER(FMantaWindowMap));
@@ -101,7 +102,9 @@
fast_quit( false ) ,
cutting_snap( 1 ),
debug_packet( 1 ),
- extra_options_dialog( 0 )
+ extra_options_dialog( 0 ),
+ debug_ray_x( 0 ),
+ debug_ray_y( 0 )
{
/////////////////////////////////////////////////////////////////////////////
// Menu Bar.
@@ -174,10 +177,16 @@
positivey_up = new FXMenuRadio( options_menu, "Positive Y up", this,
ID_POSITIVEY_UP );
new FXMenuSeparator( options_menu );
+ new FXMenuTitle( menu_bar, "Options", 0, options_menu );
+
+ // Debug Menu.
+ debug_menu = new FXMenuPane( this );
+
// Debug shoot one ray.
- new FXMenuCheck( options_menu, "Debug ray on click", new FXDataTarget(
debug_packet ), FXDataTarget::ID_VALUE );
+ new FXMenuCheck ( debug_menu, "Debug ray on click", new FXDataTarget(
debug_packet ), FXDataTarget::ID_VALUE );
+ new FXMenuCommand( debug_menu, "Debug ray at coords", 0, this,
ID_DEBUG_RAY_DIALOG );
- new FXMenuTitle( menu_bar, "Options", 0, options_menu );
+ new FXMenuTitle( menu_bar, "Debug", 0, debug_menu );
/////////////////////////////////////////////////////////////////////////////
// Create the content of the window.
@@ -414,11 +423,19 @@
long FMantaWindow::onCameraText( FXObject *sender, FXSelector key, void
*data ) {
+ // Get a pointer to the camera.
+ Camera *camera = manta_interface->getCamera(
manta_frame->getMantaChannel() );
+
+ // Get the camera in text form.
+ ostringstream str;
+ camera->output( str );
+
+ FXString camera_description = str.str().c_str();
+
// Collect a string from the user.
- FXString description;
- if (FXInputDialog::getString(description, getApp(), "Enter Text..",
"Camera Spec:", 0 )) {
+ if (FXInputDialog::getString(camera_description, getApp(), "Enter Text..",
"Camera Spec:", 0 )) {
manta_interface->addTransaction("Camera",
-
Callback::create(this,&FMantaWindow::mantaCamera2,string(description.text())));
+
Callback::create(this,&FMantaWindow::mantaCamera2,string(camera_description.text())));
}
return 1;
@@ -453,10 +470,9 @@
long FMantaWindow::onShadowAlgorithmText( FXObject *sender, FXSelector key,
void *data ) {
// Collect a string from the user.
- FXString description;
- if (FXInputDialog::getString(description, getApp(), "Enter Text..",
"Shadow Algorithm Spec:", 0 )) {
+ if (FXInputDialog::getString(shadow_description, getApp(), "Enter Text..",
"Shadow Algorithm Spec:", 0 )) {
manta_interface->addTransaction("Shadow Algorithm.",
-
Callback::create(this,&FMantaWindow::mantaShadowAlgorithm,string(description.text())));
+
Callback::create(this,&FMantaWindow::mantaShadowAlgorithm,string(shadow_description.text())));
}
return 1;
@@ -492,10 +508,9 @@
long FMantaWindow::onPixelSamplerText( FXObject *sender, FXSelector key,
void *data ) {
// Collect a string from the user.
- FXString description;
- if (FXInputDialog::getString(description, getApp(), "Enter Text", "Pixel
Sampler Spec:", 0 )) {
+ if (FXInputDialog::getString(sampler_description, getApp(), "Enter Text",
"Pixel Sampler Spec:", 0 )) {
manta_interface->addTransaction("Pixel Sampler.",
-
Callback::create(this,&FMantaWindow::mantaPixelSampler,string(description.text())));
+
Callback::create(this,&FMantaWindow::mantaPixelSampler,string(sampler_description.text())));
}
return 1;
@@ -527,10 +542,9 @@
long FMantaWindow::onTraverserText( FXObject *sender, FXSelector key, void
*data ) {
// Collect a string from the user.
- FXString description;
- if (FXInputDialog::getString(description, getApp(), "Enter Text", "Image
Traverser Spec:", 0 )) {
+ if (FXInputDialog::getString(traverser_description, getApp(), "Enter
Text", "Image Traverser Spec:", 0 )) {
manta_interface->addTransaction("Image Traverser.",
-
Callback::create(this,&FMantaWindow::mantaTraverser,string(description.text())));
+
Callback::create(this,&FMantaWindow::mantaTraverser,string(traverser_description.text())));
}
return 1;
@@ -547,8 +561,12 @@
Point point;
Vector normal;
+
+ // Save the location.
+ debug_ray_x = event->win_x;
+ debug_ray_y = event->win_y;
- if (manta_frame->shootOneRay( event->win_x, event->win_y, point, normal,
true )) {
+ if (manta_frame->shootOneRay( debug_ray_x, debug_ray_y, point, normal,
true )) {
std::cerr << point << std::endl;
std::cerr << normal << std::endl;
@@ -558,6 +576,33 @@
return 1;
}
+long FMantaWindow::onDebugRayDialog( FXObject* sender, FXSelector key,
+ void* /*data*/ ) {
+
+ FXString description;
+ description.format( "%d %d", debug_ray_x, debug_ray_y );
+
+ if (FXInputDialog::getString(description, getApp(), "Enter Text", "Image
coords:", 0 )) {
+ std::istringstream str( description.text() );
+
+ // Input the image coords.
+ str >> debug_ray_x >> debug_ray_y;
+
+ Point point;
+ Vector normal;
+
+ // Send the debug ray.
+ if (manta_frame->shootOneRay( debug_ray_x, debug_ray_y, point, normal,
true )) {
+
+ std::cerr << point << std::endl;
+ std::cerr << normal << std::endl;
+ }
+ }
+
+ return 1;
+}
+
+
long FMantaWindow::onAddCuttingPlane( FXObject *sender, FXSelector key, void
*data ) {
FXEvent *event = (FXEvent *)data;
@@ -951,6 +996,7 @@
return 1;
}
+
///////////////////////////////////////////////////////////////////////////////
Modified: trunk/fox/FManta/FMantaWindow.h
==============================================================================
--- trunk/fox/FManta/FMantaWindow.h (original)
+++ trunk/fox/FManta/FMantaWindow.h Sun Jan 29 01:24:55 2006
@@ -45,6 +45,7 @@
FXMenuPane *sampler_menu;
FXMenuPane *traverser_menu;
FXMenuPane *options_menu;
+ FXMenuPane *debug_menu;
FXMenuCommand *cutting_flip;
FXMenuCheck *hide_selected_check;
@@ -75,7 +76,16 @@
FMantaImageFrame *manta_frame;
bool fast_quit;
-
+
+ // String to save user entered specifications.
+ FXString shadow_description;
+ FXString sampler_description;
+ FXString traverser_description;
+
+ // Debug ray image locations.
+ int debug_ray_x;
+ int debug_ray_y;
+
public:
// Commands for the main window.
enum {
@@ -131,6 +141,9 @@
// Coordinate system up
ID_POSITIVEZ_UP,
ID_POSITIVEY_UP,
+
+ // Debug ray dialog.
+ ID_DEBUG_RAY_DIALOG,
ID_LAST
};
@@ -187,6 +200,7 @@
long onPOI( FXObject *sender, FXSelector key, void *data );
long onExtraOptions ( FXObject *sender, FXSelector key, void *data );
long onCoordSystemUp ( FXObject *sender, FXSelector key, void *data );
+ long onDebugRayDialog ( FXObject *sender, FXSelector key, void *data );
// Accessors.
void setMantaInterface( MantaInterface *manta_interface_, int
manta_channel_ ) {
Modified: trunk/scenes/boeing777.cc
==============================================================================
--- trunk/scenes/boeing777.cc (original)
+++ trunk/scenes/boeing777.cc Sun Jan 29 01:24:55 2006
@@ -47,6 +47,7 @@
#include <Model/Groups/KDTree.h>
#include <Model/Groups/TransparentKDTree.h>
#include <Model/Groups/VerticalKDTree.h>
+#include <Model/Groups/SSEKDTree.h>
#include <Model/Lights/PointLight.h>
#include <Model/Lights/HeadLight.h>
#include <Model/Materials/Lambertian.h>
@@ -83,7 +84,7 @@
MTL_SOLID_WIRE,
MTL_WIRE,
MTL_RAYDIRECTION };
-enum TraversalType { TRAVERSAL_SINGLE, TRAVERSAL_VERTICAL };
+enum TraversalType { TRAVERSAL_SINGLE, TRAVERSAL_VERTICAL, TRAVERSAL_SSE
};
///////////////////////////////////////////////////////////////////////////
// This function constructs the Boeing 777 Test Scene using a KdTree.
@@ -107,6 +108,7 @@
int ambient_rays = 16;
int phong_exp = 512;
ColorComponent phong_reflect = 0;
+ float scene_ambient[] = { 0.2, 0.2, 0.2 };
bool use_transparency = false;
@@ -175,12 +177,24 @@
else if (args[i] == "-vertical") {
traversal = TRAVERSAL_VERTICAL;
}
+ else if (args[i] == "-sse") {
+ traversal = TRAVERSAL_SSE;
+ }
+ else if (args[i] == "-scene_ambient") {
+ if (!(getArg(i,args,scene_ambient[0]) &&
+ getArg(i,args,scene_ambient[1]) &&
+ getArg(i,args,scene_ambient[2])))
+ {
+ cerr << "-ambient_light <r> <g> <b>\n";
+ }
+ }
else {
cerr << "Valid options for boeing777:\n";
cerr << "-file <filename>" << endl;
cerr << "-np <num build workers>" << endl;
cerr << "-cutting [<point> <normal>]" << endl;
cerr << "Materials:-------------------------------------\n";
+ cerr << "-scene_ambient <r> <g> <b>\n";
cerr << "-alpha <alpha>" << endl;
cerr << "-phong <exp> <reflection> **default**" << endl;
cerr << "-ambient <max dist> <secondary rays>" << endl;
@@ -192,6 +206,7 @@
cerr << "-bg marble Currently only marble is supported.\n";
cerr << "Traversals:------------------------------------\n";
cerr << "-vertical -- Use vertical traversal code.\n";
+ cerr << "-sse -- Use SSE intrinsic code.\n";
throw IllegalArgument( "boeing777", i, args );
}
@@ -201,6 +216,17 @@
Scene *scene = new Scene();
Object *root_object = 0;
+
/////////////////////////////////////////////////////////////////////////////
+ // Add a head light.
+ LightSet *lights = new LightSet();
+
+ lights->add( new HeadLight( 2.0, Color(RGB(1.0,1.0,1.0)) ));
+ lights->setAmbientLight( new
ConstantAmbient(Color(RGB(scene_ambient[0],
+ scene_ambient[1],
+
scene_ambient[2]))));
+ scene->setLights(lights);
+
+
// Choose a material.
Material *kd_material = 0;
switch (material_type) {
@@ -223,7 +249,7 @@
kd_material = new Flat( new NormalTexture() );
break;
case MTL_RAYDIRECTION:
- kd_material = new Lambertian( new
WireframeTexture<KDTree::ScratchPadInfo>( new RaySignTexture(), Color(RGB(0,
0, 0)) ) );
+ kd_material = new Lambertian( new RaySignTexture() );
break;
case MTL_SOLID_WIRE:
kd_material = new Phong( new WireframeTexture<KDTree::ScratchPadInfo>(
new KDTreeTexture(), Color(RGB(0, 0, 0)) ),
@@ -272,6 +298,10 @@
// Create a vertical kdtree.
kd_primitive = new VerticalKDTree( kdtree, kd_material );
}
+ else if (traversal == TRAVERSAL_SSE) {
+ // Create a sse kdtree.
+ kd_primitive = new SSEKDTree( kdtree, kd_material );
+ }
////////////////////////////////////////////////////////////////////////////
// Compute the middle of the model for a cutting plane.
@@ -292,13 +322,6 @@
root_object = kd_primitive;
}
-
/////////////////////////////////////////////////////////////////////////////
- // Add a head light.
- LightSet *lights = new LightSet();
-
- lights->add( new HeadLight( 2.0, Color(RGB(1.0,1.0,1.0)) ));
- lights->setAmbientLight( new ConstantAmbient(
Color(RGBColor(0.2,0.2,0.2) ) ));
- scene->setLights(lights);
// Add the tree to the scene.
scene->setObject( root_object );
- [MANTA] r873 - in trunk: Core/Util Interface Model/Groups fox/FManta scenes, abe, 01/29/2006
Archive powered by MHonArc 2.6.16.