osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthDrivers/engine_droam/GeodeticManifold.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003  * Copyright 2008-2009 Pelican Ventures, Inc.
00004  * http://osgearth.org
00005  *
00006  * osgEarth is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 #include "GeodeticManifold"
00020 #include <osgEarth/Registry>
00021 
00022 #define LC "[osgEarth::GeodeticManifold] "
00023 
00024 GeodeticManifold::GeodeticManifold()
00025 {
00026     _profile = osgEarth::Registry::instance()->getGlobalGeodeticProfile();
00027     _ellipsoid = _profile->getSRS()->getGeographicSRS()->getEllipsoid();
00028 }
00029 
00030 void
00031 GeodeticManifold::initialize( MeshManager* mesh )
00032 {
00033     mesh->_minGeomLevel = 1;
00034     mesh->_minActiveLevel = 3;
00035 
00036     // Construct the "vertex diamonds".
00037     _vd[0] = new Diamond(mesh, TileKey(), 0, "vd0"); // north pole 1
00038     _vd[0]->setCoord( -90, 90, 0 );
00039 
00040     _vd[1] = new Diamond(mesh, TileKey(), 0, "vd1"); // north pole 2
00041     _vd[1]->setCoord( 90, 90, 0 );
00042 
00043     _vd[2] = new Diamond(mesh, TileKey(), 0, "vd2"); // south pole 1
00044     _vd[2]->setCoord( -90, -90, 0 );
00045 
00046     _vd[3] = new Diamond(mesh, TileKey(), 0, "vd3"); // south pole 2
00047     _vd[3]->setCoord( 90, -90, 0 );
00048 
00049     _vd[4] = new Diamond(mesh, TileKey(), 0, "vd4");
00050     _vd[4]->setCoord( -180, 0, 0 );
00051 
00052     _vd[5] = new Diamond(mesh, TileKey(), 0, "vd5");
00053     _vd[5]->setCoord( 0, 0, 0 );
00054 
00055     // The 4 "face diamonds":
00056     _fd[0] = new Diamond(mesh, TileKey(), 0, "fd0");
00057     _fd[0]->setCoord( -90, 0, 0 );
00058     _fd[0]->_a[GDPARENT] = _vd[0].get();
00059     _fd[0]->_a[QUADTREE] = _vd[2].get();
00060     _fd[0]->_a[PARENT_L] = _vd[4].get();
00061     _fd[0]->_a[PARENT_R] = _vd[5].get();
00062 
00063     _fd[1] = new Diamond(mesh, TileKey(), 0, "fd1");
00064     _fd[1]->setCoord( 90, 0, 0 );
00065     _fd[1]->_a[GDPARENT] = _vd[3].get();
00066     _fd[1]->_a[QUADTREE] = _vd[1].get();
00067     _fd[1]->_a[PARENT_L] = _vd[4].get();
00068     _fd[1]->_a[PARENT_R] = _vd[5].get();
00069 
00070     _fd[2] = new Diamond(mesh, TileKey(), 0, "fd2"); // virtual north pole diamond
00071     _fd[2]->setCoord( 0, 90, 0 );
00072     _fd[2]->_a[GDPARENT] = _vd[0].get();
00073     _fd[2]->_a[QUADTREE] = _vd[1].get();
00074     _fd[2]->_a[PARENT_L] = _vd[5].get();
00075     _fd[2]->_a[PARENT_R] = _vd[4].get();
00076 
00077     _fd[3] = new Diamond(mesh, TileKey(), 0, "fd3"); // virtual south pole diamond
00078     _fd[3]->setCoord( 0, -90, 0 );
00079     _fd[3]->_a[GDPARENT] = _vd[3].get();
00080     _fd[3]->_a[QUADTREE] = _vd[2].get();
00081     _fd[3]->_a[PARENT_L] = _vd[5].get();
00082     _fd[3]->_a[PARENT_R] = _vd[4].get();
00083 
00084     // the 8 "edge diamonds" (first with geometry)
00085     _ed[0] = new Diamond(mesh, TileKey(1,0,0,_profile.get()), 1, "ed0");
00086     _ed[0]->setCoord( -135, 45, 0 );
00087     _ed[0]->_a[GDPARENT] = _vd[0].get();
00088     _ed[0]->_a[QUADTREE] = _vd[4].get();
00089     _ed[0]->_a[PARENT_L] = _fd[2].get();
00090     _ed[0]->_a[PARENT_R] = _fd[0].get();
00091     _ed[0]->_orientation = 0;
00092 
00093     _ed[1] = new Diamond(mesh, TileKey(1,1,0,_profile.get()), 1, "ed1");
00094     _ed[1]->setCoord( -45, 45, 0 );
00095     _ed[1]->_a[GDPARENT] = _vd[0].get();
00096     _ed[1]->_a[QUADTREE] = _vd[5].get();
00097     _ed[1]->_a[PARENT_L] = _fd[0].get();
00098     _ed[1]->_a[PARENT_R] = _fd[2].get();
00099     _ed[1]->_orientation = 2;
00100 
00101     _ed[2] = new Diamond(mesh, TileKey(1,0,1,_profile.get()), 1, "ed2");
00102     _ed[2]->setCoord( -135, -45, 0 );
00103     _ed[2]->_a[GDPARENT] = _vd[2].get();
00104     _ed[2]->_a[QUADTREE] = _vd[4].get();
00105     _ed[2]->_a[PARENT_L] = _fd[0].get();
00106     _ed[2]->_a[PARENT_R] = _fd[3].get();
00107     _ed[2]->_orientation = 6;
00108 
00109     _ed[3] = new Diamond(mesh, TileKey(1,1,1,_profile.get()), 1, "ed3");
00110     _ed[3]->setCoord( -45, -45, 0 );
00111     _ed[3]->_a[GDPARENT] = _vd[2].get();
00112     _ed[3]->_a[QUADTREE] = _vd[5].get();
00113     _ed[3]->_a[PARENT_L] = _fd[3].get();
00114     _ed[3]->_a[PARENT_R] = _fd[0].get();
00115     _ed[3]->_orientation = 4;
00116 
00117     _ed[4] = new Diamond(mesh, TileKey(1,2,0,_profile.get()), 1, "ed4");
00118     _ed[4]->setCoord( 45, 45, 0 );
00119     _ed[4]->_a[GDPARENT] = _vd[1].get();
00120     _ed[4]->_a[QUADTREE] = _vd[5].get();
00121     _ed[4]->_a[PARENT_L] = _fd[2].get();
00122     _ed[4]->_a[PARENT_R] = _fd[1].get();
00123     _ed[4]->_orientation = 0;
00124     
00125     _ed[5] = new Diamond(mesh, TileKey(1,3,0,_profile.get()), 1, "ed5");
00126     _ed[5]->setCoord( 135, 45, 0 );
00127     _ed[5]->_a[GDPARENT] = _vd[1].get();
00128     _ed[5]->_a[QUADTREE] = _vd[4].get();
00129     _ed[5]->_a[PARENT_L] = _fd[1].get();
00130     _ed[5]->_a[PARENT_R] = _fd[2].get();
00131     _ed[5]->_orientation = 2;
00132 
00133     _ed[6] = new Diamond(mesh, TileKey(1,2,1,_profile.get()), 1, "ed6");
00134     _ed[6]->setCoord( 45, -45, 0 );
00135     _ed[6]->_a[GDPARENT] = _vd[3].get();
00136     _ed[6]->_a[QUADTREE] = _vd[5].get();
00137     _ed[6]->_a[PARENT_L] = _fd[1].get();
00138     _ed[6]->_a[PARENT_R] = _fd[3].get();
00139     _ed[6]->_orientation = 6;
00140 
00141     _ed[7] = new Diamond(mesh, TileKey(1,3,1,_profile.get()), 1, "ed7");
00142     _ed[7]->setCoord( 135, -45, 0 );
00143     _ed[7]->_a[GDPARENT] = _vd[3].get();
00144     _ed[7]->_a[QUADTREE] = _vd[4].get();
00145     _ed[7]->_a[PARENT_L] = _fd[3].get();
00146     _ed[7]->_a[PARENT_R] = _fd[1].get();
00147     _ed[7]->_orientation = 7;
00148 
00149     // set child pointers:
00150     _fd[0]->setChild( 0, _ed[3].get() );
00151     _fd[0]->setChild( 1, _ed[1].get() );
00152     _fd[0]->setChild( 2, _ed[0].get() );
00153     _fd[0]->setChild( 3, _ed[2].get() );
00154 
00155     _fd[1]->setChild( 0, _ed[4].get() );
00156     _fd[1]->setChild( 1, _ed[6].get() );
00157     _fd[1]->setChild( 2, _ed[7].get() );
00158     _fd[1]->setChild( 3, _ed[5].get() );
00159 
00160     _fd[2]->setChild( 0, _ed[5].get() );
00161     _fd[2]->setChild( 1, _ed[0].get() );
00162     _fd[2]->setChild( 2, _ed[1].get() );
00163     _fd[2]->setChild( 3, _ed[4].get() );
00164 
00165     _fd[3]->setChild( 0, _ed[2].get() );
00166     _fd[3]->setChild( 1, _ed[7].get() );
00167     _fd[3]->setChild( 2, _ed[6].get() );
00168     _fd[3]->setChild( 3, _ed[3].get() );
00169     
00170 
00171     // seed the bouding spheres of the manifold diamonds:
00172     for( unsigned short f=0; f<4; ++f )
00173         _fd[f]->activate();
00174 
00175     for( unsigned short e=0; e<8; ++e )
00176         _ed[e]->activate();
00177 
00178     // generate Level 3 (the first renderable quadtree decendants).
00179     seed( 3 );
00180 
00181     // hopefully, that's it!
00182 }
00183 
00184 //osg::Vec3d
00185 //GeodeticManifold::project( const osg::Vec3d& coord ) const
00186 //{
00187 //    osg::Vec3d out;
00188 //
00189 //    _ellipsoid->convertLatLongHeightToXYZ( 
00190 //        osg::DegreesToRadians( coord.y() ),
00191 //        osg::DegreesToRadians( coord.x() ), 0, 
00192 //        out.x(), out.y(), out.z() );
00193 //
00194 //    return out;
00195 //}
00196 
00197 osg::Vec3d
00198 GeodeticManifold::midpoint( const osg::Vec3d& p0, const osg::Vec3d& p1 ) const
00199 {
00200     //TODO account for date line crossing
00201     return (p0+p1)*0.5;
00202 }
00203 
00204 //osg::Vec3d
00205 //GeodeticManifold::normal( const osg::Vec3d& vert ) const
00206 //{
00207 //    //TODO: this is spherical. adjust for ellipsoid if necessary.
00208 //    osg::Vec3d n = vert;
00209 //    n.normalize();
00210 //    return n;
00211 //}
00212 
00213 MeshNode
00214 GeodeticManifold::createNode( const osg::Vec3d& manCoord ) const
00215 {
00216     MeshNode node;
00217 
00218     node._manifoldCoord = manCoord;
00219 
00220     node._geodeticCoord.set( 
00221         osg::DegreesToRadians(manCoord.x()), osg::DegreesToRadians(manCoord.y()), manCoord.z() );
00222 
00223     osg::Vec3d temp;
00224     _ellipsoid->convertLatLongHeightToXYZ(
00225         node._geodeticCoord.y(), node._geodeticCoord.x(), node._geodeticCoord.z(),
00226         temp.x(), temp.y(), temp.z() );
00227 
00228     node._vertex = temp;
00229 
00230     node._normal = _ellipsoid->computeLocalUpVector(
00231         temp.x(), temp.y(), temp.z() );
00232 
00233     return node;
00234 }
00235 
00236 osg::BoundingSphere
00237 GeodeticManifold::initialBound() const
00238 {
00239     return osg::BoundingSphere( osg::Vec3d(0,0,0), _ellipsoid->getRadiusEquator() * 1.2 );
00240 }
00241 
00242 void
00243 GeodeticManifold::seed( Level maxLevel )
00244 {
00245     for( unsigned short e=0; e<8; ++e )
00246     {
00247         _ed[e]->seed( maxLevel );
00248     }
00249 }
00250 
00251 void
00252 GeodeticManifold::cull( osgUtil::CullVisitor* cv )
00253 {
00254     for( unsigned short e=0; e<8; ++e )
00255     {
00256         _ed[e]->cull( cv );
00257     }
00258 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines