mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 19:41:20 +02:00
Merge pull request #3507 from Atlante45/recording_frames_interpolation
Recording frames interpolation
This commit is contained in:
commit
4cdfe87cf1
2 changed files with 73 additions and 11 deletions
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
Player::Player(AvatarData* avatar) :
|
Player::Player(AvatarData* avatar) :
|
||||||
_recording(new Recording()),
|
_recording(new Recording()),
|
||||||
|
_currentFrame(-1),
|
||||||
|
_frameInterpolationFactor(0.0f),
|
||||||
_pausedFrame(-1),
|
_pausedFrame(-1),
|
||||||
_timerOffset(0),
|
_timerOffset(0),
|
||||||
_avatar(avatar),
|
_avatar(avatar),
|
||||||
|
@ -223,22 +225,65 @@ void Player::play() {
|
||||||
context = &_currentContext;
|
context = &_currentContext;
|
||||||
}
|
}
|
||||||
const RecordingFrame& currentFrame = _recording->getFrame(_currentFrame);
|
const RecordingFrame& currentFrame = _recording->getFrame(_currentFrame);
|
||||||
|
const RecordingFrame& nextFrame = _recording->getFrame(_currentFrame + 1);
|
||||||
|
|
||||||
_avatar->setPosition(context->position + context->orientation * currentFrame.getTranslation());
|
glm::vec3 translation = glm::mix(currentFrame.getTranslation(),
|
||||||
_avatar->setOrientation(context->orientation * currentFrame.getRotation());
|
nextFrame.getTranslation(),
|
||||||
_avatar->setTargetScale(context->scale * currentFrame.getScale());
|
_frameInterpolationFactor);
|
||||||
_avatar->setJointRotations(currentFrame.getJointRotations());
|
_avatar->setPosition(context->position + context->orientation * translation);
|
||||||
|
|
||||||
|
glm::quat rotation = safeMix(currentFrame.getRotation(),
|
||||||
|
nextFrame.getRotation(),
|
||||||
|
_frameInterpolationFactor);
|
||||||
|
_avatar->setOrientation(context->orientation * rotation);
|
||||||
|
|
||||||
|
float scale = glm::mix(currentFrame.getScale(),
|
||||||
|
nextFrame.getScale(),
|
||||||
|
_frameInterpolationFactor);
|
||||||
|
_avatar->setTargetScale(context->scale * scale);
|
||||||
|
|
||||||
|
|
||||||
|
QVector<glm::quat> jointRotations(currentFrame.getJointRotations().size());
|
||||||
|
for (int i = 0; i < currentFrame.getJointRotations().size(); ++i) {
|
||||||
|
jointRotations[i] = safeMix(currentFrame.getJointRotations()[i],
|
||||||
|
nextFrame.getJointRotations()[i],
|
||||||
|
_frameInterpolationFactor);
|
||||||
|
}
|
||||||
|
_avatar->setJointRotations(jointRotations);
|
||||||
|
|
||||||
HeadData* head = const_cast<HeadData*>(_avatar->getHeadData());
|
HeadData* head = const_cast<HeadData*>(_avatar->getHeadData());
|
||||||
if (head) {
|
if (head) {
|
||||||
head->setBlendshapeCoefficients(currentFrame.getBlendshapeCoefficients());
|
QVector<float> blendCoef(currentFrame.getBlendshapeCoefficients().size());
|
||||||
head->setLeanSideways(currentFrame.getLeanSideways());
|
for (int i = 0; i < currentFrame.getBlendshapeCoefficients().size(); ++i) {
|
||||||
head->setLeanForward(currentFrame.getLeanForward());
|
blendCoef[i] = glm::mix(currentFrame.getBlendshapeCoefficients()[i],
|
||||||
glm::vec3 eulers = glm::degrees(safeEulerAngles(currentFrame.getHeadRotation()));
|
nextFrame.getBlendshapeCoefficients()[i],
|
||||||
|
_frameInterpolationFactor);
|
||||||
|
}
|
||||||
|
head->setBlendshapeCoefficients(blendCoef);
|
||||||
|
|
||||||
|
float leanSideways = glm::mix(currentFrame.getLeanSideways(),
|
||||||
|
nextFrame.getLeanSideways(),
|
||||||
|
_frameInterpolationFactor);
|
||||||
|
head->setLeanSideways(leanSideways);
|
||||||
|
|
||||||
|
float leanForward = glm::mix(currentFrame.getLeanForward(),
|
||||||
|
nextFrame.getLeanForward(),
|
||||||
|
_frameInterpolationFactor);
|
||||||
|
head->setLeanForward(leanForward);
|
||||||
|
|
||||||
|
glm::quat headRotation = safeMix(currentFrame.getHeadRotation(),
|
||||||
|
nextFrame.getHeadRotation(),
|
||||||
|
_frameInterpolationFactor);
|
||||||
|
glm::vec3 eulers = glm::degrees(safeEulerAngles(headRotation));
|
||||||
head->setFinalPitch(eulers.x);
|
head->setFinalPitch(eulers.x);
|
||||||
head->setFinalYaw(eulers.y);
|
head->setFinalYaw(eulers.y);
|
||||||
head->setFinalRoll(eulers.z);
|
head->setFinalRoll(eulers.z);
|
||||||
head->setLookAtPosition(context->position + context->orientation * currentFrame.getLookAtPosition());
|
|
||||||
|
|
||||||
|
glm::vec3 lookAt = glm::mix(currentFrame.getLookAtPosition(),
|
||||||
|
nextFrame.getLookAtPosition(),
|
||||||
|
_frameInterpolationFactor);
|
||||||
|
head->setLookAtPosition(context->position + context->orientation * lookAt);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "WARNING: Player couldn't find head data.";
|
qDebug() << "WARNING: Player couldn't find head data.";
|
||||||
}
|
}
|
||||||
|
@ -332,10 +377,26 @@ bool Player::computeCurrentFrame() {
|
||||||
_currentFrame = 0;
|
_currentFrame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (_currentFrame < _recording->getFrameNumber() - 1 &&
|
qint64 elapsed = Player::elapsed();
|
||||||
_recording->getFrameTimestamp(_currentFrame) < elapsed()) {
|
while (_currentFrame < _recording->getFrameNumber() &&
|
||||||
|
_recording->getFrameTimestamp(_currentFrame) < elapsed) {
|
||||||
++_currentFrame;
|
++_currentFrame;
|
||||||
}
|
}
|
||||||
|
--_currentFrame;
|
||||||
|
|
||||||
|
if (_currentFrame == _recording->getFrameNumber() - 1) {
|
||||||
|
--_currentFrame;
|
||||||
|
_frameInterpolationFactor = 1.0f;
|
||||||
|
} else {
|
||||||
|
qint64 currentTimestamps = _recording->getFrameTimestamp(_currentFrame);
|
||||||
|
qint64 nextTimestamps = _recording->getFrameTimestamp(_currentFrame + 1);
|
||||||
|
_frameInterpolationFactor = (float)(elapsed - currentTimestamps) /
|
||||||
|
(float)(nextTimestamps - currentTimestamps);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_frameInterpolationFactor < 0.0f || _frameInterpolationFactor > 1.0f) {
|
||||||
|
_frameInterpolationFactor = 0.0f;
|
||||||
|
qDebug() << "Invalid frame interpolation value: overriding";
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ private:
|
||||||
QElapsedTimer _timer;
|
QElapsedTimer _timer;
|
||||||
RecordingPointer _recording;
|
RecordingPointer _recording;
|
||||||
int _currentFrame;
|
int _currentFrame;
|
||||||
|
float _frameInterpolationFactor;
|
||||||
int _pausedFrame;
|
int _pausedFrame;
|
||||||
qint64 _timerOffset;
|
qint64 _timerOffset;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue