HapticPlugin / HPGE-wrappers

Haptic Plugin for Game Engines
Other
16 stars 6 forks source link

Set object rotation and position operations #5

Closed Manurocker95 closed 1 year ago

Manurocker95 commented 1 year ago

If you still have the DLL code or at least, the knowhow, how did you manage the Unity to Chai3D euler angles transformation? These operations are not exposed and I’m facing troubles with the unity local rotation -> chai3D rotation. When using cQuaterion (wxyz) -> toRotMatrix and applying this matrix, the rotation is not the same as it is in unity. HPGE seems to manage euler angles instead and convert them into chai3D workspace angles, so… how?

I tested sending the eulerAngles (Degrees)-> rotateExtrinsicEulerAnglesDeg(objectRotation[2], -1 objectRotation[0], -1 objectRotation[1], C_EULER_ORDER_XYZ), but doesn't seem to rotate the object properly. I also tried to convert them to radians by M_PI / 180 each angle-> use rotateExtrinsicEulerAnglesRad(objectRotation[2], -1 objectRotation[0], -1 * objectRotation[1], C_EULER_ORDER_XYZ), but no luck either. Any idea?

In addition, is the position handle by:

outX = -1 * inZ OutY = inX OutZ = inY

??

and I know I can ask for the dll code by mailing ti the one in the copyright section in license, but if you could help me, it would awesome 🥰

Manurocker95 commented 1 year ago

It seems I'm missing something but I can't get what exactly. The provided DLL (here) works as expected for fixed meshes (animated meshes don't work), but at least rotation are properly set. @nico202 any idea? <3

nico202 commented 1 year ago

Thanks for tagging me as I did not get the notification. I can have a look at the dll source and copy some parts here, as I don't have time to look at your problem in details. Do you know which dll exported function code you need?

Looking at rotations, I see

    void set_world_rotation_eulerXYZ (const double x,
                     const double y,
                     const double z) {
      chai3d::cMatrix3d m;
      chai3d::cQuaternion q;
      m.setExtrinsicEulerRotationDeg(x, y, z, chai3d::C_EULER_ORDER_XYZ);
      q.fromRotMat(m);
      rotation [0] = q.w;
      rotation [1] = q.x;
      rotation [2] = q.y;
      rotation [3] = q.z;
    }

and there's also

  int mirror_quat [4] = { 1, 1, 1, 1 };
  int order [3] = { 0, 1, 2 };
  double rotation [4] = { 1.0, 0.0, 0.0, 0.0 };

 void RotToChai (const double inputRotation [4], chai3d::cQuaternion* out) {
    double outputRot [4];

    outputRot [0] = mirror_quat [0] * inputRotation [0];

    outputRot [order [0] + 1] = mirror_quat [1] * inputRotation [1];
    outputRot [order [1] + 1] = mirror_quat [2] * inputRotation [2];
    outputRot [order [2] + 1] = mirror_quat [3] * inputRotation [3];

    auto tmp = chai3d::cQuaternion (outputRot [0],
                    outputRot [1],
                    outputRot [2],
                    outputRot [3]);

     auto rot = chai3d::cQuaternion (rotation [0],
                        rotation [1],
                        rotation [2],
                        rotation [3]);

     rot.invert ();

     tmp.dot (rot);

    out -> w = tmp.w;
    out -> x = tmp.x;
    out -> y = tmp.y;
    out -> z = tmp.z;
  }

Let me know if those are of any help

Manurocker95 commented 1 year ago

Thanks for tagging me as I did not get the notification. I can have a look at the dll source and copy some parts here, as I don't have time to look at your problem in details. Do you know which dll exported function code you need?

Looking at rotations, I see

    void set_world_rotation_eulerXYZ (const double x,
                   const double y,
                   const double z) {
      chai3d::cMatrix3d m;
      chai3d::cQuaternion q;
      m.setExtrinsicEulerRotationDeg(x, y, z, chai3d::C_EULER_ORDER_XYZ);
      q.fromRotMat(m);
      rotation [0] = q.w;
      rotation [1] = q.x;
      rotation [2] = q.y;
      rotation [3] = q.z;
    }

and there's also

  int mirror_quat [4] = { 1, 1, 1, 1 };
  int order [3] = { 0, 1, 2 };
  double rotation [4] = { 1.0, 0.0, 0.0, 0.0 };

 void RotToChai (const double inputRotation [4], chai3d::cQuaternion* out) {
    double outputRot [4];

    outputRot [0] = mirror_quat [0] * inputRotation [0];

    outputRot [order [0] + 1] = mirror_quat [1] * inputRotation [1];
    outputRot [order [1] + 1] = mirror_quat [2] * inputRotation [2];
    outputRot [order [2] + 1] = mirror_quat [3] * inputRotation [3];

    auto tmp = chai3d::cQuaternion (outputRot [0],
                  outputRot [1],
                  outputRot [2],
                  outputRot [3]);

     auto rot = chai3d::cQuaternion (rotation [0],
                      rotation [1],
                      rotation [2],
                      rotation [3]);

     rot.invert ();

     tmp.dot (rot);

    out -> w = tmp.w;
    out -> x = tmp.x;
    out -> y = tmp.y;
    out -> z = tmp.z;
  }

Let me know if those are of any help

I got it working before I saw your reply but this will be definitely useful if someone needs it in a future.

Btw, the The rotation unity->chai3d I was using was correct as the "mirror world" is 1,-1,-1, to recover the euler angles I ended working with maths:

void GetRadianAnglesFromMatrix3D(chai3d::cMatrix3d matrix, double _rotation[]) { auto col0 = matrix.getCol0(); auto col1 = matrix.getCol1(); auto col2 = matrix.getCol2();

double s2 = col2.x();
double c2 = std::sqrt(1 - std::pow(s2, 2));

double c1 = col2.z() / c2;
double s1 = col2.y() / (-c2);

double s3 = col1.x() / (-c2);
double c3 = col0.x() / (c2);

double a_angle1 = atan2(s1, c1);
double a_angle2 = atan2(s2, c2);
double a_angle3 = atan2(s3, c3);

_rotation[0] = a_angle1;
_rotation[1] = a_angle2 * -1;
_rotation[2] = a_angle3 * -1;

}

We can close this! :)