Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r338 - in branches/itanium2/Model: Groups Materials


Chronological Thread 
  • From: hansong@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r338 - in branches/itanium2/Model: Groups Materials
  • Date: Tue, 24 May 2005 14:38:17 -0600 (MDT)

Author: hansong
Date: Tue May 24 14:38:15 2005
New Revision: 338

Added:
   branches/itanium2/Model/Groups/geom.h
   branches/itanium2/Model/Groups/kdtree.cc
   branches/itanium2/Model/Groups/kdtree.h
   branches/itanium2/Model/Groups/raytri.cpp
   branches/itanium2/Model/Groups/varray.h   (contents, props changed)
   branches/itanium2/Model/Materials/LambertianAlt.cc
   branches/itanium2/Model/Materials/LambertianAlt.h
Log:
add kdtree first cut and a modified Lambertian that does no per primitive 
normal computation

Added: branches/itanium2/Model/Groups/geom.h
==============================================================================
--- (empty file)
+++ branches/itanium2/Model/Groups/geom.h       Tue May 24 14:38:15 2005
@@ -0,0 +1,86 @@
+#ifndef __GEOM_H__
+#define __GEOM_H__
+
+#include <string.h>
+#include "vmath.h"
+#include "varray.h"
+
+/*
+class Geometry {
+protected:
+public:
+       void *payload;
+
+       Geometry() { payload = NULL; }
+       virtual void* getPayload() { return payload; }
+       virtual void setPayload(void *p) { payload = p; }
+};
+*/
+
+class Triangle/*: public Geometry*/ {
+public:
+       Vec3f v0, v1, v2; // 3*3 floats = 9*4 bytes = 36 bytes
+       int payload; // 4 bytes; so far 36+4=40 bytes
+       Vec3f 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) {
+               v0 = *(Vec3f*)tri; v1 = *(Vec3f*)(tri+3); v2 = 
*(Vec3f*)(tri+6);
+               payload = p;
+       }
+       Triangle(const Vec3f *v, int p=0) {
+               v0 = v[0]; v1 = v[1]; v2 = v[2];
+               payload = p;
+       }
+       Triangle(const Vec3f &v0_, const Vec3f &v1_, const Vec3f &v2_, 
+               int p=0) {
+               v0 = v0_; v1 = v1_; v2 = v2_;
+               payload = p;
+       }
+
+       Vec3f &operator[] (int i) {
+               return (&v0)[i];
+       }
+       
+       void set(const float *v0_, const float *v1_, const float *v2_) {
+               v0 = *(Vec3f*)v0_;
+               v1 = *(Vec3f*)v1_;
+               v2 = *(Vec3f*)v2_;
+       }
+
+       float* getRawData() {
+               return &v0[0];
+       }
+
+       void getBound(float *min, float*max) {
+               min[0] = min[1] = min[2] = 1e20;
+               max[0] = max[1] = max[2] = -1e20;
+               for (int i=0; i<3; i++) {
+                       float *v = (float*)(&v0 + i);
+                       if (min[0] > v[0]) min[0] = v[0];
+                       if (max[0] < v[0]) max[0] = v[0];
+                       if (min[1] > v[1]) min[1] = v[1];
+                       if (max[1] < v[1]) max[1] = v[1];
+                       if (min[2] > v[2]) min[2] = v[2];
+                       if (max[2] < v[2]) max[2] = v[2];
+               }
+       }
+};
+
+class PackedTriangles {
+       VArray<Vec3f> *_v0;
+       VArray<Vec3f> *_v1;
+       VArray<Vec3f> *_v2;
+       VArray<int> *_payload;
+public:
+       void pack(VArray<Triangle> *tris);
+       Vec3f& getV0(int i) { return _v0->_get(i); }
+       Vec3f& getV1(int i) { return _v1->_get(i); }
+       Vec3f& getV2(int i) { return _v2->_get(i); }
+       int& getPayload(int i) { return _payload->_get(i); }
+};
+
+#endif

Added: branches/itanium2/Model/Groups/kdtree.cc
==============================================================================
--- (empty file)
+++ branches/itanium2/Model/Groups/kdtree.cc    Tue May 24 14:38:15 2005
@@ -0,0 +1,344 @@
+#include <stdio.h>
+#include "math/vmath.h"
+#include "varray.h"
+#undef SWAP
+#include "geom.h"
+#include "kdtree.h"
+#include <Model/Primitives/NullPrimitive.h>
+#include <Model/Intersections/AxisAlignedBox.h>
+
+#include "raytri.cpp"
+
+using namespace Manta;
+int LoadTris(char *filename, VArray<Triangle> **tris, 
+               Vec3f **perTriNormals, Vec3f **perVertNormals, 
+               Vec3f& min, Vec3f& max)
+{
+       int i, j, n;
+       FILE *f;
+       float len;
+
+       perVertNormals=perVertNormals;
+
+       if ((f=fopen(filename, "r")) == NULL) {
+               fprintf(stderr, "Cannot open file: %s\n", filename);
+               return 0;
+       }
+
+       *tris = new VArray<Triangle>;
+
+       min[0] = min[1] = min[2] = 1e20;
+       max[0] = max[1] = max[2] = -1e20;
+       while (! feof(f)) {
+               Triangle tri;
+               bool error=false;
+               char colorString[32];
+               unsigned int color;
+               for (j=0; j<3; j++) {
+                       float * v = (float*)&tri[j];
+                       if (fscanf(f, "%f %f %f", v, v+1, v+2) != 3) {
+                               error = 1;
+                               break;
+                       }
+               }
+
+               if (! error && fscanf(f, "%s", colorString) != 1) {
+                       error = 1;
+               }
+
+               if (error) {
+                       fprintf(stderr, "Error in file\n");
+                       break;
+               }
+               sscanf(colorString+2, "%X", &color);
+               *(unsigned int*)&tri.payload = color;
+
+               // Get rid of degenerate polygons
+               if ( SAME_TOL_VEC3V(tri[0], tri[1], 1e-5) ||
+                               SAME_TOL_VEC3V(tri[1], tri[2], 1e-5) ||
+                               SAME_TOL_VEC3V(tri[2], tri[0], 1e-5) ) {
+                       fprintf(stderr, "Degenerated triangle.\n");
+                       continue;
+               }
+
+               // Update the bounding box of the whole scene
+               for (j=0; j<3; j++) {
+                       float * v = (float*)&tri[j];
+                       if (min[0] > v[0]) min[0] = v[0];
+                       else if (max[0] < v[0]) max[0] = v[0];
+                       if (min[1] > v[1]) min[1] = v[1];
+                       else if (max[1] < v[1]) max[1] = v[1];
+                       if (min[2] > v[2]) min[2] = v[2];
+                       else if (max[2] < v[2]) max[2] = v[2];
+               }
+
+               SUB_VEC3V(tri.edge1, tri.v1, tri.v0);
+               SUB_VEC3V(tri.edge2, tri.v2, tri.v0);
+               (**tris).append(tri);
+       }
+       fprintf(stderr, "%d triangles loaded\n",(**tris).getLen());
+
+       n = (**tris).getLen();
+       if (perTriNormals) { // if per-triangle normals are required
+               *perTriNormals = new Vec3f [n];
+               for (i=0; i<n; i++) {
+                       Vec3f v01, v02;
+                       SUB_VEC3V(v01, (**tris)[i][1], (**tris)[i][0]);
+                       SUB_VEC3V(v02, (**tris)[i][2], (**tris)[i][0]);
+                       CROSS_VEC3V((*perTriNormals)[i], v01, v02);
+                       UNIT_VEC3V((*perTriNormals)[i], (*perTriNormals)[i], 
len);
+               }
+       }
+
+       if (perVertNormals) { // if per-vertex normals are required
+               *perVertNormals = new Vec3f [3*n];
+               for (i=0; i<n; i++) {
+                       Vec3f v01, v02;
+                       SUB_VEC3V(v01, (**tris)[i][1], (**tris)[i][0]);
+                       SUB_VEC3V(v02, (**tris)[i][2], (**tris)[i][0]);
+
+                       int offset = i*3;
+                       CROSS_VEC3V((*perVertNormals)[offset], v01, v02);
+                       UNIT_VEC3V((*perVertNormals)[offset], 
(*perVertNormals)[offset], len);
+                       (*perVertNormals)[offset+1] = 
(*perVertNormals)[offset+2] =
+                               (*perVertNormals)[offset];
+               }
+       }
+
+       /*
+          for (i=0; i<n; i++) {
+          if (feof(f)) {
+          delete perVertNormals;
+          perVertNormals = NULL;
+          break;
+          }
+          for (j=0; j<3; j++) {
+          float * v = (*perVertNormals)[i][j];
+          fscanf(f, "%f %f %f", v, v+1, v+2);
+          }
+          }
+        */
+
+       if (fclose(f))
+               fprintf(stderr, "Error closing %s\n", filename);
+
+       return 1;
+}
+
+int
+KDTree::load(char *fn)
+{
+       LoadTris(fn, &tris, NULL, &normals,
+                       bbox.min, bbox.max);
+
+       char filename[512];
+       strcpy(filename, fn);
+       strcat(filename, ".kd"); // the kd-tree file
+       FILE *f = fopen(filename, "rb");
+       if (! f) {
+               fprintf(stderr, "Error: cannot open %s for loading\n", 
filename);
+               // return 0;
+       }
+
+       fseek(f, 0, SEEK_END);
+       long long fileSize = ftell(f);
+
+       void *buffer = (void*)malloc(fileSize);
+       fseek(f, 0, SEEK_SET);
+       long long nread = fread(buffer, 1, fileSize, f);
+       if (nread != fileSize) {
+               fprintf(stderr, "error reading file %s (size: %lld read: 
%lld)\n",
+                               filename, fileSize, nread);
+               // return 0;
+       }
+       fclose(f);
+
+       rootNode = (KDTreeNode*)buffer;
+       // get the bounding box
+       bbox = *(AABox3f*)((char*)buffer + fileSize - sizeof(AABox3f));
+       bbox_ms = AABox3f_ms(bbox);
+
+
+       // load the index file
+       strcpy(filename, fn);
+       strcat(filename, ".idx"); // the kd-tree file
+       f = fopen(filename, "rb");
+       if (! f) {
+               fprintf(stderr, "Error: cannot open %s for loading\n", 
filename);
+               return 0;
+       }
+
+       fseek(f, 0, SEEK_END);
+       fileSize = ftell(f);
+       fseek(f, 0, SEEK_SET);
+       long long nInt = fileSize/sizeof(int);
+       VArray<int> *indices = new VArray<int>(nInt);
+       indices->setLen(nInt);
+       nread = fread(indices->getArray(), sizeof(int), nInt, f);
+       if (nread != nInt) {
+               fprintf(stderr, "error reading file %s (size: %lld read: 
%lld)\n",
+                               filename, fileSize, nread);
+               return 0;
+       }
+       fclose(f);
+
+       triIndices = indices;
+
+       // create material
+       lambMat = new LambertianAlt;
+
+       return 1;
+}
+
+
+
+int 
+KDTree::intersectTriangles(const Ray3f* ray, /*const RayInternal* 
rayInternal, */
+               unsigned int listBegin, int listSize, float maxDist, void 
*userData) const
+{
+       int i,j;
+       RayTriIntersectUserData *ud = (RayTriIntersectUserData*)userData;
+       float nearest_u, nearest_v;
+       int nearest_tri=-1;
+
+       /* Intersect the ray with all the bounding boxes */
+       int listEnd = listBegin+listSize;
+       for (i = listBegin; i < listEnd; i++) {
+               int triIdx = triIndices->get(i);
+               Triangle &tri = tris->get(triIdx);
+               float t, u, v;
+               if (intersect_triangle3_edge(&ray->pos[0], &ray->dir[0],
+                                       &tri.v0[0], &tri.v1[0], &tri.v2[0],
+                                       &t, &u, &v, &tri.edge1[0], 
&tri.edge2[0])) {
+                       if (t < maxDist) {
+                               maxDist = t;
+                               nearest_u= u;
+                               nearest_v= v;
+                               nearest_tri = triIdx;
+                       }
+               }
+       }
+
+       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;
+}
+
+
+typedef struct {
+       KDTreeNode* node; //8 bytes
+       float t; // 4 bytes
+       // float point[3]; // 4*3=12 bytes
+       int prev; // 4 bytes
+} TravStackEntry;
+
+void KDTree::intersect(const RenderContext& context, RayPacket& rays) const
+{
+       rays.computeInverseDirections();
+       RayTriIntersectUserData isectData;
+       NullPrimitive nullPrim;
+       
+       for(int i=0;i<rays.getSize();i++) {
+               RayPacket::Element& e = rays.get(i);
+               Real minDist=0, maxDist=0;
+               if (! Intersection::intersect_box(bbox, 
+                                       minDist, maxDist, e.ray,
+                                       e.sign_mask, e.inverseDirection))
+                       continue;
+
+               Ray3f ray;
+               COPY_VEC3V(ray.pos, e.ray.origin());
+               COPY_VEC3V(ray.dir, e.ray.direction());
+               isectData.rayHitTriIndex = 0;
+               _intersect(&ray, e, &isectData,
+                               minDist, maxDist);
+               if (isectData.rayHitTriIndex >= 0) {
+                       COPY_VEC3V(e.normal, 
normals[isectData.rayHitTriIndex*3]);
+                       e.hitInfo.hit(isectData.rayHit.t, lambMat, &nullPrim, 
NULL);
+                       e.hitInfo.scratchpad<int>() = 
tris->get(isectData.rayHitTriIndex).payload;
+               }
+       }
+}
+
+void KDTree::_intersect(
+               const Ray3f* ray, RayPacket::Element &e, void *userData,
+               float minDist, float maxDist) const
+{
+       TravStackEntry travStack[128];
+       KDTreeNode *nearNode, *farNode;
+       float split;
+       int axis, entryPos, exitPos;
+       bool foundIntersection = false;
+       int tmp;
+
+       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) {
+
+               while (nearNode && nearNode->isInternal()) {
+
+                       axis = nearNode->axis();
+                       split = nearNode->split();
+
+                       float entryPos_coord_on_axis = ray->pos[axis] + 
+                               travStack[entryPos].t*ray->dir[axis];
+                       float exitPos_coord_on_axis = ray->pos[axis] + 
+                               travStack[exitPos].t*ray->dir[axis];
+
+                       if (entryPos_coord_on_axis <= split) {
+                               if (exitPos_coord_on_axis <= split) {
+                                       nearNode = nearNode->left();
+                                       continue;
+                               }
+                               farNode = nearNode->right();
+                               nearNode = nearNode->left();
+                       }
+                       else {
+                               if (exitPos_coord_on_axis >= split) {
+                                       nearNode = nearNode->right();
+                                       continue;
+                               }
+                               farNode = nearNode->left();
+                               nearNode = nearNode->right();
+                       }
+
+                       tmp = exitPos;
+                       if (++exitPos == entryPos) ++exitPos;
+
+                       travStack[exitPos].node = farNode;
+
+                       travStack[exitPos].t = (split - ray->pos[axis])*
+                               e.inverseDirection[axis];
+
+                       travStack[exitPos].prev = tmp;
+               }
+
+               if (nearNode) {
+                       foundIntersection = 
+                               intersectTriangles(ray,
+                                       nearNode->listBegin(), 
+                                       nearNode->listSize(), 
travStack[exitPos].t,
+                                       userData);
+               }
+
+               if (foundIntersection) break;
+
+               entryPos = exitPos;
+               exitPos = travStack[exitPos].prev;
+               nearNode = travStack[entryPos].node;
+       }
+
+}

Added: branches/itanium2/Model/Groups/kdtree.h
==============================================================================
--- (empty file)
+++ branches/itanium2/Model/Groups/kdtree.h     Tue May 24 14:38:15 2005
@@ -0,0 +1,81 @@
+#ifndef __KD_TREE_H__
+#define __KD_TREE_H__
+
+#include <Model/Groups/Group.h>
+#include <Core/Geometry/PointVector.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 "varray.h"
+#include "geom.h"
+#include "math/vmath.h"
+
+namespace Manta {
+
+struct KDTreeInternalNode {
+       unsigned char flags;
+       unsigned int left;
+       float split;
+};
+
+struct KDTreeLeafNode {
+       unsigned char flags;
+       unsigned int listBegin;
+       unsigned int listLen;
+};
+
+union KDTreeNode {
+       KDTreeInternalNode internal;
+       KDTreeLeafNode leaf;
+
+       bool hasLeftChild() { return internal.flags & KDNODE_LEFT_CHILD_MASK; 
}
+       bool hasRightChild() { return internal.flags & 
KDNODE_RIGHT_CHILD_MASK; }
+       KDTreeNode* left() { return hasLeftChild()?this+internal.left : NULL; 
}
+       KDTreeNode* right() { return hasRightChild()?
+               (hasLeftChild()?this+internal.left+1:this+internal.left) : 0; 
}
+       float split() { return internal.split; }
+       bool isInternal() { return internal.flags & KDNODE_INTERNAL_MASK; }
+       unsigned int axis() { return internal.flags & KDNODE_AXIS_MASK; }
+
+       unsigned int listBegin() { return leaf.listBegin; }
+       unsigned int listSize() { return leaf.listLen; }
+
+
+};
+
+typedef struct {
+       int rayHitTriIndex; 
+       RayHit_Triangle rayHit;
+       float eyeToHitDist2;
+} RayTriIntersectUserData;
+
+class KDTree : public Group {
+       AABox3f bbox;
+       AABox3f_ms bbox_ms;
+       KDTreeNode *rootNode;
+       VArray<int> *triIndices;
+       VArray<Triangle> *tris;
+       Vec3f *normals;
+       LambertianAlt *lambMat;
+       public:
+       int load(char *fn);
+
+       int intersectTriangles(const Ray3f* ray,
+               unsigned int listBegin, int listSize, float maxDist, void 
*userData) const;
+
+       void intersect(const RenderContext& context, RayPacket& rays) const;
+       void _intersect(const Ray3f* ray, RayPacket::Element &e, void 
*userData,
+                       float _minDist=-1, float _maxDist=-1) const;
+};
+
+}
+
+
+#endif

Added: branches/itanium2/Model/Groups/raytri.cpp
==============================================================================
--- (empty file)
+++ branches/itanium2/Model/Groups/raytri.cpp   Tue May 24 14:38:15 2005
@@ -0,0 +1,401 @@
+/********************************************************/
+/* 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]; 
+
+/* the original jgt code */
+inline int intersect_triangle(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], 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);
+
+   if (det > -EPSILON && det < EPSILON)
+     return 0;
+   inv_det = 1.0f/ det;
+
+   /* calculate distance from vert0 to ray origin */
+   SUB(tvec, orig, vert0);
+
+   /* calculate U parameter and test bounds */
+   *u = DOT(tvec, pvec) * inv_det;
+   if (*u < 0.0f || *u > 1.0)
+     return 0;
+
+   /* prepare to test V parameter */
+   CROSS(qvec, tvec, edge1);
+
+   /* calculate V parameter and test bounds */
+   *v = DOT(dir, qvec) * inv_det;
+   if (*v < 0.0f || *u + *v > 1.0)
+     return 0;
+
+   /* calculate t, ray intersects triangle */
+   *t = DOT(edge2, qvec) * inv_det;
+
+   return 1;
+}
+
+
+/* code rewritten to do tests on the sign of the determinant */
+/* the division is at the end in the code                    */
+inline int intersect_triangle1(float orig[3], float dir[3],
+                        float vert0[3], float vert1[3], float vert2[3],
+                        float *t, float *u, float *v)
+{
+   float edge1[3], edge2[3], 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);
+
+   if (det > EPSILON)
+   {
+      /* calculate distance from vert0 to ray origin */
+      SUB(tvec, orig, vert0);
+      
+      /* calculate U parameter and test bounds */
+      *u = DOT(tvec, pvec);
+      if (*u < 0.0f || *u > det)
+         return 0;
+      
+      /* prepare to test V parameter */
+      CROSS(qvec, tvec, edge1);
+      
+      /* calculate V parameter and test bounds */
+      *v = DOT(dir, qvec);
+      if (*v < 0.0f || *u + *v > det)
+         return 0;
+      
+   }
+   else if(det < -EPSILON)
+   {
+      /* calculate distance from vert0 to ray origin */
+      SUB(tvec, orig, vert0);
+      
+      /* calculate U parameter and test bounds */
+      *u = DOT(tvec, pvec);
+/*      printf("*u=%f\n",(float)*u); */
+/*      printf("det=%f\n",det); */
+      if (*u > 0.0f || *u < det)
+         return 0;
+      
+      /* prepare to test V parameter */
+      CROSS(qvec, tvec, edge1);
+      
+      /* calculate V parameter and test bounds */
+      *v = DOT(dir, qvec) ;
+      if (*v > 0.0f || *u + *v < det)
+         return 0;
+   }
+   else return 0;  /* ray is parallell to the plane of the triangle */
+
+
+   inv_det = 1.0f/ det;
+
+   /* calculate t, ray intersects triangle */
+   *t = DOT(edge2, qvec) * inv_det;
+   (*u) *= inv_det;
+   (*v) *= inv_det;
+
+   return 1;
+}
+
+/* code rewritten to do tests on the sign of the determinant */
+/* the division is before the test of the sign of the det    */
+inline int intersect_triangle2(float orig[3], float dir[3],
+                        float vert0[3], float vert1[3], float vert2[3],
+                        float *t, float *u, float *v)
+{
+   float edge1[3], edge2[3], 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;
+   
+   if (det > EPSILON)
+   {
+      /* calculate U parameter and test bounds */
+      *u = DOT(tvec, pvec);
+      if (*u < 0.0f || *u > det)
+         return 0;
+      
+      /* prepare to test V parameter */
+      CROSS(qvec, tvec, edge1);
+      
+      /* calculate V parameter and test bounds */
+      *v = DOT(dir, qvec);
+      if (*v < 0.0f || *u + *v > det)
+         return 0;
+      
+   }
+   else if(det < -EPSILON)
+   {
+      /* calculate U parameter and test bounds */
+      *u = DOT(tvec, pvec);
+      if (*u > 0.0f || *u < det)
+         return 0;
+      
+      /* prepare to test V parameter */
+      CROSS(qvec, tvec, edge1);
+      
+      /* calculate V parameter and test bounds */
+      *v = DOT(dir, qvec) ;
+      if (*v > 0.0f || *u + *v < det)
+         return 0;
+   }
+   else return 0;  /* ray is parallell to the plane of the triangle */
+
+   /* calculate t, ray intersects triangle */
+   *t = DOT(edge2, qvec) * inv_det;
+   (*u) *= inv_det;
+   (*v) *= inv_det;
+
+   return 1;
+}
+
+/* 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], const float vert1[3], const 
float vert2[3],
+                        float *t, float *u, float *v,
+                                               float *edge1, 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 void rays_intersect_triangle3(const float orig[3], const float *dir, 
+                                               int nRays,
+                        float vert0[3], float vert1[3], float vert2[3],
+                        int hits[], float t[], float u[], float v[])
+{
+   float edge1[3], edge2[3], 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);
+
+   /* calculate distance from vert0 to ray origin */
+   SUB(tvec, orig, vert0);

+   CROSS(qvec, tvec, edge1);
+
+   float tt, uu, vv;
+for (int i=0; i<nRays; i++, dir+=3) {
+   /* 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);
+   //fprintf(stderr, "dir:%f %f %f; det: %f\n", dir[0], dir[1], dir[2], det);
+
+   /* calculate distance from vert0 to ray origin */
+   // SUB(tvec, orig, vert0);
+   inv_det = 1.0f/ det;
+   
+   // CROSS(qvec, tvec, edge1);
+      
+   /* calculate U parameter and test bounds */
+   uu = DOT(tvec, pvec);
+   if (det > EPSILON) {
+      if (uu < 0.0f || uu > det) {
+             hits[i] = 0;
+                 continue;
+      }
+            
+      /* calculate V parameter and test bounds */
+      vv = DOT(dir, qvec);
+      if (vv < 0.0f || uu + vv > det) {
+             hits[i] = 0;
+                 continue;
+         }
+   }
+   else if(det < -EPSILON)
+   {
+      if (uu > 0.0f || uu < det) {
+             hits[i] = 0;
+                 continue;
+         }
+      
+      /* calculate V parameter and test bounds */
+      vv = DOT(dir, qvec) ;
+      if (vv > 0.0f || uu + vv < det) {
+             hits[i] = 0;
+                 continue;
+         }
+   } else {
+               hits[i] = 0;
+               continue;
+   }
+
+   t[i] = DOT(edge2, qvec) * inv_det;
+   u[i] = uu*inv_det;
+   v[i] = vv*inv_det;
+   hits[i] = 1;
+}
+
+}

Added: branches/itanium2/Model/Groups/varray.h
==============================================================================
--- (empty file)
+++ branches/itanium2/Model/Groups/varray.h     Tue May 24 14:38:15 2005
@@ -0,0 +1,196 @@
+/********************************************************************\
+File:   varray.h
+Author: Hansong Zhang
+Department of Computer Science
+UNC-Chapel Hill
+
+$Id: varray.h,v 1.2 1997/09/10 16:00:59 zhangh Exp $
+\********************************************************************/
+
+#ifndef __VARRAY_H__
+#define __VARRAY_H__
+
+
+#include "alloc.h"
+
+#include <assert.h>
+#include <stdio.h>
+
+#define DEBUG_ARRAY
+
+template <class T>
+class VArray {
+protected:
+       int curLen;
+       int curMaxLen;
+       T* array;
+public:
+       VArray() {
+               curLen = curMaxLen = 0;
+               array = NULL;
+       }
+
+       VArray(int initMaxLen) {
+               init(initMaxLen);
+       }
+
+       void init(int initMaxLen) {
+               curLen = 0;
+               curMaxLen = initMaxLen;
+               array = (T*)malloc(curMaxLen * sizeof(T));
+               assert (array != NULL);
+       }
+
+       inline int getLen() { return curLen; }
+       inline int getNum() { return curLen; }
+       inline void setLen(int len) {
+               curLen = len;
+               if (curMaxLen < len) {
+                       curMaxLen = len;
+                       if (array)
+                               array = (T*)realloc(array, 
curMaxLen*sizeof(T));
+                       else
+                               array = (T*)calloc(curMaxLen, sizeof(T));
+               }
+               assert (array != NULL);
+       }
+       inline void resize(int len) {
+               curMaxLen = len;
+               array = (T*)realloc(array, curMaxLen*sizeof(T));
+               assert (array != NULL);
+       }
+       inline void reset() { curLen=0; }
+       inline void append() { 
+               if (curLen < curMaxLen)
+                       curLen ++; 
+               else {
+                       curMaxLen = (int)(curMaxLen*1.3f);
+                       if (array)
+                               array = (T*)realloc(array, 
curMaxLen*sizeof(T));
+                       else
+                               array = (T*)malloc(curMaxLen*sizeof(T));
+
+                       assert(array != NULL);
+                       curLen ++;
+               }
+       }
+
+       inline void append(const T& data) {
+               if (curMaxLen == 0) {
+                       curLen = 0;
+                       curMaxLen = 8;
+                       array = (T*)malloc(curMaxLen * sizeof(T));
+               }
+
+               if (curLen < curMaxLen) {
+                       array[curLen ++] = data;
+               } else {
+                       // fprintf(stderr, "cur:%d, max:%d\n", curLen, 
curMaxLen);
+                       curMaxLen = (int)(curMaxLen*1.3f);
+                       if (array)
+                               array = (T*)realloc(array, 
curMaxLen*sizeof(T));
+                       else
+                               array = (T*)malloc(curMaxLen*sizeof(T));
+                       assert(array != NULL);
+                       array[curLen ++] = data; 
+               }
+       }
+
+       void fit() {
+               if (curLen != curMaxLen) {
+                       array = (T*)realloc(array, curLen*sizeof(T));
+                       assert(array != NULL);
+                       curMaxLen = curLen;
+               }
+       }
+
+       inline T &operator[](int i) { 
+               if (array && i < curLen)
+                       return array[i];
+               else {
+                       fprintf(stderr, "VArray(%p)::[] reference out of 
bound (idx:%d size:%d)\n", this, i, curLen);
+                       assert(0);
+                       return array[0];
+               }
+       }
+
+       inline T & get(int i) {
+#ifdef DEBUG_ARRAY
+               if (i >= curLen) {
+                       fprintf(stderr, "VArray(%p)::get() reference out of 
bound (%d).\n", this, i);
+                       assert(0);
+                       return array[0];
+               }
+#endif
+               return (*this)[i];
+       }
+
+       inline T & _get(int i) {
+#ifdef DEBUG_ARRAY
+               if (i >= curLen) {
+                       fprintf(stderr, "VArray(%p)::_get() reference out of 
bound (%d).\n", this, i);
+                       assert(0);
+                       return array[0];
+               }
+#endif
+               return array[i];
+       }
+
+       inline void set(int i, const T& elem) {
+#ifdef DEBUG_ARRAY
+               if (array && i >= curLen) {
+                       fprintf(stderr, "VArray(%p)::set() out of range 
(%d).\n", this, i);
+               }
+#endif
+               array[i] = elem;
+       }
+
+       inline void _set(int i, const T& elem) {
+               array[i] = elem;
+       }
+
+       inline T & last() {
+               return array[curLen-1];
+       }
+
+       inline T *getArray() {
+               return array;
+       }
+       inline T *dupArray() {
+               T *ret = (T*)malloc(curLen * sizeof(T));
+               if (! ret) {
+                       fprintf(stderr, "Cannot alloc mem in dupArray().\n");
+                       return NULL;
+               }
+               memcpy(ret, array, curLen * sizeof(T));
+               return ret;
+       }
+
+       ~VArray() { if (array) free(array); }
+       void freemem() { 
+               if (array) {
+                       free(array);
+                       curLen = curMaxLen = 0;
+               }
+       }
+
+       void clear() {
+               if (array)
+                       memset(array, 0, sizeof(T)*curMaxLen);
+       }
+};
+
+/*
+template <class T>
+class VPool : public VArray<T> {
+       public:
+       VPool(int size):VArray<T>(size) {}      
+       T& alloc(int * offset=NULL) {
+               append();
+               if (offset) *offset = curLen-1;
+               return array[curLen-1];
+       }
+};
+*/
+
+#endif

Added: branches/itanium2/Model/Materials/LambertianAlt.cc
==============================================================================
--- (empty file)
+++ branches/itanium2/Model/Materials/LambertianAlt.cc  Tue May 24 14:38:15 
2005
@@ -0,0 +1,83 @@
+
+#include <Model/Materials/LambertianAlt.h>
+#include <Interface/Light.h>
+#include <Interface/LightSet.h>
+#include <Interface/Primitive.h>
+#include <Interface/RayPacket.h>
+#include <Interface/AmbientLight.h>
+#include <Interface/Context.h>
+#include <Interface/ShadowAlgorithm.h>
+#include <Model/Textures/Constant.h>
+#include <Interface/Scene.h>
+
+using namespace Manta;
+
+void LambertianAlt::shade(const RenderContext& context, RayPacket& rays) 
const
+{
+  // Shade a bunch of rays.  We know that they all have the same intersected
+  // object and are all of the same material
+
+  // Compute normals
+  // rays.computeNormals(context);
+
+  // Compute colors
+  Color colors[RayPacket::MaxSize];
+  float inv255 = 1.0f/255.0f;
+  for (int i=0;i<rays.getSize();i++) {
+      RayPacket::Element& e = rays.get(i);
+      int rgb = e.hitInfo.scratchpad<int>();
+      colors[i] = Color(RGBColor(
+                 ((rgb & 0xFF0000) >> 16)*inv255,
+                 ((rgb & 0x00FF00) >> 8)*inv255,
+                 ((rgb & 0x0000FF) >> 0)*inv255));
+  }
+
+       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);
+       }
+       return;
+
+  Scene *scene = (Scene*)context.scene;
+  // Compute ambient contributions for all rays
+  scene->getLights()->getAmbientLight()->computeAmbient(context, rays);
+
+  RayPacketData data;
+  int start = 0;
+  do {
+    RayPacket shadowRays(data, 0, rays.getDepth(), 0);
+    int end = context.shadowAlgorithm->computeShadows(context, 
scene->getLights(),
+                                                     rays, start, 
shadowRays);
+    if(shadowRays.getFlags() & RayPacket::NormalizedDirections){
+      for(int i=start;i<end;i++){
+       RayPacket::Element& e = rays.get(i);
+       Color totalLight(e.ambientLight);
+       for(int j=e.shadowBegin;j<e.shadowEnd;j++){
+         RayPacket::Element& s = shadowRays.get(j);
+         if(!s.hitInfo.wasHit()){
+           double cos_theta = Dot(s.ray.direction(), e.normal);
+           totalLight += s.light*cos_theta;
+         }
+       }
+       rays.setResult(i, colors[i]*totalLight);
+      }
+    } else {
+      for(int i=start;i<end;i++){
+       RayPacket::Element& e = rays.get(i);
+       Color totalLight(e.ambientLight);
+       for(int j=e.shadowBegin;j<e.shadowEnd;j++){
+         RayPacket::Element& s = shadowRays.get(j);
+         if(!s.hitInfo.wasHit()){
+           s.ray.normalizeDirection();
+           double cos_theta = Dot(s.ray.direction(), e.normal);
+           totalLight += s.light*cos_theta;
+         }
+       }
+       rays.setResult(i, colors[i]*totalLight);
+      }
+    }
+    start = end;
+  } while(start < rays.getSize());
+}

Added: branches/itanium2/Model/Materials/LambertianAlt.h
==============================================================================
--- (empty file)
+++ branches/itanium2/Model/Materials/LambertianAlt.h   Tue May 24 14:38:15 
2005
@@ -0,0 +1,20 @@
+
+#ifndef Manta_Model_LambertianAlt_h
+#define Manta_Model_LambertianAlt_h
+
+#include <Model/Materials/LitMaterial.h>
+#include <Core/Color/Color.h>
+#include <Interface/Texture.h>
+
+namespace Manta{
+  class LightSet;
+
+  class LambertianAlt : public LitMaterial {
+  public:
+       void setActiveLights(LightSet *lights) { activeLights=lights; }
+    virtual void shade(const RenderContext& context, RayPacket& rays) const;
+  private:
+  };
+}
+
+#endif




  • [MANTA] r338 - in branches/itanium2/Model: Groups Materials, hansong, 05/24/2005

Archive powered by MHonArc 2.6.16.

Top of page