Hi,

On Donnerstag 26 Mai 2005 09:00, Dave Culp wrote:
> I tried your fix above and it didn't work for me :(
Yes, because Melchiors beacon stuff is different from that one you describe.
Especially, if AI aircraft keep on moving it sounds like something different.

I have thought about that and wanted to send a test patch to somebody with 
that problems at sunday, but by internet connection stopped working at that 
evening....

For everybody experiencing these freezes with 'no ground below aircraft'. 
Could you try the patch I have attached below?

Greetings

         Mathias

-- 
Mathias Fröhlich, email: [EMAIL PROTECTED]
Index: src/FDM/groundcache.cxx
===================================================================
RCS file: /var/cvs/FlightGear-0.9/source/src/FDM/groundcache.cxx,v
retrieving revision 1.6
diff -u -r1.6 groundcache.cxx
--- src/FDM/groundcache.cxx	29 Apr 2005 14:38:24 -0000	1.6
+++ src/FDM/groundcache.cxx	26 May 2005 07:23:48 -0000
@@ -25,6 +25,7 @@
 
 #include <plib/sg.h>
 
+#include <simgear/sg_inlines.h>
 #include <simgear/constants.h>
 #include <simgear/debug/logstream.hxx>
 #include <simgear/math/sg_geodesy.hxx>
@@ -37,6 +38,131 @@
 #include "flight.hxx"
 #include "groundcache.hxx"
 
+// #define method1
+#define method2
+
+#if defined(method1)
+static inline bool fgPointInTriangle(sgVec3 point, sgVec3 tri[3])
+{
+  sgVec3 trip[3];
+  sgSubVec3(trip[0], tri[0], point);
+  sgSubVec3(trip[1], tri[1], point);
+  sgSubVec3(trip[2], tri[2], point);
+  sgVec3 s[3];
+  sgVectorProductVec3(s[0], trip[0], trip[1]);
+  sgVectorProductVec3(s[1], trip[1], trip[2]);
+  sgVectorProductVec3(s[2], trip[2], trip[0]);
+
+  if (sgScalarProductVec3(s[0], s[1]) < -FLT_EPSILON)
+    return false;
+  if (sgScalarProductVec3(s[1], s[2]) < -FLT_EPSILON)
+    return false;
+
+  return true;
+}
+#elif defined(method2)
+static inline bool fgPointInTriangle( sgVec3 point, sgVec3 tri[3] )
+{
+    sgVec3 dif;
+
+    // Some tolerance in meters we accept a point to be outside of the triangle
+    // and still return that it is inside.
+    SGfloat eps = 10*FLT_EPSILON;
+    SGfloat min, max;
+    // punt if outside bouding cube
+    SG_MIN_MAX3 ( min, max, tri[0][0], tri[1][0], tri[2][0] );
+    if( (point[0] < min - eps) || (point[0] > max + eps) )
+        return false;
+    dif[0] = max - min;
+
+    SG_MIN_MAX3 ( min, max, tri[0][1], tri[1][1], tri[2][1] );
+    if( (point[1] < min - eps) || (point[1] > max + eps) )
+        return false;
+    dif[1] = max - min;
+
+    SG_MIN_MAX3 ( min, max, tri[0][2], tri[1][2], tri[2][2] );
+    if( (point[2] < min - eps) || (point[2] > max + eps) )
+        return false;
+    dif[2] = max - min;
+
+    // drop the smallest dimension so we only have to work in 2d.
+    SGfloat min_dim = SG_MIN3 (dif[0], dif[1], dif[2]);
+    SGfloat x1, y1, x2, y2, x3, y3, rx, ry;
+    if ( fabs(min_dim-dif[0]) <= FLT_EPSILON ) {
+        // x is the smallest dimension
+        x1 = point[1];
+        y1 = point[2];
+        x2 = tri[0][1];
+        y2 = tri[0][2];
+        x3 = tri[1][1];
+        y3 = tri[1][2];
+        rx = tri[2][1];
+        ry = tri[2][2];
+    } else if ( fabs(min_dim-dif[1]) <= FLT_EPSILON ) {
+        // y is the smallest dimension
+        x1 = point[0];
+        y1 = point[2];
+        x2 = tri[0][0];
+        y2 = tri[0][2];
+        x3 = tri[1][0];
+        y3 = tri[1][2];
+        rx = tri[2][0];
+        ry = tri[2][2];
+    } else if ( fabs(min_dim-dif[2]) <= FLT_EPSILON ) {
+        // z is the smallest dimension
+        x1 = point[0];
+        y1 = point[1];
+        x2 = tri[0][0];
+        y2 = tri[0][1];
+        x3 = tri[1][0];
+        y3 = tri[1][1];
+        rx = tri[2][0];
+        ry = tri[2][1];
+    } else {
+        // all dimensions are really small so lets call it close
+        // enough and return a successful match
+        return true;
+    }
+
+    // check if intersection point is on the same side of p1 <-> p2 as p3
+    SGfloat tmp = (y2 - y3);
+    SGfloat tmpn = (x2 - x3);
+    int side1 = SG_SIGN (tmp * (rx - x3) + (y3 - ry) * tmpn);
+    int side2 = SG_SIGN (tmp * (x1 - x3) + (y3 - side1*eps - y1) * tmpn);
+    if ( side1 != side2 ) {
+        // printf("failed side 1 check\n");
+        return false;
+    }
+
+    // check if intersection point is on correct side of p2 <-> p3 as p1
+    tmp = (y3 - ry);
+    tmpn = (x3 - rx);
+    side1 = SG_SIGN (tmp * (x2 - rx) + (ry - y2) * tmpn);
+    side2 = SG_SIGN (tmp * (x1 - rx) + (ry - side1*eps - y1) * tmpn);
+    if ( side1 != side2 ) {
+        // printf("failed side 2 check\n");
+        return false;
+    }
+
+    // check if intersection point is on correct side of p1 <-> p3 as p2
+    tmp = (y2 - ry);
+    tmpn = (x2 - rx);
+    side1 = SG_SIGN (tmp * (x3 - rx) + (ry - y3) * tmpn);
+    side2 = SG_SIGN (tmp * (x1 - rx) + (ry - side1*eps - y1) * tmpn);
+    if ( side1 != side2 ) {
+        // printf("failed side 3  check\n");
+        return false;
+    }
+
+    return true;
+}
+#else
+static inline bool fgPointInTriangle(sgVec3 point, sgVec3 tri[3])
+{
+  return sgPointInTriangle3(point, tri);
+}
+#endif
+
 FGGroundCache::FGGroundCache()
 {
   sgdSetVec3(cache_center, 0.0, 0.0, 0.0);
@@ -237,7 +363,7 @@
       sgCopyVec3(ac_cent, sp->getCenter());
       sgVec3 dst;
       sgIsectInfLinePlane( dst, ac_cent, down, plane );
-      if ( sgPointInTriangle ( dst, tri ) ) {
+      if ( fgPointInTriangle ( dst, tri ) ) {
         found_ground = true;
         sgdVec3 ddst;
         sgdSetVec3(ddst, dst);
@@ -545,7 +671,7 @@
       // Check for intersection.
       sgVec3 isecpoint;
       if ( sgIsectInfLinePlane( isecpoint, pt, dir, plane ) &&
-           sgPointInTriangle3( isecpoint, tri ) ) {
+           fgPointInTriangle( isecpoint, tri ) ) {
         // Only accept surfaces with the normal pointing upwards.
         // For double sided surfaces flip the normal in this case.
         float dirDot = sgScalarProductVec3(plane, dir);
@@ -666,7 +792,7 @@
         float isecval = sgIsectLinesegPlane( isecpoint, le[0], le[1], plane[k] );
         
         if ( 0.0 <= isecval && isecval <= 1.0 &&
-             sgPointInTriangle( isecpoint, tri[k] ) ) {
+             fgPointInTriangle( isecpoint, tri[k] ) ) {
           // Store the wire id.
           wire_id = gp->wire_id;
           ret = true;
_______________________________________________
Flightgear-devel mailing list
Flightgear-devel@flightgear.org
http://mail.flightgear.org/mailman/listinfo/flightgear-devel
2f585eeea02e2c79d7b1d8c4963bae2d

Reply via email to