Esempio n. 1
0
void dGeomSetQuaternion (dxGeom *g, const dQuaternion quat)
{
    dAASSERT (g && quat);
    dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable");
    CHECK_NOT_LOCKED (g->parent_space);
    if (g->offset_posr) {
        g->recomputePosr();
        // move body such that body+offset = rotation
        dxPosR new_final_posr;
        dxPosR new_body_posr;
        dQtoR (quat, new_final_posr.R);
        memcpy(new_final_posr.pos, g->final_posr->pos, sizeof(dVector3));

        getBodyPosr(*g->offset_posr, new_final_posr, new_body_posr);
        dBodySetRotation(g->body, new_body_posr.R);
        dBodySetPosition(g->body, new_body_posr.pos[0], new_body_posr.pos[1], new_body_posr.pos[2]);
    }
    if (g->body) {
        // this will call dGeomMoved (g), so we don't have to
        dBodySetQuaternion (g->body,quat);
    }
    else {
        dQtoR (quat, g->final_posr->R);
        dGeomMoved (g);
    }
}
Esempio n. 2
0
void command (int cmd)
{
  // note: 0.0174532925 radians = 1 degree
  dQuaternion q;
  dMatrix3 m;
  switch(cmd)
    {
    case 'w':
      geom1pos[0]+=0.05;
      break;
    case 'a':
      geom1pos[1]-=0.05;
      break;
    case 's':
      geom1pos[0]-=0.05;
      break;
    case 'd':
      geom1pos[1]+=0.05;
      break;
    case 'e':
      geom1pos[2]-=0.05;
      break;
    case 'q':
      geom1pos[2]+=0.05;
      break;
    case 'i':
      dQFromAxisAndAngle (q, 0, 0, 1,0.0174532925);
      dQMultiply0(geom1quat,geom1quat,q);
      break;
    case 'j':
      dQFromAxisAndAngle (q, 1, 0, 0,0.0174532925);
      dQMultiply0(geom1quat,geom1quat,q);
      break;
    case 'k':
      dQFromAxisAndAngle (q, 0, 0, 1,-0.0174532925);
      dQMultiply0(geom1quat,geom1quat,q);
      break;
    case 'l':
      dQFromAxisAndAngle (q, 1, 0, 0,-0.0174532925);
      dQMultiply0(geom1quat,geom1quat,q);
      break;
    case 'm':
		(drawmode!=DS_POLYFILL)? drawmode=DS_POLYFILL:drawmode=DS_WIREFRAME;
      break;
    case 'n':
		(geoms!=convex)? geoms=convex:geoms=boxes;
      break;
    default:
      dsPrint ("received command %d (`%c')\n",cmd,cmd);     
    }
#if 0
  dGeomSetPosition (geoms[1],
		    geom1pos[0],
		    geom1pos[1],
		    geom1pos[2]);
  dQtoR (geom1quat, m);
  dGeomSetRotation (geoms[1],m);
#endif
  DumpInfo=true;
}
Esempio n. 3
0
EXPORT_C void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az,
			 dReal angle)
{
  dQuaternion q;
  dQFromAxisAndAngle (q,ax,ay,az,angle);
  dQtoR (q,R);
}
 // converts a osg 4x4 matrix to an ode version of it
 void odeRotation( const Pose& pose , dMatrix3& odematrix){
   osg::Quat q;
   pose.get(q);
   // THIS should be
   //    dQuaternion quat = {q.x(), q.y(), q.z(), q.w() };
   dQuaternion quat = {q.w(), q.x(), q.y(), q.z() };
   dQtoR(quat, odematrix);
 }
Esempio n. 5
0
void testQuaternionMultiply()
{
  HEADER;
  dMatrix3 RA,RB,RC,Rtest;
  dQuaternion qa,qb,qc;
  dReal diff,maxdiff=0;

  for (int i=0; i<100; i++) {
    makeRandomRotation (RB);
    makeRandomRotation (RC);
    dRtoQ (RB,qb);
    dRtoQ (RC,qc);

    dMultiply0 (RA,RB,RC,3,3,3);
    dQMultiply0 (qa,qb,qc);
    dQtoR (qa,Rtest);
    diff = dMaxDifference (Rtest,RA,3,3);
    if (diff > maxdiff) maxdiff = diff;

    dMultiply1 (RA,RB,RC,3,3,3);
    dQMultiply1 (qa,qb,qc);
    dQtoR (qa,Rtest);
    diff = dMaxDifference (Rtest,RA,3,3);
    if (diff > maxdiff) maxdiff = diff;

    dMultiply2 (RA,RB,RC,3,3,3);
    dQMultiply2 (qa,qb,qc);
    dQtoR (qa,Rtest);
    diff = dMaxDifference (Rtest,RA,3,3);
    if (diff > maxdiff) maxdiff = diff;

    dMultiply0 (RA,RC,RB,3,3,3);
    transpose3x3 (RA);
    dQMultiply3 (qa,qb,qc);
    dQtoR (qa,Rtest);
    diff = dMaxDifference (Rtest,RA,3,3);
    if (diff > maxdiff) maxdiff = diff;
  }
  printf ("\tmaximum difference = %e - %s\n",maxdiff,
	  (maxdiff > tol) ? "FAILED" : "passed");
}
Esempio n. 6
0
void dGeomSetOffsetQuaternion (dxGeom *g, const dQuaternion quat)
{
    dAASSERT (g && quat);
    dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable");
    dUASSERT (g->body, "geom must be on a body");  
    CHECK_NOT_LOCKED (g->parent_space);
    if (!g->offset_posr) 
    {
        dGeomCreateOffset (g);
    }
    dQtoR (quat, g->offset_posr->R);
    dGeomMoved (g);
}
void dGeomSetQuaternion (dxGeom *g, const dQuaternion quat)
{
  dAASSERT (g && quat);
  dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable");
  CHECK_NOT_LOCKED (g->parent_space);
  if (g->body) {
    // this will call dGeomMoved (g), so we don't have to
    dBodySetQuaternion (g->body,quat);
  }
  else {
    dQtoR (quat, g->R);
    dGeomMoved (g);
  }
}
Esempio n. 8
0
void testRtoQandQtoR()
{
  HEADER;
  dMatrix3 R,I,R2;
  dQuaternion q;
  int i;

  // test makeRandomRotation()
  makeRandomRotation (R);
  dMultiply2 (I,R,R,3,3,3);
  printf ("\tmakeRandomRotation() - %s (1)\n",
	  cmpIdentityMat3(I) ? "passed" : "FAILED");

  // test QtoR() on random normalized quaternions
  int ok = 1;
  for (i=0; i<100; i++) {
    dMakeRandomVector (q,4,1.0);
    dNormalize4 (q);
    dQtoR (q,R);
    dMultiply2 (I,R,R,3,3,3);
    if (cmpIdentityMat3(I)==0) ok = 0;
  }
  printf ("\tQtoR() orthonormality %s (2)\n", ok ? "passed" : "FAILED");

  // test R -> Q -> R works
  dReal maxdiff=0;
  for (i=0; i<100; i++) {
    makeRandomRotation (R);
    dRtoQ (R,q);
    dQtoR (q,R2);
    dReal diff = dMaxDifference (R,R2,3,3);
    if (diff > maxdiff) maxdiff = diff;
  }
  printf ("\tmaximum difference = %e - %s (3)\n",maxdiff,
	  (maxdiff > tol) ? "FAILED" : "passed");
}
void dWorldExportDIF (dWorldID w, FILE *file, const char *prefix)
{
    PrintingContext c;
    c.file = file;
#if defined(dSINGLE)
    c.precision = 7;
#else
    c.precision = 15;
#endif
    c.indent = 1;

    fprintf (file,"-- ODE position and rotation export.\n");


    // bodies
    int num = 0;
    for (dxBody *b=w->firstbody; b; b=(dxBody*)b->next) {
        b->tag = num;
        fprintf (file,"body %d\n",num);
        c.printNum ("",b->posr.pos[0]);
        c.printNum ("",b->posr.pos[1]);
        c.printNum ("",b->posr.pos[2]);


        dMatrix3 R;
        dQtoR (b->q, R);

        //! Find Roll Pitch and Yaw
        // rotation Matrix then convert to Euler Angles
        dReal roll  = atan2(R[9], R[10]) * 1/DEGTORAD;     //phi
        dReal pitch = asin(-R[8]) * 1/DEGTORAD;            //theta
        dReal yaw   = atan2(R[4], R[0]) * 1/DEGTORAD;      //greek Y
        c.printNum ("", roll);
        c.printNum ("", pitch);
        c.printNum ("", yaw);
        num++;


    }
    fprintf (file,"end of file");
    printf ("State.dif Exported.\n");
}
Esempio n. 10
0
void dGeomSetOffsetWorldQuaternion (dxGeom *g, const dQuaternion quat)
{
    dAASSERT (g && quat);
    dUASSERT (g->gflags & GEOM_PLACEABLE,"geom must be placeable");
    dUASSERT (g->body, "geom must be on a body");  
    CHECK_NOT_LOCKED (g->parent_space);
    if (!g->offset_posr) 
    {
        dGeomCreateOffset (g);
    }

    g->recomputePosr();

    dxPosR new_final_posr;
    memcpy(new_final_posr.pos, g->final_posr->pos, sizeof(dVector3));
    dQtoR (quat, new_final_posr.R);

    getWorldOffsetPosr(g->body->posr, new_final_posr, *g->offset_posr);
    dGeomMoved (g);
}
Esempio n. 11
0
void reset_test()
{
  int i;
  dMass m,anchor_m;
  dReal q[NUM][3], pm[NUM];	// particle positions and masses
  dReal pos1[3] = {1,0,1};	// point of reference (POR)
  dReal pos2[3] = {-1,0,1};	// point of reference (POR)

  // make random particle positions (relative to POR) and masses
  for (i=0; i<NUM; i++) {
    pm[i] = dRandReal()+0.1;
    q[i][0] = dRandReal()-0.5;
    q[i][1] = dRandReal()-0.5;
    q[i][2] = dRandReal()-0.5;
  }

  // adjust particle positions so centor of mass = POR
  computeMassParams (&m,q,pm);
  for (i=0; i<NUM; i++) {
    q[i][0] -= m.c[0];
    q[i][1] -= m.c[1];
    q[i][2] -= m.c[2];
  }

  if (world) dWorldDestroy (world);
  world = dWorldCreate();

  anchor_body = dBodyCreate (world);
  dBodySetPosition (anchor_body,pos1[0],pos1[1],pos1[2]);
  dMassSetBox (&anchor_m,1,SIDE,SIDE,SIDE);
  dMassAdjust (&anchor_m,0.1);
  dBodySetMass (anchor_body,&anchor_m);

  for (i=0; i<NUM; i++) {
    particle[i] = dBodyCreate (world);
    dBodySetPosition (particle[i],
		      pos1[0]+q[i][0],pos1[1]+q[i][1],pos1[2]+q[i][2]);
    dMassSetBox (&m,1,SIDE,SIDE,SIDE);
    dMassAdjust (&m,pm[i]);
    dBodySetMass (particle[i],&m);
  }

  for (i=0; i < NUM; i++) {
    particle_joint[i] = dJointCreateBall (world,0);
    dJointAttach (particle_joint[i],anchor_body,particle[i]);
    const dReal *p = dBodyGetPosition (particle[i]);
    dJointSetBallAnchor (particle_joint[i],p[0],p[1],p[2]);
  }

  // make test_body with the same mass and inertia of the anchor_body plus
  // all the particles

  test_body = dBodyCreate (world);
  dBodySetPosition (test_body,pos2[0],pos2[1],pos2[2]);
  computeMassParams (&m,q,pm);
  m.mass += anchor_m.mass;
  for (i=0; i<12; i++) m.I[i] = m.I[i] + anchor_m.I[i];
  dBodySetMass (test_body,&m);

  // rotate the test and anchor bodies by a random amount
  dQuaternion qrot;
  for (i=0; i<4; i++) qrot[i] = dRandReal()-0.5;
  dNormalize4 (qrot);
  dBodySetQuaternion (anchor_body,qrot);
  dBodySetQuaternion (test_body,qrot);
  dMatrix3 R;
  dQtoR (qrot,R);
  for (i=0; i<NUM; i++) {
    dVector3 v;
    dMultiply0 (v,R,&q[i][0],3,3,1);
    dBodySetPosition (particle[i],pos1[0]+v[0],pos1[1]+v[1],pos1[2]+v[2]);
  }

  // set random torque
  for (i=0; i<3; i++) torque[i] = (dRandReal()-0.5) * 0.1;


  iteration=0;
}
Esempio n. 12
0
void dxStepBody (dxBody *b, dReal h)
{
  int j;
#ifdef DEBUG_VALID
dIASSERT(dValid(b->avel[0])&&dValid(b->avel[1])&&dValid(b->avel[2]));
#endif
  // handle linear velocity
  for (j=0; j<3; j++) b->pos[j] += h * b->lvel[j];

  if (b->flags & dxBodyFlagFiniteRotation) {
    dVector3 irv;	// infitesimal rotation vector
    dQuaternion q;	// quaternion for finite rotation

    if (b->flags & dxBodyFlagFiniteRotationAxis) {
      // split the angular velocity vector into a component along the finite
      // rotation axis, and a component orthogonal to it.
      dVector3 frv;		// finite rotation vector
      dReal k = dDOT (b->finite_rot_axis,b->avel);
      frv[0] = b->finite_rot_axis[0] * k;
      frv[1] = b->finite_rot_axis[1] * k;
      frv[2] = b->finite_rot_axis[2] * k;
      irv[0] = b->avel[0] - frv[0];
      irv[1] = b->avel[1] - frv[1];
      irv[2] = b->avel[2] - frv[2];

      // make a rotation quaternion q that corresponds to frv * h.
      // compare this with the full-finite-rotation case below.
      h *= REAL(0.5);
      dReal theta = k * h;
      q[0] = dCos(theta);
      dReal s = sinc(theta) * h;
      q[1] = frv[0] * s;
      q[2] = frv[1] * s;
      q[3] = frv[2] * s;
    }
    else {
      // make a rotation quaternion q that corresponds to w * h
      dReal wlen = dSqrt (b->avel[0]*b->avel[0] + b->avel[1]*b->avel[1] +
			  b->avel[2]*b->avel[2]);
      h *= REAL(0.5);
      dReal theta = wlen * h;
      q[0] = dCos(theta);
      dReal s = sinc(theta) * h;
      q[1] = b->avel[0] * s;
      q[2] = b->avel[1] * s;
      q[3] = b->avel[2] * s;
    }

    // do the finite rotation
    dQuaternion q2;
    dQMultiply0 (q2,q,b->q);
    for (j=0; j<4; j++) b->q[j] = q2[j];

    // do the infitesimal rotation if required
    if (b->flags & dxBodyFlagFiniteRotationAxis) {
      dReal dq[4];
      dWtoDQ (irv,b->q,dq);
      for (j=0; j<4; j++) b->q[j] += h * dq[j];
    }
  }
  else {
    // the normal way - do an infitesimal rotation
    dReal dq[4];
    dWtoDQ (b->avel,b->q,dq);
    for (j=0; j<4; j++) b->q[j] += h * dq[j];
  }

  // normalize the quaternion and convert it to a rotation matrix
  dNormalize4 (b->q);
  dQtoR (b->q,b->R);

  // notify all attached geoms that this body has moved
  for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom))
    dGeomMoved (geom);

#ifdef DEBUG_VALID
dIASSERT(dValid(b->avel[0])&&dValid(b->avel[1])&&dValid(b->avel[2]));
#endif






}
Esempio n. 13
0
void start()
{
  // adjust the starting viewpoint a bit
  float xyz[3],hpr[3];
  dsGetViewpoint (xyz,hpr);
  hpr[0] += 7;
  dsSetViewpoint (xyz,hpr);
  convex[0]=dCreateConvex (space,
			  planes,
			  planecount,
			  points,
			  pointcount,
			  polygons);
  convex[1]=dCreateConvex (space,
			  planes,
			  planecount,
			  points,
			  pointcount,
			  polygons);
  boxes[0]=dCreateBox(space,0.5,0.5,0.5);
  boxes[1]=dCreateBox(space,0.5,0.5,0.5);
  geoms=convex;

  dMatrix3 m1 = { 1,0,0,0,0,1,0,0,0,0,1,0 };
  dMatrix3 m2 = { 1,0,0,0,0,1,0,0,0,0,1,0 };
#if 0
  dGeomSetPosition (convex[0],
		    0.0,
		    0.0,
		    0.25);
  dGeomSetPosition (convex[1],
		    geom1pos[0],
		    geom1pos[1],
		    geom1pos[2]);
  dQtoR (geom0quat, m1);
  dGeomSetRotation (convex[0],m1);
  dQtoR (geom1quat, m2);
  dGeomSetRotation (convex[1],m2);

  dGeomSetPosition (boxes[0],
		    0.0,
		    0.0,
		    0.25);
  dGeomSetPosition (boxes[1],
		    geom1pos[0],
		    geom1pos[1],
		    geom1pos[2]);
  dQtoR (geom0quat, m1);
  dGeomSetRotation (boxes[0],m1);
  dQtoR (geom1quat, m2);
  dGeomSetRotation (boxes[1],m2);
#else
  dGeomSetPosition (convex[0],
		    fixed_pos_0[0],
		    fixed_pos_0[1],
		    fixed_pos_0[2]);
  dGeomSetPosition (convex[1],
		    fixed_pos_1[0],
		    fixed_pos_1[1],
		    fixed_pos_1[2]);
  dGeomSetRotation (convex[0],fixed_rot_0);
  dGeomSetRotation (convex[1],fixed_rot_1);
  dGeomSetPosition (boxes[0],
		    fixed_pos_0[0],
		    fixed_pos_0[1],
		    fixed_pos_0[2]);
  dGeomSetPosition (boxes[1],
		    fixed_pos_1[0],
		    fixed_pos_1[1],
		    fixed_pos_1[2]);
  dGeomSetRotation (boxes[0],fixed_rot_0);
  dGeomSetRotation (boxes[1],fixed_rot_1);
#endif

}
void dWorldExportDIFLong (dWorldID w, FILE *file, const char *prefix)
{
    PrintingContext c;
    c.file = file;
#if defined(dSINGLE)
    c.precision = 7;
#else
    c.precision = 15;
#endif
    c.indent = 1;

    fprintf (file,"-- Dynamics Interchange Format v0.1\n\n%sworld = dynamics.world {\n",prefix);
    c.print ("gravity",w->gravity);
    c.print ("ODE = {");
    c.indent++;
    c.print ("ERP",w->global_erp);
    c.print ("CFM",w->global_cfm);
    c.print ("auto_disable = {");
    c.indent++;
    c.print ("linear_threshold",w->adis.linear_average_threshold);
    c.print ("angular_threshold",w->adis.angular_average_threshold);
    c.print ("average_samples",(int)w->adis.average_samples);
    c.print ("idle_time",w->adis.idle_time);
    c.print ("idle_steps",w->adis.idle_steps);
    fprintf (file,"\t\t},\n\t},\n}\n");
    c.indent -= 3;

    // bodies
    int num = 0;
    fprintf (file,"%sbody = {}\n",prefix);
    for (dxBody *b=w->firstbody; b; b=(dxBody*)b->next) {
        b->tag = num;
        fprintf (file,"%sbody[%d] = dynamics.body {\n\tworld = %sworld,\n",prefix,num,prefix);
        c.indent++;
        c.print ("pos",b->posr.pos);
        c.print ("q",b->q,4);

        dMatrix3 R;
        dQtoR (b->q, R);

        //! Find Roll Pitch and Yaw
        // rotation Matrix then convert to Euler Angles
        dReal roll  = atan2(R[9], R[10]) * 1/DEGTORAD;     //phi
        dReal pitch = asin(-R[8]) * 1/DEGTORAD;            //theta
        dReal yaw   = atan2(R[4], R[0]) * 1/DEGTORAD;      //greek Y
        c.print ("roll ", roll);
        c.print ("pitch ", pitch);
        c.print ("yaw ", yaw);

        c.print ("lvel",b->lvel);
        c.print ("avel",b->avel);
        c.print ("mass",b->mass.mass);
        fprintf (file,"\tI = {{");
        for (int i=0; i<3; i++) {
            for (int j=0; j<3; j++) {
                c.printReal (b->mass.I[i*4+j]);
                if (j < 2) fputc (',',file);
            }
            if (i < 2) fprintf (file,"},{");
        }
        fprintf (file,"}},\n");
        c.printNonzero ("com",b->mass.c);
        c.print ("ODE = {");
        c.indent++;
        if (b->flags & dxBodyFlagFiniteRotation) c.print ("finite_rotation",1);
        if (b->flags & dxBodyDisabled) c.print ("disabled",1);
        if (b->flags & dxBodyNoGravity) c.print ("no_gravity",1);
        if (b->flags & dxBodyAutoDisable) {
            c.print ("auto_disable = {");
            c.indent++;
            c.print ("linear_threshold",b->adis.linear_average_threshold);
            c.print ("angular_threshold",b->adis.angular_average_threshold);
            c.print ("average_samples",(int)b->adis.average_samples);
            c.print ("idle_time",b->adis.idle_time);
            c.print ("idle_steps",b->adis.idle_steps);
            c.print ("time_left",b->adis_timeleft);
            c.print ("steps_left",b->adis_stepsleft);
            c.indent--;
            c.print ("},");
        }
        c.printNonzero ("facc",b->facc);
        c.printNonzero ("tacc",b->tacc);
        if (b->flags & dxBodyFlagFiniteRotationAxis) {
            c.print ("finite_rotation_axis",b->finite_rot_axis);
        }
        c.indent--;
        c.print ("},");
        if (b->geom) {
            c.print ("geometry = {");
            c.indent++;
            for (dxGeom *g=b->geom; g; g=g->body_next) {
                c.print ("{");
                c.indent++;
                printGeom (c,g);
                c.indent--;
                c.print ("},");
            }
            c.indent--;
            c.print ("},");
        }
        c.indent--;
        c.print ("}");
        num++;
    }

    // joints
    num = 0;
    fprintf (file,"%sjoint = {}\n",prefix);
    for (dxJoint *j=w->firstjoint; j; j=(dxJoint*)j->next) {
        c.indent++;
        const char *name = getJointName (j);
        fprintf (file,
                 "%sjoint[%d] = dynamics.%s_joint {\n"
                 "\tworld = %sworld,\n"
                 "\tbody = {"
                 ,prefix,num,name,prefix);

        if ( j->node[0].body )
            fprintf (file,"%sbody[%d]",prefix,j->node[0].body->tag);
        if ( j->node[1].body )
            fprintf (file,",%sbody[%d]",prefix,j->node[1].body->tag);
        fprintf (file,"}\n");

        switch (j->type()) {
        case dJointTypeBall:
            printBall (c,j);
            break;
        case dJointTypeHinge:
            printHinge (c,j);
            break;
        case dJointTypeSlider:
            printSlider (c,j);
            break;
        case dJointTypeContact:
            printContact (c,j);
            break;
        case dJointTypeUniversal:
            printUniversal (c,j);
            break;
        case dJointTypeHinge2:
            printHinge2 (c,j);
            break;
        case dJointTypeFixed:
            printFixed (c,j);
            break;
        case dJointTypeAMotor:
            printAMotor (c,j);
            break;
        case dJointTypeLMotor:
            printLMotor (c,j);
            break;
        case dJointTypePR:
            printPR (c,j);
            break;
        case dJointTypePU:
            printPU (c,j);
            break;
        case dJointTypePiston:
            printPiston (c,j);
            break;
        default:
            c.print("unknown joint");
        }
        c.indent--;
        c.print ("}");
        num++;
    }
}
Esempio n. 15
0
void dxStepBody (dxBody *b, dReal h)
{
    // cap the angular velocity
    if (b->flags & dxBodyMaxAngularSpeed) {
        const dReal max_ang_speed = b->max_angular_speed;
        const dReal aspeed = dCalcVectorDot3( b->avel, b->avel );
        if (aspeed > max_ang_speed*max_ang_speed) {
            const dReal coef = max_ang_speed/dSqrt(aspeed);
            dScaleVector3(b->avel, coef);
        }
    }
    // end of angular velocity cap


    // handle linear velocity
    for (unsigned int j=0; j<3; j++) b->posr.pos[j] += h * b->lvel[j];

    if (b->flags & dxBodyFlagFiniteRotation) {
        dVector3 irv;	// infitesimal rotation vector
        dQuaternion q;	// quaternion for finite rotation

        if (b->flags & dxBodyFlagFiniteRotationAxis) {
            // split the angular velocity vector into a component along the finite
            // rotation axis, and a component orthogonal to it.
            dVector3 frv;		// finite rotation vector
            dReal k = dCalcVectorDot3 (b->finite_rot_axis,b->avel);
            frv[0] = b->finite_rot_axis[0] * k;
            frv[1] = b->finite_rot_axis[1] * k;
            frv[2] = b->finite_rot_axis[2] * k;
            irv[0] = b->avel[0] - frv[0];
            irv[1] = b->avel[1] - frv[1];
            irv[2] = b->avel[2] - frv[2];

            // make a rotation quaternion q that corresponds to frv * h.
            // compare this with the full-finite-rotation case below.
            h *= REAL(0.5);
            dReal theta = k * h;
            q[0] = dCos(theta);
            dReal s = sinc(theta) * h;
            q[1] = frv[0] * s;
            q[2] = frv[1] * s;
            q[3] = frv[2] * s;
        }
        else {
            // make a rotation quaternion q that corresponds to w * h
            dReal wlen = dSqrt (b->avel[0]*b->avel[0] + b->avel[1]*b->avel[1] +
                b->avel[2]*b->avel[2]);
            h *= REAL(0.5);
            dReal theta = wlen * h;
            q[0] = dCos(theta);
            dReal s = sinc(theta) * h;
            q[1] = b->avel[0] * s;
            q[2] = b->avel[1] * s;
            q[3] = b->avel[2] * s;
        }

        // do the finite rotation
        dQuaternion q2;
        dQMultiply0 (q2,q,b->q);
        for (unsigned int j=0; j<4; j++) b->q[j] = q2[j];

        // do the infitesimal rotation if required
        if (b->flags & dxBodyFlagFiniteRotationAxis) {
            dReal dq[4];
            dWtoDQ (irv,b->q,dq);
            for (unsigned int j=0; j<4; j++) b->q[j] += h * dq[j];
        }
    }
    else {
        // the normal way - do an infitesimal rotation
        dReal dq[4];
        dWtoDQ (b->avel,b->q,dq);
        for (unsigned int j=0; j<4; j++) b->q[j] += h * dq[j];
    }

    // normalize the quaternion and convert it to a rotation matrix
    dNormalize4 (b->q);
    dQtoR (b->q,b->posr.R);

    // notify all attached geoms that this body has moved
    dxWorldProcessContext *world_process_context = b->world->UnsafeGetWorldProcessingContext(); 
    for (dxGeom *geom = b->geom; geom; geom = dGeomGetBodyNext (geom)) {
        world_process_context->LockForStepbodySerialization();
        dGeomMoved (geom);
        world_process_context->UnlockForStepbodySerialization();
    }

    // notify the user
    if (b->moved_callback != NULL) {
        b->moved_callback(b);
    }

    // damping
    if (b->flags & dxBodyLinearDamping) {
        const dReal lin_threshold = b->dampingp.linear_threshold;
        const dReal lin_speed = dCalcVectorDot3( b->lvel, b->lvel );
        if ( lin_speed > lin_threshold) {
            const dReal k = 1 - b->dampingp.linear_scale;
            dScaleVector3(b->lvel, k);
        }
    }
    if (b->flags & dxBodyAngularDamping) {
        const dReal ang_threshold = b->dampingp.angular_threshold;
        const dReal ang_speed = dCalcVectorDot3( b->avel, b->avel );
        if ( ang_speed > ang_threshold) {
            const dReal k = 1 - b->dampingp.angular_scale;
            dScaleVector3(b->avel, k);
        }
    }
}
void command (int cmd)
{
  // note: 0.0174532925 radians = 1 degree
  dQuaternion q;
  dMatrix3 m;
  bool changed = false;
  switch(cmd)
    {
    case 'w':
      geom1pos[0]+=0.05;
      changed = true;
      break;
    case 'a':
      geom1pos[1]-=0.05;
      changed = true;
      break;
    case 's':
      geom1pos[0]-=0.05;
      changed = true;
      break;
    case 'd':
      geom1pos[1]+=0.05;
      changed = true;
      break;
    case 'e':
      geom1pos[2]-=0.05;
      changed = true;
      break;
    case 'q':
      geom1pos[2]+=0.05;
      changed = true;
      break;
    case 'i':
      dQFromAxisAndAngle (q, 0, 0, 1,0.0174532925);
      dQMultiply0(geom1quat,geom1quat,q);
      changed = true;
      break;
    case 'j':
      dQFromAxisAndAngle (q, 1, 0, 0,0.0174532925);
      dQMultiply0(geom1quat,geom1quat,q);
      changed = true;
      break;
    case 'k':
      dQFromAxisAndAngle (q, 0, 0, 1,-0.0174532925);
      dQMultiply0(geom1quat,geom1quat,q);
      changed = true;
      break;
    case 'l':
      dQFromAxisAndAngle (q, 1, 0, 0,-0.0174532925);
      dQMultiply0(geom1quat,geom1quat,q);
      changed = true;
      break;
    case 'm':
		(drawmode!=DS_POLYFILL)? drawmode=DS_POLYFILL:drawmode=DS_WIREFRAME;
      break;
    case 'n':
		(geoms!=convex)? geoms=convex:geoms=boxes;
		if(geoms==convex)
		{
		    printf("CONVEX------------------------------------------------------>\n");
		}
		else
		{
		    printf("BOX--------------------------------------------------------->\n");
		}
      break;
    default:
      dsPrint ("received command %d (`%c')\n",cmd,cmd);
    }
#if 0
            dGeomSetPosition (geoms[1],
		    geom1pos[0],
		    geom1pos[1],
		    geom1pos[2]);
            dQtoR (geom1quat, m);
            dGeomSetRotation(geoms[1],m);
    if(changed)
    {

            printf("POS: %f,%f,%f\n",geom1pos[0],geom1pos[1],geom1pos[2]);
            printf("ROT:\n%f,%f,%f,%f\n%f,%f,%f,%f\n%f,%f,%f,%f\n",
            m[0],m[1],m[2],m[3],
            m[4],m[5],m[6],m[7],
            m[8],m[9],m[10],m[11]);
    }
#endif
  DumpInfo=true;
}
Esempio n. 17
0
void createTest()
{
  int i,j;
  if (world) dWorldDestroy (world);

  world = dWorldCreate();

  // create random bodies
  for (i=0; i<NUM; i++) {
    // create bodies at random position and orientation
    body[i] = dBodyCreate (world);
    // dBodySetPosition (body[i],dRandReal()*2-1,dRandReal()*2-1,
    // 		      dRandReal()*2+RADIUS);
    dBodySetPosition (body[i],dRandReal()*SIDE-1,dRandReal()*SIDE-1,
    		      dRandReal()*SIDE+RADIUS);

    dReal q[4];
    for (j=0; j<4; j++) q[j] = dRandReal()*2-1;
    dBodySetQuaternion (body[i],q);

    // set random velocity
    dBodySetLinearVel (body[i], dRandReal()*2-1,dRandReal()*2-1,
		       dRandReal()*2-1);
    dBodySetAngularVel (body[i], dRandReal()*2-1,dRandReal()*2-1,
			dRandReal()*2-1);

    // set random mass (random diagonal mass rotated by a random amount)
    dMass m;
    dMatrix3 R;
    dMassSetBox (&m,1,dRandReal()+0.1,dRandReal()+0.1,dRandReal()+0.1);
    dMassAdjust (&m,dRandReal()+1);
    for (j=0; j<4; j++) q[j] = dRandReal()*2-1;
    dQtoR (q,R);
    dMassRotate (&m,R);
    dBodySetMass (body[i],&m);
  }

  // create ball-n-socket joints at random positions, linking random bodies
  // (but make sure not to link the same pair of bodies twice)
  for (i=0; i<NUM*NUM; i++) linked[i] = 0;
  for (i=0; i<NUMJ; i++) {
    int b1,b2;
    do {
      b1 = dRandInt (NUM);
      b2 = dRandInt (NUM);
    } while (linked[b1*NUM + b2] || b1==b2);
    linked[b1*NUM + b2] = 1;
    linked[b2*NUM + b1] = 1;
    joint[i] = dJointCreateBall (world,0);
    dJointAttach (joint[i],body[b1],body[b2]);
    dJointSetBallAnchor (joint[i],dRandReal()*2-1,
			 dRandReal()*2-1,dRandReal()*2+RADIUS);
  }

  for (i=0; i<NUM; i++) {
    // move bodies a bit to get some joint error
    const dReal *pos = dBodyGetPosition (body[i]); 
    dBodySetPosition (body[i],pos[0]+dRandReal()*0.2-0.1,
		      pos[1]+dRandReal()*0.2-0.1,pos[2]+dRandReal()*0.2-0.1);
  }
}
Esempio n. 18
0
// simulation loop
static void simLoop (int pause)
{
  static bool todo = false;
  if ( todo ) { // DEBUG
    static int cnt = 0;
    ++cnt;

    if (cnt == 5)
      command ( 'q' );
    if (cnt == 10)
      dsStop();
  }




  if (!pause) {
    double simstep = 0.01; // 10ms simulation steps
    double dt = dsElapsedTime();

    int nrofsteps = (int) ceilf (dt/simstep);
    if (!nrofsteps)
      nrofsteps = 1;

    for (int i=0; i<nrofsteps && !pause; i++) {
      dSpaceCollide (space,0,&nearCallback);
      dWorldStep (world, simstep);

      dJointGroupEmpty (contactgroup);
    }

    update();


    dReal radius, length;

    dsSetTexture (DS_WOOD);

    drawBox (geom[W], 1,1,0);


    drawBox (geom[EXT], 0,1,0);

    dVector3 anchorPos;



    dReal ang1 = 0;
    dReal ang2 = 0;
    dVector3 axisP, axisR1, axisR2;

    if ( dJointTypePU == type ) {
      dPUJoint *pu = dynamic_cast<dPUJoint *> (joint);
      ang1 = pu->getAngle1();
      ang2 = pu->getAngle2();
      pu->getAxis1 (axisR1);
      pu->getAxis2 (axisR2);
      pu->getAxisP (axisP);

      dJointGetPUAnchor (pu->id(), anchorPos);
    }
    else if ( dJointTypePR == type ) {
      dPRJoint *pr = dynamic_cast<dPRJoint *> (joint);
      pr->getAxis1 (axisP);
      pr->getAxis2 (axisR1);

      dJointGetPRAnchor (pr->id(), anchorPos);
    }


    // Draw the axisR
    if ( geom[INT] ) {
      dsSetColor (1,0,1);
      dVector3 l;
      dGeomBoxGetLengths (geom[INT], l);

      const dReal *rotBox = dGeomGetRotation (geom[W]);

      dVector3 pos;
      for (int i=0; i<3; ++i)
        pos[i] = anchorPos[i] - 0.5*extDim[Z]*axisP[i];
      dsDrawBox (pos, rotBox, l);
    }

    dsSetTexture (DS_CHECKERED);
    if ( geom[AXIS1] ) {
      dQuaternion q, qAng;
      dQFromAxisAndAngle (qAng,axisR1[X], axisR1[Y], axisR1[Z], ang1);
      dGeomGetQuaternion (geom[AXIS1], q);

      dQuaternion qq;
      dQMultiply1 (qq, qAng, q);
      dMatrix3 R;
      dQtoR (qq,R);


      dGeomCylinderGetParams (dGeomTransformGetGeom (geom[AXIS1]), &radius, &length);
      dsSetColor (1,0,0);
      dsDrawCylinder (anchorPos, R, length, radius);
    }

    if ( dJointTypePU == type && geom[AXIS2] ) {
      //dPUJoint *pu = dynamic_cast<dPUJoint *> (joint);

      dQuaternion q, qAng, qq, qq1;
      dGeomGetQuaternion (geom[AXIS2], q);

      dQFromAxisAndAngle (qAng, 0, 1, 0, ang2);
      dQMultiply1 (qq, qAng, q);


      dQFromAxisAndAngle (qAng,axisR1[X], axisR1[Y], axisR1[Z], ang1);

      dQMultiply1 (qq1, qAng, qq);


      dMatrix3 R;
      dQtoR (qq1,R);


      dGeomCylinderGetParams (dGeomTransformGetGeom (geom[AXIS2]), &radius, &length);
      dsSetColor (0,0,1);
      dsDrawCylinder (anchorPos, R, length, radius);
    }

    dsSetTexture (DS_WOOD);

    // Draw the anchor
    if ( geom[ANCHOR] ) {
      dsSetColor (1,1,1);
      dVector3 l;
      dGeomBoxGetLengths (geom[ANCHOR], l);

      const dReal *rotBox = dGeomGetRotation (geom[D]);
      const dReal *posBox = dGeomGetPosition (geom[D]);

      dVector3 e;
      for (int i=0; i<3; ++i)
        e[i] = posBox[i] - anchorPos[i];
      dNormalize3 (e);

      dVector3 pos;
      for (int i=0; i<3; ++i)
        pos[i] = anchorPos[i] + 0.5 * l[Z]*e[i];
      dsDrawBox (pos, rotBox, l);
    }

    drawBox (geom[D], 1,1,0);
  }
}
Esempio n. 19
0
static inline void
moveAndRotateBody (dxBody * b, dReal h)
{
	int j;

	// handle linear velocity
	for (j = 0; j < 3; j++)
		b->posr.pos[j] += dMUL(h,b->lvel[j]);

	if (b->flags & dxBodyFlagFiniteRotation)
	{
		dVector3 irv;			// infitesimal rotation vector
		dQuaternion q;			// quaternion for finite rotation

		if (b->flags & dxBodyFlagFiniteRotationAxis)
		{
			// split the angular velocity vector into a component along the finite
			// rotation axis, and a component orthogonal to it.
			dVector3 frv;	// finite rotation vector
			dReal k = dDOT (b->finite_rot_axis, b->avel);
			frv[0] = dMUL(b->finite_rot_axis[0],k);
			frv[1] = dMUL(b->finite_rot_axis[1],k);
			frv[2] = dMUL(b->finite_rot_axis[2],k);
			irv[0] = b->avel[0] - frv[0];
			irv[1] = b->avel[1] - frv[1];
			irv[2] = b->avel[2] - frv[2];

			// make a rotation quaternion q that corresponds to frv * h.
			// compare this with the full-finite-rotation case below.
			h = dMUL(h,REAL (0.5));
			dReal theta = dMUL(k,h);
			q[0] = dCos (theta);
			dReal s = dMUL(sinc (theta),h);
			q[1] = dMUL(frv[0],s);
			q[2] = dMUL(frv[1],s);
			q[3] = dMUL(frv[2],s);
		}
		else
		{
			// make a rotation quaternion q that corresponds to w * h
			dReal wlen = dSqrt (dMUL(b->avel[0],b->avel[0]) + dMUL(b->avel[1],b->avel[1]) + dMUL(b->avel[2],b->avel[2]));
			h = dMUL(h,REAL (0.5));
			dReal theta = dMUL(wlen,h);
			q[0] = dCos (theta);
			dReal s = dMUL(sinc (theta),h);
			q[1] = dMUL(b->avel[0],s);
			q[2] = dMUL(b->avel[1],s);
			q[3] = dMUL(b->avel[2],s);
		}

		// do the finite rotation
		dQuaternion q2;
		dQMultiply0 (q2, q, b->q);
		for (j = 0; j < 4; j++)
			b->q[j] = q2[j];

		// do the infitesimal rotation if required
		if (b->flags & dxBodyFlagFiniteRotationAxis)
		{
			dReal dq[4];
			dWtoDQ (irv, b->q, dq);
			for (j = 0; j < 4; j++)
				b->q[j] += dMUL(h,dq[j]);
		}
	}
	else
	{
		// the normal way - do an infitesimal rotation
		dReal dq[4];
		dWtoDQ (b->avel, b->q, dq);
		for (j = 0; j < 4; j++)
			b->q[j] += dMUL(h,dq[j]);
	}

	// normalize the quaternion and convert it to a rotation matrix
	dNormalize4 (b->q);
	dQtoR (b->q, b->posr.R);

	// notify all attached geoms that this body has moved
	for (dxGeom * geom = b->geom; geom; geom = dGeomGetBodyNext (geom))
		dGeomMoved (geom);
}