Jump to content

rbds to follow point positions *and* orientations *SOLVED*


bbbaaarrr

Recommended Posts

Hi,

I need to animate a group of packed RBD prims scattered on animated set of points. The points are scattered on animated deforming geometry. They derive of course @P as well as @orient based on surface normal and tangent vectors.

Now I want to simulate RBDs that would try to follow those positions and orientations closely, but retain their dynamic properties as well (so they collide properly).

So far I managed to achieve reliable position following based on http://www.tokeru.com/cgwiki/index.php?title=HoudiniDops#RBD_follow_targets but now I'd like to set the torque accordingly.

My way of thinking is that I should somehow calculate the torque based  rbd @orient with original input point @orient (analogously to how I calculated the position delta), but anything I do produces just rotational chaos...

Anyone with C4D background should see here that MoGraph's dynamic rotation following is what I'm after...

Cheers,
B.

Link to comment
Share on other sites

Hey!
this is something I'm interested in as well. I think if you check the GuidedRBDBulletSolver example files the answer should be burried in this setup, but I haven't had the time to dig deeper.

I think this is the relevant wrangle (/obj/guidedrbdbulletsolver_example1/animated_guide_simulation/rbdbulletsolver4/dopnet/guide_geometry):

int dotQuat(vector4 q1; vector4 q2){
    int dotQ = (q1.w*q2.w+q1.x*q2.x+q1.y*q2.y+q1.z*q2.z) < 0;
    return dotQ;
}

// Unguide pieces with no guided neighbours
int useneighbours = point(0, "__guide_useneighbours", @ptnum);
int guide_count = point(0, "__guide_neighbourcount", @ptnum);
if (chi("useneighbours") && guide_count && useneighbours)
{
    int ns[] = point(0, "__guide_neighbours", @ptnum);
    int newns[];
    foreach(int n; ns)
    {
        int guided = inpointgroup(0, "__guided", n);
        if (guided) append(newns, n);
    }
    setpointattrib(0, "__guide_neighbours", @ptnum, newns);
    int num = len(newns);
    if (num < min(guide_count, chi("minneighbours")))
    {
        i@group___guided = 0;
        return;
    }
}

int pt = findattribval(1, "point", "name", s@__guide_name, 0);
if(pt >= 0)
{
    vector restpos = primintrinsic(0, "pivot", @primnum) + v@__guide_pivot_offset;
    
    int pr1 = pointprims(1, pt)[0];
    vector restpos1 = primintrinsic(1, "pivot", pr1);
    vector pos1 = point(1, "P", pt); 
    vector offset = restpos - restpos1; 
    
    matrix3 xform1 = primintrinsic(1, "transform", pr1);
    vector pos = pos1 + offset * xform1;

    float timeMult = 1.0/@TimeInc; 
    timeMult *= 1.0/chf("timescale");
    
    matrix3 xform = primintrinsic(0, "transform", @primnum);
    rotate(xform, v@__guide_rot_offset, 0);
    
    vector4 quat = quaternion(xform);
    vector4 quat1 = quaternion(xform1);
    
    int reverse = dotQuat(quat1, quat) ? -1 : 1;
    quat *= reverse;
    
    if(i@active && s@__guide_name!="")
    {
        float bias = ch("bias");
        if (haspointattrib(0, "__guide_blend"))
            bias *= clamp(float(point(0, "__guide_blend", @ptnum)), 0, 1);
        v@w = lerp(v@w, qconvert(qmultiply(quat1, qinvert(quat))) * timeMult, bias);
        v@v = lerp(v@v, (pos - @P) * timeMult,  bias);
        int hasAdiff = haspointattrib(0, "__guide_angleDiff");
        int hasLdiff = haspointattrib(0, "__guide_linearDiff");
        if(hasAdiff && hasLdiff)
        {
            setpointattrib(0, "__guide_prP", @ptnum, pos, "set");
            setpointattrib(0, "__guide_prQ", @ptnum, quat1, "set");
        }
    }
} else {
    i@group___guided = 0;
}

 

Edited by Drughi
Link to comment
Share on other sites

Hey Johannes,

There you go...

First thing to remember is to set proper piece transform attributes before the sim. It messes them up otherwise...

Per http://www.tokeru.com/cgwiki/index.php?title=HoudiniDops#RBD_extract_correct_transform_attributes

matrix m4 = primintrinsic(0,'packedfulltransform',@ptnum);
matrix3 m3 = matrix3(m4);
@orient = quaternion(m3);
@scale = cracktransform(0,0,2,0,m4);
v@pivot = primintrinsic(0,'pivot',@ptnum);

Put the above to a wrangle before the dop.

Then inside the DOPnet put the following to a geometry wrangle:

int dotQuat( vector4 q1; vector4 q2 ) {
    int dotQ = (q1.w*q2.w+q1.x*q2.x+q1.y*q2.y+q1.z*q2.z) < 0;
    return dotQ;
}

vector4 q = @orient;
vector4 q1 = point( 1, "orient", @ptnum );

int reverse = dotQuat(q1, q) ? -1 : 1;
q *= reverse;

v@w = qconvert(qmultiply(q1, qinvert(q)));

As you can see the above is directly pasted from the example code.

That's only for the rotation part. The @P part is trivial as setting @P or @v directly...

Thanks!!!

B.

  • Like 1
Link to comment
Share on other sites

  • bbbaaarrr changed the title to rbds to follow point positions *and* orientations *SOLVED*

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...