VSFX 705 - Programming Concepts for Visual Effects
Composition of a Primitive Matrix in MEL
Project Summary:
Write one or more Mel scripts that will construct a matrix of shapes.
Results:
Click on the image to the right to see a close up final render.
The Code
Below is the MEL I wrote to create a matrix of shapes based on iterations. An explanation follows.
proc makeMatrix(string $shapeCmd, int $arcs, int $rot){
for ($j=1; $j<=$arcs; $j++) {
for ($i=1.0; $i<=10; $i++) {
eval($shapeCmd);
rotate -r `rand 0 180` `rand 0 180` `rand 0 180`;
scale -a (1/$i) ($i/3) (1/$i);
move -r ((($i/1.5)*($i/1.5))/2) ($i*1.7) 0;
eval($shapeCmd);
rotate -r `rand 0 180` `rand 0 180` `rand 0 180`;
scale -a (1/$i) ($i/3) (1/$i);
move -r ((($i/2)*($i/2))/4) ($i*1.7) 0;
}
select -all;
rotate - p 0 0 0 -r 0 $rot 0;
}
}
for ($j=1; $j<=$arcs; $j++) {
for ($i=1.0; $i<=10; $i++) {
eval($shapeCmd);
rotate -r `rand 0 180` `rand 0 180` `rand 0 180`;
scale -a (1/$i) ($i/3) (1/$i);
move -r ((($i/1.5)*($i/1.5))/2) ($i*1.7) 0;
eval($shapeCmd);
rotate -r `rand 0 180` `rand 0 180` `rand 0 180`;
scale -a (1/$i) ($i/3) (1/$i);
move -r ((($i/2)*($i/2))/4) ($i*1.7) 0;
}
select -all;
rotate - p 0 0 0 -r 0 $rot 0;
}
}
The Breakdown
The main section of code uses a "for" loop to generate two arcs of polygon primitives based on simple parabolic functions. Generation begins at the origin and the shape is rotated randomly on all three axes, scaled by amounts that vary with the iteration number, and is then moved distances also based on iteration. Using a value based on "i" meant that nothing had to be expressed explicity and the transforms would change automatically based on the number of cycles. The "polyCone" commands were later replaced with an "eval" command that would parse the string passed in by the procedure call thru the variable "$shapeCmd". This way, the user can specify what type of primitive they would like to use rather than being locked into one.
for ($i=1.0; $i<=10; $i++) {polyCone;
rotate -r `rand 0 180` `rand 0 180` `rand 0 180`;
scale -a (1/$i) ($i/3) (1/$i);
move -r ((($i/1.5)*($i/1.5))/2) ($i*1.7) 0;
polyCone;
rotate -r `rand 0 180` `rand 0 180` `rand 0 180`;
scale -a (1/$i) ($i/3) (1/$i);
move -r ((($i/2)*($i/2))/4) ($i*1.7) 0;
}
The arc-building section is within another level of iteration. This one selects everything in the scene, i.e. all the arcs arlready constructed, and rotates them around the y-axis. This means the first is generated, selected, and rotated; the second is generated, selected along with the first, and rotated; etc. The angle of rotation and the number of arc pairs generated is passed, via the input variables "$arcs" and "$rot", thru the procedure call, enabling the user to control both.
for ($j=1; $j<=$arcs; $j++) {...(arc generation code)...
select -all;
rotate - p 0 0 0 -r 0 $rot 0;
}
Finally, the procedure is called with "makeMatrix($shapeCmd, $arcs, $rot)"; each of the input variables controlling
the aspects described earlier. Click on the image to the right to see a top-down view
comparing several variations on the procedure. In each the number of arcs and the angle of rotation have been
coordinated to make a complete revolution but this is not necessary. The user can easily create partial "tornado"
shapes by entering values that are out of sync.
The Final Product
Click on the images below to see examples of geometry generated with the procedure using spheres, cones, and helicies respectively. Due to the type of scaling performed on the primitives they all tend to end up as the same long thorn shape at the end of each arc. The "trunks" of the formations are unique to the type of primitive. Further expansion of the procedure could include case statements containing transforms specific to each primitive type so that the outer ends remain distinctive.
