Sunday, June 17, 2012

Creature WIP
   This is part of the manticore rig for a new show piece I'm working on, it should be properly animated and include Houdini effects. I've been working on this for a while now, I daresay the rigging is almost finished. All I need to do is to add effects on this creature ( model courtesy of Emmanuel Guevarra. )

   The way I rigged this wing is to first rig a single feather. It only needs three joints. Save this maya scene as featherA.ma, then import this file any number of times, better yet, reference it.

   Using a new maya scene and having a curve, this is the curve that all the feathers are going to be imported/ referenced on. use pointOnCurveInfo node to get the position of the curve, make sure to turn on percentage. We know that the parametric value of the curve is from 0 to 1,  so turn on the percentage in the node.
using a loop based on the number of feathers being imported, using a percentage calculation, we can determine each position on a curve:

numberOfFeathers= 27
for index in range( numberOfFeathers ):
   Length= 1.0

   number= ( Length/ numberOfFeathers * index )
   normalizedNumber= ( number/ Length )

  normalizedNumber returns the value that you need to plug into a pointOnCurveInfo parametric value, each number is unique by how many feathers you import/ reference. You can use this for a nice, even distribution of values and can be used for other methods.

  Finally, you can bind the curve to roughly 6 joints. The advantage to this is that you can rebuild any number of feathers without changing the number of wing joints.

  Rotations matter, so use the tangentConstraint on the imported feathers'  control groups. Duplicate your curve and raise it above your original curve and bind it to your wing joint. Build the locators along the curve to match the number of feathers using the percentage math. Have those locators be the objectUp for every tangentConstraint you have and Voila, you have a very stable wing rig.


Monday, June 4, 2012

HOUDINI


   I've started on a Houdini CG Workshop by Spencer Lueders, he is a great teacher by the way. 
This animation is my version of object's influenced velocity tutorial from spencer's class. The ball is animated in Houdini and I emit the particles only when it touches the ground. The particles then get influenced by the velocity of the object, plus the bouncy collision of the ground. I think it turned out rather well. I'm hoping to learn more of the Houdini particleFX. 

Thursday, May 31, 2012


New CreatureTD reel!

It's been a long, long time since the last time I've touched the google blogging tool. What can I say? I had no will and energy to take care of it.  I had a job, a life to live and so many distractions! My job at Rainmaker was over and in three days I was ready to travel Europe with my long-time girlfriend for almost two months.
Oh, that was the best two month vacation I ever had! After I came back I was ready to hit the ground running on working on my new demo-reel. Sadly, I didn't have much material to work from, so I had to choose the things I already had. I've uploaded a new demo reel that has a new footage of the short-film, shortened version of my old demo-reel and a python demonstration of useful utility such as controller construction.

Tuesday, January 3, 2012

Getting a vector from two objects.

import maya.OpenMaya as om
import maya.cmds as cmds

# I named both my objects in maya scene 'tgt' and 'src' repsectively. tgtObj= 'tgt'
aimObj = 'src'

# definition for a worldSpacePosition matrix.
def getWorldPos( object ):
# utils needed to be imported for converting from a list to a matrix product.
util = om.MScriptUtil()

xform = cmds.xform( object, ws=1, m=1, q=1 )
# the 16 is the length of numbers in list. Specifically, a Matrix.
util.createFromList( xform, 16 )


return om.MMatrix( util.asFloat4Ptr() )

# get the worldSpacePosition of both objects.
aimM = getWorldPos( aimObj )

tgtM = getWorldPos( tgtObj )

# gets a pointMatrix product.
aimOrig = om.MPoint(0.0,0.0,0.0)
tgtOrig = om.MPoint(0.0,0.0,0.0)


aimOrig *= getWorldPos( aimObj )
tgtOrig *= getWorldPos( tgtObj )


#v = aimOrig * aimM.transpose()
#print v.x, v.y, v.z

print aimOrig.x, aimOrig.y, aimOrig.z
v = aimOrig - tgtOrig
print v.x, v.y, v.z

Thursday, December 29, 2011

Maya os.environ() for windows


In a way, os.environ is similar to setting a list: sys.append( 'D:/data/folder' ). Except that it is a list from a constant environment variable from the operating system instead of writing each data path. Though they do seem to be similar in practice but the os.eviron seem to have more flexible functionality: you can call each folder as a module you can access to. Let's say you have 3 files inside the D:/Data/Path/File system path: "Modules", "Systems" and "Utilities". And inside each of those folders are more files and python files, in this case, in file "Systems" I have a file called “Addons” and a python file called "utility" and I can access that file, and all other files without writing too much code.

For example:
In windows, you can set your environment variable by right-clicking My Computer > Properties > Advanced System Settings > Environment Variables. Click on New. You will get this window:
Variable Name:
Variable Value:

Set it to something like this:
Variable Name: MODULAR_PATH
Variable Value: D:\Data\Path\File
The variable value is your file path, just make sure to invert the slashes from " / " to " \ ."

Now that you have set your environment variable, you can go back to maya and type something like this:
import os
import maya.OpenMaya as om
import sys

try:
    rootPath= os.environ[' MODULAR_PATH ']
except:
    om.MGlobal.displayWarning( ' MODULAR_PATH  is not in environment.' )
    sys.exit()

else:
    import sys
    #print rootPath
    if not  rootPath in sys.path:
        sys.path.append(  rootPath )

    print 'Systems path appended -- >', sys.path

    import Systems.Addon.utility as util
    reload( util )
    util.run()

    import Modules.testPyCode as tpc
    reload( tpc )
    tpc.runAll()

    import Utilities.__init__A as init
    reload(init)
    init.initialize()

And so on and so forth. I believe this way is a much cleaner way to handle modules than by appending each directory to a list. My opinion.

P.S.
When I write python code, I always do 4 spaces for intentation.

Wednesday, March 30, 2011

maya node: closestPointOnMesh.

 A fairly useful node for several purposes:

Let's say you want joints to slide across a surface -- like an eye for eylids. Or a body for a belt.
Or you can use it for modeling purposes where you want to snap a vertex to another surface of the mesh.
Let's talk about that for a second, down below I wrote a python script.

I will follow through every step of the code I've outlined below.

What this code does, is that it uses the two locators that it creates; 'start' is used to snap on the "Source" mesh vertex, and the 'end' locator glides along the "Target" mesh's surface. Giving away the location of the surface so that the vertex could snap on.

So you can select hundreds of vertices and snap those vertices onto another mesh. Think projection mapping. Same idea.
I apologize if some of the things I cover is 'same old', I cover it anyway for those who don't know.

"""
vertexCopy script:
Snaps a vertex onto the same vertex location as another mesh's vertex.
"""

#This part allows you to access maya commands in python language.
import maya.cmds as cmds

#The print command is very useful to remind you of things from time to time.
#Such as whether a piece of code in the next line ran or not.
print " Please select the vertices of the base mesh first before running this script. "
print " nameOfMeshA= SOURCE."


#def is a statement that you use to create function objects in python.
#Goes by def nameanything( variable ):
#The variable is what you're going to call further along inside this function statement.
def createConnections( nameOfMeshA ):
    
     #Remember the import command? Now you call the 'cmds.' module whenever you use maya commands.
     Start= cmds.spaceLocator( name= 'start' )
     End= cmds.spaceLocator( name= 'end' )

     #Each created nodes ( any object you create in the scene is a node. ) I made are stored in variables.
     #In this case, I used CPOM to store the closestPoint node. I did it so I can use this later on in the script.
     CPOM= cmds.createNode( 'closestPointOnMesh', name = 'geo_cpom' )

     #Here is how I use my stored CPOM variable. It returns the name of the node I created.
     #I use the '+' signs to combine a string and variable together.   
     #What follows after are the connections from node to node.
     cmds.connectAttr( Start + '.center', CPOM + '.inPosition' )
     cmds.connectAttr( nameOfMeshA + '.worldMatrix[0]', CPOM + '.inputMatrix' )
     cmds.connectAttr( nameOfMeshA + '.outMesh', CPOM + '.inMesh' )
     cmds.connectAttr( CPOM + '.position', End + '.translate' )

#Now I create a new function statement. It is important to note that the variable you made previously
#cannot be used in a new function statement in this way:
def snapIt( start, end ):

     #The variable stores your selected vertices by the ls command.
     #ls returns the names of objects in your scene that you specify. In this case, the selection of vertices.      selection= cmds.ls( selection= True, flatten= True )

     #len counts the total number of objects you have selected by the ls command.
     length= len( selection )

     #for and range commands tells python that for ' i ' it gets counted from 0 and onwards.
     #In this scenario, if you select 7 vertices, it will count from 0 to 7.
     for i in range( length ):

        #xform maya command is very, very useful for querying and inputting values on a transform node.
        #more on the node can be found in the technical documentation of maya help, commandsPython section.
        positionA= cmds.xform( selection[i], worldSpace=True, translation=True, query=True )

        #the selection then snaps 'end' locator to the selected vertices.
        cmds.xform( start, worldSpace=True, translation= positionA )
       
        #Gets the space location of the ' end ' locator.
        positionB= cmds.xform( end, worldSpace=True, translation=True, query=True )

        #And those values get plugged into individual selected vertices.
        cmds.xform( selection[i], worldSpace=True, translation= positionB )
    
     print ""
     print 'All vertices has been snapped.'


"""
And there you have it. I hope you have learned something! =D

"""

Sunday, February 13, 2011

The anatomy of an Award Winning rigging reel.

         I cannot express my excitement at my new job due to my timid nature, so I've set up a blog to talk about it!  firstly, before I can dive into concise details of how I got my first, ever, job. I have to show pictures! Everybody likes looking at a picture before reading something!


       During the start of my last semester of school, I despaired that I wasn't going to graduate and that earning a job during the economic downturn at the time is going to be next to impossible for a recent graduate. So in two weeks, I had to brush out my rigging skills and plan out the following two and a half months. I knew it had to be simple and up to the point. I had to find that extra 'it' on my demoreel that makes people say, "I want this guy". Though, at the time, I didn't know what to do. I had to find people, and find them fast.

        I found three people who were graduates of the Art Institute and all of them are professional riggers. One of them I already knew, Denis, then I was introduced to Nathan, and finally Chris. Nathan was particularly helpful in demonstrating how a four-sided blendshape controller works. Using the Gmail chat, he was also particularly helpful in giving me pointers on what might and might not work in a rigging reel. I was introduced to Chris much later as someone recommended him. He helped me in the scripting side of things, specifically with Python. Denis was really, really busy but he recommended that I read two very specific books: Advanced Character Rigging Techniques and Facial Rigging by Jason Osipa.

       Nathan, Chris and Denis could only help me so much. I had to pull my own weight. I had to finish my rigging. I had to ask lots of questions to my teachers, and I also personally modeled two models in the prior months which I fully intended to use. I had a Character and a Face which were the two most important things recruiters are looking for in a junior rigging reel.

     Not only that I had to finish my rigging, I also had to professionally prepare myself for the world. I knew that getting a job right off from school is very rare, so I had to quit playing games. I had to read books. I had to excel and to be noticed.

      I decided that all demo reels need to have an excellent presentation, especially for a junior reel like mine, I had to make it look good. I threw coloured shaders to every surface. I colourized the curves to make them distinguishable from left and right. I added a really simple environment composition for my character but of course, it wasn't enough. My rigs needed to be animated. They had to show that they were useful and that every controller needs to show a useful function. That's where my other friends and teachers at school came in. They were animators and producers and critics all rolled into one and they were happy to give me pointers on what I needed for the animation, music, timing and feel. One thing I also decided to do is to add consistency. My business card, my presentation and logo was to be the consistent, so I created a simple puppet with strings and red pivot points.

    Of course, I'm guilty of being of a somewhat of a perfectionist, and that I had a little more time, with that comes in "www.videocopilot.net/" which was that little bit of cherry-on-the-top. With it, I made introduction and the switch from the character to my face more visually attractive. I decided to introduce what each rigging scene had and also a title. 

    Finally, a complete contrast to what I was feeling during the start of the quarter, I was absolutely glad to have my reel to be presented as the "Best of Show" for the 3D Modeling for Animation and Games program: