0

我的手臂、腿、头部和脊椎上有许多陀螺仪(在现实生活中)。每个陀螺仪都有一个唯一的 id,我将其映射到 3d 模型上的身体部位。

每个传感器的陀螺仪数据是一个四元数。

我基本上只是想根据这些数据为我的 3d 模型制作动画。

因此,如果我将头部向右旋转,3d 模型也应该类似地旋转头部。如果我单腿站立,3d 模型也应该这样做。

当使用像 Box2d 这样的 2d 物理引擎时,这就像应用变换一样简单。在 Unity 中执行此操作的等效方法是什么?

编辑:在 Godot 中它真的很简单。

https://docs.godotengine.org/en/3.0/tutorials/3d/working_with_3d_skeletons.html

extends Spatial
var skel
var id

func _ready():
    skel = get_node("skel")
    id = skel.find_bone("upperarm")
    print("bone id:", id)
    var parent = skel.get_bone_parent(id)
    print("bone parent id:", id)
    var t = skel.get_bone_pose(id)
    print("bone transform: ", t)
    set_process(true)

func _process(delta):
    var t = skel.get_bone_pose(id)
    t = t.rotated(Vector3(0.0, 1.0, 0.0), 0.1 * delta)
    skel.set_bone_pose(id, t)
4

1 回答 1

1

在 Unity 中,您可以将四元数旋转应用于变换(覆盖其先前的旋转),如下所示:

float quatX,quatY,quatZ,quatW;

Quaternion quat = new Quaternion(quatX,quatY,quatZ,quatW);
transform.rotation = quat;

如果问题是您的arduino输出右手四元数,并且您需要将它们转换为unity使用的左手四元数,那么stackexchange用户DMGregory的这个答案可能会帮助您在Unity中进行转换:

四元数可以被认为是角轴表示:

quaternion.xyz = sin(angle/2) * axis.xyz
quaternion.w = cos(angle/2)

因此,在两个坐标系之间转换它们可以分为两个步骤:

  1. 将轴映射到新的坐标系。
  2. 如果在左右手坐标之间改变(例如,如果有奇数的轴否定或两者之间的轴交换),否定角度。

    因为这cos(-angle) = cos(angle)sin(-angle) = -sin(angle) 翻转旋转轴相同,否定 x、y 和 z 部分。

以你的具体例子:

         sensor   unity
forward    x        z
up         z        y
right     -y        x

我们可以将这些步骤组合成:

Quaternion ConvertToUnity(Quaternion input) {
    return new Quaternion(
         input.y,   // -(  right = -left  )
        -input.z,   // -(     up =  up     )
        -input.x,   // -(forward =  forward)
         input.w
    );
}
于 2019-09-08T17:25:27.063 回答