I have an object
Cube with copy transforms constraint targeting another object
Empty. The constraint is disabled, so when I enable it the
Cube's rotation, location (transformation) is copied from
Cube, which is correct. I have another object
Arm, which I want it to be transformed and rotated with the same value as
Cube so that the relative orientation of both the
Arm remains the same as if they were both shifted and rotated with the same value, not sure how this can be done? I tried adding a copy transform to
Empty but it didn't give the correct results. Any advice? Ultimately I want to do this with python but I'm trying to figure a way to do it manually first then write the python script for the steps needed.
I have an object
A driver is a way of calculating the value to use based on other values in the scene, any python expression can be used in a driver. A constraint is basically a visual way of representing a driver. For the most control, you can define a python function to calculate a value used in a driver.
As an example, a driver can calculate the x rotation as 1/4 of the x rotation of the empty. The variable named
var is set to get the x rotation of the Empty and is then used in the python expression to get the final value.
Then you can set cube2 to rotate three times the rotation of the first cube
Now let's say we want cube two to have it's rotation a constant offset from the first cube's rotation, we can use a custom property to hold the offset amount (and animate it if we want some variation) and use that in the driver.
You can also add your own function into the driver namespace -
return val * .75
bpy.app.driver_namespace['myfunc'] = mydriverfunc
and then use that in the driver expression, passing any gui configured variables as paramaters.
Note that drivers are python code and might get disabled based on the auto-run python settings.
You can create a driver using python
d = obj.driver_add('rotation_euler', 1)
d.driver.type = 'SCRIPTED'
v = d.driver.variables.new()
v.name = 'var'
v.type = 'TRANSFORMS'
v.targets.id = bpy.data.objects['Empty']
v.targets.transform_type = 'ROT_X'
d.driver.expression = 'var * .25'
Using a Copy Transforms constraint on the armature Arm gives mathematically correct results. What might be confusing you is that the the pose of your bone (which is different from the location/orientation of the armature) is unaffected by the Copy Transform constraint. And since Suzanne is rigged to the bone then the fact that the bone is offset from the armature means Suzanne will not be on top of the empty.
To consider how complicated this can get, imagine an armature with 4 bones and ask yourself what that means for the position of each bone when there is a Copy Transforms constraint on the armature.
Assuming you want Suzanne to end up on top of the Empty you have two options:
- put the Copy Transforms constraint on the armature and reset the pose of the bone to 0,0,0.
- put the Copy Transforms constraint on the bone instead of the armature. Since bone coordinate systems are a little screwy, you'll probably end up putting a rotation on Suzanne like -90,0,180 to reorient it.