[Add] Planets for stars in binary systems. Unfinished(temp wrong,

culling wrong).
This commit is contained in:
Rtch90 2018-01-16 20:19:13 +00:00
parent d4462fab3c
commit 1e3c6e55ad
3 changed files with 67 additions and 35 deletions

View File

@ -57,6 +57,7 @@ public:
friend bool operator<=(const fixed a, const fixed b) { return a.v <= b.v; } friend bool operator<=(const fixed a, const fixed b) { return a.v <= b.v; }
/* Implicit operator float() is bad. */ /* Implicit operator float() is bad. */
Sint64 ToInt64(void) const { return v>>FRAC; }
float ToFloat(void) const { return v/(float)(1<<FRAC); } float ToFloat(void) const { return v/(float)(1<<FRAC); }
double ToDouble(void) const { return v/(double)(1<<FRAC); } double ToDouble(void) const { return v/(double)(1<<FRAC); }

View File

@ -272,10 +272,15 @@ double calc_orbital_period(double semiMajorAxis, double centralMass) {
} }
void StarSystem::SBody::EliminateBadChildren(void) { void StarSystem::SBody::EliminateBadChildren(void) {
for(std::vector<SBody*>::iterator i = children.begin(); i != children.end(); ++i) {
(*i)->tmp = 0;
}
/* Check for overlapping & unacceptably close orbits. Merge planets. */ /* Check for overlapping & unacceptably close orbits. Merge planets. */
for (std::vector<SBody*>::iterator i = children.begin(); i != children.end(); ++i) { for (std::vector<SBody*>::iterator i = children.begin(); i != children.end(); ++i) {
if((*i)->GetSuperType() == SUPERTYPE_STAR) continue;
if((*i)->tmp) continue; if((*i)->tmp) continue;
for(std::vector<SBody*>::iterator j = children.begin(); j != children.end(); ++j) { for(std::vector<SBody*>::iterator j = children.begin(); j != children.end(); ++j) {
if((*j)->GetSuperType() == SUPERTYPE_STAR) continue;
if((*j) == (*i)) continue; if((*j) == (*i)) continue;
/* Don't eat anything bigger than self. */ /* Don't eat anything bigger than self. */
if((*j)->mass > (*i)->mass) continue; if((*j)->mass > (*i)->mass) continue;
@ -451,51 +456,52 @@ StarSystem::StarSystem(int sector_x, int sector_y, int system_idx) {
} }
/* Primary. */ /* Primary. */
SBody* primary = new SBody; SBody* star[4];
SBody* centGrav1, *centGrav2;
int isBinary = rand.Int32(2); int isBinary = rand.Int32(2);
if(!isBinary) { if(!isBinary) {
StarSystem::BodyType type = s.m_systems[system_idx].primaryStarClass; StarSystem::BodyType type = s.m_systems[system_idx].primaryStarClass;
primary->parent = NULL; star[0] = new SBody;
primary->name = s.m_systems[system_idx].name; star[0]->parent = NULL;
MakeStarOfType(primary, type, rand); star[0]->name = s.m_systems[system_idx].name;
rootBody = primary; star[0]->orbMin = 0;
star[0]->orbMax = 0;
MakeStarOfType(star[0], type, rand);
rootBody = star[0];
m_numStars = 1; m_numStars = 1;
} else { } else {
SBody* centGrav = new SBody; centGrav1 = new SBody;
centGrav->type = TYPE_GRAVPOINT; centGrav1->type = TYPE_GRAVPOINT;
centGrav->parent = NULL; centGrav1->parent = NULL;
centGrav->name = s.m_systems[system_idx].name; centGrav1->name = s.m_systems[system_idx].name;
rootBody = centGrav; rootBody = centGrav1;
StarSystem::BodyType type = s.m_systems[system_idx].primaryStarClass; StarSystem::BodyType type = s.m_systems[system_idx].primaryStarClass;
SBody* star[4];
star[0] = new SBody; star[0] = new SBody;
star[0]->name = s.m_systems[system_idx].name+" A"; star[0]->name = s.m_systems[system_idx].name+" A";
star[0]->parent = centGrav; star[0]->parent = centGrav1;
MakeStarOfType(star[0], type, rand); MakeStarOfType(star[0], type, rand);
star[1] = new SBody; star[1] = new SBody;
star[1]->name = s.m_systems[system_idx].name+" B"; star[1]->name = s.m_systems[system_idx].name+" B";
star[1]->parent = centGrav; star[1]->parent = centGrav1;
MakeRandomStarLighterThan(star[1], star[0]->mass, rand); MakeRandomStarLighterThan(star[1], star[0]->mass, rand);
MakeBinaryPair(star[0], star[1], fixed(0), rand); MakeBinaryPair(star[0], star[1], fixed(0), rand);
centGrav->mass = star[0]->mass + star[1]->mass; centGrav1->mass = star[0]->mass + star[1]->mass;
centGrav->children.push_back(star[0]); centGrav1->children.push_back(star[0]);
centGrav->children.push_back(star[1]); centGrav1->children.push_back(star[1]);
m_numStars = 2; m_numStars = 2;
if((star[0]->orbMax < fixed(100, 1)) && if((star[0]->orbMax < fixed(100, 1)) &&
(!rand.Int32(3))) { (!rand.Int32(3))) {
SBody* centGrav2;
/* 3rd and maybe 4th star. */ /* 3rd and maybe 4th star. */
if(!rand.Int32(2)) { if(!rand.Int32(2)) {
star[2] = new SBody; star[2] = new SBody;
star[2]->name = s.m_systems[system_idx].name+" C"; star[2]->name = s.m_systems[system_idx].name+" C";
star[2]->orbMin = 0;
star[2]->orbMax = 0; star[2]->orbMax = 0;
MakeRandomStarLighterThan(star[2], star[0]->mass, rand); MakeRandomStarLighterThan(star[2], star[0]->mass, rand);
centGrav2 = star[2]; centGrav2 = star[2];
@ -526,25 +532,53 @@ StarSystem::StarSystem(int sector_x, int sector_y, int system_idx) {
superCentGrav->type = TYPE_GRAVPOINT; superCentGrav->type = TYPE_GRAVPOINT;
superCentGrav->parent = NULL; superCentGrav->parent = NULL;
superCentGrav->name = s.m_systems[system_idx].name; superCentGrav->name = s.m_systems[system_idx].name;
centGrav->parent = superCentGrav; centGrav1->parent = superCentGrav;
centGrav2->parent = superCentGrav; centGrav2->parent = superCentGrav;
rootBody = superCentGrav; rootBody = superCentGrav;
const fixed minDist = star[0]->orbMax + star[2]->orbMax; const fixed minDist = star[0]->orbMax + star[2]->orbMax;
MakeBinaryPair(centGrav, centGrav2, 4*minDist, rand); MakeBinaryPair(centGrav1, centGrav2, 4*minDist, rand);
superCentGrav->children.push_back(centGrav); superCentGrav->children.push_back(centGrav1);
superCentGrav->children.push_back(centGrav2); superCentGrav->children.push_back(centGrav2);
} }
return;
} }
/* FIXME: Not good if the enum is tampered with... */ for(int i = 0; i < m_numStars; i++) MakePlanetsAround(star[i]);
int disc_size = rand.Int32(6, 100) + rand.Int32(60,140)*primary->type*primary->type;
if(m_numStars > 1) MakePlanetsAround(centGrav1);
if(m_numStars == 4) MakePlanetsAround(centGrav2);
}
void StarSystem::MakePlanetsAround(SBody* primary) {
int disc_size = rand.Int32(6,100) + rand.Int32(60,140)*(10*primary->mass*primary->mass).ToInt64();
//printf("disc_size %.1fAU\n", disc_size/10.0); //printf("disc_size %.1fAU\n", disc_size/10.0);
/* Some restrictions on planet formation due to binary star orbits. */
fixed orbMinKill = fixed(0);
fixed orbMaxKill = fixed(disc_size, 10);
if(primary->type == TYPE_GRAVPOINT) {
SBody* star = primary->children[0];
orbMinKill = star->orbMax*10;
/*
* TODO: Need to consider triple and quadruple systems -
* the other par will obsruct also.
*/
} else if((primary->GetSuperType() == SUPERTYPE_STAR) && (primary->parent)) {
/* Limit planets out to 10% distance to stars binary companion. */
orbMaxKill = primary->orbMin * fixed(1,10);
}
printf("Kill at %f,%f AU\n", orbMinKill.ToDouble(), orbMaxKill.ToDouble());
std::vector<int>* disc = AccreteDisc(disc_size, 10, rand.Int32(10,400), rand); std::vector<int>* disc = AccreteDisc(disc_size, 10, rand.Int32(10,400), rand);
for(unsigned int i = 0; i < disc->size(); i++) { for(unsigned int i = 0; i < disc->size(); i++) {
fixed mass = fixed((*disc)[i]); fixed mass = fixed((*disc)[i]);
if(mass == 0) continue; if(mass == 0) continue;
fixed semiMajorAxis = fixed(i+1, 10); /* In AUs. */
fixed ecc = rand.NFixed(3);
/* Perihelion and Aphelion (in AUs). */
fixed orbMin = semiMajorAxis - ecc*semiMajorAxis;
fixed orbMax = 2*semiMajorAxis - orbMin;
if((orbMin < orbMinKill) || (orbMax > orbMaxKill)) continue;
SBody* planet = new SBody; SBody* planet = new SBody;
planet->type = TYPE_PLANET_DWARF; planet->type = TYPE_PLANET_DWARF;
@ -555,27 +589,23 @@ StarSystem::StarSystem(int sector_x, int sector_y, int system_idx) {
planet->mass = mass; planet->mass = mass;
planet->rotationPeriod = fixed(rand.Int32(1,200), 24); planet->rotationPeriod = fixed(rand.Int32(1,200), 24);
fixed ecc = rand.NFixed(3);
fixed semiMajorAxis = fixed(i+1, 10); /* In AUs. */
planet->orbit.eccentricity = ecc.ToDouble(); planet->orbit.eccentricity = ecc.ToDouble();
planet->orbit.semiMajorAxis = semiMajorAxis.ToDouble() * AU; planet->orbit.semiMajorAxis = semiMajorAxis.ToDouble() * AU;
planet->orbit.period = calc_orbital_period(planet->orbit.semiMajorAxis, SOL_MASS*primary->mass.ToDouble()); planet->orbit.period = calc_orbital_period(planet->orbit.semiMajorAxis, SOL_MASS*primary->mass.ToDouble());
planet->orbit.rotMatrix = matrix4x4d::RotateYMatrix(rand.NDouble(5)*M_PI/2.0) * planet->orbit.rotMatrix = matrix4x4d::RotateYMatrix(rand.NDouble(5)*M_PI/2.0) *
matrix4x4d::RotateZMatrix(rand.Double(M_PI)); matrix4x4d::RotateZMatrix(rand.Double(M_PI));
planet->orbMin = orbMin;
planet->orbMax = orbMax;
primary->children.push_back(planet); primary->children.push_back(planet);
/* Perihelion and Aphelion. ( In AUs ) */
planet->orbMin = semiMajorAxis - ecc*semiMajorAxis;
planet->orbMax = 2*semiMajorAxis - planet->orbMin;
} }
delete disc; delete disc;
/* Merge children with overlapping or very close orbits. */ /* Merge children with overlapping or very close orbits. */
primary->EliminateBadChildren(); primary->EliminateBadChildren();
primary->name = s.m_systems[system_idx].name;
int idx = 0; int idx = 0;
for(std::vector<SBody*>::iterator i = primary->children.begin(); i != primary->children.end(); ++i) { for(std::vector<SBody*>::iterator i = primary->children.begin(); i != primary->children.end(); ++i) {
if((*i)->GetSuperType() == SUPERTYPE_STAR) continue;
/* Turn them into... something! */ /* Turn them into... something! */
char buf[3]; char buf[3];
buf[0] = ' '; buf[0] = ' ';
@ -586,9 +616,9 @@ StarSystem::StarSystem(int sector_x, int sector_y, int system_idx) {
(*i)->PickPlanetType(primary, d, rand, true); (*i)->PickPlanetType(primary, d, rand, true);
#ifdef DEBUG_DUMP #ifdef DEBUG_DUMP
printf("%s: mass %f, semi-major axis %fAU, ecc %f\n", /*printf("%s: mass %f, semi-major axis %fAU, ecc %f\n",
(*i)->name.c_str(), (*i)->mass.ToDouble(), (*i)->orbit.semiMajorAxis/AU, (*i)->name.c_str(), (*i)->mass.ToDouble(), (*i)->orbit.semiMajorAxis/AU,
(*i)->orbit.eccentricity); (*i)->orbit.eccentricity);*/
#endif #endif
} }
} }

View File

@ -127,6 +127,7 @@ public:
SBody* rootBody; SBody* rootBody;
private: private:
void MakePlanetsAround(SBody* primary);
void MakeRandomStar(SBody* sbody, MTRand& rand); void MakeRandomStar(SBody* sbody, MTRand& rand);
void MakeRandomStarLighterThan(SBody* sbody, fixed maxMass, MTRand& rand); void MakeRandomStarLighterThan(SBody* sbody, fixed maxMass, MTRand& rand);
void MakeStarOfType(SBody* sbody, BodyType type, MTRand& rand); void MakeStarOfType(SBody* sbody, BodyType type, MTRand& rand);