I recently worked on creating solution for wheel auto rotations inside maya. Well I searched a lot for finding adequate solution but some lacks a thing or two.

most commonly used solution are rotating the wheel based on translation X & Z with circumference of wheel , which is working fine but gives error when controller

is rotated in reverse direction( 180° or more). Another solution I found is to use Infinite animCurve and attach it with multiplier and manually animating it!

A guy named darvy has created a set of vehicle rigging scripts I found above method nicely implemented in there.

I find one tricky way to calculate auto rotations without worrying about rotations and direction where our rig is going. In brief I wrote expression which finds direction magnitude

where our wheel is going (forward or back). Also expression calculate the distance covered by wheel between last frame and current and calculate distance using circumference (2 π r)

Code:

float $radius =1;

int $dirVec;// get Joint translation value for calculating direction vector.

float $pastValX = `getAttr -time (frame -1) basePos_jnt.tx`;

float $pastValZ = `getAttr -time (frame -1) basePos_jnt.tz`;

// Now compare the difference of tip joint with base joint and basejoint’s previous frame

float $currPosX = tipPos_jnt.translateX – basePos_jnt.translateX;

float $currPosZ = tipPos_jnt.translateZ – basePos_jnt.translateZ;

// with past

float $pastPosX = tipPos_jnt.translateX – $pastValX;

float $pastPosZ = tipPos_jnt.translateZ – $pastValZ;

// now calculate the magnitude

float $currMag = `mag << $currPosX,0,$currPosZ>>`;

float $pastMag = `mag << $pastPosX,0,$pastPosZ>>`;

if ($pastMag >= $currMag) $dirVec = 1;

else $dirVec = -1;

// get controls translation value for actual calculations.

float $pastCtrValX = `getAttr -time (frame -1) placement_ctr.tx`;

float $pastCtrValZ = `getAttr -time (frame -1) placement_ctr.tz`;

float $currDistX = placement_ctr.translateX – $pastCtrValX;

float $currDistZ = placement_ctr.translateZ – $pastCtrValZ;

float $distance = ($currDistX*$currDistX) + ($currDistZ*$currDistZ);

$distance = sqrt($distance);

// finding distance by dividing into circumfrence

float $rotation = $distance /(2* 3.1428*$radius) *-360 * $dirVec;

$rotation += tyreRot.rotateX;

tyreRot.rotateX = $rotation %360;

sample sceneFile

### Like this:

Like Loading...

*Related*

Hi i am trying a wheel rotating for the first time. i have a rig inside my model and each time i try a different method whether it is set driven keys or parenting or different grouping(including an expression or two) once i bind skin the wheel no longer turns when i pull the whole model forward.

sounds like hierarchy problem, try unparenting ur geometry(tyre) and then just parentConstrain with whatever ur joint (which is rotating tyre than has expression)

Or send across ur sample file i will have look..

Hi there! awesome script. One problem though, when I scrub the animation back to frame 1, rotation of wheel does not come back to 0. Is there a way to solve this?

yeah! it is because of expression being calculating at per frame basis also, i’m calculating distance relative to previous frame (frame-1) . I’m finding any way to reverse it when we are scrubbing timeline or when we move timeline to initial frame. thx sunny

underearth, thank you very much for your help. I was going through the script(not an easy thing for beginner like me) and noticed “basePos_jnt” and “tipPos_jnt”. Dose it mean that there are two joints controlling the wheel?

Thank you in advance for your time!

i havent checked the file lately! but if I remember correctly tip joint is for finding direction in an expression, only problem i have find in this setup is, when vehicle moves side ways, then wheel rotes unNaturally, however it works great when tyres are on motion path

Thanks so much, is the only one that works relly, sorry for my english

I’m shortly updating this setup, stay tuned, this setup has one s,all problem when tyres are moved sideways.

Great tutorial, man! One way to remedy the sideways movement is to divide the last position by its magnitude, divide the current position by its magnitude (also known as normalizing) and then take those two normalized values and calculate the dot product. The resulting scalar value will be from -1.0 to 1.0. If you then multiply this value (which would be the cosine) by the value you are using to calculate the rotation, the tire will only spin when the movement of the ctrl object is not perpendicular to the original position. Hope that makes sense.

Hello there, simply turned into aware of your blog

through Google, and found that it is truly informative.

I am gonna

be careful for brussels. I’ll appreciate should you proceed this in future.

Many people shall be benefited

out of your writing. Cheers!

The other day, while I was at work, my cousin stole my iPad and tested to

see if it can survive a twenty five foot drop, just so she can be a youtube sensation.

My iPad is now destroyed and she has 83 views. I know this

is totally off topic but I

had to share it with someone!

Pingback: Auto rotation for carTyre, Wheel in maya | Rigging and more | timcoleman3d

Hi there! I just wanted to ask if you ever have any problems with hackers?

My last blog (wordpress) was hacked and I ended up losing months of hard work due

to no back up. Do you have any solutions to stop hackers?

Hi there, just letting you know that there is a much simpler way to do this. You can just use the Pythagorean theorem to calculate the distance using only the X and Z. a^2 + b^2 = c^2

In this case the mel code looks like:

$distPythag = sqrt((pow yourGlobalAnim.translateX 2) + (pow yourGlobalAnim.translateZ 2))

Nevermind hah, I realized how this fails shortly after posting this.

I’ve reworked it and found another method to do this which involves sampling values at the start frame vs the current frame. I also just have the user specify which direction (forward or back) the wheel is facing.

//THIS EXPRESSION WILL AUTO ROTATE A KEYFRAMED WHEEL, IT WILL NOT WORK UNLESS TWO OR MORE KEYS ARE SET

//UNLIKE OTHER AUTO ROTATE EXPRESSIONS, THIS ONE WILL WORK NO MATTER WHICH DIRECTION THE WHEEL IS FACING, YOU MAY FREELY ROTATE THE Y AXIS

//if the wheelRotateAuto control is on…

if(anim_global.wheelRotateAuto == 1){

//the user specifies what direction the wheel is facing

int $dir;

if(anim_global.direction == 0) $dir = 1;

else $dir = -1;

//read the X and Z values at the start of the playback range, and at the current frame

float $startTime = `playbackOptions -q -minTime`;

float $currTime = `currentTime -query`;

float $startX = `getAttr -time ($startTime) anim_global.translateX`;

float $startZ = `getAttr -time ($startTime) anim_global.translateZ`;

float $currX = `getAttr -time ($currTime) anim_global.translateX`;

float $currZ = `getAttr -time ($currTime) anim_global.translateZ`;

//get the difference between the start and current values

float $diffX = $currX – $startX;

float $diffZ = $currZ – $startZ;

//use the pythagorean theorem to calculate the distance

$distance = sqrt(pow($diffX, 2) + pow($diffZ, 2));

//divide the distance by the cirumference of the wheel, mult by 360, mult by which direction it is going.

anim_b_wheel_const.rotateX = $dir * 360 * $distance/(b_wheel_sizeShape.distance * 3.14);

}

hello, thank you for sharing this script. Using just one wheel works great, but when I have 4 wheels is not very friedly to animate the 4 controlers of every wheel… so I did a master control to move all the 4 wheels and remove the other controlers, but because the pivot of that master is in the center of the car (and not the center of the wheel) is not working properly. Do you have any tip or trick to solve this? Or it should work well and I may be doing something wrong? Thank U again 🙂