For anyone who's interested: I took Ivan's function and added support for
animated Axis / Camera nodes (it was only concatenating a single frame).
Cheers -E
def consolidateAnimatedNodeTransforms(axisNode):
# This is based on Ivan B's consolidateNodeTransforms().
# Added support for animated Axis/Camera nodes. Also, if it's
# a Camera being concatenated, then projection settings get copied.
# -Ean C 24/Feb/2011
m = nuke.math.Matrix4()
n = nuke.createNode(axisNode.Class())
n['scaling'].setExpression('curve')
n['rotate'].setExpression('curve')
n['translate'].setExpression('curve')
if axisNode.Class() == 'Camera2':
# If this is a Camera node, copy over important Projection settings.
camNode = axisNode
# Get the current values
focal_v = camNode['focal'].toScript()
haperture_v = camNode['haperture'].toScript()
vaperture_v = camNode['vaperture'].toScript()
near_v = camNode['near'].toScript()
far_v = camNode['far'].toScript()
win_translate_v = camNode['win_translate'].toScript()
win_scale_v = camNode['win_scale'].toScript()
winroll_v = camNode['winroll'].toScript()
focal_point_v = camNode['focal_point'].toScript()
# Copy them over to new Camera
n['focal'].fromScript(focal_v)
n['haperture'].fromScript(haperture_v)
n['vaperture'].fromScript(vaperture_v)
n['near'].fromScript(near_v)
n['far'].fromScript(far_v)
n['win_translate'].fromScript(win_translate_v)
n['win_scale'].fromScript(win_scale_v)
n['winroll'].fromScript(winroll_v)
n['focal_point'].fromScript(focal_point_v)
first_frame_v = nuke.root()['first_frame'].value()
last_frame_v = nuke.root()['last_frame'].value()
scale_anim = n['scaling'].animations()
rotate_anim = n['rotate'].animations()
translate_anim = n['translate'].animations()
for i in range(int(first_frame_v), int(last_frame_v+1)):
k = axisNode['world_matrix']
k_time_aware = axisNode['world_matrix'].getValueAt(i)
for y in range(k.height()):
for x in range(k.width()):
m[x+(y*k.width())] = k_time_aware[y + k.width()*x]
transM =nuke.math.Matrix4(m)
transM.translationOnly()
rotM = nuke.math.Matrix4(m)
rotM.rotationOnly()
scaleM = nuke.math.Matrix4(m)
scaleM.scaleOnly()
scale = (scaleM.xAxis().x, scaleM.yAxis().y, scaleM.zAxis().z)
rot = rotM.rotationsZXY()
rotDegrees = ( math.degrees(rot[0]), math.degrees(rot[1]),
math.degrees(rot[2]) )
trans = (transM[12], transM[13], transM[14])
for s in range(3):
scale_anim[s].setKey(i, scale[s])
rotate_anim[s].setKey(i, rotDegrees[s])
translate_anim[s].setKey(i, trans[s])
On Mon, Nov 29, 2010 at 11:33 AM, Scott Willman <[email protected]>wrote:
> Wow, Ivan, thank you! This should definately get me started :)
>
> Ivan Busquets wrote:
>
>> What he said :)
>>
>> If you just want to use that within a gizmo/group, linking to the
>> world_matrix of your input Axis/Camera should be enough to replicate all
>> concatenated transforms.
>>
>> However, if you need to get back absolute values in terms of
>> position/rotation/scale, you'll need to derive them yourself (with a little
>> help from nuke.math)
>>
>> Here's an example if you just wanted to get the final concatenated
>> position:
>>
>> ######################
>> import math
>>
>> def getAxisWPos(axisNode):
>>
>> k = axisNode['world_matrix']
>> m = nuke.math.Matrix4()
>>
>> for y in range(k.height()):
>> for x in range(k.width()):
>> m[x+(y*k.width())] = k.value(x,y)
>>
>> p = m.transform(nuke.math.Vector3(0,0,0))
>> return (p.x, p.y, p.z)
>>
>> worldPos = getAxisWPos(nuke.selectedNode())
>> ######################
>>
>> Or, if you wanted to create a new Axis/Camera node and fill it with the
>> concatenated translation, rotation and scale values, you could do something
>> like this: (please note that this should account for everything except for
>> skew transformations)
>>
>> ######################
>> def consolidateNodeTransforms(axisNode):
>>
>> k = axisNode['world_matrix']
>> m = nuke.math.Matrix4()
>>
>> nuke.selectAll()
>> nuke.invertSelection()
>> k = axisNode['world_matrix']
>> m = nuke.math.Matrix4()
>> for y in range(k.height()):
>> for x in range(k.width()):
>> m[x+(y*k.width())] = k.value(x,y)
>>
>> transM =nuke.math.Matrix4(m)
>> transM.translationOnly()
>> rotM = nuke.math.Matrix4(m)
>> rotM.rotationOnly()
>> scaleM = nuke.math.Matrix4(m)
>> scaleM.scaleOnly()
>> scale = (scaleM.xAxis().x, scaleM.yAxis().y, scaleM.zAxis().z)
>> rot = rotM.rotationsZXY()
>> trans = (transM[12], transM[13], transM[14])
>>
>> n = nuke.createNode(axisNode.Class())
>> n['scaling'].setValue(scale)
>> n['rotate'].setValue((math.degrees(rot[0]), math.degrees(rot[1]),
>> math.degrees(rot[2])))
>> n['translate'].setValue(trans)
>>
>> consolidateNodeTransforms(nuke.selectedNode())
>> ######################
>>
>>
>> Disclaimer: I just wrote those and have only done a couple of tests, so
>> there's a good chance they may break (no exceptions handled, etc), but
>> hopefully it'll get you on the right track.
>>
>> Hope that helps.
>>
>> Cheers,
>> Ivan
>>
>> On Sun, Nov 28, 2010 at 3:20 PM, Frank Rueter <[email protected]<mailto:
>> [email protected]>> wrote:
>>
>> that's what the world matrix knob is for (in 6.1)
>>
>>
>> On Nov 29, 2010, at 12:12 PM, [email protected]
>> <mailto:[email protected]> wrote:
>>
>> > I've got a camera that has an Axis node plugged in. The camera
>> also has
>> > transforms on it. Is there a way to get the resolved world-space
>> > pos/rot/scale of the camera?
>> >
>> > Thanks guys
>> >
>> >
>> >
>> >
>> > Cinesite (Europe) Ltd. Registered Office: HemelOne, Boundary
>> Way, Hemel Hempstead, Herts, HP2 7YU Registered in Cardiff No.
>> 2820389 VAT No. 630 5446 60
>> > _______________________________________________
>> > Nuke-python mailing list
>> > [email protected]
>> <mailto:[email protected]>
>>
>> > http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python
>>
>> _______________________________________________
>> Nuke-python mailing list
>> [email protected]
>> <mailto:[email protected]>
>>
>> http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python
>>
>>
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> Nuke-python mailing list
>> [email protected]
>> http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python
>>
>>
>
> Cinesite (Europe) Ltd. Registered Office: HemelOne, Boundary Way, Hemel
> Hempstead, Herts, HP2 7YU Registered in Cardiff No. 2820389 VAT No. 630 5446
> 60
> _______________________________________________
> Nuke-python mailing list
> [email protected]
> http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python
>
_______________________________________________
Nuke-python mailing list
[email protected]
http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python