00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <celmath/mathlib.h>
00011 #include <cstring>
00012 #include "celestia.h"
00013 #include "astro.h"
00014 #include "orbit.h"
00015 #include "star.h"
00016 #include "texmanager.h"
00017
00018
00019
00020
00021
00022
00023
00024
00025 #define SOLAR_TEMPERATURE 5860.0f
00026 #define SOLAR_RADIUS 696000
00027
00028
00029 struct SpectralTypeInfo
00030 {
00031 char* name;
00032 float temperature;
00033 float rotationPeriod;
00034 };
00035
00036 ResourceHandle StarDetails::starTexB = InvalidResource;
00037 ResourceHandle StarDetails::starTexA = InvalidResource;
00038 ResourceHandle StarDetails::starTexG = InvalidResource;
00039 ResourceHandle StarDetails::starTexM = InvalidResource;
00040 ResourceHandle StarDetails::starTexL = InvalidResource;
00041
00042 static StarDetails** normalStarDetails = NULL;
00043 static StarDetails** whiteDwarfDetails = NULL;
00044 static StarDetails* neutronStarDetails = NULL;
00045 static StarDetails* blackHoleDetails = NULL;
00046 static StarDetails* barycenterDetails = NULL;
00047
00048
00049
00050
00051
00052 static float tempO[3][10] =
00053 {
00054 { 52500, 52500, 52500, 52500, 48000, 44500, 41000, 38000, 35800, 33000 },
00055 { 50000, 50000, 50000, 50000, 45500, 42500, 39500, 37000, 34700, 32000 },
00056 { 47300, 47300, 47300, 47300, 44100, 42500, 39500, 37000, 34700, 32000 },
00057 };
00058
00059 static float tempB[3][10] =
00060 {
00061 { 30000, 25400, 22000, 18700, 17000, 15400, 14000, 13000, 11900, 10500 },
00062 { 29000, 24000, 20300, 17100, 16000, 15000, 14100, 13200, 12400, 11000 },
00063 { 26000, 20800, 18500, 16200, 15100, 13600, 13000, 12200, 11200, 10300 },
00064 };
00065
00066 static float tempA[3][10] =
00067 {
00068 { 9520, 9230, 8970, 8720, 8460, 8200, 8020, 7850, 7580, 7390 },
00069 { 10100, 9480, 9000, 8600, 8300, 8100, 7850, 7650, 7450, 7250 },
00070 { 9730, 9230, 9080, 8770, 8610, 8510, 8310, 8150, 7950, 7800 },
00071 };
00072
00073 static float tempF[3][10] =
00074 {
00075 { 7200, 7050, 6890, 6740, 6590, 6440, 6360, 6280, 6200, 6110 },
00076 { 7150, 7000, 6870, 6720, 6570, 6470, 6350, 6250, 6150, 6080 },
00077 { 7700, 7500, 7350, 7150, 7000, 6900, 6500, 6300, 6100, 5800 },
00078 };
00079
00080 static float tempG[3][10] =
00081 {
00082 { 6030, 5940, 5860, 5830, 5800, 5770, 5700, 5630, 5570, 5410 },
00083 { 5850, 5650, 5450, 5350, 5250, 5150, 5050, 5070, 4900, 4820 },
00084 { 5550, 5350, 5200, 5050, 4950, 4850, 4750, 4660, 4600, 4500 },
00085 };
00086
00087 static float tempK[3][10] =
00088 {
00089 { 5250, 5080, 4900, 4730, 4590, 4350, 4200, 4060, 3990, 3920 },
00090 { 4750, 4600, 4420, 4200, 4000, 3950, 3900, 3850, 3830, 3810 },
00091 { 4420, 4330, 4250, 4080, 3950, 3850, 3760, 3700, 3680, 3660 },
00092 };
00093
00094 static float tempM[3][10] =
00095 {
00096 { 3850, 3720, 3580, 3470, 3370, 3240, 3050, 2940, 2640, 2000 },
00097 { 3800, 3720, 3620, 3530, 3430, 3330, 3240, 3240, 3240, 3240 },
00098 { 3650, 3550, 3450, 3200, 2980, 2800, 2600, 2600, 2600, 2600 },
00099 };
00100
00101
00102
00103 static float tempWN[10] =
00104 {
00105 50000, 50000, 50000, 50000, 47000, 43000, 39000, 32000, 29000, 29000
00106 };
00107
00108 static float tempWC[10] =
00109 {
00110 60000, 60000, 60000, 60000, 60000, 60000, 60000, 54000, 46000, 38000
00111 };
00112
00113
00114 static float tempL[10] =
00115 {
00116 1960, 1930, 1900, 1850, 1800, 1740, 1680, 1620, 1560, 1500
00117 };
00118
00119 static float tempT[10] =
00120 {
00121 1425, 1350, 1275, 1200, 1140, 1080, 1020, 900, 800, 750
00122 };
00123
00124
00125
00126
00127
00128
00129
00130 static float bmag_correctionO[3][10] =
00131 {
00132
00133 {
00134 -4.75f, -4.75f, -4.75f, -4.75f, -4.45f,
00135 -4.40f, -3.93f, -3.68f, -3.54f, -3.33f,
00136 },
00137
00138 {
00139 -4.58f, -4.58f, -4.58f, -4.58f, -4.28f,
00140 -4.05f, -3.80f, -3.58f, -3.39f, -3.13f,
00141 },
00142
00143 {
00144 -4.41f, -4.41f, -4.41f, -4.41f, -4.17f,
00145 -3.87f, -3.74f, -3.48f, -3.35f, -3.18f,
00146 }
00147 };
00148
00149 static float bmag_correctionB[3][10] =
00150 {
00151
00152 {
00153 -3.16f, -2.70f, -2.35f, -1.94f, -1.70f,
00154 -1.46f, -1.21f, -1.02f, -0.80f, -0.51f,
00155 },
00156
00157 {
00158 -2.88f, -2.43f, -2.02f, -1.60f, -1.45f,
00159 -1.30f, -1.13f, -0.97f, -0.82f, -0.71f,
00160 },
00161
00162 {
00163 -2.49f, -1.87f, -1.58f, -1.26f, -1.11f,
00164 -0.95f, -0.88f, -0.78f, -0.66f, -0.52f,
00165 }
00166 };
00167
00168 static float bmag_correctionA[3][10] =
00169 {
00170
00171 {
00172 -0.30f, -0.23f, -0.20f, -0.17f, -0.16f,
00173 -0.15f, -0.13f, -0.12f, -0.10f, -0.09f,
00174 },
00175
00176 {
00177 -0.42f, -0.29f, -0.20f, -0.17f, -0.15f,
00178 -0.14f, -0.12f, -0.10f, -0.10f, -0.10f,
00179 },
00180
00181 {
00182 -0.41f, -0.32f, -0.28f, -0.21f, -0.17f,
00183 -0.13f, -0.09f, -0.06f, -0.03f, -0.02f,
00184 }
00185 };
00186
00187 static float bmag_correctionF[3][10] =
00188 {
00189
00190 {
00191 -0.09f, -0.10f, -0.11f, -0.12f, -0.13f,
00192 -0.14f, -0.14f, -0.15f, -0.16f, -0.17f,
00193 },
00194
00195 {
00196 -0.11f, -0.11f, -0.11f, -0.12f, -0.13f,
00197 -0.13f, -0.15f, -0.15f, -0.16f, -0.18f,
00198 },
00199
00200 {
00201 -0.01f, 0.00f, 0.00f, -0.01f, -0.02f,
00202 -0.03f, -0.05f, -0.07f, -0.09f, -0.12f,
00203 }
00204 };
00205
00206 static float bmag_correctionG[3][10] =
00207 {
00208
00209 {
00210 -0.18f, -0.19f, -0.20f, -0.20f, -0.21f,
00211 -0.21f, -0.27f, -0.33f, -0.40f, -0.36f,
00212 },
00213
00214 {
00215 -0.20f, -0.24f, -0.27f, -0.29f, -0.32f,
00216 -0.34f, -0.37f, -0.40f, -0.42f, -0.46f,
00217 },
00218
00219 {
00220 -0.15f, -0.18f, -0.21f, -0.25f, -0.29f,
00221 -0.33f, -0.36f, -0.39f, -0.42f, -0.46f,
00222 }
00223 };
00224
00225 static float bmag_correctionK[3][10] =
00226 {
00227
00228 {
00229 -0.31f, -0.37f, -0.42f, -0.50f, -0.55f,
00230 -0.72f, -0.89f, -1.01f, -1.13f, -1.26f,
00231 },
00232
00233 {
00234 -0.50f, -0.55f, -0.61f, -0.76f, -0.94f,
00235 -1.02f, -1.09f, -1.17f, -1.20f, -1.22f,
00236 },
00237
00238 {
00239 -0.50f, -0.56f, -0.61f, -0.75f, -0.90f,
00240 -1.01f, -1.10f, -1.20f, -1.23f, -1.26f,
00241 }
00242 };
00243
00244 static float bmag_correctionM[3][10] =
00245 {
00246
00247 {
00248 -1.38f, -1.62f, -1.89f, -2.15f, -2.38f,
00249 -2.73f, -3.21f, -3.46f, -4.10f, -4.40f,
00250 },
00251
00252 {
00253 -1.25f, -1.44f, -1.62f, -1.87f, -2.22f,
00254 -2.48f, -2.73f, -2.73f, -2.73f, -2.73f,
00255 },
00256
00257 {
00258 -1.29f, -1.38f, -1.62f, -2.13f, -2.75f,
00259 -3.47f, -3.90f, -3.90f, -3.90f, -3.90f,
00260 }
00261 };
00262
00263
00264 static float bmag_correctionL[10] =
00265 {
00266 -4.6f, -4.9f, -5.0f, -5.2f, -5.4f, -5.9f, -6.1f, -6.7f, -7.4f, -8.2f,
00267 };
00268
00269 static float bmag_correctionT[10] =
00270 {
00271 -8.9f, -9.6f, -10.8f, -11.9f, -13.1f, -14.4f, -16.1f, -17.9f, -19.6f, -19.6f,
00272 };
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 static float rotperiod_O[3][10] =
00290 {
00291 { 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f },
00292 { 6.3f, 6.3f, 6.3f, 6.3f, 6.3f, 6.3f, 6.3f, 6.3f, 6.3f, 6.3f },
00293 { 15.0f, 15.0f, 15.0f, 15.0f, 15.0f, 15.0f, 15.0f, 15.0f, 15.0f, 15.0f },
00294 };
00295
00296 static float rotperiod_B[3][10] =
00297 {
00298 { 2.0f, 1.8f, 1.6f, 1.4f, 1.1f, 0.8f, 0.8f, 0.8f, 0.8f, 0.7f },
00299 { 6.3f, 5.6f, 5.0f, 4.3f, 3.7f, 3.1f, 2.9f, 2.8f, 2.7f, 2.6f },
00300 { 15.0f, 24.0f, 33.0f, 42.0f, 52.0f, 63.0f, 65.0f, 67.0f, 70.0f, 72.0f },
00301 };
00302
00303 static float rotperiod_A[3][10] =
00304 {
00305 { 0.7f, 0.7f, 0.6f, 0.6f, 0.5f, 0.5f, 0.5f, 0.6f, 0.6f, 0.7f },
00306 { 2.5f, 2.3f, 2.1f, 1.9f, 1.7f, 1.6f, 1.6f, 1.7f, 1.7f, 1.8f },
00307 { 75.0f, 77.0f, 80.0f, 82.0f, 85.0f, 87.0f, 95.0f, 104.0f, 115.0f, 125.0f },
00308 };
00309
00310 static float rotperiod_F[3][10] =
00311 {
00312 { 0.7f, 0.7f, 0.6f, 0.6f, 0.5f, 0.5f, 0.5f, 0.6f, 0.6f, 0.7f },
00313 { 1.9f, 2.5f, 3.0f, 3.5f, 4.0f, 4.6f, 5.6f, 6.7f, 7.8f, 8.9f },
00314 { 135.0f, 141.0f, 148.0f, 155.0f, 162.0f, 169.0f, 175.0f, 182.0f, 188.0f, 195.0f },
00315 };
00316
00317 static float rotperiod_G[3][10] =
00318 {
00319 { 11.1f, 18.2f, 25.4f, 24.7f, 24.0f, 23.3f, 23.0f, 22.7f, 22.3f, 21.9f },
00320 { 10.0f, 13.0f, 16.0f, 19.0f, 22.0f, 25.0f, 28.0f, 31.0f, 33.0f, 35.0f },
00321 { 202.0f, 222.0f, 242.0f, 262.0f, 282.0f,
00322 303.0f, 323.0f, 343.0f, 364.0f, 384.0f },
00323 };
00324
00325 static float rotperiod_K[3][10] =
00326 {
00327 { 21.5f, 20.8f, 20.2f, 19.4f, 18.8f, 18.2f, 17.6f, 17.0f, 16.4f, 15.8f },
00328 { 38.0f, 43.0f, 48.0f, 53.0f, 58.0f, 63.0f, 71.0f, 78.0f, 86.0f, 93.0f },
00329 { 405.0f, 526.0f, 648.0f, 769.0f, 891.0f,
00330 1012.0f, 1063.0f, 1103.0f, 1154.0f, 1204.0f },
00331 };
00332
00333 static float rotperiod_M[3][10] =
00334 {
00335 { 15.2f, 12.4f, 9.6f, 6.8f, 4.0f, 1.3f, 1.0f, 0.7f, 0.4f, 0.2f },
00336 { 101.0f, 101.0f, 101.0f, 101.0f, 101.0f, 101.0f, 101.0f, 101.0f, 101.0f, 101.0f },
00337 { 1265.0f, 1265.0f, 1265.0f, 1265.0f, 1265.0f,
00338 1265.0f, 1265.0f, 1265.0f, 1265.0f, 1265.0f },
00339 };
00340
00341
00342 char* LumClassNames[StellarClass::Lum_Count] = {
00343 "I-a0", "I-a", "I-b", "II", "III", "IV", "V", "VI", ""
00344 };
00345
00346 char* SubclassNames[11] = {
00347 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ""
00348 };
00349
00350 char* SpectralClassNames[StellarClass::NormalClassCount] = {
00351 "O", "B", "A", "F", "G", "K", "M", "R",
00352 "S", "N", "WC", "WN", "?", "L", "T", "C",
00353 };
00354
00355 char* WDSpectralClassNames[StellarClass::WDClassCount] = {
00356 "DA", "DB", "DC", "DO", "DQ", "DZ", "D", "DX",
00357 };
00358
00359
00360 StarDetails*
00361 StarDetails::GetStarDetails(const StellarClass& sc)
00362 {
00363 switch (sc.getStarType())
00364 {
00365 case StellarClass::NormalStar:
00366 return GetNormalStarDetails(sc.getSpectralClass(),
00367 sc.getSubclass(),
00368 sc.getLuminosityClass());
00369
00370 case StellarClass::WhiteDwarf:
00371 return GetWhiteDwarfDetails(sc.getSpectralClass(),
00372 sc.getSubclass());
00373 case StellarClass::NeutronStar:
00374 return GetNeutronStarDetails();
00375 case StellarClass::BlackHole:
00376 return GetBlackHoleDetails();
00377 default:
00378 return NULL;
00379 }
00380 }
00381
00382
00383 StarDetails*
00384 StarDetails::CreateStandardStarType(const std::string& specTypeName,
00385 float _temperature,
00386 float _rotationPeriod)
00387
00388 {
00389 StarDetails* details = new StarDetails();
00390
00391 details->setTemperature(_temperature);
00392 details->setSpectralType(specTypeName);
00393
00394 RotationElements re = details->getRotationElements();
00395 re.period = _rotationPeriod;
00396 details->setRotationElements(re);
00397
00398 return details;
00399 }
00400
00401
00402 StarDetails*
00403 StarDetails::GetNormalStarDetails(StellarClass::SpectralClass specClass,
00404 unsigned int subclass,
00405 StellarClass::LuminosityClass lumClass)
00406 {
00407 if (normalStarDetails == NULL)
00408 {
00409 unsigned int nTypes = StellarClass::Spectral_Count * 11 *
00410 StellarClass::Lum_Count;
00411 normalStarDetails = new StarDetails*[nTypes];
00412 for (unsigned int i = 0; i < nTypes; i++)
00413 normalStarDetails[i] = NULL;
00414 }
00415
00416 if (subclass > StellarClass::Subclass_Unknown)
00417 subclass = StellarClass::Subclass_Unknown;
00418
00419 uint index = subclass + (specClass + lumClass * StellarClass::Spectral_Count) * 11;
00420 if (normalStarDetails[index] == NULL)
00421 {
00422 char name[16];
00423 sprintf(name, "%s%s%s",
00424 SpectralClassNames[specClass],
00425 SubclassNames[subclass],
00426 LumClassNames[lumClass]);
00427
00428
00429 if (subclass == StellarClass::Subclass_Unknown)
00430 {
00431
00432
00433
00434
00435 switch (specClass)
00436 {
00437 case StellarClass::Spectral_O:
00438 case StellarClass::Spectral_WN:
00439 case StellarClass::Spectral_WC:
00440 subclass = 9;
00441 break;
00442 default:
00443 subclass = 5;
00444 break;
00445 }
00446 }
00447
00448 unsigned int lumIndex = 0;
00449 switch (lumClass)
00450 {
00451 case StellarClass::Lum_Ia0:
00452 case StellarClass::Lum_Ia:
00453 case StellarClass::Lum_Ib:
00454 case StellarClass::Lum_II:
00455 lumIndex = 2;
00456 break;
00457 case StellarClass::Lum_III:
00458 case StellarClass::Lum_IV:
00459 lumIndex = 1;
00460 break;
00461 case StellarClass::Lum_V:
00462 case StellarClass::Lum_VI:
00463 case StellarClass::Lum_Unknown:
00464 lumIndex = 0;
00465 break;
00466 }
00467
00468 float temp = 0.0f;
00469 switch (specClass)
00470 {
00471 case StellarClass::Spectral_O:
00472 temp = tempO[lumIndex][subclass];
00473 break;
00474 case StellarClass::Spectral_B:
00475 temp = tempB[lumIndex][subclass];
00476 break;
00477 case StellarClass::Spectral_Unknown:
00478 case StellarClass::Spectral_A:
00479 temp = tempA[lumIndex][subclass];
00480 break;
00481 case StellarClass::Spectral_F:
00482 temp = tempF[lumIndex][subclass];
00483 break;
00484 case StellarClass::Spectral_G:
00485 temp = tempG[lumIndex][subclass];
00486 break;
00487 case StellarClass::Spectral_K:
00488 temp = tempK[lumIndex][subclass];
00489 break;
00490 case StellarClass::Spectral_M:
00491 temp = tempM[lumIndex][subclass];
00492 break;
00493 case StellarClass::Spectral_R:
00494 temp = tempK[lumIndex][subclass];
00495 break;
00496 case StellarClass::Spectral_S:
00497 temp = tempM[lumIndex][subclass];
00498 break;
00499 case StellarClass::Spectral_N:
00500 temp = tempM[lumIndex][subclass];
00501 break;
00502 case StellarClass::Spectral_C:
00503 temp = tempM[lumIndex][subclass];
00504 break;
00505 case StellarClass::Spectral_WN:
00506 temp = tempWN[subclass];
00507 break;
00508 case StellarClass::Spectral_WC:
00509 temp = tempWC[subclass];
00510 break;
00511 case StellarClass::Spectral_L:
00512 temp = tempL[subclass];
00513 break;
00514 case StellarClass::Spectral_T:
00515 temp = tempT[subclass];
00516 break;
00517 }
00518
00519 float bmagCorrection = 0.0f;
00520 float period = 1.0f;
00521 switch (specClass)
00522 {
00523 case StellarClass::Spectral_O:
00524 period = rotperiod_O[lumIndex][subclass];
00525 bmagCorrection = bmag_correctionO[lumIndex][subclass];
00526 break;
00527 case StellarClass::Spectral_B:
00528 period = rotperiod_B[lumIndex][subclass];
00529 bmagCorrection = bmag_correctionB[lumIndex][subclass];
00530 break;
00531 case StellarClass::Spectral_Unknown:
00532 case StellarClass::Spectral_A:
00533 period = rotperiod_A[lumIndex][subclass];
00534 bmagCorrection = bmag_correctionA[lumIndex][subclass];
00535 break;
00536 case StellarClass::Spectral_F:
00537 period = rotperiod_F[lumIndex][subclass];
00538 bmagCorrection = bmag_correctionF[lumIndex][subclass];
00539 break;
00540 case StellarClass::Spectral_G:
00541 period = rotperiod_G[lumIndex][subclass];
00542 bmagCorrection = bmag_correctionG[lumIndex][subclass];
00543 break;
00544 case StellarClass::Spectral_K:
00545 period = rotperiod_K[lumIndex][subclass];
00546 bmagCorrection = bmag_correctionK[lumIndex][subclass];
00547 break;
00548 case StellarClass::Spectral_M:
00549 period = rotperiod_M[lumIndex][subclass];
00550 bmagCorrection = bmag_correctionM[lumIndex][subclass];
00551 break;
00552
00553 case StellarClass::Spectral_R:
00554 case StellarClass::Spectral_S:
00555 case StellarClass::Spectral_N:
00556 case StellarClass::Spectral_C:
00557 period = rotperiod_M[lumIndex][subclass];
00558 bmagCorrection = bmag_correctionM[lumIndex][subclass];
00559 break;
00560
00561 case StellarClass::Spectral_WC:
00562 case StellarClass::Spectral_WN:
00563 period = rotperiod_O[lumIndex][subclass];
00564 bmagCorrection = bmag_correctionO[lumIndex][subclass];
00565 break;
00566
00567 case StellarClass::Spectral_L:
00568
00569 period = 0.2f;
00570 bmagCorrection = bmag_correctionL[subclass];
00571 break;
00572
00573 case StellarClass::Spectral_T:
00574
00575 period = 0.2f;
00576 bmagCorrection = bmag_correctionT[subclass];
00577 break;
00578 }
00579
00580 normalStarDetails[index] = CreateStandardStarType(name, temp, period);
00581 normalStarDetails[index]->setBolometricCorrection(bmagCorrection);
00582
00583 if (specClass == StellarClass::Spectral_L ||
00584 specClass == StellarClass::Spectral_T)
00585 {
00586 normalStarDetails[index]->setTexture(MultiResTexture(starTexL, starTexL, starTexL));
00587 }
00588 else
00589 {
00590 normalStarDetails[index]->setTexture(MultiResTexture(starTexA, starTexA, starTexA));
00591 }
00592 }
00593
00594 return normalStarDetails[index];
00595 }
00596
00597
00598 StarDetails*
00599 StarDetails::GetWhiteDwarfDetails(StellarClass::SpectralClass specClass,
00600 unsigned int subclass)
00601 {
00602
00603 unsigned int scIndex = static_cast<unsigned int>(specClass) -
00604 StellarClass::FirstWDClass;
00605
00606 if (whiteDwarfDetails == NULL)
00607 {
00608 unsigned int nTypes =
00609 StellarClass::WDClassCount * StellarClass::SubclassCount;
00610 whiteDwarfDetails = new StarDetails*[nTypes];
00611 for (unsigned int i = 0; i < nTypes; i++)
00612 whiteDwarfDetails[i] = NULL;
00613 }
00614
00615 if (subclass > StellarClass::Subclass_Unknown)
00616 subclass = StellarClass::Subclass_Unknown;
00617
00618 uint index = subclass + (scIndex * StellarClass::SubclassCount);
00619 if (whiteDwarfDetails[index] == NULL)
00620 {
00621 char name[16];
00622 sprintf(name, "%s%s",
00623 WDSpectralClassNames[scIndex],
00624 SubclassNames[subclass]);
00625
00626 float temp;
00627 if (subclass == 0)
00628 temp = 100000.0f;
00629 if (subclass == StellarClass::Subclass_Unknown)
00630 temp = 10080.0f;
00631 else
00632 temp = 50400.0f / subclass;
00633
00634
00635
00636 float period = 1.0f / 48.0f;
00637
00638 whiteDwarfDetails[index] = CreateStandardStarType(name, temp, period);
00639 whiteDwarfDetails[index]->setTexture(MultiResTexture(starTexA, starTexA, starTexA));
00640 }
00641
00642 return whiteDwarfDetails[index];
00643 }
00644
00645
00646 StarDetails*
00647 StarDetails::GetNeutronStarDetails()
00648 {
00649 if (neutronStarDetails == NULL)
00650 {
00651
00652
00653 neutronStarDetails = CreateStandardStarType("Q", 5000000.0f,
00654 1.0f / 86400.0f);
00655 neutronStarDetails->setRadius(10.0f);
00656 neutronStarDetails->addKnowledge(KnowRadius);
00657 neutronStarDetails->setTexture(MultiResTexture(starTexA, starTexA, starTexA));
00658 }
00659
00660 return neutronStarDetails;
00661 }
00662
00663
00664 StarDetails*
00665 StarDetails::GetBlackHoleDetails()
00666 {
00667 if (blackHoleDetails == NULL)
00668 {
00669
00670
00671
00672
00673 blackHoleDetails = CreateStandardStarType("X", 6.15e-8f,
00674 1.0f / 86400.0f);
00675 blackHoleDetails->setRadius(2.9f);
00676 blackHoleDetails->addKnowledge(KnowRadius);
00677 }
00678
00679 return blackHoleDetails;
00680 }
00681
00682
00683 StarDetails*
00684 StarDetails::GetBarycenterDetails()
00685 {
00686
00687 if (barycenterDetails == NULL)
00688 {
00689 barycenterDetails = CreateStandardStarType("Bary", 1.0f, 1.0f);
00690 barycenterDetails->setRadius(0.001f);
00691 barycenterDetails->addKnowledge(KnowRadius);
00692 barycenterDetails->setVisibility(false);
00693 }
00694
00695 return barycenterDetails;
00696 }
00697
00698
00699 void
00700 StarDetails::InitializeStarTextures()
00701 {
00702 starTexB = GetTextureManager()->getHandle(TextureInfo("bstar.jpg", 0));
00703 starTexA = GetTextureManager()->getHandle(TextureInfo("astar.jpg", 0));
00704 starTexG = GetTextureManager()->getHandle(TextureInfo("gstar.jpg", 0));
00705 starTexM = GetTextureManager()->getHandle(TextureInfo("mstar.jpg", 0));
00706 starTexL = GetTextureManager()->getHandle(TextureInfo("browndwarf.jpg", 0));
00707 }
00708
00709
00710 StarDetails::StarDetails() :
00711 radius(0.0f),
00712 temperature(0.0f),
00713 bolometricCorrection(0.0f),
00714 knowledge(0u),
00715 visible(true),
00716 model(InvalidResource),
00717 orbit(NULL),
00718 orbitalRadius(0.0f),
00719 barycenter(NULL),
00720 semiAxes(1.0f, 1.0f, 1.0f)
00721 {
00722 spectralType[0] = '\0';
00723 }
00724
00725
00726 void
00727 StarDetails::setRadius(float _radius)
00728 {
00729 radius = _radius;
00730 }
00731
00732
00733 void
00734 StarDetails::setTemperature(float _temperature)
00735 {
00736 temperature = _temperature;
00737 }
00738
00739
00740 void
00741 StarDetails::setSpectralType(const std::string& s)
00742 {
00743 strncpy(spectralType, s.c_str(), sizeof(spectralType));
00744 spectralType[sizeof(spectralType) - 1] = '\0';
00745 }
00746
00747
00748 void
00749 StarDetails::setKnowledge(uint32 _knowledge)
00750 {
00751 knowledge = _knowledge;
00752 }
00753
00754
00755 void
00756 StarDetails::addKnowledge(uint32 _knowledge)
00757 {
00758 knowledge |= _knowledge;
00759 }
00760
00761
00762 void
00763 StarDetails::setBolometricCorrection(float correction)
00764 {
00765 bolometricCorrection = correction;
00766 }
00767
00768
00769 void
00770 StarDetails::setTexture(const MultiResTexture& tex)
00771 {
00772 texture = tex;
00773 }
00774
00775
00776 void
00777 StarDetails::setModel(ResourceHandle rh)
00778 {
00779 model = rh;
00780 }
00781
00782
00783 void
00784 StarDetails::setOrbit(Orbit* o)
00785 {
00786 orbit = o;
00787 computeOrbitalRadius();
00788 }
00789
00790
00791 void
00792 StarDetails::setOrbitBarycenter(Star* bc)
00793 {
00794 barycenter = bc;
00795 computeOrbitalRadius();
00796 }
00797
00798
00799 void
00800 StarDetails::setOrbitalRadius(float r)
00801 {
00802 if (orbit != NULL)
00803 orbitalRadius = r;
00804 }
00805
00806
00807 void
00808 StarDetails::computeOrbitalRadius()
00809 {
00810 if (orbit == NULL)
00811 {
00812 orbitalRadius = 0.0f;
00813 }
00814 else
00815 {
00816 orbitalRadius = (float) astro::kilometersToLightYears(orbit->getBoundingRadius());
00817 if (barycenter != NULL)
00818 orbitalRadius += barycenter->getOrbitalRadius();
00819 }
00820 }
00821
00822
00823 void
00824 StarDetails::setVisibility(bool b)
00825 {
00826 visible = b;
00827 }
00828
00829
00830 void
00831 StarDetails::setRotationElements(const RotationElements& re)
00832 {
00833 rotationElements = re;
00834 }
00835
00836
00837
00838 float Star::getRadius() const
00839 {
00840 if (details->getKnowledge(StarDetails::KnowRadius))
00841 return details->getRadius();
00842
00843 #ifdef NO_BOLOMETRIC_MAGNITUDE_CORRECTION
00844
00845
00846 return SOLAR_RADIUS * (float) sqrt(getLuminosity()) *
00847 square(SOLAR_TEMPERATURE / getTemperature());
00848 #else
00849
00850
00851 float solarBMag = SOLAR_ABSMAG + bmag_correctionG[0][2];
00852 float bmag = getBolometricMagnitude();
00853 float boloLum = (float) exp((solarBMag - bmag) / LN_MAG);
00854
00855
00856
00857 return SOLAR_RADIUS * (float) sqrt(boloLum) *
00858 square(SOLAR_TEMPERATURE / getTemperature());
00859 #endif
00860 }
00861
00862
00863 void
00864 StarDetails::setEllipsoidSemiAxes(const Vec3f& v)
00865 {
00866 semiAxes = v;
00867 }
00868
00869
00870 UniversalCoord
00871 Star::getPosition(double t) const
00872 {
00873 const Orbit* orbit = getOrbit();
00874 if (!orbit)
00875 {
00876 return UniversalCoord(position.x * 1.0e6,
00877 position.y * 1.0e6,
00878 position.z * 1.0e6);
00879 }
00880 else
00881 {
00882 const Star* barycenter = getOrbitBarycenter();
00883
00884 if (barycenter == NULL)
00885 {
00886 Point3d barycenterPos(position.x * 1.0e6,
00887 position.y * 1.0e6,
00888 position.z * 1.0e6);
00889
00890 return UniversalCoord(barycenterPos) +
00891 ((orbit->positionAtTime(t) - Point3d(0.0, 0.0, 0.0)) *
00892 astro::kilometersToMicroLightYears(1.0));
00893 }
00894 else
00895 {
00896 return barycenter->getPosition(t) +
00897 ((orbit->positionAtTime(t) - Point3d(0.0, 0.0, 0.0)) *
00898 astro::kilometersToMicroLightYears(1.0));
00899 }
00900 }
00901 }
00902
00903
00904 MultiResTexture
00905 Star::getTexture() const
00906 {
00907 return details->getTexture();
00908 }
00909
00910
00911 ResourceHandle
00912 Star::getModel() const
00913 {
00914 return details->getModel();
00915 }
00916
00917
00918 void Star::setCatalogNumber(uint32 n)
00919 {
00920 catalogNumber = n;
00921 }
00922
00923 void Star::setPosition(float x, float y, float z)
00924 {
00925 position = Point3f(x, y, z);
00926 }
00927
00928 void Star::setPosition(Point3f p)
00929 {
00930 position = p;
00931 }
00932
00933 void Star::setAbsoluteMagnitude(float mag)
00934 {
00935 absMag = mag;
00936 }
00937
00938
00939 float Star::getApparentMagnitude(float ly) const
00940 {
00941 return astro::absToAppMag(absMag, ly);
00942 }
00943
00944
00945 float Star::getLuminosity() const
00946 {
00947 return astro::absMagToLum(absMag);
00948 }
00949
00950 void Star::setLuminosity(float lum)
00951 {
00952 absMag = astro::lumToAbsMag(lum);
00953 }
00954
00955 void Star::setDetails(StarDetails* sd)
00956 {
00957 details = sd;
00958 }
00959
00960 void Star::setOrbitBarycenter(Star* s)
00961 {
00962 details->setOrbitBarycenter(s);
00963 }
00964
00965 void Star::computeOrbitalRadius()
00966 {
00967 details->computeOrbitalRadius();
00968 }
00969
00970 void
00971 Star::setRotationElements(const RotationElements& re)
00972 {
00973 details->setRotationElements(re);
00974 }