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

Revision 1933, 5.4 KB checked in by mattausch, 17 years ago (diff)

worked on gvs reverse sampling (still in debug state)

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