here is the snapshot (keyframe) structure
Code: Select all
struct SRecordedFrame
{
vector3df position;
vector3df target;
unsigned int transition_time;
};
snapshots are saved in std::vector container
here is my take snapshot method
Code: Select all
void CGameModeRail::takeSnapshot()
{
SRecordedFrame frame;
frame.position = m_pGame->getPlayerCamera()->getAbsolutePosition();
frame.target = m_pGame->getPlayerCamera()->getTarget();
frame.transition_time = 1000;
m_RecordedFrames.push_back(frame);
}
and finally, here is the animate method
Code: Select all
void CGameModeRail::animatePlayerMovement(int delta)
{
if (m_RecordedFrames.size() < 2)
{
return;
}
if (!m_bPlaybacking)
{
return;
}
//get two frames we will be interpolating between
SRecordedFrame &a = m_RecordedFrames[m_nStage];
SRecordedFrame &b = m_RecordedFrames[m_nStage + 1];
int transition_time = a.transition_time;
//advance time
m_nActionTime += delta;
//calculate transition ratio
float transition_ratio;
//finished?
if (m_nActionTime > transition_time)
{
//goto next move
m_nActionTime = 0;
++m_nStage;
transition_ratio = 1.0f;
//or stop playing when done
if (m_nStage + 1 == m_RecordedFrames.size())
{
m_bPlaybacking = false;
}
}
//not yet finished
else
{
transition_ratio = (float)m_nActionTime / transition_time;
}
//update position
vector3df new_position = a.position.getInterpolated(b.position, transition_ratio);
m_pGame->getPlayerCamera()->setPosition(new_position);
//update rotation
vector3df a_rotation = a.target - a.position;
vector3df b_rotation = b.target - b.position;
quaternion a_q(a_rotation);
quaternion b_q(b_rotation);
quaternion new_q;
new_q.slerp(a_q, b_q, transition_ratio);
vector3df new_rotation;
new_q.toEuler(new_rotation);
m_pGame->getPlayerCamera()->setTarget(new_position + new_rotation);
}
and because rotation of camera is always zero vector, I am using: setTarget(pos + rot)
and now, even that I am using quaternions, when I take one snapshot looking forward, and another snapshot looking backward (about 180 degrees)
when I then play the animation, the transition between frames is not straight, but its like some wave, because exactly between the frames
the camera is looking down, which I think is due gimbal lock.
Gimbal lock was present when I was using euler rotation interpolation, but why the problem stays, when I am now using quaternions?