I'm try to rig a low poly clock for blender, so I added a copy rotation constraint so the minute hand would automatically spin with the second hand, but when I rotate the second hand 180 degrees, the minute hand reverses its rotation.
-
$\begingroup$ I think it has to do with how Blender handles rotations internally concerning positive and negative values, but I don't know hot to actually solve it. It also only seems to happen when the Influence parameter is set to lower than 1 unit $\endgroup$– Duarte Farrajota Ramos ♦Jan 17, 2018 at 5:31
4 Answers
Maybe you can alternatively do it with drivers instead.
Rather than add constrains use a driver on the rotation properties of the hour hand by right clicking them and choosing Add Driver > Manually Create Later
Then proceed to the Graph Editor, change to Drivers from the header, and choose the desired channel (Z in this case).
From there open the Properties Panel (N Key), Drivers tab choose the option Scripted Expression and add a new variable.
Use the Transform Chanel option, pick the other hand and choose its $Z$ Rotation. The scripted expression should read something along the lines of $var/12$ so it rotates at one twelfth of the angular speed.
-
$\begingroup$ Thanks, I didn't know how to multiply scripted expressions. This fixed the problem. $\endgroup$– ConnerJan 19, 2018 at 4:47
There really seems to be a limitation with rotational constraints. You run into a similar problem if you are using Transformation Constraints instead of Rotation Constraints, where after a full revolution the hour hand would jump back to the 12 position and start again from there. But: Using Transform Constraints you can rig that situation the other way around. In other words, animate the hour hand, and have the minute hand follow accordingly.
Here is a blend file that shows this idea:
And a quick screenshot of the constraint setup:
As you can see, I have extrapolate checked, and map from a source rotation to a target rotation in local space. The values I set are simply the time values: If the hour hand moves by one hour, the minute hand shall rotate for 12 hours, or a full revolution of 360 degrees in other words.
The other answers are good solutions, but nobody (so far) has answered your explicit question, which is why this happens.
Here's what Blender does when it figures out a copy rotation constraint:
- It reads the f-curves. It runs any f-curve modifiers. It applies any drivers to these values.
- It turns these values into a 4x4 transform matrix.
- In order to evaluate the constraint, it decomposes the matrices of both the constraining and constrained objects into location, scale, and XYZ Euler rotation triplets.
- It adds a multiple (from constraint influence mostly, usually) of the rotation channel of the constraining object's transform to the constrained object's rotation channel.
- It converts the new loc/rot/scale triplets of the constrained object back into a 4x4 matrix for rendering or further constraints.
The important thing to realize here is that an orientation, as a set of rotation triplets back on step 1, is aliased-- there are multiple sets of numbers that can give you a particular rotation. For example, 360 degrees rotation is the same as 0 degrees of rotation, right? In a way, the f-curves contain not just the orientation information, but a little bit extra information-- how many times they've made full rotations already, maybe.
But when we get to step 2, 4x4 matrices are not aliased. There is only a single 4x4 matrix to represent any particular orientation. That extra information about how many times it's already rotated is lost, and is unavailable to any constraints.
(Why do this? Mostly, because of space switching. You can convert orientations to different transformation spaces, but you can't convert "how many times it rotated." That just isn't something that makes the same kind of sense when evaluated in arbitrary spaces.)
So when Blender takes your 190 degree rotation, turns it into a matrix, and then turns it back into triplets, what does it get? It's designed to output results from -180 to 180. So 190 degrees is equal to -170 degrees, and that's what it returns, and that's what gets used by your constraints. If you're using some fraction of this as a multiple, you'll see your constraints jump. Like if you were copying rotation at 0.5 influence, you'd all of a sudden go from 90 degrees rotation to -90 degrees rotation.
-
$\begingroup$ Interesting read. Did you gather this information from the manual or the source code of blender? $\endgroup$ Apr 6, 2021 at 19:37
-
$\begingroup$ No, it's mostly from understanding math from editing shaders and reading a lot of people writing about engine creation, and then observing Blender's behavior with constraints. $\endgroup$– NathanApr 6, 2021 at 21:02
Although this question was essentially answered a long time ago. There are few things I want to add.
I encountered the same issue creating what is essentially Ramyans Haircopter.
What I found out is that both the Transform and the Rotation Constraints work just fine (tested in 3.0) when the Influence is 1.
However when the Influence is less than 1 (or the transform constraint maps a 180 to a smaller degree) the mentioned issue appears. So if you instead use a Transformation constrain to map from the lower value to the higher value the Issue can be worked around (as showcased in aliasgurus File).
So these mappings are fine:
while these are not:
So essentially what I do for my Usecase is rotating the topmost bone 4 times as much and the last bone 1 times as much, instead of rotating the first bone 1 times as much and the last bone 0,25 times as much.
Hope my findings are helpful for someone.