[Add] Planet landing.

This commit is contained in:
Rtch90 2018-01-18 20:30:41 +00:00
parent 18427f1497
commit 9961d38782
9 changed files with 86 additions and 15 deletions

View File

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

View File

@ -10,7 +10,8 @@ class DynamicBody : public ModelBody {
public:
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 vector3d GetVelocity(void);
void SetAngVelocity(vector3d v);

View File

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

View File

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

View File

@ -15,6 +15,7 @@ public:
virtual void SetFrame(Frame* f);
virtual bool OnCollision(Body* b, Uint32 flags) { return true; }
virtual double GetMass(void) const { return m_mass; }
virtual Object::Type GetType(void) { return Object::PLANET; }
private:
void DrawRockyPlanet(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_MINUS)) m_external_view_dist += 10;
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()) {
@ -265,6 +268,7 @@ void Player::DrawHUD(const Frame* cam_frame) {
if(GetFrame()->m_astroBody) {
double radius = GetFrame()->m_astroBody->GetRadius();
double altitude = GetPosition().Length() - radius;
if(altitude < 0) altitude = 0;
char buf[128];
snprintf(buf, sizeof(buf), "Altitude: %.0f m", altitude);
glPushMatrix();

View File

@ -23,13 +23,15 @@ static ObjParams params = {
};
Ship::Ship(ShipType::Type shipType) : DynamicBody() {
m_isLanded = false;
m_testLanded = false;
m_wheelTransition = 0;
m_wheelState = 0;
m_dockedWith = 0;
dockingTimer = 0;
m_navTarget = 0;
m_combatTarget = 0;
m_shipType = shipType;
m_wheelState = 0;
m_dockedWith = 0;
dockingTimer = 0;
m_navTarget = 0;
m_combatTarget = 0;
m_shipType = shipType;
m_angThrusters[0] = m_angThrusters[1] = m_angThrusters[2] = 0;
m_laserCollisionObj.owner = this;
m_equipment = EquipSet(shipType);
@ -52,6 +54,14 @@ void Ship::UpdateMass(void) {
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) {
/* Rotation damping. */
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;
}
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) {
dockingTimer = (dockingTimer-timeStep > 0 ? dockingTimer-timeStep : 0);
/* 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);
if((m_wheelState == 0) || (m_wheelState == 1)) m_wheelTransition = 0;
}
if(m_testLanded) TestLanded();
}
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);
vector3d pos = m_dockedWith->GetPosition() + stationRot*m_dockedWith->port.center;
SetPosition(pos);
SetRotation(rot);
SetRotMatrix(rot);
SetVelocity(vector3d(0, 0, 0));
SetAngVelocity(vector3d(0, 0, 0));
Enable();
@ -253,7 +302,7 @@ static void render_coll_mesh(const CollMesh* m) {
}
void Ship::Render(const Frame* camFrame) {
if(!dBodyIsEnabled(m_body)) return;
if((!dBodyIsEnabled(m_body)) && !m_isLanded) return;
const ShipType& stype = GetShipType();
params.angthrust[0] = m_angThrusters[0];
params.angthrust[1] = m_angThrusters[1];

View File

@ -38,6 +38,7 @@ public:
void SetDockingTimer(float t) { dockingTimer = t; }
virtual void TimeStepUpdate(const float timeStep);
virtual void NotifyDeath(const Body* const dyingBody);
virtual bool OnCollision(Body* b, Uint32 flags);
class LaserObj : public Object {
public:
@ -50,11 +51,14 @@ protected:
void RenderLaserfire(void);
SpaceStation* m_dockedWith;
bool m_isLanded;
enum ShipType::Type m_shipType;
Uint32 m_gunState[ShipType::GUNMOUNT_MAX];
private:
bool IsFiringLasers(void);
void TestLanded(void);
bool m_testLanded;
float m_wheelState;
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++) {
contact[i].surface.mode = dContactBounce;
contact[i].surface.mu = 0;
contact[i].surface.mu = 0.8;
contact[i].surface.mu2 = 0;
contact[i].surface.bounce = 0.1;
contact[i].surface.bounce_vel = 0.1;