[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:
parent
438d986b47
commit
ad76b2ee25
@ -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) {
|
||||
|
@ -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.
|
||||
{
|
||||
|
@ -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;
|
||||
};
|
||||
|
1
resources/skottie/skottie-camera-one-node.json
Normal file
1
resources/skottie/skottie-camera-one-node.json
Normal 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":[]}
|
Loading…
Reference in New Issue
Block a user