QGLSceneNode *Earth::buildEarthNode(qreal radius, int divisions, int cur_zoom){ qreal separation = qPow(2, cur_zoom); QGLBuilder builder; for (int lonTileNum = 0; lonTileNum < separation; lonTileNum++) { for (int latTileNum = 0; latTileNum < separation; latTileNum++) { addTileNode(&builder, radius, divisions, cur_zoom, lonTileNum, latTileNum); } } return builder.finalizedSceneNode();}
void Earth::addTileNode(QGLBuilder* builder, qreal radius, int divisions, int cur_zoom, qint32 lonTileNum, qint32 latTileNum){ int separation = qPow(2, cur_zoom); // degrees for one tile qreal NTLat = 2*maxAbsLat / separation; qreal NTLon = 2*maxAbsLon / separation; // min and max tile degrees qreal minLat = latTileNum * NTLat - maxAbsLat; qreal maxLat = (latTileNum+1) * NTLat - maxAbsLat; qreal minLon = lonTileNum * NTLon - maxAbsLon; qreal maxLon = (lonTileNum+1) * NTLon - maxAbsLon; // calculate spherical min and max lon and lat int signMinLat = (minLat<0)?-1:1; int signMaxLat = (maxLat<0)?-1:1; qreal minSphereLat = Mercator2SphereAnalyticDegrees(qAbs(minLat))*signMinLat; qreal maxSphereLat = Mercator2SphereAnalyticDegrees(qAbs(maxLat))*signMaxLat; qreal minSphereLon = minLon; qreal maxSphereLon = maxLon; // all stacks and slices int stacks = 32; int slices = 32; if (cur_zoom > 6) { stacks *= qPow(2, cur_zoom - 6); slices *= qPow(2, cur_zoom - 6); } // stacks and slices for one tile int stacksForOne = stacks/separation; int slicesForOne = slices/separation; // degrees for one stack (slice) qreal oneStackDegrees = (maxLat - minLat)/(qreal)stacksForOne; qreal oneSliceDegrees = (maxLon - minLon)/(qreal)slicesForOne; qreal curSphereLat, curSphereLatNext, curSphereLon; QVector3D curDecart; QVector3D curDecartNext; QGLBuilder tempBuilder; for (qreal curMerLat = maxLat; curMerLat >= (minLat+0.2); curMerLat-=oneStackDegrees) { qreal curMerLatNext = curMerLat - oneStackDegrees; QGeometryData prim; double yTexCoord; double yTexCoordNext; double xTexCoord; double xTexCoordNext; prim.clear(); for (qreal curMerLon = minLon; curMerLon <= maxLon; curMerLon += oneSliceDegrees) { int signLat = (curMerLat >= 0)?1:-1; int signLatNext = (curMerLatNext >= 0)?1:-1; // перевод текущих широт в сферическую проекцию curSphereLat = Mercator2SphereAnalytic(qAbs(curMerLat)/90.0)*signLat*90; curSphereLatNext = Mercator2SphereAnalytic(qAbs(curMerLatNext)/90.0)*signLatNext*90; // широты не изменяются curSphereLon = curMerLon; // перевод из lat и lon в декартовые (h = 0) curDecart = llh2xyz(curSphereLat, curSphereLon); curDecartNext = llh2xyz(curSphereLatNext, curSphereLon); prim.appendVertex(curDecart); prim.appendNormal(curDecart); xTexCoord = (curSphereLon - minSphereLon)/(maxSphereLon - minSphereLon); yTexCoord = (curSphereLat/90.0 - minSphereLat)/(maxSphereLat - minSphereLat); prim.appendTexCoord(QVector2D(xTexCoord, yTexCoord)); prim.appendVertex(curDecartNext); prim.appendNormal(curDecartNext); xTexCoordNext = (curSphereLon - minSphereLon)/(maxSphereLon - minSphereLon); yTexCoordNext = (curSphereLatNext/90.0 - minSphereLat)/(maxSphereLat - minSphereLat); prim.appendTexCoord(QVector2D(xTexCoordNext, yTexCoordNext)); } tempBuilder.addQuadStrip(prim); }.....//проверяется существование текстуры (тайла), если нужно скачивается и применяется......}