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