7

これは大学での私の最初のグラフィック科目であり、実装の一部が機能していません。関節を適切に描画することはできますが、関節の間に「骨」を入れる関数を書こうとしています。この時点では、骨は四角柱に変換された単なる立方体ですが、後でブレンダーなどから適切なモデルを導入しようとします。

私の悩みはローテーションです。約 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;
4

2 に答える 2

3

ボーンの向きについては、次を確認してください。

skeleton.BoneOrientations[joint.JointType]

それはあなたに BoneOrientation クラスを与えます

http://msdn.microsoft.com/en-us/library/microsoft.kinect.boneorientation.aspx

そこから、ワールド空間または親ボーン空間 (スキニング用) のいずれかで、Quaternion/Matrix として回転を行うことができます。

また、次を使用します。

new Quaternion(0)

これは 0 ベクトルであり、回転に有効なクォータニオンではありません。次を使用してください:

Quaternion.Identity;

(0,0,0,1)になります

于 2012-09-28T14:03:32.897 に答える
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()))

詳細については、MSDNページを参照してください。

于 2013-01-13T02:48:01.360 に答える