Tuesday, January 2, 2018

The new LEGO Friends 2018!

The project I worked on last year just came out! This is a bit too girly for my taste but it turned out pretty nice (thanks to our great team at Picture This), and surprisingly, I'm so proud!

As a Rigging TD / kinda general TD
I was responsible for:
- Facial model development
   - modifying existing model making sure the girls are as pretty as possible
     (all the main girls and half a dozen of others)
- Facial rigging/blendshape/workflow devlopment
    - for all the main girls and half a dozen of others
- Rigging tools development
   - setup rigging workflow
   - blendshape tool and many others...
- Animation tools development
   - Anim picker, Dynamic chain tool, etc...
- Pipeline
   - a couple of asset pipeline tools I helped with
   - fixing, fixing, fixing, trouble shooting and...back to FIXING


We've Got Heart - Music Video

Girls on a Mission in Heartlake City - Mini Movie

Meet Olivia! Character Spot

Meet Stephanie! Character Spot

Meet Mia! Character Spot

Meet Andrea! Character Spot

Meet Emma! Character Spot

Sunday, June 11, 2017

Long time no see! Lego City is done and gone

Hi all,
I have been so caught up with work so bad that this blog has been left abandoned for a year (or 2).
I just want to update with the work I've done for Lego, the Lego City series.

I did R&D on the 2D facial rig system(from Flash created images to the 3D asset). Each part of the face (eyebrows, eyes, mouth etc.) are fully translatable, rotatable, and scalable.

Also there's a big improvement in SLR and FX. This is a big step for all of us as at Picture This Studio and it did require a huge collaboration between many people.

Here you go!

Monday, April 18, 2016

2015 Freelance work

Long time no post!
I was so lucky to be a part of these cool projects for the past year.


Phyto SC Plus Commercial(2015) - freelance
Responsibility: Rigging(Angel wings)

Smooth-E Commercial(2015) - freelance
Responsibility: Facial Rigging(Acne face)

PTT Commercial(2015) - freelance
Time: 0:05 - 0:07 (CGI bird)
Responsibility: Rigging, Technical direction

Roojai Insurance Commercial(2015) - freelance
Responsibility: Rigging(Kangkaroo)

Tuesday, August 4, 2015

Average Vertex Skin Weight 2.0 beta (Python only)

Have had some time lately to to what I wanted to do for quite some time.
While using the brush it usually screw up vertices that are modeled to be close to each other, i.e. for stylize character with hard edges or hard surface stuff.

This is an attempt to fix the problem by adding "distance between surrounding vertices" into the calculation.

 - Supports undo/redo.
 - Supports maintain max influence set on the skinCluster node.
 - Optimized (I did try, really.)
 - Big changes in calculation.
   Averaging weights will take distance between its
   surroundings into account.


Tuesday, October 7, 2014

Rearrange your geometry group for tidiness!

Haven't got much time to update lately. Been busy with work.
Still, I managed to wrote a little script when my patience was out looking at a messy geo_grp from the model department.

Just select the root geo_grp, the script will reorder all the children under it alphabetically (groups will be ordered last).

import pymel.core as pm
import maya.OpenMaya as om

def rearrangeGeoGrp(geoGrp=None):
    if not geoGrp:
            geoGrp = pm.selected(type='transform')[0]
        if not geoGrp:
            om.MGlobal.displayError('Select a geo group.')

    exit = False
    grps = [geoGrp]
    while not exit:
        nextGrps = []
        for grp in grps:
            children = grp.getChildren(type='transform')

            if not children:
                om.MGlobal.displayWarning('%s : is an empty group.' %grp.longName())

            # seperate grps and plys
            cgrps, plys = [], []
            for c in children:
                checkIfPly = False
                    shp = c.getShape(ni=True)
                    if isinstance(shp, pm.nt.Mesh):
                        checkIfPly = True

                if checkIfPly == True:

            plys = sorted(plys)
            cgrps = sorted(cgrps)

            for i, item in enumerate(plys):
                currentIndx = grp.getChildren(type='transform').index(item)
                pm.reorder(item, r=((currentIndx * -1) + i))

        if nextGrps:
            grps = nextGrps
            exit = True

Thursday, September 4, 2014

Resetting controller's transform with pymel

A tricky way to reset ctrl transform is to multiply the ctrl and the parent group matrices together and put the result to the parent then zero out ctrl transform. Whola! You got zeroed out ctrl where you put it.

import pymel.core as pm
import maya.OpenMaya as om

def resetChannelBox(obj):
cbAttr = ['tx', 'ty', 'tz', 'rx', 'ry', 'rz', 'sx', 'sy', 'sz']
for a in cbAttr:
attr = obj.attr(a)
locked = False

if attr.isLocked() == True and obj.isReferenced() == False:
locked = True
if 's' in a:
return False

if locked == True:

return True

def resetCtrlTransform(objs=[]) :
if not objs:
objs = pm.selected(type='transform')
if not objs:

for obj in objs:
offsetGrp = obj.getParent()
if not offsetGrp:
om.MGlobal.displayWarning('%s  has no parent. Continue.' %obj.nodeName())

srcMtx = obj.getMatrix()
grpMtx = offsetGrp.getMatrix()
resultMtx = srcMtx * grpMtx


if isinstance(obj, pm.nt.Joint) == True:
obj.jointOrient.set([0.0, 0.0, 0.0])


Tuesday, September 2, 2014

Average Vertex Skin Weight Brush!

    A custom brush for smoothing skin weight. It takes its surrounding vertices weights and blend it to the original weights. The result is kinda like hammer weight tool, but with brush you can paint on.

    Base on the original 'tf_smoothSkinWeight.py' by Tom Ferstl posted on createivecrash.com
I did a little modification. The brush now performs a little faster and supports undo/redo.
Please see: creative crash link

How to use  : 1.Put averageVertexSkinWeightCmd.py to your plugin path.
                         (ie. C:\Program Files\Autodesk\maya<Version>\bin\plug-ins)
                      2.Put averageVertexSkinWeightBrush.py to your python path.
                         (ie. C:\Documents and Settings\<username>\My Documents\maya\<Version>\scripts)
                      3.Execute the following python command.

import averageVertexSkinWeightBrush


Sunday, August 17, 2014

Mirror Mesh Deformer Plugin

This is my personal test project. The aim is to create a node that can mirror mesh deformation from left to right (for blendShape, maybe?). Yes, we have a bunch of scripts out there that does the job fine, but this is my personal challange to be able to have them deform together in real-time. And, yes, I just wanna practice.

I wrote this plugin in Python first because that's the only language I know (except MEL which I don't really consider a programming language). And when it comes to a LOT of vertices python kinda sucks. It lag so hard. So I spent a few weeks studying basic C++ just enough to get the plugin to be translate to C++. I found translating pretty easy since I already got all the algorithm working fine just a bit off this and that that C++ needs.


Fluid deformation on 100k+ vertices!
You can try it out for free. I just did this for fun so there'll be errors and cause unpredicted behaviour to Maya, of course. (Maya2012 64 bit only)

DOWNLOAD: mirrorMesh.mll

    -  Put mirrorMesh.mll in the Maya's plugin directory(wherever it is). Load the plugin.
    -  Select a polygon, Create the deformer. (cmds.deformer(type='mirrorMesh')
    -  Connect "outMesh" of the mesh you'd consider it the "base" to the "baseMesh" attribute on the node.
    -  Connect "outMesh" of the mesh you'd consider it the "Original" to the "origMesh" attribute on the node.
    -  Tweak(lower) the tolerance value on the node if you have a very dense mesh so the node can match vertices on each side

Have fun.

Friday, June 13, 2014

Corrective Sculpter beta

Hi, folks

    Since we all know linear skinning has been the backbone of rigging for quite some time then the fancy dual-quaternion has came out, but hasn't really play very well in practice and also setting up muscle system is quite heavy and can sometime be an overkill for such mid-end project. The only solution left was to setup driven key, or connections using joint's rotation to drive a blendShape or joint. As for elbows and knees, they're fine because they only rotate on 1 axis. But, for the shoulders and upper legs, this method will eventually FLIP at some point due to the euler angle calcualtion.

    I'd like to introduce my new tool for sculpting corrective shapes - 'Corrective Sculpter'. The tool was written in PyMel, again I'm too lazy not to use it. The idea is "when bad deformation happens, sculpt it!".

This is how it's designed to use.
- Provide the skin mesh, the buffer mesh(the blendShape target for the skin mesh)
- Select a body part to do shape correcting. In the clip is the upper-arm. Load joints.
- Pose to where the deformation looks bad, hit create target.
- Hit sculpt. Modify the shape as you like, then hit apply.

    Yeah, people have done it before, Michel Comet's PSD has a very great reputation for this kind of work. But,...I really  don't wanna have any custom node in my rig.

    Thanks to THIS TUTORIAL by Macro Giordano, I have recently learned how to set up a 'cone pose reader' using just Maya's standard nodes. The good thing is IT WILL NOT FLIP! Yeah, that's what I was looking for.

   And...thanks to Chad Vernon's cvShapeInverter link. Some part of the code in my script was taken from his code. The plugin does extract the modification from a deformed mesh. IE. You bend the arm, duplicate it, sculpt the duplicate, select original mesh select sculpted mesh, hit the script, BAM. It gives you the new mesh that can be use as front-of-chain corrective blendshape.

    That's it. Not really my work, isn't it. Just pieces of other people's work put together. Again BIG THANKS TO THOSE PEOPLE! *respect*

PS. The tool is still under development. I'm thinking of adding more functionality to it.