Physics Based Animation Effects Final Report

Summary

The project

The project’s main goal was to create at least three new animation effects on LibreOffice Impress that are simulated using 2D physics engine Box2D. Which would use the 2D physics engine’s capabilities to create some exciting animations that bounce around interact with each other and hopefully look cool.

My work

First thing to do was bundling Box2D with the build system of LO.

After that, worked on a wrapper that was going to be the backbone of the project and abstract all Box2D related stuff. This wrapper didn’t take it’s final shape until the end of the project since it is the main place where the magic happened – throughout the project it always changed.

Building it from the start was useful though, since it gave me a solid vision on how would the animation engine interact with it (or what kind of information from LO would the wrapper need to function properly).

Later, I’ve connected up the animation engine creating a new animation node for physics animation by following the implementation of path motion animation. And worked on making them saveable through SMIL hierarchies on content.xml.

Up till this point all shapes in the slide were approximated by their bounding box in the simulations, which was not ideal. Therefore, I’ve worked on representing the shapes as closely as possible to their original shape. Got that to work by getting the shape’s bezier/polygon representation (simplifying it as much as i can without losing the resemblance of the original shape), triangulating it and adding the collection of triangles to a single physics body.


In the hope of spicing things up a little, added some options that can be used on xml hierarchies that make it possible to create more exciting physics based animation effects that specify the bounciness, density, and the starting velocity of the physics body.

To finish up, created a total of 4 animation effect presets that use the physics based animation effects.

Demonstration video

Please accept YouTube cookies to play this video. By accepting you will be accessing content from YouTube, a service provided by an external third party.

YouTube privacy policy

If you accept this notice, your choice will be saved and the page will refresh.

How does the current implementation function?

The Box2D wrapper lives in:

  • slideshow/source/engine/box2dtools.hxx
  • slideshow/source/engine/box2dtools.cxx

It manages the Box2D World and the Box2D Bodies. When a physics animation starts (if not initiated before by another physics animation) the Box2D World gets initiated and a physics body with an edge loop shaped fixture that represents the slide frame is created with it. This slide frame always has 100 meters width or height depending on which is actually greater in the current slide properties, and a scale factor is calculated depending on the slide size which is used in mapping the Box2D coordinates to LO coordinates and vice versa. Later, all the shapes in the current slide that are in the foreground (which are shapes that do not belong to the master slide and not a background shape) created as a static Box2D Body.


During this creation process if the shape is filled & closed it is created by triangulating the shape and adding the resulting triangles to the Box2D Body, this is necessary since a Box2D physics body can only have convex shaped fixtures.


If the shape isn’t a filled & closed one or is just an edge shape, it’s divided up into it’s edge segments and each edge segment is represented by a quadrilateral shaped fixture.


Here’s a visualization showing how a shape is represented in the Box2D world:

When a physics animation starts, it makes the corresponding physics body to it’s shape a dynamic one, and applies the density, bounciness, starting velocity parameters specified in the xml to it. On each update cycle physics animation steps through the simulation using box2DWorld::stepAmount.

If there are other type of animation effects going in parallel with a physics animation, those animation effects queue up updates on what property they have manipulated (position, rotation etc.) and to which value. And then when a physics animation calls box2DWorld::stepAmount, box2DWorld::processUpdateQueue is called and these updates are processed in a way that produce convincing simulations. For instance if it is a change in position, instead of just setting the corresponding physics body’s position, a linear velocity is calculated which will make the body travel to the given position in the time box2DWorld::stepAmount will step through and applied to the body.

When there are two physics animations going on in parallel, only one of them steps through the simulation. This is achieved using a simple lock mechanism. If the physics animation that was stepping the simulation ends, it unlocks and if there’s another one still going on it takes the lock.

Whats left to do or can be done?

  • Physics animations do not take in account animation effects that manipulate size and skew of the shapes.
  • Shapes that are self intersecting polygons/beziers are not handled properly.
  • Bounciness, density options can be added to the animation side panel so that the user can have more control over the animation effects.

Conclusion

Overall, working on this project was really fun! I’m pretty proud with the outcome, and hoping it is some nice eye candy that the community and the users of LibreOffice will like :). If you’d like the check out and play around with the physics based animations you can build from master or grab a nightly build!

I’m really thankful for Google and LibreOffice for providing me with such a great opportunity which helped me grow quite a bit! Thanks to everyone in the LibreOffice community for giving me a helping hand :). And most importantly, greatly thankful to Thorsten Behrens which was my mentor throughout the GSoC period, he has literally guided me everyday on what to do, what not to do and how to do, on top of it answered each of my silly newbie questions. You were the greatest mentor I could’ve asked for!

Since working with the LibreOffice community was great and now that I’m kind of warmed up working on LibreOffice, my plan is to keep hacking on LibreOffice and especially Impress from now on!

Commits

All of the commits I’ve sent at the GSoC period can be found at:
https://gerrit.libreoffice.org/q/owner:q.sarperakdemir%2540gmail.com+after:2020-05-15+before:2020-09-01+-status:abandoned

They are also listed below: