[Add] Landing on ground based stations. Uses the same geom flag 1 thing

to indicate docking surface, but they are visible surfaces in this case.
This commit is contained in:
Allanis 2018-01-21 00:12:28 +00:00
parent 4824a797b9
commit bed1c183c7
16 changed files with 186 additions and 71 deletions

View File

@ -9,7 +9,7 @@ include_HEADERS = body.h frame.h generic_system_view.h glfreetype.h gui_button.h
gui_radio_group.h gui_screen.h gui_toggle_button.h gui_widget.h libs.h matrix4x4.h mtrand.h l3d.h \
planet.h player.h dynamic_body.h sector.h sector_view.h ship_cpanel.h ship.h space.h star.h star_system.h system_info_view.h \
system_view.h vector3.h view.h world_view.h date.h space_station.h space_station_view.h model_body.h gui_iselectable.h \
ship_type.h object.h info_view.h model_coll_mesh_data.h object_viewer_view.h fixed.h custom_starsystems.h
ship_type.h object.h info_view.h model_coll_mesh_data.h object_viewer_view.h fixed.h custom_starsystems.h gameconsts.h
libgui_a_SOURCES = gui_button.cpp gui.cpp gui_fixed.cpp gui_screen.cpp gui_label.cpp gui_toggle_button.cpp gui_radio_button.cpp \
gui_radio_group.cpp gui_image_button.cpp gui_image.cpp gui_image_radio_button.cpp gui_multi_state_image_button.cpp gui_widget.cpp \

View File

@ -14,13 +14,13 @@ public:
virtual ~Body(void);
virtual Object::Type GetType(void) { return Object::BODY; }
virtual void SetPosition(vector3d p) = 0;
virtual vector3d GetPosition(void) = 0; /* Within frame. */
virtual vector3d GetPosition(void) const = 0; /* Within frame. */
virtual void SetVelocity(vector3d v) { assert(0); }
virtual vector3d GetVelocity(void) { assert(0); return vector3d(0.0); }
virtual double GetRadius(void) const = 0 ;
virtual double GetMass(void) const { assert(0); return 0; }
virtual void SetRotMatrix(const matrix4x4d& r) {};
virtual void GetRotMatrix(matrix4x4d& m) {};
virtual void GetRotMatrix(matrix4x4d& m) const {};
virtual void Render(const Frame* camFrame) = 0;
virtual void SetFrame(Frame* f) { m_frame = f; }
/* return true if to we do collision response and apply damage. */

4
src/gameconsts.h Normal file
View File

@ -0,0 +1,4 @@
#pragma once
#define MAX_LANDING_SPEED 20.0

View File

@ -5,6 +5,7 @@
#include "gui.h"
#include "view.h"
#include "mtrand.h"
#include "gameconsts.h"
class Player;
class SectorView;

View File

@ -227,27 +227,23 @@ void L3D::MainLoop(void) {
Space::AddBody(body);
}
SpaceStation* station = new SpaceStation();
SpaceStation* station = new SpaceStation(SpaceStation::JJHOOP);
station->SetLabel("Poemi-chan's Folly");
station->SetFrame(stationFrame);
station->SetPosition(vector3d(0,0,0));
Space::AddBody(station);
SpaceStation* station2 = new SpaceStation();
SpaceStation* station2 = new SpaceStation(SpaceStation::GROUND_FLAVOURED);;
station2->SetLabel("Dfighter's point");
station2->SetFrame(*pframe->m_children.begin()); /* Rotating frame of planet. */
station2->OrientOnSurface(EARTH_RADIUS, M_PI/4, M_PI/4);
Space::AddBody(station2);
player->SetFrame(stationFrame);
player->SetPosition(vector3d(0,0,0));
player->SetFrame(pframe);
//player->SetPosition(vector3d(0,0,0));
player->OrientOnSurface(EARTH_RADIUS*1.001, M_PI/4, M_PI/4);
//player->SetPosition(vector3d(0,0,2000));
//player->SetFrame(pframe);
float ang1 = L3D::rng.Double(0,M_PI);
float ang2 = L3D::rng.Double(0,M_PI);
double r = EARTH_RADIUS*1.0001;
//player->SetPosition(vector3d(r*cos(ang1)*cos(ang2), r*sin(ang1)*cos(ang2), r*sin(ang2)));
//player->SetPosition(vector3d(r, 0, 0);
Gui::Init(scrWidth, scrHeight, 640, 480);
@ -263,7 +259,7 @@ void L3D::MainLoop(void) {
infoView = new InfoView();
SetView(worldView);
player->SetDockedWith(station);
player->SetDockedWith(station2);
Uint32 last_stats = SDL_GetTicks();
int frame_stat = 0;

View File

@ -57,7 +57,7 @@ void ModelBody::SetPosition(vector3d p) {
}
}
vector3d ModelBody::GetPosition(void) {
vector3d ModelBody::GetPosition(void) const {
const dReal* pos = dGeomGetPosition(geoms[0]);
return vector3d(pos[0], pos[1], pos[2]);
}
@ -96,7 +96,7 @@ void ModelBody::SetRotMatrix(const matrix4x4d& r) {
}
}
void ModelBody::GetRotMatrix(matrix4x4d& m) {
void ModelBody::GetRotMatrix(matrix4x4d& m) const {
m.LoadFromOdeMatrix(dGeomGetRotation(geoms[0]));
}

View File

@ -14,10 +14,10 @@ public:
void SetPosition(vector3d p);
virtual void SetRotMatrix(const matrix4x4d& r);
/* Not valid to SetVelocity on these. If you want them to move, use a DynamicBody. */
vector3d GetPosition(void);
vector3d GetPosition(void) const;
virtual double GetRadius(void) const;
void TransformToModelCoords(const Frame* camFrame);
void GetRotMatrix(matrix4x4d& m);
void GetRotMatrix(matrix4x4d& m) const;
virtual void SetFrame(Frame* f);
void GeomsSetBody(dBodyID body);
/* To remove from simulation for a period. */

View File

@ -19,7 +19,7 @@ Planet::~Planet(void) {
dGeomDestroy(geom);
}
vector3d Planet::GetPosition(void) {
vector3d Planet::GetPosition(void) const {
return pos;
}

View File

@ -8,7 +8,7 @@ public:
Planet(StarSystem::SBody*);
virtual ~Planet(void);
virtual void SetPosition(vector3d p);
virtual vector3d GetPosition(void);
virtual vector3d GetPosition(void) const;
void SetRadius(double radius);
virtual double GetRadius(void) const { return sbody.GetRadius(); }
virtual void Render(const Frame* camFrame);

View File

@ -1256,45 +1256,67 @@ static PlainVertex metalFrameTowerVtx1[] = {
{ VTYPE_PLAIN, { -1, 10, -1 } },
};
static CompoundVertex metalFrameTowerVtx2[] = {
{ VTYPE_ANIMLIN, { 6, 10, static_cast<uint16>(-1), static_cast<uint16>(-1), 0 } },
{ VTYPE_ANIMLIN, { 7, 11, static_cast<uint16>(-1), static_cast<uint16>(-1), 0 } },
{ VTYPE_ANIMLIN, { 8, 12, static_cast<uint16>(-1), static_cast<uint16>(-1), 0 } },
{ VTYPE_ANIMLIN, { 9, 13, static_cast<uint16>(-1), static_cast<uint16>(-1), 0 } },
};
static uint16 metalFrameTowerData[] = {
PTYPE_CYLINDER, 0x8000, 4, 6, 14, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 7, 15, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 8, 16, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 9, 17, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 6, 15, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 7, 14, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 7, 16, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 8, 15, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 8, 17, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 9, 16, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 6, 17, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 9, 14, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 14, 15, 1, 10,
PTYPE_CYLINDER, 0x8000, 4, 15, 16, 1, 10,
PTYPE_CYLINDER, 0x8000, 4, 16, 17, 1, 10,
PTYPE_CYLINDER, 0x8000, 4, 17, 14, 1, 10,
PTYPE_CYLINDER, 0x8000, 4, 6, 10, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 7, 11, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 8, 12, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 9, 13, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 6, 11, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 7, 10, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 7, 12, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 8, 11, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 8, 13, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 9, 12, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 6, 13, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 9, 10, 0, 10,
PTYPE_CYLINDER, 0x8000, 4, 10, 11, 1, 10,
PTYPE_CYLINDER, 0x8000, 4, 11, 12, 1, 10,
PTYPE_CYLINDER, 0x8000, 4, 12, 13, 1, 10,
PTYPE_CYLINDER, 0x8000, 4, 13, 10, 1, 10,
PTYPE_END,
};
Model metalFrameTowerModel = { 0.1f, 20.0f, 14, metalFrameTowerVtx1, 14, 4, metalFrameTowerVtx2, 0,
Model metalFrameTowerModel = { 0.1f, 20.0f, 14, metalFrameTowerVtx1, 14, 4, dummyvtx2, 0,
{ { 0, metalFrameTowerData, 0, 0, 0 } } };
static PlainVertex starport1vtx1[] = {
{ VTYPE_PLAIN, { 0, 0, 0 } },
{ VTYPE_PLAIN, { 0, .01, 0 } },
{ VTYPE_PLAIN, { -0.1, .01, -0.1 } },
{ VTYPE_PLAIN, { 0, 0, -2 } },
{ VTYPE_PLAIN, { 0, 0, 2 } },
{ VTYPE_PLAIN, { 0.5, 0, 0 } },
{ VTYPE_PLAIN, { -0.5, 0, 0 } },
};
#if 0
uint16 PFUNC_COMPSMOOTH
uint16 cacheidx
uint16 steps
uint16 centpos
uint16 centnorm
uint16 starpos
uint16 startnorm
uint16 COMP_END
uint16 COMP_LINE
uint16 pos
uint16 norm
uint16 COMP_HERMITE
uint16 pos
uint16 norm
uint16 tan0
uint16 tan1
#endif
static uint16 starport1data[] = {
PTYPE_MATFIXED, 30, 30, 30, 0, 0, 0, 0, 0, 0, 0,
PTYPE_CYLINDER, 0x8000, 8, 6, 7, 0, 50,
PTYPE_SETCFLAG, 1,
PTYPE_COMPFLAT, 0x8000, 20, 6, 1, 11, 1,
COMP_HERMITE, 12, 1, 9, 10,
COMP_HERMITE, 11, 1, 10, 9,
COMP_END,
//PTYPE_CYLINDER, 0x8000, 8, 6, 7, 0, 50,
PTYPE_SETCFLAG, 0,
PTYPE_MATFIXED, 100, 100, 100, 0, 0, 0, 0, 0, 0, 0,
PTYPE_ZBIAS, 6, 1, 0,
PTYPE_TEXT, 0, 10, 8, 1, 0, 0, 0, 20,
@ -1304,6 +1326,6 @@ static uint16 starport1data[] = {
PTYPE_END,
};
Model starport1model = { 100.0f, 55.0f, 9, starport1vtx1, 9, 0, dummyvtx2, 1,
Model starport1model = { 100.0f, 55.0f, 13, starport1vtx1, 13, 0, dummyvtx2, 1,
{ { 0, starport1data, 0, 0, 0 } } };

View File

@ -127,6 +127,7 @@ void Ship::Blastoff(void) {
dBodySetAngularVel(m_body, 0, 0, 0);
dBodySetForce(m_body, 0, 0, 0);
dBodySetTorque(m_body, 0, 0, 0);
/* TODO: We need to be able to get sbre aabb. */
SetPosition(up*planetRadius+10.0*up);
SetThrusterState(ShipType::THRUSTER_TOP, 1.0f);
}
@ -138,7 +139,7 @@ void Ship::TestLanded(void) {
double speed = vector3d(vel[0], vel[1], vel[2]).Length();
const double planetRadius = GetFrame()->m_astroBody->GetRadius();
if(speed < 20) {
if(speed < MAX_LANDING_SPEED) {
/* Orient the damn thing right!
* Why is the inverse of the body rot matrix being used?!?!
* *shrugs* it just works this way.
@ -188,6 +189,13 @@ void Ship::TimeStepUpdate(const float timeStep) {
m_launchLockTimeout -= timeStep;
if(m_launchLockTimeout < 0) m_launchLockTimeout = 0;
/*
* Can't orient ships in SetDockedWith() because it gets
* called from ode collision handler, and body is locked
* and can't be positioned. Instead we do it every freaking
* update which is stupid.
*/
if(m_dockedWith) m_dockedWith->OrientDockedShip(this);
const ShipType& stype = GetShipType();
for(int i = 0; i < ShipType::THRUSTER_MAX; i++) {
@ -248,26 +256,14 @@ const ShipType& Ship::GetShipType(void) {
void Ship::SetDockedWith(SpaceStation* s) {
if(m_dockedWith && !s) {
/*
* Position player in middle of docking bay, pointing out of it.
* TODO Need to do forced thrusting thingy.
* TODO ang vel not zeroed for some reason..
*/
matrix4x4d stationRot;
m_dockedWith->GetRotMatrix(stationRot);
vector3d port_y = vector3d::Cross(-m_dockedWith->port.horiz, m_dockedWith->port.normal);
matrix4x4d rot = stationRot * matrix4x4d::MakeRotMatrix(m_dockedWith->port.horiz, port_y, m_dockedWith->port.normal);
vector3d pos = m_dockedWith->GetPosition() + stationRot*m_dockedWith->port.center;
SetPosition(pos);
SetRotMatrix(rot);
SetVelocity(vector3d(0, 0, 0));
SetAngVelocity(vector3d(0, 0, 0));
m_dockedWith->OrientLaunchingShip(this);
Enable();
m_dockedWith = 0;
} else {
m_dockedWith = s;
m_dockingTimer = 0.0f;
if(s->IsGroundStation()) m_flightState = LANDED;
SetVelocity(vector3d(0, 0, 0));
SetAngVelocity(vector3d(0, 0, 0));
Disable();

View File

@ -41,7 +41,8 @@ public:
virtual void NotifyDeath(const Body* const dyingBody);
virtual bool OnCollision(Body* b, Uint32 flags);
enum FlightState { FLYING, LANDED };
FlightState GetFlightState(void) { return m_flightState; }
FlightState GetFlightState(void) const { return m_flightState; }
float GetWheelState(void) const { return m_wheelState; }
class LaserObj : public Object {
public:

View File

@ -1,8 +1,17 @@
#include "space_station.h"
#include "ship.h"
#include "model_coll_mesh_data.h"
#include "gameconsts.h"
#define STATION_SBRE_MODEL 65
struct SpaceStationType {
Uint32 sbreModel;
enum { ORBITAL, SURFACE } dockMethod;
};
struct SpaceStationType stationTypes[SpaceStation::TYPE_MAX] = {
{ 65, SpaceStationType::ORBITAL },
{ 90, SpaceStationType::SURFACE },
};
static ObjParams params = {
{ 0.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
@ -55,10 +64,12 @@ void SpaceStation::GetDockingSurface(CollMeshSet* mset, int midx) {
port.horiz.z); */
}
SpaceStation::SpaceStation(void) : ModelBody() {
SetModel(STATION_SBRE_MODEL);
SpaceStation::SpaceStation(TYPE type) : ModelBody() {
const Uint32 sbreModel = stationTypes[type].sbreModel;
m_type = type;
SetModel(sbreModel);
CollMeshSet* mset = GetModelCollMeshSet(STATION_SBRE_MODEL);
CollMeshSet* mset = GetModelCollMeshSet(sbreModel);
for(unsigned int i = 0; i < geomColl.size(); i++) {
if(geomColl[i].flags == 0x1) {
/* Docking surface. */
@ -79,6 +90,64 @@ SpaceStation::~SpaceStation(void) {
}
bool SpaceStation::IsGroundStation(void) const {
return (stationTypes[m_type].dockMethod == SpaceStationType::SURFACE);
}
void SpaceStation::OrientDockedShip(Ship* ship) const {
const int dockMethod = stationTypes[m_type].dockMethod;
if(dockMethod == SpaceStationType::SURFACE) {
matrix4x4d stationRot;
GetRotMatrix(stationRot);
vector3d port_y = vector3d::Cross(-port.horiz, port.normal);
matrix4x4d rot = stationRot * matrix4x4d::MakeRotMatrix(-port.horiz, -port.normal, -port_y);
vector3d pos = GetPosition() + stationRot*port.center;
ship->SetPosition(pos - stationRot*port.normal);
ship->SetRotMatrix(rot);
}
}
void SpaceStation::OrientLaunchingShip(Ship* ship) const {
const int dockMethod = stationTypes[m_type].dockMethod;
if(dockMethod == SpaceStationType::ORBITAL) {
/*
* Position ship in middle of docking bat, pointing out of it.
* TODO: Need to do forced thrusting thing.
* TODO: ang vel not zeroed for some reason..
*/
matrix4x4d stationRot;
GetRotMatrix(stationRot);
vector3d port_y = vector3d::Cross(-port.horiz, port.normal);
matrix4x4d rot = stationRot * matrix4x4d::MakeRotMatrix(port.horiz, port_y, port.normal);
vector3d pos = GetPosition() + stationRot*port.center;
ship->SetPosition(pos);
ship->SetRotMatrix(rot);
ship->SetVelocity(vector3d(0,0,0));
ship->SetAngVelocity(vector3d(0,0,0));
}
else if(dockMethod == SpaceStationType::SURFACE) {
ship->Blastoff();
/*
* Not necessary, since for the time being 'SURFACE' starports are on planets
* so the positioning Blastoff does is fine.
*/
#if 0
matrix4x4d stationRot;
GetRotMatrix(stationRot);
vector3d port_y = vector3d::Cross(-port.horiz, port.normal);
matrix4x4d rot = stationRot * matrix4x4d::MakeRotMatrix(-port.horiz, -port.normal, -port_y);
vector3d pos = GetPosition() + stationRot*port.center;
ship->SetPosition(pos - stationRot*(10*port.normal));
ship->SetRotMatrix(rot);
ship->SetVelocity(vector3d(0,0,0));
ship->SetAngVelocity(vector3d(0,0,0));
#endif
} else {
assert(0);
}
}
bool SpaceStation::GetDockingClearance(Ship* s) {
s->SetDockingTimer(68*10);
return true;
@ -89,9 +158,28 @@ bool SpaceStation::OnCollision(Body* b, Uint32 flags) {
/* Hitting docking area of a station. */
if(b->GetType() == Object::SHIP) {
Ship* s = static_cast<Ship*>(b);
if((!s->GetDockedWith()) && (s->GetDockingTimer() != 0.0f)) {
const dReal* vel = dBodyGetLinearVel(s->m_body);
double speed = vector3d(vel[0], vel[1], vel[2]).Length();
/* Must be oriented sensibly and have wheels down. */
if(IsGroundStation()) {
matrix4x4d rot;
s->GetRotMatrix(rot);
matrix4x4d invRot = rot.InverseOf();
matrix4x4d stationRot;
GetRotMatrix(stationRot);
vector3d dockingNormal = stationRot*port.normal;
/* Check player is sort of sensibly oriented for landing. */
const double dot = vector3d::Dot(vector3d(-invRot[1], -invRot[5], -invRot[9]), dockingNormal);
if((dot < 0.99) || (s->GetWheelState() != 1.0)) return false;
}
if((speed < MAX_LANDING_SPEED) &&
(!s->GetDockedWith()) &&
(s->GetDockingTimer() != 0.0f)) {
s->SetDockedWith(this);
printf("Docking!\n");
}
}
return false;
@ -101,6 +189,6 @@ bool SpaceStation::OnCollision(Body* b, Uint32 flags) {
}
void SpaceStation::Render(const Frame* camFrame) {
RenderSbreModel(camFrame, STATION_SBRE_MODEL, &params);
RenderSbreModel(camFrame, stationTypes[m_type].sbreModel, &params);
}

View File

@ -7,17 +7,24 @@ class Ship;
class SpaceStation : public ModelBody {
public:
SpaceStation(void);
enum TYPE { JJHOOP, GROUND_FLAVOURED, TYPE_MAX };
SpaceStation(TYPE);
virtual ~SpaceStation(void);
virtual bool OnCollision(Body* b, Uint32 flags);
virtual Object::Type GetType(void) { return Object::SPACESTATION; }
virtual void Render(const Frame* camFrame);
void OrientLaunchingShip(Ship* ship) const;
void OrientDockedShip(Ship* ship) const;
void GetDockingSurface(CollMeshSet* mset, int midx);
bool GetDockingClearance(Ship* s);
bool IsGroundStation(void) const;
struct dockingport_t {
vector3d center;
vector3d normal;
vector3d horiz;
} port;
private:
TYPE m_type;
};

View File

@ -9,7 +9,7 @@ Star::Star(StarSystem::SBody* sbody): Body() {
pos = vector3d(0,0,0);
}
vector3d Star::GetPosition(void) {
vector3d Star::GetPosition(void) const {
return pos;
}

View File

@ -9,7 +9,7 @@ public:
Star(StarSystem::SBody* sbody);
virtual ~Star(void) { };
virtual void SetPosition(vector3d p);
virtual vector3d GetPosition(void);
virtual vector3d GetPosition(void) const;
virtual double GetRadius(void) const { return radius; }
virtual void Render(const Frame* camFrame);
virtual double GetMass(void) const { return mass; }