Well, most (all?) of the cameras I deal with don't have skew (or non-uniform
scale) so this isn't really a problem for me.

I did try fbx and it keeps all the precision. However it doesn't keep the
hierarchy of transformations; it just gives me each one as a different,
un-linked, node name. That makes me wonder: is it a reasonable to expect
that WriteGeo would export the hierarchical transformation properly to FBX?
I think so.

-E

On Sun, Feb 27, 2011 at 8:16 PM, Ivan Busquets <[email protected]>wrote:

> Hmm, I see.
> But if you have a skew transformation matrix, you you won't be able to fit
> that into TRS values. You'll need skew as well, or at least another set of
> rotations (rotation-scale-rotation-translation).
>
> On top of that, if you want to open that in a different app, it's likely
> that the the camera model will not match Nuke's camera model. Like, Maya's
> shear and Nuke's skew don't correlate. You would need to rebuild the Maya
> camera parameters with Maya's model in mind. That's why I think that, for
> those cases, it's easier to just keep the hierarchy of transformations and
> export that to your app of choice. I think there's a much better chance to
> rebuild a matching camera that way.
>
> As for the loss of precision when exporting .chan files, have you tried
> exporting an fbx instead? Can't check right now, but I believe exporting to
> fbx should keep the double-precision of your knob values.
>
> Cheers,
> Ivan
>
>
> On Sun, Feb 27, 2011 at 4:50 AM, Ean Carr <[email protected]> wrote:
>
>> 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
>>
>>
>
> _______________________________________________
> 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