Work in progress: Kid in suit character

Had some free time and wanted to build a character from start to finish so I can touch up on my rusty rigging/char. animation skills. Think this one's gonna be fun to play around with!

Howto: Maya scripted animation with MEL

This is basicly the same code I used for the old video I posted. Since then I've received a couple of requests on how to get that code to work. So I've finally fixed it up a bit and made it a bit more user friendly.

Download the Maya 2008 SP1 project files: Melanim.rar

Download the code in txt format: infectiousmelcode.txt

int $startnum = 1;
int $endnum = 125;
int $startobject = 1;
float $distace = 1.5;
float $slow = 0.3;
string $name = "pCube";
 
//init
//on frame 2 we run through all the objects(except for object number 1) and give them a random rotation and scale them to zero
if (frame == 2) {
int $z;
for ($z = $startnum; $z <=$endnum; $z++) {
if ($z != $startobject) {
float $rand = rand(1) * 360 ;
setAttr ($name + $z + ".rotateX") $rand;
setAttr ($name + $z + ".rotateY") $rand;
setAttr ($name + $z + ".rotateZ") $rand;
setAttr ($name + $z + ".scaleX") 0;
setAttr ($name + $z + ".scaleY") 0;
setAttr ($name + $z + ".scaleZ") 0;
}
}
}
 
if (frame > 2) {
for ($x = $startnum; $x <= $endnum; $x++)
{
float $attrx = getAttr ($name + $x + ".scaleX");
float $attry = getAttr ($name + $x + ".scaleY");
float $attrz = getAttr ($name + $x + ".scaleZ");
 
float $attrrx = getAttr ($name + $x + ".rotateX");
float $attrry = getAttr ($name + $x + ".rotateY");
float $attrrz = getAttr ($name + $x + ".rotateZ");
 
float $attr[3] = `xform -ws -q -piv ($name + $x)`;
 
if (($attrx != 1) || ($attry != 1) || ($attrz != 1) || ($attrrx !=0) || ($attrry !=0) || ($attrrz !=0))
{
// now go through all other objects and check
// if nearest objects are visible
int $y;
for ($y = $startnum; $y <=$endnum; $y++) {
if ($y != $x) {
float $attr2x = getAttr ($name + $y + ".rotateX");
float $attr2sz = getAttr ($name + $y + ".scaleZ");
if ($attr2sz > 0.8) {
 
float $attr2[3] = `xform -ws -q -piv ($name + $y)`;
float $distancex = $attr[0] - $attr2[0];
float $distancey = $attr[1] - $attr2[1];
float $distancez = $attr[2] - $attr2[2];
float $dist = sqrt ($distancex*$distancex + $distancey*$distancey + $distancez*$distancez);
float $randnum = rand(1);
if (($dist <= $distace) && ($randnum > $slow)) {
float $attribtemp = getAttr ($name + $x + ".scaleX");
if ($attribtemp < 1) $attribtemp = $attribtemp + (rand(1) / 10);
if ($attribtemp > 1) $attribtemp = 1;
setAttr ($name + $x + ".scaleX") $attribtemp;
 
$attribtemp = getAttr ($name + $x + ".scaleY");
if ($attribtemp < 1) $attribtemp = $attribtemp + (rand(1) / 10);
if ($attribtemp > 1) $attribtemp = 1;
setAttr ($name + $x + ".scaleY") $attribtemp;
 
$attribtemp = getAttr ($name + $x + ".scaleZ");
if ($attribtemp < 1) $attribtemp = $attribtemp + (rand(1) / 10);
if ($attribtemp > 1) $attribtemp = 1;
setAttr ($name + $x + ".scaleZ") $attribtemp;
 
$attribtemp = getAttr ($name + $x + ".rotateX");
if ($attribtemp != 0) {
$attribtemp = $attribtemp * 0.75;
if (($attribtemp <= 5) && ( $attribtemp >= -5 )) $attribtemp = 0;
setAttr ($name + $x + ".rotateX") $attribtemp;
}
 
$attribtemp = getAttr ($name + $x + ".rotateY");
if ($attribtemp != 0) {
$attribtemp = $attribtemp * 0.75;
if (($attribtemp <= 5) && ( $attribtemp >= -5 )) $attribtemp = 0;
setAttr ($name + $x + ".rotateY") $attribtemp;
}
 
$attribtemp = getAttr ($name + $x + ".rotateZ");
if ($attribtemp != 0) {
$attribtemp = $attribtemp * 0.75;
if (($attribtemp <= 5) && ( $attribtemp >= -5 )) $attribtemp = 0;
setAttr ($name + $x + ".rotateZ") $attribtemp;
}
 
}
}
}
}
}
}
}

How to use this?

Create a new scene, create a bunch of objects (I just created a cube and duplicated) where you want them to be at the end of the animation. Make sure their object names are all the same followed by a number. Also make sure that their scales are on 1 and rotations on 0.

Now open up Window->Animation Editors->Expression Editor.

Go to Select->By Expression Name, type a name for the script under Expression Name, paste the code in the code window.

You'll need to alter the values at the top of the script to work for your scene.
$startnum should usually be 1, but if your objects start at a different number, replace the 1 in the code.
$endnum is the number of the last object.
$startobject is the number of the object where the animation will start from.
$distance is the maximum distance between objects before the animation will start kicking in.
$slow is to slow the animation speed down, the higher the value the slower it will be (has to be between 0 and 1).
$name is the prefix for your object names, in the example scene you'll see I use pCube1 to pCube125.

Click Create. Hopefully maya wont complain about anything. You can close the window now and click play.

To actually render the animation you'll have to bake it by using Edit->Keys->Bake Simulation. And then delete the mel script from the Expression Editor, the baked animation should now play realtime and be renderable.

Good luck and don't be afraid to play around with the code. Feel free to post comments below if you have questions or anything.

How to get maya to work with your new nvidia gfx card

Finally got Maya to work, no more viewport update bugs!!
My setup: Intel Quad core, Nvidia 8600gt, 4gb ram, Windows XP 64.

Install 64bit 158.22 forceware drivers

Put MAYA_NO_VERTEX_ARRAY_SELECT = 1 in my maya env file.

Then in your nvidia control panel:

Threaded optimization = off
All the antialiasing and vsync stuff = off
Multi-display/mixed-GPU acceleration = single display
Horizontal Span (to get opengl to work on 2nd monitor)

Plug: Siggraph advanced photo resizing

Just saw this vid linked on digg, very interesting! Wouldn't be surprised if this made its way into browsers and photoshop.

Mel: Infectious animation

Heres an animation I did yesterday.

Basicly the mel loop checks which objects still have to be transformed/rotated/scaled whatever, and if they are next to ones that are already visible, if they are, they are animated towards the original mesh.

 
int $x;
 
//init
if (frame == 1) {
	int $z;
	for ($z = 159; $z <=338; $z++) {
		if ($z != 159) {
			float $rand = rand(1) * 360 ;
			setAttr ("polySurface" + $z + ".rotateX") $rand;
			setAttr ("polySurface" + $z + ".rotateY") $rand;
			setAttr ("polySurface" + $z + ".rotateZ") $rand;
			setAttr ("polySurface" + $z + ".scaleX") 0;
			setAttr ("polySurface" + $z + ".scaleY") 0;
			setAttr ("polySurface" + $z + ".scaleZ") 0;
		}
	}
}
 
if (frame > 2) {
for ($x = 159; $x <= 338; $x++)
{
	float $attrx = getAttr ("polySurface" + $x + ".scaleX");
	float $attry = getAttr ("polySurface" + $x + ".scaleY");
	float $attrz = getAttr ("polySurface" + $x + ".scaleZ");
 
	float $attrrx = getAttr ("polySurface" + $x + ".rotateX");
	float $attrry = getAttr ("polySurface" + $x + ".rotateY");
	float $attrrz = getAttr ("polySurface" + $x + ".rotateZ");
 
	float $attr[3] = `xform -ws -q -piv ("polySurface" + $x)`;
 
	if (($attrx > 1) || ($attry != 1) || ($attrz != 1) || ($attrrx !=0) || ($attrry !=0) || ($attrrz !=0))
	{
		// now go through all other objects and check
		// if nearest objects are visible
		int $y;
		for ($y = 159; $y <=338; $y++) {
			if ($y != $x) {
					float $attr2x = getAttr ("polySurface" + $y + ".rotateX");
					float $attr2sz = getAttr ("polySurface" + $y + ".scaleZ");
					if ($attr2sz > 0.5) {
 
						float $attr2[3] = `xform -ws -q -piv ("polySurface" + $y)`;
						float $distancex = $attr[0] - $attr2[0];
						float $distancey = $attr[1] - $attr2[1];
						float $distancez = $attr[2] - $attr2[2];
						float $dist = sqrt ($distancex*$distancex + $distancey*$distancey + $distancez*$distancez);
						if ($dist <= 0.3) {
								float $attribtemp = getAttr ("polySurface" + $x + ".scaleX");
								if ($attribtemp < 1) $attribtemp = $attribtemp + (rand(1) / 10);
								if ($attribtemp > 1) $attribtemp = 1;
								setAttr ("polySurface" + $x + ".scaleX") $attribtemp;
 
								$attribtemp = getAttr ("polySurface" + $x + ".scaleY");
								if ($attribtemp < 1) $attribtemp = $attribtemp + (rand(1) / 10);
								if ($attribtemp > 1) $attribtemp = 1;
								setAttr ("polySurface" + $x + ".scaleY") $attribtemp;
 
								$attribtemp = getAttr ("polySurface" + $x + ".scaleZ");
								if ($attribtemp < 1) $attribtemp = $attribtemp + (rand(1) / 10);
								if ($attribtemp > 1) $attribtemp = 1;
								setAttr ("polySurface" + $x + ".scaleZ") $attribtemp;
 
								$attribtemp = getAttr ("polySurface" + $x + ".rotateX");
								if ($attribtemp != 0) {
									if (($attribtemp <= 5) && ( $attribtemp >= -5 )) $attribtemp = 0;
									}
									if ($attribtemp > 0) $attribtemp = $attribtemp - 5;
									if ($attribtemp < 0) $attribtemp = $attribtemp + 5;
								setAttr ("polySurface" + $x + ".rotateX") $attribtemp;
 
								$attribtemp = getAttr ("polySurface" + $x + ".rotateY");
								if ($attribtemp != 0) {
									$attribtemp = $attribtemp * 0.75;
									if (($attribtemp <= 5) && ( $attribtemp >= -5 )) $attribtemp = 0;
									}
									if ($attribtemp > 0) $attribtemp = $attribtemp - 5;
									if ($attribtemp < 0) $attribtemp = $attribtemp + 5;
								setAttr ("polySurface" + $x + ".rotateY") $attribtemp;
 
								$attribtemp = getAttr ("polySurface" + $x + ".rotateZ");
								if ($attribtemp != 0) {
									$attribtemp = $attribtemp * 0.75;
									if (($attribtemp <= 5) && ( $attribtemp >= -5 )) $attribtemp = 0;
									}
									if ($attribtemp > 0) $attribtemp = $attribtemp - 5;
									if ($attribtemp < 0) $attribtemp = $attribtemp + 5;
								setAttr ("polySurface" + $x + ".rotateZ") $attribtemp;
 
						}
					}
			}
		}
	}
}
}
 

How you should browse

Why on earth are people still struggling with IE, slow loading pages full of ads, and bookmarking pages you know you'll want to use later but never find again.

If your guilty please follow this little howto and save yourself:

  • Install Firefox already...
  • Install Adblock Plus to get rid of pesky ads :D
  • Install del.icio.us Bookmarks addon and learn to bookmark like you should.