2013-10-12 3 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

Любая помощь будет оценена по достоинству.

EDIT: Я уже попытался создать кватернион с креста и угол от 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 И: http://imgur.com/PEz1aMc

Любая помощь?

ответ

0

ОК, так что после того, как много проблем, вот рабочий код:

// 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 пи/2: Надеюсь, что это помогает кто-то, я был с это в течение длительного времени.

EDIT: Небольшой комментарий.В этом случае я устанавливаю Y равным 0, поскольку это удаляет ненужный бросок, но считайте, что эта строка является необязательной, поэтому играйте с ней, если хотите. Кроме того, это дает АБСОЛЮТНЫЕ вращения, а не относительно последнего вращения.

0

Прежде всего, вам нужно знать вектор, который определяет плоскость объекта, к которому вы хотите обратиться к зрителю. Скажем, этот вектор «вперед». Обычно этот вектор может быть локальным вектором оси z в пространстве объектов, преобразованным в мировое пространство.

После того, как у вас есть этот вектор вы должны найти де оси вращения:

ось = векторное произведение (NEWDIR, вперед)

и угол поворота:

угол = Экос (DotProduct (NEWDIR , вперед))

где все векторы должны быть унитарными.

Как только у вас есть угол и ось, просто вычислите кватернион, определяющий это вращение. Вы можете сделать это, используя функцию API, такую ​​как: RotationAxis или построение кватерниона с нуля.

Наконец, как только у вас есть кватернион, просто поверните свой объект, используя его.

+0

Вы могли бы видеть мой отредактированный вопрос? –

+0

Проблема в том, что вы всегда используете один и тот же вектор-ориг., И он должен меняться по мере изменения вращения объекта. Вы должны преобразовать этот ориг вектор, используя модель в мировую матрицу. –

+0

Но если я преобразую начало в мировое пространство, мне не нужно будет умножаться с предыдущим вращением, как это было бы относительно предыдущей ориентации? –

Смежные вопросы