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

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

removed using namespace std from .h

Line 
1#include "Triangle3.h"
2#include "Ray.h"
3#include "AxisAlignedBox3.h"
4#include "Containers.h"
5#include "Polygon3.h"
6
7
8using namespace std;
9
10namespace GtpVisibilityPreprocessor {
11
12       
13Triangle3::Triangle3(const Vector3 &a, const Vector3 &b, const Vector3 &c)
14{
15        Init(a, b, c);
16}
17
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
33int
34Triangle3::CastRay(const Ray &ray,
35                                   float &t,
36                                   const float nearestT,
37                                   Vector3 &normal) const
38{
39#if 0
40        VertexContainer vertices;
41        vertices.push_back(mVertices[0]);
42        vertices.push_back(mVertices[1]);
43        vertices.push_back(mVertices[2]);
44
45        Polygon3 poly(vertices);
46
47        int dummy = poly.CastRay(ray, t, nearestT);
48        normal = poly.GetNormal();
49       
50        //      cout << "polyversion code: " << dummy << " t: " << t << " nearestT: " << nearestT << endl;
51        return dummy;
52#endif
53       
54        //////////////
55        // specialised triangle ray casting version
56        // using ray-plane intersection
57       
58        // get triangle edge vectors and plane normal
59        const Vector3 u = mVertices[0] - mVertices[1];
60    const Vector3 v = mVertices[2] - mVertices[1];
61
62        // cross product
63    normal = Normalize(CrossProd(v, u));
64
65        // ray direction vector
66    const Vector3 dir = ray.GetDir();
67    const Vector3 w0 = ray.GetLoc() - mVertices[1];
68
69        // params to calc ray-plane intersect
70    const float a = -DotProd(normal, w0);
71    const float b = DotProd(normal, dir);
72
73        // check for division by zero
74        if (fabs(b) < Limits::Small)
75        {   
76                // ray is parallel to triangle plane
77        if (a == 0)
78                {
79                        // ray lies in triangle plane
80            return Ray::INTERSECTION_OUT_OF_LIMITS;
81                }
82        else
83                {
84                        // ray disjoint from plane
85                        return Ray::NO_INTERSECTION;
86                }
87    }
88
89    // distance from origin of ray to plane
90    t = a / b;
91
92    if (t <= Limits::Small) // ray goes away from triangle
93        {
94          return Ray::INTERSECTION_OUT_OF_LIMITS;
95        }
96        // already found nearer intersection
97        else if ((ray.GetType() == Ray::LOCAL_RAY) && (t >= nearestT))
98        {
99                return Ray::NO_INTERSECTION;
100        }
101
102        /////////////////
103    //-- found intersection point
104        //-- check if it is inside triangle
105 
106        const Vector3 pt = ray.GetLoc() + t * dir;
107#if GTP_DEBUG
108        if (!pt.CheckValidity())
109        {
110                cout << "tr: " << *this << endl;
111                cout << "v: " << pt << " t: " << t << " a: " << a << " b: " << b << " n: " << normal << endl;
112        }
113#endif
114        const Vector3 w = pt - mVertices[1];
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
123
124        const float D = uv * uv - uu * vv;
125
126    // get and test parametric coords
127    const float s = (uv * wv - vv * wu) / D;
128
129    if ((s < -Limits::Small) || (s > 1.0f + Limits::Small)) // pt is outside triangle
130        {       
131        return Ray::NO_INTERSECTION;
132        }
133
134        const float s2 = (uv * wu - uu * wv) / D;
135
136    if ((s2 < -Limits::Small) || ((s + s2) > 1.0f + Limits::Small)) // pt is outside triangle
137        {       
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];
161        const Vector3 v2 = mVertices[2] - mVertices[1];
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{
175        Vector3 v1 = mVertices[0] - mVertices[1], v2=mVertices[2] - mVertices[1];
176        return 0.5f * Magnitude(CrossProd(v2, v1));
177}
178
179
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
189
190bool Triangle3::GetPlaneIntersection(const Plane3 &plane,
191                                                                         Vector3 &intersectA,
192                                                                         Vector3 &intersectB) const
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];
219                       
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
232                if ((side[i] >= 0) && (side[i_2] <= 0) ||
233                        (side[i] <= 0) && (side[i_2] >= 0))
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]);
240                       
241                                foundA = true;
242                        }
243                        else
244                        {
245                                intersectB = mVertices[i] + t * (mVertices[i_2] - mVertices[i]);
246                       
247                                return true;
248                        }
249                }
250        }
251
252        cout << "warning! wrong triangle - plane intersection" << endl;
253        return false; // something went wrong!
254}
255
256
257}
Note: See TracBrowser for help on using the repository browser.