]> git.mxchange.org Git - simgear.git/commitdiff
bucket: Make no bucket cross the 0 and 180 deg longitude border.
authorMathias Froehlich <Mathias.Froehlich@web.de>
Sun, 20 Jan 2013 14:33:25 +0000 (15:33 +0100)
committerMathias Froehlich <Mathias.Froehlich@web.de>
Sun, 20 Jan 2013 14:33:25 +0000 (15:33 +0100)
Change the bucket tiling at the poles not to cross the
0deg longitude and not to cross the 180deg longitude line.
This lets some special cases disappear for the buckets as well
as for the hierarchical level of detail spt loader.
Also change the last degree tiles from spanning 360 degrees to
12 degrees. Before we had 8 nested rings which neither helps
scenery paging nor culling. With that change the chunks are
about the same order of size than any other tile. Also the
tile shapes are much more friendly for culling and paging.
Also in presence of the current scenery, this polar tiles contain
as of today just totally broken geometry which tells me that
also the scenery generation process did not like these rings
for the tile shapes.

The impact on the current scenery is low. With this change the
polar regions do no longer load the tiles that are available
in the current scenery builds. The last degree tiles are broken
in this scenery version anyway. The next degree that is changed
will really loose some tiles that were sensible as of today.
All these areas are replaced with sea tiles by the old paging
structure. So, you will have at least ground below you when you
fly there. A hopefully comming soon scenery rebuild will
use this new tiling structure and thus will be the first one
providing closed polar caps.

simgear/bucket/newbucket.cxx
simgear/bucket/newbucket.hxx
simgear/scene/tgdb/BucketBox.hxx
simgear/scene/tgdb/ReaderWriterSPT.cxx

index 227d9979382c064590384a2dd8434e682db6af77..bb373fed851ca45cc12bbee20155cf0fef25b433 100644 (file)
@@ -224,17 +224,6 @@ std::string SGBucket::gen_base_path() const {
 
 // return width of the tile in degrees
 double SGBucket::get_width() const {
-    if (lon==-180 && (lat==-89 || lat==88) ) {
-        /* Normally the tile at 180W in 88N and 89S
-         * would cover 184W to 176W and the next
-         * on the east side starts at 176W.
-         * To correct, make this a special tile
-         * from 180W to 176W with 4 degrees width
-         * instead of the normal 8 degrees at
-         * that latitude.
-         */
-         return 4.0;
-    }
     return sg_bucket_span( get_center_lat() );
 }
 
index 56333c4d670e4b985529fa289be32fec6fe77a2b..64aa5f80a3f721f43f1b25c946fe6ae54ae98b4b 100644 (file)
@@ -57,9 +57,7 @@
 // return the horizontal tile span factor based on latitude
 static double sg_bucket_span( double l ) {
     if ( l >= 89.0 ) {
-       return 360.0;
-    } else if ( l >= 88.0 ) {
-       return 8.0;
+       return 12.0;
     } else if ( l >= 86.0 ) {
        return 4.0;
     } else if ( l >= 83.0 ) {
@@ -80,12 +78,10 @@ static double sg_bucket_span( double l ) {
        return 1.0;
     } else if ( l >= -86.0 ) {
        return 2.0;
-    } else if ( l >= -88.0 ) {
-       return 4.0;
     } else if ( l >= -89.0 ) {
-       return 8.0;
+       return 4.0;
     } else {
-       return 360.0;
+       return 12.0;
     }
 }
 
index 8e67f29162521ee8d296c6383384840711d679ca..b459289864efcff37418cacfa134096239ecd665 100644 (file)
@@ -31,10 +31,10 @@ namespace simgear {
 
 #define Elements(x) (sizeof(x)/sizeof((x)[0]))
 
-// 3*5*3 * 8 = 360
-static const unsigned _lonFactors[] = { 3, 5, 3,  2, 2, 2, /* sub degree */ 2, 2, 2 };
-// 5*3*3 * 4 = 180
-static const unsigned _latFactors[] = { 5, 3, 3,  2, 2, /* sub degree */ 2, 2, 2, 1 };
+// 2*5*3*3 * 4 = 360
+static const unsigned _lonFactors[] = { 2, 5, 3, 3, 2, 2, /* sub degree */ 2, 2, 2 };
+// 3*3*5 * 4 = 180
+static const unsigned _latFactors[] = { 3, 5, 1, 3, 2, 2, /* sub degree */ 2, 2, 2 };
 
 static unsigned product(const unsigned* factors, unsigned count)
 {
@@ -50,13 +50,10 @@ static unsigned product(const unsigned* factors, unsigned count)
 /// bits which matches the SGBuckets maximum tile resolution.
 ///
 /// Notable /design/ decision:
-/// * The longitude maps to the interval [0,360[ which appears to be
-///   counter productive for the file/directory names and the
-///   texture coordinates which map [-180,180[.
-///   The reason is that the buckets at 89deg longitude are 8deg
-///   latitude width. So there is a bunch of buckets that range from
-///   [176, -184[ longitude. So the wrap happens at 0deg instead
-///   of 180deg since we have a cut edge for all latitudes.
+/// * The longitude maps to the interval [-180,180[.
+///   The latitude maps to the interval [-90,90].
+///   This works now that the tiles do no longer cut
+///   neither the 180deg nor the 0deg boundary.
 /// * This is not meant to be an API class for simgear. This is
 ///   just an internal tool that I would like to keep in the SPT loader.
 ///   But I want to have coverage somehow tested with the usual unit
@@ -142,6 +139,20 @@ public:
         return SGBucket(_offsetToLongitudeDeg(offset), _offsetToLatitudeDeg(_offset[1]));
     }
 
+    BucketBox getParentBox(unsigned level) const
+    {
+        BucketBox box;
+        unsigned plon = product(_lonFactors + level, Elements(_lonFactors) - level);
+        unsigned plat = product(_latFactors + level, Elements(_latFactors) - level);
+        box._offset[0] = _offset[0] - _offset[0] % plon;
+        box._offset[0] = _normalizeLongitude(box._offset[0]);
+        box._offset[1] = _offset[1] - _offset[1] % plat;
+        box._size[0] = plon;
+        box._size[1] = plat;
+
+        return box;
+    }
+
     BucketBox getSubBoxHeight(unsigned j, unsigned level) const
     {
         assert(0 < level);
@@ -283,22 +294,22 @@ public:
         SGGeod p00 = _offsetToGeod(x0, y0, 0);
         SGVec3f v00 = SGVec3f::fromGeod(p00);
         SGVec3f n00 = SGQuatf::fromLonLat(p00).backTransform(SGVec3f(0, 0, -1));
-        SGVec2f t00(x0*1.0/(360*8) + 0.5, y0*1.0/(180*8));
+        SGVec2f t00(x0*1.0/(360*8), y0*1.0/(180*8));
 
         SGGeod p10 = _offsetToGeod(x1, y0, 0);
         SGVec3f v10 = SGVec3f::fromGeod(p10);
         SGVec3f n10 = SGQuatf::fromLonLat(p10).backTransform(SGVec3f(0, 0, -1));
-        SGVec2f t10(x1*1.0/(360*8) + 0.5, y0*1.0/(180*8));
+        SGVec2f t10(x1*1.0/(360*8), y0*1.0/(180*8));
 
         SGGeod p11 = _offsetToGeod(x1, y1, 0);
         SGVec3f v11 = SGVec3f::fromGeod(p11);
         SGVec3f n11 = SGQuatf::fromLonLat(p11).backTransform(SGVec3f(0, 0, -1));
-        SGVec2f t11(x1*1.0/(360*8) + 0.5, y1*1.0/(180*8));
+        SGVec2f t11(x1*1.0/(360*8), y1*1.0/(180*8));
 
         SGGeod p01 = _offsetToGeod(x0, y1, 0);
         SGVec3f v01 = SGVec3f::fromGeod(p01);
         SGVec3f n01 = SGQuatf::fromLonLat(p01).backTransform(SGVec3f(0, 0, -1));
-        SGVec2f t01(x0*1.0/(360*8) + 0.5, y1*1.0/(180*8));
+        SGVec2f t01(x0*1.0/(360*8), y1*1.0/(180*8));
     
         if (y0 != 0) {
             points[numPoints] = v00;
@@ -341,17 +352,11 @@ private:
 
     static unsigned _longitudeDegToOffset(double lon)
     {
-        lon = SGMiscd::normalizePeriodic(0, 360, lon);
-        unsigned offset = (unsigned)(8*lon + 0.5);
+        unsigned offset = (unsigned)(8*(lon + 180) + 0.5);
         return _normalizeLongitude(offset);
     }
     static double _offsetToLongitudeDeg(unsigned offset)
-    {
-        if (180*8 <= offset)
-            return offset*0.125 - 360;
-        else
-            return offset*0.125;
-    }
+    { return offset*0.125 - 180; }
 
     static unsigned _latitudeDegToOffset(double lat)
     {
index dacb89cfa1ac2e332630f6b52fe833b264df04c0..289448c57057a7e2e8b1698300e90b63bcabd6f2 100644 (file)
@@ -161,7 +161,7 @@ ReaderWriterSPT::readNode(const std::string& fileName, const osgDB::Options* opt
     // The file name without path and without the spt extension
     std::string strippedFileName = osgDB::getStrippedName(fileName);
     if (strippedFileName == "earth")
-        return createTree(BucketBox(0, -90, 360, 180), options, true);
+        return createTree(BucketBox(-180, -90, 360, 180), options, true);
 
     std::stringstream ss(strippedFileName);
     BucketBox bucketBox;