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)
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;