Cytopia icon indicating copy to clipboard operation
Cytopia copied to clipboard

Views Animation

Open ghost opened this issue 4 years ago • 1 comments

It should be possible for sprites to move in the world. For example if we want cars, we need to be able to move their sprites on a street. Developers should be able to describe an animation through a duration and a set of key frames. Each key frame must be represented as an affine transformation with an augmented matrix. To make this easy, there must be an AffineTransformation object made available. This object must have a constexpr constructor which allows the following operations:

  • Translate which moves the sprite around its origin
  • Rotate which rotates the sprite around its origin
  • Scale which scales the sprite around its origin The transformations must be applied in the following order: Scale, Rotate, Translate.

When the developer registers an animation, they must specify an AffineTransformation for each keyframe following the start t0. The Animation Engine must interpolate between each pair of successive keyframes. Each Affine transformation must apply on the position at the previous keyframe. For example, T(5, 0) + T(5, 0) will translate the object by T(10, 0) when comparing the last keyframe with t0. To interpolate between keyframes, there are two alternatives:

  1. Trivial way: The trivial way is to interpolate the rotation angle, the displacement, and the scaling factors. To do this, on every frame, we must scale the shape S/N where S is the scaling factor for one of the dimensions and N is the number of frames between the two successive keyframes. Then for rotation, we must rotate by Theta / N. We need to make sure that both of these operations are around the shape's barycenter. Finally for translation, we translate by T / N.

  2. Complex way: The issue with the previous way is that it restricts our transformations. For example, it's impossible for us to specify that our shape should move around in an orbit of pivot point between two keyframes. Instead, the shape will move linearly between the points and rotate onto itself. To improve on this, we can compute the Nth root of the Affine Matrix. If you think about it, we would like to apply a same transformation N times such that the end result is our affine matrix. Since applying a transformation means matrix multiplication, we are searching for the Nth root of a matrix. The issue is that there might be multiple roots of a matrix. We are looking for a unique one. We can use this trick to always get a unique result.

These two techniques are very different. It is up to the developer to choose which one they want to implement.

ghost avatar Sep 07 '19 05:09 ghost

I think we do not need to use such a complete system since the graphics use parallel projection. One of the advantages of said projection is that no scaling is needed when moving an object. So it would only really be required when an object is meant to literally shrink or grow.

Rotation could make sense, but would be rather limited in that a rotation of a 2D sprite in an isometric projection is equivalent to turning the 3D object around the $\begin{pmatrix}1\ 1\ 1\end{pmatrix}$ axis. Additionally, if we are not using a truly isometric perspective (are we?) it would also mean scaling along all axes with different factors.

Due to these points and the fact that the scaling and rotating of pixel-art itself is non-trivial and comparatively expensive, e.g.: https://en.wikipedia.org/wiki/Pixel-art_scaling_algorithms#RotSprite I would prefer just having translation as an in-game animation option. Which is kinda sad, since I was really eager to implement that matrix-exponent algorithm…

DanielMowitz avatar Aug 31 '22 11:08 DanielMowitz