23 February, 2010
Animatable Pivot System
This is a working demo of my solution for animatable pivot in Maya. I believe it is quite flexible and fast. It allows animators to shift pivots very easily and only one object needs to be keyed. No adjacent two key mechanism necessary, but you can do it if you want.
Most of the logic is implemented using Node network. There is one sctiptJob for each pivot which calls a function. This function is very small and common for all pivots hence no multiple expressions. And the only thing this mel function does is to add the value to the offset to create a new offset which then can be keyed. So there is very minimal mel footprint. All the calculations including matrix multiplication, finding how much object will move, calculate temporary offset etc are done via nodes. I should probably make a single node out of this later.
I will post a video showing the usage of this method.
22 February, 2010
Attribute Change Event
If you have a boolean attribute set to 0. And you set the value again to 0 then the attribute change event is still fired even if it is the same value as before. That means the network will be evaluated again even if the actual value does not change. Hence a dirty bit is set whenever you set a value, it does not matter if it's the same as before. I concluded this from testing with expression node since it works based on input output concept.
edit:(23-2-10)
This feature is actually nice if you want to use an attribute as a button. i.e. you can use only one enum value and user can just click the same value to execute some kind of script or node network.
edit:(23-2-10)
This feature is actually nice if you want to use an attribute as a button. i.e. you can use only one enum value and user can just click the same value to execute some kind of script or node network.
19 February, 2010
Interesting Notes @ Expression Node
Expression in maya is basically a node that takes inputs and processes them with MEL and gives output.
If you want to create an Expression node without connection to the actual objects, you can do the following.
Also, you should note that if you rename the nodes, expression automatically updates the object names in the expression (if you have used direct value assignments e.g. obj1.tx = obj2.tx).
It is also possible to have input connections to expression node from other nodes even if we are not using them later in expression. To do this you can just assign the attribute value to a variable instead of another attribute. So you can create an expression just with $myVar = $myCtrl.attr. We can use this technique to evaluate expression when an attribute changes (with evaluate = on demand). This is a good alternative to a scriptJob for attribute change!! I discovered this technique while trying to solve bidirectional dependency using nodes in my independent study in spring'09. I could not manage to make bidirectional stuff in a perfectly working solution using just maya nodes. But, I have not given up.
edit:
Few Notes:
If you want to create an Expression node without connection to the actual objects, you can do the following.
.O[0] = .I[0]; .O[1] = .I[1]; .O[2] = .I[2];After this you can connect the inputs and outputs to this Expression node manually through connection editor. If you want your expression to be evaluated only based on value change of inputs then you can change expression to be evaluated "On Demand" instead of always. With always "time" node will be connected to expression resulting in evaluation when time changes (i.e. also while animation is playing).
Also, you should note that if you rename the nodes, expression automatically updates the object names in the expression (if you have used direct value assignments e.g. obj1.tx = obj2.tx).
It is also possible to have input connections to expression node from other nodes even if we are not using them later in expression. To do this you can just assign the attribute value to a variable instead of another attribute. So you can create an expression just with $myVar = $myCtrl.attr. We can use this technique to evaluate expression when an attribute changes (with evaluate = on demand). This is a good alternative to a scriptJob for attribute change!! I discovered this technique while trying to solve bidirectional dependency using nodes in my independent study in spring'09. I could not manage to make bidirectional stuff in a perfectly working solution using just maya nodes. But, I have not given up.
edit:
Few Notes:
- Only those nodes will be renamed in expression that has direct assignment values.
- It is required to compute some kind of output to be able to call expression, without any output connection expression will not be computed.
- You can use any kind of input and any kind of output connection even if they are not related.
17 February, 2010
Understanding Pivot Point
Generally we rotate an object about the origin. But we can also rotate an object around any arbitrary point in space. This arbitrary point is the pivot which is a reference point for rotating or scaling the object. So how does pivot point affect the object's transformation?
In essence, the pivot point just translates the object. It does not affect the orientation of the object in any way. This means that the object's orientation remains the same weather it is rotated around the origin or any arbitrary point in space. Following image explains this characteristic. You can see that even if the pivot changes, the object's orientation remains the same in all cases.
In essence, the pivot point just translates the object. It does not affect the orientation of the object in any way. This means that the object's orientation remains the same weather it is rotated around the origin or any arbitrary point in space. Following image explains this characteristic. You can see that even if the pivot changes, the object's orientation remains the same in all cases.
12 February, 2010
API: Node start and end functions
Following are what I call startup and ending functions that are called during some kind of (un)initializing process. I have also described at what event they are called in Maya.
Sequence in which these functions are called:
MPxNode::initialize()
When a node plugin is loaded this is the first function to be called.
initializePlugin()
After above function is called during loading of the plugin.
Constructor
When a node is created, e.g. using createNode.
Destructor
When node is deleted and it is not referenced by undo queue (imp).
uninitializePlugin()
When a node plugin is unloaded from Maya.
-initializePlugin()
-uninitializePlugin()
-Constructor
-Destructor
-MPxNode::initialize()
Sequence in which these functions are called:
MPxNode::initialize()
When a node plugin is loaded this is the first function to be called.
initializePlugin()
After above function is called during loading of the plugin.
Constructor
When a node is created, e.g. using createNode.
Destructor
When node is deleted and it is not referenced by undo queue (imp).
uninitializePlugin()
When a node plugin is unloaded from Maya.
animCurveTA update after set key
While looking into how set keyframe event works, I found that animCurveTA nodes (or any other animation curve nodes) don't get recalculated until time changes. And this makes sense considering input for animCurveTA node is time1.outTime. So here is what happens,
- You set a key on the object.
- animCurveTA node creates a key-value pair, but it does not recalculate its "output" attribute. (I think some DG node adds value to animCurveTA)
- If you change time then output will get recomputed as "input" (time value) changes and plug is marked dirty.
So animCurveTA.output is updated only when time changes, not when a key is set.
- You set a key on the object.
- animCurveTA node creates a key-value pair, but it does not recalculate its "output" attribute. (I think some DG node adds value to animCurveTA)
- If you change time then output will get recomputed as "input" (time value) changes and plug is marked dirty.
So animCurveTA.output is updated only when time changes, not when a key is set.
11 February, 2010
ScriptJob for Keyable Attribute Change Event
Reading from forums it seems that there is a resistance in using ScriptJobs amongst character TDs. And there are reasons for that. But, I think there are some good uses of scriptJob without hitting the performance.
I was trying to make an attribute that is boolean and it jumps from one value to the other like a step key. And I wanted to detect change in this attribute. So I used scriptJob to do the same. However, as soon as I make this attribute keyable, scriptJob does not work as intended. And the reason is that if you are scrubbing the timeline and jump from one key to the other and then release the mouse, it fires up change attribute event even if you are not on the keyframe! And there isn't any elegant way to solve this in MEL. So scriptJob even if powerful is limited when animation comes in the picture.
edit:
There is a work around logic to ensure within the scriptjob call that the attribute change was caused only by a manual change in channel box.
edit:
There is a similar problem with non-keyable attribute and scriotJob. However, that happens only if you are continuously playing animation in viewport and then stop the animation, not while scrubbing timeline.
I was trying to make an attribute that is boolean and it jumps from one value to the other like a step key. And I wanted to detect change in this attribute. So I used scriptJob to do the same. However, as soon as I make this attribute keyable, scriptJob does not work as intended. And the reason is that if you are scrubbing the timeline and jump from one key to the other and then release the mouse, it fires up change attribute event even if you are not on the keyframe! And there isn't any elegant way to solve this in MEL. So scriptJob even if powerful is limited when animation comes in the picture.
edit:
There is a work around logic to ensure within the scriptjob call that the attribute change was caused only by a manual change in channel box.
edit:
There is a similar problem with non-keyable attribute and scriotJob. However, that happens only if you are continuously playing animation in viewport and then stop the animation, not while scrubbing timeline.
08 February, 2010
Using Constraints in Scripts
Sometime we require to align one object to another object or do some other kind of matching in our scripts. We can use dynamically created constraints in a script for such purpose and delete the constraint once we get the data. However, while using constraints in this way one should make sure that the object on which constraint is applied does not contain any animation curve. Because if animation curve already exists and constraint is applied then a pairBlend node is created which by default is turned off for the constraint.
Subscribe to:
Posts (Atom)