Collision Detection in Maya

Posted by on Oct 13, 2010 in code, Maya, MEL | 2 Comments

Based on this tutorial. You will need to download and source this script.

I added attributes to the cubes: .col1(int), .theCol_u(int), and .vel(float) to watch for collisions, “unique” collisions (see the tutorial), and the velocity of the cube, respectively.

Two expressions are created for each cube, each rigidBody. The first is created to watch the dynamic rigid body collisions, and the velocity of the rigid body.

// variables
string $myRigidBody = "rigidBody1";
int $contactCount;
int $uniqueContactCount;

//check velocity
vector $theVelocity1 = `getAttr rigidBody1.velocity`;
float $velCheck1 = ($theVelocity1.x + $theVelocity1.y + $theVelocity1.z);
float $absVel = `abs $velCheck1`;

pCube1.vel = $absVel;

// get $contactCount
$contactCount = `getAttr($myRigidBody+".contactCount")`;

// compute theCol_u
if ($contactCount > 0)
{
  string $array[] = `rigidBody -q -contactName $myRigidBody`;
  string $flatArray[] = flattenStringArray($array);
  $uniqueContactCount = size($flatArray);
}
else
{
  $uniqueContactCount = 0;
}

// set interface attributes
pCube1.col1 = $contactCount;
pCube1.theCol_u = $uniqueContactCount;

The second expression affects a shader, based on the collision and velocity values collected by the expression above.

int $theTime = `currentTime -query`;
if ($theTime > 0)
	if (myLam1.incandescenceR >.05)
		myLam1.incandescenceR = myLam1.incandescenceR -.075;
	else
		if (pCube1.vel > 0.2)
			if ( pCube1.theCol_u >=1)
				myLam1.incandescenceR = 2.5;
		else
			myLam1.incandescenceR = 0;

create a grid of cubes

Posted by on Sep 29, 2010 in code, how to, Maya, MEL, python | No Comments

Grid of cubes in Maya.

# create a grid of cubes, their bottom plane set to zero y, and the center point at zero y.
x = -20
count = 0
cubes = []
while x <= 20:
	z = -20
	while z <= 20:
		cube = mc.polyCube( name = ('polyCube_' + str(count) + '_' + str(x) + str(z)) )
		count +=1
		cubeName=cube[0]
		cubes.append(cubeName)
		mc.setAttr((cubeName + '.translateY'), .5);
		mc.makeIdentity(apply=True, t =True, r=True, s=True, n= 0)
		mc.ResetTransformations()
		mc.move(x, 0, z)
		z += 1
	x +=1

Block of cubes

import maya.cmds as mc
# create a block grid of cubes
# change the mult number below to change the amount of cubes created.
mult =  3;
count = 0
cubes = []
y = mult - mult
while y <= mult *2:
    x = mult * -1
    while x <= mult:
	    z = mult * -1
	    while z <= mult:
		    cube = mc.polyCube( name = ('cube_' + str(count) ) )
		    count +=1
		    cubeName=cube[0]
		    cubes.append(cubeName)
		    mc.move(x, y, z)
		    z += 1
	    x +=1
    y +=1

Make a 3d cube grid, based on a selected object’s bounding box.

//MEL
proc makeCubeGrid(int $cubeGridDiv)
{
    string $cube[];
    string $cubes[] = {};
    string $sel[] = `ls -long -sl`;
    float $bBox[] = `polyEvaluate -b -ae $sel[0]`;

    float $w = ($bBox[1] - $bBox[0]) / $cubeGridDiv;
    float $h = ($bBox[3] - $bBox[2]) / $cubeGridDiv;
    float $d = ($bBox[5] - $bBox[4]) / $cubeGridDiv;

    float $p[3];
    for($i=0;$i<$cubeGridDiv;$i++)
    {
        $p[0] = $bBox[0] + (($bBox[1] - $bBox[0]) / $cubeGridDiv) * $i;
        for($k=0;$k<$cubeGridDiv;$k++)
        {
            $p[1] = $bBox[2] + (($bBox[3] - $bBox[2]) / $cubeGridDiv) * $k;
            for($n=0;$n<$cubeGridDiv;$n++)
            {
                $p[2] = $bBox[4] + (($bBox[5] - $bBox[4]) / $cubeGridDiv) * $n;
                $cube = `polyCube -w $w -h $h -d $d -sx 1 -sy 1 -sz 1 -ax 0 0 0 -ch 0`;
                move ($p[0] + $w / 2) ($p[1] + $h / 2) ($p[2] + $d / 2) $cube[0];
                makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 $cube[0];
                $cubes[`size $cubes`] = $cube[0];
            };
        };
    };
    string $group = `group -em -n "cubes"`;
    parent $cubes $group;
};

makeCubeGrid(10);

Create a Graphic EQ using SoundKeys and Maya

Posted by on Sep 26, 2010 in animation, code, Maya, MEL, python | 10 Comments

You can create this graphic equalizer with Trapcode Soundkeys and Maya. Use my Python script, below, to automatically import keyframe data and create the eq.

Trapcode Soundkeys, an Adobe After Effects plugin, breaks audio into into about 27 frequency blocks, “ranges”, and allows you to drive animation, set keyframes, or export keyframes. To export keys, copy the keyframes from the After Effects timeline, then paste into a text editor to create your data.txt files. Each frequency range should have it’s own text file, named sequentially. Use a code editor like BB Edit or Text Wrangler, as these apps will save your .txt files with UNIX line returns, which are necessary to make my Python script work properly.

Place all the data files in a directory, by themselves, and use the Python script below to automatically build the EQ in Maya.

## make a graphic equalizer, based on keyframe data from After Effects and Sound Keys.
import os
import maya.cmds as mc
## add path to keyframe data files - just the source directory that contains them.
rootdir='/path/to/data/folder'
theAttribute = 'data'
count = 0
theCubes = []
for subdir, dirs, files in os.walk(rootdir):
	dataFiles = [each for each in files if each.endswith('.txt')]
	for thisFile in dataFiles:
		## create a cube for each data file, and distibute them across the  X axis
		mc.polyCube()
		cube = mc.ls(sl = True)
		cubeName=cube[0]
		theCubes.append(cubeName)
		mc.setAttr((cubeName + '.translateY'), .5);
		mc.makeIdentity(apply=True, t =True, r=True, s=True, n= 0)
		mc.ResetTransformations()
		mc.move( count -(len(dataFiles)/2), 0, 0)
		count +=1
count = 0
for subdir, dirs, files in os.walk(rootdir):
	dataFiles = [each for each in files if each.endswith('.txt')]
	for thisFile, o in zip(dataFiles, theCubes):
		## prepare each cube for animation by ading an attibute to accept the keys, and creating an expression
		theName = theCubes[count]
		mc.addAttr( theName, shortName='data', longName='data', defaultValue=1.0)
		mc.setAttr ( (theName + '.data'), e=True, keyable=True)
		mc.expression(o=theName, s = (theName + '.scaleY =' +  theName + '.data / 4'),  ae = True, uc = all)
		## make shader for each cube
		myBlinn = mc.shadingNode('blinn', asShader=True, name = ("myBlinn" + str(count)))
		myShader = mc.sets(renderable=True, noSurfaceShader=True, empty=True, name = ('myBlinn' + str(count) + 'SG'))
		mc.connectAttr( (myBlinn + ".outColor"), (myShader + ".surfaceShader"), f=True)
		mc.setAttr((myBlinn + ".color"), 0.1, 0.1, 0.1, type ='double3' )
		mySetRange =  mc.shadingNode('setRange', asUtility=True)
		mySetRange2 = mc.shadingNode('setRange', asUtility=True)
		mc.setAttr((mySetRange + ".minX"),230)
		mc.setAttr((mySetRange + ".maxX") ,240)
		mc.setAttr((mySetRange + ".oldMaxX") ,25)
		mc.setAttr((mySetRange2 + ".maxX") ,3)
		mc.setAttr((mySetRange2 + ".minX") ,.1)
		mc.setAttr((mySetRange2 + ".oldMaxX") ,25)
		myRamp = mc.shadingNode('ramp', asTexture=True)
		my2dPlace = mc.shadingNode('place2dTexture', asUtility=True)
		mc.connectAttr((my2dPlace + ".outUV"), (myRamp + ".uv"))
		mc.connectAttr((my2dPlace + ".outUvFilterSize"), (myRamp + ".uvFilterSize"))
		mc.setAttr((myRamp + ".colorEntryList[2].color"), 0, 0, 0 , type = 'double3')
		mc.removeMultiInstance((myRamp + ".colorEntryList[0]"), b=True )
		mc.removeMultiInstance(myRamp + ".colorEntryList[1]", b=True )
		mc.connectAttr( (theName + ".scaleY"), (mySetRange + ".valueX"), f=True)
		mc.connectAttr( (theName+ ".scaleY"), (mySetRange2 + ".valueX"), f=True)
		mc.connectAttr( (theName + ".scaleY"), (mySetRange2 + ".valueY"), f=True)
		mc.connectAttr( (theName + ".scaleY"), (mySetRange2 + ".valueZ"), f=True)
		myhsvToRgb = mc.createNode('hsvToRgb', ss=True)
		mc.setAttr((myhsvToRgb+".inHsv"), .75, .75, .75)
		mc.connectAttr( (mySetRange + ".outValueX"), (myhsvToRgb + ".inHsvR"), f=True )
		mc.connectAttr( (myRamp  + ".outColor"), (myBlinn + ".incandescence"), f=True )
		mc.connectAttr( (myhsvToRgb + ".outRgb"), (myRamp+ ".colorEntryList[2].color"), f=True )
		mc.connectAttr( (mySetRange2 + ".outValue"), (myRamp + ".colorGain"), f=True )
		mc.select(theName)
		mc.sets( e=True, forceElement= myShader)
		count +=1
		## read keyframe data and set keyframes
		dataFile = open((os.path.join(rootdir, thisFile)), 'r')
		lines = dataFile.readlines()
		dataFile.close()
		mylines = lines[10:-4]
		for eachLine in mylines:
			data = eachLine.split('\t')
			theFrame = data[1]
			theValue = data[2]
			mc.setKeyframe( o, v=float(theValue), at=theAttribute, t =float(theFrame))
## the code below will set the playback range to equal the amount of the keyframe data in the files
fileData = open(rootdir + '/' + dataFiles[0])
lines= fileData.readlines()
fileData.close()
myLines = lines[10:-4]
countLines = len(myLines)
mc.playbackOptions( minTime='0sec', maxTime=countLines)

Sample keyframe data, exported from After Effects.

Maya Gamma Node MEL Script

Posted by on Jul 5, 2010 in code, Maya, MEL | 3 Comments

If you are working linear in Maya, you probably add gamma correct nodes between each texture and it’s material.

This MEL script will add a gamma correct node (set to gamma .45) between a selected texture and it’s selected target material, and it will attach the network to the material’s color attribute.

Before you run the script:
first select the material and the texture that you want to attach to it.

string $mySel[] = `ls -sl`;
string $myMaterial[] = `ls -mat $mySel`;
string $myTex[] = `ls -tex $mySel`;
string $myGamma = `shadingNode -asUtility gammaCorrect`;
setAttr ($myGamma + ".gammaX") 0.45;
setAttr ($myGamma + ".gammaY") 0.45;
setAttr ($myGamma + ".gammaZ") 0.45;
connectAttr -force ($myTex[0] + ".outColor") ($myGamma + ".value");
connectAttr -force ($myGamma + ".outValue") ($myMaterial[0] + ".color");

Launch Maya through Terminal

Posted by on Jun 22, 2010 in Mac, Maya | No Comments

If you are using a Macintosh, you can launch Maya by opening a terminal window, typing Maya and hitting the enter key. This will launch one instance of the Maya application, which will close if you quit the terminal window, by the way. This is also useful if you want to open multiple instances of Maya. Just open another terminal window, and repeat the procedure above.

Red and Blue Chair

Posted by on Jun 13, 2010 in animation, Maya, modeling, rendering | No Comments
The Red Blue Chair was a chair designed in 1917 by Gerrit Rietveld. It represents one of the first explorations by the De Stijl art movement in three dimensions.

 

Maya and Mental Ray.

Model based on several models found on the 3D warehouse. Download an obj of the Red and Blue Chair.

More info from Wikipedia.

Simple backdrop MEL script

Posted by on Jun 8, 2010 in code, lighting, Maya, MEL, rendering | No Comments

This MEL script will create a simple soft cornered backdrop from a poly plane and bend deformer.



XPM icon for shelf item.

Maya duplicate and move by frame

Posted by on May 23, 2010 in code, Maya, MEL | No Comments

Duplicate and move based on the frame number. This MEL script will duplicate your object once per frame (set up to be 0 – 30 in this script) and move it to a position based on the frame number (this script: 0 – 30, 0, 0).

Usage: select your object and run script.

string $myObj[] = `ls -sl`; for( $index = 0; $index <= 30; $index++ ) { currentTime $index; select $myObj[0]; duplicate; move -a $index 0 0 ; }

Possible uses: This can help if you have an animated object and you want to save the position at each frame as a separate piece of geometry.

Shattering Glass Dynamic Simulation

Posted by on May 22, 2010 in animation, dynamics, Maya | No Comments

Maya rigid bodies and Mental Ray.

Load More