Wednesday, April 11, 2012

Ira Glass on Persistence

This quotation has more than made the rounds by now, but I find it encouraging and a regular point of reflection, so I'm sharing it:
“Nobody tells this to people who are beginners, I wish someone told me. All of us who do creative work, we get into it because we have good taste. But there is this gap. For the first couple years you make stuff, it’s just not that good. It’s trying to be good, it has potential, but it’s not. But your taste, the thing that got you into the game, is still killer. And your taste is why your work disappoints you. A lot of people never get past this phase, they quit. Most people I know who do interesting, creative work went through years of this. We know our work doesn’t have this special thing that we want it to have. We all go through this. And if you are just starting out or you are still in this phase, you gotta know its normal and the most important thing you can do is do a lot of work. Put yourself on a deadline so that every week you will finish one story. It is only by going through a volume of work that you will close that gap, and your work will be as good as your ambitions. And I took longer to figure out how to do this than anyone I’ve ever met. It’s gonna take awhile. It’s normal to take awhile. You’ve just gotta fight your way through.”  --Ira Glass of This American Life
Keep fighting, even if you're a pacifist.

Friday, April 6, 2012

Plugin Development Guidelines for a Seamless User Experience


I've been evaluating a lot of utility plugins for Cinema 4D, based on my experiences, here are a few suggestions on creating a better user-experience. In no particular order:
  • As much as possible, make your tool fit seamlessly into your user's existing workflow.
  • Follow the visual conventions of the application:
  • Make your icons looks as much like native icons as possible. No-one likes the bolt-on appearance of most plugin icons.
  • Gray out your icon if your tool isn't appropriate to a given mode.
  • Ensure that your plugin is undo friendly.
  • Choose a simple descriptive name, it should feel like just another command.
  • Write a mouse-over help string, include any useful key-commands
  • It's better to make simpler discreet tools that don't require user-interaction than one giant tool with a million options.
  • Fully document your tool: written docs, video tutorials, and multiple example files.

Friday, March 23, 2012

Real World Lighting Tips from Nick Campbell

Nick Campbell gave a great talk on lighting.


Here are my takeaways:

  • Fuzzy shadows indicate small scale
  • Sharp shadows indicate large scale
  • Mimic the real-world as much as possible in terms of light placement and size
  • Play with different color temperatures for your lights - pure-white light rarely happens in the real world.
  • GI leads to more realistic lighting behavior

Friday, February 17, 2012

C4D Python Matrix Basics & Helper Functions

I seem to forget the basics of working with matrices in C4D immediately after I use them. Here are some resources and helper functions:

Maxon's How to Use Matrices
C4D Python SDK Matrix Reference

Some PSR helper functions written by Maxon with additions for point manipulation by me
############## HIERARCHY HELPERS ######################
def GetGlobalPosition(obj):
    """
    Returns the global position of obj
    """
    return obj.GetMg().off
 
def GetGlobalRotation(obj):
    """
    Returns the global rotation of obj
    """
    return utils.MatrixToHPB(obj.GetMg())
 
def GetGlobalScale(obj):
    """
    Returns the global scale of obj
    """
    m = obj.GetMg()
    return c4d.Vector(  m.v1.GetLength(),
                        m.v2.GetLength(),
                        m.v3.GetLength())
 
def SetGlobalPosition(obj, pos):
    """
    Sets the global position of obj to pos
    """
    m = obj.GetMg()
    m.off = pos
    obj.SetMg(m)
 
def SetGlobalRotation(obj, rot):
    """
    Sets the global rotation of obj to rot
    Please remember, CINEMA 4D handles rotation in radians.
 
    Example for H=10, P=20, B=30:
 
    import c4d
    from c4d import utils
    #...
    hpb = c4d.Vector(utils.Rad(10), utils.Rad(20), utils.Rad(30))
    SetGlobalRotation(obj, hpb) #object's rotation is 10, 20, 30
    """
    m = obj.GetMg()
    pos = m.off
    scale = c4d.Vector( m.v1.GetLength(),
                        m.v2.GetLength(),
                        m.v3.GetLength())
 
    m = utils.HPBToMatrix(rot)
 
    m.off = pos
    m.v1 = m.v1.GetNormalized() * scale.x
    m.v2 = m.v2.GetNormalized() * scale.y
    m.v3 = m.v3.GetNormalized() * scale.z
 
    obj.SetMg(m)
 
def SetGlobalScale(obj, scale):
    """
    Sets the global scale of obj to scale
    """
    m = obj.GetMg()
 
    m.v1 = m.v1.GetNormalized() * scale.x
    m.v2 = m.v2.GetNormalized() * scale.y
    m.v3 = m.v3.GetNormalized() * scale.z
 
    obj.SetMg(m)

def LocalToGlobal(obj, local_pos):
    """
    Returns a point in local coordinate in global space.
    """
    obj_mg = obj.GetMg()
    return obj_mg * local_pos

def GlobalToLocal(obj, global_pos):
    """
    Returns a point in global coordinate in local space.
    """
    obj_mg = obj.GetMg()
    return ~obj_mg * global_pos

def SetPointGlobal(point_object, point_index, global_pos):
    """
    Sets the global position of point_object's point to global_pos
    """
    p_local_pos = GlobalToLocal(point_object, global_pos)

    #Set Point
    point_object.SetPoint(point_index, p_local_pos)

    #Tell C4D the spline has changed.
    point_object.Message(c4d.MSG_UPDATE)
    #Move this line to the end of your loop if you're call this command a lot.

def SetPointGlobalVirtual(point_object, parent, point_index, global_pos):
    """
    Sets the global position of a virtual point_object's point to global_pos
    Most useful when setting the points of a spline created in a Python Generator
""" p_local_pos = GlobalToLocal(parent, global_pos) #Set Point point_object.SetPoint(point_index, p_local_pos)

    #Tell C4D the spline has changed.
    point_object.Message(c4d.MSG_UPDATE) #Move this line to the end of your loop if you're call this command a lot.
def GetPointGlobal(point_object, point_index):
    """
    Return the position of a point in Global Space
    """
    ppos = point_object.GetPoint(point_index) #Get the point in local coords
    return LocalToGlobal(point_object, ppos) #Return the point in global space

#######################################################

Thursday, December 15, 2011

Guiding Thoughts for Subdivision Surface Modeling


  1. Volume, form, detail. Always in that order.
  2. Before adding another point/edge/poly, ensure that those that are already there are correctly placed.
  3. The vast majority of your time will be spent tweaking points.
  4. Don't get stuck working on your model from one angle, use your 4-way view and rotate around.
  5. Edge flows should follow the contours of your object.
  6. Trace edge flows onto real objects to get a sense of how to approach them.
  7. Use the bare minimum level of detail you can get away with to accomplish your task.
  8. Add detail by cutting in loops; localized detail tends to get messy.
  9. Quads, quads, quads.
  10. All previous thoughts should be discarded if they do not serve your aim.

How HipHop Dancing Can Make You A Better Teacher

With most subjects I'm a pretty quick study, especially if I have an opportunity to ask clarifying questions. Which is why dance classes are always an eye-opening experience for me; they force me to occupy the role of frustrated student.

I am not a natural dancer, I am naturally enthusiastic, but that's about all I have working in my favor. It took me 5+ years of near weekly dance classes to discover "the beat" and its integral role in dance.

Last night I took a hip hop dance class at my gym. I was unquestionably the worst out of 30+ people. Yet somehow, I managed to smile my way through.

Some thoughts on what worked and didn't work in the class:

Worked:
  • After learning new steps we would go back to top and review that. By the end of the class those first 4 moves had been reinforced to the point that I could probably still do them now.
  • The instructor had a great enthusiasm for his work, and it was infectious. This, more than anything, is what kept a grin on my face.
  • The skills being taught were of particularly high interest.
  • I was allowed to quietly fail without comment or criticism.
Didn't Work (For Me):
  • At one point the class was broken down into performance groups by gender. That totally killed the safety for me. Random assignment is way better.
  • The pacing of the class was far too quick (for me, almost everyone else was keeping up fine)
  • The rate of instruction increased as the instructor felt pressed for time.
  • Repeatedly saying "Now I know this is a lot...".
Takeaways / Ideas for My Teaching Practice:
  • Let people walk away with mastery of at least one skill: For each lesson, pick 1-3 skills that will be reinforced throughout the lesson. Explicitly state what they are, break them down, give a rationale, the whole shebang.
  • If you set an ambitious goal, where failure is a risk, allow people the space to fail privately. Don't single people out for congratulations or criticism - this helps to generate intrinsic value for the learning.
  • Some classes are not for all people, and that's okay. I nearly walked out many times due to frustration, it was entirely a battle with myself and had nothing to do with the instructor.
  • Find a way to make your material exciting to *you* but don't let your excitement detract you from your primary goal: ensuring your students learn.
  • Don't say "Now I know this is a lot...". Instead say: "We will be covering a lot of material. My goal is for you to learn X, everything else is gravy."
Thoughts that were helpful to me as a learner:
  • This is your first attempt at this, of course you aren't amazing.
  • Your peers have been at this (if not hip hop, perhaps jazz, etc) much longer than you.
  • Even if you suck, you better keep a grin on your face, because the only sadder than a bad dancer is a bad dancer beating himself up.
I managed to take some of these lessons into my private training work, with good results. Here are my takeaways from that:

  • Always, always, always make time for skills integration. People much prefer walking away with one thing they can use over 50 things that really impressed them but they have no idea how to approach on their own.
  • Examples with wow-factor are great, but only if they demonstrate good habits. Otherwise they're a trick and manipulation used to make YOU the teacher feel better.
  • You must constantly evaluate your teaching practice and adapt to the needs of your students.
I'm sure there are more, but those are the biggies.

Friday, December 9, 2011

U.S. CG Feature Film Animation Studios

Over the next few months I'll be posting the results of research towards my goal of making a living by telling touching stories through the medium of CG Animation. I now present, a list of the U.S. studios that have put out an CG animated feature film, and are likely to do so again in the future. This is no doubt a partial list, and I invite you to add your own contributions to this post's comments.