218 lines
6.8 KiB
C++
218 lines
6.8 KiB
C++
#include "system_view.h"
|
|
#include "l3d.h"
|
|
#include "sector_view.h"
|
|
#include "star_system.h"
|
|
|
|
SystemView::SystemView(void): View() {
|
|
m_system = 0;
|
|
SetTransparency(true);
|
|
|
|
m_timePoint = new Gui::Label("");
|
|
m_timePoint->SetColor(.7, .7, .7);
|
|
Add(m_timePoint, 2, Gui::Screen::GetHeight()-Gui::Screen::GetFontHeight()-66);;
|
|
|
|
m_zoomInButton = new Gui::ImageButton("icons/zoom_in_f7.png");
|
|
m_zoomInButton->SetShortcut(SDLK_F6, KMOD_NONE);
|
|
m_zoomInButton->SetToolTip("Zoom in.");
|
|
m_rightButtonBar->Add(m_zoomInButton, 34, 2);
|
|
|
|
m_zoomOutButton = new Gui::ImageButton("icons/zoom_out_f8.png");
|
|
m_zoomOutButton->SetShortcut(SDLK_F7, KMOD_NONE);
|
|
m_zoomOutButton->SetToolTip("Zoom out.");
|
|
m_rightButtonBar->Add(m_zoomOutButton, 66, 2);
|
|
|
|
Gui::ImageButton* b = new Gui::ImageButton("icons/sysview_accel_r3.png",
|
|
"icons/sysview_accel_r3_on.png");
|
|
b->onPress.connect(sigc::bind(sigc::mem_fun(this, &SystemView::OnClickAccel), -10000000.0));
|
|
b->onRelease.connect(sigc::bind(sigc::mem_fun(this, &SystemView::OnClickAccel), 0.0));
|
|
m_rightRegion2->Add(b, 0, 0);
|
|
|
|
b = new Gui::ImageButton("icons/sysview_accel_r2.png",
|
|
"icons/sysview_accel_r2_on.png");
|
|
b->onPress.connect(sigc::bind(sigc::mem_fun(this, &SystemView::OnClickAccel), -1000000.0));
|
|
b->onRelease.connect(sigc::bind(sigc::mem_fun(this, &SystemView::OnClickAccel), 0.0));
|
|
m_rightRegion2->Add(b, 26, 0);
|
|
|
|
b = new Gui::ImageButton("icons/sysview_accel_r1.png",
|
|
"icons/sysview_accel_r1_on.png");
|
|
b->onPress.connect(sigc::bind(sigc::mem_fun(this, &SystemView::OnClickAccel), -100000.0));
|
|
b->onRelease.connect(sigc::bind(sigc::mem_fun(this, &SystemView::OnClickAccel), 0.0));
|
|
m_rightRegion2->Add(b, 45, 0);
|
|
|
|
b = new Gui::ImageButton("icons/sysview_accel_f1.png",
|
|
"icons/sysview_accel_f1_on.png");
|
|
b->onPress.connect(sigc::bind(sigc::mem_fun(this, &SystemView::OnClickAccel), 100000.0));
|
|
b->onRelease.connect(sigc::bind(sigc::mem_fun(this, &SystemView::OnClickAccel), 0.0));
|
|
m_rightRegion2->Add(b, 64, 0);
|
|
|
|
b = new Gui::ImageButton("icons/sysview_accel_f2.png",
|
|
"icons/sysview_accel_f2_on.png");
|
|
b->onPress.connect(sigc::bind(sigc::mem_fun(this, &SystemView::OnClickAccel), 1000000.0));
|
|
b->onRelease.connect(sigc::bind(sigc::mem_fun(this, &SystemView::OnClickAccel), 0.0));
|
|
m_rightRegion2->Add(b, 83, 0);
|
|
|
|
b= new Gui::ImageButton("icons/sysview_accel_f3.png",
|
|
"icons/sysview_accel_f3_on.png");
|
|
b->onPress.connect(sigc::bind(sigc::mem_fun(this, &SystemView::OnClickAccel), 10000000.0));
|
|
b->onRelease.connect(sigc::bind(sigc::mem_fun(this, &SystemView::OnClickAccel), 0.0));
|
|
m_rightRegion2->Add(b, 102, 0);
|
|
|
|
ResetViewpoint();
|
|
}
|
|
|
|
SystemView::~SystemView(void) {
|
|
|
|
}
|
|
|
|
void SystemView::OnClickAccel(float step) {
|
|
m_timeStep = step;
|
|
}
|
|
|
|
void SystemView::ResetViewpoint(void) {
|
|
m_selectedObject = 0;
|
|
m_rot_x = m_rot_z = 0;
|
|
m_zoom = 1.0f/AU;
|
|
m_timeStep = 1.0f;
|
|
m_time = L3D::GetGameTime();
|
|
}
|
|
|
|
void SystemView::PutOrbit(StarSystem::SBody* b) {
|
|
glColor3f(0, 1, 0);
|
|
glBegin(GL_LINE_LOOP);
|
|
double inc = b->orbit.period/100.0;
|
|
for(double t = 0.0; t < b->orbit.period; t += inc) {
|
|
vector3d pos = b->orbit.CartesianPosAtTime(t);
|
|
pos = pos * m_zoom;
|
|
glVertex3dv(&pos[0]);
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
void SystemView::OnClickObject(StarSystem::SBody* b, const Gui::MouseButtonEvent* ev) {
|
|
m_selectedObject = b;
|
|
}
|
|
|
|
void SystemView::PutLabel(StarSystem::SBody* b) {
|
|
GLdouble modelMatrix[16];
|
|
GLdouble projMatrix[16];
|
|
GLint viewport[4];
|
|
|
|
glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
|
|
glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
|
|
glGetIntegerv(GL_VIEWPORT, viewport);
|
|
|
|
Gui::Screen::EnterOrtho();
|
|
|
|
vector3d pos;
|
|
if(Gui::Screen::Project(0, 0, 0, modelMatrix, projMatrix, viewport, &pos[0], &pos[1], &pos[2])) {
|
|
/* libsigc++ is a lovely thing! */
|
|
Gui::Screen::PutClickableLabel(b->name, pos.x, pos.y,
|
|
sigc::bind<0>(sigc::mem_fun(this, &SystemView::OnClickObject), b));
|
|
}
|
|
|
|
Gui::Screen::LeaveOrtho();
|
|
glDisable(GL_LIGHTING);
|
|
}
|
|
|
|
/* Yeah, I'm having trouble with a suitable name. :/ idc.*/
|
|
#define ROUGH_SIZE_OF_THING 10.0
|
|
|
|
void SystemView::PutBody(StarSystem::SBody* b) {
|
|
if(b->type == StarSystem::TYPE_STARPORT_SURFACE) return;
|
|
if(b->type != StarSystem::TYPE_GRAVPOINT) {
|
|
glPointSize(5);
|
|
glColor3f(1,1,1);
|
|
glBegin(GL_POINTS);
|
|
glVertex3f(0,0,0);
|
|
glEnd();
|
|
|
|
PutLabel(b);
|
|
}
|
|
|
|
if(b->children.size())
|
|
for(std::vector<StarSystem::SBody*>::iterator kid = b->children.begin();
|
|
kid != b->children.end(); ++kid) {
|
|
if((*kid)->orbit.semiMajorAxis * m_zoom < ROUGH_SIZE_OF_THING)
|
|
PutOrbit(*kid);
|
|
|
|
glPushMatrix();
|
|
{
|
|
/* Not using current time yet. */
|
|
vector3d pos = (*kid)->orbit.CartesianPosAtTime(m_time);
|
|
pos = pos * m_zoom;
|
|
glTranslatef(pos.x, pos.y, pos.z);
|
|
PutBody(*kid);
|
|
}
|
|
glPopMatrix();
|
|
}
|
|
}
|
|
|
|
static const GLfloat fogDensity = 0.1;
|
|
static const GLfloat fogColor[4] = { 0, 0, 0, 1.0 };
|
|
|
|
void SystemView::ViewingTransformTo(StarSystem::SBody* b) {
|
|
if(b->parent) {
|
|
ViewingTransformTo(b->parent);
|
|
vector3d pos = b->orbit.CartesianPosAtTime(m_time);
|
|
pos = pos * m_zoom;
|
|
glTranslatef(-pos.x, -pos.y, -pos.z);
|
|
}
|
|
}
|
|
|
|
void SystemView::Draw3D(void) {
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
gluPerspective(50, L3D::GetScrAspect(), 1.0, 1000.0);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
glClearColor(0, 0, 0, 0);
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
int sector_x, sector_y, system_idx;
|
|
L3D::sectorView->GetSelectedSystem(§or_x, §or_y, &system_idx);
|
|
if(m_system) {
|
|
if(!m_system->IsSystem(sector_x, sector_y, system_idx)) {
|
|
delete m_system;
|
|
m_system = 0;
|
|
ResetViewpoint();
|
|
}
|
|
}
|
|
m_time += m_timeStep*L3D::GetFrameTime();
|
|
std::string t = "Time point: "+date_format(m_time);
|
|
m_timePoint->SetText(t);
|
|
|
|
if(!m_system) m_system = new StarSystem(sector_x, sector_y, system_idx);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
glEnable(GL_FOG);
|
|
glFogi(GL_FOG_MODE, GL_EXP2);
|
|
glFogfv(GL_FOG_COLOR, fogColor);
|
|
glFogf(GL_FOG_DENSITY, fogDensity);
|
|
glHint(GL_FOG_HINT, GL_NICEST);
|
|
|
|
glTranslatef(0, 0, -ROUGH_SIZE_OF_THING);
|
|
glRotatef(m_rot_x, 1, 0, 0);
|
|
glRotatef(m_rot_z, 0, 0, 1);
|
|
|
|
if(m_selectedObject) ViewingTransformTo(m_selectedObject);
|
|
if(m_system->rootBody) PutBody(m_system->rootBody);
|
|
|
|
glEnable(GL_LIGHTING);
|
|
glDisable(GL_FOG);
|
|
}
|
|
|
|
void SystemView::Update(void) {
|
|
const float ft = L3D::GetFrameTime();
|
|
if(L3D::KeyState(SDLK_EQUALS) ||
|
|
m_zoomInButton->IsPressed()) m_zoom *= pow(4.0f, ft);
|
|
if(L3D::KeyState(SDLK_MINUS) ||
|
|
m_zoomOutButton->IsPressed()) m_zoom *= pow(0.25f, ft);
|
|
if(L3D::MouseButtonState(3)) {
|
|
int motion[2];
|
|
L3D::GetMouseMotion(motion);
|
|
m_rot_x += motion[1]*20*ft;
|
|
m_rot_z += motion[0]*20*ft;
|
|
}
|
|
}
|
|
|