colorAtPoint Maya command

Expressions for transforming nodes via pixel values.

string $cubes2[] = `ls -type transform "newCube*"`;
for( $each in $cubes2) {
float $u = `getAttr($each + ".translateX")`;
float $v = `getAttr($each + ".translateZ")`;
float $capValueF[] = `colorAtPoint -o RGB -u (($u+40)/80) -v (($v+40)/80) file1`;
setAttr ($each + ".scaleY") (($capValueF[0]+$capValueF[1]+$capValueF[2])*10);
setAttr ($each + "Lam.incandescenceR") $capValueF[0];
setAttr ($each + "Lam.incandescenceG") $capValueF[1];
setAttr ($each + "Lam.incandescenceB") $capValueF[2];
}
flushUndo;

Maya Particle Instancing Experiment

Maya Python script:

#Audio Driven Particle System 2011.10.27 A1
#Python for Maya
#Code By: Oliver Wolfson
#oliverwolfson.com - wolf@oliverwolfson.com
#You will need keyframes formatted in text files in an exclusive directory to make this work. See:
#http://oliverwolfson.com/animating-with-audio/ for more details

import os
import maya.cmds as mc

##LIGHT
Light = mc.spotLight(ca=120, n="mySpotLight")
mc.setAttr( ("mySpotLightShape.useDepthMapShadows"), 1)
mc.setAttr( ("mySpotLightShape.dmapResolution"), 2048)
mc.setAttr( ("mySpotLightShape.dmapFilterSize"), 6)
mc.setAttr( ("mySpotLightShape.penumbraAngle"), 10)
mc.setAttr( ("mySpotLightShape.dropoff"), 1)
mc.setAttr( ("mySpotLight.translateX"), 125)
mc.setAttr( ("mySpotLight.translateY"), 100)
mc.setAttr( ("mySpotLight.translateZ"), 20)
mc.setAttr( ("mySpotLight.rotateX"), -33)
mc.setAttr( ("mySpotLight.rotateY"), 10)
mc.setAttr( ("mySpotLight.rotateZ"), -45)
mc.setAttr( ("mySpotLight.scaleX"), 30)
mc.setAttr( ("mySpotLight.scaleY"), 30)
mc.setAttr( ("mySpotLight.scaleZ"), 30)

##AUDIO DRIVEN THING
num = 0
for p in range(0, 64, 2):
    print("this is the " + str(num) + " num:" + str(p))
    num += 1
    Locator = mc.spaceLocator(n=("myLocator"+ str(num)))

    Shader = mc.shadingNode('blinn', asShader = True)
    mc.setAttr ((Shader+ ".glowIntensity"), .1)
    SG = mc.sets (renderable=True, noSurfaceShader=True, empty=True)
    mc.connectAttr((Shader +".outColor"), (SG + ".surfaceShader"))
    mc.setAttr((Shader + ".color"),0.203189, 0.252033, 0.57554)

    Plane = mc.polyPlane(h = 10, sw = 1, sh = 15, cuv = 2)
    mc.setAttr(str(Plane[0]) + ".rotateX", 90)
    mc.setAttr(str(Plane[0]) + ".scaleX", .25)
    mc.makeIdentity( apply=True )
    mc.hyperShade(assign = Shader)

    mc.select(clear=True)
    Emitter = mc.emitter (type = 'omni')
    Particles = mc.particle()
    mc.connectDynamic(Particles, em= Emitter )
    mc.setAttr((Particles[1] + ".lifespanMode"), 1)
    mc.select(Plane[0])

    Wave = mc.nonLinear( type= 'wave' )
    mc.setAttr((Wave[0] + ".wavelength"), .4)
    mc.setAttr((Wave[0] + "Handle.rotateZ"), 90)
    mc.setAttr((Wave[0] + "Handle.rotateY"), 50)
    mc.setAttr((Wave[0] + "Handle.translateY"), -7)
    mc.setAttr((Wave[0] + "Handle.translateZ"), 11)
    mc.makeIdentity( apply=True )
    mc.select(clear=True)
    mc.particleInstancer( Particles[1], addObject = True, object = Plane[0], cycle='None', cycleStep=1, cycleStepUnits='Frames', levelOfDetail='Geometry', rotationUnits='Degrees', rotationOrder='XYZ', position='worldPosition', age='age')

    mc.expression ( s = Wave[0] + ".offset = " + Locator[0] + ".translateY/10;\n" + Wave[0] + ".amplitude = " + Locator[0] + ".translateY/10;\n" + Wave[0] + "Handle.rotateX = frame;\n" + Wave[0] + "Handle.rotateZ = " + Locator[0] +  ".translateY*0;\n" + Wave[0] + "Handle.scaleX =" + Locator[0] + ".translateY;\n"  + Wave[0] + "Handle.scaleY = " + Locator[0] + ".translateY;\n" + Wave[0] + "Handle.scaleZ = " +  Locator[0] + ".translateY;\n")
    mc.expression ( s = Emitter[0] + ".translateY = " + Locator[0] + ".translateY;\n" + Emitter[0] + ".rate = " + Locator[0] + ".translateY*20;\n" + Emitter[0] + ".speed = " + Locator[0] + ".translateY;\n")
    mc.expression ( s = Plane[0] + ".rotateY = " + Locator[0] + ".translateY*60;\n" + Plane[0] + ".translateY = " + Locator[0] + ".translateY;\n" + Plane[0] + ".scaleY = " + Locator[0] + ".translateY/;\n" + Plane[0] + ".rotateX = " + Locator[0] + ".translateY;\n")
    mc.expression ( s = Shader + ".incandescenceR =" + Locator[0] + ".translateY/200;\n" + Shader + ".incandescenceG = " + Locator[0] + ".translateY/200;\n" + Shader + ".incandescenceB = " + Locator[0] + ".translateY/100;")

    mc.select(Locator)
    mc.select(Plane, add=True)
    mc.select(Emitter, add=True)
    mc.select(Wave , add=True)
    mc.group(n= ("myGroup" + str(num)) )
    mc.setAttr("myGroup" + str(num) + ".translateZ", p*-10)

mc.select(clear=True)
for l in range(1, 33, 1):
    mc.select(("myLocator" + str(l)), add=True)

## add path to keyframe data files - just the source directory that contains them.
rootdir='/Volumes/2TB/work/3D/Maya/Maya_projects/Mogwai/sound/ranoPanoKeys01/zapped'
## "ty", in line 13, refers to the Maya attribute channel of the selected objects. Modify this attribute as necessary.
objs= mc.ls(sl=True)
for subdir, dirs, files in os.walk(rootdir):
    for thisFile, o in zip(files, objs):
        file = open((os.path.join(rootdir, thisFile)), 'r')
        lines = file.readlines()
        file.close()
        for i in range(len(lines)):
            mc.setKeyframe(o, at='ty', v=float(lines[i]), t=i, itt='linear', ott='linear')

Use this information to build key data for this script
http://oliverwolfson.com/extracting-raw-key-frame-data/

CG Rain Drops

Splashes created in Real Flow, and instanced to Maya Particles.

Ripples created with a dynamic fluid texture.

float $colU = particleShape1.collisionU;
float $colV = particleShape1.collisionV;

if ($colU > 0) {
int $xpos = fluidTexture2DShape1.resolutionW * $colU;
int $ypos = fluidTexture2DShape1.resolutionH * $colV;
setFluidAttr -xi $xpos -yi $ypos -at density -ad -fv 0.6 fluidTexture2DShape1;
particleShape1.lifespanPP=0;
}

Create a Graphic EQ using SoundKeys and Maya

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.

White Light Group web teaser

Web teaser for White Light Group media company.

Red and Blue Chair

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.

Animating with audio

This animation was created using After Effects and Maya.

Getting audio key frames out of After Effects using Trapcode Sound Keys.

Extracting raw key frame data from After Effects formatted keyfame data that can be used by Maya, via shell script.

Importing keyframe data to Maya using Python.

Creating Maya shaders that react to audio key frames

Outputting a depth map from Maya and creating depth of field in After Effects.

Shattering Glass Dynamic Simulation

Maya rigid bodies and Mental Ray.

Acuvue Product Launch Video

Created at Elastic Creative in San Francisco. I was tasked with texture, lighting, and rendering.

Falling Diamonds

Part of a Thai music video in tribute to Petchara, a star of the 60′s, and featuring Weir, a current star. I was tasked with adding cg diamonds falling from above.