[skottie] One-node camera support

So far Skottie has been assuming all cameras are two-node (have a point
of interest).

AE also supports one-node cameras, where the camera does not auto-orient
towards a POI but starts off perpendicular to the z == 0 plane.

(https://helpx.adobe.com/after-effects/how-to/camera-animation.html)

Change-Id: Id565de7d8feb9a762940ac372c1bbbcce2e2dfc6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/254559
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
This commit is contained in:
Florin Malita 2019-11-14 13:11:20 -05:00 committed by Skia Commit-Bot
parent 438d986b47
commit ad76b2ee25
4 changed files with 43 additions and 15 deletions

View File

@ -325,7 +325,12 @@ sk_sp<sksg::Transform> LayerBuilder::doAttachTransform(const AnimationBuilder& a
auto parent_transform = this->getParentTransform(abuilder, cbuilder, ttype);
if (this->isCamera()) {
auto camera_adapter = sk_make_sp<CameraAdapter>(abuilder.fSize);
// The presence of an anchor point property ('a') differentiates
// one-node vs. two-node cameras.
const auto camera_type = (*jtransform)["a"].is<skjson::NullValue>()
? CameraAdapter::Type::kOneNode
: CameraAdapter::Type::kTwoNode;
auto camera_adapter = sk_make_sp<CameraAdapter>(abuilder.fSize, camera_type);
abuilder.bindProperty<ScalarValue>(fJlayer["pe"],
[camera_adapter] (const ScalarValue& pe) {

View File

@ -120,42 +120,56 @@ void TransformAdapter3D::apply() {
fMatrixNode->setMatrix(this->totalMatrix());
}
CameraAdapter:: CameraAdapter(const SkSize& viewport_size)
: fViewportSize(viewport_size) {}
CameraAdapter:: CameraAdapter(const SkSize& viewport_size, Type type)
: fViewportSize(viewport_size)
, fType(type)
{}
CameraAdapter::~CameraAdapter() = default;
sk_sp<CameraAdapter> CameraAdapter::MakeDefault(const SkSize &viewport_size) {
auto adapter = sk_make_sp<CameraAdapter>(viewport_size);
auto adapter = sk_make_sp<CameraAdapter>(viewport_size, Type::kOneNode);
static constexpr float kDefaultAEZoom = 879.13f;
const auto center = SkVector::Make(viewport_size.width() * 0.5f,
viewport_size.height() * 0.5f);
adapter->setZoom(kDefaultAEZoom);
adapter->setAnchorPoint(TransformAdapter3D::Vec3({center.fX, center.fY, 0}));
adapter->setPosition (TransformAdapter3D::Vec3({center.fX, center.fY, -kDefaultAEZoom}));
return adapter;
}
SkPoint3 CameraAdapter::poi() const {
// AE supports two camera types:
//
// - one-node camera: does not auto-orient, and starts off perpendicular to the z = 0 plane.
//
// - two-node camera: has a point of interest (encoded as the anchor point), and auto-orients
// to point in its direction.
return fType == Type::kOneNode
? SkPoint3{ this->getPosition().fX,
this->getPosition().fY,
0 }
: SkPoint3{ this->getAnchorPoint().fX,
this->getAnchorPoint().fY,
-this->getAnchorPoint().fZ};
}
SkMatrix44 CameraAdapter::totalMatrix() const {
// Camera parameters:
//
// * location -> position attribute
// * point of interest -> anchor point attribute
// * point of interest -> anchor point attribute (two-node camera only)
// * orientation -> rotation attribute
//
SkPoint3 pos = { this->getPosition().fX,
this->getPosition().fY,
-this->getPosition().fZ },
poi = { this->getAnchorPoint().fX,
this->getAnchorPoint().fY,
-this->getAnchorPoint().fZ },
up = { 0, 1, 0 };
const auto pos = SkPoint3{ this->getPosition().fX,
this->getPosition().fY,
-this->getPosition().fZ },
up = SkPoint3{ 0, 1, 0 };
// Initial camera vector.
SkMatrix44 cam_t;
Sk3LookAt(&cam_t, pos, poi, up);
Sk3LookAt(&cam_t, pos, this->poi(), up);
// Rotation origin is camera position.
{

View File

@ -172,9 +172,14 @@ private:
class CameraAdapter final : public TransformAdapter3D {
public:
enum class Type {
kOneNode, // implicitly facing the z == 0 plane, does not auto-orient
kTwoNode, // explicitly facing a POI (the anchor point), auto-orients
};
static sk_sp<CameraAdapter> MakeDefault(const SkSize& viewport_size);
explicit CameraAdapter(const SkSize& viewport_size);
CameraAdapter(const SkSize& viewport_size, Type);
~CameraAdapter() override;
ADAPTER_PROPERTY(Zoom, SkScalar, 0)
@ -182,7 +187,10 @@ public:
private:
SkMatrix44 totalMatrix() const override;
SkPoint3 poi() const;
const SkSize fViewportSize;
const Type fType;
using INHERITED = TransformAdapter3D;
};

View File

@ -0,0 +1 @@
{"v":"5.5.5","fr":60,"ip":0,"op":601,"w":1920,"h":1080,"nm":"Comp 1","ddd":1,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"rc","d":1,"s":{"a":0,"k":[1500,750],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"rc","d":1,"s":{"a":0,"k":[812,403],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 2","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.171292886138,0.169715076685,0.803477346897,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false}],"ip":0,"op":601,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":13,"nm":"Camera 1","sr":1,"pe":{"a":0,"k":2133.333,"ix":1},"ks":{"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[560,740,-2133.333],"to":[133.333,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[1360,740,-2133.333],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":120,"s":[1360,340,-2133.333],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":180,"s":[560,340,-2133.333],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":240,"s":[560,740,-2133.333],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":300,"s":[560,740,-3104.333],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":360,"s":[1360,740,-3104.333],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":420,"s":[1360,340,-3104.333],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":480,"s":[560,340,-3104.333],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":540,"s":[560,740,-3104.333],"to":[0,0,0],"ti":[0,0,0]},{"t":600,"s":[560,740,-2133.3]}],"ix":2},"or":{"a":0,"k":[0,0,0],"ix":7},"rx":{"a":0,"k":0,"ix":8},"ry":{"a":0,"k":0,"ix":9},"rz":{"a":0,"k":0,"ix":10}},"ip":0,"op":601,"st":0,"bm":0},{"ddd":1,"ind":3,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"rx":{"a":0,"k":0,"ix":8},"ry":{"a":0,"k":0,"ix":9},"rz":{"a":0,"k":0,"ix":10},"or":{"a":0,"k":[0,0,0],"ix":7},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[0,0,1000],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[35,35],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[100,100],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0,1,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":603,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":1,"nm":"Light Gray Solid 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,540,0],"ix":2},"a":{"a":0,"k":[960,540,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"sw":1920,"sh":1080,"sc":"#c8c8c8","ip":0,"op":603,"st":0,"bm":0}],"markers":[]}