View Full Version : Need some help making tentacles taper at the end

09 September 2005, 04:22 PM
I have been writing a mel script that creates a tentacle along a curve and I have run into a strange problem that I just can't get past. I am using a IK spline with a nurbs cylinder skinned to the bones. To create the taper I am trying to scale on Y and Z for each joint. However I can't get the second to last joint to scale properly. If I scale that joint it loses the IK spline connection and the whole thing jumps off the curve. Why would that happen? Is it something with the way I'm doing to IK spline or the taper? I have been staring at this way too long.

Any help is appreciated

global proc new_tent(float $radius) {

// selection variables
string $selected_curves[] = `ls -sl`;
string $current_curve;

// curve variables
float $curve_length;
int $num_of_joints;

// cylinder variables
string $cyl_name;
string $num_cyl_spans;

// joint creation variables
string $cur_joint_name;
string $prev_joint_name;
string $root_joint_name;
string $final_joint_name;
float $y_offset;
float $y_pos;

// taper variables
float $taper_length;
float $taper_value;

// utility variables
int $i;
int $j;

// create one tentacle for each curve selected
for ($current_curve in $selected_curves) {

$curve_length = `arclen $current_curve`;
$num_of_joints = int($curve_length);

/* create nurbs cylinder */
$cyl_name = $current_curve + "_cylinder";

cylinder -r $radius
-hr ($curve_length/$radius)
-p 0 ($curve_length/2) 0
-ax 0 1 0
-d 3
-s 10
-nsp $num_of_joints
-ch 1
-n $cyl_name;

/* create joints */
$cur_joint_name = "";
$y_pos = 0;
$y_offset = $curve_length/$num_of_joints;

for ($j = 0; $j <= $num_of_joints; $j++) {

$prev_joint_name = $cur_joint_name;
$cur_joint_name = $current_curve + "_joint" + ($j+1);
joint -p 0 $y_pos 0
-n $cur_joint_name;
if ($j != 0) {
joint -e
-oj xyz
-sao yup $prev_joint_name;
else {
$root_joint_name = $cur_joint_name;
$y_pos += $y_offset;

$final_joint_name = $cur_joint_name;

/* smooth bind cylinder to joints */
select $cyl_name;
select -tgl $root_joint_name;
newSkinCluster "-mi 1 -dr 1";

/* even trying to force it doesnt work
setAttr ( $current_curve + "_joint" + $num_of_joints + ".scaleY" ) 0;
setAttr ( $current_curve + "_joint" + $num_of_joints + ".scaleZ" ) 0;

/* create IK spline solver */
select -r ($root_joint_name + ".rotatePivot");
select -add ($final_joint_name + ".rotatePivot");
select -add $current_curve;
ikHandle -sol ikSplineSolver -ccv false -ns 3;

/* make tentacle taper */
$taper_length = 30;

for ( $i = 0; $i <= $taper_length; $i++) {
$taper_value = linstep( 0, sqrt($taper_length), sqrt($taper_length - $i) );
setAttr ( $current_curve + "_joint" + (($num_of_joints - $taper_length) + $i) + ".scaleY" ) $taper_value;
setAttr ( $current_curve + "_joint" + (($num_of_joints - $taper_length) + $i) + ".scaleZ" ) $taper_value;

} //end curve select for loop

} //end new_tent

09 September 2005, 07:10 PM
rather than using a nurbs cylindar,

you could do one of two things... extrude a circle down the spline curve (this allows a taper attribute to be changed.


you could try doing a loft between 2 nurbs circles and then just scaling the one on the other end of the spline.

hope this points you in some helpful direction.


09 September 2005, 07:32 PM
I am all for a new or different way of doing it. I would love to be able to do this without joints. But, the reason I didn't do it with an extrude or loft was that I don't want it to taper evenly along the entire tentacle. I want it to be a fixed radius until a specified point and then begin to taper according to a function (in the code I gave above I use a square root function, but I could easily give options for x^2, sin(x), etc.) to allow for different taper shapes.

09 September 2005, 08:45 PM
I see what you mean...

the problem you are having is in the scaling of the joints... scaling joints that have skin on them and have IK solvers attached can be really buggy and probably cause issues. As you have seen.

you could attach a deformer (maybe lattice) to the nurbs cylinder and do the same taper functions on that deformer instead of the joints. that way it only effects the mesh and not the controls.

something I just thought of is using a bound / control rig method. you could create one joint chain that has the skin attached, then do the tapering you want. Then create an identical joint chain that has the IK solver on it, then have the control rig (IK rig) control the bound (scaled and skined rig) by point and orient constraining each bound rig joint to each control rig joint.

The important thing you need to remember is that this taper is a deformation completely seperate from the tentacle joint deformation. So by using different deformers to do each job you should get the result you are looking for.


09 September 2005, 08:53 PM
That really helped me out. I will play with one of those solutions later tonight (or both if I have time).


09 September 2005, 12:38 AM
Thanks a million musicraker! That works beautifully with the lattice deformation. :thumbsup:

09 September 2005, 01:00 AM
no prob,

im glad it helped.


CGTalk Moderation
09 September 2005, 01:00 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.