TL;DR: Unfortunately disabling rotation inheritance must also disable reflection because math. π
This is a very tricky area. Most apps don't allow disabling parts of the transform inheritance because it's difficult to make it behave sanely in all situations. We put a lot of effort into it and came up with these combinations:
normal
onlyTranslation
noRotationOrReflection
noScale
noScaleOrReflection
When you uncheck only Rotation
, you'll notice that Reflection
becomes unchecked, even though it's disabled. The behavior you are getting from the above list is noRotationOrReflection
.
The reason why is in the math. It's been years so I'm a bit rusty on the details, but an affine transformation matrix is used to apply the bone transforms in a way that ascendant bone transforms are combined and applied to all children. The matrix has 4 values that describe rotation, scale, and shear and 2 more values for translation:
Loading Image
Once you convert the individual values for rotation, scale, and shear into a matrix, it is not always possible to extract those same values. That is because sometimes there are more than one set of rotation, scale, and shear values that result in the same matrix. This is super damned annoying!
For example, there is no difference between 180 rotation, 1,1 scale
and 0 rotation, -1,-1 scale
. You may think it's only a problem with specific values, but the transform behavior needs to be consistent across the range of all possible value combinations, otherwise you'd get sudden jumps when you arrive at certain values.
Another horrible example is scale 0,0
. You're definitely not getting your rotation and shear values back out of the matrix after multiplying it with zero! This one is less important, since just about everything falls apart with zero scale.
Anyway, at each level in the bone hierarchy we have a matrix that is the combined transforms of all parent bones. Now we say we want to not inherit rotation from that matrix, but we've established that rotation, scale, and shear are intertwined in the matrix and can't be extracted back into the original set of values. If we just do it anyway, we get inconsistent, jumpy behavior that isn't acceptable. This is where most apps give up, but not Spine!
We came up with ways to support disabling inheritance as much as possible while keeping the behavior consistent. It has some drawbacks, such as that disabling rotation inheritance must also disable reflection, but it can still be useful.