lauantai 19. lokakuuta 2013

Vector and Matrix functions with Vector Product node in Maya

This document will explain how to use the vector product node in Maya to calculate vector cross and dot products as well as to find out object's translation in a custom space, as in to find out object's world space coordinates without moving it from the hierarchy or vice versa. This method bypasses the rotation problem that you get if trying to find out object’s world space by doing maths on the basic translation values of objects that have also rotations in the mix.

Vector Product node can be found under utilities in Hypershade. It has operation option which defines which calculation you want to perform, they include dot product, cross product, vector matrix product and point matrix product. You can attach 2 vectors into input1 and input2 of the vector product. You can also attach a matrix into the node; this does not show up on the attribute menu which is why you need to use the connection editor to do this. This will become necessary when trying to find out custom space translations. It also has a normalize option which you can switch on and off, based on your needs (more uses explained below)

Dot product
Output: float
Output represents the angle between the 2 input vectors. If the output is normalized output is the actual cosine value and will vary between -1 and 1.If the normalized output is one it signifies that the input vectors run parallel to each other. If the output is 0 the vectors are perpendicular. And if the output is -1 the vectors run in opposite directions


Cross Product
Output: vector
The output vector will be in right angle (perpendicular) to the input vectors. In other words the output vector is almost like the normal of the plane that is defined by the 2 input vectors.


Vector matrix Product and Point Matrix product
Output: vector/point
Point Matrix product allows you to find out object’s translations in a custom space i.e. under some other hierarchy in the scene that it currently is in.

Example scene:
hierarchy:
purpleCone (world/local t:0,4,0 r:0,0,0 s:1,1,1)
orangeSphere (local t:2,-2,2 r:45,45,45 s:1,1,1)
blueCube (local t:-3,-3,-3 r:0,0,0 s:1,1,1)
greenTorus (world/local t:-3,-3,-3 r:0,0,0 s:1,1,1)


To find out object's translation in it’s parents local space as in move the translation values up one level in the hierarchy without breaking the current hierarchy, you need to connect the parent object's xFormMatrix into the vector product node’s matrix input. You also need to connect the queried object's translation vector into the vector products input1 slot. The input2 vector will be left blank. Change the operation of the vector product node into `point matrix product` under the attribute editor. The resulting vector is the queried object's translation in the parent objects local space, if the parent object is under the world then you get the world space coordinates of the queried object.

In the example scene we could find out the blueCube's (bottom of the hierarchy) translation values under the purpleCone (top of the hierarchy) without braking the hierarchy. So we would connect the spheres xFormMatrix into the input matrix of a vectorProduct node and then connect the translate output of the cube into the first input vector of the vectorProduct node. Switch the vectorProduct node's operation into Point Matrix Product. The output is the translation of the cube as if it were under the cone. (t:-1.6. -5.6. 1.1)

Notice how the the rotations of the sphere are taken into account translation because we use matrices, without having to worry about rotation orders.

If you have an object buried under a hierarchy of multiple objects and you need to move up multiple levels, you can feed the output translate from the vector product into another vector product and attach the xFormMatrix of the next-object-up-in-the-hierarchy into the matrix input in the new vectorProduct node. This way you can walk up the hierarchy as you wish. On the other hand if you want to know the objects translation in world space you can do this easily by using the parent objects worldMatrix instead of the xFormMatrix and this will give you the world translation straight away.

You can also reverse the process and find out translation of an object upwards in the hierarchy, so for example finding out object’s, which is in the root of the scene (world space), translation under another object which is under multiple objects. In order to do this you need to connect the queried object’s translation into the input1 of the vector product node and connect the object’s worldInverseMatrix, under which you want to virtually move the queried objects translation space to, into the matrix input of the vector product node. The output will be the queried object’s translations as if it would be under the specified object which matrix you plugged into the vector product.

In our example scene we could query the greenToruse's translation, which are currently in worldspace as it is not part of the hierarchy in which the other belong to, under the orangeSphere, which already under the purpleCone. Connect the the orange Sphere's worldInverseMatrix into the vectroProduct node's matrix input slot in the connection editor. Then connect the greenToruses translation into the vectorProduct's input1 slot. Make sure the vector product operation is Point Matrix Product. The output is the translation of the torus as if it were under the sphere (t:-1.6. -1.1. -5.1).

I hope this will be usefull for some of you =)

Note about maya matrix maths:
Maya has a few matrix math nodes that are hidden. The can be created with createNode command in the script editor and found then in the outliner if you show all the scene nodes (un-check show only dag nodes).

These nodes include:
pointMatrixMult
multMatrix
fourByfourMatrix
passMatrix
addMatrix
holdMatrix


sunnuntai 16. syyskuuta 2012

Adjustment layers and groups in Photoshop


This has been a bit of a revelation for me, some of you might have known about this all along, but this option has eluded my knowledge for ages...yes, you can use adjustment layer in Photoshop for groups, not just for individual layers or the whole document.

I have been complaining, with my work colleagues, about the lack of ability to confine adjustment layer effects to a group, so that you could effect multiple layers with one adjustment layer and yet not the whole document underneath the adjustment layer (nor having to copy an adjustment layer multiple times and the connect them individually to desired layers). You can connect a adjustment layer to a single layer by having the adjustment layer above the desired layer and then alt+LMB inbetween the two layers in the layers tab. If you have multiple layers under a group and then add an adjustment layer above the group and try the same trick, nothing will happen.

Just placing the adjustment layer inside the group (on the top) will give you exactly the same result as it being outside on the top of the group and it will effect the layer underneath the group as well. This is because groups' layer blending mode is by default "Pass Through" which means that the group has no effect on the visual style of the document, but it is only a organizational element in the layers tab. If you switch the blending mode of the group to "normal" instead of "Pass Through" the group effectively becomes a single layer with a blending option of "normal"(essentially the same visual effect as merging the group and leaving on "normal" blending mode). What this means is that the elements inside the group get composite together first and only afterwards layered on top of the rest of the document and this is the way to confine adjustment layers to a group.

So, by putting an adjustment layer inside a group and switching the groups blending mode from "Pass Through" to "Normal" you can have the adjustment layer to effect only layers underneath it inside the group and not the layers outside the group, even if they are underneath the group.

This helps to keep the document clean and easy to manage, you no longer have to duplicate multiple adjustment layers in order to keep the workflow undestuctive.

lauantai 12. maaliskuuta 2011

Rigging with Jason Schleifer

So I got a new job (yey =D) as a 3D generalist at Golden sq post, so Im a happy man, but I haven't really had any time to draw anything for my self, so no image update this week (nor last week it seems =P). I have been doing some rigging this week and I came across this wonderful tutorial called Animator Friendly Rigging by Jason Schleifer, a man who has worked on e.g. the Lord of the Rings. In this tutorial he goes through the principles of rigging and creates a complex production ready rig in Maya, but these principles of course are the same for any rig regardless of the software. The tutorial is around 10h long and comes with a 1500 page manual, so you can imagine that it is very detailed.

Here is a small example how he creates the base of a stretchy ik arm system with Maya. This follows closely his tutorial and all the credit goes to Jason for the principles and ideas, the only difference is that instead of mel expressions to control the stretchiness I have created connections in the hypergraph to do this (this should make the calculations faster, even thought the way he does it is not heavy in the first place).

1.First create 3 joint joint chain (best done in the side of front view) so that you will end up with something that looks like upper arm and forearm with a slight bend in the middle. You can name the joints up_arm, low_arm and hand. I have snapped the first joint in the side view to the grid position x=0 y=8 z=0 and the second randomly slightly to the left and lover around x=0 y=4 z=1 and the last joint to the centre of the world x=0 y=0 z=0.

2.Next create an ik system for the arm, by clicking Skeleton> IK Handle Tool and then by selecting your first join (up_arm) and then your last joint (hand).

3.Now you should have base for a normal working ik hand. Now create a locator and parent the ik handle to the locator, by first selecting the handle and then the locator and pressing [p]. You can rename the locator arm_loc and you should now be able to control the ik movement of the arm with this locator.

4.Now to the stretchy part. Maya evaluates the length of a bone by the distance of the joints child joint. In other words you can see the length of your upper_arm from the translate x value of your low_arm joint and we can also control the length of the upper arm by the translate x value of the low_arm joint. Same goes of course for the fore arm and the position of the hand joint

Just to make clear, even though maya displays bones between the joint balls, these balls are the actual joints. Easily demonstrated if you create a 2 joint joint-chain and then unparent the child by selecting it and pressing [shift+p], now you are left with 2 joints but no bone between them, so the bones are an extension of the joint and a visual representation of the joint hierarchy and these do effect the skinning of the character of course, but are not the joints them selves.

In order to know when to start the stretching of the arm we need to know the length of the whole arm which is of course the combined length of the upper arm and the fore arm. We can find these out from the child nodes of the upper arm’s and fore arm’s translation x values.
the length of the up_arm (upper arm) is the translation x value of low_arm and
the length of the low_arm (fore arm) is the translation x value of hand.
The arm needs to start to strech when the arm is completely straight witch means that the length after witch the arm needs to start to strech is the combined length of upper and lower arm ( low_arm.tx + hand.tx)

5. In order to know that we have reached the completely straight arm position we need to create something that measures the distance between the up_arm and the hand joint and when this value has reached the combined length of upper arm and fore arm we know that the hand is straight. We can do this by selecting Create > measure tool > distance tool. Now click on two places on the grid to create 2 locators and you can see that they are connected with a vector  and a value that displays the distance between the two locators. Now parent the first locator to arm_loc and then parent your up_arm(and of course the joint hierarchy with it) to the second locator. We do not want to parent the second locator to the up_arm because we are to control the length of the joint with the distance between the locators and this would be then affected by the up_arm and therefore it would create a loop. Now in my scene I get a value of 8 for the distance between the up_arm and hand when the hand is in its current slightly bend position.

6. In this example I will say that the translation x value of the low_arm is 4.3 and hand 4.5 so the full length of the arm is 8.8. If you want to know the exact values of your low_arm.tx you can type getAttr low_arm.tx to your Script editor and you will get a six decimal value for the translation value. We can now start to create the connections in the hypergraph. Now some people like to script things, but as I am more of a visual person I like to do things in the hypergraph rather than with mel if possible. So instead of doing Jason’s scripted set Driven Key system I have opted for mathematical graph system to do the same operations. Select your joints and your distanceDimensionShape (not just distanceDimension, but the actual shape node of it) and select input and output connections in the hypergraph.

So what we need to do is start to move the translate x values of the child joints to scale the joints as we move the arm locator, but we do not want to scale the joint smaller than their current value or other vice they will not bend at all but simply retain their current shape but get smaller. We also do not simply want to scale them up at their current position, so that the hand would not get straight ever. So we want the scaling only to happen when the arm is fully stretched to its maximum length, completely straight, but not before. We can do this by limiting the scale range with a clamp node to effect the arm only when the distance of the measure toll get bigger than the original length of the arm. You can get the clamp node from Rendering>create render node…and by selecting utilities and clamp. We can now make the following connections in order to create a system that outputs the translate x values to the joints.

We connect the measure tool’s distance to clamp node’s input R . We want to make the min value on the clamp 8.8 which is the full length of the arm so that the arm does not scale after the distance between the upper arm and hand goes below this value. We do not really want to put any limit on the scaling so we can connect the distance node to the max value so that as it gets larger so does the max limit, but what happens if the distance gets smaller? Our min is 8.8, but our max would be less than this (and the max value would over ride the min) so we need to make sure that the max value never gets smaller than 8.8 and we can do this by adding 8.8 (the full length of the arm when not stretched) between the distance node and the clamp max value. Now the clamp always outputs values between 8.8 and infinity.

Next we want to divide this value by the full length of the arm in its original form, so by 8.8. We do this with multiplyDivide node and connect the output of the clamp noted to the input1 x value of this node and in the input2 x value we type 8.8. Remember to change the operation from multiply to divide. Now we get values between 1 and infinity. These values are scale values, so that if the out put is 2 the translate x value(the length of the bone) should be twice as big. But in order to connect these values to the translate x value we need to multiply them with the original joint length for each joint as they have different lengths. We can do this with multiplyDivide nodes as well.

Create 2 more multiplyDivide nodes, one for each joint. Now connect the output value from the previous division operation to the input1 x value of both of these nodes. Next type the original length values (child joint translate x values) to the input2 x values of these nodes. In my example scene the values are 4.3 and 4.5 so one node has 4.3 and the other 4.5 in the input2.x. Now all you need to do is connect the multiplyDivide nodes to the corresponding joints translate x values. So in my case the node that had the multiply value of 4.3 to the low_arm.tx value and the one with value 4.5 to hand.tx.

Here are the actual connections (the hypergraph shows other nodes as well, but I have not mentioned them here as they are not relevant to the operation):

distanceDimensionShape1.distance->clamp1.inputR

distanceDimensionShape1.distance->addDoubleLinear1.input1
addDoubleLinear1.input1->clamp1.maxR

clamp1.inputR->multiplyDivide1.input1x
( typed in value of 8.8 -> multiplyDivide1.input2x)

multiplyDivide1.outputX->multiplyDivide2.input1x
( typed in value of 4.3-> multiplyDivide2.input2x)

multiplyDivide1.outputX->multiplyDivide3.input1x
( typed in value of 4.5-> multiplyDivide3.input2x)

multiplyDivide2.outputX->low_arm.translateX

multiplyDivide3.outputX->hand.translateX


Now if everything has gone as it should you should have an ik arm that works normally, but also stretches when the handle goes beyond the normal length value of the arm. This is great for cartoony animation or even if you just need a little bit of exaggeration for your normal character.

Jason continues the creation of the arm, hand and the whole body from here and also creates a separate fk system for each part (in fact he has 4 separate joint systems for the legs for optimal flexibility), so if you like what you have seen here I truly recommend that you will have a look at the complete Animator Friendly Rigging tutorial. Here is his website www.jasonschleifer.com.

maanantai 28. helmikuuta 2011

Punk

Here's something I did this weekend as I was asked by an employer can I create somewhat realistic digital paintings. I decided to go for an old punk. I do admire people who have skills to do realistic paintings and drawings, but I rarely spend my precious time creating just realistic looking paintings as I feel that I can just go and take photo of a similar subject in a minute which would take hours to paint. Doing these kind of portraits is good practice though and when I embark to do one of these I try to pick a subject that is not too common, such as an old punk.

sunnuntai 20. helmikuuta 2011

black lion update

I managed to refine the design today a bit. I decided to incorporate some polar bear and panther into the lion (with some fantasy element as well of course) and here is the result. Even though they are suppose to be the same animal I like the side view better as the mane is more smoky and less fire like although less mane like in general but ok in this case.

lauantai 19. helmikuuta 2011

black lion

Ok, so I haven't managed to update my blog every week, the weeks just seem to fly by. Here is a creature that I have drawn couple of weeks ago. it is not finished as I have spend more time on practicing marker drawing here than actually concentrating on the design as I got new copic markers =). I have a fairly clear idea how I want it to look, I just need to decide on the details. The creature is going to resemble a lion but I do not tend to make it look exactly like one, I want it to have a bit more of a creature quality than an actual lion. It is going to be black and it is going to have a smoke or black fire mane and maybe some rune like patterns (not like the orange lines currently on one of the faces) on its skin, well see. Anyway this is what I have for now.

sunnuntai 30. tammikuuta 2011

Birthday present

It is my girlfriend's birthday next week, but she will be visiting her parents on the actual day so I gave her my present already this week which is this picture. Her favorite animal is pig and she likes purple so this is her inner piggy in a secret forest garden.