Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r440 - in branches/itanium2: Engine/Control Model/Groups Model/Materials


Chronological Thread 
  • From: abe@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r440 - in branches/itanium2: Engine/Control Model/Groups Model/Materials
  • Date: Mon, 25 Jul 2005 19:29:59 -0600 (MDT)

Author: abe
Date: Mon Jul 25 19:29:54 2005
New Revision: 440

Added:
   branches/itanium2/Model/Groups/TransparentKDTree.cc
   branches/itanium2/Model/Groups/TransparentKDTree.h
Modified:
   branches/itanium2/Engine/Control/RTRT.cc
   branches/itanium2/Model/Groups/CMakeLists.txt
   branches/itanium2/Model/Groups/RealisticBvh.h
   branches/itanium2/Model/Groups/kdtree.cc
   branches/itanium2/Model/Groups/kdtree.h
   branches/itanium2/Model/Groups/varray.h
   branches/itanium2/Model/Materials/LambertianAlt.cc
Log:



Changed shootOneRay so that the proc number is numprocs
M    Engine/Control/RTRT.cc

Added a "TransparerntKDTree" which shades during intersection.
A    Model/Groups/TransparentKDTree.cc
A    Model/Groups/TransparentKDTree.h


M    Model/Groups/varray.h
M    Model/Groups/kdtree.cc
M    Model/Groups/kdtree.h
M    Model/Groups/RealisticBvh.h
M    Model/Groups/CMakeLists.txt

Lambertian Alt material is pretty hacked up right now. It will be all sorted 
out for the next commit.
M    Model/Materials/LambertianAlt.cc


Modified: branches/itanium2/Engine/Control/RTRT.cc
==============================================================================
--- branches/itanium2/Engine/Control/RTRT.cc    (original)
+++ branches/itanium2/Engine/Control/RTRT.cc    Mon Jul 25 19:29:54 2005
@@ -1174,7 +1174,7 @@
        Channel *channel = channels[ channel_index ];
        
        // Create a render context.
-       RenderContext render_context(this, channel_index, -1, 
workersRendering, 0,
+       RenderContext render_context(this, channel_index, workersRendering, 
workersRendering+1, 0,
                                                                              
                               currentLoadBalancer, currentPixelSampler,
                                                                              
                                           currentRenderer, 
currentShadowAlgorithm,
                                                                              
                                           channel->camera, scene );

Modified: branches/itanium2/Model/Groups/CMakeLists.txt
==============================================================================
--- branches/itanium2/Model/Groups/CMakeLists.txt       (original)
+++ branches/itanium2/Model/Groups/CMakeLists.txt       Mon Jul 25 19:29:54 
2005
@@ -8,6 +8,8 @@
      Groups/Group.cc
      Groups/kdtree.h
      Groups/kdtree.cc
+     Groups/TransparentKDTree.h
+     Groups/TransparentKDTree.cc
      Groups/PsiGammaTable.cc
      Groups/PsiGammaTable.h
      Groups/VolumeGrid.h

Modified: branches/itanium2/Model/Groups/RealisticBvh.h
==============================================================================
--- branches/itanium2/Model/Groups/RealisticBvh.h       (original)
+++ branches/itanium2/Model/Groups/RealisticBvh.h       Mon Jul 25 19:29:54 
2005
@@ -67,6 +67,8 @@
     void intersect    (const RenderContext& context, RayPacket& rays) const; 
          
        };
        
+       
+#if 0  
        // This class contains code to rebuild the bvh in parallel.
        class RealisticBvhBuilder {
        protected:
@@ -83,6 +85,7 @@
                // This function should be called as a parallel animation 
callback to rebuild the bvh.
                void parallel_rebuild_bvh( int proc, int num_procs );
        };
+#endif
 };
 
 #endif

Added: branches/itanium2/Model/Groups/TransparentKDTree.cc
==============================================================================
--- (empty file)
+++ branches/itanium2/Model/Groups/TransparentKDTree.cc Mon Jul 25 19:29:54 
2005
@@ -0,0 +1,595 @@
+
+
+/*
+ For more information, please see: http://software.sci.utah.edu

+ The MIT License

+ Copyright (c) 2005
+ Silicon Graphics Inc. Mountain View California.

+ License for the specific language governing rights and limitations under
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ 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/TransparentKDTree.h>
+
+#include <iostream>
+
+
+#include <stdio.h>
+#include "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>
+
+using namespace Manta;
+using namespace Manta::Kdtree;
+using namespace SCIRun;
+using std::cerr;
+using std::endl;
+
+
+// From Tomas Akenine-Mˆller's code, included below in this file.
+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 );
+
+int intersect_triangle3_edge(     const float orig[3], 
+                                                                             
                                                          const float dir[3],
+                                                                             
                                                          const float 
vert0[3],
+                                                                             
                                                          float *t, float *u, 
float *v,
+                                                                             
                                                          const float *edge1, 
const float *edge2);
+
+int intersectTriangle3Edge(const Vectorf &direction, const Pointf &origin, 
+                           const Vectorf &edge1, Vectorf &edge2, Pointf &p0,
+                                                                             
                           float &t, float &u, float &v );
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// CONSTRUCTOR  CONSTRUCTOR  CONSTRUCTOR  CONSTRUCTOR  CONSTRUCTOR  
CONSTRUCTOR
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+TransparentKDTree::TransparentKDTree( KDTree *kdtree_, Real sample_alpha_ ) :
+       rootNode( kdtree_->rootNode ),
+       triIndices( kdtree_->triIndices ),
+       tris( kdtree_->tris ),
+       normals( kdtree_->normals ),
+       lambMat( kdtree_->lambMat ),
+       sample_alpha( sample_alpha_ ) {
+       
+       bbox.extendByBox( kdtree_->bbox );
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// INTERSECT TRIANGLES  INTERSECT TRIANGLES  INTERSECT TRIANGLES  INTERSECT 
TRI
+///////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////
+VArray<VArray<TransparentKDTree::Isect> *> 
TransparentKDTree::isectBuffers(1024, 0);
+
+int TransparentKDTree::intersectTrianglesTransparent(const Ray* ray, 
RayPacket::Element &e, unsigned int listBegin, int listSize, float maxDist, 
void *userData, const RenderContext &context) const
+{
+       int i;
+       RayTriIntersectUserData *ud = (RayTriIntersectUserData*)userData;
+       float nearest_u, nearest_v;
+       int nearest_tri = -1;
+
+       Vectorf direction = ray->direction();
+       Pointf  origin    = ray->origin();      
+
+       
////////////////////////////////////////////////////////////////////////////
+       // Check to see if the thread buffers array is allocated.
+       if (isectBuffers.getLen() != (context.numProcs+1)) {
+               // One additional buffer is needed for "shootSingleRay" 
queries from the gui thread.
+               isectBuffers.setLen( context.numProcs+1, 0 );
+       }
+       
+       // Determine the thread number.
+       int threadId = context.proc;
+       VArray<TransparentKDTree::Isect> *isectbuf = 
isectBuffers.get(threadId);
+       
+       // Check to see if the per-thread buffer for this thread is allocated.
+       if (! isectbuf) {
+               isectbuf = new VArray<TransparentKDTree::Isect>(8);
+               isectBuffers.set(threadId, isectbuf);
+       }
+       isectbuf->setLen(0);
+        
+       
////////////////////////////////////////////////////////////////////////////
+       // Intersect the ray with all the triangles. 
+       Real &sample_t = e.hitInfo.scratchpad<ScratchPadInfo>().sample_t;
+       
+       int listEnd = listBegin+listSize;
+       
+       #pragma swp
+       for (i = listBegin; i < listEnd; i++) {
+               int triIdx = triIndices->get(i);
+               Triangle &tri = tris->get(triIdx);
+               float t, u, v;
+               
+               // if (intersectTriangle3Edge( direction, origin, tri.edge1, 
tri.edge2, tri[0], t, u, v )) {
+               if(intersect_triangle3_edge( &origin, &direction, &tri[0], 
&t, &u, &v, &tri.edge1, &tri.edge2 )) {
+               
+                       // Check to see if the t value is closer.
+                       if ((t > sample_t) && (t < maxDist)) {
+                               Isect &isect = isectbuf->append();
+                               isect.t = t;
+                               isect.u = u;
+                               isect.v = v;
+                               isect.triIdx = triIdx;
+                       }
+               }
+       }
+
+       
////////////////////////////////////////////////////////////////////////////
+       // Check to see if any triangles need to be blended.
+       if (isectbuf->getLen()) {
+               
+               // sort the intersections
+               Isect *array = isectbuf->getArray();
+               std::sort(array, array+isectbuf->getLen());
+
+               // Modify the hit record color directly.
+               Color &ray_color = 
e.hitInfo.scratchpad<ScratchPadInfo>().payload;
+               Real  &ray_alpha = 
e.hitInfo.scratchpad<ScratchPadInfo>().alpha;                
+               
+               // Check to see if this is the first triangle the ray hit.
+               if (ray_alpha == 0.0) {
+                       ud->rayHit.t = array[0].t;
+                       ud->rayHit.u = array[0].u;
+                       ud->rayHit.v = array[0].v;
+                       ud->rayHitTriIndex = array[0].triIdx;
+               }               
+               
+               Real sample_alpha__ = sample_alpha;
+               
+               // combine  color and opacity 
+               for (int i=0; (i<isectbuf->getLen()) && (ray_alpha < 0.95); 
i++) {
+                       
+                       Color &sample_color = tris->get( array[i].triIdx 
).payload;
+                        
+                       ray_color += (sample_color*sample_alpha__) * (1.0 - 
ray_alpha);
+                       ray_alpha += sample_alpha__ * (1.0 - ray_alpha);
+               }
+               
+               // Update sample t to the last triangle composited.
+               sample_t = array[isectbuf->getLen()-1].t;
+
+               return 1;
+       }
+       else { 
+               return 0;
+       }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// This is the Manta interface method.
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+void TransparentKDTree::intersect(const RenderContext& context, RayPacket& 
rays) const
+{
+       
+       // Normalize and compute inverse directions, 
+       // As a side effect this also computes the sign mask for the box 
intersection.
+  rays.normalizeDirections();
+       rays.computeInverseDirections();
+       
+       RayTriIntersectUserData isectData;
+       
+       for(int i=0;i<rays.getSize();i++) {
+               
+               RayPacket::Element& e = rays.get(i);
+               Real minDist, maxDist;
+               
+               // Intersect the ray with the bounding box for the group.
+               if (Intersection::intersectAaBox( bbox, 
+                                                                             
                                                                          
minDist, maxDist, 
+                                                                             
                                                                          
e.ray,
+                                                                             
                                                                          
e.signMask, 
+                                                                             
                                                                          
e.inverseDirection )) {
+                       
+                       // Determine the actual minimum distance.
+                       minDist = SCIRun::Max( minDist, T_EPSILON );
+                       maxDist = SCIRun::Min( maxDist, e.hitInfo.minT() );
+                       
+                       // Send the ray to the _intersect function.
+                       isectData.rayHitTriIndex = -1;
+                       _intersect( &e.ray, e, isectData, context, 
(float)minDist, (float)maxDist);
+
+               }
+       }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This function performs the KD-Tree Traversal.
+///////////////////////////////////////////////////////////////////////////////
+void TransparentKDTree::computeNormal(const RenderContext& context, 
RayPacket& rays) const {
+       
+       // Copy the normal out of the TransparentKDTree::ScratchPadInfo 
structure.
+       for (int i=0;i<rays.getSize();++i) {
+               rays.get(i).normal = 
rays.get(i).hitInfo.scratchpad<ScratchPadInfo>().normal;
+       }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// This function performs the KD-Tree Traversal.
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+// Traversal Stack Entry.
+struct TravStackEntry {
+       KDTreeNode* node;  //8 bytes
+       float t;           // 4 bytes
+                                                                             
   // float point[3]; // 4*3=12 bytes
+       int prev;          // 4 bytes
+};
+
+void TransparentKDTree::_intersect(const Ray* ray, RayPacket::Element &e, 
RayTriIntersectUserData &isectData, const RenderContext &context,
+                                                                             
                  float minDist, float maxDist) const
+{
+       // Set the ray color to black, alpha to 1.0.
+       e.hitInfo.scratchpad<ScratchPadInfo>().reset();
+       
+       Color &ray_color = e.hitInfo.scratchpad<ScratchPadInfo>().payload;
+       Real  &ray_alpha = e.hitInfo.scratchpad<ScratchPadInfo>().alpha;
+       
+       // Keep a stack of entry and exit positions into the traversal nodes.
+       TravStackEntry travStack[128];
+       
+       KDTreeNode *nearNode, *farNode;
+       float split;
+       int axis, entryPos, exitPos;
+       bool foundIntersection = false;
+       int tmp;
+       
+       // Initialize the first two entries on the stack.
+       entryPos = 0;
+       nearNode = travStack[entryPos].node = rootNode; 
+       travStack[entryPos].prev = 1;
+       travStack[entryPos].t = minDist < 0.0f ? 0 : minDist;
+       
+       exitPos = 1;
+       travStack[exitPos].node = NULL;
+       travStack[exitPos].t = maxDist;
+       travStack[exitPos].prev = 0;
+       
+       while (travStack[entryPos].prev) {
+               
+               // Traverse down until we find a leaf node.
+               while (nearNode && nearNode->isInternal()) {
+                       
+                       // Determine the axis and the split point.
+                       axis = nearNode->axis();
+                       split = nearNode->split();
+                       
+                       // Find where along the axis the ray enters and 
exits. 
+                       float entryPos_coord_on_axis = ray->origin()[axis] + 
+                                                       
travStack[entryPos].t*ray->direction()[axis];
+                                                       
+                       float exitPos_coord_on_axis = ray->origin()[axis] + 
+                                                       
travStack[exitPos].t*ray->direction()[axis];
+                       
+                       // Check to see which side of the split the ray 
enters first.
+                       if (entryPos_coord_on_axis <= split) {
+                               // Check to see if entry and exit are on the 
+                               // same side of the split.
+                               if (exitPos_coord_on_axis <= split) {
+                                       // Same side of the split, so the 
original interval is ok.
+                                       nearNode = nearNode->left();
+                                       continue;
+                               }
+                               // 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) {
+                                       nearNode = nearNode->right();
+                                       continue;
+                               }
+                               // Update otherwise.
+                               farNode = nearNode->left();
+                               nearNode = nearNode->right();
+                       }
+                       
+                       // Update location on the traversal stack.
+                       tmp = exitPos;
+                       
+                       // ??? Increment to an unused node ???
+                       if (++exitPos == entryPos) ++exitPos;
+                       
+                       // Specify a new exit node.
+                       travStack[exitPos].node = farNode;
+                       travStack[exitPos].t = (split - ray->origin()[axis])* 
e.inverseDirection[axis];
+                       
+                       travStack[exitPos].prev = tmp;
+               }
+               
+               // Check to see if we found a leaf node.
+               if (nearNode) {
+               
+                       bool first_leaf = (ray_alpha == 0.0);
+                       
+                       // Intersect the ray with a list of triangles.
+                       if (intersectTrianglesTransparent(ray, e, 
+                                                                             
                                                                              
    nearNode->listBegin(), nearNode->listSize(), 
+                                                                             
                                                                              
    travStack[exitPos].t, &isectData, context) && 
+                                       (isectData.rayHitTriIndex >= 0)) {
+       
+                               // If this is the first leaf, record the hit 
and normal.                        
+                               if (first_leaf) {
+                                       // Process the hit.
+                                       e.hitInfo.hit(isectData.rayHit.t, 
lambMat, this, 0 );
+                                       
+                                       // Copy the normal into the scratch 
pad.
+                                       
e.hitInfo.scratchpad<TransparentKDTree::TransparentKDTree::ScratchPadInfo>().normal
 = 
+                                               
normals[isectData.rayHitTriIndex*3];
+                                       
+                                       first_leaf = false;
+                               }
+                               
+                               // Check to see if the ray is fully 
attenuated.
+                               if 
(e.hitInfo.scratchpad<ScratchPadInfo>().alpha > 0.9) {
+                                       break;
+                               }
+                       }
+               }
+               
+               // Move to the next 
+               entryPos = exitPos;
+               exitPos = travStack[exitPos].prev;
+               nearNode = travStack[entryPos].node;
+       }
+       
+       // Blend with the background.
+       ray_color += (Color(RGB(0.8,0.8,0.8))) * (1.0 - ray_alpha);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+/********************************************************/
+/* AABB-triangle overlap test code                      */
+/* by Tomas Akenine-Mˆller                              */
+/* Function: int triBoxOverlap(float boxcenter[3],      */
+/*          float boxhalfsize[3],float triverts[3][3]); */
+/* History:                                             */
+/*   2001-03-05: released the code in its first version */
+/*   2001-06-18: changed the order of the tests, faster */
+/* 2003-2005: converted to using routines/macros in vmath.h */
+/*                                                      */
+/* Acknowledgement: Many thanks to Pierre Terdiman for  */
+/* suggestions and discussions on how to optimize code. */
+/* Thanks to David Hunt for finding a ">="-bug!         */
+/********************************************************/
+
+
+// #include <math.h>
+// #include <stdio.h>
+
+#define EPSILON 0.000001
+
+#define CROSS(dest,v1,v2) \
+(dest)[0]=(v1)[1]*(v2)[2]-(v1)[2]*(v2)[1]; \
+(dest)[1]=(v1)[2]*(v2)[0]-(v1)[0]*(v2)[2]; \
+(dest)[2]=(v1)[0]*(v2)[1]-(v1)[1]*(v2)[0];
+#define DOT(v1,v2) ((v1)[0]*(v2)[0]+(v1)[1]*(v2)[1]+(v1)[2]*(v2)[2])
+#define SUB(dest,v1,v2) \
+(dest)[0]=(v1)[0]-(v2)[0]; \
+(dest)[1]=(v1)[1]-(v2)[1]; \
+(dest)[2]=(v1)[2]-(v2)[2]; 
+
+/* code rewritten to do tests on the sign of the determinant */
+/* the division is before the test of the sign of the det    */
+/* and one CROSS has been moved out from the if-else if-else */
+inline 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)
+{
+       float edge1[3], edge2[3];
+       float tvec[3], pvec[3], qvec[3];
+       float det,inv_det;
+       
+       /* find vectors for two edges sharing vert0 */
+       SUB(edge1, vert1, vert0);
+       SUB(edge2, vert2, vert0);
+       
+       /* begin calculating determinant - also used to calculate U parameter 
*/
+       CROSS(pvec, dir, edge2);
+       
+       /* if determinant is near zero, ray lies in plane of triangle */
+       det = DOT(edge1, pvec);
+       
+       /* calculate distance from vert0 to ray origin */
+       SUB(tvec, orig, vert0);
+       inv_det = 1.0f/ det;
+       
+       CROSS(qvec, tvec, edge1);
+       
+       /* calculate U parameter */
+       float uu = DOT(tvec, pvec);
+       float vv;
+       
+       if (det > EPSILON)
+       {
+               if (uu < 0.0f || uu > det)
+                                               return 0;
+               
+               /* calculate V parameter and test bounds */
+               vv = DOT(dir, qvec);
+               if (vv < 0.0f || uu + vv > det)
+                                               return 0;
+               
+       }
+       else if(det < -EPSILON)
+       {
+               if (uu > 0.0f || uu < det)
+                                               return 0;
+               
+               /* calculate V parameter and test bounds */
+               vv = DOT(dir, qvec) ;
+               if (vv > 0.0f || uu + vv < det)
+                                               return 0;
+       }
+       else return 0;  /* ray is parallell to the plane of the triangle */
+       
+       *t = DOT(edge2, qvec) * inv_det;
+       (*u) = uu*inv_det;
+       (*v) = vv*inv_det;
+       
+       return 1;
+}
+
+inline int intersect_triangle3_edge(const float orig[3], const float dir[3],
+                                                                             
                                                                  const float 
vert0[3],
+                                                                             
                                                                  float *t, 
float *u, float *v, const float *edge1, const float *edge2 )
+{
+       // float edge1[3], edge2[3];
+       float tvec[3], pvec[3], qvec[3];
+       float det,inv_det;
+       
+       /* find vectors for two edges sharing vert0 */
+       // SUB(edge1, vert1, vert0);
+       // SUB(edge2, vert2, vert0);
+       
+       /* begin calculating determinant - also used to calculate U parameter 
*/
+       CROSS(pvec, dir, edge2);
+       
+       /* if determinant is near zero, ray lies in plane of triangle */
+       det = DOT(edge1, pvec);
+       
+       /* calculate distance from vert0 to ray origin */
+       SUB(tvec, orig, vert0);
+       inv_det = 1.0f/ det;
+       
+       CROSS(qvec, tvec, edge1);
+       
+       /* calculate U parameter */
+       float uu = DOT(tvec, pvec);
+       float vv;
+       
+       if (det > EPSILON)
+       {
+               if (uu < 0.0f || uu > det)
+                                               return 0;
+               
+               /* calculate V parameter and test bounds */
+               vv = DOT(dir, qvec);
+               if (vv < 0.0f || uu + vv > det)
+                                               return 0;
+               
+       }
+       else if(det < -EPSILON)
+       {
+               if (uu > 0.0f || uu < det)
+                                               return 0;
+               
+               /* calculate V parameter and test bounds */
+               vv = DOT(dir, qvec) ;
+               if (vv > 0.0f || uu + vv < det)
+                                               return 0;
+       }
+       else return 0;  /* ray is parallell to the plane of the triangle */
+       
+       *t = DOT(edge2, qvec) * inv_det;
+       (*u) = uu*inv_det;
+       (*v) = vv*inv_det;
+       
+       return 1;
+}
+
+inline int intersectTriangle3Edge(const Vectorf &direction, const Pointf 
&origin, 
+                           const Vectorf &edge1, Vectorf &edge2, Pointf &p0,
+                                                                             
                           float &t, float &u, float &v )
+{
+       
+       Vectorf tvec, pvec, qvec;
+       
+       
+       // Vectorf edge1 = ( tri.edge1 );
+       // Vectorf edge2 = ( tri.edge2 );
+       
+       /* begin calculating determinant - also used to calculate U parameter 
*/
+       pvec = Cross( direction, edge2 );
+       
+       // CROSS(pvec, dir, edge2);
+       
+       /* if determinant is near zero, ray lies in plane of triangle */
+       // det = DOT(edge1, pvec);
+       float det = Dot( edge1, pvec );
+       
+       /* calculate distance from vert0 to ray origin */
+       // SUB(tvec, orig, vert0);
+       tvec = origin - p0;
+       
+       qvec = Cross( tvec, edge1 );
+       // CROSS(qvec, tvec, edge1);
+       
+       /* calculate U parameter */
+       // float uu = DOT(tvec, pvec);
+       // float vv;
+       float uu = Dot( tvec, pvec );
+       float vv;
+       
+       if (det > 1e-5f) {
+               if (uu < 0.0 || uu > det)
+                       return 0;
+               
+               /* calculate V parameter and test bounds */
+               vv = Dot( direction, qvec );
+               
+               if (vv < 0.0 || uu + vv > det)
+                       return 0;
+               
+       }
+       else if(det < -1e-5f) {
+               if (uu > 0.0 || uu < det)
+                       return 0;
+               
+               /* calculate V parameter and test bounds */
+               vv = Dot(direction, qvec) ;
+               if (vv > 0.0 || uu + vv < det)
+                       return 0;
+       }
+       else {
+               return 0;  /* ray is parallell to the plane of the triangle */
+       }
+       
+       float inv_det = 1.0f / det;
+       
+       t = (Dot( edge2, qvec ) * inv_det);
+       u = (uu * inv_det);
+       v = (vv * inv_det);
+       
+       return 1;
+}
+

Added: branches/itanium2/Model/Groups/TransparentKDTree.h
==============================================================================
--- (empty file)
+++ branches/itanium2/Model/Groups/TransparentKDTree.h  Mon Jul 25 19:29:54 
2005
@@ -0,0 +1,122 @@
+/*
+ For more information, please see: http://software.sci.utah.edu

+ The MIT License

+ Copyright (c) 2005
+ Silicon Graphics Inc. Mountain View California.

+ License for the specific language governing rights and limitations under
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+ 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 __TRANSPARENT_KD_TREE_H__
+#define __TRANSPARENT_KD_TREE_H__
+
+#include <Model/Groups/Group.h>
+#include <Core/Geometry/PointVector.h>
+#include <Core/Geometry/BBox.h>
+
+#include <Interface/RayPacket.h>
+#include <Model/Materials/LambertianAlt.h>
+
+#define KDNODE_AXIS_MASK 0x0003
+#define KDNODE_INTERNAL_MASK 0x0004
+#define KDNODE_LEFT_CHILD_MASK 0x0008
+#define KDNODE_RIGHT_CHILD_MASK 0x0010
+#define KDNODE_CHILD_MASK 0x0030
+
+#include <Model/Groups/varray.h>
+#include <Model/Groups/kdtree.h>
+
+namespace Manta {
+
+       namespace Kdtree {
+       
+               
///////////////////////////////////////////////////////////////////////////
+               
///////////////////////////////////////////////////////////////////////////
+               // TRANSPARENT KDTREE CLASS
+               // Note: Uses data structures defined in normal 
TransparentKDTree.
+               
///////////////////////////////////////////////////////////////////////////
+               
///////////////////////////////////////////////////////////////////////////
+               class TransparentKDTree : public Primitive {
+               private:
+                       BBox bbox;
+
+                       KDTreeNode       *rootNode;
+                       
+                       VArray<int>      *triIndices;
+                       VArray<Triangle> *tris;
+                       Vectorf          *normals;
+                       
+                       LambertianAlt *lambMat;
+                       Real sample_alpha;
+                       
+                       // This method intersects a list of triangles with 
the ray.
+                       int intersectTrianglesTransparent(const Ray* ray, 
RayPacket::Element &e, unsigned int listBegin, int listSize, float maxDist, 
void *userData, const RenderContext &context) const;
+                       
+                       // This method is called by the above method with a 
hansong ray.
+                       void _intersect(const Ray* ray, RayPacket::Element 
&e, RayTriIntersectUserData &isectData, const RenderContext &context, float 
_minDist=-1, float _maxDist=-1) const;
+               
+                       // This structure is used to order the triangle hits 
along the ray
+                       // before blending.
+                       struct Isect {
+                               Real t, u, v;
+                               int triIdx;
+                               
+                               inline bool operator < (const Isect &b) const 
{ return t < b.t; }
+                       };
+                       
+                       // Per thread buffers used to order samples for 
blending.
+                       // Note, numprocs+1 are used to allow space for 
shootOneRay queries.
+                       static VArray<VArray<Isect> *> isectBuffers;
+                       
+               public:
+                       // 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 alpha;    // Alpha of the ray (fully 
attenuated at alpha==1.0)
+                               Real sample_t; // t value along ray of last 
sample blended.
+                               
+                               inline void reset() {
+                                       payload  = Color(RGB(0.0,0.0,0.0));
+                                       alpha    = 0.0;
+                                       sample_t = 0.0;
+                               }
+                       };
+                       
+                       // Constructor.
+                       // The transparent KDTree uses data owned by a normal 
KDTree.
+                       TransparentKDTree( KDTree *kdtree_, Real 
sample_alpha_ = 0.25 );
+                       
+                       // Primitive Interface.
+                 void intersect(const RenderContext& context, RayPacket& 
rays) const;
+                       void preprocess(const PreprocessContext& context) {  
};
+                       void setTexCoordMapper(const TexCoordMapper* new_tex) 
{  };
+                       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 ); }
+               };
+       }
+
+}
+
+
+#endif

Modified: branches/itanium2/Model/Groups/kdtree.cc
==============================================================================
--- branches/itanium2/Model/Groups/kdtree.cc    (original)
+++ branches/itanium2/Model/Groups/kdtree.cc    Mon Jul 25 19:29:54 2005
@@ -120,7 +120,7 @@
                                }
                        }
                        
-                       long r, g, b;
+                       float r, g, b;
                        
                        // Check for big endian data.
                        if (is_big_endian()) {
@@ -130,9 +130,12 @@
                                _rawData += 3;
                        }
                        else {
-                               r = int(_rawData[0] * 255 + .5f);
-                               g = int(_rawData[1] * 255 + .5f);
-                               b = int(_rawData[2] * 255 + .5f);
+                               r = _rawData[0];
+                               g = _rawData[1];
+                               b = _rawData[2];
+                               // r = int(_rawData[0] * 255 + .5f);
+                               // g = int(_rawData[1] * 255 + .5f);
+                               // b = int(_rawData[2] * 255 + .5f);
                                _rawData += 3;                  
                        }
                        
@@ -141,7 +144,8 @@
                        (**tris)[i].edge2 = (**tris)[i][2] - (**tris)[i][0];
                        
                        // Specify the payload.
-                       (**tris)[i].payload = ((r<<16)+(g<<8)+b);
+                       // (**tris)[i].payload = ((r<<16)+(g<<8)+b);
+                       (**tris)[i].payload = Color(RGB( r, g, b ));
                        
                        // Compute the normal.
                        (*perVertNormals)[3*i] = Cross((**tris)[i].edge1, 
(**tris)[i].edge2).normal();
@@ -445,7 +449,7 @@
                (**tris)[i][2] = Point(_rawData[0], _rawData[1], _rawData[2]);
                _rawData += 3;
                
-               (**tris)[i].payload = 0xFFFFFF;
+               (**tris)[i].payload = Color(RGB(1.0,1.0,1.0));
                
                // Compute edges.
                (**tris)[i].edge1 = (**tris)[i][1] - (**tris)[i][0]; 
@@ -654,80 +658,6 @@
        }
 }
 
-
-VArray<VArray<KDTree::Isect> *> KDTree::isectBuffers(1024, 0);
-
-int KDTree::intersectTrianglesTransparent(const Ray* ray, unsigned int 
listBegin, int listSize, float maxDist, void *userData, const RenderContext 
&context) const
-{
-       int i;
-       RayTriIntersectUserData *ud = (RayTriIntersectUserData*)userData;
-       float nearest_u, nearest_v;
-       int nearest_tri = -1;
-
-       Vectorf direction = ray->direction();
-       Pointf  origin    = ray->origin();      
-
-       int threadId = context.proc;
-       VArray<KDTree::Isect> *isectbuf = isectBuffers.get(threadId);
-       if (! isectbuf) {
-               isectbuf = new VArray<KDTree::Isect>(8);
-               isectBuffers.set(threadId, isectbuf);
-       }
-       isectbuf->setLen(0);
-       
-       // Intersect the ray with all the triangles. 
-       int listEnd = listBegin+listSize;
-       
-       #pragma swp
-       for (i = listBegin; i < listEnd; i++) {
-               int triIdx = triIndices->get(i);
-               Triangle &tri = tris->get(triIdx);
-               float t, u, v;
-               
-               // if (intersectTriangle3Edge( direction, origin, tri.edge1, 
tri.edge2, tri[0], t, u, v )) {
-               if(intersect_triangle3_edge( &origin, &direction, &tri[0], 
&t, &u, &v, &tri.edge1, &tri.edge2 )) {
-               
-                       // Check to see if the t value is closer.
-                       /*
-                       if (t < maxDist) {
-                               maxDist = t;
-                               nearest_u = u;
-                               nearest_v = v;
-                               nearest_tri = triIdx;
-                       }
-                       */
-                       Isect &isect = isectbuf->append();
-                       isect.t = t;
-                       isect.u = u;
-                       isect.v = v;
-                       isect.triIdx = triIdx;
-               }
-       }
-       
-       if (isectbuf->getLen()) {
-               // sort the intersections
-               Isect *array = isectbuf->getArray();
-               std::sort(array, array+isectbuf->getLen());
-               // combine color and opacity
-               for (int i=0; i<isectbuf->getLen(); i++) {
-               }
-
-               return 1;
-       }
-
-       /*
-       if (nearest_tri >= 0) {
-               ud->rayHit.t = maxDist;
-               ud->rayHit.u = nearest_u;
-               ud->rayHit.v = nearest_v;
-               ud->rayHitTriIndex = nearest_tri;
-               return 1;
-               
-       }*/ else { 
-               return 0;
-       }
-}
-
 
///////////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////////
 // This is the Manta interface method.
@@ -1051,7 +981,7 @@
        return 1;
 }
 
-int intersectTriangle3Edge(const Vectorf &direction, const Pointf &origin, 
+inline int intersectTriangle3Edge(const Vectorf &direction, const Pointf 
&origin, 
                            const Vectorf &edge1, Vectorf &edge2, Pointf &p0,
                                                                              
                           float &t, float &u, float &v )
 {

Modified: branches/itanium2/Model/Groups/kdtree.h
==============================================================================
--- branches/itanium2/Model/Groups/kdtree.h     (original)
+++ branches/itanium2/Model/Groups/kdtree.h     Mon Jul 25 19:29:54 2005
@@ -57,21 +57,21 @@
                class Triangle/*: public Geometry*/ {
                public:
                        Pointf  v[3];         // 3*3 floats = 9*4 bytes = 36 
bytes
-                       int     payload;      // 4 bytes; so far 36+4=40 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, int p=0) {
+                       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_, int p=0) {
+                       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_, int p=0) {
+                       Triangle(const Pointf &v0_, const Pointf &v1_, const 
Pointf &v2_, const Color &p) {
                                v[0] = v0_; v[1] = v1_; v[2] = v2_;
                                payload = p;
                        }
@@ -240,6 +240,10 @@
                
///////////////////////////////////////////////////////////////////////////
                
///////////////////////////////////////////////////////////////////////////
                class KDTree : public Primitive {
+               
+                       // Transparent KDTree will use data owned by this 
kdtree.
+                       friend class TransparentKDTree;
+               
                private:
                        BBox bbox;
                        
@@ -253,25 +257,15 @@
                        
                        // This method intersects a list of triangles with 
the ray.
                        int intersectTriangles(const Ray* ray, unsigned int 
listBegin, int listSize, float maxDist, void *userData, const RenderContext 
&context) const;
-                       int intersectTrianglesTransparent(const Ray* ray, 
unsigned int listBegin, int listSize, float maxDist, void *userData, const 
RenderContext &context) const;
                        
                        // This method is called by the above method with a 
hansong ray.
                        void _intersect(const Ray* ray, RayPacket::Element 
&e, RayTriIntersectUserData &isectData, const RenderContext &context, float 
_minDist=-1, float _maxDist=-1) const;
-               public:
-                       struct Isect {
-                               float t, u, v;
-                               int triIdx;
-                               bool operator<(const Isect &b) const {
-                                       return t < b.t;
-                               }
-                       };
-                       static VArray<VArray<Isect> *> isectBuffers;
-                       
+
                public:
                        // This structure is used to record info about the 
hit.
                        struct ScratchPadInfo {
                                Vector normal;        // Normal of the 
intersected face.
-                               unsigned int payload; // Payload of the 
intersected face.
+                               Color payload; // Payload of the intersected 
face.
                        };
                        
                        // Primitive Interface.

Modified: branches/itanium2/Model/Groups/varray.h
==============================================================================
--- branches/itanium2/Model/Groups/varray.h     (original)
+++ branches/itanium2/Model/Groups/varray.h     Mon Jul 25 19:29:54 2005
@@ -66,6 +66,22 @@
                }
                assert (array != NULL);
        }
+       inline void setLen(int len,const T &val) {
+               curLen = len;
+               if (curMaxLen < len) {
+                       curMaxLen = len;
+                       if (array)
+                               array = (T*)realloc(array, 
curMaxLen*sizeof(T));
+                       else
+                               array = (T*)malloc(curMaxLen*sizeof(T));
+               }
+               
+               for (int i=0;i<len;++i) {
+                       array[i] = val;
+               }
+               
+               assert (array != NULL);
+       }
        inline void resize(int len) {
                curMaxLen = len;
                array = (T*)realloc(array, curMaxLen*sizeof(T));

Modified: branches/itanium2/Model/Materials/LambertianAlt.cc
==============================================================================
--- branches/itanium2/Model/Materials/LambertianAlt.cc  (original)
+++ branches/itanium2/Model/Materials/LambertianAlt.cc  Mon Jul 25 19:29:54 
2005
@@ -10,32 +10,44 @@
 #include <Interface/ShadowAlgorithm.h>
 #include <Model/Textures/Constant.h>
 #include <Interface/Scene.h>
+#include <SCIRun/Core/Math/MiscMath.h>
 
 using namespace Manta;
 
+using namespace SCIRun;
+
 void LambertianAlt::shade(const RenderContext& context, RayPacket& rays) 
const {
        
        // Copy colors from hit info.
        Color colors[RayPacket::MaxSize];
        Real inv255 = 1.0/255.0;
-       
+
        for (int i=0;i<rays.getSize();i++) {
                RayPacket::Element& e = rays.get(i);
-               unsigned int rgb = 
e.hitInfo.scratchpad<Kdtree::KDTree::ScratchPadInfo>().payload;
+               // colors[i] = 
e.hitInfo.scratchpad<Kdtree::KDTree::ScratchPadInfo>().payload;
+               
+               Vector &normal = 
e.hitInfo.scratchpad<Kdtree::KDTree::ScratchPadInfo>().normal;
                
-               colors[i] = Color(RGBColor(((rgb & 0xFF0000) >> 16)*inv255,
-                                                                  ((rgb & 
0x00FF00) >>  8)*inv255,
-                                                                  ((rgb & 
0x0000FF) >>  0)*inv255));
+               Real scale   = Abs(Dot(normal,e.ray.direction()));
+               scale = (scale * 0.5)+0.5;
+               
+               Color result = 
(e.hitInfo.scratchpad<Kdtree::KDTree::ScratchPadInfo>().payload * scale);
+               
+               rays.setResult( i, result );
        }
-#if 0  
+
+#if 0
        for(int i=0;i<rays.getSize();i++) {
                RayPacket::Element& e = rays.get(i);
-               float z = SCIRun::Abs(e.normal[2]);
-               Color totalLight(RGBColor(z,z,z));
-               rays.setResult(i, colors[i]*totalLight);
+               Vector normal = 
e.hitInfo.scratchpad<Kdtree::KDTree::ScratchPadInfo>().normal;
+               normal *= 0.5;
+               normal += Vector( 0.5, 0.5, 0.5 );
+               Color normal_color( RGB( normal[0], normal[1], normal[2] ) );
+               rays.setResult( i, normal_color );
        }
-       return;
-#endif
+#endif 
+
+#if 0
        
        Scene *scene = (Scene*)context.scene;
        
@@ -45,17 +57,6 @@
        // Compute the normals.
        rays.computeNormals( context );
        
-# if 0
-       for (int i=0;i<rays.getSize();++i) {
-               
-               Vector n = rays.get(i).normal;
-               Color color(RGB( n[0]*0.5+0.5,
-                                n[1]*0.5+0.5,
-                                                n[2]*0.5+0.5 ) );
-               rays.setResult(i,color);
-       }
-#endif 
-       
        // #if 0
        RayPacketData data;
        int start = 0;
@@ -96,5 +97,5 @@
                
                start = end;
        } while(start < rays.getSize());
-       // #endif
+       #endif
 }




  • [MANTA] r440 - in branches/itanium2: Engine/Control Model/Groups Model/Materials, abe, 07/25/2005

Archive powered by MHonArc 2.6.16.

Top of page