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

Revision 2176, 5.5 KB checked in by mattausch, 18 years ago (diff)

removed using namespace std from .h

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
[2176]8using namespace std;
9
[863]10namespace GtpVisibilityPreprocessor {
[860]11
[1328]12       
13Triangle3::Triangle3(const Vector3 &a, const Vector3 &b, const Vector3 &c)
[191]14{
[1328]15        Init(a, b, c);
[191]16}
[860]17
[1328]18
19void Triangle3::Init(const Vector3 &a, const Vector3 &b, const Vector3 &c)
20{
21        mVertices[0] = a;
22        mVertices[1] = b;
23        mVertices[2] = c;
24}
25
26
27float Triangle3::GetSpatialAngle(const Vector3 &point) const
28{
29        return 0.0f;
30}
31
32
[1867]33int
34Triangle3::CastRay(const Ray &ray,
35                                   float &t,
36                                   const float nearestT,
37                                   Vector3 &normal) const
[1328]38{
[1420]39#if 0
40        VertexContainer vertices;
[1344]41        vertices.push_back(mVertices[0]);
42        vertices.push_back(mVertices[1]);
43        vertices.push_back(mVertices[2]);
44
45        Polygon3 poly(vertices);
[1867]46
47        int dummy = poly.CastRay(ray, t, nearestT);
48        normal = poly.GetNormal();
[1344]49       
[1867]50        //      cout << "polyversion code: " << dummy << " t: " << t << " nearestT: " << nearestT << endl;
[1420]51        return dummy;
52#endif
53       
54        //////////////
55        // specialised triangle ray casting version
[1586]56        // using ray-plane intersection
[1344]57       
[1328]58        // get triangle edge vectors and plane normal
[1344]59        const Vector3 u = mVertices[0] - mVertices[1];
60    const Vector3 v = mVertices[2] - mVertices[1];
[1328]61
[1420]62        // cross product
63    normal = Normalize(CrossProd(v, u));
[1328]64
[1420]65        // ray direction vector
66    const Vector3 dir = ray.GetDir();
[1344]67    const Vector3 w0 = ray.GetLoc() - mVertices[1];
[1328]68
69        // params to calc ray-plane intersect
[1344]70    const float a = -DotProd(normal, w0);
71    const float b = DotProd(normal, dir);
[1328]72
[1344]73        // check for division by zero
[1328]74        if (fabs(b) < Limits::Small)
75        {   
76                // ray is parallel to triangle plane
[1420]77        if (a == 0)
[1328]78                {
[1420]79                        // ray lies in triangle plane
[1328]80            return Ray::INTERSECTION_OUT_OF_LIMITS;
81                }
82        else
83                {
[1420]84                        // ray disjoint from plane
85                        return Ray::NO_INTERSECTION;
[1328]86                }
87    }
88
[1344]89    // distance from origin of ray to plane
[1328]90    t = a / b;
91
[1867]92    if (t <= Limits::Small) // ray goes away from triangle
[1328]93        {
[1867]94          return Ray::INTERSECTION_OUT_OF_LIMITS;
[1328]95        }
[1344]96        // already found nearer intersection
97        else if ((ray.GetType() == Ray::LOCAL_RAY) && (t >= nearestT))
98        {
99                return Ray::NO_INTERSECTION;
100        }
[1328]101
[1420]102        /////////////////
[1344]103    //-- found intersection point
104        //-- check if it is inside triangle
105 
106        const Vector3 pt = ray.GetLoc() + t * dir;
[1715]107#if GTP_DEBUG
[1420]108        if (!pt.CheckValidity())
109        {
110                cout << "tr: " << *this << endl;
111                cout << "v: " << pt << " t: " << t << " a: " << a << " b: " << b << " n: " << normal << endl;
112        }
[1421]113#endif
[1344]114        const Vector3 w = pt - mVertices[1];
[1328]115
116        const float uu = DotProd(u, u);
117    const float uv = DotProd(u, v);
118    const float vv = DotProd(v, v);
119   
120        const float wu = DotProd(w, u);
121    const float wv = DotProd(w, v);
122
[1867]123
124        const float D = uv * uv - uu * vv;
125
[1328]126    // get and test parametric coords
127    const float s = (uv * wv - vv * wu) / D;
128
[1867]129    if ((s < -Limits::Small) || (s > 1.0f + Limits::Small)) // pt is outside triangle
[1344]130        {       
[1328]131        return Ray::NO_INTERSECTION;
132        }
133
134        const float s2 = (uv * wu - uu * wv) / D;
135
[1867]136    if ((s2 < -Limits::Small) || ((s + s2) > 1.0f + Limits::Small)) // pt is outside triangle
[1344]137        {       
[1328]138        return Ray::NO_INTERSECTION;
139        }
140
141        return Ray::INTERSECTION; // I is in T
142}
143
144
145AxisAlignedBox3 Triangle3::GetBoundingBox() const
146{
147        AxisAlignedBox3 box;
148        box.Initialize();
149
150        box.Include(mVertices[0]);
151        box.Include(mVertices[1]);
152        box.Include(mVertices[2]);
153
154        return box;
155}
156
157
158Vector3 Triangle3::GetNormal() const
159{
160        const Vector3 v1 = mVertices[0] - mVertices[1];
[1344]161        const Vector3 v2 = mVertices[2] - mVertices[1];
[1328]162
163        return Normalize(CrossProd(v2, v1));
164}
165
166
167Vector3 Triangle3::GetCenter() const
168{
169        return (mVertices[0] + mVertices[1] + mVertices[2]) / 3.0f;
170}
171
172
173float Triangle3::GetArea() const
174{
[1344]175        Vector3 v1 = mVertices[0] - mVertices[1], v2=mVertices[2] - mVertices[1];
[1328]176        return 0.5f * Magnitude(CrossProd(v2, v1));
177}
178
179
[1420]180bool Triangle3::CheckValidity() const
181{
182        return !(
183                EpsilonEqualV3(mVertices[0], mVertices[1]) ||
184                EpsilonEqualV3(mVertices[0], mVertices[2]) ||
185                EpsilonEqualV3(mVertices[1], mVertices[2])
186                );
187}
188
[1932]189
[1933]190bool Triangle3::GetPlaneIntersection(const Plane3 &plane,
191                                                                         Vector3 &intersectA,
192                                                                         Vector3 &intersectB) const
[1932]193{
194        int side[3];
195
196        // compute distance from plane
197        for (int i = 0; i < 3; ++ i)
198        {
199                side[i] = plane.Side(mVertices[i], Limits::Small);
200        }
201
202        /////
203        // no intersection => early exit
204        if (((side[0] > 0) && (side[1] > 0) && (side[2] > 0)) ||
205                ((side[0] < 0) && (side[1] < 0) && (side[2] < 0)))
206        {
207                return false;
208        }
209
210        /////////////
211        // at least 2 triangle vertices lie in plane => early exit
212
213        for (int i = 0; i < 3; ++ i)
214        {
215                if (!side[i] && !side[(i + 1) % 3])
216                {
217                        intersectA = mVertices[i];
218                        intersectB = mVertices[(i + 1) % 3];
[1933]219                       
[1932]220                        return true;
221                }
222        }
223
224        bool foundA = false;
225
226        // compute intersection points
227        for (int i = 0; i < 3; ++ i)
228        {
229                const int i_2 = (i + 1) % 3;
230
231                // intersection found
[1933]232                if ((side[i] >= 0) && (side[i_2] <= 0) ||
233                        (side[i] <= 0) && (side[i_2] >= 0))
[1932]234                {       
235                        const float t = plane.FindT(mVertices[i], mVertices[i_2]);
236                       
237                        if (!foundA)
238                        {
239                                intersectA = mVertices[i] + t * (mVertices[i_2] - mVertices[i]);
[1933]240                       
[1932]241                                foundA = true;
242                        }
243                        else
244                        {
245                                intersectB = mVertices[i] + t * (mVertices[i_2] - mVertices[i]);
[1933]246                       
[1932]247                                return true;
248                        }
249                }
250        }
251
252        cout << "warning! wrong triangle - plane intersection" << endl;
253        return false; // something went wrong!
[1715]254}
[1932]255
256
257}
Note: See TracBrowser for help on using the repository browser.