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
