C# 使用Kinect SDK创建完整的三维骨架

C# 使用Kinect SDK创建完整的三维骨架,c#,rotation,kinect,quaternions,sharpdx,C#,Rotation,Kinect,Quaternions,Sharpdx,这是我在uni的第一门图形课程,实现的某些部分对我来说根本不起作用。我可以正确地绘制关节,但我正在尝试编写一个函数,在关节之间插入“骨骼”。在这一点上,骨骼只是被转换成矩形棱柱体的立方体,稍后我将尝试从blender或其他方面介绍合适的模型 我的问题是旋转。大约5个小时后,我和我的搭档开始工作,但只要你把胳膊或腿伸出来,立方体就会扭曲,看起来很奇怪。任何帮助都将不胜感激。下面是尝试绘制骨骼的函数 private void DrawBone(Skeleton skeleton, JointType

这是我在uni的第一门图形课程,实现的某些部分对我来说根本不起作用。我可以正确地绘制关节,但我正在尝试编写一个函数,在关节之间插入“骨骼”。在这一点上,骨骼只是被转换成矩形棱柱体的立方体,稍后我将尝试从blender或其他方面介绍合适的模型

我的问题是旋转。大约5个小时后,我和我的搭档开始工作,但只要你把胳膊或腿伸出来,立方体就会扭曲,看起来很奇怪。任何帮助都将不胜感激。下面是尝试绘制骨骼的函数

private void DrawBone(Skeleton skeleton, JointType jointType0, JointType jointType1)
{
    Joint joint0 = skeleton.Joints[jointType0];
    Joint joint1 = skeleton.Joints[jointType1];

    // If we can't find either of these joints, exit
    if (joint0.TrackingState == JointTrackingState.NotTracked ||
        joint1.TrackingState == JointTrackingState.NotTracked)
    {
        return;
    }

    // Don't draw if both points are inferred
    if (joint0.TrackingState == JointTrackingState.Inferred &&
        joint1.TrackingState == JointTrackingState.Inferred)
    {
        return;
    }

    // We assume all drawn bones are inferred unless BOTH joints are tracked
    if (joint0.TrackingState == JointTrackingState.Tracked && joint1.TrackingState == JointTrackingState.Tracked)

        //jointvector(joint) takes a joint and returns a Vector2 with its position data, with the z invtred to work properly with directx11
        Vector3 bonevector = Vector3.Subtract(jointVector(joint0), jointVector(joint1));
        //cubevector is supposed to describe the initial vector of a cube centred at (0,0,0) with a side length of 2. A fair amount of guesswork has gone into this bit.
        Vector3 cubevector = new Vector3(0, 2, 0);
        //midpoint of two joints
        Vector3 transTest = Vector3.Divide(Vector3.Add(jointVector(joint0),jointVector(joint1)), 2);
        //divide by two because our original cube has side length 2
        float scaleFactor = Math.Abs(bonevector.Length() / cubevector.Length());

        //we haven't been taught quaternions in class or anything, but after a fair while searching for similar problems they seemed like the go-to option for rotations.
        world = Matrix.Transformation(new Vector3(0, 0, 0), new Quaternion(0), new Vector3(0.05f, scaleFactor, 0.05f), new Vector3(0, 0, 0), new Quaternion(Vector3.Cross(cubevector, bonevector), (float)Math.Acos(Vector3.Dot(bonevector, cubevector))), transTest);     

        //view and proj are defined elsewhere and are working fine, it's just the world that is being lame         
        worldViewProj = world * view * proj;
        worldViewProj.Transpose();
        sDXdata.context.UpdateSubresource(ref worldViewProj, sDXdata.constantBuffer);
        //36 vertices of the cube (two triangles per face) defined elsewhere
        sDXdata.context.Draw(36, 0);
        return;

有关骨骼方向,请选中:

skeleton.BoneOrientations[joint.JointType]
它会给你一堂骨骼定向课

从那里,可以在世界空间或父骨骼空间(用于蒙皮)中将旋转设置为四元数/矩阵

您还可以使用:

new Quaternion(0)
这是0向量,不是用于旋转的有效四元数,请使用:

Quaternion.Identity;

这将是(0,0,0,1)

虽然这是前一段时间提出的问题,但我认为在计算角度时也有一个错误。你有:

(float)Math.Acos(Vector3.Dot(bonevector, cubevector)
我认为你需要:

(float)Math.Acos(Vector3.Dot(bonevector, cubevector) / (bonevector.Length() *
cubevector.Length()))
这是一个很好的数学小例子。您也可以将它们设置为单位向量,这样它们的长度为1,而不必进行除法:

(float)Math.Acos(Vector3.Dot(bonevector.Normalize(), cubevector.Normalize()))

查看该页面了解更多信息。

嗨,文斯,你有过这样的经历吗?有兴趣了解如何在3D中显示模型。