Copying the world_matrix of the source cam to local_matrix is fine when
you're in Nuke, but I wanted to export this as one baked camera to the
outside world. And for the chan exporter to work, I need TRS values (which
is where my other post came from about a camera round trip via chan losing
precision).

-Ean

On Sat, Feb 26, 2011 at 7:06 PM, Ivan Busquets <[email protected]>wrote:

> Someone with stronger math skills should probably confirm or refute this,
> but I think the issue is not so much scaling, but the combo of rotation +
> non-uniform scaling.
>
> Rotation + non-uniform scaling, when done in that order, are in fact
> skewing the camera. But, as I said when I originally posted it, that
> decomposition script doesn't handle skewing.
>
> To do that you would need to decompose the rotation and scale component of
> the matrix into rotation, scale, and skew.
>
> For such a case, though, it's probably easier to just copy the world_matrix
> of the source camera into the local_matrix of the dest camera. You'll loose
> the ability to easily animate or change the translation, rotation, scaling,
> etc curves, but it'll be a perfect match.
> And if you do need to make tweaks to such a camera, isn't it easier to do
> it while you still have all the separate transforms (Axis->Axis->Camera)
> anyway?
>
> Cheers,
> Ivan
>
>
> On Fri, Feb 25, 2011 at 1:15 AM, Ean Carr <[email protected]> wrote:
>
>> You're right. Scaling the camera breaks it. Will take a look at that when
>> I have a few min. Thanks Sebastian.
>>
>>
>> On Thu, Feb 24, 2011 at 2:03 PM, Sebastian Elsner 
>> <[email protected]>wrote:
>>
>>> Hey Ean,
>>>
>>> I just tested the script. Seems to work for simple setups, but I had
>>> problems with some of the more crazier ones (which I have actually seen in
>>> Production):
>>>
>>> set cut_paste_input [stack 0]
>>> version 6.1 v2
>>> push $cut_paste_input
>>> Axis2 {
>>>  translate {{curve x1 0 x10 0 x20 0.8400000334} {curve x1 0 x10
>>> 1.909999967 x20 0.9399999976} {curve x1 0 x10 -0.9549999833 x20
>>> 0.7500000596}}
>>>  rotate {{curve x1 0 x10 39.95999908 x20 -7.99200058} {curve x1 0 x10
>>> -23.64299965 x20 84.58200836} {curve x1 0 x10 0 x20 0}}
>>>  scaling {{curve x1 1 x10 0.6} {curve x1 1 x10 1.1} {curve x1 1}}
>>>  name Axis2
>>>  selected true
>>>  xpos -262
>>>  ypos -181
>>> }
>>> Axis2 {
>>>  translate {{curve x15 0 x30 3.160000086} {curve x15 0 x30 0} {curve x15
>>> 0 x30 0}}
>>>  rotate {{curve x15 0 x30 12.65400028} {curve x15 0 x30 56.61000443}
>>> {curve x15 0 x30 0}}
>>>  scaling {{curve x15 1} {curve x15 1} {curve x15 1}}
>>>  name Axis1
>>>  selected true
>>>  xpos -262
>>>  ypos -115
>>> }
>>> Camera2 {
>>>  translate {{curve x25 0.4099999964 x36 0.4099999964} {curve x25 0 x36
>>> 0.3899999857} {curve x25 0 x36 0}}
>>>  rotate {{curve x25 0 x36 -14.65200043} {curve x25 0 x36 17.31599998}
>>> {curve x25 0 x36 0}}
>>>  scaling {{curve x25 1} {curve x25 1} {curve x25 1}}
>>>  name Camera1
>>>  selected true
>>>  xpos -262
>>>  ypos -49
>>> }
>>>
>>> Maybe you want to have a look at it.
>>>
>>> cheers
>>>
>>> Sebastian
>>>
>>>
>>> On 02/24/2011 02:23 PM, Ean Carr wrote:
>>>
>>>> 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]
>>>> <mailto:[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]>
>>>>        <mailto:[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]>
>>>>        <mailto:[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]>
>>>>        <mailto:[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]>
>>>>        <mailto:[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
>>>>
>>>>
>>>>    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]
>>>> http://support.thefoundry.co.uk/cgi-bin/mailman/listinfo/nuke-python
>>>>
>>>
>>> --
>>> Sebastian Elsner - Pipeline TD - r i s e | fx
>>>
>>> t: +49 30 201 803 00 [email protected]
>>> c: +49 175 336 5739 7548 www.risefx.com
>>>
>>> r i s e | fx GmbH
>>> Schlesische Strasse 28, Aufgang B 10997 Berlin
>>> Richard-Byrd-Strasse 12, 50829 Cologne
>>> Geschaeftsfuehrer: Sven Pannicke, Robert Pinnow
>>> Handelsregister Berlin HRB 106667 B
>>>
>>> _______________________________________________
>>> 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
>>
>>
>
> _______________________________________________
> 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

Reply via email to