If I link the rotation of object1 to object2 in the form of a rotation script (where the script in object1’s rotation script controller would be “inverse object2.rotation”), it works fine if both object’s pivots are aligned to the world…but if the pivots are not both aligned to each other, object2’s rotation will translate (visually) incorrectly.
I guess a simple way to illustrate the problem would be to try this:
Create a box in the top view, and then create a box in the front view. Then, using a script controller, link the first box’s rotation to the second box’s rotation in the way described above. Now, if you rotate box 2…you’ll notice that box 1 appears to rotate in the wrong axis (technically it’s the right axis, but the pivot of the object is orientated wrong due to the fact that both objects were created in different viewport angles).
Anywho…anyone know a way to get around this and fix this? One method would be to align both object’s pivot to the world before scripting the connection…but that’s pretty intrusive if you’ve got a rig already setup and it tends to break things.
Hey guys, Thanks for stopping by…but I still can’t figure out the problem (your suggestion, Charles, didn’t seem to work).
Basically, what I want to be able to do…is have 1 object rotate in a certain direction (for example, rotating up or down in the front viewport), and then have another object rotate in that same direction, no matter what it’s current orientation is.
The resulting effect would make it seem that both objects are rotating in the same direction, and on the same axis, even though object 2 could be orientated in any arbitrary way.
To do this, you just need to capture the initial transformations of both objects to assume as the base coordinate system. That means that when object one is rotated the way it is, the other object will also be rotated the way it is initially. Then, using these initial transformations and the change in the first object, you can always calculate the change needed in the second object to assume its new orientation.
*Let’s say you have created a Teapot in Top viewport and another Teapot in Front viewport. The second one is rotated at 90 degrees relatively to the other, but it could be ANY orientation.
*Now you snapshot the current orientations of both teapots:
t1 = $Teapot01 --grab the first object
t2 = $Teapot02 --grab the second object
tm1 = t1.transform --get the TM of the first object
tm1.row4 = [0,0,0] --reset the translation to 0
tm2 = t2.transform --get the TM of the second object
tm2.row4 = [0,0,0] --and reset it's translation to 0
*Then we will define a function which uses this initial data to calculate the new rotation of object 2 based on the new rotation of object one:
fn matchRotation =
new_tm1 = t1.transform --this is the actual transform of Teapot01
new_tm1.row4 = [0,0,0] --we remove the translation again, as we want just the orientation
thePos2 = t2.pos --grab the current position of teapot02
--we transform the old orientation of teapot02 out of the old space of teapot01 and
--back into the new transformation of teapot01 - the result is the new orientation,
--but all these TMs have no offset, so the teapot02 is oriented correctly
--AT WORLD ORIGIN!
t2.transform = tm2 * inverse tm1 * new_tm1
t2.pos = thePos2 --so we just need to assign the old position again and here it is...
matchRotation() --call the function when you want to match a new rotation
*You could hard-code the initial transformations of both objects into the corresponding scripted controllers or whatever it is that links the rotation from the one to the other. Then the rest should go interactively by just running the function code again and again…
In my example above, re-running the initial state code will assume the new relative rotations as the initial state and start working from there, so it really should be called just once when both objects have their initial rotations.
The code could be optimized some more since both tm1 and tm2 are captured in the beginning. Instead of constantly multiplying tm2 with the inverse of tm1, you could do it once in the beginning and store the result either in a variable or hard-code it into your scripted controller (or save as constant in a scipted controller’s variable).
That’s brilliant! And I tested it and it works great! Thanks for the effort you put into it
I’ve come to a stumbling block though…it would be nice if Teapot02’s orientation could be changed after being “linked” to Teapot01’s orientation, as described in your script. Right now, if you change Teapot02’s orientation and then rotate Teapot01…Teapot02 snaps back into the orientation that it was in when the script was first initialized.
I tried fixing this by putting the initial code (where we first get the value of tm1 and tm2) into a rotation script in a list controller in Teapot02…but it gives an illegal self-reference error (obviously) because we’re trying to read a .transform value while we’re changing it.
I guess ideally, once the code is fully working you’d be able to change Teapot02’s orientation to whatever you want at any time…but as soon as Teapot01 is rotated…Teapot02 appears to rotate in the same way (as per the original problem)