Friday 2 February 2024

simple rigging setups using kinefx

 

typical basic kinefx rigging for organicish shapes


simple rigid body FK rig. Key points are packing each rigid part, and using the capture packed geo node. make sure the skeleton points are at the desired pivot points.


basic setup here - line as a skeleton, isolate the FBIK controller points. the MATCH BY ATTRIBUTE setting is usually what makes things work! Also on the FBIK node, you might need to tweak the tolerance parameter.

look at constraint but only in the X or Y etc

 


There's a Look At Constraint, in the Constraints tab, however if you only want this aim to work on the X, or maybe just the Y, you have to dig into the constraint, then go to the Common Tab (see top screenshot) and then only specify the rx or ry in the scope.

Remember to use Nulls to set custom pivots etc, then parent your desired geometry to the null.

Monday 25 September 2023

resolving intersections between multiple closed objects (like cushions)

to summarise - convert to vdb, do a volume point sample. multiply the normal of the geo by the volume sample and then add back to the original position. It should push in -or out- for a packed cushiony effect.

nicely demo'd here by Emīls Geršinskis - Ješinskis
https://www.youtube.com/watch?v=2yGxLHSYf8I

Tuesday 28 March 2023

fusing geo using uv attribute (eg. separated head from neck)

Lets say you've separated the head geo from the body for rigging purposes or otherwise.
How do you glue it back together reliably, without resorting to many individual vertex pair selections and fusing each?
UV's! As long as your mesh has good non overlapping UV's (which existed before you chopped it), you can promote them from vertex to point (might as well give it a new name, and keep the originals for actual texture use) then specify this new attribute at the Match Attribute (see below). Turn off Snap Distance, as the UV data is what will snap vertices/points together (in this case I've called it fuse_uv). I've left everything else in the Fuse node as default.
This is super handy especially if your model's point count is not fixed (eg you're not sure where you're cutting the model yet)


Thursday 9 March 2023

Wednesday 8 March 2023

padzero in vex - sprintf %04d

s@name = sprintf('%04d',@primnum);
padzero doesn't work in vex, so you have to use sprintf and the `%04d` method - don't forget those little backticks

Thursday 2 March 2023

curl curves with vex

VEX code taken from this forum post, by user F1 -
Curling hair curves with VEX - General Houdini Questions - od|forum (odforce.net)

Very hand bit of code that can curl up your curves for hairstyles, bits of fluff or any other curly things you might imagine. 

If you're going to use a path deform SOP after this (eg, you're using the curves to deform a bunch of snakes) you'll want to Attribute Delete the Normal "N" attribute that this script creates. Otherwise your geo might come out a bit flat/squashed/wrong in places.


 // Primitive wrangle.

#define TWO_PI 6.2831852

addpointattrib(0, "N", {0, 0, 0});
int pts[] = primpoints(0, @primnum);
int npt = len(pts);

// Loop variables.
vector rest = point(0, "P", pts[0]);
vector prev_pos = rest;
matrix3 frame = ident();

for (int i = 0; i < npt; i++)
{
    vector pos = point(0, "P", pts[i]);
    vector delta = pos - rest;
    rest = pos;

    // Make normal. Point normals could be used instead.
    vector normal = normalize(cross(cross({0, 1, 0}, delta), delta));
    if (length(normal) == 0)
    {
        normal = {0, 0, 1};
    }

    // Drive a shape with ramps and multipliers.
    vector axis;
    float ramp, angle;

    // Twist the bend axis.
    axis = normalize(delta);
    ramp = chramp("twist_profile", (float) i / npt);
    angle = fit01(ramp, -TWO_PI, TWO_PI) * ch("twist") / (npt - 1);
    rotate(frame, angle, axis);

    // Bend the curve.
    axis = normalize(cross(normal, delta));
    ramp = chramp("bend_profile", (float) i / npt);
    angle = fit01(ramp, -TWO_PI, TWO_PI) * ch("bend") / (npt - 1);
    rotate(frame, angle, axis);

    // Compute new position and normal.
    vector new_pos = delta * frame + prev_pos;
    prev_pos = new_pos;
    setpointattrib(0, "P", pts[i], new_pos);
    setpointattrib(0, "N", pts[i], normal * frame);
}




// Primitive wrangle.

int pts[] = primpoints(0, @primnum);

vector rest = point(0, "P", pts[0]);
vector prev_pos = rest;
matrix3 frame = ident();

for (int i = 0; i < len(pts); i++)
{
    vector pos = point(0, "P", pts[i]);
    rotate(frame, 0.1, {0, 0, 1});
    vector new_pos = (pos - rest) * frame + prev_pos;
    rest = pos;
    prev_pos = new_pos;
    setpointattrib(0, "P", pts[i], new_pos);
}