initial work on binary star systems. currently they are generated without planets and with no more than 2 stars. orbits around centre of mass should be correct. world view objects now move along their orbit rails
git-svn-id: https://pioneer.svn.sourceforge.net/svnroot/pioneer/trunk@87 e632f14b-6550-0410-b89e-a82653faca30master
parent
c675e1952b
commit
5ab5761dca
|
@ -23,6 +23,7 @@ void Frame::RemoveChild(Frame *f)
|
|||
|
||||
void Frame::Init(Frame *parent, const char *label, unsigned int flags)
|
||||
{
|
||||
sBody = 0;
|
||||
m_parent = parent;
|
||||
m_flags = flags;
|
||||
m_radius = 0;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "libs.h"
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include "StarSystem.h"
|
||||
|
||||
/*
|
||||
* Frame of reference.
|
||||
|
@ -36,6 +37,7 @@ public:
|
|||
/* if parent is null then frame position is absolute */
|
||||
Frame *m_parent;
|
||||
std::list<Frame*> m_children;
|
||||
StarSystem::SBody *sBody; // points to SBodies in Pi::current_system
|
||||
|
||||
enum { TEMP_VIEWING=1 };
|
||||
private:
|
||||
|
|
1
src/Pi.h
1
src/Pi.h
|
@ -86,6 +86,7 @@ public:
|
|||
static InfoView *infoView;
|
||||
static ShipCpanel *cpan;
|
||||
static GLUquadric *gluQuadric;
|
||||
static StarSystem *current_system;
|
||||
private:
|
||||
static void InitOpenGL();
|
||||
static void HandleEvents();
|
||||
|
|
|
@ -253,11 +253,11 @@ void Player::DrawHUD(const Frame *cam_frame)
|
|||
vector3d abs_pos = GetPositionRelTo(Space::GetRootFrame());
|
||||
const char *rel_to = (GetFrame() ? GetFrame()->GetLabel() : "System");
|
||||
snprintf(buf, sizeof(buf), "Pos: %.1f,%.1f,%.1f\n"
|
||||
"AbsPos: %.1f,%.1f,%.1f\n"
|
||||
"Rel-to: %s",
|
||||
"AbsPos: %.1f,%.1f,%.1f (%.3f AU)\n"
|
||||
"Rel-to: %s (%.0f km)",
|
||||
pos.x, pos.y, pos.z,
|
||||
abs_pos.x, abs_pos.y, abs_pos.z,
|
||||
rel_to);
|
||||
abs_pos.x, abs_pos.y, abs_pos.z, abs_pos.Length()/AU,
|
||||
rel_to, pos.Length()/1000);
|
||||
Gui::Screen::RenderString(buf);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
|
|
@ -42,9 +42,25 @@ void Space::Clear()
|
|||
Pi::player->SetFrame(rootFrame);
|
||||
}
|
||||
|
||||
void Space::GenBody(StarSystem *system, StarSystem::SBody *sbody, Frame *f)
|
||||
void Space::MoveFramesOfReference(Frame *f)
|
||||
{
|
||||
if (f->sBody) {
|
||||
vector3d pos = f->sBody->orbit.CartesianPosAtTime(Pi::GetGameTime());
|
||||
f->SetPosition(pos);
|
||||
}
|
||||
|
||||
for (std::list<Frame*>::iterator i = f->m_children.begin(); i != f->m_children.end(); ++i) {
|
||||
MoveFramesOfReference(*i);
|
||||
}
|
||||
}
|
||||
|
||||
void Space::GenBody(StarSystem::SBody *sbody, Frame *f)
|
||||
{
|
||||
Body *b;
|
||||
|
||||
// yay goto
|
||||
if (sbody->type == StarSystem::TYPE_GRAVPOINT) goto just_make_kids;
|
||||
|
||||
if (sbody->GetSuperType() == StarSystem::SUPERTYPE_STAR) {
|
||||
Star *star = new Star(sbody);
|
||||
b = star;
|
||||
|
@ -60,24 +76,27 @@ void Space::GenBody(StarSystem *system, StarSystem::SBody *sbody, Frame *f)
|
|||
vector3d pos = sbody->orbit.CartesianPosAtTime(0);
|
||||
myframe->SetPosition(pos);
|
||||
myframe->SetRadius(10*sbody->GetRadius());
|
||||
myframe->sBody = sbody;
|
||||
b->SetFrame(myframe);
|
||||
} else {
|
||||
b->SetFrame(f);
|
||||
myframe = f;
|
||||
}
|
||||
f = myframe;
|
||||
|
||||
b->SetPosition(vector3d(0,0,0));
|
||||
|
||||
AddBody(b);
|
||||
|
||||
just_make_kids:
|
||||
for (std::vector<StarSystem::SBody*>::iterator i = sbody->children.begin(); i != sbody->children.end(); ++i) {
|
||||
GenBody(system, *i, myframe);
|
||||
GenBody(*i, f);
|
||||
}
|
||||
}
|
||||
|
||||
void Space::BuildSystem(StarSystem *system)
|
||||
void Space::BuildSystem()
|
||||
{
|
||||
GenBody(system, system->rootBody, rootFrame);
|
||||
GenBody(Pi::current_system->rootBody, rootFrame);
|
||||
}
|
||||
|
||||
void Space::AddBody(Body *b)
|
||||
|
@ -228,6 +247,7 @@ void Space::TimeStep(float step)
|
|||
dJointGroupEmpty(_contactgroup);
|
||||
// XXX does not need to be done this often
|
||||
UpdateFramesOfReference();
|
||||
MoveFramesOfReference(rootFrame);
|
||||
|
||||
for (bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i) {
|
||||
(*i)->TimeStepUpdate(step);
|
||||
|
|
|
@ -13,8 +13,8 @@ class Space {
|
|||
public:
|
||||
static void Init();
|
||||
static void Clear();
|
||||
static void BuildSystem(StarSystem *s);
|
||||
static void GenBody(StarSystem *s, StarSystem::SBody *b, Frame *f);
|
||||
static void BuildSystem();
|
||||
static void GenBody(StarSystem::SBody *b, Frame *f);
|
||||
static void TimeStep(float step);
|
||||
static void AddBody(Body *);
|
||||
static void KillBody(Body *);
|
||||
|
@ -26,6 +26,7 @@ public:
|
|||
typedef std::list<Body*>::iterator bodiesIter_t;
|
||||
static Frame *rootFrame;
|
||||
private:
|
||||
static void MoveFramesOfReference(Frame *f);
|
||||
static void UpdateFramesOfReference();
|
||||
static void CollideFrame(Frame *f);
|
||||
static void PruneCorpses();
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
#define DEBUG_DUMP
|
||||
|
||||
// indexed by enum type turd
|
||||
float StarSystem::starColors[7][3] = {
|
||||
float StarSystem::starColors[][3] = {
|
||||
{ 0, 0, 0 }, // gravpoint
|
||||
{ 1.0, 0.2, 0.0 }, // M
|
||||
{ 1.0, 0.6, 0.1 }, // K
|
||||
{ 1.0, 1.0, 0.4 }, // G
|
||||
|
@ -25,6 +26,8 @@ static const struct SBodySubTypeInfo {
|
|||
int tempMin, tempMax;
|
||||
} bodyTypeInfo[StarSystem::TYPE_MAX] = {
|
||||
{
|
||||
StarSystem::SUPERTYPE_NONE, 0, 0, "Shouldn't see this!",
|
||||
}, {
|
||||
StarSystem::SUPERTYPE_STAR,
|
||||
40, 50, "Type 'M' red star",
|
||||
"icons/object_star_m.png",
|
||||
|
@ -394,14 +397,82 @@ StarSystem::StarSystem(int sector_x, int sector_y, int system_idx)
|
|||
// primary
|
||||
SBody *primary = new SBody;
|
||||
|
||||
StarSystem::BodyType type = s.m_systems[system_idx].primaryStarClass;
|
||||
primary->type = type;
|
||||
primary->parent = NULL;
|
||||
primary->radius = fixed(bodyTypeInfo[type].radius, 100);
|
||||
primary->mass = fixed(bodyTypeInfo[type].mass, 100);
|
||||
primary->averageTemp = rand.Int32(bodyTypeInfo[type].tempMin,
|
||||
bodyTypeInfo[type].tempMax);
|
||||
rootBody = primary;
|
||||
int isBinary = rand.Int32(2);
|
||||
if (!isBinary) {
|
||||
StarSystem::BodyType type = s.m_systems[system_idx].primaryStarClass;
|
||||
primary->type = type;
|
||||
primary->parent = NULL;
|
||||
primary->radius = fixed(bodyTypeInfo[type].radius, 100);
|
||||
primary->mass = fixed(bodyTypeInfo[type].mass, 100);
|
||||
primary->averageTemp = rand.Int32(bodyTypeInfo[type].tempMin,
|
||||
bodyTypeInfo[type].tempMax);
|
||||
primary->name = s.m_systems[system_idx].name;
|
||||
rootBody = primary;
|
||||
} else {
|
||||
SBody *centGrav = new SBody;
|
||||
centGrav->type = TYPE_GRAVPOINT;
|
||||
centGrav->parent = NULL;
|
||||
centGrav->name = s.m_systems[system_idx].name;
|
||||
rootBody = centGrav;
|
||||
|
||||
fixed ecc = rand.NFixed(3);
|
||||
StarSystem::BodyType type = s.m_systems[system_idx].primaryStarClass;
|
||||
SBody *star[2];
|
||||
star[0] = new SBody;
|
||||
star[0]->type = type;
|
||||
star[0]->name = s.m_systems[system_idx].name+" A";
|
||||
star[0]->parent = centGrav;
|
||||
star[0]->radius = fixed(bodyTypeInfo[type].radius, 100);
|
||||
star[0]->mass = fixed(bodyTypeInfo[type].mass, 100);
|
||||
star[0]->averageTemp = rand.Int32(bodyTypeInfo[type].tempMin,
|
||||
bodyTypeInfo[type].tempMax);
|
||||
|
||||
// normally star types are picked by spectral class distribution in
|
||||
// our galactic neighbourhood. in binary systems instead just pick
|
||||
// random companion types up to spectral class of primary.
|
||||
StarSystem::BodyType type2 = (BodyType)rand.Int32(TYPE_STAR_M, type);
|
||||
star[1] = new SBody;
|
||||
star[1]->type = type2;
|
||||
star[1]->name = s.m_systems[system_idx].name+" B";
|
||||
star[1]->parent = centGrav;
|
||||
star[1]->radius = fixed(bodyTypeInfo[type2].radius, 100);
|
||||
star[1]->mass = fixed(bodyTypeInfo[type2].mass, 100);
|
||||
star[1]->averageTemp = rand.Int32(bodyTypeInfo[type2].tempMin,
|
||||
bodyTypeInfo[type2].tempMax);
|
||||
fixed m = star[0]->mass + star[1]->mass;
|
||||
fixed a0 = star[1]->mass / m;
|
||||
fixed a1 = star[0]->mass / m;
|
||||
fixed semiMajorAxis;
|
||||
|
||||
switch (rand.Int32(3)) {
|
||||
case 2: semiMajorAxis = fixed(rand.Int32(100,10000), 100); break;
|
||||
case 1: semiMajorAxis = fixed(rand.Int32(10,1000), 100); break;
|
||||
default:
|
||||
case 0: semiMajorAxis = fixed(rand.Int32(1,100), 100); break;
|
||||
}
|
||||
printf("Binary separation: %.2fAU\n", semiMajorAxis.ToDouble());
|
||||
|
||||
star[0]->orbit.eccentricity = ecc.ToDouble();
|
||||
star[0]->orbit.semiMajorAxis = AU * (semiMajorAxis * a0).ToDouble();
|
||||
star[0]->orbit.period = 60*60*24*365* semiMajorAxis.ToDouble() * sqrt(semiMajorAxis.ToDouble() / m.ToDouble());
|
||||
star[0]->orbit.rotMatrix = matrix4x4d::RotateZMatrix(M_PI);
|
||||
|
||||
star[1]->orbit.eccentricity = ecc.ToDouble();
|
||||
star[1]->orbit.semiMajorAxis = AU * (semiMajorAxis * a1).ToDouble();
|
||||
star[1]->orbit.period = star[0]->orbit.period;
|
||||
star[1]->orbit.rotMatrix = matrix4x4d::Identity();
|
||||
|
||||
fixed radMin = semiMajorAxis - ecc*semiMajorAxis;
|
||||
fixed radMax = 2*semiMajorAxis - radMin;
|
||||
star[0]->radMin = radMin;
|
||||
star[1]->radMin = radMin;
|
||||
star[0]->radMax = radMax;
|
||||
star[1]->radMax = radMax;
|
||||
|
||||
centGrav->children.push_back(star[0]);
|
||||
centGrav->children.push_back(star[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX bad if the enum is fiddled with........
|
||||
int disc_size = rand.Int32(6,100) + rand.Int32(60,140)*primary->type*primary->type;
|
||||
|
|
|
@ -26,6 +26,7 @@ struct CustomSBody;
|
|||
|
||||
class StarSystem {
|
||||
public:
|
||||
StarSystem() { rootBody = 0; }
|
||||
StarSystem(int sector_x, int sector_y, int system_idx);
|
||||
~StarSystem();
|
||||
bool IsSystem(int sector_x, int sector_y, int system_idx);
|
||||
|
@ -34,7 +35,7 @@ public:
|
|||
*sec_x = loc.secX; *sec_y = loc.secY; *sys_idx = loc.sysIdx;
|
||||
}
|
||||
|
||||
static float starColors[7][3];
|
||||
static float starColors[][3];
|
||||
|
||||
struct Orbit {
|
||||
void KeplerPosAtTime(double t, double *dist, double *ang);
|
||||
|
@ -46,6 +47,7 @@ public:
|
|||
};
|
||||
|
||||
enum BodyType {
|
||||
TYPE_GRAVPOINT,
|
||||
TYPE_STAR_M,
|
||||
TYPE_STAR_K,
|
||||
TYPE_STAR_G,
|
||||
|
|
|
@ -57,22 +57,48 @@ void SystemInfoView::SystemChanged(StarSystem *s)
|
|||
{
|
||||
DeleteAllChildren();
|
||||
float csize[2];
|
||||
int majorBodies = 0;
|
||||
GetSize(csize);
|
||||
|
||||
float xpos = 0;
|
||||
float size[2];
|
||||
Gui::ImageButton *ib = new Gui::ImageButton(s->rootBody->GetIcon());
|
||||
ib->GetSize(size);
|
||||
ib->onClick.connect(sigc::bind(sigc::mem_fun(this, &SystemInfoView::OnBodySelected), s->rootBody));
|
||||
Add(ib, 0, csize[1] - size[1]);
|
||||
xpos += size[0];
|
||||
float ycent = csize[1] - size[1]*0.5;
|
||||
float ycent;
|
||||
std::vector<StarSystem::SBody*>::iterator i = s->rootBody->children.begin();
|
||||
|
||||
for (std::vector<StarSystem::SBody*>::iterator i = s->rootBody->children.begin(); i != s->rootBody->children.end(); ++i) {
|
||||
if (s->rootBody->type == StarSystem::TYPE_GRAVPOINT) {
|
||||
// binary system
|
||||
Gui::ImageButton *ib = new Gui::ImageButton((*i)->GetIcon());
|
||||
ib->GetSize(size);
|
||||
ib->onClick.connect(sigc::bind(sigc::mem_fun(this, &SystemInfoView::OnBodySelected), *i));
|
||||
Add(ib, 0, csize[1] - size[1]);
|
||||
float yoffset = size[1];
|
||||
float xoffset = size[0];
|
||||
++i; majorBodies++;
|
||||
|
||||
ib = new Gui::ImageButton((*i)->GetIcon());
|
||||
ib->GetSize(size);
|
||||
ib->onClick.connect(sigc::bind(sigc::mem_fun(this, &SystemInfoView::OnBodySelected), *i));
|
||||
Add(ib, 0, csize[1] - size[1] - yoffset);
|
||||
++i; majorBodies++;
|
||||
|
||||
xpos += xoffset;
|
||||
ycent = csize[1] - yoffset*0.5;
|
||||
} else {
|
||||
Gui::ImageButton *ib = new Gui::ImageButton(s->rootBody->GetIcon());
|
||||
ib->GetSize(size);
|
||||
ib->onClick.connect(sigc::bind(sigc::mem_fun(this, &SystemInfoView::OnBodySelected), s->rootBody));
|
||||
Add(ib, 0, csize[1] - size[1]);
|
||||
xpos += size[0];
|
||||
ycent = csize[1] - size[1]*0.5;
|
||||
majorBodies++;
|
||||
}
|
||||
|
||||
for (; i != s->rootBody->children.end(); ++i) {
|
||||
Gui::ImageButton *ib = new Gui::ImageButton((*i)->GetIcon());
|
||||
ib->GetSize(size);
|
||||
ib->onClick.connect(sigc::bind(sigc::mem_fun(this, &SystemInfoView::OnBodySelected), *i));
|
||||
Add(ib, xpos, ycent - 0.5*size[1]);
|
||||
majorBodies++;
|
||||
|
||||
float moon_ypos = ycent - size[1] - 5;
|
||||
if ((*i)->children.size()) for(std::vector<StarSystem::SBody*>::iterator moon = (*i)->children.begin(); moon != (*i)->children.end(); ++moon) {
|
||||
|
@ -87,7 +113,7 @@ void SystemInfoView::SystemChanged(StarSystem *s)
|
|||
}
|
||||
|
||||
char buf[512];
|
||||
snprintf(buf, sizeof(buf), "Stable system with %d major bodies.", 1+s->rootBody->children.size());
|
||||
snprintf(buf, sizeof(buf), "Stable system with %d major bodies.", majorBodies);
|
||||
m_infoText = new Gui::Label(buf);
|
||||
m_infoText->SetColor(1,1,0);
|
||||
Add(m_infoText, 50, 200);
|
||||
|
|
|
@ -117,13 +117,15 @@ void SystemView::PutLabel(StarSystem::SBody *b)
|
|||
|
||||
void SystemView::PutBody(StarSystem::SBody *b)
|
||||
{
|
||||
glPointSize(5);
|
||||
glColor3f(1,1,1);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3f(0,0,0);
|
||||
glEnd();
|
||||
if (b->type != StarSystem::TYPE_GRAVPOINT) {
|
||||
glPointSize(5);
|
||||
glColor3f(1,1,1);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex3f(0,0,0);
|
||||
glEnd();
|
||||
|
||||
PutLabel(b);
|
||||
PutLabel(b);
|
||||
}
|
||||
|
||||
if (b->children.size()) for(std::vector<StarSystem::SBody*>::iterator kid = b->children.begin(); kid != b->children.end(); ++kid) {
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ void WorldView::Draw3D()
|
|||
|
||||
void WorldView::Update()
|
||||
{
|
||||
if (Pi::GetSelectedSystem() /* && isn't current system */ ) {
|
||||
if (Pi::GetSelectedSystem() && !Pi::player->GetDockedWith()/* && isn't current system */ ) {
|
||||
m_hyperspaceButton->Show();
|
||||
} else {
|
||||
m_hyperspaceButton->Hide();
|
||||
|
|
|
@ -44,6 +44,7 @@ SystemView *Pi::system_view;
|
|||
SystemInfoView *Pi::system_info_view;
|
||||
ShipCpanel *Pi::cpan;
|
||||
StarSystem *Pi::selected_system;
|
||||
StarSystem *Pi::current_system;
|
||||
MTRand Pi::rng;
|
||||
double Pi::gameTime;
|
||||
float Pi::frameTime;
|
||||
|
@ -317,8 +318,14 @@ StarSystem *Pi::GetSelectedSystem()
|
|||
|
||||
void Pi::HyperspaceTo(StarSystem *dest)
|
||||
{
|
||||
int sec_x, sec_y, sys_idx;
|
||||
dest->GetPos(&sec_x, &sec_y, &sys_idx);
|
||||
|
||||
if (current_system) delete current_system;
|
||||
current_system = new StarSystem(sec_x, sec_y, sys_idx);
|
||||
|
||||
Space::Clear();
|
||||
Space::BuildSystem(dest);
|
||||
Space::BuildSystem();
|
||||
float ang = rng.Double(M_PI);
|
||||
Pi::player->SetPosition(vector3d(sin(ang)*8*AU,cos(ang)*8*AU,0));
|
||||
dest->GetPos(&Pi::playerLoc);
|
||||
|
|
Loading…
Reference in New Issue