Permalink
Browse files

Interpolate the camera transform when adding a new camera key

  • Loading branch information...
chchwy committed Sep 22, 2017
1 parent 53ec07f commit 0a9d393b28a4a4cf7942bcf23861bcfec87c16e1
View
@@ -39,6 +39,7 @@ GNU General Public License for more details.
#include "bitmapimage.h"
#include "vectorimage.h"
#include "soundclip.h"
#include "camera.h"
#include "movieexporter.h"
#include "filedialogex.h"
@@ -272,11 +273,11 @@ void ActionCommands::addNewKey()
{
KeyFrame* key = mEditor->addNewKey();
SoundClip* clip = dynamic_cast< SoundClip* >( key );
SoundClip* clip = dynamic_cast<SoundClip*>(key);
if ( clip )
{
FileDialog fileDialog( mParent );
QString strSoundFile = fileDialog.openFile( FileType::SOUND );
QString strSoundFile = fileDialog.openFile(FileType::SOUND);
if ( strSoundFile.isEmpty() )
{
@@ -286,6 +287,16 @@ void ActionCommands::addNewKey()
Status st = mEditor->sound()->loadSound( clip, strSoundFile );
Q_ASSERT( st.ok() );
}
Camera* cam = dynamic_cast<Camera*>(key);
if (cam)
{
auto camLayer = static_cast<LayerCamera*>(mEditor->layers()->currentLayer());
Q_ASSERT(camLayer);
camLayer->LinearInterpolateTransform(cam);
mEditor->view()->updateViewTransforms();
}
}
void ActionCommands::removeKey()
@@ -74,9 +74,9 @@ class ViewManager : public BaseManager
void onCurrentFrameChanged();
private:
void updateViewTransforms();
private:
QTransform mView;
QTransform mViewInverse;
QTransform mViewCanvas;
@@ -33,6 +33,14 @@ Camera::~Camera()
{
}
void Camera::assign(const Camera& rhs)
{
mTranslate = rhs.mTranslate;
mRotate = rhs.mRotate;
mScale = rhs.mScale;
updateViewTransform();
}
QTransform Camera::getView()
{
if (mNeedUpdateView)
@@ -74,6 +82,11 @@ void Camera::translate(float dx, float dy)
mNeedUpdateView = true;
}
void Camera::translate(const QPointF pt)
{
translate(pt.x(), pt.y());
}
void Camera::rotate(float degree)
{
mRotate = degree;
@@ -31,8 +31,10 @@ class Camera : public KeyFrame
QTransform getView();
void reset();
void updateViewTransform();
void assign(const Camera& rhs);
void translate(float dx, float dy);
void translate(const QPointF);
QPointF translation() { return mTranslate; }
void rotate(float degree);
@@ -102,7 +102,7 @@ void CameraPropertiesDialog::setHeight(int height)
LayerCamera::LayerCamera( Object* object ) : Layer( object, Layer::CAMERA )
{
mName = QString(tr("Camera Layer"));
viewRect = QRect(QPoint(-320, -240), QSize(640, 480));
viewRect = QRect(QPoint(-400, -300), QSize(800, 600));
dialog = NULL;
}
@@ -150,11 +150,11 @@ QTransform LayerCamera::getViewAtFrame(int frameNumber)
return camera1->view;
}
int frame1 = camera1->pos();
int frame2 = camera2->pos();
double frame1 = camera1->pos();
double frame2 = camera2->pos();
// linear interpolation
qreal c2 = ( frameNumber - frame1 + 0.0 ) / ( frame2 - frame1 );
qreal c2 = ( frameNumber - frame1) / ( frame2 - frame1 );
qreal c1 = 1.0 - c2;
auto interpolation = [=]( double f1, double f2 ) -> double
@@ -171,6 +171,55 @@ QTransform LayerCamera::getViewAtFrame(int frameNumber)
}
void LayerCamera::LinearInterpolateTransform(Camera* cam)
{
Q_ASSERT(keyFrameCount() > 0);
int frameNumber = cam->pos();
Camera* camera1 = static_cast<Camera*>(getLastKeyFrameAtPosition(frameNumber - 1));
int nextFrame = getNextKeyFramePosition(frameNumber);
Camera* camera2 = static_cast<Camera*>(getLastKeyFrameAtPosition(nextFrame));
if (camera1 == NULL && camera2 == NULL)
{
return; // do nothing
}
else if (camera1 == NULL && camera2 != NULL)
{
return cam->assign(*camera2);
}
else if (camera2 == NULL && camera1 != NULL)
{
return cam->assign(*camera1);
}
if (camera1 == camera2)
{
return cam->assign(*camera1);
}
double frame1 = camera1->pos();
double frame2 = camera2->pos();
// linear interpolation
double c2 = (frameNumber - frame1) / (frame2 - frame1);
auto lerp = [](double f1, double f2, double ratio) -> double
{
return f1 * (1.0 - ratio) + f2 * ratio;
};
double dx = lerp(camera1->translation().x(), camera2->translation().x(), c2);
double dy = lerp(camera1->translation().y(), camera2->translation().y(), c2);
double r = lerp(camera1->rotation(), camera2->rotation(), c2);
double s = lerp(camera1->scaling(), camera2->scaling(), c2);
cam->translate(dx, dy);
cam->rotate(r);
cam->scale(s);
}
QRect LayerCamera::getViewRect()
{
return viewRect;
@@ -60,6 +60,7 @@ class LayerCamera : public Layer
Camera* getCameraAtFrame(int frameNumber);
Camera* getLastCameraAtFrame(int frameNumber, int increment);
QTransform getViewAtFrame(int frameNumber);
void LinearInterpolateTransform(Camera*);
QRect getViewRect();
QSize getViewSize();

0 comments on commit 0a9d393

Please sign in to comment.