Simple Matrix Q (Transforming Bullet Packed Primitives)

   1203   4   0
User Avatar
Member
162 posts
Joined: 9月 2017
オフライン
I have a question about transforming Bullet Packed Primitives. This is just for learning; I am able to correctly transform everything using the Transform Pieces SOP but I want to learn how to make the matrices my self and feed them into a Transform By Attributes SOP.


So, I am using the RBD Bullet Solver SOP and Output 4 (Simulation Points) gives me points with:

v@P
p@orient
v@pivot

I know there is a qconvert that takes in a quaterion and and offset and generates a 4x4 matrix. Sounds perfect! I tack a rest on the at-rest packed primitives and try the following:

4@transform = qconvert(p@orient, v@P - v@rest);

This ALMOST looks right, but the pivots look a little wonky. Which makes sense, because I didn't use the pivot at all when I built the matrix. However, I cannot for the life of me figure out how to use the pivot. I tried subtracting it form the displacement vector, adding it, rotating it and then adding it, all sorts of things. Can anybody point me in the right direction?

And more generally, is the pivot a pivot for the rotation or a pivot for the entire transformation? I think that a big part of my problem here is that I don't understand pivot enough.

Thanks!
User Avatar
Member
9432 posts
Joined: 7月 2007
オフライン
You may want to have a look at instance VEX function [www.sidefx.com] which can build transform from instancing attributes for you

Since pivot needs to be applied as an offset before rotation and qconvert does post rotation offset so it's not applicable for pivot
Tomas Slancik
CG Supervisor
Framestore, NY
User Avatar
Member
162 posts
Joined: 9月 2017
オフライン
Awesome, that was really helpful! I was trying to do it by hand, and the docs on that page helped me understand a little more. Though to be honest, I just ended up brute forcing the sequence. Since there were only three operations (P, pivot, orient) I thought there would be only 3*2*1 combinations. But apparently pivot is supposed to be an inverse transformation so there was the 3*2*1 orderings of (P, pivot, orient) plus 3*2*1 more orderings of (P, -pivot, orient).

Anyways, I ended up with this sequence, which I sort of get but wanted to ask if there were a more concise way to type:

matrix m = ident();

m *= maketransform({0, 0, 1}, {0, 1, 0}, -v@pivot);
m *= qconvert(p@orient);
m *= maketransform({0, 0, 1}, {0, 1, 0}, v@P);

4@transform = m;

My understanding is that pivot is the MOST important, so it needs to be accounted for before the rotation and transform.

Also, I was kind of a dummy and originally trying to compute the translation component of the matrix by figuring out the displacement from P_rest to the P that the Bullet Solver generated but I guess that wasn't necessary.

Anyways, is this the correct way to build the matrix? Or is there a more direct way to build the translation matricies?

Attachments:
houdini_breakfast_pivot_orient_to_transform.hiplc (341.3 KB)

User Avatar
Member
9432 posts
Joined: 7月 2007
オフライン
nicholasralabate
My understanding is that pivot is the MOST important, so it needs to be accounted for before the rotation and transform.
I wouldn't use the words most important
it simply needs to be in local space as mentioned therefore for transforms represented by row major matrices it needs to be applied before rotation and scale and translation is in world space so needs to be applied after

nicholasralabate
Anyways, is this the correct way to build the matrix? Or is there a more direct way to build the translation matricies?
it's correct, but there are other ways to build it, more convenient to translate a matrix may be translate() function

matrix m = ident();

translate( m, -v@pivot );
m *= qconvert( p@orient );
translate( m, v@P );

4@transform = m;

you can of course combine them if you want to reduce the number of lines, like:
matrix m = maketransform({0, 0, 1}, {0, 1, 0}, -v@pivot);
m *= qconvert( p@orient );
translate( m, v@P );

4@transform = m;
or
vector euler = quaterniontoeuler( p@orient, 0 );
4@transform  = maketransform( 0, 0, v@P-v@pivot, degrees( euler ), {1,1,1}, v@pivot);
or the mentioned instance():
4@transform = instance(v@P, {0,0,1}, {1,1,1}, {0,0,0,1}, p@orient, v@pivot);
Edited by tamte - 2025年2月18日 00:01:20
Tomas Slancik
CG Supervisor
Framestore, NY
User Avatar
Member
162 posts
Joined: 9月 2017
オフライン
Thanks again, this super helpful for learning purposes. I like
translate(m, offset)
the best -- it is consistent with how I write rig wrangles and the granularity of one-vex-function-per-transformation helps me build an intuition for which transformations need to happen in which order.
  • Quick Links