2
$\begingroup$

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 Empty to 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 Cube and 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 Arm targeting 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.

My .blend file can be found here

$\endgroup$
0
$\begingroup$

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.

cube rotation driver

Then you can set cube2 to rotate three times the rotation of the first cube

cube2 rotation driver

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.

driver with two values

You can also add your own function into the driver namespace -

import bpy

def mydriverfunc(val):
    return val * .75

bpy.app.driver_namespace['myfunc'] = mydriverfunc

and then use that in the driver expression, passing any gui configured variables as paramaters.

enter image description here

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[0].id = bpy.data.objects['Empty']
v.targets[0].transform_type = 'ROT_X'
d.driver.expression = 'var * .25'
$\endgroup$
0
$\begingroup$

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:

  1. put the Copy Transforms constraint on the armature and reset the pose of the bone to 0,0,0.
  2. 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.
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.