StephG
06-14-2006, 07:52 PM
OK, I'm pretty annoyed with the way Maya's splineIK works. The fact that there's no option to turn off the roll control so you can just input it directly into the bones via constraints or other connections is infuriating, and getting arbitrary roll data into it even with advanced twist is a bodge of trial and error that never works the same way twice. Think using splineIK with mocap data.
So, what I'd like to do, is create a curve, and attach the joints to the curve without roll restrictions. So I set out to make a "homebrew splineIK".
The approach I've tried so far, is to create a pointOnCurveInfo node for each joint. I found a brute force way to find the percentage of the curve that corresponds to the joint's current location (approximately, but very very close).
This is where things get ugly. I tried to connect the position (output) from the POCI node to the joint's translate. This would be neat if it works, because then the joints move stretchy IKspline style. Bad news. The joint's translate info is local, while the POCI output is world space. It flings the joint across the screen.
The roll vector on the joints is the y-axis. I prefer keeping my axes oriented approximately to the world axis direction they're pointing whenever possible, and this is a spine.
OK, so turn off "inherit transforms". Now I can get the joints into the right place, but the joints no longer point at each other. More bad news. Also, their represention now points into space like porcupine quills. So I set up aim constraints with no up-vector, which seems to work. The joints are still super long and pointing beyond the "child" joints, but at least they're pointing in the right direction.
So far so...well if not good, at least it's promising. So I try breaking the connection on the joints' y-axis. This should work. Nope. The y-axis isn't the roll vector, because the parent of the joint is the "world" when the inherit transforms are turned off, and the rotation axis doesn't seem to pick up the resulting transform from aiming the x-z vectors. WTF?
Ideally, I'd be able to find a way to keep the inherit transforms on, and get the data out of the pointOnCurveInfo node onto the joints while they still work like a joint chain. I'm not married to the way I'm doing this, it's just all I've thought of so far.
Very frustrating. It's like Maya has one and only one way it wants you to do something, and they've thought of a way to defeat you at every turn should you get any uppity notions of circumventing their tool.
Any suggestions or tutorials out there for making a homebrewed splineIK that doesn't use Maya's overly restrictive splineIK handles? Or, for that matter, coming up with a way to make this methodology work?
Oh, and this is my brute force method of finding the POCI percentage that corresponds to the joint location (where the CVs were placed at the joint location to draw the curve, not the most accurate method but accurate enough, and I'm open to suggestions for more elegant ways of getting the info):
string $listCV[] = `ls -fl ($curveName + ".cv
")`;
int $count = 0;
float $percentage[];
for ($lc in $listCV)
{
float $pos[] = `xform -q -r -t $lc`;
for ($countFloat = 0.0;$countFloat<1.0; $countFloat+=0.00015)
{
float $pocPos[] = `pointOnCurve -top 1 -pr $countFloat "tempCurve"`;
$pos[1] = `roundoff $pos[1] 3`;
$pocPos[1] = `roundoff $pocPos[1] 3`;
if ($pocPos[1] != $pos[1])continue;
print ($lc + " " + $countFloat + "\n");
$percentage[$count] = $countFloat;
$count++;
}
}
So, what I'd like to do, is create a curve, and attach the joints to the curve without roll restrictions. So I set out to make a "homebrew splineIK".
The approach I've tried so far, is to create a pointOnCurveInfo node for each joint. I found a brute force way to find the percentage of the curve that corresponds to the joint's current location (approximately, but very very close).
This is where things get ugly. I tried to connect the position (output) from the POCI node to the joint's translate. This would be neat if it works, because then the joints move stretchy IKspline style. Bad news. The joint's translate info is local, while the POCI output is world space. It flings the joint across the screen.
The roll vector on the joints is the y-axis. I prefer keeping my axes oriented approximately to the world axis direction they're pointing whenever possible, and this is a spine.
OK, so turn off "inherit transforms". Now I can get the joints into the right place, but the joints no longer point at each other. More bad news. Also, their represention now points into space like porcupine quills. So I set up aim constraints with no up-vector, which seems to work. The joints are still super long and pointing beyond the "child" joints, but at least they're pointing in the right direction.
So far so...well if not good, at least it's promising. So I try breaking the connection on the joints' y-axis. This should work. Nope. The y-axis isn't the roll vector, because the parent of the joint is the "world" when the inherit transforms are turned off, and the rotation axis doesn't seem to pick up the resulting transform from aiming the x-z vectors. WTF?
Ideally, I'd be able to find a way to keep the inherit transforms on, and get the data out of the pointOnCurveInfo node onto the joints while they still work like a joint chain. I'm not married to the way I'm doing this, it's just all I've thought of so far.
Very frustrating. It's like Maya has one and only one way it wants you to do something, and they've thought of a way to defeat you at every turn should you get any uppity notions of circumventing their tool.
Any suggestions or tutorials out there for making a homebrewed splineIK that doesn't use Maya's overly restrictive splineIK handles? Or, for that matter, coming up with a way to make this methodology work?
Oh, and this is my brute force method of finding the POCI percentage that corresponds to the joint location (where the CVs were placed at the joint location to draw the curve, not the most accurate method but accurate enough, and I'm open to suggestions for more elegant ways of getting the info):
string $listCV[] = `ls -fl ($curveName + ".cv
")`;
int $count = 0;
float $percentage[];
for ($lc in $listCV)
{
float $pos[] = `xform -q -r -t $lc`;
for ($countFloat = 0.0;$countFloat<1.0; $countFloat+=0.00015)
{
float $pocPos[] = `pointOnCurve -top 1 -pr $countFloat "tempCurve"`;
$pos[1] = `roundoff $pos[1] 3`;
$pocPos[1] = `roundoff $pocPos[1] 3`;
if ($pocPos[1] != $pos[1])continue;
print ($lc + " " + $countFloat + "\n");
$percentage[$count] = $countFloat;
$count++;
}
}
