PDA

View Full Version : Quick mel script question


ChrisSosa
08-25-2008, 09:19 PM
I have 4 expression that I want to convert into a mel script that I will shelve into a button. But I have no idea hot to convert the expressions into a mel script. Can somone help me out?

-Sosa

Gravedigger
08-25-2008, 09:56 PM
hey chris

do i get you right that you want a shelf button wich creates those expressions when pressed?

for this have a look at the "expression" command in the maya documentation.

grs Gravedigger

ChrisSosa
08-25-2008, 10:00 PM
That's correct but I have four expression I want to execute at once. I'll check out the documentation though. Thanks

Gravedigger
08-25-2008, 10:06 PM
you have to store your expression as a string which can be, depending on the length of your expression, quite a messy thing.

what i would suggest is that you write your expressions in the expression editor and after hitting the "create" button you go to your script editor and there in the history you have the command which has been executed.

copy this command and repeat this for all of your expressions. then you can add this script to the shelf and voilà

grs Gravedigger

ChrisSosa
08-25-2008, 10:59 PM
I actually tried that but I tried to input all the expression in the same script. I'll try it out again though.

Thanks a lot
-Sosa

ChrisSosa
08-26-2008, 10:53 PM
Alright guy's my simple question just turned into a pain in the butt... I'm trying to edit an expression I go off lostpencil.com. It's a pretty good wheel rotation expression that accounts for the ry problem. Now in the video tutorials on the website it he said there's a way to have the script evaluate the ty but I can't seem to figure it out.

Is there a better solution to my problem? Can someone fix my alteration to the expression? Or am I just sol?

Here's what I have so far.


// ===================================================================================
//
// rotate_wheel - rotate a wheel by moving the group1 translate node
//
// Use the control_handle to move and rotate the wheel. Use Object Mode when translating
// and local mode when rotating this control.
//
// Note: if you translate the control_handle in X direction, the wheel will rotate.
// Also, if you rotate the wheel upside down, then the wheel will rotate as if
// the floor is above it. If you wish to change this script, be sure to unlock
// the driven.rotateX channel.
//
// ===================================================================================

// these global definitions will only be executed once
//
global float $rl_oldX = 0.0;
global float $rl_oldZ = 0.0;
global float $rl_oldy = 0.0;

// set the radius of the wheel mesh
//
$radius = 1.56924;

// Initialize:
// distance - the distance the wheel has moved
// flip - multiplier used to determine if we need to change wheel rotation direction
//
$distance = 0.0;
$flip = 1;

// initialize wheel rotation to 0
//
if ($rl_oldX == 0.0 && $rl_oldZ == 0.0 && $rl_oldy == 0.0)
Gusher_anim_LBack_Wheel.rotateX = 0.0;
else
{
// calculate the distance between the last position and current position
// change_X is (x2-x1)
// change_Y is (y2-y1)
//
$change_X = Gusher_anim_LftBackWheelBuffer.translateX - $rl_oldX;
$change_Z = Gusher_anim_LftBackWheelBuffer.translateZ - $rl_oldZ;
$change_Y = Gusher_anim_LftBackWheelBuffer.translateY - $rl_oldy;

// distance = sqrt ((x2-x1)^2 + (y2-y1)^2)
//
$distance = sqrt (($change_X * $change_X) + ($change_Z * $change_Z) + ($change_Y * $change_Y));
// normalize the rotation of the wheel control to between 0 and 360 degrees
//
$cur_angle = Gusher_anim_LftBackWheelBuffer.rotateY % 360;

// depending on the way the wheel is turned, change the direction
// of the rotation
//
if ($change_Z < 0)
$flip = -1;
if ($cur_angle > 90)
$flip = -1 * $flip;
if ($cur_angle >= 270)
$flip = -1 * $flip;
if ($cur_angle < -90)
$flip = -1 * $flip;
if ($cur_angle <= -270)
$flip = -1 * $flip;

// convert the distance travelled by wheel into a rotation
// and add or subtract that to the current rotation.
//
Gusher_anim_LBack_Wheel.rotateX = Gusher_anim_LBack_Wheel.rotateX + ($flip * (( $distance / (6.2831 * $radius)) * 360.0));

}

// set the new last position
//
$rl_oldX = Gusher_anim_LftBackWheelBuffer.translateX;
$rl_oldZ = Gusher_anim_LftBackWheelBuffer.translateZ;
$rl_oldY = Gusher_anim_LftBackWheelBuffer.translateY;

kaymatrix
08-27-2008, 01:40 AM
Its working fine for me...

All I changed is ...

float $radius = 2;
float $distance = 0.0;
float $flip = 1;

Make sure Wheel rotation axis is X and Wheel Radius given specified.
AND WHEEL MUST BE NAMED - Gusher_anim_LBack_Wheel.
AND THE GROUP ABOVE.. IT MUST BE NAMED - Gusher_anim_LftBackWheelBuffer.


and Here is the script for shelf...


string $k = "// ================================================== =================================\r\n//\r\n// rotate_wheel - rotate a wheel by moving the group1 translate node\r\n//\r\n// Use the control_handle to move and rotate the wheel. Use Object Mode when translating\r\n// and local mode when rotating this control.\r\n//\r\n// Note: if you translate the control_handle in X direction, the wheel will rotate.\r\n// Also, if you rotate the wheel upside down, then the wheel will rotate as if\r\n// the floor is above it. If you wish to change this script, be sure to unlock\r\n// the driven.rotateX channel.\r\n//\r\n// ================================================== =================================\r\n\r\n// these global definitions will only be executed once\r\n//\r\nglobal float $rl_oldX = 0.0;\r\nglobal float $rl_oldZ = 0.0;\r\nglobal float $rl_oldy = 0.0;\r\n\r\n// set the radius of the wheel mesh\r\n//\r\n\r\n// Initialize:\r\n// distance - the distance the wheel has moved\r\n// flip - multiplier used to determine if we need to change wheel rotation direction\r\n//\r\nfloat $radius = 2;\r\nfloat $distance = 0.0;\r\nfloat $flip = 1;\r\n\r\n// initialize wheel rotation to 0\r\n//\r\nif ($rl_oldX == 0.0 && $rl_oldZ == 0.0 && $rl_oldy == 0.0)\r\nGusher_anim_LBack_Wheel.rotateX = 0.0;\r\nelse\r\n{\r\n// calculate the distance between the last position and current position\r\n// change_X is (x2-x1)\r\n// change_Y is (y2-y1)\r\n//\r\n$change_X = Gusher_anim_LftBackWheelBuffer.translateX - $rl_oldX;\r\n$change_Z = Gusher_anim_LftBackWheelBuffer.translateZ - $rl_oldZ;\r\n$change_Y = Gusher_anim_LftBackWheelBuffer.translateY - $rl_oldy;\r\n\r\n// distance = sqrt ((x2-x1)^2 + (y2-y1)^2)\r\n//\r\n$distance = sqrt (($change_X * $change_X) + ($change_Z * $change_Z) + ($change_Y * $change_Y));\r\n// normalize the rotation of the wheel control to between 0 and 360 degrees\r\n//\r\n$cur_angle = Gusher_anim_LftBackWheelBuffer.rotateY % 360;\r\n\r\n// depending on the way the wheel is turned, change the direction\r\n// of the rotation\r\n//\r\nif ($change_Z < 0)\r\n$flip = -1;\r\nif ($cur_angle > 90)\r\n$flip = -1 * $flip;\r\nif ($cur_angle >= 270)\r\n$flip = -1 * $flip;\r\nif ($cur_angle < -90)\r\n$flip = -1 * $flip;\r\nif ($cur_angle <= -270)\r\n$flip = -1 * $flip;\r\n\r\n// convert the distance travelled by wheel into a rotation\r\n// and add or subtract that to the current rotation.\r\n//\r\nGusher_anim_LBack_Wheel.rotateX = Gusher_anim_LBack_Wheel.rotateX + ($flip * (( $distance / (6.2831 * $radius)) * 360.0));\r\n\r\n}\r\n\r\n// set the new last position\r\n//\r\n$rl_oldX = Gusher_anim_LftBackWheelBuffer.translateX;\r\n$rl_oldZ = Gusher_anim_LftBackWheelBuffer.translateZ;\r\n$rl_oldY = Gusher_anim_LftBackWheelBuffer.translateY;";

expression -s $k -o Gusher_anim_LBack_Wheel -ae 1 -uc all ;

ChrisSosa
08-27-2008, 02:24 AM
Did it work well when moving in both the YZX Translate? Example if you where to make a Curve that goes in a circle and alter the CV’s so the wheel goes up and down. Sorry for the specifics it's just been pretty frustrating trying to get it right.

Its working well going on the zx translate it's just when I introduce the Y that seems to start going wacky cracky.

kaymatrix
08-30-2008, 06:17 AM
nope isnt workin'

i tried change ...
$rl_oldY = Gusher_anim_LftBackWheelBuffer.translateY;
to...
$rl_oldy = Gusher_anim_LftBackWheelBuffer.translateY;

but its running backward while Y increases at the beginning... after tht its running.
I think it can be fixed! with the FLAG -flip variable!

kaymatrix
08-30-2008, 02:44 PM
hey i modified a little and its working slightly in Y direction too...



// ================================================== =================================
//
// rotate_wheel - rotate a wheel by moving the group1 translate node
//
// Use the control_handle to move and rotate the wheel. Use Object Mode when translating
// and local mode when rotating this control.
//
// Note: if you translate the control_handle in X direction, the wheel will rotate.
// Also, if you rotate the wheel upside down, then the wheel will rotate as if
// the floor is above it. If you wish to change this script, be sure to unlock
// the driven.rotateX channel.
//
// ================================================== =================================

// these global definitions will only be executed once
//
global float $rl_oldX = 0.0;
global float $rl_oldZ = 0.0;
global float $rl_oldy = 0.0;

// set the radius of the wheel mesh
//

// Initialize:
// distance - the distance the wheel has moved
// flip - multiplier used to determine if we need to change wheel rotation direction
//
float $radius = 2;
float $distance = 0.0;
float $flip = 1;

// initialize wheel rotation to 0
//
if ($rl_oldX == 0.0 && $rl_oldZ == 0.0 && $rl_oldy == 0.0)
Gusher_anim_LBack_Wheel.rotateX = 0.0;
else
{
// calculate the distance between the last position and current position
// change_X is (x2-x1)
// change_Y is (y2-y1)
//
$change_X = Gusher_anim_LftBackWheelBuffer.translateX - $rl_oldX;
$change_Z = Gusher_anim_LftBackWheelBuffer.translateZ - $rl_oldZ;
$change_Y = Gusher_anim_LftBackWheelBuffer.translateY - $rl_oldy;

// distance = sqrt ((x2-x1)^2 + (y2-y1)^2)
//
$distance = sqrt (($change_X * $change_X) + ($change_Z * $change_Z) + ($change_Y * $change_Y));

// normalize the rotation of the wheel control to between 0 and 360 degrees
//
$cur_angle = Gusher_anim_LftBackWheelBuffer.rotateY % 360;

// depending on the way the wheel is turned, change the direction
// of the rotation
//
if ($change_Z < 0)
$flip = -1;
if ($cur_angle > 90)
$flip = -1 * $flip;
if ($cur_angle >= 270)
$flip = -1 * $flip;
if ($cur_angle < -90)
$flip = -1 * $flip;
if ($cur_angle <= -270)
$flip = -1 * $flip;

//-----Modified Area-----//
if ($change_Y >0 && $flip ==-1)
$flip = -1 * $flip;




// convert the distance travelled by wheel into a rotation
// and add or subtract that to the current rotation.
//
Gusher_anim_LBack_Wheel.rotateX = Gusher_anim_LBack_Wheel.rotateX + ($flip * (( $distance / (6.2831 * $radius)) * 360.0));

}

// set the new last position
//
$rl_oldX = Gusher_anim_LftBackWheelBuffer.translateX;
$rl_oldZ = Gusher_anim_LftBackWheelBuffer.translateZ;
$rl_oldy = Gusher_anim_LftBackWheelBuffer.translateY;




I have add the line...

if ($change_Y >0 && $flip ==-1)
$flip = -1 * $flip;


As per logic it must work .... i testd placing it in a curve and its running well... i need some ppls to test it more for unknown bugs!


you can try the script available in HIGHEND3D - Wheel Rigger and it almost similar to this..!

primalorb
04-29-2009, 03:11 AM
hey there
i am trying to implement this expression into one of my scenes
i have this script working for 1 wheel and it seems to work quite well. my question would be how could i make this evaluate for 4 wheels? ive tried adding in lines and it gives errors, and also creating different expressions for each wheel, and that didnt work, as it only still allowed one wheel to run the expression?

also, i have the wheel being controlled by the translation of the ctrl locator of the car, which is in the middle of the car. obviously the rotation of the wheel around a turn is incorrect as the inside and outside wheels would be rotating at the same speed, when the inside should turn slower and the outside faster.

is it possible to use a locator at each wheels position to drive the rotation expression? i initially tried it like that but it didnt seem to do anything as the actual animation was on the control locator, which the 4 independant wheel locators were parented to

sorry if this is confusing, but if anyone has any ideas, or could use more info please ask

thanks in advance, greatly appreciated!

kaymatrix
04-29-2009, 05:27 PM
I think its not a good idea to calculate rotations for all 4 wheels individually!

Just try ... connecting rotation attribute of main one wheel to other wheels... through a multiply/divide node , in case you need it!
i never seen a vehicle with wheels each has various RPM.

-Kumar

ChrisSosa
04-30-2009, 02:29 PM
You actually have to run different scripts for each of the wheels. Just change the name on the script to match the name of your wheels and save it as 4 different expressions. Let me know if that works.

And yes it is possible to use the rotation of the wheel to drive the position of the wheel's rotation. You just need to make sure the expression is looking at that wheels position and not the master controller.

primalorb
05-01-2009, 10:29 PM
hey
yeah i had originally tried different expressions for each wheel (had tried the first two to see how it was going) and only one was working
it made no difference which one it was, i could delete one of the expressions and the other would work.
hmmm, ill have some time tomorrow to do some more experimenting

so as this expression is now, is it getting the translation from the actual local translation (hence why a child of the main body wont drive the wheel rotation) or is it a global position? i would think if it was global that i could use the location of each wheel locator as an individual driver to the rotation, but maybe not?

any ideas again would be appreciated, thanks for the help guys

ChrisSosa
05-02-2009, 07:11 AM
Try this script. I've tested this one and it's working on my side. Just make sure when you create your tires there grouped properly.

Driver>Driven>Object

Make sure you have a specific prefix for each tire group such as Rgt_rr_, Lft_rr_ and so on. Also make sure the tires are not grouped together. Keep them all seperate and parrent constrain them to your master controller.

For the front wheels you can use the connection editor and create a wheel turn cntrl that is connected to your tirer prefix_Driver.translateY.

Also, make sure you messure your radius and change the $radius to that value. Make sure you keep it with a decimel even if it's 1.0. I've found that some computer's will evaluate it differently if listed otherwise.

Hope that helps.

Sosa out!




// ================================================== =================================
//
// rotate_wheel - rotate a wheel by moving the group1 translate node
//
// Use the control_handle to move and rotate the wheel. Use Object Mode when translating
// and local mode when rotating this control.
//
// Note: if you translate the control_handle in X direction, the wheel will rotate.
// Also, if you rotate the wheel upside down, then the wheel will rotate as if
// the floor is above it. If you wish to change this script, be sure to unlock
// the driven.rotateX channel.
//
// ================================================== =================================

// these global definitions will only be executed once
//
global float $Rgt_rr_oldX = 0.0;
global float $Rgt_rr_oldZ = 0.0;
global float $Rgt_rr_oldY = 0.0;

// set the radius of the wheel mesh
//
$radius = 1.0;

// Initialize:
// distance - the distance the wheel has moved
// flip - multiplier used to determine if we need to change wheel rotation direction
//
$distance = 0.0;
$flip = 1.0;

// initialize wheel rotation to 0
//
if ($Rgt_rr_oldX == 0.0 && $Rgt_rr_oldZ == 0.0 && $Rgt_rr_oldY == 0.0)
Rgt_rr_Wheel_Object_Driven.rotateX = 0.0;
else
{
// calculate the distance between the last position and current position
// change_X is (x2-x1)
// change_Y is (y2-y1)
//
$change_X = Rgt_rr_Wheel_Object_Driver.translateX - $Rgt_rr_oldX;
$change_Z = Rgt_rr_Wheel_Object_Driver.translateZ - $Rgt_rr_oldZ;
$change_Y = Rgt_rr_Wheel_Object_Driver.translateY - $Rgt_rr_oldY;

// distance = sqrt ((x2-x1)^2 + (y2-y1)^2)
//
$distance = sqrt (($change_X * $change_X) + ($change_Z * $change_Z) + ($change_Y * $change_Y));
// normalize the rotation of the wheel control to between 0 and 360 degrees
//
$cur_angle = Rgt_rr_Wheel_Object_Driver.rotateY % 360;

// depending on the way the wheel is turned, change the direction
// of the rotation
//
if ($change_Z < 0)
$flip = -1;
if ($cur_angle > 90)
$flip = -1 * $flip;
if ($cur_angle >= 270)
$flip = -1 * $flip;
if ($cur_angle < -90)
$flip = -1 * $flip;
if ($cur_angle <= -270)
$flip = -1 * $flip;

// convert the distance travelled by wheel into a rotation
// and add or subtract that to the current rotation.
//
Rgt_rr_Wheel_Object_Driven.rotateX = Rgt_rr_Wheel_Object_Driven.rotateX + ($flip * (( $distance / (6.2831 * $radius)) * 360.0));

}

// set the new last position
//
$Rgt_rr_oldX = Rgt_rr_Wheel_Object_Driver.translateX;
$Rgt_rr_oldZ = Rgt_rr_Wheel_Object_Driver.translateZ;
$Rgt_rr_oldY = Rgt_rr_Wheel_Object_Driver.translateY;

primalorb
05-03-2009, 01:40 PM
i was still having issues getting 4 scripts to run at the same time, but i managed to copy the rotation value to the other wheels in the hypershade with the multiply/divide

im wondering though, is there a way to keep the rotation values positive?
i just put it on a test motion path and it was working until it turned a certain direction, and then the wheels rotated in reverse. if there was a way to keep the translation a positive number maybe it would fix that?

thanks for the help so far guys

ChrisSosa
05-06-2009, 01:47 AM
It's sounds like you still have a problem in the script. Can you upload your scene so I can check it out?

CGTalk Moderation
05-06-2009, 01:47 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.