From a66869c16f81d75f1e84d9a984f683b092d74c5c Mon Sep 17 00:00:00 2001
From: Allanis <allanis.saracraft.studios@gmail.com>
Date: Sun, 7 Jan 2018 14:59:56 +0000
Subject: [PATCH] [Change] More rotating frame work. Looks pretty nice now..

---
 src/main.cpp               | 16 ++++++++--------
 src/model_body.cpp         | 21 +++++++++------------
 src/model_body.h           |  1 -
 src/object_viewer_view.cpp | 22 ++++++----------------
 src/object_viewer_view.h   |  1 -
 src/planet.cpp             |  9 ++++++++-
 src/player.cpp             | 36 ++++++++++++++----------------------
 src/player.h               |  2 +-
 src/ship.cpp               | 20 ++++++++++++++------
 src/ship.h                 |  2 ++
 src/world_view.cpp         | 21 +++++++++++++++++----
 src/world_view.h           |  1 -
 12 files changed, 79 insertions(+), 73 deletions(-)

diff --git a/src/main.cpp b/src/main.cpp
index d972e74..4f697c4 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -195,22 +195,22 @@ void L3D::MainLoop(void) {
   const float zpos = EARTH_RADIUS * 1;
   Frame* pframe = *(Space::rootFrame->m_children.begin());
 
+  Frame* stationFrame = new Frame(pframe, "Station frame..");
+  stationFrame->SetRadius(5000);
+  stationFrame->sBody = 0;
+  stationFrame->SetPosition(vector3d(0, 0, zpos));
+  stationFrame->SetAngVelocity(vector3d(0,0,0.5));
+
   for(int i = 0; i < 4; i++) {
     Ship* body = new Ship(ShipType::SLEEK/*LADYBIRD*/);
     char buf[64];
     snprintf(buf, sizeof(buf), "X%c-0%02d", "A"+i, i);
     body->SetLabel(buf);
-    body->SetFrame(pframe);
-    body->SetPosition(vector3d(i*2000, zpos*0.1, zpos+1000));
+    body->SetFrame(stationFrame);
+    body->SetPosition(vector3d(200*(i+1), 0, 2000));
     Space::AddBody(body);
   }
 
-  Frame* stationFrame = new Frame(pframe, "Station frame...");
-  stationFrame->SetRadius(5000);
-  stationFrame->sBody = 0;
-  stationFrame->SetPosition(vector3d(0,0,zpos));
-  stationFrame->SetAngVelocity(vector3d(0,0,0.5));
-
   SpaceStation* station = new SpaceStation();
   station->SetLabel("Poemi-chan's Folly");
   station->SetFrame(stationFrame);
diff --git a/src/model_body.cpp b/src/model_body.cpp
index 35d0475..dd316a3 100644
--- a/src/model_body.cpp
+++ b/src/model_body.cpp
@@ -100,22 +100,18 @@ void ModelBody::GetRotMatrix(matrix4x4d& m) {
   m.LoadFromOdeMatrix(dGeomGetRotation(geoms[0]));
 }
 
-void ModelBody::ViewingRotation(void) {
-  matrix4x4d m;
-  GetRotMatrix(m);
-  m = m.InverseOf();
-  glMultMatrixd(&m[0]);
-}
-
 void ModelBody::TransformToModelCoords(const Frame* camFrame) {
-  vector3d fpos = GetPositionRelTo(camFrame);
-
+  const vector3d pos = GetPosition();
   const dReal* r = dGeomGetRotation(geoms[0]);
   matrix4x4d m;
+
+  Frame::GetFrameTransform(GetFrame(), camFrame, m);
+  glMultMatrixd(&m[0]);
+
   m[ 0] = r[ 0]; m[ 1] = r[ 4]; m[ 2] = r[ 8]; m[ 3] = 0;
   m[ 4] = r[ 1]; m[ 5] = r[ 5]; m[ 6] = r[ 9]; m[ 7] = 0;
   m[ 8] = r[ 2]; m[ 9] = r[ 6]; m[10] = r[10]; m[11] = 0;
-  m[12] = fpos.x; m[13] = fpos.y; m[14] = fpos.z; m[15] = 1;
+  m[12] = pos.x; m[13] = pos.y; m[14] = pos.z; m[15] = 1;
   glMultMatrixd(&m[0]);
 }
 
@@ -172,11 +168,12 @@ void ModelBody::RenderSbreModel(const Frame* camFrame, int model, ObjParams* par
   Frame::GetFrameTransform(GetFrame(), camFrame, frameTrans);
 
   vector3d pos = GetPosition();
-  pos = L3D::world_view->viewingRotation * frameTrans * pos;
+  pos = frameTrans * pos;
   Vector p; p.x = pos.x; p.y = pos.y; p.z = -pos.z;
   matrix4x4d rot;
   rot.LoadFromOdeMatrix(dGeomGetRotation(geoms[0]));
-  rot = L3D::world_view->viewingRotation * frameTrans * rot;
+  frameTrans.ClearToRotOnly();
+  rot = frameTrans * rot;
   Matrix m;
   m.x1 =  rot[0]; m.x2 =  rot[4]; m.x3 = -rot[8];
   m.y1 =  rot[1]; m.y2 =  rot[5]; m.y3 = -rot[9];
diff --git a/src/model_body.h b/src/model_body.h
index 78d6088..3d51172 100644
--- a/src/model_body.h
+++ b/src/model_body.h
@@ -17,7 +17,6 @@ public:
   vector3d GetPosition(void);
   virtual double GetRadius(void) const;
   void TransformToModelCoords(const Frame* camFrame);
-  void ViewingRotation(void);
   void GetRotMatrix(matrix4x4d& m);
   virtual void SetFrame(Frame* f);
   void GeomsSetBody(dBodyID body);
diff --git a/src/object_viewer_view.cpp b/src/object_viewer_view.cpp
index 00c815f..34b39ac 100644
--- a/src/object_viewer_view.cpp
+++ b/src/object_viewer_view.cpp
@@ -7,7 +7,6 @@
 
 ObjectViewerView::ObjectViewerView(void) : View() {
   SetTransparency(true);
-  viewingRotation = matrix4x4d::Identity();
   viewingDist = 1000.0f;
 
   m_infoLabel = new Gui::Label("");
@@ -26,27 +25,18 @@ void ObjectViewerView::Draw3D(void) {
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
 
-  vector3d pos = vector3d(0, 0, viewingDist);
-  //p = matrix4x4d::RotateXMatrix(-DEG_2_RAD*m_external_view_rotx) * p;
-  pos = matrix4x4d::RotateYMatrix(-DEG_2_RAD*rot) * pos;
-  pos = matrix4x4d::RotateXMatrix(-DEG_2_RAD*rot) * pos;
+  matrix4x4d camRot;
+  camRot = matrix4x4d::RotateXMatrix(-DEG2RAD(rot));
+  camRot = matrix4x4d::RotateYMatrix(-DEG2RAD(rot)) * camRot;
+  vector3d pos = camRot * vector3d(0,0,viewingDist);
 
-  float lightPos[4];
-  lightPos[0] = 1;
-  lightPos[1] = 1;
-  lightPos[2] = 1;
-  lightPos[3] = 0;
+  float lightPos[4] = { 1, 1, 1, 0 };
   glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
 
-  /* SBRE rendering (See ModelBody.cpp) uses this.. */
-  glRotatef(-rot, 0, 1, 0);
-  glRotatef(-rot, 1, 0, 0);
-  //L3D::world_view->viewingRotation = matrix4x4d::Identity();
-  glGetDoublev(GL_MODELVIEW_MATRIX, &L3D::world_view->viewingRotation[0]);
-
   Body* body = L3D::player->GetNavTarget();
   if(body) {
     Frame cam_frame(body->GetFrame(), "", Frame::TEMP_VIEWING);
+    cam_frame.SetOrientation(camRot);
     cam_frame.SetPosition(body->GetPosition()+pos);
     body->Render(&cam_frame);
     body->GetFrame()->RemoveChild(&cam_frame);
diff --git a/src/object_viewer_view.h b/src/object_viewer_view.h
index f2dbfbb..535d3a6 100644
--- a/src/object_viewer_view.h
+++ b/src/object_viewer_view.h
@@ -11,7 +11,6 @@ public:
   virtual void Update(void);
   virtual void Draw3D(void);
 private:
-  matrix4x4d viewingRotation;
   float viewingDist;
   Gui::Label* m_infoLabel;
   const Body* lastTarget;
diff --git a/src/planet.cpp b/src/planet.cpp
index 35a7fc8..8add198 100644
--- a/src/planet.cpp
+++ b/src/planet.cpp
@@ -831,7 +831,9 @@ void Planet::Render(const Frame* a_camFrame) {
   glPushMatrix();
 
   double rad = sbody.GetRadius();
-  vector3d fpos = GetPositionRelTo(a_camFrame);
+  matrix4x4d ftran;
+  Frame::GetFrameTransform(GetFrame(), a_camFrame, ftran);
+  vector3d fpos = ftran * GetPosition();
 
   double apparent_size = rad / fpos.Length();
   double len = fpos.Length();
@@ -845,6 +847,9 @@ void Planet::Render(const Frame* a_camFrame) {
   glTranslatef(fpos.x, fpos.y, fpos.z);
   glColor3f(1, 1, 1);
 
+  ftran.ClearToRotOnly();
+  glMultMatrixd(&ftran[0]);
+
   if(apparent_size < 0.001) {
     if(crudDList) {
       glDeleteLists(crudDList, 1);
@@ -873,6 +878,8 @@ void Planet::Render(const Frame* a_camFrame) {
     glCallList(crudDList);
     glPopMatrix();
 
+    fpos = ftran.InverseOf() * fpos;
+
     DrawAtmosphere(rad, fpos);
 
     glClear(GL_DEPTH_BUFFER_BIT);
diff --git a/src/player.cpp b/src/player.cpp
index a278198..cccfdf8 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -6,8 +6,6 @@
 #include "world_view.h"
 #include "space_station_view.h"
 
-#define DEG_2_RAD 0.0174532925
-
 Player::Player(ShipType::Type shipType) : Ship(shipType) {
   m_external_view_rotx = m_external_view_roty = 0;
   m_external_view_dist = 200;
@@ -27,7 +25,6 @@ void Player::Render(const Frame* camFrame) {
   } else {
     glPushMatrix();
     /* Could only rotate, since transform is zero (camFrame is at player origin). */
-    TransformToModelCoords(camFrame);
     RenderLaserfire();
     glPopMatrix();
   }
@@ -42,8 +39,8 @@ void Player::SetDockedWith(SpaceStation* s) {
 
 vector3d Player::GetExternalViewTranslation(void) {
   vector3d p = vector3d(0, 0, m_external_view_dist);
-  p = matrix4x4d::RotateXMatrix(-DEG_2_RAD*m_external_view_rotx) * p;
-  p = matrix4x4d::RotateYMatrix(-DEG_2_RAD*m_external_view_roty) * p;
+  p = matrix4x4d::RotateXMatrix(-DEG2RAD(m_external_view_rotx)) * p;
+  p = matrix4x4d::RotateYMatrix(-DEG2RAD(m_external_view_roty)) * p;
   matrix4x4d m;
   GetRotMatrix(m);
   p = m*p;
@@ -51,10 +48,9 @@ vector3d Player::GetExternalViewTranslation(void) {
   return p;
 }
 
-void Player::ApplyExternalViewRotation(void) {
-  //glTranslatef(0, 0, m_external_view_dist);
-  glRotatef(-m_external_view_rotx, 1, 0, 0);
-  glRotatef(-m_external_view_roty, 0, 1, 0);
+void Player::ApplyExternalViewRotation(matrix4x4d& m) {
+  m = matrix4x4d::RotateXMatrix(-DEG2RAD(m_external_view_rotx)) * m;
+  m = matrix4x4d::RotateYMatrix(-DEG2RAD(m_external_view_roty)) * m;
 }
 
 void Player::TimeStepUpdate(const float timeStep) {
@@ -169,21 +165,16 @@ void Player::DrawHUD(const Frame* cam_frame) {
   glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
   glGetIntegerv(GL_VIEWPORT, viewport);
 
-  const dReal* vel = dBodyGetLinearVel(m_body);
-
-  const matrix4x4d& rot = L3D::world_view->viewingRotation;
-  vector3d loc_v = rot*vector3d(vel[0], vel[1], vel[2]);
-
   Gui::Screen::EnterOrtho();
   glColor3f(.7, .7, .7);
 
+  /* Object labels. */
   {
     for(std::list<Body*>::iterator i = Space::bodies.begin(); i != Space::bodies.end(); ++i) {
       if((L3D::GetCamType() != L3D::CAM_EXTERNAL) && (*i == this)) continue;
       Body* b = *i;
       vector3d _pos = b->GetPositionRelTo(cam_frame);
-      vector3d cam_coord = rot*_pos;
-      if(cam_coord.z < 0
+      if(_pos.z < 0
           && Gui::Screen::Project(_pos.x,_pos.y,_pos.z,modelMatrix,projMatrix,viewport,
                                   &_pos.x, &_pos.y, &_pos.z)) {
         b->SetProjectedPos(_pos);
@@ -196,13 +187,14 @@ void Player::DrawHUD(const Frame* cam_frame) {
 
   DrawTargetSquares();
 
-  GLdouble pos[3];
-
+  /* Direction indicator. */
   const float sz = HUD_CROSSHAIR_SIZE;
-  /* If velocity vector is in front ofus. Draw indicator. */
+  const dReal* vel = dBodyGetLinearVel(m_body);
+  vector3d loc_v = cam_frame->GetOrientation().InverseOf() * vector3d(vel[0], vel[1], vel[2]);
   if(loc_v.z < 0) {
-    if(Gui::Screen::Project(vel[0],vel[1],vel[2], modelMatrix, projMatrix, viewport,
-                            &pos[0], &pos[1], &pos[2])) {
+    GLdouble pos[3];
+    if(Gui::Screen::Project(loc_v[0], loc_v[1], loc_v[2], modelMatrix, projMatrix,
+          viewport, &pos[0], &pos[1], &pos[2])) {
       glBegin(GL_LINES);
         glVertex2f(pos[0]-sz, pos[1]-sz);
         glVertex2f(pos[0]-0.5*sz, pos[1]-0.5*sz);
@@ -219,8 +211,8 @@ void Player::DrawHUD(const Frame* cam_frame) {
     }
   }
 
+  /* Normal crosshairs. */
   if(L3D::GetCamType() == L3D::CAM_FRONT) {
-    /* Normal crosshairs. */
     float px = Gui::Screen::GetWidth()/2.0;
     float py = Gui::Screen::GetHeight()/2.0;
     glBegin(GL_LINES);
diff --git a/src/player.h b/src/player.h
index f3739f4..7cb2081 100644
--- a/src/player.h
+++ b/src/player.h
@@ -11,7 +11,7 @@ public:
   void DrawHUD(const Frame* cam_frame);
   virtual void SetDockedWith(SpaceStation*);
   vector3d GetExternalViewTranslation(void);
-  void ApplyExternalViewRotation(void);
+  void ApplyExternalViewRotation(matrix4x4d &m);
   void TimeStepUpdate(const float timeStep);
 private:
   void DrawTargetSquares();
diff --git a/src/ship.cpp b/src/ship.cpp
index 7166c46..cd5226a 100644
--- a/src/ship.cpp
+++ b/src/ship.cpp
@@ -203,6 +203,13 @@ void Ship::SetCombatTarget(Body* const target) {
   L3D::world_view->UpdateCommsOptions();
 }
 
+bool Ship::IsFiringLasers(void) {
+  for(int i = 0; i < ShipType::GUNMOUNT_MAX; i++) {
+    if(m_gunState[i]) return true;
+  }
+  return false;
+}
+
 /* Assumed to be at model coords. */
 void Ship::RenderLaserfire(void) {
   const ShipType& stype = GetShipType();
@@ -264,11 +271,12 @@ void Ship::Render(const Frame* camFrame) {
   strncpy(params.pText[0], GetLabel().c_str(), sizeof(params.pText));
 
   RenderSbreModel(camFrame, stype.sbreModel, &params);
-  
-  glPushMatrix();
-  TransformToModelCoords(camFrame);
-  //render_coll_mesh(sbreCollMesh);
-  RenderLaserfire();
-  glPopMatrix();
+ 
+ if(IsFiringLasers()) {
+   glPushMatrix();
+   TransformToModelCoords(camFrame);
+   RenderLaserfire();
+   glPopMatrix();
+ } 
 }
 
diff --git a/src/ship.h b/src/ship.h
index 469f4ea..322da74 100644
--- a/src/ship.h
+++ b/src/ship.h
@@ -53,6 +53,8 @@ protected:
   enum ShipType::Type m_shipType;
   Uint32 m_gunState[ShipType::GUNMOUNT_MAX];
 private:
+  bool IsFiringLasers(void);
+
   float m_wheelState;
   float m_wheelTransition;
 
diff --git a/src/world_view.cpp b/src/world_view.cpp
index a5df94e..ac0ef0b 100644
--- a/src/world_view.cpp
+++ b/src/world_view.cpp
@@ -94,20 +94,33 @@ void WorldView::Draw3D(void) {
     /* Make temporary camera frame at player. */
     Frame cam_frame(L3D::player->GetFrame(), "", Frame::TEMP_VIEWING);
 
+    matrix4x4d camRot = matrix4x4d::Identity();
+
     if(L3D::GetCamType() == L3D::CAM_FRONT) {
       cam_frame.SetPosition(L3D::player->GetPosition());
     } else if(L3D::GetCamType() == L3D::CAM_REAR) {
-      glRotatef(180.0f, 0, 1, 0);
+      camRot.RotateY(M_PI);
+      //glRotatef(180.0f, 0, 1, 0);
       cam_frame.SetPosition(L3D::player->GetPosition());
     } else { /* CAM_EXTERNAL */
       cam_frame.SetPosition(L3D::player->GetPosition() + L3D::player->GetExternalViewTranslation());
-      L3D::player->ApplyExternalViewRotation();
+      L3D::player->ApplyExternalViewRotation(camRot);
     }
-    L3D::player->ViewingRotation();
 
-    glGetDoublev(GL_MODELVIEW_MATRIX, &viewingRotation[0]);
+    {
+      matrix4x4d prot;
+      L3D::player->GetRotMatrix(prot);
+      camRot = prot * camRot;
+    }
+    cam_frame.SetOrientation(camRot);
 
+    matrix4x4d trans2bg;
+    Frame::GetFrameTransform(Space::GetRootFrame(), &cam_frame, trans2bg);
+    trans2bg.ClearToRotOnly();
+    glPushMatrix();
+    glMultMatrixd(&trans2bg[0]);
     glCallList(m_bgstarsDlist);
+    glPopMatrix();
     /* Position light at sol. */
     matrix4x4d m;
     Frame::GetFrameTransform(Space::GetRootFrame(), &cam_frame, m);
diff --git a/src/world_view.h b/src/world_view.h
index 5e3531e..01c967a 100644
--- a/src/world_view.h
+++ b/src/world_view.h
@@ -10,7 +10,6 @@ public:
   WorldView(void);
   virtual void Update(void);
   virtual void Draw3D(void);
-  matrix4x4d viewingRotation;
   static const float PICK_OBJECT_RECT_SIZE;
   void UpdateCommsOptions(void);
   bool GetShowLabels(void) { return labelsOn; }