[Add] Preliminary: Gravity for player only, when in planet frame.

This commit is contained in:
Rtch90 2018-01-17 21:53:10 +00:00
parent 1e3c6e55ad
commit aa577e863d
11 changed files with 62 additions and 15 deletions

View File

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

View File

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

View File

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

View File

@ -4,6 +4,8 @@
#include "libs.h" #include "libs.h"
#include "star_system.h" #include "star_system.h"
class Body;
/* Frame of reference. */ /* Frame of reference. */
class Frame { class Frame {
public: public:
@ -43,6 +45,7 @@ public:
Frame* m_parent; Frame* m_parent;
std::list<Frame*> m_children; std::list<Frame*> m_children;
StarSystem::SBody* m_sBody; /* Points to SBodies in L3D::current_system. */ StarSystem::SBody* m_sBody; /* Points to SBodies in L3D::current_system. */
Body* m_astroBody; /* If frame contains a star or planet or something.. */
enum { TEMP_VIEWING=1 }; enum { TEMP_VIEWING=1 };

View File

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

View File

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

View File

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

View File

@ -261,6 +261,18 @@ void Player::DrawHUD(const Frame* cam_frame) {
glPopMatrix(); glPopMatrix();
} }
/* Altitude. */
if(GetFrame()->m_astroBody) {
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, 6, 0);
Gui::Screen::RenderString(buf);
glPopMatrix();
}
Gui::Screen::LeaveOrtho(); Gui::Screen::LeaveOrtho();
} }

View File

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

View File

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

View File

@ -189,7 +189,7 @@ static double calcEnergyPerUnitAreaAtDist(double star_radius, double star_temp,
} }
/* Bond albedo, not geometric. */ /* Bond albedo, not geometric. */
static double calcSurfaceTemp(double star_radius, double star_temp, static double CalcSurfaceTemp(double star_radius, double star_temp,
double object_dist, double albedo, double object_dist, double albedo,
double greenhouse) { double greenhouse) {
@ -208,8 +208,17 @@ static fixed calcEnergyPerUnitAreaAtDist(fixed star_radius, int star_temp, fixed
return fixed(1744665451, 100000)*(total_solar_emission / (object_dist*object_dist)); 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); const fixed surface_temp_pow4 = energy_per_meter2*(1-albedo)/(1-greenhouse);
return isqrt(isqrt((surface_temp_pow4.v>>16)*4409673)); return isqrt(isqrt((surface_temp_pow4.v>>16)*4409673));
} }
@ -474,7 +483,7 @@ StarSystem::StarSystem(int sector_x, int sector_y, int system_idx) {
centGrav1 = new SBody; centGrav1 = new SBody;
centGrav1->type = TYPE_GRAVPOINT; centGrav1->type = TYPE_GRAVPOINT;
centGrav1->parent = NULL; centGrav1->parent = NULL;
centGrav1->name = s.m_systems[system_idx].name; centGrav1->name = s.m_systems[system_idx].name+" A,B";
rootBody = centGrav1; rootBody = centGrav1;
StarSystem::BodyType type = s.m_systems[system_idx].primaryStarClass; StarSystem::BodyType type = s.m_systems[system_idx].primaryStarClass;
@ -509,7 +518,7 @@ StarSystem::StarSystem(int sector_x, int sector_y, int system_idx) {
} else { } else {
centGrav2 = new SBody; centGrav2 = new SBody;
centGrav2->type = TYPE_GRAVPOINT; 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; centGrav2->orbMax = 0;
star[2] = new SBody; star[2] = new SBody;
@ -558,15 +567,14 @@ void StarSystem::MakePlanetsAround(SBody* primary) {
if(primary->type == TYPE_GRAVPOINT) { if(primary->type == TYPE_GRAVPOINT) {
SBody* star = primary->children[0]; SBody* star = primary->children[0];
orbMinKill = star->orbMax*10; 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)) { } else if((primary->GetSuperType() == SUPERTYPE_STAR) && (primary->parent)) {
/* Limit planets out to 10% distance to stars binary companion. */ /* Limit planets out to 10% distance to stars binary companion. */
orbMaxKill = primary->orbMin * fixed(1,10); 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); 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++) {
@ -636,7 +644,7 @@ void StarSystem::SBody::PickPlanetType(SBody* star, const fixed distToPrimary, M
int bbody_temp; int bbody_temp;
bool fiddle = false; bool fiddle = false;
for(int i = 0; i < 10; i++) { 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); //printf(temp %f, albedo %f, globalwarming %f\n", bbody_temp, albedo, globalwarming);
/* Extreme high temperature and low mass causes atmosphere loss. */ /* Extreme high temperature and low mass causes atmosphere loss. */
#define ATMOS_LOSS_MASS_CUTOFF 2 #define ATMOS_LOSS_MASS_CUTOFF 2
@ -658,7 +666,7 @@ void StarSystem::SBody::PickPlanetType(SBody* star, const fixed distToPrimary, M
globalwarming *= 0.2; globalwarming *= 0.2;
albedo = rand.Double(0.05) + 0.9; 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); // printf("= temp %f, albedo %f, globalwarming %f\n", bbody_temp, albedo, globalwarming);
averageTemp = bbody_temp; averageTemp = bbody_temp;
@ -684,8 +692,8 @@ void StarSystem::SBody::PickPlanetType(SBody* star, const fixed distToPrimary, M
} else if(mass < 3) { } else if(mass < 3) {
if((averageTemp > CELSIUS-10) && (averageTemp < CELSIUS+70)) { if((averageTemp > CELSIUS-10) && (averageTemp < CELSIUS+70)) {
/* Try for life.. */ /* Try for life.. */
int minTemp = calcSurfaceTemp(star->radius, star->averageTemp, orbMax, albedo, globalwarming); int minTemp = CalcSurfaceTemp(star, orbMax, albedo, globalwarming);
int maxTemp = calcSurfaceTemp(star->radius, star->averageTemp, orbMin, albedo, globalwarming); int maxTemp = CalcSurfaceTemp(star, orbMin, albedo, globalwarming);
if((minTemp > CELSIUS-10) && (minTemp < CELSIUS+70) && if((minTemp > CELSIUS-10) && (minTemp < CELSIUS+70) &&
(maxTemp > CELSIUS-10) && (maxTemp < CELSIUS+70)) { (maxTemp > CELSIUS-10) && (maxTemp < CELSIUS+70)) {
type = TYPE_PLANET_INDIGENOUS_LIFE; type = TYPE_PLANET_INDIGENOUS_LIFE;