[Change] Some gravity improvements.

[Add] Apply star colours to world lighting.
This commit is contained in:
Rtch90 2018-01-18 19:28:21 +00:00
parent aa577e863d
commit 18427f1497
9 changed files with 92 additions and 49 deletions

View File

@ -18,7 +18,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_astroBody = 0;
m_parent = parent; m_parent = parent;
m_flags = flags; m_flags = flags;

View File

@ -44,7 +44,7 @@ public:
/* If parent is null then frame position is absolute. */ /* If parent is null then frame position is absolute. */
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.. */ Body* m_astroBody; /* If frame contains a star or planet or something.. */
enum { TEMP_VIEWING=1 }; enum { TEMP_VIEWING=1 };

View File

@ -209,7 +209,7 @@ void L3D::MainLoop(void) {
Frame* stationFrame = new Frame(pframe, "Station frame.."); Frame* stationFrame = new Frame(pframe, "Station frame..");
stationFrame->SetRadius(5000); stationFrame->SetRadius(5000);
stationFrame->m_sBody = 0; stationFrame->m_sbody = 0;
stationFrame->SetPosition(vector3d(0, 0, zpos)); stationFrame->SetPosition(vector3d(0, 0, zpos));
stationFrame->SetAngVelocity(vector3d(0,0,0.5)); stationFrame->SetAngVelocity(vector3d(0,0,0.5));

View File

@ -42,10 +42,10 @@ void Space::Clear(void) {
} }
void Space::MoveOrbitingObjectFrames(Frame* f) { void Space::MoveOrbitingObjectFrames(Frame* f) {
if(f->m_sBody) { if(f->m_sbody) {
/* Not too efficient. */ /* Not too efficient. */
vector3d pos = f->m_sBody->orbit.CartesianPosAtTime(L3D::GetGameTime()); vector3d pos = f->m_sbody->orbit.CartesianPosAtTime(L3D::GetGameTime());
vector3d pos2 = f->m_sBody->orbit.CartesianPosAtTime(L3D::GetGameTime()+1.0); vector3d pos2 = f->m_sbody->orbit.CartesianPosAtTime(L3D::GetGameTime()+1.0);
vector3d vel = pos2 - pos; vector3d vel = pos2 - pos;
f->SetPosition(pos); f->SetPosition(pos);
f->SetVelocity(vel); f->SetVelocity(vel);
@ -59,23 +59,36 @@ void Space::MoveOrbitingObjectFrames(Frame* f) {
static Frame* MakeFrameFor(StarSystem::SBody* sbody, Body* b, Frame* f) { static Frame* MakeFrameFor(StarSystem::SBody* sbody, Body* b, Frame* f) {
Frame* orbFrame, *rotFrame; Frame* orbFrame, *rotFrame;
double frameRadius;
if(!sbody->parent) { if(!sbody->parent) {
b->SetFrame(f); if(b) b->SetFrame(f);
f->m_sbody = sbody;
f->m_astroBody = b;
return f; return f;
} }
switch(sbody->GetSuperType()) { if(sbody->type == StarSystem::TYPE_GRAVPOINT) {
orbFrame = new Frame(f, sbody->name.c_str());
orbFrame->m_sbody = sbody;
orbFrame->m_astroBody = b;
orbFrame->SetRadius(sbody->GetMaxChildOrbitalDistance()*1.1);
return orbFrame;
}
StarSystem::BodySuperType supertype = sbody->GetSuperType();
if((supertype == StarSystem::SUPERTYPE_GAS_GIANT) ||
(supertype == StarSystem::SUPERTYPE_ROCKY_PLANET)) {
/* /*
* For planets we want a non-rotating frame for a few radii * For planets we want a non-rotating frame for a few radii
* and a rotating frame in the same position but with maybe 1.1*radius, * and a rotating frame in the same position but with maybe 1.1*radius,
* which actually contains the object. * which actually contains the object.
*/ */
case StarSystem::SUPERTYPE_GAS_GIANT: frameRadius = sbody->GetMaxChildOrbitalDistance()*1.1;
case StarSystem::SUPERTYPE_ROCKY_PLANET:
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->SetRadius(10*sbody->GetRadius()); orbFrame->SetRadius(frameRadius ? frameRadius : 10*sbody->GetRadius());
assert(sbody->GetRotationPeriod() != 0); assert(sbody->GetRotationPeriod() != 0);
rotFrame = new Frame(orbFrame, sbody->name.c_str()); rotFrame = new Frame(orbFrame, sbody->name.c_str());
@ -84,23 +97,21 @@ static Frame* MakeFrameFor(StarSystem::SBody* sbody, Body* b, Frame* f) {
rotFrame->m_astroBody = b; rotFrame->m_astroBody = b;
b->SetFrame(rotFrame); b->SetFrame(rotFrame);
return orbFrame; return orbFrame;
} else {
/* Stars want a single small non-rotating frame. */ /* Stars want a single small non-rotating frame. */
case StarSystem::SUPERTYPE_STAR:
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->m_astroBody = b;
orbFrame->SetRadius(1.2*sbody->GetRadius()); orbFrame->SetRadius(sbody->GetMaxChildOrbitalDistance()*1.1);
b->SetFrame(orbFrame); b->SetFrame(orbFrame);
return orbFrame; return orbFrame;
} }
} }
void Space::GenBody(StarSystem::SBody* sbody, Frame* f) { void Space::GenBody(StarSystem::SBody* sbody, Frame* f) {
Body* b; Body* b = 0;
if(sbody->type == StarSystem::TYPE_GRAVPOINT) goto just_make_child;
if(sbody->type != StarSystem::TYPE_GRAVPOINT) {
if(sbody->GetSuperType() == StarSystem::SUPERTYPE_STAR) { if(sbody->GetSuperType() == StarSystem::SUPERTYPE_STAR) {
Star* star = new Star(sbody); Star* star = new Star(sbody);
b = star; b = star;
@ -109,13 +120,11 @@ void Space::GenBody(StarSystem::SBody* sbody, Frame* f) {
b = planet; b = planet;
} }
b->SetLabel(sbody->name.c_str()); b->SetLabel(sbody->name.c_str());
b->SetPosition(vector3d(0,0,0)); b->SetPosition(vector3d(0,0,0));
AddBody(b);
}
f = MakeFrameFor(sbody, b, f); f = MakeFrameFor(sbody, b, f);
AddBody(b);
just_make_child:
for(std::vector<StarSystem::SBody*>::iterator i = sbody->children.begin(); for(std::vector<StarSystem::SBody*>::iterator i = sbody->children.begin();
i != sbody->children.end(); ++i) { i != sbody->children.end(); ++i) {
GenBody(*i, f); GenBody(*i, f);
@ -291,11 +300,23 @@ void Space::CollideFrame(Frame* f) {
} }
void Space::ApplyGravity(void) { void Space::ApplyGravity(void) {
/* Just to the player and only in the most stupid way for the moment. */ Body* lump = 0;
/*
* Gravity is applied when our frame contains an 'astroBody', ie a star or planet,
* or when our frame contains a rotating frame which contains this body.
*/
if(L3D::player->GetFrame()->m_astroBody) { if(L3D::player->GetFrame()->m_astroBody) {
Body* other = L3D::player->GetFrame()->m_astroBody; lump = L3D::player->GetFrame()->m_astroBody;
vector3d b1b2 = other->GetPosition() - L3D::player->GetPosition(); } else if(L3D::player->GetFrame()->m_sbody &&
const double m1m2 = L3D::player->GetMass() * other->GetMass(); (L3D::player->GetFrame()->m_children.begin() !=
L3D::player->GetFrame()->m_children.end())) {
lump = (*L3D::player->GetFrame()->m_children.begin())->m_astroBody;
}
/* Just to the player and only in the most stupid way for the moment. */
if(lump) {
vector3d b1b2 = lump->GetPosition() - L3D::player->GetPosition();
const double m1m2 = L3D::player->GetMass() * lump->GetMass();
const double r = b1b2.Length(); const double r = b1b2.Length();
const double force = G*m1m2 / (r*r); const double force = G*m1m2 / (r*r);
b1b2.Normalize(); b1b2.Normalize();
@ -306,6 +327,7 @@ void Space::ApplyGravity(void) {
void Space::TimeStep(float step) { void Space::TimeStep(float step) {
ApplyGravity(); ApplyGravity();
CollideFrame(rootFrame); CollideFrame(rootFrame);
dWorldQuickStep(world, step); dWorldQuickStep(world, step);
dJointGroupEmpty(_contactgroup); dJointGroupEmpty(_contactgroup);

View File

@ -5,6 +5,7 @@
Star::Star(StarSystem::SBody* sbody): Body() { Star::Star(StarSystem::SBody* sbody): Body() {
this->type = sbody->type; this->type = sbody->type;
radius = sbody->GetRadius(); radius = sbody->GetRadius();
mass = sbody->GetMass();
pos = vector3d(0,0,0); pos = vector3d(0,0,0);
} }

View File

@ -12,10 +12,12 @@ public:
virtual vector3d GetPosition(void); virtual vector3d GetPosition(void);
virtual double GetRadius(void) const { return radius; } virtual double GetRadius(void) const { return radius; }
virtual void Render(const Frame* camFrame); virtual void Render(const Frame* camFrame);
virtual double GetMass(void) const { return mass; }
private: private:
StarSystem::BodyType type; StarSystem::BodyType type;
vector3d pos; vector3d pos;
double radius; double radius;
double mass;
}; };

View File

@ -160,6 +160,16 @@ const char* StarSystem::SBody::GetIcon(void) {
return bodyTypeInfo[type].icon; return bodyTypeInfo[type].icon;
} }
double StarSystem::SBody::GetMaxChildOrbitalDistance(void) const {
double max = 0;
for(unsigned int i = 0; i < children.size(); i++) {
if(children[i]->orbMax.ToDouble() > max) {
max = children[i]->orbMax.ToDouble();
}
}
return AU * max;
}
static inline Sint64 isqrt(Sint64 a) { static inline Sint64 isqrt(Sint64 a) {
Sint64 ret = 0; Sint64 ret = 0;
Sint64 s; Sint64 s;

View File

@ -107,6 +107,8 @@ public:
return rotationPeriod.ToDouble()*60*60*24; return rotationPeriod.ToDouble()*60*60*24;
} }
double GetMaxChildOrbitalDistance(void) const;
int tmp; int tmp;
Orbit orbit; Orbit orbit;
int seed; /* planet.cpp can use to generate terrain. */ int seed; /* planet.cpp can use to generate terrain. */

View File

@ -6,7 +6,6 @@
#include "space_station.h" #include "space_station.h"
#include "ship_cpanel.h" #include "ship_cpanel.h"
static const float lightCol[] = { 1, 1, .9, 0 };
const float WorldView::PICK_OBJECT_RECT_SIZE = 20.0f; const float WorldView::PICK_OBJECT_RECT_SIZE = 20.0f;
#define BG_STAR_MAX 5000 #define BG_STAR_MAX 5000
@ -130,8 +129,15 @@ void WorldView::Draw3D(void) {
lightPos[1] = lpos.y; lightPos[1] = lpos.y;
lightPos[2] = lpos.z; lightPos[2] = lpos.z;
lightPos[3] = 0; lightPos[3] = 0;
const float* col = StarSystem::starColors[L3D::currentSystem->rootBody->type];
float lightCol[4] = { col[0], col[1], col[2], 0 };
float ambCol[4] = { col[0]*0.1, col[1]*0.1, col[2]*0.1, 0 };
//glColor3fv(StarSystem::starColors[(*i).primaryStarClass]);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos); glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glLightfv(GL_LIGHT0, GL_AMBIENT_AND_DIFFUSE, lightCol); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightCol);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambCol);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightCol); glLightfv(GL_LIGHT0, GL_SPECULAR, lightCol);
Space::Render(&cam_frame); Space::Render(&cam_frame);