2013-10-12 31 views
0

我在這裏遇到了一些問題,希望得到一些幫助。我試圖找到一個旋轉角度,讓我能夠讓對象跟隨玩家(始終面對它)。 我第一次嘗試做交叉產品,點和旋轉,但只是不能正常工作。 然後我開始將它分解爲兩個旋轉(偏航和俯仰)和鎖定滾動。它現在可行,但僅適用於某些方向(我相信四分之一圓,但可能更少)。 這是我當前的代碼:關注3D中的對象

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

任何幫助將不勝感激。

編輯: 我已經嘗試從十字架和點的角度創建四元數。事實上,這是我第一次。問題是它無法正常工作。下面是我如何做它:

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 人和:http://imgur.com/PEz1aMc

任何幫助嗎?

回答

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是雙打的載體,XM_PIDIV2是PI/2: 希望這可以幫助別人,我已經與這很長一段時間。

編輯:有點評論。在這種情況下,我將Y設置爲0,因爲這會消除一些不需要的滾動,但請考慮該行是可選的,因此如果喜歡,請使用它。此外,這會產生ABSOLUTE旋轉,而不是相對於上一次旋轉。

0

首先,您必須知道定義要面向觀察者的對象平面的矢量。假設這個向量是「向前」的。通常這個矢量可以是轉換到世界空間的物體空間中的局部z軸向量。

一旦有了這種矢量你必須找到解旋轉軸:

軸=交叉積(NEWDIR,向前)

和旋轉角度:

角= ACOS(DotProduct(NEWDIR ,向前))

其中所有載體必須是單一的。

一旦你有角度和軸,只需計算定義這個旋轉的四元數。您可以使用以下API函數來完成此操作:RotationAxis或從頭開始構建四元數。

最後,一旦你有四元數,只需旋轉你的對象使用它。

+0

你能看到我編輯的問題嗎? –

+0

問題是,您始終使用相同的原始矢量,並且應該隨着對象的旋轉更改而改變。您必須使用模型將此原始矢量轉換爲世界矩陣。 –

+0

但是,如果我將原始數據轉換爲世界空間,是否需要與先前的旋轉相乘,因爲它將相對於之前的方向? –