From 7054a045cf877374ec5b0ff069ddc9fa771f5853 Mon Sep 17 00:00:00 2001 From: Allanis Date: Tue, 16 Jan 2018 20:19:13 +0000 Subject: [PATCH] [Add] Planets for stars in binary systems. Unfinished(temp wrong, culling wrong). --- src/fixed.h | 1 + src/star_system.cpp | 100 ++++++++++++++++++++++++++++---------------- src/star_system.h | 1 + 3 files changed, 67 insertions(+), 35 deletions(-) diff --git a/src/fixed.h b/src/fixed.h index 911d7d3..28857dd 100644 --- a/src/fixed.h +++ b/src/fixed.h @@ -57,6 +57,7 @@ public: friend bool operator<=(const fixed a, const fixed b) { return a.v <= b.v; } /* Implicit operator float() is bad. */ + Sint64 ToInt64(void) const { return v>>FRAC; } float ToFloat(void) const { return v/(float)(1<::iterator i = children.begin(); i != children.end(); ++i) { + (*i)->tmp = 0; + } /* Check for overlapping & unacceptably close orbits. Merge planets. */ for (std::vector::iterator i = children.begin(); i != children.end(); ++i) { + if((*i)->GetSuperType() == SUPERTYPE_STAR) continue; if((*i)->tmp) continue; for(std::vector::iterator j = children.begin(); j != children.end(); ++j) { + if((*j)->GetSuperType() == SUPERTYPE_STAR) continue; if((*j) == (*i)) continue; /* Don't eat anything bigger than self. */ if((*j)->mass > (*i)->mass) continue; @@ -451,51 +456,52 @@ StarSystem::StarSystem(int sector_x, int sector_y, int system_idx) { } /* Primary. */ - SBody* primary = new SBody; + SBody* star[4]; + SBody* centGrav1, *centGrav2; int isBinary = rand.Int32(2); if(!isBinary) { StarSystem::BodyType type = s.m_systems[system_idx].primaryStarClass; - primary->parent = NULL; - primary->name = s.m_systems[system_idx].name; - MakeStarOfType(primary, type, rand); - rootBody = primary; + star[0] = new SBody; + star[0]->parent = NULL; + star[0]->name = s.m_systems[system_idx].name; + star[0]->orbMin = 0; + star[0]->orbMax = 0; + MakeStarOfType(star[0], type, rand); + rootBody = star[0]; m_numStars = 1; } else { - SBody* centGrav = new SBody; - centGrav->type = TYPE_GRAVPOINT; - centGrav->parent = NULL; - centGrav->name = s.m_systems[system_idx].name; - rootBody = centGrav; + centGrav1 = new SBody; + centGrav1->type = TYPE_GRAVPOINT; + centGrav1->parent = NULL; + centGrav1->name = s.m_systems[system_idx].name; + rootBody = centGrav1; StarSystem::BodyType type = s.m_systems[system_idx].primaryStarClass; - SBody* star[4]; star[0] = new SBody; star[0]->name = s.m_systems[system_idx].name+" A"; - star[0]->parent = centGrav; - + star[0]->parent = centGrav1; MakeStarOfType(star[0], type, rand); star[1] = new SBody; 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); MakeBinaryPair(star[0], star[1], fixed(0), rand); - centGrav->mass = star[0]->mass + star[1]->mass; - centGrav->children.push_back(star[0]); - centGrav->children.push_back(star[1]); + centGrav1->mass = star[0]->mass + star[1]->mass; + centGrav1->children.push_back(star[0]); + centGrav1->children.push_back(star[1]); m_numStars = 2; if((star[0]->orbMax < fixed(100, 1)) && (!rand.Int32(3))) { - SBody* centGrav2; /* 3rd and maybe 4th star. */ if(!rand.Int32(2)) { star[2] = new SBody; star[2]->name = s.m_systems[system_idx].name+" C"; + star[2]->orbMin = 0; star[2]->orbMax = 0; MakeRandomStarLighterThan(star[2], star[0]->mass, rand); centGrav2 = star[2]; @@ -526,25 +532,53 @@ StarSystem::StarSystem(int sector_x, int sector_y, int system_idx) { superCentGrav->type = TYPE_GRAVPOINT; superCentGrav->parent = NULL; superCentGrav->name = s.m_systems[system_idx].name; - centGrav->parent = superCentGrav; + centGrav1->parent = superCentGrav; centGrav2->parent = superCentGrav; rootBody = superCentGrav; const fixed minDist = star[0]->orbMax + star[2]->orbMax; - MakeBinaryPair(centGrav, centGrav2, 4*minDist, rand); - superCentGrav->children.push_back(centGrav); + MakeBinaryPair(centGrav1, centGrav2, 4*minDist, rand); + superCentGrav->children.push_back(centGrav1); superCentGrav->children.push_back(centGrav2); } - return; } - /* FIXME: Not good if the enum is tampered with... */ - int disc_size = rand.Int32(6, 100) + rand.Int32(60,140)*primary->type*primary->type; - //printf("disc_size %.1fAU\n", disc_size/10.0); + for(int i = 0; i < m_numStars; i++) MakePlanetsAround(star[i]); + 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); + + /* 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* disc = AccreteDisc(disc_size, 10, rand.Int32(10,400), rand); for(unsigned int i = 0; i < disc->size(); i++) { fixed mass = fixed((*disc)[i]); 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; planet->type = TYPE_PLANET_DWARF; @@ -555,27 +589,23 @@ StarSystem::StarSystem(int sector_x, int sector_y, int system_idx) { planet->mass = mass; 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.semiMajorAxis = semiMajorAxis.ToDouble() * AU; 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) * matrix4x4d::RotateZMatrix(rand.Double(M_PI)); + planet->orbMin = orbMin; + planet->orbMax = orbMax; primary->children.push_back(planet); - - /* Perihelion and Aphelion. ( In AUs ) */ - planet->orbMin = semiMajorAxis - ecc*semiMajorAxis; - planet->orbMax = 2*semiMajorAxis - planet->orbMin; } delete disc; /* Merge children with overlapping or very close orbits. */ primary->EliminateBadChildren(); - primary->name = s.m_systems[system_idx].name; int idx = 0; for(std::vector::iterator i = primary->children.begin(); i != primary->children.end(); ++i) { + if((*i)->GetSuperType() == SUPERTYPE_STAR) continue; /* Turn them into... something! */ char buf[3]; buf[0] = ' '; @@ -586,9 +616,9 @@ StarSystem::StarSystem(int sector_x, int sector_y, int system_idx) { (*i)->PickPlanetType(primary, d, rand, true); #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)->orbit.eccentricity); + (*i)->orbit.eccentricity);*/ #endif } } diff --git a/src/star_system.h b/src/star_system.h index b4164ef..3099db5 100644 --- a/src/star_system.h +++ b/src/star_system.h @@ -127,6 +127,7 @@ public: SBody* rootBody; private: + void MakePlanetsAround(SBody* primary); void MakeRandomStar(SBody* sbody, MTRand& rand); void MakeRandomStarLighterThan(SBody* sbody, fixed maxMass, MTRand& rand); void MakeStarOfType(SBody* sbody, BodyType type, MTRand& rand);