Mel Vertice Tricks I - Using RIB archives on point data
This project is a further advancement on the earlier saw palmetto concepts. By advancing further into Maya's scripting interface, we explore more possibilities and uses in the ReadArchive functions where numerous effects and controls can be used to generate much more complex effects and animations.
Notes!
This project may differ from the initial assignment writeup written for Professor Malcolm Kesson. It would have been edited to also reflect my later experiences, clearer tutorial techniques/codes and also later advancements made to the projects as well.
Introduction
The goal of this assignment is to master the ideology of evaluting polygonal properties for the distribution of objects and the possible animatable features that it can encompass in the use of "time" based codes and expressions. Of course, in this context time refers to the frame changes and other possible user induced changes in the scene.
The getVertices() Procedure
As a possible convenience and as a matter of study, Professor Malcolm Kesson has provided us with a global procedure called the getVertices(). The purpose of this procedure is to evalute the properties of a selected polygonal geometry and to extract its vertice position for use in a later provided command to propagade sphere on the vertices of a single object. This idea would be most difficult to express in a paragraph format, so I am attaching the code below with appropriate comments.
The pointSpheres() Procedure
A later command, which was also provided will be used to generate spheres using information generate by the getVertices() procedure. As a general note, incase anyone is confused - the information generated by the procedure is carried out of the "box" via the use of the variable $data. In case anyone wasn't paying enough attention, $data is a global variable when declared under a global proc command.
Essentially, this two coding works together to create spheres on every single vertice point of a evaluted polygon. A polygon, not nurbs or curves because of the very specific polyEvaluate command! The result of this code can be seen on the right ->
Though I would have to very frankly admit that the oddity of the script itself did confused me at the very beginning. Why so? Firstly, for the getVertices() procedure. It was indeed a clever way to ensure that data does get overwritten via the $counts, which also measures the initial size of the available global array, it was odd because the notion seemed to be redundant in my opinion, or at the very least for the function of this script. Due to the nature that all shapes gets truncated except for the very first shape node.
I would believe that the $count procedure to protect the global array would have been most effective if a loop was created to evaluate an entire selection of multiple shapes in the single getVertices() procedure. So, I decided to reduce the script as a really bad occupational habit.
This new command essentially removes the questionable areas from the earlier code. While personally, there are definitely better ways to execute this considering the nescessity of even using a vector array. But for now, let us follow through with the motions to identity the possible outcomes of this coding.
The moveSS() Procedure
Proceeding on, I now will add an expression that will refresh the position of the spheres as the original sphere is being animated. This is relatively easy, since expressions itself is alike to a Melscript and automatically adheres to the "time" of the frames as they are being changed. For this, a new procecure called moveSS() is created. The name is probably odd, but I do not want to risk create any logical name which may end up conflicting with a mel command
The key point of this command is to take note that I have removed the sphere creation command. Since are only required to move sphere, it was not needed. Also, because we are calling back older objects which are out of our selections, the move command will no longer work as initially intended. To ensure this feature, a naming convention has been created in both scripts. In the earlier script, sphere -r 0.2; has been changed to sphere -r 0.2 -n ("MovSphere" + $n);. This command essentially means that the auxillary spheres created will bear the name MovSphere1, MovSphere2 and etc.
This new procedure will be added to the main object "pSphere1" as an expression to update the movement of the MovSpheres at all times. This, coupled with a few adjustments creates the final code as seen below:-
Making Animation Possible
Now that we have basically complete the goal of creating spheres and having it move accordingly to the vertices of the selected polygon, it is time to make the code more efficient by completely proceduralizing it, adding animatable controls and cleaning up whatever mesh that I may have left in my haste in creating the script
Because this procedure included quite a significant amount of conceptualization and testing, I have decided to instead express the entire coding and explain my progress as I had worked to create it.
The final code with animatable features is as below:-
Explaining the Process
While the code itself is probably a very confusing piece of melscript (if you have not read the commented introduction), this following code packed with new animatable features is basically the same except for a few changes.
One, instead of including a move command in the pointSpheres() procedure, the move is now entirely depend on the expression based moveSS() procedure. Thus you will notice that the line move ($pos.x) ($pos.y) ($pos.z); has been removed .
Second, 5 attributes (interMovement, speedvar, posclamp, wobble and basename) have been added onto the main effected objects for two reason - and they are as listed as:-
► interMovement - This is the floating point based modifier which will determine the expression based animation. It represents the 0 - 100% cartesian coordinate of a point along a tangent from 0,0,0 to the position of the targeted vertice. An further explanation of this can be seen in a later math explanation below...
► speedvar - This value multiplies a sin based curve which adds onto the effect of the interMovement thus creating moving spheres that are either ahead or behind in its position along the earlier said tangent.
► posclamp - This position clamps the result of the interMovement and speedvar, thus either allowing moving spheres to overshoot or stop at the very exact point of its targets vertice.
► wobble - This value multiplies a sin base curve which will distort the cartesian coordinates of the moving spheres, causing it to lose its uniform appearance as each sphere "vibrates" along the tangent towards its targeted vertice.
► basename - This last attribute stores the name of the effected polygon! It is crucial because inorder to run a procedure, the command has to be either a name($variable) or name("objectname"). Since variables will lose its data in continual execution of the same code on multiple objects, and the objectname which are fixed contains "" which cannot be stored in a string. The logical way for me to execute a script based expression was to store the data into the object itself from which I can extract the information from as a unique variable.
Basename attribute is the very reason why I can proceduralize the entire code without having to determine the name of the targets polygon as a literal.
The Math
Quite frankly, the math turned out to be much more straight forward than expected. To explain in word, I simply interpolated the moving spheres along a tangent between an orginal position and a targets vertice position retrieved by the getVertices() procedure. Using interMovement to define the 0-100% point along the tangent. But since I am also defining the original point as 0,0,0 , there was no need to add the continued math onto a value where original point is. Thus, in my script the idea of the position is basically
Targeted Vertice position * Intermovement and speed var + distortions cause by sin based wobble.
And each of this values are mutiplied by user controled attributes, thus adding the animatable features to the script generation!! The results of each manipulation can be seen below:-
Ghosting
Yes, if you had not already realized. The earlier script had calculated the original position of the moving spheres as 0,0,0. While this effect works, it does not give a very complete appeal if you are considering the wide and possible animatable features of what ever polygon that becomes the intended use for this script.
So, to solve this problem I am going to make a "trail" commonly known as ghosting. Which will allow user a similar set of control as if it was previously manifested in the earlier script.
How do we go about it? The concept is simple... as long as one can interpret anything in a linear graph of math, anything is possible. Yes! This means that one will have to interpret the trajectory of the intended polygons into a linear format.
Sounds hard, but not really. Since the intended has already given us its cartesian coordinates in the getVertice() procedure, we need only to store it in a generic array of information and later interpret it into a linear form using correlational techniques. This can be easily done by simple createing multiple sets of arrays of which information will be transferred with every single frame.
And the diagram pretty much says it... all I really need to do is to create a series of arrays example $vertspos1 $vertspos2 $vertspos3 etc etc, to recover the data as retreive by the getVertice() procedure. Next, I only need to beable to correlate the data into a linear graph.
The technique is to simply change the way that I read my original position data from. For example if my interMovement is a value of 0.55, this means that my original position should be taken from the data of the 4th array and be calculated against the 3rd array. Which technically means 50% along the tangent formed by the cartesian coordinates of the 4th and the 3rd array.
Case in point, this concept is sound. However, because I want the moving spheres to feel more like homing missles than trailing smoke, I will choose to use the targeted vertice as the actual current position dictated by the getVertices() procedure. This would mean that a value of 0.55 would equate to the 50% mark on the tangent between the point recorded by the 4th array and the actual point position.
And now to actually implement the script, I have added a loop to load the required arrays $ghosts. But because we cannot generate names in a variable declaration code, I have used strings and the eval command to load the variables and to copy the data from the getVertices(). Since we need to understand that there is no data in the first frame and this would probably cause errors later on.
Now that we have created all these arrays, we need a system to reload them everytime. This would probably be added into the MoveSS() procedure. Sadly, for some very very odd reason, the same code that works here did not work in the MoveSS() procedure. The concept should be theoretically sound, but nevertheless, a procedurally generated ghosting array would have been easier to tweak and even amount up to the thousands. But for now, I shall manually code the 10 globals into the procedure. I have also added a part where the earlier would transfer its data to the arrays after them with each refresh done by the expression.
Similarly, some tweaks have been done to the general script. For example, because I am correlating the use of interMovement onto the list of arrays I have to extract the use of Speedvar out of the general moving math and directly in the code that defines which array the spheres take references from.
To do this, I simply multiplied the interMovement. Where 0 - 0.099999999~ induced no scripted movement and 0.1 -0.999999~ creates a variant movement and 1 forces the sphere onto the final targeted vertices. By say multiply a value of say 0.523 by 10, I get 5.23 - the 5 now tells me which array to load the data from and the 0.23 tells me that the point should be 23% on the tangent from the position recorded in array 5 towards the final vertice position.
The trick to most parts of the numeric extraction comes in the play of floats and integers. Since 0.523 equates 0 in integers and 5.23 equates 5 in integers, its easy to extract the front value by mere multiplication. This value of course is then inverted because the higher value = further away ghosting from the actual vertices.. While a higher intermovement value equates being closer to the final vertices. Thus the idea for this line of code goes:-
Ghosting array number = 10 - the integer of(intermovement multiplied by 10.
Take note that the code for extract the rest of the values from interMovement would extract values in an example where 0.523 becomes 0.023. This is done simply by deducting the actual interMovement value with the ghosting array number which is mutiplied by 0.1. Technically speaking the value should have been 0.23 instead of 0.023 if I were going by the original theory of which I had constructed this script. However because I am also not using the position of the array before but rather the final vertice position, I relented to allow this little script to happen to at the very least create some form of interpolation. A 23% instead of a 2.3% would have probably overshot the entire array's value anyway resulting in a jittery animation.
The last thing to note also are that I have removed the existance of posClamp since the value no longer works with the current math. Also a last feature which last scaling has also been added into the script
► basesize- This refers to the basic scale of the moving spheres in the scene. Users can animate or adjust this value to fix the basuic size of the spheres
► bubble- This refers to how drastically the spheres react to movement. The script compares the position of each sphere and extracts the intensity of its speed which will be multiplied to this value to create variants in scale. To generally put, the faster moving spheres will find themselves descaled according.
Download Code here
Content on this page requires a newer version of Adobe Flash Player.
Content on this page requires a newer version of Adobe Flash Player.
dave kin chang wei - visual effects artist / technical director - davekcw@yahoo.com.sg - www.kamid.net