hi christianmassyn,
I might be of help, I hope it isn't too late cuz I just saw this thread. I'm trying to understand your problem. I'm imagining you've got a scene with a bunch of points (probably locators) moving in your scene. Six of those locators are there to "supposedly" describe the movement of your "actor's" head. But the movement of the head isn't really as important as the movement as the markers for the face, right? So if I understand you correctly, your goal is to subtract the movement (and rotation and maybe) of the head from the track points for the other facial markers.
If my understanding of your problem is wrong, please disregard my solution. (NOTE: It might seem like I'm talkin down on you cuz I'll over explain steps, but I'm not. I find it weird actually. You're already scripting and most of what I'll say might not need explanation. But I'll overexplain things none the less just to avoid miscommunications.) Otherwise, cross your fingers and hope this works:
The first thing you need to do, just as you've originally intended, is to get the head's movement and rotation. I think it'll be better to separate position and orientation. To get the position, we'll just have to go for the average of those six points. This means: 1) creating a a locator, null, sphere or any transform node of your choice 2) select all six locators and then the object we just created 3) point constraint. Turn off maintain offset.
Scrub through your animation. The object we created should now be dead center to the head markers. What it doesn't have, currently, is rotation. Let's name that object "headPosition" so we don't lose it.
Next we'll have to do is get the rotation of the head. This is when aim constraints are gonna be important. An aim constraint allows you to make sure an object is looking at a particular object at all times. But looking at objects isn't everything. Imagine this scenario. Make a gun out of your hand so that your index and thumb fingers are sticking out and the rest tucked into your palm. Then point at something, anything. Try the start menu button, your mouse, a bottled water's cap. Notice that you could turn your hand so that your thumb is no longer pointing at the ceiling (or the meridian) but instead looking or pointing at the horizon? This is when up vectors and world up vectors come into play. You define an up vector so that Maya will make your index finger point at a target you define, and at the same time, you could also define which direction your thumb point to.
Just some definitions:
1) aim vector is the vector (in the object's local space) that defines the direction you want to aim.
2) up vector is the vector (again in the object's local space) that defines which part of the object is it's top part. this works a lot like the "This side UP" stickers on packages or crates.
3) world up vector is a vector that defines which is up in your scene, if you are using "vector" as your world up type.
Now, if we are to use world up type "vector", we'll be supplying a vector that'll define the up in our scene. Think about this. This is'll mean a constant world up vector. This won't work, in your case (if my imaginations are correct). What you need to do is set up an object that'll serve as your world up and use "Object up" as your world up type.
How do we do this? Well, we work with the data that we have. We'll either create two new locator/null/object-transform node that is constrianed to be in a position that'll serve as the "new" UP and the new "target". We do this in the same way we did the "headPosition" only this time, we won't use all six locators. We'll use maybe two reliable markers. You'd also want to pick markers (from the six) to constrain your new object so that your new object falls as far from the "headPosition" as possible. Hmmm.. if this part is unclear, consider the following: if you chose all six markers again for this, your new obj will end up in the same exact position as "headPostion". If you chose 5 markers only, you'll be slightly farther from "headPosition." In order for aimconstraints to work you'll want to choose "targetsObjects" and "upObjects" as far as possible. Then name them, of course.
Now to set up the aim constraint, open the options box for your aim constraint, and choose "Object up" for your "world up type" and then enter the name of your "upObject" in world up object. Then select your "targetObject" and then your "headPosition" and hit Add or Apply. Now, notice this is assuming you don't really care about offsets and such, cuz if so you'll have to put them in here.
So now, your headPosition object should be moving and rotating somewhat correctly.
If you are unsatisfied with the movement, the reason would be your faulty mocap data. You may want to try setting up the point constraint with less markers.
If you are unsatisfied with your orientation, you'll have to resetup your "upObject" and your "targetObject". Again farther is better, though you can only go as far.
Now, for the last part. How do we get the position of your facial markers in relation to your new "headPosition"? This part is pretty simple, though it'll be tedious. And because you can script, we won't have much of a problem.
First, you'll have to make duplicates of each facial marker and parent these duplicates to the "headPositon" object. Then you'll pointConstraint each duplicate to their original copies. After which you'll yet again create another duplicate of each locator (and probably store them in another group). Then, lastly you'll connect the translation attributes of the first duplicate to the last duplicate in the group. The last duplicate in the group has nothing but movement in relation to the head.
note: instead of duplicate (which is unnecessary) you can simply create another transform node
in script, if I may:
/// start here ////
// run this script with all your facial markers selected
$headPosition = "headPosition"; // this should be a string containing the name of the object you used for "headPosition"
$grp = createNode transform -n "groupOfTransformNodesWithRelativeMovement";
for ($each in
ls -sl) {
$constrained =
createNode transform -n ($each+"_constrained");
pointConstraint $each $constrained;
$relativeTransformNode = `createNode transform -n ($each+"_relative");
parent $relativeTransformNode $grp;
connectAttr ($constrained+".t") ($relativeTransformNode+".t");
toggle -localAxis; // this part is optional but it lets you see your new
// transform nodes moving if you use nulls or transform nodes with no shapes
}
/// end ///
If you dont want to use the script, another option you might want is to simply select all the transform nodes that are pointConstrained and are parented under your "headPosition". Then bake simulation (Edit->Keys->Bake Simulation). Just keep things at default and hit Bake.
This will generate keyframe animation for every movement your markers are doing, sort of like a recording. You can now delete the pointconstraints.
if there's too much, you can easily type:
select -r "headPosition";
select -hi;
delete ls -sl -et "pointConstraint"
;
Then, lastly, reparent all those transform nodes under a new group that isn't moving and prefferably under world.
Whew, mouthful! Hope it works!
Keep us updated!
David