startextdump.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:9k
源码类别:

OpenGL

开发平台:

Visual C++

  1. // startextdump.cpp
  2. //
  3. // Copyright (C) 2004, Chris Laurel <claurel@shatters.net>
  4. //
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU General Public License
  7. // as published by the Free Software Foundation; either version 2
  8. // of the License, or (at your option) any later version.
  9. //
  10. // Dump the contents of a Celestia star database file in a text
  11. // format that's easy read and edit.
  12. #include <iostream>
  13. #include <fstream>
  14. #include <iomanip>
  15. #include <celutil/basictypes.h>
  16. #include <celutil/bytes.h>
  17. #include <celengine/astro.h>
  18. #include <celengine/stellarclass.h>
  19. using namespace std;
  20. static string inputFilename;
  21. static string outputFilename;
  22. static string hdFilename;
  23. static bool useOldFormat = false;
  24. static bool useSphericalCoords = false;
  25. void Usage()
  26. {
  27.     cerr << "Usage: startextdump [options] <star database file> [output file]n";
  28.     cerr << "  Options:n";
  29.     cerr << "    --old (or -o)       : input star database is pre-2.0 formatn";
  30.     cerr << "    --hd                : dump HD catalog cross referencen";
  31.     cerr << "    --spherical (or -s) : output spherical coordinates (RA/dec/distancen";
  32. }
  33. static uint32 readUint(istream& in)
  34. {
  35.     uint32 n;
  36.     in.read(reinterpret_cast<char*>(&n), sizeof n);
  37.     LE_TO_CPU_INT32(n, n);
  38.     return n;
  39. }
  40. static float readFloat(istream& in)
  41. {
  42.     float f;
  43.     in.read(reinterpret_cast<char*>(&f), sizeof f);
  44.     LE_TO_CPU_FLOAT(f, f);
  45.     return f;
  46. }
  47. static int16 readShort(istream& in)
  48. {
  49.     int16 n;
  50.     in.read(reinterpret_cast<char*>(&n), sizeof n);
  51.     LE_TO_CPU_INT16(n, n);
  52.     return n;
  53. }
  54. static uint16 readUshort(istream& in)
  55. {
  56.     uint16 n;
  57.     in.read(reinterpret_cast<char*>(&n), sizeof n);
  58.     LE_TO_CPU_INT16(n, n);
  59.     return n;
  60. }
  61. static uint8 readUbyte(istream& in)
  62. {
  63.     uint8 n;
  64.     in.read((char*) &n, 1);
  65.     return n;
  66. }
  67. void printStellarClass(uint16 sc, ostream& out)
  68. {
  69.     StellarClass::StarType st = (StellarClass::StarType) (sc >> 12);
  70.     if (st == StellarClass::WhiteDwarf)
  71.     {
  72.         out << "WD";
  73.     }
  74.     else if (st == StellarClass::NeutronStar)
  75.     {
  76.         out << "Q";
  77.     }
  78.     else if (st == StellarClass::BlackHole)
  79.     {
  80.         out << "X";
  81.     }
  82.     else if (st == StellarClass::NormalStar)
  83.     {
  84.         unsigned int spectralClass = (sc >> 8 & 0xf);
  85.         unsigned int spectralSubclass = (sc >> 4 & 0xf);
  86.         unsigned int luminosityClass = (sc & 0xf);
  87.         if (spectralClass == 12)
  88.         {
  89.             out << '?';
  90.         }
  91.         else
  92.         {
  93.             out << "OBAFGKMRSNWW?LTC"[spectralClass];
  94.             out << "0123456789"[spectralSubclass];
  95.             switch (luminosityClass)
  96.             {
  97.             case StellarClass::Lum_Ia0:
  98.                 out << "I-a0";
  99.                 break;
  100.             case StellarClass::Lum_Ia:
  101.                 out << "I-a";
  102.                 break;
  103.             case StellarClass::Lum_Ib:
  104.                 out << "I-b";
  105.                 break;
  106.             case StellarClass::Lum_II:
  107.                 out << "II";
  108.                 break;
  109.             case StellarClass::Lum_III:
  110.                 out << "III";
  111.                 break;
  112.             case StellarClass::Lum_IV:
  113.                 out << "IV";
  114.                 break;
  115.             case StellarClass::Lum_V:
  116.                 out << "V";
  117.                 break;
  118.             case StellarClass::Lum_VI:
  119.                 out << "VI";
  120.                 break;
  121.             }
  122.         }
  123.     }
  124.     else
  125.     {
  126.         out << '?';
  127.     }
  128. }
  129. bool DumpOldStarDatabase(istream& in, ostream& out, ostream* hdOut,
  130.                          bool spherical)
  131. {
  132.     uint32 nStarsInFile = readUint(in);
  133.     if (!in.good())
  134.     {
  135.         cerr << "Error reading count of stars from database.n";
  136.         return false;
  137.     }
  138.     out << nStarsInFile << 'n';
  139.     for (uint32 i = 0; i < nStarsInFile; i++)
  140.     {
  141.         if (!in.good())
  142.         {
  143.             cerr << "Error reading from star database at record " << i << endl;
  144.             return false;
  145.         }
  146.         uint32 catalogNum    = readUint(in);
  147.         uint32 HDCatalogNum  = readUint(in);
  148.         float  RA            = readFloat(in);
  149.         float  dec           = readFloat(in);
  150.         float  parallax      = readFloat(in);
  151.         int16  appMag        = readShort(in);
  152.         uint16 stellarClass  = readUshort(in);
  153.         uint8  parallaxError = readUbyte(in);
  154. // Compute distance based on parallax
  155. double distance = LY_PER_PARSEC / (parallax > 0.0 ? parallax / 1000.0 : 1e-6);
  156.         out << catalogNum << ' ';
  157.         out << setprecision(8);
  158.         if (spherical)
  159.         {
  160.             out << RA * 360.0 / 24.0 << ' ' << dec << ' ' << distance << ' ';
  161.             out << setprecision(6);
  162.             out << (float) appMag / 256.0f << ' ';
  163.         }
  164.         else
  165.         {
  166.             Point3d pos = astro::equatorialToCelestialCart((double) RA, (double) dec, distance);
  167.             float absMag = (float) (appMag / 256.0 + 5 -
  168.                                     5 * log10(distance / 3.26));
  169.             out << (float) pos.x << ' ' <<
  170.                    (float) pos.y << ' ' <<
  171.                    (float) pos.z << ' ';
  172.             out << setprecision(5);
  173.             out << absMag << ' ';
  174.         }
  175.         printStellarClass(stellarClass, out);
  176.         out << 'n';
  177.         // Dump HD catalog cross reference
  178.         if (hdOut != NULL && HDCatalogNum != ~0)
  179.             *hdOut << HDCatalogNum << ' ' << catalogNum << 'n';
  180.     }
  181.     return true;
  182. }
  183. bool DumpStarDatabase(istream& in, ostream& out, ostream* hdOut)
  184. {
  185.     char header[8];
  186.     in.read(header, sizeof header);
  187.     if (strncmp(header, "CELSTARS", sizeof header))
  188.     {
  189.         cerr << "Missing header in star database.n";
  190.         return false;
  191.     }
  192.     uint16 version = readUshort(in);
  193.     if (version != 0x0100)
  194.     {
  195.         cerr << "Unsupported file version " << (version >> 8) << '.' <<
  196.             (version & 0xff) << 'n';
  197.         return false;
  198.     }
  199.     uint32 nStarsInFile = readUint(in);
  200.     if (!in.good())
  201.     {
  202.         cerr << "Error reading count of stars from database.n";
  203.         return false;
  204.     }
  205.     out << nStarsInFile << 'n';
  206.     for (uint32 i = 0; i < nStarsInFile; i++)
  207.     {
  208.         if (!in.good())
  209.         {
  210.             cerr << "Error reading from star database at record " << i << endl;
  211.             return false;
  212.         }
  213.         uint32 catalogNum    = readUint(in);
  214.         float  x             = readFloat(in);
  215.         float  y             = readFloat(in);
  216.         float  z             = readFloat(in);
  217.         int16  absMag        = readShort(in);
  218.         uint16 stellarClass  = readUshort(in);
  219.         out << catalogNum << ' ';
  220.         out << setprecision(7);
  221.         out << x << ' ' << y << ' ' << z << ' ';
  222.         out << setprecision(4);
  223.         out << ((float) absMag / 256.0f) << ' ';
  224.         printStellarClass(stellarClass, out);
  225.         out << 'n';
  226.     }
  227.     return true;
  228. }
  229. bool parseCommandLine(int argc, char* argv[])
  230. {
  231.     int i = 1;
  232.     int fileCount = 0;
  233.     while (i < argc)
  234.     {
  235.         if (argv[i][0] == '-')
  236.         {
  237.             if (!strcmp(argv[i], "--hd"))
  238.             {
  239.                 if (i == argc - 1)
  240.                 {
  241.                     return false;
  242.                 }
  243.                 else
  244.                 {
  245.                     i++;
  246.                     hdFilename = string(argv[i]);
  247.                 }
  248.             }
  249.             else if (!strcmp(argv[i], "-o") || !strcmp(argv[i], "--old"))
  250.             {
  251.                 useOldFormat = true;
  252.             }
  253.             else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--spherical"))
  254.             {
  255.                 useSphericalCoords = true;
  256.             }
  257.             else
  258.             {
  259.                 cerr << "Unknown command line switch: " << argv[i] << 'n';
  260.                 return false;
  261.             }
  262.             i++;
  263.         }
  264.         else
  265.         {
  266.             if (fileCount == 0)
  267.             {
  268.                 // input filename first
  269.                 inputFilename = string(argv[i]);
  270.                 fileCount++;
  271.             }
  272.             else if (fileCount == 1)
  273.             {
  274.                 // output filename second
  275.                 outputFilename = string(argv[i]);
  276.                 fileCount++;
  277.             }
  278.             else
  279.             {
  280.                 // more than two filenames on the command line is an error
  281.                 return false;
  282.             }
  283.             i++;
  284.         }
  285.     }
  286.     return true;
  287. }
  288. int main(int argc, char* argv[])
  289. {
  290.     if (!parseCommandLine(argc, argv) || inputFilename.empty())
  291.     {
  292.         Usage();
  293.         return 1;
  294.     }
  295.     ifstream stardbFile(inputFilename.c_str(), ios::in | ios::binary);
  296.     if (!stardbFile.good())
  297.     {
  298.         cerr << "Error opening star database file " << inputFilename << 'n';
  299.         return 1;
  300.     }
  301.     ofstream* hdOut = NULL;
  302.     if (!hdFilename.empty())
  303.     {
  304.         hdOut = new ofstream(hdFilename.c_str(), ios::out);
  305.         if (!hdOut->good())
  306.         {
  307.             cerr << "Error opening HD catalog output file " << hdFilename << 'n';
  308.             return 1;
  309.         }
  310.     }
  311.     bool success;
  312.     ostream* out = &cout;
  313.     if (!outputFilename.empty())
  314.     {
  315.         out = new ofstream(outputFilename.c_str(), ios::out);
  316.         if (!out->good())
  317.         {
  318.             cerr << "Error opening output file " << outputFilename << 'n';
  319.             return 1;
  320.         }
  321.     }
  322.     if (useOldFormat)
  323.     {
  324.         success = DumpOldStarDatabase(stardbFile, *out, hdOut,
  325.                                       useSphericalCoords);
  326.     }
  327.     else
  328.     {
  329.         success = DumpStarDatabase(stardbFile, *out, hdOut);
  330.     }
  331.     return success ? 0 : 1;
  332. }