Wednesday, July 30, 2008

Ghost (plug-in demo)

I made a demo for the plug-in. (The actor is me ;)

Click to see the movie


First I customized texPPattrMapperNode so that it takes camera world matrix, wrote a per particle expression, and made something like this. Particles which background are whiter move faster.

Then I made this in Shake, by ...difference from bg image...blur...contrast...brabrabra.

I connected Maya and Shake with this


Sunday, July 27, 2008

Integrating Maya and Shake

In Houdini 3D and 2D composite features are packed in one software but most 3D software has no composite functionalities. I think it is not natural, it hasn't become a big problem but there is no reason they cannot be in one package. Having them in the same place will be good not only for smooth image data transfer but mixing 2D and 3D functionalities to generate one image (composite an image, send it to 3D to build a 3D object which has the shape similar to what's on the image, render it in 3D, composite it with other images, pass it to 3D again to make the image as a source of particle, ... ). Though not as good as Houdini, I thought if I could integrate these two softwares with my Maya and Shake, and I made an experimental system.

(Click to see a movie)

Internally It is implemented on a generic Shake node which behavior is determined by Python scripts. It is similar to PythonNode in pyshake but higher abstraction level and less generic.

Manual and reference.


Friday, July 25, 2008

Python Inheritance

This grid shows how methods (and any attributes) are inherited.

This is a simplified chart and technically it's not quite correct, where lines go from left to right should not be called inheritance.

Back to Python implementation, when a method gets called from an instance, it's __get__ is called and it returns a bound method.

>>> class A(object):
... def __init__(self, name):
... = name
... def printName(self):
... print
>>> a = A('Koichi')
>>> boundmethod = A.printName.__get__(a)
>>> boundmethod
<bound method ?.printName of <__main__.A object at 0x69bf0>>
>>> boundmethod()

This is equivalent to this.

>>> boundmethod = a.printName
>>> boundmethod
<bound method A.printName of <__main__.A object at 0x69bf0>>
>>> boundmethod()

Thursday, July 24, 2008

World point to point on image (Maya Python)

Python version of mapping function from point on world space to point on 2d image.

Just a memo so that you dont't have to reinvent the wheel.

import maya.OpenMaya as OpenMaya

def floatMMatrixToMMatrix_(fm):
mat = OpenMaya.MMatrix()
OpenMaya.MScriptUtil.createMatrixFromList ([
fm(0,0),fm(0, 1),fm(0, 2),fm(0, 3),
fm(1,0),fm(1, 1),fm(1, 2),fm(1, 3),
fm(2,0),fm(2, 1),fm(2, 2),fm(2, 3),
fm(3,0),fm(3, 1),fm(3, 2),fm(3, 3)], mat)
return mat

def WorldPositionToImageCoordinate(cameraName, imageXRes, imageYRes, worldX, worldY, worldZ):
p = OpenMaya.MPoint(worldX, worldY, worldZ)
sl = OpenMaya.MSelectionList()
sl.getDagPath(0, dpathCameraShape)
fnc = OpenMaya.MFnCamera(dpathCameraShape.node())
mmatProjection = floatMMatrixToMMatrix_(fnc.projectionMatrix())
mmatInvCamera = dpathCameraShape.inclusiveMatrix().inverse();
projected = p * mmatInvCamera * mmatProjection
imageX = (projected.x/projected.w / 2.0 + 0.5) * imageXRes
imageY = (projected.y/projected.w / 2.0 + 0.5) * imageYRes
return imageX, imageY

#print WorldPositionToImageCoordinate('persp', 720, 486, -0.543, 3.926, 7.532)

Sunday, July 20, 2008


MEulerRotation::decompose() seems to be buggy.

import math
import maya.OpenMaya as OpenMaya

def _getScaleMMatrix(sx, sy, sz, space = OpenMaya.MSpace.kTransform):
ar = OpenMaya.MScriptUtil()
ar.createFromDouble(sx, sy, sz)
trns = OpenMaya.MTransformationMatrix()
trns.setScale(ar.asDoublePtr(), space)
return trns.asMatrix()

def _getRotationMMatrix(rx, ry, rz):
ar = OpenMaya.MScriptUtil()
ar.createFromDouble(rx, ry, rz)
trns = OpenMaya.MTransformationMatrix()
trns.setRotation(ar.asDoublePtr(), OpenMaya.MTransformationMatrix.kXYZ, OpenMaya.MSpace.kTransform)
return trns.asMatrix()

mmat = OpenMaya.MMatrix()
mmat *= _getScaleMMatrix(1.0, 10.0, 1.0)
mmat *= _getRotationMMatrix(math.radians(30), math.radians(80), math.radians(0))
euler = OpenMaya.MEulerRotation.decompose(mmat, OpenMaya.MEulerRotation.kXZY)

print math.degrees(euler.x), math.degrees(euler.y), math.degrees(euler.z)

It prints 3.30430518016 80.0 0.0, not 30.0, 80.0, 0.0 or equivalent.

Saturday, July 12, 2008

Mpemba Effect

Did you know...

If you need to make some ice quickly, you can do it by putting hot water to a freezer.

I tried it but in my test environment (freezer and ice tray :) I couldn't reproduce it.

July 31th added