Ragdoll sandbox

A place to discuss everything related to Newton Dynamics.

Moderators: Sascha Willems, walaber

Ragdoll sandbox

Postby mway » Sat Oct 08, 2011 11:31 am

Hi all,

I am looking for some source of a simple ragdoll sandbox (ie. a ragdoll and a floor) with which I can have a play with the code. Any ideas?
mway
 
Posts: 6
Joined: Sat Oct 08, 2011 11:29 am

Re: Ragdoll sandbox

Postby JoeJ » Sun Oct 09, 2011 3:56 pm

There are two of them in the demos.
You might need older Newton-Version, because some damos where removed and there are also troubles with crossplatform GUI.
NewtonWin-2.16 works good for me on Win7.

The demos show snowmans and gymnasts on ground plane, you can also drag them around.
It's very stable, but to improve realism you can create your own custum joints.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Ragdoll sandbox

Postby mway » Sun Oct 09, 2011 7:19 pm

Thanks mate,

You wouldn't possibly be able to step me in the right direction, if I was trying to add some control to the ragdolls (ie. press a key and the knee joint would contract?).
mway
 
Posts: 6
Joined: Sat Oct 08, 2011 11:29 am

Re: Ragdoll sandbox

Postby JoeJ » Mon Oct 10, 2011 2:56 am

Yes, i'm working on powered ragdolls for nearly a year. But at the moment no time to proceed - hopefully soon... :(
First i've set up joints and their powering, then kinematic solvers for legs / arms / spine, then AI to take control.
Actually the ragdoll can stand still and keeps balance, falling comes next, then walking...
Note: Powered joints don't do the entire job, i use torques in the force and torque callback in addition to get fast responsive motion, phyisics running at 120 Hz. My ragdoll counts 21 bodies, no problems with jitter or drifting, so the living ragdoll with newton is more stable than a dead ragdoll in actual AAA games :)

The code below is still experimental and messy, but i'll try to explain in comments.
The dJointLibrary coming with Newton is the best source to learn joints, you can decide to use and extend it, or begin from scratch (which i did). It contains a hinge joint too, but my code is very different because i derived it quickly from my cone twist joint, which differs a lot from the newton ball socket.

Caution: In my math lib, matrix and quaternion rotation order is reversed compared to newtons, and quats are (x,y,z,w) for me but (w,x,y,z) in newton.

Code: Select all

   void AddPointToPointConstraint (sMat4 &matrix0, sMat4 &matrix1) // simple point to point constraint
   {
      NewtonUserJointAddLinearRow (joint, (float*)&matrix0[3], (float*)&matrix1[3], (float*)&matrix0[0]);
      NewtonUserJointAddLinearRow (joint, (float*)&matrix0[3], (float*)&matrix1[3], (float*)&matrix0[1]);
      NewtonUserJointAddLinearRow (joint, (float*)&matrix0[3], (float*)&matrix1[3], (float*)&matrix0[2]);
   }

   void SubmitHingeConstraints (float timestep, int threadIndex)  // newton calls this as callback
   {

      sMat4 matrix0, matrix1; // construct joint matrices in global space
      BodyGetMatrix ((Body*)body0, *((sMat4*)&matrix0)); matrix0 *= localMatrix0;      
      BodyGetMatrix ((Body*)body1, *((sMat4*)&matrix1)); matrix1 *= localMatrix1;
      sQuat q0, q1; // same as matrix0 orientation, but in quat form...
      BodyGetRotation (body0, q0); q0 *= localRot0; // note: BodyGetRotation does (w,x,y,z)->(x,y,z,w) conversation
      BodyGetRotation (body1, q1); q1 *= localRot1;

      AddPointToPointConstraint (matrix0, matrix1);

      const sVec3& dir0 = matrix0[0]; // direction vectors along upper and lower leg
      const sVec3& dir1 = matrix1[0];

      float dot = dir0.Dot (dir1); if (dot < -0.999) return; // todo: lazy hack for now, remove!
      
      // do the twist (avoid lower leg turning around it's length)
      {
         // very nice quaternion trick to get rotation about x axis between 2 orientations
         float twistAngle = 2.0 * atan (
            ( ( ( (q0[3] * q1[0]) + (-q0[0] * q1[3]) ) + (-q0[1] * q1[2]) ) - (-q0[2] * q1[1]) ) /
            ( ( ( (q0[3] * q1[3]) - (-q0[0] * q1[0]) ) - (-q0[1] * q1[1]) ) - (-q0[2] * q1[2]) ) );

         sVec3 twistAxis = sVec3(dir0+dir1).Unit(); // could use dir0 OR dir1 too, but average seems most stable - unsure about that
         NewtonUserJointAddAngularRow (joint, twistAngle, (float*)&twistAxis); // newton will try to correct the twistAngle error for us
      }

      // additional hinge constraints...
      
         // plane constraint...

         sVec3 d = matrix1.Unrotate (dir0);
         float planeAngle = asin (d[2]);
         d[2] = 0; d.Normalize();

         sVec3 swingAxis (matrix1.Rotate(sVec3 (-d[1], d[0], 0)));
         NewtonUserJointAddAngularRow (joint, planeAngle, (float*)&swingAxis);

         // hinge limits...

         float minHingeAngle = ...
         float maxHingeAngle = ...
         float limitAngle = atan2 (d[1], d[0]);
         if (limitAngle < minHingeAngle)
         {
            NewtonUserJointAddAngularRow (joint, minHingeAngle - limitAngle, (float*)&matrix1[2]);
            NewtonUserJointSetRowMinimumFriction (joint, 0.0f);
         }
         else if (limitAngle > maxHingeAngle)
         {
            NewtonUserJointAddAngularRow (joint, maxHingeAngle - limitAngle, (float*)&matrix1[2]);
            NewtonUserJointSetRowMaximumFriction (joint, 0.0f);
         }
      
            
      // powering
      {
         float m_maxAngularFriction = 2000.0; // max muscle strength
         sVec3 omega0, omega1;
         BodyGetAngVel(body0, omega0); // == NewtonBodyGetOmega
         BodyGetAngVel(body1, omega1);
               
         sVec3 &axis = matrix1[2];
         float relAccel;
               
         float motorAngle = ...target knee angle
         relAccel = (motorAngle - limitAngle);
         relAccel -= sVec3(omega0 - omega1).Dot(axis) * ...some value (0...1) like 0.5, to take current velocity into account
         relAccel *= ...some value to drive speed... / timestep;
         
         NewtonUserJointAddAngularRow (joint, 0.0f, &axis[0]); // now we don't want to fix an error, so use 0.0
         NewtonUserJointSetRowAcceleration (joint, relAccel); // instead, provide acceleration
         NewtonUserJointSetRowMinimumFriction (joint, -m_maxAngularFriction);
         NewtonUserJointSetRowMaximumFriction (joint,  m_maxAngularFriction);
      }
      
   }
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm

Re: Ragdoll sandbox

Postby tedanoell » Thu Oct 20, 2011 5:46 pm

JoeJ wrote:There are two of them in the demos.

Any stable versions?
tedanoell
 

Re: Ragdoll sandbox

Postby JoeJ » Fri Oct 21, 2011 6:13 am

To clear that out: I suggested the older Newton version only because of the demos.
Both demos are stable, and they should run with newest Newton with minor changes.
User avatar
JoeJ
 
Posts: 1489
Joined: Tue Dec 21, 2010 6:18 pm


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 1 guest