2016-04-11 6 views
0

В настоящее время я завершаю реализацию камеры, которая функционирует так же, как камера в Maya. Часть, которую я застрял в функциональности падения.Камера Arcball заблокирована при параллельном перемещении вверх

Проблема заключается в том, что функция падения работает нормально, пока положение камеры не параллельна вектору вверх (в настоящее время определено значение (0, 1, 0)). Как только камера станет параллелью с этим вектором (поэтому он смотрит прямо вверх или вниз), камера фиксируется на месте и будет вращаться вокруг вектора вверх, а не продолжать катиться.

Этот вопрос уже задан here, к сожалению, нет действительного решения проблемы. Для справки, я также попробовал обновить вектор вверх, когда я повернул камеру, но результат в результате не является тем, что мне нужно (просмотр рулонов в результате новой ориентации).

Вот код для моей камеры:

using namespace glm; 
// point is the position of the cursor in screen coordinates from GLFW 
float deltaX = point.x - mImpl->lastPos.x; 
float deltaY = point.y - mImpl->lastPos.y; 

// Transform from screen coordinates into camera coordinates 
Vector4 tumbleVector = Vector4(-deltaX, deltaY, 0, 0); 
Matrix4 cameraMatrix = lookAt(mImpl->eye, mImpl->centre, mImpl->up); 
Vector4 transformedTumble = inverse(cameraMatrix) * tumbleVector; 

// Now compute the two vectors to determine the angle and axis of rotation. 
Vector p1 = normalize(mImpl->eye - mImpl->centre); 
Vector p2 = normalize((mImpl->eye + Vector(transformedTumble)) - mImpl->centre); 

// Get the angle and axis 
float theta = 0.1f * acos(dot(p1, p2)); 
Vector axis = cross(p1, p2); 

// Rotate the eye. 
mImpl->eye = Vector(rotate(Matrix4(1.0f), theta, axis) * Vector4(mImpl->eye, 0)); 

Вектор библиотеки я использую GLM. Вот краткий справочник по пользовательским типам используемых здесь:

typedef glm::vec3 Vector; 
typedef glm::vec4 Vector4; 
typedef glm::mat4 Matrix4; 
typedef glm::vec2 Point2; 

mImpl является Pimpl, который содержит следующие элементы:

Vector eye, centre, up; 
Point2 lastPoint; 
+0

Редактировать: добавлена ​​недостающая ссылка на аналогичный вопрос. – Mauricio

ответ

0

Вот что я думаю. Это как-то связано с кардановым замком, который встречается с углами Эйлера (и, следовательно, сферическими координатами).

Если вы превысите минимальные (0, -zoom, 0) или максимумы (0, зум, 0), вам нужно переключить логическое значение. Это логическое значение скажет вам, следует ли вам лечить дельта-положительный или нет.

Это может быть просто вызвано особенностью, поэтому просто ограничьте значения полярного угла между 89,99 ° и -89,99 °.

Ваша проблема может быть решена следующим образом.

Так что если ваша камера находится точно над (0, зум, 0) или ниже (0, -zoom, 0) вашего объекта, чем камера только рулонах. (Я также предполагаю, что ваш объект находится в (0,0,0), а верхний вектор установлен на (0,1,0).)

Может быть какой-то математический трюк, чтобы разрешить это, я бы сделайте это с помощью линейной алгебры.

Вам необходимо ввести новый вектор. Если вы сделаете перекрестный продукт, вы получите вектор камеры. Вектор-вектор = вектор-вектор-вектор-вектор. Представьте, что эти векторы начинаются с (0,0,0), а затем легко, чтобы получить положение вашей камеры, просто выполните это вычитание (0,0,0) - (вектор камеры).

Итак, если вы получаете некоторый треугольник, вы поворачиваетесь вправо-вектор (вокруг вектора вверх) и обновляете его.

Любое влияние deltaX не должно изменять ваш вектор.

Если вы получаете некоторый дельта, вы вращаетесь в направлении вверх-вектора (вокруг правого вектора) и обновляете его. (Это не влияет на правый вектор).

https://en.wikipedia.org/wiki/Rotation_matrix При поворотной матрице от оси и угла вы можете найти важную формулу.

Вы говорите, что ваш вектор, который вы хотите повернуть, и тета - это сумма, которую вы хотите развернуть. Размер тета пропорционален deltaX/Y.

Например: у нас есть вход от deltaX, поэтому мы вращаемся вокруг вектора вверх.

up-vector:= (0,1,0) 

right-vector:= (0,0,-1) 

cam-vector:= (0,1,0) 

theta:=-1*30° // -1 due to the positive mathematical direction of rotation 


R={[cos(-30°),0,-sin(-30°)],[0,1,0],[sin(-30°),0,cos(-30°)]} 

new-cam-vector=R*cam-vector // normal matrix multiplication 

Осталось только сделать следующее: Обновить вектор.

right-vector=camera-vector x up-vector . 
+0

Проблема, с которой я сталкиваюсь, - это не совсем карданный замок. Gimbal lock заставляет вас потерять две степени свободы при вращении, в то время как я теряю только один. Я могу перемещать мышь, и камера по-прежнему будет вращаться вокруг вектора вверх, как ось, но я не смогу продолжать вращаться мимо этого. – Mauricio

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