From 96299b64f5004f9db69cc8f6a0f5a0332e8adab4 Mon Sep 17 00:00:00 2001 From: Allanis Date: Thu, 18 Jan 2018 19:28:21 +0000 Subject: [PATCH] [Change] Some gravity improvements. [Add] Apply star colours to world lighting. --- src/frame.cpp | 2 +- src/frame.h | 2 +- src/main.cpp | 2 +- src/space.cpp | 110 ++++++++++++++++++++++++++------------------ src/star.cpp | 1 + src/star.h | 2 + src/star_system.cpp | 10 ++++ src/star_system.h | 2 + src/world_view.cpp | 10 +++- 9 files changed, 92 insertions(+), 49 deletions(-) diff --git a/src/frame.cpp b/src/frame.cpp index 577ced8..6a5d23f 100644 --- a/src/frame.cpp +++ b/src/frame.cpp @@ -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; diff --git a/src/frame.h b/src/frame.h index 5e0b969..069f2f2 100644 --- a/src/frame.h +++ b/src/frame.h @@ -44,7 +44,7 @@ public: /* If parent is null then frame position is absolute. */ Frame* m_parent; std::list 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 }; diff --git a/src/main.cpp b/src/main.cpp index ed87888..1bcc509 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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)); diff --git a/src/space.cpp b/src/space.cpp index 7dc68e1..6e9b0be 100644 --- a/src/space.cpp +++ b/src/space.cpp @@ -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::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); diff --git a/src/star.cpp b/src/star.cpp index b5e620e..3ce7e05 100644 --- a/src/star.cpp +++ b/src/star.cpp @@ -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); } diff --git a/src/star.h b/src/star.h index ae16868..6572614 100644 --- a/src/star.h +++ b/src/star.h @@ -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; }; diff --git a/src/star_system.cpp b/src/star_system.cpp index 676d056..52dd5a1 100644 --- a/src/star_system.cpp +++ b/src/star_system.cpp @@ -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; diff --git a/src/star_system.h b/src/star_system.h index 3099db5..f482514 100644 --- a/src/star_system.h +++ b/src/star_system.h @@ -106,6 +106,8 @@ public: double GetRotationPeriod(void) const { return rotationPeriod.ToDouble()*60*60*24; } + + double GetMaxChildOrbitalDistance(void) const; int tmp; Orbit orbit; diff --git a/src/world_view.cpp b/src/world_view.cpp index ac0ef0b..805ea0f 100644 --- a/src/world_view.cpp +++ b/src/world_view.cpp @@ -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);