We initially developed this script to transfer the ocean data to Realflow to make splashes, but I discovered that it works extremely well to make collision objects for a CDT 4-Wheeler to be used to control boats/floating objects. What it does is bake displacement to poly for every frame specified in the GUI then creates a blendshape on the first one based off all the others. It also automatically animates the blendshape based on the frame range. So basically after you hit the Go button you'll end up with an animated polygrid that will match the Maya ocean perfectly.
Code: Select all
//###################################] C2i Studios [#######################################
// Script Name: C2i_OceanOven.mel
//
// By: Yuris Mangolds - [email protected]
// Jesus Orozco - [email protected]
//
// Version: 0.2
//
// Last Updated: 12/05/08
//
// Bugs/Comments/Suggestions: Send to [email protected]
//
// Update/Change this file at:
// http://c-2iinc.dyndns.org:8001/Public/C2i_OceanOven.mel
//
// Compatibility: Writen for Maya 2008
//
// Description: A tool to bake a patch of a Maya ocean to an animated blendshaped poly.
// Will work on anything that has animated displacement, not just Maya oceans.
// Very useful if you want the quality of a Maya ocean but need information that's
// compatible with third party plugins like Craft Director or RealWave.
//
// Installation: Place this script in your user scripts directory.
//
// Useage: Create or use an existing Maya ocean (examples in Visor).
// Type "C2i_OceanOven" in the command line. Press "Create" to make a new patch or
// pick an existing one and press "Choose". The rest should be self explanitory...
//#########################################################################################
global proc C2i_OceanOven() {
int $sf = `playbackOptions -q -ast`;
int $ef = `playbackOptions -q -aet`;
string $window = "C2i_OceanOven";
if (`window -ex ($window + "GUI")`)
{ deleteUI ($window + "GUI");}
//window starts
window -title $window -sizeable 0 ($window + "GUI");
columnLayout -columnOffset "left" 8 ;
rowColumnLayout -nc 3 -columnWidth 1 60 -cw 2 160 -cw 3 60 -columnAlign 2 "center";
button -l "Create" -c "polyOceanCreate" btnPolyOceanCreate;
textField -editable 0 -text "Create or Choose" -font "obliqueLabelFont" txfPolyOceanNurbs;
button -l "Choose" -c "polyOceanChoose" btnPolyOceanChoose;
setParent ..;
columnLayout -w 280;
floatSliderGrp -cw3 70 50 200 -label "Scale:" -field true
-cl3 "right" "center" "center"
-value 1 -en 0 -minValue 0.001 -maxValue 100
-fieldMinValue 0.001 -fieldMaxValue 10000
-ss 1 -precision 3
-dc "sldPolyOceanChange" -cc "sldPolyOceanChange" sldPolyOceanScale;
intSliderGrp -cw3 70 50 200 -label "Tesslation:" -field true
-cl3 "right" "center" "center"
-value 10 -en 0 -minValue 1 -maxValue 20
-fieldMinValue 1 -fieldMaxValue 50
-dc "sldPolyOceanChange" -cc "sldPolyOceanChange" sldPolyOceanTess;
setParent ..;
rowColumnLayout -nc 7
-cw 1 65 -cw 2 30 -cw 3 30 -cw 4 25 -cw 5 30 -cw 6 50 -cw 7 50;
text -l "Frame Range";
text -l "Start:" -align "right";
intField -value $sf infPolyOceanStart;
text -l "End:" -align "right";
intField -value $ef infPolyOceanEnd;
button -l "Timeline" -c "polyOceanFrame time"
-ann "Get time from timeline" btnPolyOceanFrameTime;
button -l "Render" -c "polyOceanFrame rend"
-ann "Get Time from render global" sbtnPolyOceanFrameRen;
setParent ..;
rowColumnLayout -nc 2 -cw 1 110 -cw 2 170;
checkBox -l "Lock Transforms" -annotation "Lock the created polyOcean's transforms to make sure it lines up with the render ocean"
-v 1 chkLockPoly;
button -l "Covert Ocean to Polys" -c "polyOceanConvert"
-width 160 -align "center" -enable 0 btnPolyOceanConvert;
setParent ..;
setParent ..;
showWindow ($window + "GUI");
window -edit -widthHeight 300 150 -sizeable 0 ($window + "GUI");
}
global proc polyOceanCreate(){
string $oceanShader = getCurrentOcean();
if( $oceanShader != "" ){
string $oceanSG[] = `listConnections ($oceanShader+".outColor")`;
string $nurbsPlane[] = `nurbsPlane
-name "nurbsOceanPatch" -w 10 -ax 0 1 0 -lr 1 -u 3 -v 3`;
float $position[] = `autoPlace`;
move -relative $position[0] $position[1] $position[2] $nurbsPlane[0];
setAttr ($nurbsPlane[0]+".translateY") 0;
setAttr -lock true ($nurbsPlane[0]+".ty");
sets -edit -forceElement $oceanSG[0] $nurbsPlane[0];
select -replace $nurbsPlane[0];
polyOceanChoose;
}
}
global proc polyOceanChoose(){
global int $polyOceanNurbsTessU;
global int $polyOceanNurbsTessV;
global float $nurbsOceanScale;
string $polyOceanNurbs;
string $sel[] = `ls -sl -tr`;
if (size($sel) > 1){
print "Select a single nurbs plane";
}else{
$polyOceanNurbs = $sel[0];
textField -e -tx $polyOceanNurbs -font "boldLabelFont" txfPolyOceanNurbs;
string $shape[] = `pickWalk -d down $sel[0]`;
setAttr ($shape[0] + ".displayRenderTessellation") 1;
setAttr ($shape[0] + ".overrideShading") 1;
setAttr ($shape[0] +".explicitTessellationAttributes") 1;
setAttr ($shape[0] +".featureDisplacement") 0;
$polyOceanNurbsTessU = `getAttr ($shape[0] + ".numberU")`;
$polyOceanNurbsTessV = `getAttr ($shape[0] + ".numberV")`;
$nurbsOceanScale = `getAttr ($polyOceanNurbs+".scaleX")`;
floatSliderGrp -e -en 1 sldPolyOceanScale;
floatSliderGrp -e -v $nurbsOceanScale sldPolyOceanScale;
intSliderGrp -e -en 1 sldPolyOceanTess;
intSliderGrp -e -v $polyOceanNurbsTessU sldPolyOceanTess;
select -r $polyOceanNurbs;
button -e -c "polyOceanConvert" -enable 1 -bgc 0.3 0.8 0.3 btnPolyOceanConvert;
DisplayShaded;
}
}
global proc sldPolyOceanChange(){
string $polyOceanNurbs = `textField -q -tx txfPolyOceanNurbs`;
string $shape[] = `pickWalk -d down $polyOceanNurbs`;
int $tess = `intSliderGrp -q -v sldPolyOceanTess`;
float $scale = `floatSliderGrp -q -v sldPolyOceanScale`;
setAttr ($shape[0] + ".numberU") $tess;
setAttr ($shape[0] + ".numberV") $tess;
setAttr ($polyOceanNurbs+".scaleX") $scale;
setAttr ($polyOceanNurbs+".scaleY") $scale;
setAttr ($polyOceanNurbs+".scaleZ") $scale;
select -r $polyOceanNurbs;
}
global proc polyOceanFrame(string $getTime){
int $sf;
int $ef;
switch ($getTime){
case "time":
$sf = `playbackOptions -q -ast`;
$ef = `playbackOptions -q -aet`;
break;
case "render":
$sf = `getAttr defaultRenderGlobals.startFrame`;
$ef = `getAttr defaultRenderGlobals.endFrame`;
break;
}
intField -e -value $sf infPolyOceanStart;
intField -e -value $ef infPolyOceanEnd;
}
global proc polyOceanConvert(){
global int $polyOceanNurbsTessU;
global int $polyOceanNurbsTessV;
global float $nurbsOceanScale;
string $polyOceanNurbs = `textField -q -tx txfPolyOceanNurbs`;
string $shape[] = `pickWalk -d down $polyOceanNurbs`;
string $oceanSG[] = `listConnections ($shape[0]+".instObjGroups[0]")`;
string $dispPolys[];
int $osf = `playbackOptions -q -min`;
int $oef = `playbackOptions -q -max`;
int $sf = `intField -q -v infPolyOceanStart`;
int $ef = `intField -q -v infPolyOceanEnd`;
int $fr = $ef - $sf + 1;
playbackOptions -e -min $sf;
playbackOptions -e -max $ef;
currentTime -edit $sf ;
int $amount = 0;
int $step = $fr/100;
progressWindow
-title "Baking Ocean to Poly"
-maxValue $fr
-minValue 0
-progress $amount
-status "Baking..."
-isInterruptable true;
for ($i=0; $i<$fr; $i++)
{
if ( `progressWindow -query -isCancelled` )
{
delete ($dispPolys);
break;
}
select -r $polyOceanNurbs;
displacementToPoly;
string $newPoly[] = `ls -sl`;
$dispPolys[$i] = $newPoly[0];
$amount += $step;
progressWindow -edit
-step 1;
playButtonStepForward;
}
if ( (`progressWindow -query -isCancelled` ) != 1)
{
string $baseFiName = `rename $dispPolys[0] "PolyOcean"`;
select -clear;
for ($j=1; $j<$fr; $j++){
select -add $dispPolys[$j];
}
select -add $baseFiName;
string $bs[] =`blendShape -ib -name "PolyOceanBlendshape"`;
string $tgts[]=`listConnections ($bs[0] + ".it")`;
delete $tgts;
setKeyframe ($bs[0]+".w");
currentTime -edit $ef;
blendShape -e -w 0 1 $bs[0];
setKeyframe ($bs[0]+".w");
//restore origional settings
currentTime -edit $sf;
playbackOptions -e -min $osf;
playbackOptions -e -max $oef;
setAttr ($shape[0] + ".displayRenderTessellation") 0;
setAttr ($shape[0] + ".overrideShading") 0;
string $PolyShape[] = `pickWalk -d down $baseFiName`;
sets -edit -forceElement $oceanSG[0] $PolyShape[0];
CenterPivot;
int $lock =`checkBox -q -v chkLockPoly`;
if ($lock != 0){
//Lock the patch
setAttr -l true ($baseFiName + ".scaleX");
setAttr -l true ($baseFiName + ".scaleY");
setAttr -l true ($baseFiName + ".scaleZ");
setAttr -l true ($baseFiName + ".translateX");
setAttr -l true ($baseFiName + ".translateY");
setAttr -l true ($baseFiName + ".translateZ");
setAttr -l true ($baseFiName + ".rotateX");
setAttr -l true ($baseFiName + ".rotateY");
setAttr -l true ($baseFiName + ".rotateZ");
}
}
progressWindow -endProgress;
select -r $polyOceanNurbs;
}
A couple notes about using CDT to simulate boats: The simulate button currently doesn't work on animated ground so you need to use record. If you play back your recorded animation and the 4-Wheeler jumps around crazily you need to increase the record speed so that it has time to display every frame while recording (I usually just put it on 5 to make sure). I found the most "boat like" simulations were done when having the resolution of the poly grid (set by using the tesslation slider before you hit the go button) so that each poly was roughly 1/2 the size of the boat (if the resolution is too high the 4 wheeler will act like it's on bumpy ground and won't be all floaty like). Also I found better results by scaling up the wheels really big (about 4 times thier default scale), for settings I used the ones described on CDT's gallery page, which worked pretty good. When needing to float many objects that were far apart in the scene I found it easiest to create a patch around the first robot, bake it, move the non baked patch to the next robot and bake it again, and rinse and repeat. Ended up with each robot having it's own little collision plane which worked really nice.