Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Animating rod rest position
#1
Hi, i want to animate the rod rest position in order to animate a rod as a creature. Is this feasable? If so, what, variables do i need to edit?
Reply
#2
(02-05-2021, 02:47 PM)Hakazaba Wrote: Hi, i want to animate the rod rest position in order to animate a rod as a creature. Is this feasable? If so, what, variables do i need to edit?

Hi,

To do this you need to iterate trough all bend/twist constraint batches in the rod and change each constraint's rest Darboux vector. (see:https://en.wikipedia.org/wiki/Darboux_vector). These are per-constraint angular velocities stored as quaternions that determine the material frame's bending/torsion, it's quite advanced stuff so let me know if you need further help.

Also, this paper (included in Obi's webpage references section) contains good information about Cosserat theory and Darboux vectors:
https://animation.rwth-aachen.de/media/p...t-Rods.pdf


See the "Per-constraint parameters (Obi 5.6 and up)" in the scripting section of the manual to learn to change constraint data at runtime:
http://obi.virtualmethodstudio.com/tutor...aints.html
Reply
#3
Thank you for the help. Is there any existing code in obi for converting a quaternion(rotation of a joint of an animated rig) into a Darboux vector?

Also out of curiosity, what is the point of having a rest position with rotational velocity? doesn't a rest position always have no rotational velocity?
Reply
#4
(04-05-2021, 06:12 AM)Hakazaba Wrote: Thank you for the help. Is there any existing code in obi for converting a quaternion(rotation of a joint of an animated rig) into a Darboux vector?

You have ObiUtils.RestDarboux(Quaternion q1, Quaternion q2). It takes two rotation quaternions as input, and outputs the Darboux vector that describes the change in curvature and torsion from q1 to q2. So you can take one joint as q2, its parent as q1, pass them to this function and you will get a Darboux vector.

(04-05-2021, 06:12 AM)Hakazaba Wrote: Also out of curiosity, what is the point of having a rest position with rotational velocity? doesn't a rest position always have no rotational velocity?

A rod is basically a curve, right? On a curve, you can define a orthonormal frame (3 unit vectors orthogonal to each other) at any point:
- A vector that's tangent to the curve, pointing to the "direction" of the curve (tangent vector)
- A vector pointing "inside" or "outside" the curve (normal vector)
- A vector orthogonal to the other 2 (binormal vector)

This is known as the Frenet-Serret frame. If you want to describe how the shape of the curve changes between two points, you need to somehow compare two Frenet frames. This is where the Darboux vector comes into play.

Back to your original question: The Darboux vector determines the frame's change in curvature and torsion between two points. Both curvature and torsion are rotations (curvature is rotation around the normal/binormal frame vectors, and torsion is rotation around the tangent vector), so the Darboux vector is directly proportional to the curve's angular momentum. That's why it can be understood as an angular velocity vector.
Reply
#5
Interesting. Thank you very much for the detailed explanation!

What should the Darboux vector of the first particle of the rod be, since it doesn't have a parent particle?

I would like to double check that im on the right track. I should use.
actor.solverBatchOffsets[(int)Oni.ConstraintType.BendTwist];
actor.solver.GetConstraintsByType(Oni.ConstraintType.BendTwist)

And if i do, will these values need updating every frame? Or will they be consistant after start?
Reply
#6
Ok i have this script in update, and i'm not seeing it have any effect on the physics. What am i doing wrong?

            var Bendtwist = rope.solverBatchOffsets[(int)Oni.ConstraintType.BendTwist];
        
            var solverConstraints = solver.GetConstraintsByType(Oni.ConstraintType.BendTwist)
            as ObiConstraints<ObiBendTwistConstraintsBatch>;

            int b = 0;
            int b2 = 0;
            bool batch = true;
            Quaternion prior = followChain[0].rotation;
            for (int i = 0i<chain.Length;i++)
            {
                Quaternion next = prior;
                prior = followChain[i].rotation;
                if (batch){
                    solverConstraints.batches[0].restDarbouxVectors[Bendtwist[0]+b] = ObiUtils.RestDarboux(next,prior);
                    batch = false;
                    b++;
                }
                else {
                    
                    solverConstraints.batches[1].restDarbouxVectors[Bendtwist[1]+b2] = ObiUtils.RestDarboux(next,prior);
                    batch = true;
                    b2++;
                }
            }
Reply
#7
I get the solver constraints, but how do i actually set them in the solver?
Reply
#8
(05-05-2021, 06:28 AM)Hakazaba Wrote: What should the Darboux vector of the first particle of the rod be, since it doesn't have a parent particle?

There's not one Darboux vector per particle, but one per constraint. You can think of constraints as the "edges" in between particles. If you have N particles in the rod, there will be N-1 constraints.

Terrible ASCII diagram to the rescue:

Code:
(X)-------(X)-------(X)-------(X)

(X) = particle
------- = constraint

That would be a straight rod. As you can see, there's 4 particles but only 3 constraints.

Keep in mind that Darboux vectors do not determine an absolute orientation, but a change in orientation. So the first darboux vector in the rod will tell you how rod orientation changes from the first particle to the second particle. If it's Quaternion.identity, it will mean that the second particle has the same orientation as the first, however oriented it is.

Quote:I would like to double check that im on the right track. I should use.
actor.solverBatchOffsets[(int)Oni.ConstraintType.BendTwist];
actor.solver.GetConstraintsByType(Oni.ConstraintType.BendTwist)

Correct.

Quote:And if i do, will these values need updating every frame? Or will they be consistant after start?

They will remain set to whatever you set them to. If you want to animate them over time though, you will have to update them every frame to set new values.
Reply
#9
(05-05-2021, 12:53 AM)Hakazaba Wrote: Ok i have this script in update, and i'm not seeing it have any effect on the physics. What am i doing wrong?

This works for me as-is.

I see your rod is named "rope" in the code. Is this just coincidental, or are you actually using a rope? Remember that only rods can remember their rest shape, and have bend/twist constraints! Ropes work in a completely different way.

Here's a video of my results using your code:
Reply
#10
The name rope is just an artifact of the object once being a rope, until i changed it to a rod. No idea why its not working on my end then
Reply