[Add] Planet landing.

This commit is contained in:
Allanis 2018-01-18 20:30:41 +00:00
parent 96299b64f5
commit 92bac965d1
9 changed files with 86 additions and 15 deletions

View File

@ -22,12 +22,16 @@ void DynamicBody::Disable(void) {
dBodyDisable(m_body); dBodyDisable(m_body);
} }
void DynamicBody::SetRotation(const matrix4x4d &r) { void DynamicBody::SetRotMatrix(const matrix4x4d& r) {
dMatrix3 _m; dMatrix3 _m;
r.SaveToOdeMatrix(_m); r.SaveToOdeMatrix(_m);
dBodySetRotation(m_body, _m); dBodySetRotation(m_body, _m);
} }
void DynamicBody::GetRotMatrix(matrix4x4d& m) {
m.LoadFromOdeMatrix(dBodyGetRotation(m_body));
}
void DynamicBody::SetMassDistributionFromCollMesh(const CollMesh* m) { void DynamicBody::SetMassDistributionFromCollMesh(const CollMesh* m) {
/* /*
* XXX: This is silly. the radius of mass distribution should be * XXX: This is silly. the radius of mass distribution should be

View File

@ -10,7 +10,8 @@ class DynamicBody : public ModelBody {
public: public:
DynamicBody(void); DynamicBody(void);
virtual ~DynamicBody(void); virtual ~DynamicBody(void);
virtual void SetRotation(const matrix4x4d& r); virtual void SetRotMatrix(const matrix4x4d& r);
virtual void GetRotMatrix(matrix4x4d& m);
virtual void SetVelocity(vector3d v); virtual void SetVelocity(vector3d v);
virtual vector3d GetVelocity(void); virtual vector3d GetVelocity(void);
void SetAngVelocity(vector3d v); void SetAngVelocity(vector3d v);

View File

@ -98,6 +98,8 @@ void L3D::Init(IniConfig& config) {
L3D::scrHeight = height; L3D::scrHeight = height;
L3D::scrAspect = width / (float)height; L3D::scrAspect = width / (float)height;
L3D::rng.seed(time(NULL));
InitOpenGL(); InitOpenGL();
dInitODE(); dInitODE();
@ -229,8 +231,14 @@ void L3D::MainLoop(void) {
station->SetPosition(vector3d(0,0,0)); station->SetPosition(vector3d(0,0,0));
Space::AddBody(station); Space::AddBody(station);
player->SetFrame(stationFrame); //player->SetFrame(stationFrame);
player->SetPosition(vector3d(0,0,2000)); //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); Gui::Init(scrWidth, scrHeight, 640, 480);
@ -246,7 +254,7 @@ void L3D::MainLoop(void) {
infoView = new InfoView(); infoView = new InfoView();
SetView(worldView); SetView(worldView);
player->SetDockedWith(station); //player->SetDockedWith(station);
Uint32 last_stats = SDL_GetTicks(); Uint32 last_stats = SDL_GetTicks();
int frame_stat = 0; int frame_stat = 0;

View File

@ -2,7 +2,7 @@
class Object { class Object {
public: public:
enum Type { NONE, BODY, SHIP, SPACESTATION, LASER, GEOM }; enum Type { NONE, BODY, SHIP, SPACESTATION, LASER, GEOM, PLANET };
virtual Type GetType(void) = 0; virtual Type GetType(void) = 0;
}; };

View File

@ -15,6 +15,7 @@ public:
virtual void SetFrame(Frame* f); virtual void SetFrame(Frame* f);
virtual bool OnCollision(Body* b, Uint32 flags) { return true; } virtual bool OnCollision(Body* b, Uint32 flags) { return true; }
virtual double GetMass(void) const { return m_mass; } virtual double GetMass(void) const { return m_mass; }
virtual Object::Type GetType(void) { return Object::PLANET; }
private: private:
void DrawRockyPlanet(void); void DrawRockyPlanet(void);
void DrawGasGiant(void); void DrawGasGiant(void);

View File

@ -88,6 +88,9 @@ void Player::PollControls(void) {
if(L3D::KeyState(SDLK_EQUALS)) m_external_view_dist -= 10; if(L3D::KeyState(SDLK_EQUALS)) m_external_view_dist -= 10;
if(L3D::KeyState(SDLK_MINUS)) m_external_view_dist += 10; if(L3D::KeyState(SDLK_MINUS)) m_external_view_dist += 10;
m_external_view_dist = MAX(50, m_external_view_dist); m_external_view_dist = MAX(50, m_external_view_dist);
/* When landed don't let external view look from below. */
if(m_isLanded) m_external_view_rotx = CLAMP(m_external_view_rotx, -170.0, -10);
} }
if((time_accel == 0) || GetDockedWith()) { if((time_accel == 0) || GetDockedWith()) {
@ -265,6 +268,7 @@ void Player::DrawHUD(const Frame* cam_frame) {
if(GetFrame()->m_astroBody) { if(GetFrame()->m_astroBody) {
double radius = GetFrame()->m_astroBody->GetRadius(); double radius = GetFrame()->m_astroBody->GetRadius();
double altitude = GetPosition().Length() - radius; double altitude = GetPosition().Length() - radius;
if(altitude < 0) altitude = 0;
char buf[128]; char buf[128];
snprintf(buf, sizeof(buf), "Altitude: %.0f m", altitude); snprintf(buf, sizeof(buf), "Altitude: %.0f m", altitude);
glPushMatrix(); glPushMatrix();

View File

@ -23,6 +23,8 @@ static ObjParams params = {
}; };
Ship::Ship(ShipType::Type shipType) : DynamicBody() { Ship::Ship(ShipType::Type shipType) : DynamicBody() {
m_isLanded = false;
m_testLanded = false;
m_wheelTransition = 0; m_wheelTransition = 0;
m_wheelState = 0; m_wheelState = 0;
m_dockedWith = 0; m_dockedWith = 0;
@ -52,6 +54,14 @@ void Ship::UpdateMass(void) {
dBodySetMass(m_body, &m_mass); dBodySetMass(m_body, &m_mass);
} }
bool Ship::OnCollision(Body* b, Uint32 flags) {
if(b->GetType() == Object::PLANET) {
if(m_isLanded) return false;
else m_testLanded = true;
}
return true;
}
vector3d Ship::CalcRotDamping(void) { vector3d Ship::CalcRotDamping(void) {
/* Rotation damping. */ /* Rotation damping. */
const dReal* _av = dBodyGetAngularVel(m_body); const dReal* _av = dBodyGetAngularVel(m_body);
@ -97,6 +107,43 @@ void Ship::CalcStats(shipstats_t* stats) {
stats->hyperspace_range = 200 * hyperclass * hyperclass / stats->total_mass; stats->hyperspace_range = 200 * hyperclass * hyperclass / stats->total_mass;
} }
void Ship::TestLanded(void) {
if(GetFrame()->m_astroBody) {
const dReal* vel = dBodyGetLinearVel(m_body);
double speed = vector3d(vel[0], vel[1], vel[2]).Length();
const double planetRadius = GetFrame()->m_astroBody->GetRadius();
if(speed < 15) {
printf("Landed!\n");
/* Orient the damn thing right! */
matrix4x4d rot;
GetRotMatrix(rot);
vector3d up = vector3d::Normalize(GetPosition());
/* Position at zero altitude. */
SetPosition(up * planetRadius);
vector3d forward = rot * vector3d(0, 0, 1);
vector3d other = vector3d::Normalize(vector3d::Cross(up, forward));
rot = matrix4x4d::MakeRotMatrix(other, up, forward);
rot = rot.InverseOf();
SetRotMatrix(rot);
/*
* We don'tuse DynamicBody::Disable because that also disables the geom
* and that must still get collisions.
*/
dBodyDisable(m_body);
ClearThrusterState();
m_isLanded = true;
m_testLanded = false;
}
}
}
void Ship::TimeStepUpdate(const float timeStep) { void Ship::TimeStepUpdate(const float timeStep) {
dockingTimer = (dockingTimer-timeStep > 0 ? dockingTimer-timeStep : 0); dockingTimer = (dockingTimer-timeStep > 0 ? dockingTimer-timeStep : 0);
/* ODE tri mesh likes to know our old position. */ /* ODE tri mesh likes to know our old position. */
@ -143,6 +190,8 @@ void Ship::TimeStepUpdate(const float timeStep) {
m_wheelState = CLAMP(m_wheelState, 0, 1); m_wheelState = CLAMP(m_wheelState, 0, 1);
if((m_wheelState == 0) || (m_wheelState == 1)) m_wheelTransition = 0; if((m_wheelState == 0) || (m_wheelState == 1)) m_wheelTransition = 0;
} }
if(m_testLanded) TestLanded();
} }
void Ship::NotifyDeath(const Body* const dyingBody) { void Ship::NotifyDeath(const Body* const dyingBody) {
@ -169,7 +218,7 @@ void Ship::SetDockedWith(SpaceStation* s) {
matrix4x4d rot = stationRot * matrix4x4d::MakeRotMatrix(m_dockedWith->port.horiz, port_y, 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; vector3d pos = m_dockedWith->GetPosition() + stationRot*m_dockedWith->port.center;
SetPosition(pos); SetPosition(pos);
SetRotation(rot); SetRotMatrix(rot);
SetVelocity(vector3d(0, 0, 0)); SetVelocity(vector3d(0, 0, 0));
SetAngVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0));
Enable(); Enable();
@ -253,7 +302,7 @@ static void render_coll_mesh(const CollMesh* m) {
} }
void Ship::Render(const Frame* camFrame) { void Ship::Render(const Frame* camFrame) {
if(!dBodyIsEnabled(m_body)) return; if((!dBodyIsEnabled(m_body)) && !m_isLanded) return;
const ShipType& stype = GetShipType(); const ShipType& stype = GetShipType();
params.angthrust[0] = m_angThrusters[0]; params.angthrust[0] = m_angThrusters[0];
params.angthrust[1] = m_angThrusters[1]; params.angthrust[1] = m_angThrusters[1];

View File

@ -38,6 +38,7 @@ public:
void SetDockingTimer(float t) { dockingTimer = t; } void SetDockingTimer(float t) { dockingTimer = t; }
virtual void TimeStepUpdate(const float timeStep); virtual void TimeStepUpdate(const float timeStep);
virtual void NotifyDeath(const Body* const dyingBody); virtual void NotifyDeath(const Body* const dyingBody);
virtual bool OnCollision(Body* b, Uint32 flags);
class LaserObj : public Object { class LaserObj : public Object {
public: public:
@ -50,11 +51,14 @@ protected:
void RenderLaserfire(void); void RenderLaserfire(void);
SpaceStation* m_dockedWith; SpaceStation* m_dockedWith;
bool m_isLanded;
enum ShipType::Type m_shipType; enum ShipType::Type m_shipType;
Uint32 m_gunState[ShipType::GUNMOUNT_MAX]; Uint32 m_gunState[ShipType::GUNMOUNT_MAX];
private: private:
bool IsFiringLasers(void); bool IsFiringLasers(void);
void TestLanded(void);
bool m_testLanded;
float m_wheelState; float m_wheelState;
float m_wheelTransition; float m_wheelTransition;

View File

@ -254,7 +254,7 @@ static void nearCallback(void* data, dGeomID oO, dGeomID o1) {
for(int i = 0; i < MAX_CONTACTS; i++) { for(int i = 0; i < MAX_CONTACTS; i++) {
contact[i].surface.mode = dContactBounce; contact[i].surface.mode = dContactBounce;
contact[i].surface.mu = 0; contact[i].surface.mu = 0.8;
contact[i].surface.mu2 = 0; contact[i].surface.mu2 = 0;
contact[i].surface.bounce = 0.1; contact[i].surface.bounce = 0.1;
contact[i].surface.bounce_vel = 0.1; contact[i].surface.bounce_vel = 0.1;