osgEarth 2.1.1
|
Public Member Functions | |
Projected (const osgEarth::Map *map, const osgEarth::Drivers::SeamlessOptions &options) | |
virtual osg::Transform * | createPatch (const std::string &filename, PatchOptions *poptions) |
class for rendering seamless projected maps for osgEarth
This class fills the role of an "engine" for osgEarth. It uses the tiling scheme of the map to create the quadtree leaves of the seamless surface.
The heightfield resolution is fixed at 65x65 vertices. If this doesn't match the tile size returned by the map then the tile is resampled.
seamless::Projected::Projected | ( | const osgEarth::Map * | map, |
const osgEarth::Drivers::SeamlessOptions & | options | ||
) |
Definition at line 104 of file Projected.cpp.
: PatchSet(options) { setPrecisionFactor(8); setMap(map); { int maxLevel = 0; const ElevationLayerVector& elevations = _mapf->elevationLayers(); for (ElevationLayerVector::const_iterator itr = elevations.begin(), end = elevations.end(); itr != end; ++itr) { const TerrainLayerOptions& options = (*itr)->getTerrainLayerOptions(); if (options.maxLevel().isSet() && options.maxLevel().get() > maxLevel) maxLevel = options.maxLevel().get(); } if (maxLevel > 0) setMaxLevel(maxLevel); } }
Transform * seamless::Projected::createPatch | ( | const std::string & | filename, |
PatchOptions * | poptions | ||
) | [virtual] |
Reimplemented from seamless::PatchSet.
Definition at line 129 of file Projected.cpp.
{ Patch* patch = new Patch; patch->setPatchSet(this); ProjectedOptions* pjoptions = static_cast<ProjectedOptions*>(poptions); TileKey key = makeTileKey(static_cast<Projected*>(patch->getPatchSet()), pjoptions); const GeoExtent& extent = key.getExtent(); double xMin = extent.xMin(), yMin = extent.yMin(); double centerX, centerY; extent.getCentroid(centerX, centerY); MatrixTransform* transform = new MatrixTransform; Matrixd mat = Matrixd::translate(centerX, centerY, 0.0); transform->setMatrix(mat); transform->addChild(patch); ref_ptr<HeightField> hf; GeoImage gimage; { _mapf->getHeightField(key, true, hf, 0L, INTERP_BILINEAR); const ImageLayerVector& layers = _mapf->imageLayers(); if (!layers.empty()) gimage = layers[0]->createImage(key); } ref_ptr<Patch::Data> data = new Patch::Data; int patchDim = _resolution + 1; hf = resampleHeightField(hf, patchDim); Vec3Array* verts = new Vec3Array(patchDim * patchDim); Vec3Array* normals = new Vec3Array(patchDim * patchDim); Vec2f minCoord(xMin - centerX, yMin - centerY); float xInt = hf->getXInterval(), yInt = hf->getYInterval(); for (int j = 0; j < patchDim; ++j) for (int i = 0; i < patchDim; ++i) { (*verts)[patchDim * j + i] = Vec3( minCoord.x() + xInt * i, minCoord.y() + yInt * j, hf->getHeight(i, j) * getVerticalScale()); // XXX normals change if verticalScale != 1.0 (*normals)[patchDim * j + i] = hf->getNormal(i, j); } data->vertexData.array = verts; data->vertexData.binding = Geometry::BIND_PER_VERTEX; data->normalData.array = normals; data->normalData.binding = Geometry::BIND_PER_VERTEX; Vec4Array* colors = new Vec4Array(1); (*colors)[0] = Vec4(1.0, 1.0, 1.0, 1.0); data->colorData.array = colors; data->colorData.binding = Geometry::BIND_OVERALL; if (gimage.valid()) { Texture2D* tex = new Texture2D(); tex->setImage(gimage.getImage()); tex->setWrap(Texture::WRAP_S, Texture::CLAMP_TO_EDGE); tex->setWrap(Texture::WRAP_T, Texture::CLAMP_TO_EDGE); tex->setFilter(Texture::MIN_FILTER, Texture::LINEAR_MIPMAP_LINEAR); tex->setFilter(Texture::MAG_FILTER, Texture::LINEAR); StateSet* ss = patch->getOrCreateStateSet(); ss->setTextureAttributeAndModes(0, tex, StateAttribute::ON); } Vec2Array* texCoords = new Vec2Array(patchDim * patchDim); for (int j = 0; j < patchDim; ++j) for (int i = 0; i < patchDim; ++i) (*texCoords)[patchDim * j + i] = Vec2(static_cast<float>(i) / (patchDim - 1), static_cast<float>(j) / (patchDim - 1)); data->texCoordList .push_back(Geometry::ArrayData(texCoords, Geometry::BIND_PER_VERTEX)); patch->setData(data); return transform; } }