How to get an obj's world pos in a nice expression-friendly way (say for driving a particle source from a null)?

   5905   8   4
User Avatar
Member
146 posts
Joined: Sept. 2011
Offline
If you want a Particle Source to follow a Null, you can just stick
ch("/obj/MY_NULL/tx")
(etc) into the Position boxes.

But that'll only work if the Null itself is animated/translated. If it's parented to something else, you'll just get
{0,0,0}
out. So how do I get the Null object's position in world space? I've found optransform(), but it doesn't seem very stuff-it-in-a-parameter-as-an-expression-friendly, if you get me.

(And whenever you're controlling something's location/rotation with expressions, you always end up with three separate copies of your expression as Vectors are always broken out into separate axes in the UI, when often it would be easier to be able to just use a Vector. Is there any way to have Houdini kinda munge translation or rotation parameters into a nice single expression-friendly Vector type box?)
User Avatar
Member
402 posts
Joined: June 2014
Offline
Hi howiem,

Have you checked out the RMB menu on a parameter? Try going to Reference->Scene Data and then in the selection dialog find your target obj and look under Transforms->World. This will populate the parameter with a bunch of expressions (that you probably wouldn't want to type by hand )
Edited by friedasparagus - Jan. 23, 2018 12:31:17
Henry Dean
User Avatar
Member
146 posts
Joined: Sept. 2011
Offline
Oh my goodness. That's wonderful. Thanks a million

And no, I wouldn't have liked to type this by hand (let alone copy and paste and tweak for Y and Z):

{

matrix src_xform = optransform("../MY_NULL");
matrix target_xform_inverted = invert(optransform(opinputpath(".", 0)));
matrix final_xform = src_xform * target_xform_inverted; 


matrix rest_xform = identity(4);
matrix self_xform = rest_xform * final_xform;

float result = explodematrixpr(
        self_xform, 
        vector3(ch("./px"), ch("./py"), ch("./pz")),
        vector3(ch("./prx"), ch("./pry"), ch("./prz")),
        chs("./xOrd"), chs("./rOrd"), "TX");
return result;

}

Crikey - I didn't know you could stuff that much code in one of those tiny little boxes either
User Avatar
Member
7737 posts
Joined: Sept. 2011
Offline
Why not create a constraint? No funky cryptic expressions, just nodes.
User Avatar
Member
402 posts
Joined: June 2014
Offline
Oh, if it was going to an obj node's transforms, constraints totally the way to go.

I was thinking that we were looking at sticking an objects world space translate into a vector parm buried in a dopnet or some such… In which case you could possibly export the t channels from a Get World Space chop node, but the reference->scene data was fewer clicks
Henry Dean
User Avatar
Member
146 posts
Joined: Sept. 2011
Offline
… and right now less clicks = more likely to get home on time. But I promise to learn the constraint approach. Thanks!
User Avatar
Member
101 posts
Joined: May 2006
Offline
This….. Just changed my life.
Many thanks!


friedasparagus
Hi howiem,

Have you checked out the RMB menu on a parameter? Try going to Reference->Scene Data and then in the selection dialog find your target obj and look under Transforms->World. This will populate the parameter with a bunch of expressions (that you probably wouldn't want to type by hand )
User Avatar
Member
75 posts
Joined: Feb. 2017
Offline
friedasparagus
Hi howiem,

Have you checked out the RMB menu on a parameter? Try going to Reference->Scene Data and then in the selection dialog find your target obj and look under Transforms->World. This will populate the parameter with a bunch of expressions (that you probably wouldn't want to type by hand )

This is the greatest thing in the world. Thank you so much!
User Avatar
Member
192 posts
Joined: April 2015
Offline
howiem
And no, I wouldn't have liked to type this by hand (let alone copy and paste and tweak for Y and Z):

{

matrix src_xform = optransform(“../MY_NULL”);
matrix target_xform_inverted = invert(optransform(opinputpath(“.”, 0)));
matrix final_xform = src_xform * target_xform_inverted;


matrix rest_xform = identity(4);
matrix self_xform = rest_xform * final_xform;

float result = explodematrixpr(
self_xform,
vector3(ch(“./px”), ch(“./py”), ch(“./pz”)),
vector3(ch(“./prx”), ch(“./pry”), ch(“./prz”)),
chs(“./xOrd”), chs(“./rOrd”), “TX”);
return result;

}



Why all this code when it could just be done with the origin() vtorigin() vrorigin() expression functions?
  • Quick Links