[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) {
m_sBody = 0;
m_sbody = 0;
m_astroBody = 0;
m_parent = parent;
m_flags = flags;

View File

@ -44,7 +44,7 @@ public:
/* If parent is null then frame position is absolute. */
Frame* m_parent;
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 };

View File

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

View File

@ -42,10 +42,10 @@ void Space::Clear(void) {
}
void Space::MoveOrbitingObjectFrames(Frame* f) {
if(f->m_sBody) {
if(f->m_sbody) {
/* Not too efficient. */
vector3d pos = f->m_sBody->orbit.CartesianPosAtTime(L3D::GetGameTime());
vector3d pos2 = f->m_sBody->orbit.CartesianPosAtTime(L3D::GetGameTime()+1.0);
vector3d pos = f->m_sbody->orbit.CartesianPosAtTime(L3D::GetGameTime());
vector3d pos2 = f->m_sbody->orbit.CartesianPosAtTime(L3D::GetGameTime()+1.0);
vector3d vel = pos2 - pos;
f->SetPosition(pos);
f->SetVelocity(vel);
@ -59,63 +59,72 @@ void Space::MoveOrbitingObjectFrames(Frame* f) {
static Frame* MakeFrameFor(StarSystem::SBody* sbody, Body* b, Frame* f) {
Frame* orbFrame, *rotFrame;
double frameRadius;
if(!sbody->parent) {
b->SetFrame(f);
if(b) b->SetFrame(f);
f->m_sbody = sbody;
f->m_astroBody = b;
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
* and a rotating frame in the same position but with maybe 1.1*radius,
* which actually contains the object.
*/
case StarSystem::SUPERTYPE_GAS_GIANT:
case StarSystem::SUPERTYPE_ROCKY_PLANET:
orbFrame = new Frame(f, sbody->name.c_str());
orbFrame->m_sBody = sbody;
orbFrame->SetRadius(10*sbody->GetRadius());
frameRadius = sbody->GetMaxChildOrbitalDistance()*1.1;
orbFrame = new Frame(f, sbody->name.c_str());
orbFrame->m_sbody = sbody;
orbFrame->SetRadius(frameRadius ? frameRadius : 10*sbody->GetRadius());
assert(sbody->GetRotationPeriod() != 0);
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;
assert(sbody->GetRotationPeriod() != 0);
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;
} else {
/* Stars want a single small non-rotating frame. */
case StarSystem::SUPERTYPE_STAR:
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;
orbFrame = new Frame(f, sbody->name.c_str());
orbFrame->m_sbody = sbody;
orbFrame->m_astroBody = b;
orbFrame->SetRadius(sbody->GetMaxChildOrbitalDistance()*1.1);
b->SetFrame(orbFrame);
return orbFrame;
}
}
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->GetSuperType() == StarSystem::SUPERTYPE_STAR) {
Star* star = new Star(sbody);
b = star;
} else {
Planet* planet = new Planet(sbody);
b = planet;
if(sbody->type != StarSystem::TYPE_GRAVPOINT) {
if(sbody->GetSuperType() == StarSystem::SUPERTYPE_STAR) {
Star* star = new Star(sbody);
b = star;
} else {
Planet* planet = new Planet(sbody);
b = planet;
}
b->SetLabel(sbody->name.c_str());
b->SetPosition(vector3d(0,0,0));
AddBody(b);
}
b->SetLabel(sbody->name.c_str());
b->SetPosition(vector3d(0, 0, 0));
f = MakeFrameFor(sbody, b, f);
AddBody(b);
just_make_child:
for(std::vector<StarSystem::SBody*>::iterator i = sbody->children.begin();
i != sbody->children.end(); ++i) {
GenBody(*i, f);
@ -291,11 +300,23 @@ void Space::CollideFrame(Frame* f) {
}
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) {
Body* other = L3D::player->GetFrame()->m_astroBody;
vector3d b1b2 = other->GetPosition() - L3D::player->GetPosition();
const double m1m2 = L3D::player->GetMass() * other->GetMass();
lump = L3D::player->GetFrame()->m_astroBody;
} else if(L3D::player->GetFrame()->m_sbody &&
(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 force = G*m1m2 / (r*r);
b1b2.Normalize();
@ -306,6 +327,7 @@ void Space::ApplyGravity(void) {
void Space::TimeStep(float step) {
ApplyGravity();
CollideFrame(rootFrame);
dWorldQuickStep(world, step);
dJointGroupEmpty(_contactgroup);

View File

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

View File

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

View File

@ -160,6 +160,16 @@ const char* StarSystem::SBody::GetIcon(void) {
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) {
Sint64 ret = 0;
Sint64 s;

View File

@ -106,6 +106,8 @@ public:
double GetRotationPeriod(void) const {
return rotationPeriod.ToDouble()*60*60*24;
}
double GetMaxChildOrbitalDistance(void) const;
int tmp;
Orbit orbit;

View File

@ -6,7 +6,6 @@
#include "space_station.h"
#include "ship_cpanel.h"
static const float lightCol[] = { 1, 1, .9, 0 };
const float WorldView::PICK_OBJECT_RECT_SIZE = 20.0f;
#define BG_STAR_MAX 5000
@ -130,8 +129,15 @@ void WorldView::Draw3D(void) {
lightPos[1] = lpos.y;
lightPos[2] = lpos.z;
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_AMBIENT_AND_DIFFUSE, lightCol);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightCol);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambCol);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightCol);
Space::Render(&cam_frame);