#include #include #include #include using namespace std; #include "body.h" #include "findFile.h" #include "Map.h" #include "Options.h" #include "PlanetProperties.h" #include "Ring.h" #include "xpUtil.h" #include "libimage/Image.h" #include "libplanet/Planet.h" extern void loadSSEC(Image *&image, const unsigned char *&rgb, string &imageFile, const int imageWidth, const int imageHeight); static void loadRGB(Image *&image, const unsigned char *&rgb, string &imageFile, const string &name, const int imageWidth, const int imageHeight, const int shift) { bool foundFile = findFile(imageFile, "images"); if (foundFile) { image = new Image; foundFile = image->Read(imageFile.c_str()); } if (foundFile) { if ((image->Width() != imageWidth) || (image->Height() != imageHeight)) { ostringstream errStr; errStr << "Resizing " << name << " map\n" << "For better performance, all image maps should " << "be the same size as the day map\n"; xpWarn(errStr.str(), __FILE__, __LINE__); image->Resize(imageWidth, imageHeight); } if (shift != 0) image->Shift(shift); rgb = image->getRGBData(); } else { ostringstream errStr; errStr << "Can't load map file " << imageFile << "\n"; xpWarn(errStr.str(), __FILE__, __LINE__); } } Map * createMap(const double sLat, const double sLon, const double obsLat, const double obsLon, const int width, const int height, const double pR, Planet *planet, Ring *ring, map &planetsFromSunMap, PlanetProperties *planetProperties) { Map *m = NULL; string imageFile(planetProperties->DayMap()); bool foundFile = findFile(imageFile, "images"); if (!foundFile) { string errMsg("Can't find map file "); errMsg += imageFile; errMsg += "\n"; xpWarn(errMsg, __FILE__, __LINE__); } Image *day = new Image; foundFile = day->Read(imageFile.c_str()); if (!foundFile) { string errMsg("Can't load map file "); errMsg += imageFile; errMsg += "\n"; xpWarn(errMsg, __FILE__, __LINE__); // If the day map isn't found, assume the other maps won't be // found either int xsize = (int) (pR*4); if (xsize < 128) xsize = 128; if (xsize > width) xsize = width; int ysize = xsize / 2; m = new Map(xsize, ysize, sLat, sLon, planet, planetProperties, ring, planetsFromSunMap); } else { int imageWidth = day->Width(); int imageHeight = day->Height(); int ishift = 0; Options *options = Options::getInstance(); if (options->GRSSet() && planet->Index() == JUPITER) { double shift = (fmod(planet->Flipped() * (options->GRSLon()/360 + 0.5), 1.0)); shift *= imageWidth; ishift = static_cast (-shift); if (ishift != 0 && day != NULL) day->Shift(ishift); } const unsigned char *dayRGB = day->getRGBData(); Image *night = NULL; const unsigned char *nightRGB = NULL; Image *bump = NULL; const unsigned char *bumpRGB = NULL; Image *cloud = NULL; const unsigned char *cloudRGB = NULL; Image *specular = NULL; const unsigned char *specularRGB = NULL; imageFile = planetProperties->NightMap(); if (!imageFile.empty() && planetProperties->Shade() < 1) loadRGB(night, nightRGB, imageFile, "night", imageWidth, imageHeight, ishift); imageFile = planetProperties->BumpMap(); if (!imageFile.empty()) loadRGB(bump, bumpRGB, imageFile, "bump", imageWidth, imageHeight, ishift); imageFile = planetProperties->SpecularMap(); if (!imageFile.empty()) loadRGB(specular, specularRGB, imageFile, "specular", imageWidth, imageHeight, ishift); imageFile = planetProperties->CloudMap(); if (!imageFile.empty()) { if (planetProperties->SSECMap()) { loadSSEC(cloud, cloudRGB, imageFile, imageWidth, imageHeight); } else { loadRGB(cloud, cloudRGB, imageFile, "cloud", imageWidth, imageHeight, ishift); } } m = new Map(imageWidth, imageHeight, sLat, sLon, obsLat, obsLon, dayRGB, nightRGB, bumpRGB, specularRGB, cloudRGB, planet, planetProperties, ring, planetsFromSunMap); delete night; delete bump; delete cloud; delete specular; // If the map dimensions are each a power of two, the map size // will be reduced to get rid of high-frequency noise const double log2 = log(2.0); double e = log((double) imageWidth) / log2; double remainder = fabs(e - floor(e+0.5)); if (remainder < 1e-3) { e = log((double) imageHeight) / log2; remainder = fabs(e - floor(e+0.5)); if (remainder < 1e-3) { // optimal size for image is about 4*pR x 2*pR const double ratio = day->Height()/pR; const int factor = (int) (log(ratio)/log2) - 1; m->Reduce(factor); } } } delete day; return(m); }