Dev:Bone Layer

From Synfig Studio :: Documentation
Revision as of 23:29, 18 November 2008 by Genete (Talk | contribs) (What happen if there are more than one bone affecting the point?: Remove the concept of w depending on the distance)

Jump to: navigation, search

Initial seed for concepts

This portion of IRC logs sets the basis for the implementation of a Bone Layer. The interesting part is from 16:49 to 18:56.

Also this one has some interesting thoughts. From 8:20 to 14:43

Concepts

This is a not sorted list of concepts what I would write to let me clarify my self and also allow others to understand the next sections.

Bones intentions

Initial intention of Bones is attempt to emulate the skeleton of a vertebrate animal. In this way you have a skin and a skeleton. Skin is associated to the bones of the skeleton. When the skeleton moves the skin follows.

Application of bones in animation

In traditional animation produce a walk cycle implies draw each keyframe for the walk and maybe, depending on the walking speed, draw the in betweens too. To avoid to draw the in between images there comes the tweening animation programs (like synfig) to help the animator. Then the animator just need to draw the keyframes and the application would do the rest. That's quite good but in certain situations you see your self redrawing the same pose (with small variations) frequently at different times. Then the bones comes to help. They allow to to the animator in the following manner.

  • With the manipulation of a single object (or a set of them) you can manage a lot of points of the drawing definition.
  • Rotations of drawings using keyframes needs lots of them (by the nature that the tweening is defined in the x,y coordinates system and the rotation is performed in the angle, radius coordinate system). Using bones you can perform rotations of large angles with just two waypoints. As well as characters have limbs and limbs in living beings do mainly rotations, the usage of bones becomes handy in that kind of animations.
  • Once the character (or whatever thing that uses bones) is rigged (the skeleton structure is created and the relationship between the skin and it is set) it is possible to produce different kind of keyframes for different purposes: Walk, run, jump, sit, ...

How can we do this in Synfig?

Before we research how to do that in synfig, first let's see how is it done in a abstract mode. The relationship between the skeleton and the skin is in this way:

The Skin is made by Points and blines. Blines are defined by Points. Points are made of Vertexes and Tangents

Skeleton is made of bones and its relationship.

If Bones would have influence on the Vertexes and Tangents then the bones movements would move the points and therefore the skin would be moved.

That's the key, if we understand how does a bones has influence on a vertex and a tangent then we can find the way a skeleton can have influence over a skin.

Features of bones

By my experience with bones in other 2D animation applications, watching its strong and weak points, the bones needs to have the following features:

  • A bone has a origin place where the rotation is performed.
  • A bone has a length.
  • A bone has an angle with the horizontal.
  • A bone has a region of influence.
  • A bone can have a parent bone and only one.
  • A bone can have one (or more) child(ren) bone(s).
  • A skeleton is defined as a connected set of bones (consisting of exactly one parentless bone and its children bones and their children...).

All the bones on a synfig Document can produce several skeletons (depending on how many parent-less bones are in it).

How does a Vertex move under the influence of a single Bone?

Conceptually a bone has influence over a point doing affine transformation of it position according to the bone values. See also transformation matrix. A bone produces rotation, scale and translation to a point in this way:

File:Bonesimulation.png

As you can see the values that produces the movement of the point P to the point P' are given by:

  • Translation of the bone: O'-O
  • Rotation of the bone: alpha'-alpha
  • Scale of the bone: s=length'/length

Then, given a Point P in the 2D space and known the translation, rotation and scale of the bone you can calculate the new point position P' using this formulation:

Failed to parse (MathML with SVG or PNG fallback (recommended for modern browsers and accessibility tools): Invalid response ("Math extension cannot connect to Restbase.") from server "https://api.formulasearchengine.com/v1/":): {\displaystyle T(-O)=\begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ -O_x & -O_y & 1 \end{bmatrix} } Translation to origin (0,0)

Failed to parse (MathML with SVG or PNG fallback (recommended for modern browsers and accessibility tools): Invalid response ("Math extension cannot connect to Restbase.") from server "https://api.formulasearchengine.com/v1/":): {\displaystyle R(-alpha)=\begin{bmatrix} \cos(-alpha) & \sin(-alpha) & 0 \\ -\sin(-alpha) & \cos(-alpha) & 0 \\ 0 & 0 & 1 \end{bmatrix} } Rotate an angle of amount '-alpha' around the origin. That aligns the bone with the X axis

Failed to parse (MathML with SVG or PNG fallback (recommended for modern browsers and accessibility tools): Invalid response ("Math extension cannot connect to Restbase.") from server "https://api.formulasearchengine.com/v1/":): {\displaystyle S(lenght'/lenght)=\begin{bmatrix} length'/length & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix} } Scale a value of 's=length'/length' in the direction of X (the current direction of the bone).

Failed to parse (MathML with SVG or PNG fallback (recommended for modern browsers and accessibility tools): Invalid response ("Math extension cannot connect to Restbase.") from server "https://api.formulasearchengine.com/v1/":): {\displaystyle R(alpha)=\begin{bmatrix} \cos(alpha^') & \sin(alpha^') & 0 \\ -\sin(alpha^') & \cos(alpha^') & 0 \\ 0 & 0 & 1 \end{bmatrix} } Rotate an angle of amount 'alpha around the origin.

Failed to parse (MathML with SVG or PNG fallback (recommended for modern browsers and accessibility tools): Invalid response ("Math extension cannot connect to Restbase.") from server "https://api.formulasearchengine.com/v1/":): {\displaystyle V=\begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ O^'_x & O^'_y & 1 \end{bmatrix} } Translation to new position O'

Then the transformation from P to P' is give by the matrix multiplication:

Failed to parse (MathML with SVG or PNG fallback (recommended for modern browsers and accessibility tools): Invalid response ("Math extension cannot connect to Restbase.") from server "https://api.formulasearchengine.com/v1/":): {\displaystyle P'=P\cdot T(-O)\cdot R(-alpha) S_x(length'/lenght)\cdot R(alpha')\cdot T(O')}

What happen if there are more than one bone affecting the point?

The first thing you can think when you deal with more than one bone making influence over the same point is to calculate the average of the sum of the influences of all bones. So if there are N bones affecting to the point then we can think on sum all the resulting points from each bone and then divide the result by N to not scale the result.

Failed to parse (MathML with SVG or PNG fallback (recommended for modern browsers and accessibility tools): Invalid response ("Math extension cannot connect to Restbase.") from server "https://api.formulasearchengine.com/v1/":): {\displaystyle B=\frac{\sum_{k=1}^N B_k}{N} }

Where Failed to parse (MathML with SVG or PNG fallback (recommended for modern browsers and accessibility tools): Invalid response ("Math extension cannot connect to Restbase.") from server "https://api.formulasearchengine.com/v1/":): {\displaystyle B_k} is the bone matrix for the bone k on the point P.

That's fine but I would like to have more control to the way the bones affects to the points. When you move a bone it looks reasonable that not all the points are influence in the same way. This can be solved by using "weighted" average instead of a plain one. That means give more influence to one bone than others over the same point under similar geometrical position of the bones in relation to the point.

Failed to parse (MathML with SVG or PNG fallback (recommended for modern browsers and accessibility tools): Invalid response ("Math extension cannot connect to Restbase.") from server "https://api.formulasearchengine.com/v1/":): {\displaystyle B=\frac{\sum_{k=1}^N B_k \cdot w_k}{\sum_{k=1}^N w_k} }

Where Failed to parse (MathML with SVG or PNG fallback (recommended for modern browsers and accessibility tools): Invalid response ("Math extension cannot connect to Restbase.") from server "https://api.formulasearchengine.com/v1/":): {\displaystyle w_k} is the weight for the bone k over the point P.

Can Points (Bone influenced) be moved independently?

Yes, they should be. If not the animator is tight to only do the animation with the bones animation what would end to some insoluble problems during the animation. Considered this, the point position result would come from the addition of two terms: the movement of the point as described by (a) the influence of the bone(s) + (b) the free movement of the point in the 2D space. In terms of the interface with the user, the second term of the mentioned above is just obtained in this way:

1) In any position of the time line (bones are animated) the point P have a position given by the influence of the bones. Let's call P(B).

2) The user wrap a point, drags it, placing it at P'.

3) The final position of the point is P' but the user cannot modify the first term of what I mentioned above so the second term (b) becomes: P(animated)=P'-P(B).

Cool! We know how to calculate the position of the "free movement of the point" knowing the final -user desired- position of the bone (P') and the calculated position of the point based on bone(s) movement.

Rewinding to the concept introduced in the previous section (the amount of influence of each bone called w) you can remember that it was calculated based on the "distance" (d) of the point from the bone and the "strength" (s) of the bone. See the graphics before. As you can see, there are some of the possible w definitions that has a value of w=0 for d>s. It means that the weight of that bone over this point is null and doesn't contribute to the movement of the point resulting of the influence of the bone(s).

That possibility (w=0) triggers two questions:

1) What happen if all the bones has the weight w=0 for a certain point?.

2) If the point can move additionally to the bone movement influence, can the distance (d) to the bone produce that the weight (w) becomes w=0 and the point is out of influence from that bone? If the point goes out of all the bones influence regions it triggers the question 1).

Answer to 2):

We are assuming that the distance (d) from the point to the bone is calculated based on the current distance from the point to the bone. That's not necessarily true. We can have a kind of "static" point that defines the relative position of the point from the bone for the distance (d) calculation and then apply the weight to the bone(s) influence matrix regardless the current point position give by the sum of (a) + (b) (explained before).

Let's call that relative position Q. That "static" position can be given in two ways: in coordinates relative to each bone (a Failed to parse (MathML with SVG or PNG fallback (recommended for modern browsers and accessibility tools): Invalid response ("Math extension cannot connect to Restbase.") from server "https://api.formulasearchengine.com/v1/":): {\displaystyle Q_i } for each bone i) or a single absolute coordinate Q value for the point and the distances (d) for each bone is calculated based on an static set of bone positions (Failed to parse (MathML with SVG or PNG fallback (recommended for modern browsers and accessibility tools): Invalid response ("Math extension cannot connect to Restbase.") from server "https://api.formulasearchengine.com/v1/":): {\displaystyle B_s } ). In any case the weights (w) need some "static" values to get the information from. I type "static" and not static (without quotes) because I think that it can be an animatable value (but usually it isn't).