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

OpenGL

开发平台:

Visual C++

  1. // makestardb.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. // Convert a file with ASCII star records to a Celestia star database
  11. #include <iostream>
  12. #include <fstream>
  13. #include <iomanip>
  14. #include <cctype>
  15. #include <cassert>
  16. #include <celutil/basictypes.h>
  17. #include <celutil/bytes.h>
  18. #include <celengine/astro.h>
  19. #include <celengine/star.h>
  20. using namespace std;
  21. static string inputFilename;
  22. static string outputFilename;
  23. static bool useSphericalCoords = false;
  24. void Usage()
  25. {
  26.     cerr << "Usage: makestardb [options] <input file> <output star database>n";
  27.     cerr << "  Options:n";
  28.     cerr << "    --spherical (or -s) : input file has spherical coords (RA/dec/distancen";
  29. }
  30. bool parseCommandLine(int argc, char* argv[])
  31. {
  32.     int i = 1;
  33.     int fileCount = 0;
  34.     while (i < argc)
  35.     {
  36.         if (argv[i][0] == '-')
  37.         {
  38.             if (!strcmp(argv[i], "--spherical") || !strcmp(argv[i], "-s"))
  39.             {
  40.                 useSphericalCoords = true;
  41.             }
  42.             else
  43.             {
  44.                 cerr << "Unknown command line switch: " << argv[i] << 'n';
  45.                 return false;
  46.             }
  47.             i++;
  48.         }
  49.         else
  50.         {
  51.             if (fileCount == 0)
  52.             {
  53.                 // input filename first
  54.                 inputFilename = string(argv[i]);
  55.                 fileCount++;
  56.             }
  57.             else if (fileCount == 1)
  58.             {
  59.                 // output filename second
  60.                 outputFilename = string(argv[i]);
  61.                 fileCount++;
  62.             }
  63.             else
  64.             {
  65.                 // more than two filenames on the command line is an error
  66.                 return false;
  67.             }
  68.             i++;
  69.         }
  70.     }
  71.     return true;
  72. }
  73. static void writeUint(ostream& out, uint32 n)
  74. {
  75.     LE_TO_CPU_INT32(n, n);
  76.     out.write(reinterpret_cast<char*>(&n), sizeof n);
  77. }
  78. static void writeFloat(ostream& out, float f)
  79. {
  80.     LE_TO_CPU_FLOAT(f, f);
  81.     out.write(reinterpret_cast<char*>(&f), sizeof f);
  82. }
  83. static void writeUshort(ostream& out, uint16 n)
  84. {
  85.     LE_TO_CPU_INT16(n, n);
  86.     out.write(reinterpret_cast<char*>(&n), sizeof n);
  87. }
  88. static void writeShort(ostream& out, int16 n)
  89. {
  90.     LE_TO_CPU_INT16(n, n);
  91.     out.write(reinterpret_cast<char*>(&n), sizeof n);
  92. }
  93. bool WriteStarDatabase(istream& in, ostream& out, bool sphericalCoords)
  94. {
  95.     unsigned int record = 0;
  96.     unsigned int nStarsInFile = 0;
  97.     in >> nStarsInFile;
  98.     if (!in.good())
  99.     {
  100.         cerr << "Error reading star count at beginning of input file.n";
  101.         return 1;
  102.     }
  103.     // Write the header
  104.     out.write("CELSTARS", 8);
  105.     // Write the version
  106.     writeShort(out, 0x0100);
  107.     writeUint(out, nStarsInFile);
  108.     for (unsigned int record = 0; record < nStarsInFile; record++)
  109.     {
  110.         unsigned int catalogNumber;
  111.         float x, y, z;
  112.         float absMag;
  113.         in >> catalogNumber;
  114.         if (in.eof())
  115.             return true;
  116.         if (!in.good())
  117.         {
  118.             cerr << "Error parsing catalog number for record #" << record << 'n';
  119.             return false;
  120.         }
  121.         if (sphericalCoords)
  122.         {
  123.             float RA, dec, distance;
  124.             float appMag;
  125.             in >> RA >> dec >> distance;
  126.             if (!in.good())
  127.             {
  128.                 cerr << "Error parsing position of star " << catalogNumber << 'n';
  129.                 return false;
  130.             }
  131.             in >> appMag;
  132.             if (!in.good())
  133.             {
  134.                 cerr << "Error parsing magnitude of star " << catalogNumber << 'n';
  135.                 return false;
  136.             }
  137.             Point3d pos =
  138.                 astro::equatorialToCelestialCart((double) RA * 24.0 / 360.0,
  139.                                                  (double) dec,
  140.                                                  (double) distance);
  141.             x = (float) pos.x;
  142.             y = (float) pos.y;
  143.             z = (float) pos.z;
  144.             absMag = (float) (appMag + 5 - 5 * log10(distance / 3.26));
  145.         }
  146.         else
  147.         {
  148.             in >> x >> y >> z;
  149.             if (!in.good())
  150.             {
  151.                 cerr << "Error parsing position of star " << catalogNumber << 'n';
  152.                 return false;
  153.             }
  154.             in >> absMag;
  155.             if (!in.good())
  156.             {
  157.                 cerr << "Error parsing magnitude of star " << catalogNumber << 'n';
  158.                 return false;
  159.             }
  160.         }
  161.         string scString;
  162.         in >> scString;
  163.         StellarClass sc = StellarClass::parse(scString);
  164. #if 0
  165.         StarDetails* details = StarDetails::GetStarDetails(sc);
  166.         if (details == NULL)
  167.         {
  168.             cerr << "Error parsing spectral type of star " << catalogNumber << 'n';
  169.             return false;
  170.         }
  171.         // For spectral type parser debugging . . .
  172.         cout << scString << ' ' << details->getSpectralType() << 'n';
  173. #endif
  174.         writeUint(out, catalogNumber);
  175.         writeFloat(out, x);
  176.         writeFloat(out, y);
  177.         writeFloat(out, z);
  178.         writeShort(out, (int16) (absMag * 256.0f));
  179.         writeUshort(out, sc.pack());
  180.     }
  181.     return true;
  182. }
  183. int main(int argc, char* argv[])
  184. {
  185.     if (!parseCommandLine(argc, argv) || inputFilename.empty())
  186.     {
  187.         Usage();
  188.         return 1;
  189.     }
  190.     ifstream inputFile(inputFilename.c_str(), ios::in);
  191.     if (!inputFile.good())
  192.     {
  193.         cerr << "Error opening input file " << inputFilename << 'n';
  194.         return 1;
  195.     }
  196.     ofstream stardbFile(outputFilename.c_str(), ios::out | ios::binary);
  197.     if (!stardbFile.good())
  198.     {
  199.         cerr << "Error opening star database file " << outputFilename << 'n';
  200.         return 1;
  201.     }
  202.     bool success = WriteStarDatabase(inputFile, stardbFile, useSphericalCoords);
  203.     return success ? 0 : 1;
  204. }