• Unity中的旋转和矩阵操作


    Definition for Matrix4x4 is from unity
                    Matrix4x4 matrix = new Matrix4x4();
                    matrix.SetRow(0, new Vector4(m[3], m[6], m[9], m[12] / scaleMultiplier));//经过实际测试前三个都是0,从第四个开始才跟transform中的数据一样,跟openIGTLink官方的协议说明不同,按实际的来,所以从m[3]开始
                    matrix.SetRow(1, new Vector4(m[4], m[7], m[10], m[13] / scaleMultiplier));
                    matrix.SetRow(2, new Vector4(m[5], m[8], m[11], m[14] / scaleMultiplier));
                    matrix.SetRow(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f));

    在Unity中使用Matrix4x4.Inverse(matrix)求得一个矩阵得逆矩阵

    1. IEnumerator ReceiveTransformMessage(byte[] data, string transformName)
    2. {
    3. // Find Game Objects with Transform Name and determine if they should be updated
    4. string objectName;
    5. foreach (GameObject gameObject in GameObjects)
    6. {
    7. // Could be a bit more efficient
    8. if (gameObject.name.Length > 20)
    9. {
    10. objectName = gameObject.name.Substring(0, 20);
    11. }
    12. else
    13. {
    14. objectName = gameObject.name;
    15. }
    16. if (objectName.Equals(transformName) & gameObject.GetComponent().ReceiveTransform)
    17. {
    18. // Transform Matrix starts from byte 58 until 106
    19. // Extract transform matrix
    20. byte[] matrixBytes = new byte[4];
    21. float[] m = new float[15];
    22. for (int i = 0; i < 15; i++)
    23. {
    24. Buffer.BlockCopy(data, 58 + i * 4, matrixBytes, 0, 4);
    25. if (BitConverter.IsLittleEndian)
    26. {
    27. Array.Reverse(matrixBytes);
    28. }
    29. m[i] = BitConverter.ToSingle(matrixBytes, 0);
    30. // Debug.Log($"m{i},is {m[i]}");
    31. }
    32. // Slicer units are in millimeters, Unity is in meters, so convert accordingly
    33. // Definition for Matrix4x4 is from unity
    34. Matrix4x4 matrix = new Matrix4x4();
    35. /* matrix.SetRow(0, new Vector4(m[0], m[3], m[6], m[9] / scaleMultiplier));
    36. matrix.SetRow(1, new Vector4(m[1], m[4], m[7], m[10] / scaleMultiplier));
    37. matrix.SetRow(2, new Vector4(m[2], m[5], m[8], m[11] / scaleMultiplier));*/
    38. matrix.SetRow(0, new Vector4(m[3], m[6], m[9], m[12] / scaleMultiplier));//经过实际测试前三个都是0,从第四个开始才跟transform中的数据一样,跟openIGTLink官方的协议说明不同,按实际的来,所以从m[3]开始
    39. matrix.SetRow(1, new Vector4(m[4], m[7], m[10], m[13] / scaleMultiplier));
    40. matrix.SetRow(2, new Vector4(m[5], m[8], m[11], m[14] / scaleMultiplier));
    41. matrix.SetRow(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
    42. Matrix4x4 IJKToRAS = new Matrix4x4();
    43. IJKToRAS.SetRow(0, new Vector4(-1.0f, 0, 0, 0));
    44. IJKToRAS.SetRow(1, new Vector4(0, -1.0f, 0, 2));
    45. IJKToRAS.SetRow(2, new Vector4(0, 0, 1.0f, 0));
    46. IJKToRAS.SetRow(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
    47. //在Unity中使用Matrix4x4.Inverse(matrix)求得一个矩阵得逆矩阵
    48. Matrix4x4 matrixRAS = matrix * IJKToRAS;//暂时没用上
    49. Vector3 translation = matrix.GetColumn(3);//上面matrix.SetRow已经转为以m为单位了
    50. tro = new Vector3(m[12], m[13], m[14]);//平移记录给全局变量,继续保持以mm为单位,为了在NDI设备中方位合成计算方便
    51. rro[0, 0] = matrix.m00; rro[0, 1] = matrix.m01; rro[0, 2] = matrix.m02; //旋转记录给全局变量
    52. rro[1, 0] = matrix.m10; rro[1, 1] = matrix.m11; rro[1, 2] = matrix.m12;//旋转记录给全局变量
    53. rro[2, 0] = matrix.m20; rro[2, 1] = matrix.m21; rro[2, 2] = matrix.m22;//旋转记录给全局变量
    54. if (tibiacontrolclass.targetflag)//如果ControllerTibia中点了button,tibiacontrolclass.targetflag变为true,表面现象是显示target plane位置
    55. {
    56. // gameObject.transform.localPosition = new Vector3(-translation.x + TrackerOriginPosition.cubeposition.x, translation.y + TrackerOriginPosition.cubeposition.y, translation.z + TrackerOriginPosition.cubeposition.z);
    57. gameObject.transform.localPosition = TrackerOriginPosition.cuberotation * new Vector3(translation.y, translation.z, -translation.x) + TrackerOriginPosition.cubeposition;
    58. ReferenceInGlass = new Vector3(translation.y, translation.z, -translation.x);//从tracker设备坐标系下转换到glass坐标系下,标记到全局变量给ReceivePointMessage函数用
    59. Debug.Log($"Tracker is {TrackerOriginPosition.cubeposition};Reference is {-translation.x},{translation.y},{translation.z};sum is {gameObject.transform.localPosition}");
    60. }
    61. else
    62. {
    63. gameObject.transform.localPosition = new Vector3(-translation.x, translation.y, translation.z);
    64. Debug.Log($"Reference is {gameObject.transform.localPosition}");
    65. }
    66. // gameObject.transform.localPosition = new Vector3(-translation.x, translation.y, translation.z);
    67. // Debug.Log($"Reference is {gameObject.transform.localPosition}");
    68. Vector3 eulerAngles = matrix.rotation.eulerAngles;
    69. gameObject.transform.localRotation = Quaternion.Euler(eulerAngles.x, -eulerAngles.y, -eulerAngles.z);
    70. // Debug.Log($"Rotation is {eulerAngles.x},{eulerAngles.y},{eulerAngles.z}");
    71. }
    72. else if (objectName.Equals(transformName) & gameObject.GetComponent().ReceiveImage)//官方协议是错误的,因此图片传输用OpenIGTLink没法进行下去。
    73. {
    74. }
    75. }
    76. // Place this inside the loop if you only want to perform one loop per update cycle
    77. yield return null;
    78. }

  • 相关阅读:
    一点C知识:数据类型和内存地址。
    HHDBCS监控功能
    2594. 修车的最少时间
    大数据之力:从数据湖到数据智能的升级之路
    实战|轻松用 Python 开发一个简单有趣的聊天小程序
    Redis实战之年会抽奖
    零样本文本分类应用:基于UTC的医疗意图多分类,打通数据标注-模型训练-模型调优-预测部署全流程。
    【算法】剑指offer-删除链表中重复的节点&&最小栈
    企业防护墙管理,有什么防火墙管理工具?
    【android】install android NDK
  • 原文地址:https://blog.csdn.net/weixin_44345862/article/details/126289106