Future of the animation feature
Boudewijn Rempt
boud at valdyas.org
Sat Dec 20 10:57:49 UTC 2014
Jouni's mail got chewed up by kmail :-(. We did discuss the idea a bit on
irc, though. I think it's important to start with the basic way an
animation is structured, apart from any datamodel we currently have in
Krita.
At its most basic, an animation is a sparse 2d table, with every cell
potentiall containing an image. Every column is a frame, every row
corresponds to something structural in the animator's mind.
That's to say, all frames have the same structure, but some slots in that
structure can be empty.
Now from this to Krita, and disregarding the current data model, which is
half hidden in a QDomDocument and half some code I was experimenting with
when I was trying to understand the requirements:
* a frame should be rendered as a Krita layerstack, i.e., when a user
activates a frame, they should get a KisImage to work on.
* every frame have the same organization of layers: so the structure of
all the KisImages the user works on is the same, but some or even
most layers are invisible.
* but from frame to frame, a particular layer can be used or not: so when
creating a frame, each layer only exists in potentia, and can be either
cloned from another instance of a KisLayer in that stack position.
I'm not sure how that ties in with having a special animation layer type
-- I cannot see how we can do anything if the structure of an animation
does not transcend that of a KisImage.
So the datamodel I was investigating was like this:
KisAnimation:
* contains one or more KisAnimationLayer (which is not a KisNode!)
KisAnimationLayer:
* contains one or more KisAnimationCell instances and positions
them on the timeline
* knows which KisNode type its frames should be
KisAnimationCell (KisAnimationFrame in the source code...)
* contains an actual reference to a KisNode. That is to say, it's a
single cell in the sparse 2d table.
I also think we'd need:
KisAnimationFrame:
* contains all the cells for a particular frame
The next problem is memory and caching. Eric wants to be able to have a
few hundred frames and a hundred layers. That means we just cannot keep
all the image data in memory, we have to write nodes to disk and keep
rendered frames cached. Pretty much all animation applications I've looked
at do that in one way or another, so it's a good bet that we'll need to do
that, too.
I really want to get this structure explicit and done before working on
the rest -- we've had too many attempts where the animation's structure
was hidden in a QDomDocument or fakes by doing weird things to a KisImage.
On Sat, 20 Dec 2014, Dmitry Kazakov wrote:
> Hi, Jouni!
>
>
> Nearly all animation related data and functionality is currently contained within a single class,
> KisAnimationDoc. It handles all kinds of operations from playback to renaming files. This needs
> refactoring to improve the separation of concerns.
>
>
> Yeah, maintaining the code contained in a single class might be rather
> complicated. More than that, right now we already have at least two
> implementations of the animation :)
We have at least three, two by Torio Mlshi, one by Somsubhra, and there's
what I was doing while trying to figure out what we'd need to do for Eric.
> Before starting refactoring I would highly recommend to prepare at least
> a draft of UML diagrams of what you are planning to achieve. This way
> the refactoring will come faster and more successful. I usually create
> diagrams using http://creately.com They allow create public diagrams and
> edit them collaboratively.
>
>
> Another issue is that currently the animator effectively reimplements its own layer stack. I think
> this is unnecessary. I suggest we add a new layer type instead, an animated layer, which would
> integrate into the Krita layer stack. Existing workflows with layer groups, masks, filters, etc.
> would work as expected with little or no additional work.
>
> This is implementable as a subclass of KisPaintLayer. All the frames associated with the animation
> layer would be contained here. As the active frame of the animation is changed, this class would
> swap the appropriate contents into view. I have made a quick prototype to test this concept and it
> works surprisingly well.
>
>
> Yes, I totally agree with this solution. We had talks about that some
> time ago. I'm not sure whether and to what extent they were implemented
> in the animation branch.
>
> There are actually two approaches for that: you can switch a paint
> device in KisPaintLayer::paintDevice() or you can switch the data
> manager inside the paint device itself. I would recommend the second
> approach, because in many places in Krita (e.g. in KisCloneLayer) we
> store a pointer to other layer's original, so switching the paint device
> would break at least clone layers.
Well, I'm not really happy with this solution, because we'd need to have
an animation layer for every kind of layer, except for the group layer. (A
file layer needs to switch to a different file along the timeline as well
as a paint layer, a filter layer needs a different config along the
timeline). I think it would also complicate the bookkeeping of what is
shown in which cell/frame.
Boudewijn
More information about the kimageshop
mailing list