# Space changing

## Recommended Posts

Ok I'm in a twist with different spaces in Vex.

Imagine two spheres, one stays put ( A ), the other one moves around ( B ). The one that moves around has a rest attribute on it. All I want to do is get the world position of a point on A by reading the rest position on B. Sounds simple but it isn't. What I thought was read in the rest position for the point being shaded on B, space change it into world space and this would match the world position of the same point on A in world space. Nope.

To see what I mean take a look at the attached.

I think I know why this doesn't work, but how you do get it to work stumps me. I'm sure it's simple I just can't see it. Can anyone help.

space_change.zip

##### Share on other sites

Unfortunally I have no Houdini in front of me and I'm not 100% sure I know exactly what you want/need, but anyhow:

object B's pivot it stored in a transformation matrix B (in world space), now you only need to inverse the matrix B(inv) (I'm pretty sure houdini has an inbuilt function for this). Afterwards you only need to multiply the current point of intrested with B(inv). Do the same with A, if the position isn't on <<0,0,0>>. Now it should be easy to find the corresponding point since effectively you set pivot of B on <<0,0,0>> by multiplying with the inverse.

I assume the problem will be more complex, since otherwise you'd have solved it already ...

Jens

Written by pretty tired Jens who's spent most of the day in front of LaTeX* writing down math formulas and is in a rather confused state

*No this is no xxx-toy, but the most convinient way to write down anything that involves formulas and alike

Just realisedI more or less wrote rubbish ... anyhow Mario put everything clear. Better just ignore my post

##### Share on other sites

Hey Simon,

Welcome to the Space Club. We're all here. What took you so long!?!

OK... let me see if I can do this without fumbling the explanation -- as you know, these things appear simple until you actually sit down and try to do them...

In the following, all references to "world space" should be taken to mean VEX's world space; that is: camera space -- which I'm sure is what you meant, but I just want to make it clear.

So we have a rest position attribute that matches another object's object-space position (point-for-point). Now we want to express this attribute in terms of the world position of the reference object, as opposed to our own world position (where "us" is B, and the reference is A).

Transforming this rest attribute to our own world space is the direct equivalent to simply using P, since that's exactly what our P is. And that's no good because what we really want is to map rest to the A object's P; not to our own.

What if we used an "Space Change To Object" (SCTO) VOP instead, and transformed rest to A's space? This would give us rest's world position "from the point of view of A". If you think about it for a bit, you'll realize that this is again not what we want.

In reality, rest is A, sans the world transforms. So what we need is a way to transform from A (that is: A's world transforms -- their object-space positions already match) to B's world transforms. But the SCTO VOP only allows us to go the other way (from ourselves to A) -- what we would like then, is the inverse of what the SCTO VOP can give us..... <sigh> hope that makes some sense...

Unfortunately, SCTO doesn't give us the matrix that it uses internally. Instead, we need to use the "Get Object Transform" VOP to cough up the matrix which we then invert and use to transform rest (through multiplication). This, finally, gives us the transformation we want. :banned:

Perhaps a simpler way to think about this whole mess is this: If you want to "bring in" an object into some other object's SOPs, you use the "Object Merge" SOP, and you set the "Transform Object" to self ("."), right? Well; we're doing the same thing here (or rather, the first half of that trip): we're transforming rest (which we define as living in A's space) to ourselves (B) -- or we're viewing A with respect to us (B). (If we then further transformed this result to B's object-space, we would have the same thing that the "Object Merge" SOP does).

Spaces just absolutely destroy any attempts at putting them into words... take two aspirin and call me in the morning

Here's the modified hip: space_change_mario.zip

Cheers!

##### Share on other sites

Hi Mario,

I was kinda hoping you would be able to answer this. I was kinda getting to where you suggest in my head but by a completely different root. I was actually thinking I could calculate the same matrix to map B to A but by put P and rest into object space (even though rest is already there) and working out then a mapping between them. I don't think this will work though it was late and in my head it made sense. What you describe makes perfect sense, I knew it was fairly straight forward it just trying to picture it that was difficult. It's actually very simple as I suspected, but I wish all this was wrapped up it one big uber space changer that let you go from any space to any space without the aspirin.

Anyway thanks a million, I'll add it to my bag of tricks. Actually I've been in space change land for a bit, it's just been easier cos up til now our stuff hasn't done a lot of moving around.....

##### Share on other sites

Monumental gotcha, otransform won't return a transform matrix for a null!!

Been pulling my hair out all morning going why does this work as a test but not in my real file. Answer 'cos all your objects are parented to a null and I'm trying to use the null as the transform to map A to B etc.

##### Share on other sites

Hi Mario, have you ever had cause to test the accuracy of the otransform function? I'll try and post a hip file to show this but I'm not very happy with the results I'm getting and I can only assume it is down to the accuracy of the transform function, especially since I have a method that does the same thing using a basic offset for static models and it works fine. This is really annoying, so close yet so far.

##### Share on other sites

Hi Simon,

Monumental gotcha, otransform won't return a transform matrix for a null!!

13905[/snapback]

Yup; this has been a very unfortunate devolution. JC and I made some noise in the beta forum, but never got a satisfactory answer. The brief history of this feature is that in H5.X Nulls didn't work, then some noise was made and in H6.1 Nulls worked fine. Now in H7.0 Nulls don't work again...

And as if that weren't enough, objects used as transformation references (otransform()) must be geometry types and as of H7.0 have the additional requirement that they must also be displayed (i.e: be part of the ifd), else mantra won't see them!... very annoying, yes.

Hi Mario, have you ever had cause to test the accuracy of the otransform function?

13906[/snapback]

Mmmm..no; not really. But I'd like to hear about it if you found such a problem.

There is one thing that I just realized I forgot to mention. I'm pretty sure it doesn't apply to the example you posted, but if you're transforming some element that comes directly from Mantra/ifd (e.g: the actual P, instead of the attribute rest) to some object's space (using otransform()), then you also have to take into account that the Z-coordinate of the reference space will be reversed. This is because the Z-orientation in Houdini looks down negative Z, whereas all Mantra spaces look down positive Z.

Could this be giving you some headaches?

Cheers!

##### Share on other sites
And as if that weren't enough, objects used as transformation references (otransform()) must be geometry types and as of H7.0 have the additional requirement that they must also be displayed (i.e: be part of the ifd), else mantra won't see them!... very annoying, yes.

Thanks for the heads up on that one, saved me a few strands of hair there, I don't have much but what i do I want to keep. I'll make some noise too, for want it's worth.

Mmmm..no; not really. But I'd like to hear about it if you found such a problem.

Well having done some more work on it I don't know if it is an accuracy thing or just me expecting too much. What I'm doing is this: Having transformed the rest P into the world space of A I then fire a ray off along the also transformed rest N and look for the colour of A.

A is in my real hip file a small patch cut from B, in this way I can fake a texture map on B using a piece of geometry A.

My concerns lie in the fact that I have to move the transformed rest P back along it's normal and then ray it quite a long way passed where I expect to find a surface before the correct colour is returned. To my mind I should only have to move the rest P backwards a small amount and ray it just passed where it started in order to hit something. I'm finding however that I have to move it 16 times the length of a normal before I hit every point in A.

Now this might be because my geometry is very big and once transformed the normals are very small (I normalise the length though), or it might be that the trace function isn't very accurate ( but I use this in another similiar shader and it seems fine ) or it might be that otransform has a lot of rounding errors in it. Or as I say I'm just expecting too much. I might even still have bugs in the code, but I think this is unlikely since it is pretty much doing what I expect.

The only other possibility is this: I cut A from B using the cookie cutter sop, which triangulates everything, B however is made of quads. so perhaps when mantra interpolates restP it is returning quite different values to where the surface is when triangulated.

Lots of possibilities, but it essentially works well enough so I'm not too worried, more interested in where the truth lies.

Could this be giving you some headaches?

No it's all working fine, apart from that mentioned above

## Create an account

Register a new account