Crappy gravity for player only, when in planet's frame.

Altitude display.
Cull planets of gravpoints better in 3,4 star systems.
Calculate surface temperature of gravpoint planets.


git-svn-id: https://pioneer.svn.sourceforge.net/svnroot/pioneer/trunk@107 e632f14b-6550-0410-b89e-a82653faca30
master
tompox 2008-08-17 11:28:25 +00:00
parent faa7f3daf2
commit 5a7a094167
11 changed files with 65 additions and 15 deletions

View File

@ -19,6 +19,7 @@ public:
virtual void SetVelocity(vector3d v) { assert(0); }
virtual vector3d GetVelocity() { assert(0); return vector3d(0.0); }
virtual double GetRadius() const = 0;
virtual double GetMass() const { assert(0); return 0; }
virtual void SetRotMatrix(const matrix4x4d &r) {};
virtual void GetRotMatrix(matrix4x4d &m) { };
virtual void Render(const Frame *camFrame) = 0;

View File

@ -21,6 +21,7 @@ public:
void SetMassDistributionFromCollMesh(const CollMesh *m);
virtual void Disable();
virtual void Enable();
virtual double GetMass() const { return m_mass.mass; }
dBodyID m_body;
dMass m_mass;

View File

@ -24,6 +24,7 @@ void Frame::RemoveChild(Frame *f)
void Frame::Init(Frame *parent, const char *label, unsigned int flags)
{
m_sbody = 0;
m_astroBody = 0;
m_parent = parent;
m_flags = flags;
m_radius = 0;

View File

@ -6,6 +6,8 @@
#include <list>
#include "StarSystem.h"
class Body;
/*
* Frame of reference.
*/
@ -44,6 +46,7 @@ public:
Frame *m_parent;
std::list<Frame*> m_children;
StarSystem::SBody *m_sbody; // points to SBodies in Pi::current_system
Body *m_astroBody; // if frame contains a star or planet or something
enum { TEMP_VIEWING=1 };
private:

View File

@ -51,7 +51,7 @@ void GenericSystemView::Draw3D()
desc = s->rootBody->GetAstroDescription();
}
m_systemName->SetText(s->rootBody->name);
m_systemName->SetText(sec.m_systems[pidx].name);
m_distance->SetText(buf);
m_starType->SetText(desc);
m_shortDesc->SetText("Short description of system");

View File

@ -9,6 +9,7 @@ Planet::Planet(StarSystem::SBody *sbody): Body()
pos = vector3d(0,0,0);
geom = dCreateSphere(0, sbody->GetRadius());
dGeomSetData(geom, static_cast<Body*>(this));
m_mass = sbody->GetMass();
this->sbody = *sbody;
this->sbody.children.clear();
this->sbody.parent = 0;

View File

@ -17,11 +17,13 @@ public:
virtual void Render(const Frame *camFrame);
virtual void SetFrame(Frame *f);
virtual bool OnCollision(Body *b, Uint32 flags) { return true; }
virtual double GetMass() const { return m_mass; }
private:
void DrawRockyPlanet();
void DrawGasGiant();
void DrawAtmosphere(double rad, vector3d &pos);
double m_mass;
vector3d pos;
dGeomID geom;
StarSystem::SBody sbody;

View File

@ -266,6 +266,19 @@ void Player::DrawHUD(const Frame *cam_frame)
glPopMatrix();
}
// altitude
if (GetFrame()->m_astroBody) {
//(GetFrame()->m_sbody->GetSuperType() == SUPERTYPE_ROCKY_PLANET)) {
double radius = GetFrame()->m_astroBody->GetRadius();
double altitude = GetPosition().Length() - radius;
char buf[128];
snprintf(buf, sizeof(buf), "Altitude: %.0f m", altitude);
glPushMatrix();
glTranslatef(400, 66, 0);
Gui::Screen::RenderString(buf);
glPopMatrix();
}
Gui::Screen::LeaveOrtho();
}

View File

@ -82,6 +82,7 @@ static Frame *MakeFrameFor(StarSystem::SBody *sbody, Body *b, Frame *f)
rotFrame = new Frame(orbFrame, sbody->name.c_str());
rotFrame->SetRadius(1.1*sbody->GetRadius());
rotFrame->SetAngVelocity(vector3d(0,2*M_PI/sbody->GetRotationPeriod(),0));
rotFrame->m_astroBody = b;
b->SetFrame(rotFrame);
return orbFrame;
// stars want a single small non-rotating frame
@ -89,6 +90,7 @@ static Frame *MakeFrameFor(StarSystem::SBody *sbody, Body *b, Frame *f)
default:
orbFrame = new Frame(f, sbody->name.c_str());
orbFrame->m_sbody = sbody;
orbFrame->m_astroBody = b;
orbFrame->SetRadius(1.2*sbody->GetRadius());
b->SetFrame(orbFrame);
return orbFrame;
@ -295,8 +297,26 @@ void Space::CollideFrame(Frame *f)
}
}
void Space::ApplyGravity()
{
// just to the player and only in the most stupid way for the moment
if (Pi::player->GetFrame()->m_astroBody) {
Body *other = Pi::player->GetFrame()->m_astroBody;
vector3d b1b2 = other->GetPosition() - Pi::player->GetPosition();
const double m1m2 = Pi::player->GetMass() * other->GetMass();
const double r = b1b2.Length();
const double force = G*m1m2 / (r*r);
b1b2.Normalize();
b1b2 = b1b2 * force;
dBodyAddForce(Pi::player->m_body, b1b2.x, b1b2.y, b1b2.z);
}
}
void Space::TimeStep(float step)
{
ApplyGravity();
CollideFrame(rootFrame);
dWorldQuickStep(world, step);
dJointGroupEmpty(_contactgroup);

View File

@ -30,6 +30,7 @@ private:
static void UpdateFramesOfReference();
static void CollideFrame(Frame *f);
static void PruneCorpses();
static void ApplyGravity();
// static std::list<Frame*> rootFrames;
static std::list<Body*> corpses;

View File

@ -178,7 +178,7 @@ static double calcEnergyPerUnitAreaAtDist(double star_radius, double star_temp,
}
// bond albedo, not geometric
static double calcSurfaceTemp(double star_radius, double star_temp, double object_dist, double albedo, double greenhouse)
static double CalcSurfaceTemp(double star_radius, double star_temp, double object_dist, double albedo, double greenhouse)
{
const double energy_per_meter2 = calcEnergyPerUnitAreaAtDist(star_radius, star_temp, object_dist);
const double surface_temp = pow(energy_per_meter2*(1-albedo)/(4*(1-greenhouse)*boltzman_const), 0.25);
@ -203,15 +203,22 @@ static fixed calcEnergyPerUnitAreaAtDist(fixed star_radius, int star_temp, fixed
return fixed(1744665451,100000)*(total_solar_emission / (object_dist*object_dist));
}
static int calcSurfaceTemp(fixed star_radius, int star_temp, fixed object_dist, fixed albedo, fixed greenhouse)
static int CalcSurfaceTemp(StarSystem::SBody *primary, fixed distToPrimary, fixed albedo, fixed greenhouse)
{
const fixed energy_per_meter2 = calcEnergyPerUnitAreaAtDist(star_radius, star_temp, object_dist);
fixed energy_per_meter2;
if (primary->type == StarSystem::TYPE_GRAVPOINT) {
// binary. take energies of both stars
energy_per_meter2 = calcEnergyPerUnitAreaAtDist(primary->children[0]->radius,
primary->children[0]->averageTemp, distToPrimary);
energy_per_meter2 += calcEnergyPerUnitAreaAtDist(primary->children[1]->radius,
primary->children[1]->averageTemp, distToPrimary);
} else {
energy_per_meter2 = calcEnergyPerUnitAreaAtDist(primary->radius, primary->averageTemp, distToPrimary);
}
const fixed surface_temp_pow4 = energy_per_meter2*(1-albedo)/(1-greenhouse);
return isqrt(isqrt((surface_temp_pow4.v>>16)*4409673));
}
void StarSystem::Orbit::KeplerPosAtTime(double t, double *dist, double *ang)
{
double e = eccentricity;
@ -488,7 +495,7 @@ StarSystem::StarSystem(int sector_x, int sector_y, int system_idx)
centGrav1 = new SBody;
centGrav1->type = TYPE_GRAVPOINT;
centGrav1->parent = NULL;
centGrav1->name = s.m_systems[system_idx].name;
centGrav1->name = s.m_systems[system_idx].name+" A,B";
rootBody = centGrav1;
StarSystem::BodyType type = s.m_systems[system_idx].primaryStarClass;
@ -523,7 +530,7 @@ StarSystem::StarSystem(int sector_x, int sector_y, int system_idx)
} else {
centGrav2 = new SBody;
centGrav2->type = TYPE_GRAVPOINT;
centGrav2->name = s.m_systems[system_idx].name;
centGrav2->name = s.m_systems[system_idx].name+" C,D";
centGrav2->orbMax = 0;
star[2] = new SBody;
@ -574,14 +581,14 @@ void StarSystem::MakePlanetsAround(SBody *primary)
if (primary->type == TYPE_GRAVPOINT) {
SBody *star = primary->children[0];
orbMinKill = star->orbMax*10;
// XXX need to consider triple and quadruple systems -
// the other pair will obstruct also
}
else if ((primary->GetSuperType() == SUPERTYPE_STAR) && (primary->parent)) {
// limit planets out to 10% distance to star's binary companion
orbMaxKill = primary->orbMin * fixed(1,10);
}
printf("kill at %f,%f AU\n", orbMinKill.ToDouble(), orbMaxKill.ToDouble());
if (m_numStars >= 3) {
orbMaxKill = MIN(orbMaxKill, fixed(5,100)*rootBody->children[0]->orbMin);
}
std::vector<int> *disc = AccreteDisc(disc_size, 10, rand.Int32(10,400), rand);
for (unsigned int i=0; i<disc->size(); i++) {
@ -652,7 +659,7 @@ void StarSystem::SBody::PickPlanetType(SBody *star, const fixed distToPrimary, M
int bbody_temp;
bool fiddle = false;
for (int i=0; i<10; i++) {
bbody_temp = calcSurfaceTemp(star->radius, star->averageTemp, distToPrimary, albedo, globalwarming);
bbody_temp = CalcSurfaceTemp(star, distToPrimary, albedo, globalwarming);
//printf("temp %f, albedo %f, globalwarming %f\n", bbody_temp, albedo, globalwarming);
// extreme high temperature and low mass causes atmosphere loss
#define ATMOS_LOSS_MASS_CUTOFF 2
@ -673,7 +680,7 @@ void StarSystem::SBody::PickPlanetType(SBody *star, const fixed distToPrimary, M
globalwarming *= 0.2;
albedo = rand.Double(0.05) + 0.9;
}
bbody_temp = calcSurfaceTemp(star->radius, star->averageTemp, distToPrimary, albedo, globalwarming);
bbody_temp = CalcSurfaceTemp(star, distToPrimary, albedo, globalwarming);
// printf("= temp %f, albedo %f, globalwarming %f\n", bbody_temp, albedo, globalwarming);
averageTemp = bbody_temp;
@ -698,8 +705,8 @@ void StarSystem::SBody::PickPlanetType(SBody *star, const fixed distToPrimary, M
} else if (mass < 3) {
if ((averageTemp > CELSIUS-10) && (averageTemp < CELSIUS+70)) {
// try for life
int minTemp = calcSurfaceTemp(star->radius, star->averageTemp, orbMax, albedo, globalwarming);
int maxTemp = calcSurfaceTemp(star->radius, star->averageTemp, orbMin, albedo, globalwarming);
int minTemp = CalcSurfaceTemp(star, orbMax, albedo, globalwarming);
int maxTemp = CalcSurfaceTemp(star, orbMin, albedo, globalwarming);
if ((minTemp > CELSIUS-10) && (minTemp < CELSIUS+70) &&
(maxTemp > CELSIUS-10) && (maxTemp < CELSIUS+70)) {