0

私はここでちょっとした問題を抱えていて、助けてもらいたいのです。オブジェクトをプレーヤーに追従させることができる回転を見つけようとしています(常に直面しています)。私は最初に外積、ドット、回転を試みましたが、それは正しく機能しません。次に、それを 2 つの回転 (ヨーとピッチ) とロックアウト ロールに分解しました。現在は機能していますが、一部の方向に対してのみです (円の 4 分の 1 を信じていますが、それよりも小さい可能性があります)。これは私の現在のコードです:

    XMVECTOR newDir = Vec3DtoDX((Player->Position - InternalEntity->Position).getNormalized());
    XMVECTOR orig = XMVectorSet(0,0,1,0);

    XMVECTOR xNewDir,xOrigDir,yNewDir,yOrigDir;
    xOrigDir = XMVectorSet(0,1,0,0); // (y,z)
    yOrigDir = XMVectorSet(0,1,0,0); // (x,z)

    xNewDir = XMVectorSet(newDir.m128_f32[1],newDir.m128_f32[2],0,0);
    yNewDir = XMVectorSet(newDir.m128_f32[0],newDir.m128_f32[2],0,0);

    float xAngle = XMVector2AngleBetweenVectors(xNewDir,xOrigDir).m128_f32[0];
    float yAngle = XMVector2AngleBetweenVectors(yNewDir,yOrigDir).m128_f32[0];

    XMVECTOR rotDX = XMQuaternionRotationRollPitchYaw(xAngle,yAngle,0);
    PxQuat rot = VecDXto4D<PxQuat>(rotDX);

Z軸に近いオブジェクトに直面すると、ここで正しく機能します http://imgur.com/oNNNRXo

さらに動かすと、次のようになります: http://imgur.com/xFIEzdg

どんな助けでも大歓迎です。

編集:私はすでにクロスからクォータニオンを作成し、ドットの acos から角度を作成しようとしました。実は初めてでしたが。問題は、それが正しく機能しないことです。これが私がやっている方法です:

    PxVec3 newDir = (Player->Position - InternalEntity->Position).getNormalized();

    PxVec3 orig(0,0,1);

    PxVec3 axis = newDir.cross(orig);

    float angle = XMVector3AngleBetweenVectors(Vec3DtoDX(newDir),Vec3DtoDX(orig)).m128_f32[0];

    PxQuat rot(angle,axis);

ここで、XMVector3AngleBetweenVectors は次のとおりです。

  XMVECTOR L1 = XMVector3ReciprocalLength(V1);
  XMVECTOR L2 = XMVector3ReciprocalLength(V2);

  XMVECTOR Dot = XMVector3Dot(V1, V2);

  L1 = XMVectorMultiply(L1, L2);

  XMVECTOR CosAngle = XMVectorMultiply(Dot, L1);
  CosAngle = XMVectorClamp(CosAngle, g_XMNegativeOne.v, g_XMOne.v);

  return XMVectorACos(CosAngle);

これにより、次の画面が表示されます: http://imgur.com/vlMPAwG And : http://imgur.com/PEz1aMc

何か助けはありますか?

4

2 に答える 2

0

OK、多くのトラブルの後、ここに動作するコードがあります:

// Using PxExtendedVec3 to use double
// For ground enemies, just flatten the positions across the Up vector ( set y to 0  in this case )
PxExtendedVec3 newDir = Vec3Dto3D<PxExtendedVec3>(Vec3Dto3D<PxExtendedVec3>(Player->Position) - Vec3Dto3D<PxExtendedVec3>(InternalEntity->Position));
newDir.y = 0;
newDir.normalize();
PxExtendedVec3 orig(0,0,1);
PxExtendedVec3 axis = newDir.cross(orig);

double angle = -asin(_Core::Clamp<double>(axis.magnitude(),-1.0,1.0));
axis.normalize();
// Compensate the [-pi/2,pi/2] range of asin
if(newDir.dot(Vec3Dto3D<PxVec3>(orig)) < 0.0)
    angle = XM_PIDIV2 - angle + XM_PIDIV2;//angle += XM_PI/2.0;

PxQuat rot(angle,Vec3Dto3D<PxVec3>(axis));

PxExtendedVec3 は double のベクトルで、XM_PIDIV2 は pi / 2 です: これが誰かの役に立てば幸いです。

編集:少しコメント。この場合、Y を 0 に設定します。これにより、不要なロールが削除されますが、その行はオプションであると考えられるため、必要に応じて試してみてください。また、これにより、最後の回転に関連するのではなく、絶対的な回転が得られます。

于 2013-10-23T18:30:42.967 に答える
0

まず、ビューアーに向けたいオブジェクトの平面を定義するベクトルを知る必要があります。このベクトルが「前方」であるとしましょう。通常、このベクトルはワールド空間に変換されたオブジェクト空間のローカル z 軸ベクトルです。

このベクトルを取得したら、回転軸を見つける必要があります。

axis = CrossProduct( newDir, forward )

および回転角度:

angle = acos( DotProduct( newDir, forward ) )

ここで、すべてのベクトルはユニタリでなければなりません。

角度と軸を取得したら、この回転を定義するクォータニオンを計算するだけです。RotationAxis のような API 関数を使用するか、ゼロからクォータニオンを構築することができます。

最後に、クォータニオンを取得したら、それを使用してオブジェクトを回転させます。

于 2013-10-12T08:26:10.713 に答える