nmn Posted December 5, 2009 Share Posted December 5, 2009 (edited) Hi, is there any way in houdini i can do a world space rotation ?!! in Maya it was very simple to do! using the rotate function rotate -r -ws $x 0 0; and specifying -ws for world space. after a lot of tests i wasn't able to achieve such a thing in houdini, the only way i know of to rotate in world space is to use the rotate handle and align it to the world, but since i need to do that dynamically ... well that couldn't be a solution in my case. an example would be : ---------------------------- i use for example a transform node to rotate an object i wan't to change the rotation values with python script i want' those rotations to occur around the world axis so whenever i change rx it always rotates around the same x axis in world space and be independant from the previous rotations that occured i hope i was clear enough, and that someone could shed some light on this subject coz i would be really surprised if MEL can do it and houdini couldn't :S:S Cheers Edited December 5, 2009 by nmn Quote Link to comment Share on other sites More sharing options...
edward Posted December 6, 2009 Share Posted December 6, 2009 - Grab the worldTransform() of the node you want to rotate - Multiply it by the corresponding result of buildRotate() - Call setWorldTransform() on the object with your rotated result Quote Link to comment Share on other sites More sharing options...
nmn Posted December 6, 2009 Author Share Posted December 6, 2009 (edited) Thanks for your answer Edward, is that applicable on any kind of node ? ( at least the ones that have transformation parameters) because whenever i try to do it on a transform nodei get this error : AttributeError: 'SopNode' object has no attribute 'worldTransform' :S is that normal ? if not , is there a solution to that ? or am i obliged to use it only on a geometry node ? besides whenever i do : xform = hou_myNode.worldTransform() rot = hou.hmath.buildRotate(90, 0, 0) res = xform * rotation hou_myNode.setWorldTransform(res) i get my object translated ... with the rotation does this transformation always rotate around the origin ? is there a workaround for that, or the only solution would be by using the hou.hmath.buildRotateAboutAxis method (even though i don't see how yet )? and what if we need quaternion rotations ? Cheers Edited December 6, 2009 by nmn Quote Link to comment Share on other sites More sharing options...
edward Posted December 6, 2009 Share Posted December 6, 2009 Thanks for your answer Edward, is that applicable on any kind of node ? ( at least the ones that have transformation parameters) No, it is only applicable to Object nodes. because whenever i try to do it on a transform nodei get this error :AttributeError: 'SopNode' object has no attribute 'worldTransform' :S is that normal ? if not , is there a solution to that ? or am i obliged to use it only on a geometry node ? SOP Nodes do not contain transforms, they only contain the already transformed geometry. When you're using a Transform SOP, it is directly transforming the point positions. It doesn't maintain a separate transform. xform = hou_myNode.worldTransform() rot = hou.hmath.buildRotate(90, 0, 0) res = xform * rotation hou_myNode.setWorldTransform(res) i get my object translated ... with the rotation does this transformation always rotate around the origin ? But that is what rotating "in world space" means. If you want to rotate around its local pivot, then you will have add in some translation transforms that move it to the world origin before rotating, and then moving it back. and what if we need quaternion rotations ? Use hou.Quaternion. Quote Link to comment Share on other sites More sharing options...
nmn Posted December 6, 2009 Author Share Posted December 6, 2009 (edited) Thanks for all the infos Edward that was very helpful now i have a working beta ... though i still have some questions and issues 1- i wasn't able to get the world space translates of my objects, unless i parented a null to each one of them (putting it in the center) and used xform = hou_myNull.worldTransform() X = xform.at(3,0) Y = xform.at(3,1) Z = xform.at(3,2) not sure if this is the best way to go, it works though... what do you think ( i should mention also that the pivot of my objects is not at the center, where i put the nulls, because i need it like this for the rotations) 2- my rotations are working correctly when using this form xform = hou_myNode.worldTransform() rot = hou.hmath.buildRotate(90, 0, 0) res = xform * rotation hou_myNode.setWorldTransform(res) but the problem is that whenever i try to key the rotation values... all i can see in the rotation fields is zero (after i put a key) though when i run my script the rotations occur , i see them in the viewport but the values stay at zero in the rotation fields :S if i don't put any keys in there, i can see the rotation calues normally whenver i run my script any explanation for that? could it be that i can only do it with a code like that hou_keyframe = hou.Keyframe() hou_keyframe.setTime(0) hou_keyframe.setValue(90) specifying explicitly the value ? what if i don't specify the time let us say, won't it take the current time by default ? 3- for the quaternion rotations, i should transform my ratations to quaternions and then key ? or how should i do that ? Thanks Edited December 7, 2009 by nmn Quote Link to comment Share on other sites More sharing options...
anim Posted December 6, 2009 Share Posted December 6, 2009 can you explain more clearly what are you trying to do? do you want to modify the rotation values on transform SOP so that it will rotate certain degrees along certain global axis? do you want your python script to be realtime or just executed once the user press a button or something? do you need to rotate it in geometry level (transform SOP) or it is intended to be used in rigging so the object level transform is prefered? maybe a description of the purpose of this rotation thing would help, because it is too abstract for me to imagine exactly what you need for quaternion rotation it makes no sense to rotate as quaternion then save key, unless your curves are not interpolated as quaternions (houdini support only qlinear() quaternion interpolation function at this time) but if it is easier for you to set pose with quaternions please ignore previous line Quote Link to comment Share on other sites More sharing options...
nmn Posted December 6, 2009 Author Share Posted December 6, 2009 Hi anim and thanks for your reply. do you want to modify the rotation values on transform SOP so that it will rotate certain degrees along certain global axis? at the beginning that was my purpose but i wasn't able to do it until now, so i moved on and now i'm doing it on object level using edward's suggestion, it's working, but if there is a solution on SOP level I'm also interested to know how. do you want your python script to be realtime or just executed once the user press a button or something? the user will click a rotate button, and when he's satisfied with the rotation, he will click another button to set keys for that rotation. do you need to rotate it in geometry level (transform SOP) or it is intended to be used in rigging so the object level transform is prefered? i have no preference, as i said above i tried doing it with a transform SOP i couldn't so now i'm using object level, but i\m interested to know if it's doable with a transform SOP maybe a description of the purpose of this rotation thing would help, because it is too abstract for me to imagine exactly what you need not allowed to give details ... sorry about that the main thing is that we have multiple objects that can rotate, with a button click, after they rotate we set a key then we do another rotation on another group of those objects then key ... etc for quaternion rotation it makes no sense to rotate as quaternion then save key, unless your curves are not interpolated as quaternions (houdini support only qlinear() quaternion interpolation function at this time)but if it is easier for you to set pose with quaternions please ignore previous line the problem with euler rotations is when your object have to do many rotations around many axes (with keys set for each rotation) and your rotations go beyond 360 degrees ... etc you will begin getting odd behaviours especially with interpolations, in fact i did the same project in Maya and i solved this problem by just setting the keys using euler rotations then transforming my animation curves to quaternions, but now i need to do that in houdini i hope that can help you diagnose, if you could ask me more specific questions i would be glad to answer ... any explanation about quaternions in houdini would be good (like what's qlinear ... etc). Thanks again Cheers Quote Link to comment Share on other sites More sharing options...
anim Posted December 6, 2009 Share Posted December 6, 2009 (edited) i have no preference, as i said above i tried doing it with a transform SOP i couldn't so now i'm using object level, but i\m interested to know if it's doable with a transform SOP you should have, if you want to do it in SOPs, you better have reason for it, because it can complicate things later a lot (or simplify if there is a reason) one more question to SOPs: is the object level transform allways the same? preferably T 0,0,0 R 0,0,0 S 1,1,1 a: if so, do you want all the transforms to be done in transform SOP? b: if not, are you translating/scaling the object at object level and only the rotations are done in SOPs? (maybe to keep the SOP pivot to 0,0,0 or to only pose and scale it and animate only the rotation) c: if not, are you rotating on both levels? i guess you want a), but please tell me (or maybe you want something else) then we can do some math to make it work the problem with euler rotations is when your object have to do many rotations around many axes (with keys set for each rotation) and your rotations go beyond 360 degrees ... etc you will begin getting odd behaviours especially with interpolations yes, i know that, but what i was telling you was, that no matter what you use to set the rotation up (eulers or quaternions), the interpolation of the animation curves is by default behaving as eulers so it will mess up the way as eulers if you want it to behave like quaternions, you need to use qlinear() interpolation function instead of bezier(), or any other, and you have to use it on all rotation channels rx, ry, rz but qlinear() only interpolates linearly between keyframes, no TCB controls or anything Edited December 6, 2009 by anim Quote Link to comment Share on other sites More sharing options...
anim Posted December 6, 2009 Share Posted December 6, 2009 here is quick code for python function that will rotate transform SOP in world space no matter what the object level transforms are it should work for a, b and c situation i mentioned above def rotateSOP(xformSOP, rotate = (0,10,0)): obj = xformSOP.parent() rotParm = xformSOP.parmTuple("r") lRot = rotParm.eval() wTrn = obj.worldTransform() iwTrn = wTrn.inverted() wRot = hou.hmath.buildRotate(lRot)*wTrn wRot *= hou.hmath.buildRotate(rotate) lRot = wRot*iwTrn rotParm.setPending(lRot.extractRotates()) (there is more code than for object level solution since it needs to compensate for object level transforms, because it's in SOPs so you are editing underlaying geometry) it is built to work in default modes (transform_order='srt', rotate_order='xyz') it can be easily done to work for all cases, but i wanted to make it simple since it is only an example Quote Link to comment Share on other sites More sharing options...
nmn Posted December 6, 2009 Author Share Posted December 6, 2009 (edited) OH! i should have thought of that ! taking into my xform SOP the transform of its parent ! thanks for that tip ! nice one i won't use it for this project now coz i got it working with object level but it sure will be usefull in the future my project is almost done i solved most of the issues i still have only one bugging me at the moment whenever i set a key it stops taking into account my new rotation values UNLESS i do an extract pre transform after each click on the rotate button though i don't know the command to do that in python i tried this preTrans = hou_myNode.preTransform() hou_myNode.setParmTransform(preTrans) but this makes my rotation be applied twice ! any ideas ? Thanks edit : now i also discovered that my tool works the way it should if i turn on the option 'Edit > Preferences > Objects and Geometry > Read-Only Pre-transforms.' but i don't want the user to change his houdini settings just for my tool this might help with the diagnosis ... Ah and thanks for the qlinear tip it solved my rotations issue Edited December 6, 2009 by nmn Quote Link to comment Share on other sites More sharing options...
anim Posted December 6, 2009 Share Posted December 6, 2009 (edited) i do not know what the problem might be i am able to set the key after using swtWorldTransform() and it is working with new values, autokey is working too but to extract transform you can do this obj.parm("pre_xform").set(4) # since option 4 is Extract Pre-Transform obj.parm("pre_xform").pressButton() # to apply the option you set Edited December 6, 2009 by anim 1 Quote Link to comment Share on other sites More sharing options...
nmn Posted December 7, 2009 Author Share Posted December 7, 2009 but to extract transform you can do this obj.parm("pre_xform").set(4) # since option 4 is Extract Pre-Transform obj.parm("pre_xform").pressButton() # to apply the option you set i don't know what the problem is either but those two lines solved the problem !! really appreciated , you helped me a lot with this project, thanks very much Regards Quote Link to comment Share on other sites More sharing options...
edward Posted December 7, 2009 Share Posted December 7, 2009 but to extract transform you can do this Or, you can just use hou.ObjNode.movePreTransformIntoParmTransform(). Quote Link to comment Share on other sites More sharing options...
edward Posted December 7, 2009 Share Posted December 7, 2009 i wasn't able to get the world space translates of my objects, unless i parented a null to each one of them (putting it in the center) I don't see why you couldn't have just called hou.Matrix4.extractTranslates(). 1 Quote Link to comment Share on other sites More sharing options...
nmn Posted December 7, 2009 Author Share Posted December 7, 2009 I don't see why you couldn't have just called hou.Matrix4.extractTranslates(). Maybe it could've worked if the pivots were in the centers of the objects, but since the pivots are offset (i need that for my rotations) i didn't give me the values to the center of my objects ( i could've inetgrated the offset values in the equation maybe, but ... i went the NULLs way and it worked) is that logical or am i missing something here? Or, you can just use hou.ObjNode.movePreTransformIntoParmTransform(). are you saying this is the same thing as doing : obj.parm("pre_xform").set(4) # since option 4 is Extract Pre-Transform obj.parm("pre_xform").pressButton() # to apply the option you set i have two other a little bit unrelated questions: 1 - is there a way i can hide everything inside a digital asset ? meaning the users won't be able to see the nodes inside nor the code ... etc ? 2 - is there a way we can set keyframes on nodes inside the digital asset (with spare buttons on it) without the user being obliged to 'allow editing' ? 2' - what about this question if we did '1' ? Thanks Quote Link to comment Share on other sites More sharing options...
nmn Posted December 7, 2009 Author Share Posted December 7, 2009 LoL sorry my mistake I didn't this reply before, since you did 2 successive replys I saw only the last one ... you should have, if you want to do it in SOPs, you better have reason for it, because it can complicate things later a lot (or simplify if there is a reason) can you please explain to me a little what are the advantages and disadvantages of each ? especially that you are saying 'complicate' ... 'or simplify' lol is the object level transform always the same? preferably T 0,0,0 R 0,0,0 S 1,1,1 a: if so, do you want all the transforms to be done in transform SOP? b: if not, are you translating/scaling the object at object level and only the rotations are done in SOPs? (maybe to keep the SOP pivot to 0,0,0 or to only pose and scale it and animate only the rotation) c: if not, are you rotating on both levels? i guess you want a), but please tell me (or maybe you want something else) then we can do some math to make it work assuming we're doing it in SOPs, the transform nodes in SOPs will have only their rotations modified and the object level node (containing the different transform SOPs) can have its rotations, translations and scale modified so i guess 'b' would be the closest now that i'm doing it in object level, instead of having multiple SOP chains - each with its transform node - merged together, i have an object node for each chain and instead of doing the rotation on the a transform SOP i'm doing it on the object node itself, and all those object nodes are put inside a subnet which will have rotation scale and translation. if you want it to behave like quaternions, you need to use qlinear() interpolation function instead of bezier(), or any other, and you have to use it on all rotation channels rx, ry, rz but qlinear() only interpolates linearly between keyframes, no TCB controls or anything yes that's what i did, and i think for the moment it serves the purpose well, since i don't need TCB ot anything other than linear for now ... even if i needed in some particular cases i can still add more keys to draw some animation curve of my own ... Cheers Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.