Fix to planets not rotating at low accel

master
John Jordan 2012-11-25 02:48:14 +00:00
parent 71becfa998
commit 41d909195e
7 changed files with 27 additions and 23 deletions

View File

@ -116,7 +116,7 @@ void DynamicBody::CalcExternalForce()
// atmospheric drag
m_atmosForce = vector3d(0.0);
/* if (GetFrame()->IsRotFrame() && body->IsType(Object::PLANET))
if (GetFrame()->IsRotFrame() && body->IsType(Object::PLANET))
{
Planet *planet = static_cast<Planet*>(body);
double dist = GetPosition().Length();
@ -145,7 +145,6 @@ void DynamicBody::CalcExternalForce()
m_externalForce -= m_mass * angRot.Cross(angRot.Cross(GetPosition())); // centrifugal
m_externalForce -= 2 * m_mass * angRot.Cross(GetVelocity()); // coriolis
}
*/
}
void DynamicBody::TimeStepUpdate(const float timeStep)
@ -189,7 +188,7 @@ void DynamicBody::UpdateInterpTransform(double alpha)
m_interpOrient = m_oldOrient;
double len = m_oldAngDisplacement.Length() * alpha;
if (!is_zero_general(len)) {
if (len > 1e-16) {
vector3d axis = m_oldAngDisplacement.Normalized();
matrix3x3d rot = matrix3x3d::BuildRotate(len, axis);
m_interpOrient = rot * m_interpOrient;

View File

@ -32,7 +32,7 @@ void Frame::Serialize(Serializer::Writer &wr, Frame *f, Space *space)
wr.String(f->m_label);
wr.Vector3d(f->m_pos);
for (int i=0; i<9; i++) wr.Double(f->m_orient[i]);
wr.Vector3d(f->m_angVel);
wr.Double(f->m_angSpeed);
wr.Int32(space->GetIndexForSystemBody(f->m_sbody));
wr.Int32(space->GetIndexForBody(f->m_astroBody));
wr.Int32(f->m_children.size());
@ -51,7 +51,7 @@ Frame *Frame::Unserialize(Serializer::Reader &rd, Space *space, Frame *parent)
f->m_label = rd.String();
f->m_pos = rd.Vector3d();
for (int i=0; i<9; i++) f->m_orient[i] = rd.Double();
f->m_angVel = rd.Vector3d();
f->m_angSpeed = rd.Double();
f->m_sbody = space->GetSystemBodyByIndex(rd.Int32());
f->m_astroBodyIndex = rd.Int32();
f->m_vel = vector3d(0.0);
@ -83,7 +83,7 @@ void Frame::Init(Frame *parent, const char *label, unsigned int flags)
m_radius = 0;
m_pos = vector3d(0.0);
m_vel = vector3d(0.0);
m_angVel = vector3d(0.0);
m_angSpeed = 0.0;
m_orient = matrix3x3d::Identity();
ClearMovement();
m_collisionSpace = new CollisionSpace();
@ -172,9 +172,9 @@ void Frame::UpdateInterpTransform(double alpha)
m_interpPos = alpha*m_pos + (1.0-alpha)*m_oldPos;
m_interpOrient = m_oldOrient;
double len = m_oldAngDisplacement.Length() * double(alpha);
double len = m_oldAngDisplacement * double(alpha);
if (!is_zero_general(len)) {
vector3d axis = m_oldAngDisplacement.Normalized();
vector3d axis = vector3d(0,1,0);
matrix3x3d rot = matrix3x3d::BuildRotate(len, axis);
m_interpOrient = rot * m_interpOrient;
}
@ -211,14 +211,14 @@ void Frame::ClearMovement()
m_rootInterpOrient = m_rootOrient;
m_oldPos = m_interpPos = m_pos;
m_oldOrient = m_interpOrient = m_orient;
m_oldAngDisplacement = vector3d(0.0);
m_oldAngDisplacement = 0.0;
}
void Frame::UpdateOrbitRails(double time, double timestep)
{
m_oldPos = m_pos;
m_oldOrient = m_orient;
m_oldAngDisplacement = m_angVel * timestep;
m_oldAngDisplacement = m_angSpeed * timestep;
// update frame position and velocity
if (m_parent && m_sbody && !IsRotFrame()) {
@ -230,9 +230,9 @@ void Frame::UpdateOrbitRails(double time, double timestep)
else m_pos = m_pos + m_vel * timestep;
// update frame rotation
double ang = m_angVel.Length() * timestep; // hmm. cumulative inaccuracy?
if (!is_zero_general(ang)) {
vector3d axis = m_angVel.Normalized();
double ang = m_angSpeed * timestep; // hmm. cumulative inaccuracy? worse!
if (!is_zero_exact(m_angSpeed)) { // calling this with very low numbers is still important
vector3d axis = vector3d(0,1,0);
matrix3x3d rot = matrix3x3d::BuildRotate(ang, axis);
m_orient = m_orient * rot; // angvel always +y
}

View File

@ -39,8 +39,8 @@ public:
const matrix3x3d &GetInterpOrient() const { return m_interpOrient; }
void SetVelocity(const vector3d &vel) { m_vel = vel; }
vector3d GetVelocity() const { return m_vel; }
void SetAngVelocity(const vector3d &angvel) { m_angVel = angvel; }
vector3d GetAngVelocity() const { return m_angVel; }
void SetAngSpeed(const double angspeed) { m_angSpeed = angspeed; }
double GetAngSpeed() const { return m_angSpeed; }
void SetRadius(double radius) { m_radius = radius; }
double GetRadius() const { return m_radius; }
bool IsRotFrame() const { return m_flags & FLAG_ROTATING; }
@ -72,7 +72,7 @@ public:
// For an object in a rotating frame, relative to non-rotating frames it
// must attain this velocity within rotating frame to be stationary.
vector3d GetStasisVelocity(const vector3d &pos) const { return -m_angVel.Cross(pos); }
vector3d GetStasisVelocity(const vector3d &pos) const { return -vector3d(0,m_angSpeed,0).Cross(pos); }
vector3d GetPositionRelTo(const Frame *relTo) const;
vector3d GetVelocityRelTo(const Frame *relTo) const;
@ -106,8 +106,8 @@ private:
matrix3x3d m_interpOrient;
vector3d m_vel; // note we don't use this to move frame. rather,
// orbital rails determine velocity.
vector3d m_angVel; // this however *is* directly applied (for rotating frames)
vector3d m_oldAngDisplacement;
double m_angSpeed; // this however *is* directly applied (for rotating frames)
double m_oldAngDisplacement;
std::string m_label;
double m_radius;
int m_flags;

View File

@ -531,7 +531,12 @@ static vector3d GetPosInFrame(Frame *frame, Frame *target, const vector3d &offse
static vector3d GetVelInFrame(Frame *frame, Frame *target, const vector3d &offset)
{
vector3d vel = vector3d(0.0);
if (target != frame) vel = -target->GetStasisVelocity(offset);
if (target != frame && target->IsRotFrame()) {
// double ang = Pi::game->GetTimeStep() * target->GetAngSpeed();
// vector3d newpos = offset * matrix3x3d::RotateYMatrix(ang);
// vel = (newpos - offset) / Pi::game->GetTimeStep();
vel = -target->GetStasisVelocity(offset); // stasis velocity not accurate enough
}
return target->GetOrientRelTo(frame) * vel + target->GetVelocityRelTo(frame);
}

View File

@ -490,8 +490,8 @@ static Frame *MakeFrameFor(SystemBody *sbody, Body *b, Frame *f)
rotFrame->SetRadius(frad);
matrix3x3d rotMatrix = matrix3x3d::RotateXMatrix(sbody->axialTilt.ToDouble());
vector3d angVel = vector3d(0.0, 2.0*M_PI/sbody->GetRotationPeriod(), 0.0);
rotFrame->SetAngVelocity(angVel);
double angSpeed = 2.0*M_PI/sbody->GetRotationPeriod();
rotFrame->SetAngSpeed(angSpeed);
if (sbody->rotationalPhaseAtStart != fixed(0))
rotMatrix = rotMatrix * matrix3x3d::RotateYMatrix(sbody->rotationalPhaseAtStart.ToDouble());

View File

@ -550,7 +550,7 @@ void SpaceStation::DockingUpdate(const double timeStep)
if (dt.stage < -m_type->shipLaunchStage && dt.ship->GetFlightState() != Ship::FLYING) {
// launch ship
dt.ship->SetFlightState(Ship::FLYING);
dt.ship->SetAngVelocity(GetFrame()->GetAngVelocity());
dt.ship->SetAngVelocity(vector3d(0,GetFrame()->GetAngSpeed(),0));
if (m_type->dockMethod == SpaceStationType::SURFACE) {
dt.ship->SetThrusterState(1, 1.0); // up
} else {

View File

@ -42,7 +42,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../src;../../win32/src;../../win32/include;../../contrib;../../src/win32"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS"
PreprocessorDefinitions="DEBUG_AUTOPILOT;WIN32;_DEBUG;_WINDOWS;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
SmallerTypeCheck="true"