Text archives Help
- 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.