Hi,
I merged 3 geos and gave them a specific v@myCustomPivot. My plan was to use this attribute to pack them with a pivot of my choosing but the Pack sop only has 2 options: Origin and Centroid. How can I pack with my custom pivot vector?
Custom Pivot for Packing? {[SOLVED]}
2136 3 1-
- olivierth
- Member
- 1143 posts
- Joined: 4月 2017
- オフライン
-
- olivierth
- Member
- 1143 posts
- Joined: 4月 2017
- オフライン
Ok, I found a solution. In my for-each-loop, I move the points with my v@myCustomPivot vector, I pack (with origin option) and finally, I move it back to its original position.
My first wrangle is:
my second wrangle is:
My first wrangle is:
int ptprims[] = pointprims(0, @ptnum); //myCustomPivot is stored on prims vector myCustomPivot = prim(0, "myCustomPivot", ptprims[0]); @P -= myCustomPivot; setdetailattrib(0, "myCustomPivot", myCustomPivot, "set");
my second wrangle is:
vector myCustomPivot = detail(1, "myCustomPivot", 0); @P += myCustomPivot;
Edited by olivierth - 2023年9月11日 08:58:46
-
- arkaen
- Member
- 14 posts
- Joined: 7月 2023
- オンライン
I know this is old, but wanted to put some more information here because this is a high-ranked search result for "packed pivot" questions ... since the geometry's location is being represented by a single point, you can of course do simple vector math on them with point wrangles, like you did here by adding an offset to the packed geo's point position.
However, there is actually a silent intrinsic attribute that controls the pivot of packed geometry. You can manipulate it like this:
NOTE:
If you comment out the line to set the point position, the geometry will snap to the pivot point instead of vice-versa ... this might be desirable in certain situations, but you usually want to re-pivot the geometry around a custom point without it moving so you can transform it from there. Since packed geometry is treated like a point, you can even fill in the "Pivot Translate" fields of a transform node with something like... can even go as far as lining up the pivot rotation by reading values from other nodes or measuring/calculating it in some way. I made my own micro-HDA called "set_packed_pivot" where you can modify it instantly from a custom attribute or point input and it comes in handy now and again.
However, there is actually a silent intrinsic attribute that controls the pivot of packed geometry. You can manipulate it like this:
vector pos = set( x, y, z ) ; int geo = 0, ptnum = i@ptnum ; setpointattrib( geo, "P", ptnum, pos ) ; setprimintrinsic( geo, "pivot", ptnum, pos ) ;
NOTE:
If you comment out the line to set the point position, the geometry will snap to the pivot point instead of vice-versa ... this might be desirable in certain situations, but you usually want to re-pivot the geometry around a custom point without it moving so you can transform it from there. Since packed geometry is treated like a point, you can even fill in the "Pivot Translate" fields of a transform node with something like
point(0, "P", 0)
"Make it exist ..."
-
- toadstorm
- Member
- 402 posts
- Joined: 4月 2017
- オフライン
There's no need to adjust pivots of packed primitives in a for/each loop... VEX is inherently a loop over all prims within the group mask, so you can make this kind of adjustment with a single wrangle.
Pivots are defined in the local space of the packed transform, so there's a bit of math to set them up if you want to define a new pivot in world space AND make sure the primitive itself doesn't move when you do this.
You can also do this easily with MOPs Pivot [github.com].
Transforming the prim after the fact would ideally be done by manipulating P and the transform intrinsic rather than using expressions to drive a Transform SOP. For example to rotate the prim with the new pivot 90 degrees around X:
Or use MOPs Transform [github.com].
Pivots are defined in the local space of the packed transform, so there's a bit of math to set them up if you want to define a new pivot in world space AND make sure the primitive itself doesn't move when you do this.
// define old and new pivots vector old_pivot = primintrinsic(0, "pivot", @ptnum); vector new_pivot = chv("pivot"); // get rotation and scale matrix from prim matrix3 xform = matrix3(getpackedtransform(0, @ptnum)); // get the pivot in world space vector world_pivot = @P - (xform * old_pivot); // compute difference between current and new pivot in world space vector offset = new_pivot - world_pivot; // move this pivot difference into the local space of the prim new_pivot = offset * invert(xform); // move P and set the new pivot @P = new_pivot; setprimintrinsic(0, "pivot", @ptnum, new_pivot);
You can also do this easily with MOPs Pivot [github.com].
Transforming the prim after the fact would ideally be done by manipulating P and the transform intrinsic rather than using expressions to drive a Transform SOP. For example to rotate the prim with the new pivot 90 degrees around X:
// define rotation axis and angle vector axis = {1,0,0}; float angle = radians(90); // get the transform matrix matrix3 xform = primintrinsic(0, "transform", @ptnum); // rotate the transform rotate(xform, angle, axis); // bind the new transform back to the primitive intrinsic setprimintrinsic(0, "transform", @ptnum, xform);
Or use MOPs Transform [github.com].
Edited by toadstorm - 2025年7月30日 13:59:32
MOPs (Motion Operators for Houdini): http://www.motionoperators.com [www.motionoperators.com]
-
- Quick Links