Representing Breaking Waves In Computer Graphics / Daniel Blacker / 07/03/05 / Page 8

 

1. Abstract 2.Introduction 3.Ocean Waves 4.Waves in CG 5.Tool Development 6. Conclusion 7. References 8.Code

8.1 Instructions

Load the scene waveGenMain.mb into Maya.

Open danielBlackerInnovations.mel in the script editor, select all and press enter to define.

Define the length and the degree of control of the desired wave with the first two sliders. To add an initial frame offset between the profiles adjust the bottom slider.

Press 'Create Key Profiles' To generate the Key-Profile Curves.

Refine the shape of the wave by adjusting the sliders, choose the desired resolution of the final wave and press 'Create Wave Surface'.

In Maya, in the modeling toolset go to surfaces>loft.

 

8.2 MEL Script 'danielBlackerInnovations.mel'


//Proxy Wave Creation Tool
//Daniel Blacker b1423465
//07/03/05


//requires scene waveGenMain.mb to function

proc duplicateProfile(float $dis, int $off, int $amount) //Duplicates profile curve, takes duplication distance, amount of curves and initial frame offset
{
global float $waveDataArray[100];
global float $keyDis;
global int $amountKey;

$amountKey = $amount;

float $offsetFrame = (`getAttr clip1.startFrame`) + $off;
int $i;
$dis = $dis*-1;

$keyDis = $dis;

select -r mainAnimCurve1 ;

for($i=2; $i <=$amount; $i++)
{
duplicate -rr -un;
move -r -ls -wd 0 0 $dis ;

select -addFirst ("clip" + $i) ;
setAttr ("clip" + $i + ".startFrame") $offsetFrame;
$offsetFrame += $off;
}

resetWaveArray();
}

proc printWaveArray(int $length) //Prints contents of the main array used to store the wave profile offset data
{
global float $waveDataArray[100];

int $i;

for($i=0; $i<=$length; $i++)
{
print ($waveDataArray[$i]);
print " ";
}

print "\n";

}

proc resetWaveArray() //Resets main wave array
{
global float $waveDataArray[100];

int $i;

for($i=0; $i<100; $i++)
{
$waveDataArray[$i] = 0;
}
}


proc interpolateProfiles(int $resolution) //Generates inbetween values from the key profiles, stores them in the main wave array, and creates the corresponding curves
{
global float $waveDataArray[100];
global float $keyDis;
global int $amountKey;


int $step = 0;
int $i;
int $j;
int $x = 1;
int $gap = $resolution;
int $arraySize = ($amountKey*$resolution);
int $curveCount = $amountKey;
int $resGap = 0;
float $newValue;
float $interpDis = $keyDis/$resolution;

for($i=1; $i<=$amountKey; $i++)
{
$waveDataArray[$step] = `getAttr ("clip"+$i+".startFrame")`;
print $waveDataArray[$step];
print "\n";
$step += $resolution;


}

printWaveArray($resolution*$amountKey);

while($gap>1)
{
for($i=0; $i<$arraySize; $i+=$gap)
{
$newValue = (($waveDataArray[$i]+$waveDataArray[$i+$gap])/2);
$waveDataArray[$i+($gap/2)] = $newValue;

}

$gap = $gap/2;
}

printWaveArray($resolution*$amountKey);

for($i=0; $i<$amountKey-1; $i++)
{
select -r ("mainAnimCurve" + $x);
for($j=1; $j<$resolution; $j++)
{

duplicate -rr -un;
move -r -ls -wd 0 0 ($interpDis) ;

$curveCount += 1;

select -addFirst ("clip" + $curveCount) ;
setAttr ("clip" + $curveCount + ".startFrame") $waveDataArray[$resGap + $j];

print ("Created array element " + ($i+$j) + "\n");
}

select -cl ;

$x++;
$resGap += $resolution;

}


}


proc waveKeyBuild() //links the UI to the functions
{
int $distance = `intSliderGrp -q -v DK`;
int $offset = `floatSliderGrp -q -v OK`;
int $amount = `intSliderGrp -q -v AK`;
duplicateProfile($distance,$offset,$amount);
}

proc selectProfiles(int $res) //selects the profile curves in sequential order, so a loft can be made sucsessfully
{

global int $amountKey;


int $resolution = $res;
int $curveTotal = ($amountKey*$resolution)-$resolution;
int $i;
int $j;
int $resOffset = $amountKey + 1;
int $step = $resOffset + ($resolution - 2);

select -r mainAnimCurve1 ;

print ("amountKey: " + $amountKey + "\n");

for ($i=2; $i<=$amountKey; $i++)
{
for ($j=$resOffset; $j<=$step; $j++)
{
select -tgl ("mainAnimCurve" + $j);
print ("added mainAnimCurve" + $j + "1\n");
}

select -tgl ("mainAnimCurve" + $i) ;
print ("added mainAnimCurve" + $i + "2\n");
$resOffset = ($resOffset + ($resolution - 2) + 1);
$step = $resOffset + ($resolution - 2);

}

}

proc waveSurface(int $res) //generates inbetween profiles and selects them ready for lofting
{
global int $amountKey;

int $resolution = $res;

interpolateProfiles($resolution);

selectProfiles($resolution);
}

global proc updateProfileOffset(int $offsetNum)
{
print ("offsetNum " + $offsetNum + "\n");
setAttr ("clip" + $offsetNum +".startFrame") `floatSliderGrp -q -v ("V" + $offsetNum)`;
}

global proc modifyKeys() //creates the second GUI window, generating sliders depending on the amount of existing key profiles
{

global int $amountKey;

int $resPass;

int $i;
float $profileBuff;

if (`window -exists GUI2`)

{ deleteUI GUI2;}

window -title "Create Breaking Wave" -widthHeight 600 600 GUI2;


columnLayout -columnWidth 600;

text -label " ";

text -fn boldLabelFont -label " Modify Key profile offset: ";

columnLayout -columnWidth 600;

rowColumnLayout -numberOfColumns 1 -columnWidth 1 600;


floatSliderGrp -dc "updateProfileOffset(1)" -label ("Profile 1 offset") -field true

-minValue 0 -maxValue 300

-fieldMinValue -800 -fieldMaxValue 800

-value `getAttr clip1.startFrame` V1;

if($amountKey>1)
{
floatSliderGrp -dc "updateProfileOffset(2)" -label ("Profile 2 offset") -field true

-minValue 0 -maxValue 300

-fieldMinValue -800 -fieldMaxValue 800

-value `getAttr clip2.startFrame` V2;
}
if($amountKey>2)
{
floatSliderGrp -dc "updateProfileOffset(3)" -label ("Profile 3 offset") -field true

-minValue 0 -maxValue 300

-fieldMinValue -800 -fieldMaxValue 800

-value `getAttr clip3.startFrame` V3;
}
if($amountKey>3)
{
floatSliderGrp -dc "updateProfileOffset(4)" -label ("Profile 4 offset") -field true

-minValue 0 -maxValue 300

-fieldMinValue -800 -fieldMaxValue 800

-value `getAttr clip4.startFrame` V4;
}
if($amountKey>4)
{
floatSliderGrp -dc "updateProfileOffset(5)" -label ("Profile 5 offset") -field true

-minValue 0 -maxValue 300

-fieldMinValue -800 -fieldMaxValue 800

-value `getAttr clip5.startFrame` V5;
}
if($amountKey>5)
{
floatSliderGrp -dc "updateProfileOffset(6)" -label ("Profile 6 offset") -field true

-minValue 0 -maxValue 300

-fieldMinValue -800 -fieldMaxValue 800

-value `getAttr clip6.startFrame` V6;
}
if($amountKey>6)
{
floatSliderGrp -dc "updateProfileOffset(7)" -label ("Profile 7 offset") -field true

-minValue 0 -maxValue 300

-fieldMinValue -800 -fieldMaxValue 800

-value `getAttr clip3.startFrame` V7;
}
if($amountKey>7)
{
floatSliderGrp -dc "updateProfileOffset(8)" -label ("Profile 8 offset") -field true

-minValue 0 -maxValue 300

-fieldMinValue -800 -fieldMaxValue 800

-value `getAttr clip8.startFrame` V8;
}
if($amountKey>8)
{
floatSliderGrp -dc "updateProfileOffset(9)" -label ("Profile 9 offset") -field true

-minValue 0 -maxValue 300

-fieldMinValue -800 -fieldMaxValue 800

-value `getAttr clip9.startFrame` V9;
}
if($amountKey>9)
{
floatSliderGrp -dc "updateProfileOffset(10)" -label ("Profile 10 offset") -field true

-minValue 0 -maxValue 300

-fieldMinValue -800 -fieldMaxValue 800

-value `getAttr clip10.startFrame` V10;
}

text -label " ";
text -fn boldLabelFont -label " Subdivision level: ";


columnLayout;

radioButtonGrp -numberOfRadioButtons 4

-label "Subdivisions" -labelArray4 "1" "2" "3" "4" -select 2 -onCommand1 ("$resPass = 2") -onCommand2 ("$resPass = 4") -onCommand3 ("$resPass = 8") -onCommand4 ("$resPass = 16");

text -label " ";

string $button = `button -label "Create Wave Surface"`;
button -edit -command ("waveSurface($resPass); ") $button;


showWindow GUI2;

}


proc waveBuilderUI() //initial GUI window

{

if (`window -exists GUI`)

{ deleteUI GUI;}

window -title "Create Key Profiles" -widthHeight 500 300 GUI;


columnLayout -columnWidth 500;

text -label " ";

columnLayout -columnWidth 400;

text -fn boldLabelFont -label " Key profile control: ";

rowColumnLayout -numberOfColumns 1 -columnWidth 1 400;

intSliderGrp -label "No. of key profiles" -field true

-minValue 2 -maxValue 10

-fieldMinValue 2 -fieldMaxValue 30

-value 4 AK;

rowColumnLayout -numberOfColumns 1 -columnWidth 1 400;

intSliderGrp -label "Distance between Keys" -field true

-minValue 1 -maxValue 20

-fieldMinValue 1 -fieldMaxValue 50

-value 8 DK;

rowColumnLayout -numberOfColumns 1 -columnWidth 1 400;

floatSliderGrp -label "Initial Key offset" -field true

-minValue -50 -maxValue 50

-fieldMinValue -100 -fieldMaxValue 100

-value 0 OK;

text -label " ";

string $button = `button -label "Create Key profiles"`;
button -edit -command ("waveKeyBuild(); modifyKeys(); ") $button;


showWindow GUI;

}

waveBuilderUI();


< prev page
Page 8 - Code