Jump to content

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

## 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.

#### Share this post

##### 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

#### Share this post

##### 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...

```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.

• 1

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account

## Sign in

Already have an account? Sign in here.

Sign In Now

×
• Donations

• Leaderboard