osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthDrivers/engine_seamless/GeoPatch.cpp

Go to the documentation of this file.
00001 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00002  * Copyright 2010 Pelican Ventures, Inc.
00003  * http://osgearth.org
00004  *
00005  * osgEarth is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU Lesser General Public License as published by
00007  * the Free Software Foundation; either version 2 of the License, or
00008  * (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU Lesser General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Lesser General Public License
00016  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00017  */
00018 
00019 #include "GeoPatch"
00020 
00021 #include <algorithm>
00022 
00023 #include "Geographic"
00024 #include "Euler"
00025 #include "PatchSet"
00026 
00027 namespace seamless
00028 {
00029 using namespace osg;
00030 using namespace osgEarth;
00031 
00032 GeoPatch::GeoPatch()
00033 {
00034     _face = -1;
00035     std::fill(&_edgeLengths[0], &_edgeLengths[4], 0.0);
00036 
00037 }
00038 
00039 GeoPatch::GeoPatch(const TileKey& key)
00040 {
00041     // When an arc on the cube grid is subdivided, this is the largest
00042     // ratio of the lengths of the parent arc and its longest
00043     // child. The ratio goes to .5 as the arcs are further subdivided
00044     // at higher LODs. The error threshold is set to this value to
00045     // insure that the triles that share an edge will display the same
00046     // LOD when the enclosing patches are from different LODs.
00047     setErrorThreshold(.5371);
00048     const GeoExtent& extent = key.getExtent();
00049     double xMin = extent.xMin(), yMin = extent.yMin(),
00050         xMax = extent.xMax(), yMax = extent.yMax();
00051     euler::cubeToFace(xMin, yMin, xMax, yMax, _face);
00052     Vec2d faceCoords[4];
00053     _faceCoords[0][0] = xMin; _faceCoords[0][1] = yMin;
00054     _faceCoords[1][0] = xMax; _faceCoords[1][1] = yMin;
00055     _faceCoords[2][0] = xMax; _faceCoords[2][1] = yMax;
00056     _faceCoords[3][0] = xMin; _faceCoords[3][1] = yMax;
00057     for (int i = 0; i < 4; ++i)
00058         _edgeLengths[i] = euler::arcLength(_faceCoords[i],
00059                                            _faceCoords[(i + 1) % 4], _face);
00060 }
00061 
00062 GeoPatch::GeoPatch(const GeoPatch& rhs, const CopyOp& copyop)
00063     : Patch(rhs, copyop), _face(rhs._face)
00064 {
00065     std::copy(&rhs._edgeLengths[0], &rhs._edgeLengths[4], &_edgeLengths[0]);
00066     std::copy(&rhs._faceCoords[0], &rhs._faceCoords[4], &_faceCoords[0]);
00067 }
00068 
00069 float GeoPatch::getEdgeError(const osg::Vec3& eye, int edge)
00070 {
00071     // Hack to get back to face parameters and world coordinates.
00072     Transform* parent = static_cast<Transform*>(getParent(0));
00073     PatchGroup* pgroup = static_cast<PatchGroup*>(parent->getParent(0));
00074     Matrix worldMat;
00075     parent->computeLocalToWorldMatrix(worldMat, 0);
00076     Vec3d worldEye = Vec3d(eye) * worldMat;
00077     double d = euler::distanceToSegment(worldEye, _faceCoords[edge],
00078                                         _faceCoords[(edge + 1) % 4], _face);
00079     return _patchSet->getPrecisionFactor() * _edgeLengths[edge] / d;
00080 }
00081 
00082 void GeoPatch::setGeographic(Geographic* geo)
00083 {
00084     _patchSet = geo;
00085 }
00086 
00087 Geographic* GeoPatch::getGeographic() const
00088 {
00089     return static_cast<Geographic*>(_patchSet.get());
00090 }
00091 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines