コード例 #1
0
ファイル: DxJoint.java プロジェクト: kephale/ode4j
  /**
   * set three orientation rows in the constraint equation, and the corresponding right hand side.
   *
   * @param joint
   * @param info
   * @param qrel
   * @param start_row
   */
  void setFixedOrientation(DxJoint joint, Info2 info, DQuaternion qrel, int start_row) {
    int s = info.rowskip();
    int start_index = start_row * s;
    // 3 rows to make body rotations equal
    info._J[info.J1ap + start_index] = 1;
    info._J[info.J1ap + start_index + s + 1] = 1;
    info._J[info.J1ap + start_index + s * 2 + 2] = 1;
    if (joint.node[1].body != null) {
      info._J[info.J2ap + start_index] = -1;
      info._J[info.J2ap + start_index + s + 1] = -1;
      info._J[info.J2ap + start_index + s * 2 + 2] = -1;
    }

    // compute the right hand side. the first three elements will result in
    // relative angular velocity of the two bodies - this is set to bring them
    // back into alignment. the correcting angular velocity is
    //   |angular_velocity| = angle/time = erp*theta / stepsize
    //                      = (erp*fps) * theta
    //    angular_velocity  = |angular_velocity| * u
    //                      = (erp*fps) * theta * u
    // where rotation along unit length axis u by theta brings body 2's frame
    // to qrel with respect to body 1's frame. using a small angle approximation
    // for sin(), this gives
    //    angular_velocity  = (erp*fps) * 2 * v
    // where the quaternion of the relative rotation between the two bodies is
    //    q = [cos(theta/2) sin(theta/2)*u] = [s v]

    // get qerr = relative rotation (rotation error) between two bodies
    DQuaternion qerr = new DQuaternion();
    DVector3 e = new DVector3();
    if (joint.node[1].body != null) {
      DQuaternion qq = new DQuaternion();
      dQMultiply1(qq, joint.node[0].body._q, joint.node[1].body._q);
      dQMultiply2(qerr, qq, qrel);
    } else {
      dQMultiply3(qerr, joint.node[0].body._q, qrel);
    }
    if (qerr.get0() < 0) {
      qerr.set1(-qerr.get1()); // adjust sign of qerr to make theta small
      qerr.set2(-qerr.get2());
      qerr.set3(-qerr.get3());
    }
    // TZ:
    //		dMULTIPLY0_331( e, joint.node[0].body.posr.R, qerr + 1 );  // @@@ bad SIMD padding!
    DVector3 qerr2 = new DVector3();
    qerr2.set0(qerr.get1());
    qerr2.set1(qerr.get2());
    qerr2.set2(qerr.get3());
    dMultiply0_331(e, joint.node[0].body.posr().R(), qerr2); // @@@ bad SIMD padding!
    double k = info.fps * info.erp;
    info.setC(start_row, 2 * k * e.get0());
    info.setC(start_row + 1, 2 * k * e.get1());
    info.setC(start_row + 2, 2 * k * e.get2());
  }