Есть несколько вопросов по этому поводу в Stack Overflow, но большинство используют Quaternions, и я ищу что-то, чего нет. И этот вопрос существует во всем Интернете, но на удивление трудно найти простой пример в коде. Я ищу решение C / C ++ или GLSL / Metal для матрицы вращения для преобразования одного вектора в другой. Я нашел это, которое, кажется, отвечает на вопрос: http://www.j3d.org/matrix_faq/matrfaq_latest.html#Q38
Однако на практике это не работает для меня. При этом я получаю правильные преобразования под углами в девяносто градусов (то есть, трансформируя от 0,0,1 до 0,1,0), но между ними он поворачивается в неправильном направлении. Вот код, который я использую - кто-нибудь видит, что с ним не так?
В этом случае я всегда выполняю преобразование из фиксированной начальной нормали (0,0,1).
// matrix to rotate from (0,0,1) to specified direction
float4x4 directionMatrix(float3 direction) {
float3 normal = float3(0.0,0.0,1.0);
float3 V = normalize(cross(normal, direction));
float phi = acos(dot(normal,direction));
float rcos = cos(phi);
float rsin = sin(phi);
float4x4 M;
M[0].x = rcos + V.x * V.x * (1.0 - rcos);
M[1].x = V.z * rsin + V.y * V.x * (1.0 - rcos);
M[2].x = -V.y * rsin + V.z * V.x * (1.0 - rcos);
M[3].x = 0.0;
M[0].y = -V.z * rsin + V.x * V.y * (1.0 - rcos);
M[1].y = rcos + V.y * V.y * (1.0 - rcos);
M[2].y = -V.x * rsin + V.z * V.y * (1.0 - rcos);
M[3].y = 0.0;
M[0].z = V.y * rsin + V.x * V.z * (1.0 - rcos);
M[1].z = -V.x * rsin + V.y * V.z * (1.0 - rcos);
M[2].z = rcos + V.z * V.z * (1.0 - rcos);
M[3].z = 0.0;
M[0].w = 0.0;
M[1].w = 0.0;
M[2].w = 0.0;
M[3].w = 1.0;
return M;
}
Я попытался транспонировать это на тот случай, если в оригинальной статье использовалось мое противоположное большинство строк, но это не помогло.
РЕДАКТИРОВАТЬ: Проблема здесь оказалась в том, что этот код работает для левосторонней системы координат, где моя правша. Таким образом, чтобы это сработало, вам просто нужно умножить фи на -1. Я также отредактировал код, чтобы добавить нормализацию кросс-вектора, как это предлагается в комментариях.