Animation/interactions progress! (Patreon)
Content
Hi all!
We hope you're doing well!
This has been a very productive month for us. We've been hard at work integrating our new physics engine (that we demonstrated some time ago) into FurryVNE. As you may know, the idea is to try and completely replace previous animation systems with this new technology, in the hopes that it will leverage a ton of benefits and a much better experience in general. There were many questions marks regarding whether or not this physics engine could actually be adapted to accomplish what we need it to do, but after this months work, we are hopeful and very excited!
So read on to discover our thoughts behind all this - why we are going down this path, what a successful implementation would mean, as well as a detailed description of the implementation itself, how it differs from our previous implementation and why its potential is higher.
The old system
The animation in Yiffalicious and the posing tools in FurryVNE (so far) has been based on an IK system known as "FinalIK". It's essentially a tech for affecting a rig (a skeleton) through the help of control points. I.e., rather than manually editing the rotation of bones to configure a certain pose, a control point (like that of the hand) is placed somewhere in the scene, and the IK system automatically figures out how to rotate the bones in the skeleton in order for the hand to reach that point (without the skeleton deforming in a way that would look too unnatural).
There's no problem with the concept of IK in itself. Indeed, even our new system could be considered an IK system as well to some extent (although the way it functions is very different from the one currently employed). But... the problem with the system we were using is that it was applied independently and sequentially. (We will go into detail about this below.) Furthermore, since the system doesn't have any physics in it, we had to combine it with other systems to get the kind of functionality that we needed. In Yiffalicious, we were using a total of 4 different systems for the animation and physics (not counting our own implementation combining them), all running separately from eachother and in a sequential manner, not only affecting performance but also making the implementation complicated for us, as well as introducing limits as to what could be achieved using it (due to performance considerations).
The problem with the old systems
As stated in the previous paragraph, the previous IK system was solved sequentially. Each character was running it's own IK solver - control points were placed in certain locations, the system figured out how the skeleton is supposed to rotate its bones in order for them to reach those desired locations. That's all fine and dandy... if the animation only depends on itself. However, in an environment as complicated as the ones you can create with multiple characters intimately interacting with eachother, suddenly it's not enough. Why? Because, if any of the control points depend on the result of another IK solver, it means they wouldn't end up in the correct positions.
To better explain this, picture this scenario:
One character (A) is standing up, thrusting another character (B) from behind (who is bent over). The thrusting character (A) has one hand placed on (B's) elbow, while (B) is reaching back, placing a hand on (A's) back. (This is a nightmare scenario for the IK system to figure out.)
Ok, so now lets start trying to solve this, sequentially.
Starting with (A), we first reset the character's bones, making it stand in a T-Pose (as has to be done for the old IK system to work, every frame, since otherwise it becomes unstable). Then, we move on to solving the IK pose (the control points that result in the standing pose). (The hand's control point is on (B's) elbow). We solve this IK and get a pose. In order for the character to reach the elbow, the spine and arm is rotated in a specific way. All is fine (for now).
Now, we move on to (B). The character's skeleton is reset. Since the character is being thrusted, it is moved a little bit. Through the help of control points, we make the character bend over. Also, the hand control point is placed on (A's) back. We solve this and get a pose. Excellent. The pose matches what we want to fulfill the constraints [for this current (B) character].
However, now, with this new pose, the elbow of (B) doesn't quite match the position it had when (A) did its solving. It has moved slightly. So the hand of (A) doesn't land on the elbow anymore. The only way to fix this is to solve (A) again, so that it matches the new elbow pose of (B). Alright, so we do this and get a new pose for (A). The spine and arm is rotated to satisfy our constraints. Excellent.
But now the hand (B) doesn't quite land where it needs to be, since the back of (A) was slightly shifted when it solved to adapt to (B).
Do you see where this is going... ?
The only way to solve the problems of this system is to run it multiple times every frame, iterating through the characters, one by one, each time making them get a little bit closer to where they need to be after they've adapted to each others resulting poses, but doing so costs A LOT of performance. As a matter of fact, we didn't even have the frame budget to solve IKs more than ONE time per character, per frame! So things would not match up no matter what for certain configurations, making posing very limited.
Yiffalicious did a ton of clever things to mitigate this and try to place control points where it thought they'd end up, prior to solving the pose (in addition to solving the characters backwards rather than forwards, which came with its own set of benefits but also some challenges). But, in the end, such a system will always be limited. The ideal way to solve this would still be to do it in iterations. If we only could do it fast enough ...
The previous IK solution could not be multi threaded, making any glimpse of hope for adding extra iterations out of the question.
In addition to this, the physics were not part of the IK solver (as previously mentioned). They were applied independently, afterwards. So if any control points were parented to physical entities, and if those entities were moved by physics after the IK posing was already done, then they wouldn't match up anymore. Furthermore, the time step of each individual physics system wouldn't necessarily match up with the IK animation or eachother, meaning some frames animation was applied to these physical entities, and some not, giving it a jittery behavior. For example, the tits of Yiffalicious were affected by 3 different systems. The IK system (which would affect the spine and chest, and thus the breasts as they're connected to the chest), "PhysX" (being used for the main tit parts, being affected by the chest), and finally "Dynamic Bone" applied to the tips of the tits. If you looked closely, you could notice the tips sort of jittering, despite the movement of the tits and spine being smooth, since the individual simulation of those tips were being applied independently and out of sync with the other solvers.
One might ask, then, why we simply didn't just replace all this with just PhysX, for example. Using a physics engine for all of it, rather than trying to combine all of these different technologies.
We actually tried that. That was the first thing we did. But alas, it turned out that combining a lot characters' joints in this fashion would make the simulation very unstable and jittery. Even just simulating 1 character can cause a lot of problems, so adding more characters to it would make it even worse. This, in part, has to do with a limitation in PhysX, which makes the simulation incapable of handling long chains of joints, especially if the weight distribution isn't decreasing over the length of the chain (which it doesn't in the case of multiple characters being connected with each other). That's the reason why we moved over the FinalIK in the first place, since it made the animation much more stable and smoother. The idea of using solely one physics system is however something that always appealed to me, partly because it would make things simpler and more elegant, but also because physics based animation is more interesting (in my opinion).
(An overview of the previous implementation for handling animation in the case of 4 characters.)
Our new system is an attempt to solve all of these problems.
The new system
One system.
If there's anything I want you to take away from this text, it is this - "One system".
One system for everything.
Our new system uses physics calculations to solve the positions of all parts. What's special about it, though, is that it doesn't solve one character at a time. Instead, it considers all of them just as a collection of individual parts connected with joints (aka constraints). It solves all of these joints, continuously and iteratively. The concept of a "character" doesn't exist to the engine.
Since the system is based off physical calculations, it means we don't need extra systems to compute things that are supposed to jiggle. They can be part of the same system, being computed in the same fashion and in the same loops. Again - "One system".
At the heart of our physics engine is this:
- 1. Hyper optimized constraint loop, squeezing out as many iterations as possible.
- 2. Each frame builds on the last.
- 3. When solving joints, solve both connected entities at the same time.
- 4. Solve each group of entities in its own thread.
- 5. Always interpolate the results.
1. Our system isn't complicated or smart. All our system does, essentially, is run through all the constraints (the components that connect physical entities together and control their behavior) and try to satisfy them. In a way, our system is much, much, much simpler than the complex IK systems we've been using. But that's also what makes it possible for us to run these constraint solvers hundreds of times per frame. So when we get a pose from it, we don't get that pose because the system could "imagine" it and because it did tons of complex computations on it. Rather, we converge at that pose simply because that is what will satisfy the physical constraints.
2. Unlike the previous IK system which would become unstable unless it was reset every frame, ours doesn't need to be. Each frame builds on the last one. This makes the movement more natural and the convergence faster. The math doesn't need to be complicated because it isn't solving a whole character, just the individual constraints. This is a core difference.
3. Instead of solving one character and then the next one, we solve all of them in the same loop. Each constraint runs individually, and when it does, it affects both connected physical entities. Succeeding constraints operate on the newly updated data, trying to satisfy themselves as well. This means that (at least in theory) we never end up in a position where one character is out of sync with another one, as the joints that make them up are updated in the same loops, affecting both bodies, fulfilling all constraints.
4. Since our system runs independently of Unity, we can spawn multiple threads, each running its own simulation. This will come in handy when having multiple characters in a scene, because then groups of characters that don't have anything to do with eachother can each be run separately in parallel (rather than sequentially), meaning we save a lot of time and thus performance.
5. The simulation runs continuously and independently, always solving constraints and updating data. One might think, then, that by the time we're ready to render the scene, the physical data wouldn't be ready or sync with the rendering. That's true - it actually happens all the time. But that is no problem, though, as the current and previous physical data is stored in between each loop, and can be interpolated. So if rendering the scene anywhere in between two physics steps, we're simply interpolating between them, getting an ultra smooth result no matter what.
(An overview of our new implementation. Each group of characters is run in its own thread, meaning we can have multiple groups running in parallel without affecting performance. Physical entities such as tits are computed along with each iteration, meaning we don't need an extra step for that.)
So those are the things we're trying to achieve with this engine.
Results so far
This month we've been focusing on trying to implement our posing tools using our own physics engine rather than FinalIK (essentially trying to implement an IK system based on this new engine). We're happy so say we've made great progress in this endeavor.
Here we can see it in action:
(New rig setup, not yet fully implemented.)
(Controlling the right hand IK point to affect the character.)
https://gyazo.com/eae5319d258a180b0f3bdc4de15357c2
On first glance, things look similar. But beneath the surface, everything is different. One thing you may have noticed is that the body is acting in a more natural fashion. As the hand is moved forward and back, the spine is adjusting in a more believable way rather than instantly snapping to a certain pose.
(While the skeleton more or less instantly converges at the desired pose with the hand reaching its target, the back of the character still moves slowly and as if physics and muscles are driving its behavior.)
https://gyazo.com/b7407d738a0bb79d346d8bb28ab4cca0
You may also have noticed the hand point is in the middle of the palm of the hand rather than at the wrist joint. This is another benefit of our system - anchors can be placed anywhere [as far as the physics engine is concerned]. This will make it more natural for the user to place hands.
(The IK point of the hand is placed in the palm of it rather than at the wrist, making placement more natural and easier.)
https://gyazo.com/17723aa18daf1eb6b1e5e389975eed66
Another improvement we want to make in the future is hand snapping. Rather than manually moving hand to desired location, you would then be able to simply snap it to a point on a surface, and the palm of the hand would be placed there in the most natural way for the arm. This would speed up posing and make the whole posing process a lot easier and more fun.
Naturally, we have also implemented pole targets to control the rotation of the limbs:
https://gyazo.com/d02d7a1b9a40b8b6c69524872fdac83f
This was a bit more challenging to implement. It turned out we couldn't simply use the equivalent of spring joints to control this behavior (as we first thought would be enough and what we tried first). Rather, we had to implement code that directly affected the physical anchors in such a way that the limbs would be rotated in the desired direction. Getting that to work together with multi threading required some extra tinkering (as nodes are handled on main thread while the simulation runs in its own thread, and since character can change their location in relation to the pole target, the pole target's direction has to be continuously updated), but eventually we got it working.
As explained in the previous segment, tits can be simulated in our system without the need for extra steps. We spent a considerable amount of time translating our previous work regarding tits into our new engine, to not only match previous behaviour but also surpass it.
Here we can see how the tits behave, but also how it differs and how it has been improved:
https://gyazo.com/89edee58fa51a86ed42ddfac0eabf5b9
https://gyazo.com/7257839396cae1b692c7b26c7e6312de
Reaction to inflation:
https://gyazo.com/eafaad1a51515ee28854ab6c91686178
In the image above, you can see a major benefit from before. In our previous system, tit joints had to be reset in order to change them, but that also made the tits behave oddly when dragging the sliders. Here, we don't have that problem as we have full control of the simulation at all times and can make whatever changes we want and have it update properly.
Comparison with previous:
(NOTE!! Old implementation, for comparison. As you can see, changing the tits inflation would make them behave oddly.)
https://gyazo.com/ededd8d7e3536177e69508fc76bcec31
Of course, our system can handle flatchested breast physics, too:
https://gyazo.com/42af8981fef4288769f95b58b7a34db8
One thing that FurryVNE lacked in comparison to Yiffalicious was simulation of the tit tips. To make the tits more juicy and bouncy, Yiffalicious simulated the tits with 2 systems - PhysX for the major tit movements, and Dynamic bone for the tips of them. However, in FurryVNE, we only used PhysX. This was in part because we made the tits be able to squish, which required a more complicated PhysX setup, but extending that setup with simulation for the tips turned out to be difficult. We never got around to doing it properly, and it never sat well with me. Now, however, with our new systems, we've managed to implement that (using solely our own systems), while at the same time retaining (and improving on) the squish behavior:
(The tips of the tits are now simulated in FurryVNE, making the animation much juicier.)
https://gyazo.com/59a277b91926836491addc0139aef4cb
Comparison with previous:
(NOTE!! Old implementation, for comparison.)
https://gyazo.com/9a1ab0dc3f316e91ebd37469a650e27c
As previously mentioned, the engine itself supports having anchors anywhere [in relation to the connected entities]. So we tried experimenting with this dynamic to see what we could implement. Here, we added something we simply referred to as a "kissing point". This point is attached to the head (but with an offset), forcing it to reach this point. The skeleton correctly adapts for this constraint to be met:
(A test of an arbitrary "kissing point", attached to the head. The rig correctly adapts.)
https://gyazo.com/359bfb52d80b9bf115525d03a4239940
(Another angle.)
https://gyazo.com/52f6f200b6c926d70009d90ecfb227d6
(Even as moving the pelvis, the system manages to keep the converge at the kissing point.)
https://gyazo.com/e9c93b50bcddcc2797c738ff8213ea7f
(Same thing with the hands - the system adapts and is able to fulfill both constraints.)
https://gyazo.com/210721c95b483ee1848b6c17aa57fc08
What's amazing about all this is that this required almost zero effort or extra systems to achieve. Adding something like this to the previous IK system would have been a huge and very complicated task. Here, however, it's as simple as adding just another generic constraint (the same kind that drives everything else in the simulation).
This could be an interesting feature to add to the interaction systems in general, as I think this would it's a common thing wanting the characters mouths to reach certain points in the scene.
Additionally, making mouths, shafts and other specific points on the body meet up wouldn't really require anything special to add [as far as the physics engine is concerned]. It would simply be a matter of setting up the constraints. (Naturally, the idea is to abstract this and make it easy to set up any kind of interaction with ease.)
Future
More work remains on the this new physical IK rig before we'd feel happy with it. For example, we want to add ways to affect the spine in a more simple manner than before, and behavior for affecting the head and look direction is currently missing. We also want to add behaviors for tails, shafts and balls for them to also react in a physical way.
Once we have those things in place, we will move over to implementing scenes that support multiple characters.
Summary
We're moving away from the previous IK solution to a custom one based on our new physics engine. This will hopefully mean a ton of benefits to the animation and interaction systems, not only resulting in better, more fluid and more physically accurate animation, but also more performant while at the same time offering a greater variety in the types of interactions you'd be able to set up.
Initial results are looking promising, and as soon as we're done with this new IK rig as well as implementing physical behaviors for tails, shafts and balls, we're moving over to systems for adding multiple characters to a scene.
All the best.
- odes