Skip to content

Commit

Permalink
lots more timestep fix work. cities have disappeared and things start…
Browse files Browse the repository at this point in the history
… off pretty weird when docked...
  • Loading branch information
tomm committed Nov 16, 2010
1 parent 9393c49 commit 6a6b5f5
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 36 deletions.
7 changes: 7 additions & 0 deletions src/Body.cpp
Expand Up @@ -116,6 +116,13 @@ vector3d Body::GetPositionRelTo(const Frame *relTo) const
return m * GetPosition();
}

vector3d Body::GetInterpolatedPositionRelTo(const Frame *relTo) const
{
matrix4x4d m;
Frame::GetFrameTransform(m_frame, relTo, m);
return m * GetInterpolatedPosition();
}

vector3d Body::GetPositionRelTo(const Body *relTo) const
{
return GetPositionRelTo(relTo->GetFrame()) - relTo->GetPosition();
Expand Down
27 changes: 20 additions & 7 deletions src/Body.h
Expand Up @@ -24,13 +24,6 @@ class Body: public Object {
virtual vector3d GetPosition() const = 0; // within frame
virtual void SetVelocity(vector3d v) { assert(0); }
virtual vector3d GetVelocity() const { return vector3d(0.0); }
virtual void GetInterpolatedPositionOrientation(float alpha, matrix4x4d &outOrient) const {
outOrient = matrix4x4d::Identity();
vector3d v = GetVelocity();
outOrient[12] = v.x;
outOrient[13] = v.y;
outOrient[14] = v.z;
}
/** Should really be renamed to GetClipRadius */
virtual double GetBoundingRadius() const = 0;
virtual double GetMass() const { assert(0); return 0; }
Expand Down Expand Up @@ -69,6 +62,23 @@ class Body: public Object {
// Only Space::KillBody() should call this method.
void MarkDead() { m_dead = true; }
bool IsDead() const { return m_dead; }
/** Interpolated between physics ticks. */
const matrix4x4d &GetInterpolatedTransform() const { return m_interpolatedTransform; }
vector3d GetInterpolatedPosition() const {
return vector3d(m_interpolatedTransform[12], m_interpolatedTransform[13], m_interpolatedTransform[14]);
}
vector3d GetInterpolatedPositionRelTo(const Frame *relTo) const;

/** should set m_interpolatedTransform to the smoothly interpolated
* value (interpolated by 0 <= alpha <=1) between the previous and current
* physics tick */
virtual void UpdateInterpolatedTransform(double alpha) {
const vector3d pos = GetPosition();
m_interpolatedTransform = matrix4x4d::Identity();
m_interpolatedTransform[12] = pos.x;
m_interpolatedTransform[13] = pos.y;
m_interpolatedTransform[14] = pos.z;
}

enum { FLAG_CAN_MOVE_FRAME = (1<<0),
FLAG_LABEL_HIDDEN = (1<<1),
Expand All @@ -77,6 +87,9 @@ class Body: public Object {
virtual void Save(Serializer::Writer &wr);
virtual void Load(Serializer::Reader &rd);
unsigned int m_flags;

// Interpolated draw orientation-position
matrix4x4d m_interpolatedTransform;
private:
// frame of reference
Frame *m_frame;
Expand Down
20 changes: 12 additions & 8 deletions src/DynamicBody.cpp
Expand Up @@ -11,6 +11,7 @@ DynamicBody::DynamicBody(): ModelBody()
m_flags = Body::FLAG_CAN_MOVE_FRAME;
m_orient = matrix4x4d::Identity();
m_oldOrient = m_orient;
m_oldAngDisplacement = vector3d(0.0);
m_force = vector3d(0.0);
m_torque = vector3d(0.0);
m_vel = vector3d(0.0);
Expand Down Expand Up @@ -170,30 +171,31 @@ void DynamicBody::TimeStepUpdate(const float timeStep)

m_force = vector3d(0.0);
m_torque = vector3d(0.0);
} else {
m_oldOrient = m_orient;
m_oldAngDisplacement = vector3d(0.0);
}
}

void DynamicBody::GetInterpolatedPositionOrientation(float alpha, matrix4x4d &outOrient) const
void DynamicBody::UpdateInterpolatedTransform(double alpha)
{
assert ((alpha >= 0) && (alpha <= 1.0));
// interpolating matrices like this is a sure sign of madness
outOrient = alpha*m_orient + (1.0-alpha)*m_oldOrient;
vector3d outPos = alpha*vector3d(m_orient[12], m_orient[13], m_orient[14]) +
(1.0-alpha)*vector3d(m_oldOrient[12], m_oldOrient[13], m_oldOrient[14]);

outOrient = m_oldOrient;
m_interpolatedTransform = m_oldOrient;
{
double len = m_oldAngDisplacement.Length() * (double)alpha;
if (len != 0) {
vector3d rotAxis = m_oldAngDisplacement.Normalized();
matrix4x4d rotMatrix = matrix4x4d::RotateMatrix(len,
rotAxis.x, rotAxis.y, rotAxis.z);
outOrient = rotMatrix * outOrient;
m_interpolatedTransform = rotMatrix * m_interpolatedTransform;
}
}
outOrient[12] = outPos.x;
outOrient[13] = outPos.y;
outOrient[14] = outPos.z;
m_interpolatedTransform[12] = outPos.x;
m_interpolatedTransform[13] = outPos.y;
m_interpolatedTransform[14] = outPos.z;
}

void DynamicBody::UndoTimestep()
Expand All @@ -219,6 +221,8 @@ void DynamicBody::SetRotMatrix(const matrix4x4d &r)
{
vector3d pos = GetPosition();
m_orient = r;
m_oldOrient = r;
m_oldAngDisplacement = vector3d(0.0);
SetPosition(pos);
}

Expand Down
4 changes: 1 addition & 3 deletions src/DynamicBody.h
Expand Up @@ -17,9 +17,6 @@ class DynamicBody: public ModelBody {
virtual void SetPosition(vector3d p);
virtual vector3d GetPosition() const;
virtual vector3d GetVelocity() const;
/** Give the interpolated position (0 <= alpha <= 1) between previous
* and current physics tick */
virtual void GetInterpolatedPositionOrientation(float alpha, matrix4x4d &outOrient) const;
vector3d GetAngVelocity() const;
void SetAngVelocity(vector3d v);
void SetMesh(ObjMesh *m);
Expand All @@ -45,6 +42,7 @@ class DynamicBody: public ModelBody {
void AddRelForce(const vector3d);
void AddRelTorque(const vector3d);
double GetAtmosphericDragGs() const { return m_atmosDragGs; }
virtual void UpdateInterpolatedTransform(double alpha);

protected:
virtual void Save(Serializer::Writer &wr);
Expand Down
9 changes: 9 additions & 0 deletions src/ModelBody.cpp
Expand Up @@ -124,6 +124,15 @@ void ModelBody::GetRotMatrix(matrix4x4d &m) const
m = m_geom->GetRotation();
}

void ModelBody::UpdateInterpolatedTransform(double alpha)
{
const vector3d pos = GetPosition();
GetRotMatrix(m_interpolatedTransform);
m_interpolatedTransform[12] = pos.x;
m_interpolatedTransform[13] = pos.y;
m_interpolatedTransform[14] = pos.z;
}

void ModelBody::TransformToModelCoords(const Frame *camFrame)
{
matrix4x4d m = m_geom->GetTransform();
Expand Down
2 changes: 2 additions & 0 deletions src/ModelBody.h
Expand Up @@ -35,6 +35,8 @@ class ModelBody: public Body {
void SetModel(const char *lmrModelName, bool isStatic = false);

void RenderLmrModel(const vector3d &viewCoords, const matrix4x4d &viewTransform);

virtual void UpdateInterpolatedTransform(double alpha);
protected:
virtual void Save(Serializer::Writer &wr);
virtual void Load(Serializer::Reader &rd);
Expand Down
29 changes: 18 additions & 11 deletions src/Pi.cpp
Expand Up @@ -824,8 +824,6 @@ void Pi::MainLoop()
int frame_stat = 0;
int phys_stat = 0;
char fps_readout[128];
Uint32 time_before_frame = SDL_GetTicks();
int time_to_simulate = 0;
double time_player_died = 0;
#ifdef MAKING_VIDEO
Uint32 last_screendump = SDL_GetTicks();
Expand All @@ -844,16 +842,20 @@ void Pi::MainLoop()
Pi::frameTime = newTime - currentTime;
if (Pi::frameTime > 0.25) Pi::frameTime = 0.25;
currentTime = newTime;
accumulator += Pi::frameTime;
accumulator += Pi::frameTime * GetTimeAccel();

while (accumulator >= dt) {
const float step = Pi::GetTimeStep();
if (step) Space::TimeStep(step);
gameTime += step;
phys_stat++;

t += dt;
accumulator -= dt;
const float step = Pi::GetTimeStep();
if (step) {
while (accumulator >= dt) {
Space::TimeStep(step);
gameTime += step;
phys_stat++;

t += dt;
accumulator -= dt;
}
} else {
// paused
}
Pi::gameTickAlpha = accumulator / dt;

Expand All @@ -866,6 +868,11 @@ void Pi::MainLoop()
Render::PrepareFrame();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

/* Calculate position for this rendered frame (interpolated between two physics ticks */
for (std::list<Body*>::iterator i = Space::bodies.begin(); i != Space::bodies.end(); ++i) {
(*i)->UpdateInterpolatedTransform(Pi::GetGameTickAlpha());
}

currentView->Draw3D();
// XXX HandleEvents at the moment must be after view->Draw3D and before
Expand Down
3 changes: 1 addition & 2 deletions src/Space.cpp
Expand Up @@ -873,8 +873,7 @@ void Render(const Frame *cam_frame)
int idx = 0;
for (std::list<Body*>::iterator i = bodies.begin(); i != bodies.end(); ++i) {
/* This is the position-orientation interpolated between the previous and current physics tick */
matrix4x4d orient;
(*i)->GetInterpolatedPositionOrientation(Pi::GetGameTickAlpha(), orient);
matrix4x4d orient = (*i)->GetInterpolatedTransform();
const vector3d pos(orient[12], orient[13], orient[14]);

Frame::GetFrameTransform((*i)->GetFrame(), cam_frame, bz[idx].viewTransform);
Expand Down
9 changes: 4 additions & 5 deletions src/WorldView.cpp
Expand Up @@ -166,8 +166,8 @@ vector3d WorldView::GetExternalViewTranslation()
vector3d p = vector3d(0, 0, m_externalViewDist);
p = matrix4x4d::RotateXMatrix(-DEG2RAD(m_externalViewRotX)) * p;
p = matrix4x4d::RotateYMatrix(-DEG2RAD(m_externalViewRotY)) * p;
matrix4x4d m;
Pi::player->GetRotMatrix(m);
matrix4x4d m = Pi::player->GetInterpolatedTransform();
m.ClearToRotOnly();
p = m*p;
return p;
}
Expand Down Expand Up @@ -435,8 +435,7 @@ void WorldView::Draw3D()

// interpolate between last physics tick position and current one,
// to remove temporal aliasing
matrix4x4d pposOrient;
Pi::player->GetInterpolatedPositionOrientation(Pi::GetGameTickAlpha(), pposOrient);
matrix4x4d pposOrient = Pi::player->GetInterpolatedTransform();
const vector3d ppos(pposOrient[12], pposOrient[13], pposOrient[14]);

// make temporary camera frame at player
Expand Down Expand Up @@ -925,7 +924,7 @@ void WorldView::DrawHUD(const Frame *cam_frame)
for(std::list<Body*>::iterator i = Space::bodies.begin(); i != Space::bodies.end(); ++i) {
if ((GetCamType() != WorldView::CAM_EXTERNAL) && (*i == Pi::player)) continue;
Body *b = *i;
vector3d _pos = b->GetPositionRelTo(cam_frame);
vector3d _pos = b->GetInterpolatedPositionRelTo(cam_frame);

if (_pos.z < 0
&& Gui::Screen::Project (_pos.x,_pos.y,_pos.z, modelMatrix, projMatrix, viewport, &_pos.x, &_pos.y, &_pos.z)) {
Expand Down

0 comments on commit 6a6b5f5

Please sign in to comment.