home *** CD-ROM | disk | FTP | other *** search
- /*
- * Triangle.C - methods for triangle manipulations.
- *
- * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
- * University of Berne, Switzerland
- * Copyright (C) 1989, 1991, Craig E. Kolb
- * All rights reserved.
- *
- * This software may be freely copied, modified, and redistributed
- * provided that this copyright notice is preserved on all copies.
- *
- * You may not distribute this software, in whole or in part, as part of
- * any commercial product without the express consent of the authors.
- *
- * There is no warranty or other guarantee of fitness of this software
- * for any purpose. It is provided solely "as is".
- *
- */
-
- #include "Triangle.h"
-
- //___________________________________________________________ Triangle
-
- Triangle::Triangle(const Vector& p1, const Vector& p2, const Vector& p3)
- : v1(p1), v2(p2), v3(p3)
- {
- e1 = v2 - v1; // create edges
- e2 = v3 - v1;
-
- /*
- * calculate triangle normal
- */
- Vector nNotNormalized = n = e1*e2;
-
- D = v1^n;
-
- /*
- * find dominant part of normal vector
- */
- real absNx = fabs(nNotNormalized[0]);
- real absNy = fabs(nNotNormalized[1]);
- real absNz = fabs(nNotNormalized[2]);
- real scale;
-
- if (absNx > absNy && absNx > absNz) {
- index1 = 1;
- index2 = 2;
- scale = 1/nNotNormalized[0];
- }
- else if (absNy > absNz) {
- index1 = 2;
- index2 = 0;
- scale = 1/nNotNormalized[1];
- }
- else {
- index1 = 0;
- index2 = 1;
- scale = 1/nNotNormalized[2];
- }
-
- e1 *= scale;
- e2 *= scale;
- }
-
- GeoObject* Triangle::create(const Vector& p1, const Vector& p2, const Vector& p3)
- {
- if (equal(((p2-p1)*(p3-p1)).sqr(), 0))
- return NULL;
-
- return new Triangle(p1, p2, p3);
- }
-
- /*
- * Compute the intersection between a ray and a triangle using barycentric
- * coordinates. The original algorithm was discribed by John M. Snyder and
- * Alan H. Barr in Computer Graphics (SIGGRAPH 87), pp. 119-126. This
- * algorithm is a optimized version adapted from Craig Kolbs rayshade.
- */
-
- int Triangle::intersect(const Ray& ray, real minDist, real& maxDist)
- {
- intersectionTests++;
-
- /*
- * calculate ray/plane intersection
- */
- real t = n^ray.getDir();
- if (fabs(t) < minDist)
- return FALSE;
-
- t = (D - (ray.getOrig()^n))/t;
-
- if (t < minDist || t > maxDist)
- return FALSE;
-
- real h1 = ray.getOrig()[index1] + t*ray.getDir()[index1];
- real h2 = ray.getOrig()[index2] + t*ray.getDir()[index2];
-
- real g = e1[index1]*(h2 - v1[index2]) - e1[index2]*(h1 - v1[index1]);
- if (g < 0 || g > 1)
- return FALSE;
-
- real b = e2[index2]*(h1 - v1[index1]) - e2[index1]*(h2 - v1[index2]);
- if (b < 0 || b > 1)
- return FALSE;
-
- if (b+g > 1 )
- return FALSE;
-
- maxDist = t;
- intersections++;
- return TRUE;
- }
-
- Vector Triangle::normal(const Vector&) const
- {
- return n;
- }
-
- PolygonList* Triangle::tesselate(const BoundingBox&)
- {
- Polygon* p = new Polygon(v1, v2, v3);
- p->transform(*trans);
- PolygonList* polys = new PolygonList(1);
- polys->append(p);
-
- return polys;
- }
-