Adaptive Treads

I’m working on a set of tank treads for a robotic character. This is how i have the treads set up right now.


The setup is a basic circle curve with clusters controlling each vertex.

I used: arclen -ch on; to enable maya to calculate the length of the curve. (at rest it is at 27.087).

The basic idea im going for is to preserve volume with the treads as say, the bottom two wheels come closer the top middle rises.

To do this I used an expression

//---------------| Have to evaluate up to 100 to ensure enough calculation have been made 
for ($a = 0; $a<100; $a++){
	float $arcLeng_01 = `getAttr crv_length_01.arcLength`;
    float $CT_top = `getAttr clus_track_top.translateY `;
    //--------------| Value the translateY increases when length is not met
	float $upVal = 0.1;
    if ($arcLeng_01<27.087){
        	setAttr "clus_track_top.translateY" ($CT_top+$upVal);
    }
    if ($arcLeng_01>27.087){
            setAttr "clus_track_top.translateY" ($CT_top-$upVal);
    }
}

What I need help with is this expression wont run while I’m manipulating the rig but only when I change keyframes. Possible ideas are to switch to using hypershade nodes rather than expressions or just finding a new way.

Any thoughts would be greatly appreciated!
Thanks!

EDIT:

I have now minimized my Expression to the following, but still no live feedback when manipulating.

float $cC_Length = `getAttr testCurve.length`;
if ($cC_Length < 27.087){
  float $restLength = 27.087;
  float $upVal = ($restLength-$cC_Length);
  setAttr "clus_track_top.translateY" $upVal;
}

This However causes the top cluster to now have a jiggle effect :frowning:

If I understand correctly, you were saying if it is greater than, do something and if it is less than, do something. But when it is equal to, it won’t do anything.

Would it help if you use “<=” or include an equal to statement?

[QUOTE=clesage;16984]If I understand correctly, you were saying if it is greater than, do something and if it is less than, do something. But when it is equal to, it won’t do anything.

Would it help if you use “<=” or include an equal to statement?[/QUOTE]

This would work nicely, thanks for the idea, however the main problem is knowing how much to move the top cluster to make it the exact length. Right now It go up .01 or .1 so sometimes it would miss the 0 mark and then would be calculated to go back down and ultimately create an infinite loop and i feel if it did end up working that way it would be very inefficient.

Dude, i want your minecraft viewcube! :slight_smile:

I believe (although I am not sure and did not test it) the solution is to not use MEL commands like getAttr/setAttr, as the attributes are not flagged as dirty until the time is changed. Instead, use direct assignment to have it change while manipulating. So instead of saying:


float $CT_top = `getAttr clus_track_top.translateY `;
or
setAttr "clus_track_top.translateY" ($CT_top+$upVal);

use


CT_top = clus_track_top.translateY;
or
clus_track_top.translateY =  (CT_top+upVal);

Phil

[QUOTE=rgkovach123;17008]Dude, i want your minecraft viewcube! :)[/QUOTE]

I didn’t know it was this easy:
http://lesterbanks.com/2010/10/customizing-maya’s-viewport-view-cube-to-spongebob/

[QUOTE=Phil;17016]I believe (although I am not sure and did not test it) the solution is to not use MEL commands like getAttr/setAttr, as the attributes are not flagged as dirty until the time is changed. Instead, use direct assignment to have it change while manipulating. So instead of saying:


float $CT_top = `getAttr clus_track_top.translateY `;
or
setAttr "clus_track_top.translateY" ($CT_top+$upVal);

use


CT_top = clus_track_top.translateY;
or
clus_track_top.translateY =  (CT_top+upVal);

Phil[/QUOTE]

This is just what I was looking for. Thanks Phil!
This is what I have.

Before:

	float $arcLeng_01 = `getAttr crv_length_01.arcLength`;
    float $CT_top = `getAttr clus_track_top.translateY `;
    float $upVal = 0.1;
    if ($arcLeng_01<27.087){
        	setAttr "clus_track_top.translateY" ($CT_top+$upVal);
    }
    if ($arcLeng_01>27.087){
            setAttr "clus_track_top.translateY" ($CT_top-$upVal);
    } 

After:

	$arcLeng_01 = crv_length_01.arcLength;
    $CT_top = clus_track_top.translateY;
    $upVal = 0.1;
    if ($arcLeng_01<27.087){
        	clus_track_top.translateY = ($CT_top+$upVal);
    }
    if ($arcLeng_01>27.087){
            clus_track_top.translateY = ($CT_top-$upVal);
    }

This now updates while I move clusters around. Though This is what happens:

Yet the curve length remains the same. So at this point how can I get the curveInfo node, that gets the arcLength, to update as well?

[QUOTE=dgovil;17020]I didn’t know it was this easy:
http://lesterbanks.com/2010/10/customizing-maya’s-viewport-view-cube-to-spongebob/[/QUOTE]

Haha yeah it pretty simple, I figured it out from here.

So working a bit more on this project I have broken away from the true dynamic volume and instead I am using a Driven key to cheat the result I want.

This is what I got:

There is still a slight stretching of the space between the tread pieces (the sliding is from the timing of the right cluster), but I feel this is fine for the first draft as I’ll be refining it as I continue adding more control.

what is happening in the gif?
So what I’m basically doing is a driven key where the green numbers are the diver and the topcluster.translateY is the driven.
This works great! the only problem is that when I get to creating the controls on the base of the track that will follow the ground terrain/geometry editing the clusters at the bottom will not be able to effect the positioning of the top cluster.

Any feedback or suggestions (or questions) would be grand!