source: GTP/trunk/Lib/Vis/Preprocessing/src/Triangle3.cpp @ 1586

Revision 1586, 3.9 KB checked in by mattausch, 18 years ago (diff)

resolved bug for object space distribution using triangles
fixed biasing bug for mesh::GetRandomSurfacePoint? method and
GetRandomVisibleSurfacePoint?.

RevLine 
[191]1#include "Triangle3.h"
[1328]2#include "Ray.h"
3#include "AxisAlignedBox3.h"
[1344]4#include "Containers.h"
5#include "Polygon3.h"
[191]6
[1328]7
[863]8namespace GtpVisibilityPreprocessor {
[860]9
[1328]10       
11Triangle3::Triangle3(const Vector3 &a, const Vector3 &b, const Vector3 &c)
[191]12{
[1328]13        Init(a, b, c);
[191]14}
[860]15
[1328]16
17void Triangle3::Init(const Vector3 &a, const Vector3 &b, const Vector3 &c)
18{
19        mVertices[0] = a;
20        mVertices[1] = b;
21        mVertices[2] = c;
22}
23
24
25float Triangle3::GetSpatialAngle(const Vector3 &point) const
26{
27        return 0.0f;
28}
29
30
[1344]31int Triangle3::CastRay(const Ray &ray, float &t, const float nearestT, Vector3 &normal) const
[1328]32{
[1420]33#if 0
34        VertexContainer vertices;
[1344]35        vertices.push_back(mVertices[0]);
36        vertices.push_back(mVertices[1]);
37        vertices.push_back(mVertices[2]);
38
39        Polygon3 poly(vertices);
40       
41        int dummy = poly.CastRay(ray, t, nearestT);
42
[1420]43        cout << "polyversion code: " << dummy << " t: " << t << " nearestT: " << nearestT << endl;
44        return dummy;
45#endif
46       
47        //////////////
48        // specialised triangle ray casting version
[1586]49        // using ray-plane intersection
[1344]50       
[1328]51        // get triangle edge vectors and plane normal
[1344]52        const Vector3 u = mVertices[0] - mVertices[1];
53    const Vector3 v = mVertices[2] - mVertices[1];
[1328]54
[1420]55        // cross product
56    normal = Normalize(CrossProd(v, u));
[1328]57
[1420]58        // ray direction vector
59    const Vector3 dir = ray.GetDir();
[1344]60    const Vector3 w0 = ray.GetLoc() - mVertices[1];
[1328]61
62        // params to calc ray-plane intersect
[1344]63    const float a = -DotProd(normal, w0);
64    const float b = DotProd(normal, dir);
[1328]65
[1344]66        // check for division by zero
[1328]67        if (fabs(b) < Limits::Small)
68        {   
69                // ray is parallel to triangle plane
[1420]70        if (a == 0)
[1328]71                {
[1420]72                        // ray lies in triangle plane
[1328]73            return Ray::INTERSECTION_OUT_OF_LIMITS;
74                }
75        else
76                {
[1420]77                        // ray disjoint from plane
78                        return Ray::NO_INTERSECTION;
[1328]79                }
80    }
81
[1344]82    // distance from origin of ray to plane
[1328]83    t = a / b;
84
85    if (t < 0.0) // ray goes away from triangle
86        {
[1344]87                return Ray::NO_INTERSECTION; // => no intersect
[1328]88        }
[1344]89        // already found nearer intersection
90        else if ((ray.GetType() == Ray::LOCAL_RAY) && (t >= nearestT))
91        {
92                return Ray::NO_INTERSECTION;
93        }
[1328]94
[1420]95        /////////////////
[1344]96    //-- found intersection point
97        //-- check if it is inside triangle
98 
99        const Vector3 pt = ray.GetLoc() + t * dir;
[1421]100#if _DEBUG
[1420]101        if (!pt.CheckValidity())
102        {
103                cout << "tr: " << *this << endl;
104                cout << "v: " << pt << " t: " << t << " a: " << a << " b: " << b << " n: " << normal << endl;
105        }
[1421]106#endif
[1344]107        const Vector3 w = pt - mVertices[1];
[1328]108
109        const float uu = DotProd(u, u);
110    const float uv = DotProd(u, v);
111    const float vv = DotProd(v, v);
112   
113        const float wu = DotProd(w, u);
114    const float wv = DotProd(w, v);
115    const float D = uv * uv - uu * vv;
116
117    // get and test parametric coords
118    const float s = (uv * wv - vv * wu) / D;
119
[1344]120    if ((s < 0.0) || (s > 1.0)) // pt is outside triangle
121        {       
[1328]122        return Ray::NO_INTERSECTION;
123        }
124
125        const float s2 = (uv * wu - uu * wv) / D;
126
[1344]127    if ((s2 < 0.0) || ((s + s2) > 1.0)) // pt is outside triangle
128        {       
[1328]129        return Ray::NO_INTERSECTION;
130        }
131
132        return Ray::INTERSECTION; // I is in T
133}
134
135
136AxisAlignedBox3 Triangle3::GetBoundingBox() const
137{
138        AxisAlignedBox3 box;
139        box.Initialize();
140
141        box.Include(mVertices[0]);
142        box.Include(mVertices[1]);
143        box.Include(mVertices[2]);
144
145        return box;
146}
147
148
149Vector3 Triangle3::GetNormal() const
150{
151        const Vector3 v1 = mVertices[0] - mVertices[1];
[1344]152        const Vector3 v2 = mVertices[2] - mVertices[1];
[1328]153
154        return Normalize(CrossProd(v2, v1));
155}
156
157
158Vector3 Triangle3::GetCenter() const
159{
160        return (mVertices[0] + mVertices[1] + mVertices[2]) / 3.0f;
161}
162
163
164float Triangle3::GetArea() const
165{
[1344]166        Vector3 v1 = mVertices[0] - mVertices[1], v2=mVertices[2] - mVertices[1];
[1328]167        return 0.5f * Magnitude(CrossProd(v2, v1));
168}
169
170
[1420]171bool Triangle3::CheckValidity() const
172{
173        return !(
174                EpsilonEqualV3(mVertices[0], mVertices[1]) ||
175                EpsilonEqualV3(mVertices[0], mVertices[2]) ||
176                EpsilonEqualV3(mVertices[1], mVertices[2])
177                );
178}
179
[860]180}
Note: See TracBrowser for help on using the repository browser.