Вращение объекта OpenGL ES с помощью GLKit

Я пытаюсь повернуть объект OpenGL в iOS с помощью сенсорного ввода, но у меня возникают проблемы. Я захватываю пользовательские прикосновения здесь:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
    UITouch *touch = [touches anyObject];
    startPoint = [touch locationInView:self.view];
    }

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
   {
   UITouch *touch = [touches anyObject];
   CGPoint point = [touch locationInView:self.view];
   dx = point.y - startPoint.y;
   dy = point.x - startPoint.x;
   startPoint = point;
   }

Я использую это в своей функции обновления для выполнения поворота. Прямо сейчас я просто пытаюсь вращаться слева направо, когда я касаюсь слева направо, а затем спереди назад, когда я иду вверх и вниз. Однако я получаю странное комбинированное вращение. Вот код:

- (void)update
   {    
   float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
   GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);

   self.effect.transform.projectionMatrix = projectionMatrix;

   GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -3.5f);
   modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, -1, startPoint.x, startPoint.y, 0.0f);
   dx = dy =0;
   self.effect.transform.modelviewMatrix = modelViewMatrix;
   }

person Adam    schedule 05.01.2012    source источник
comment
не знаю, как это сделать в GLK, но переводите ли вы его в исходное положение перед поворотом (и обратно после)?   -  person 最白目    schedule 05.01.2012
comment
Нет, я не думаю, что я делаю это. Объект не уходит с экрана, он вращается, просто не так, как я хочу. Должен ли я делать это?   -  person Adam    schedule 05.01.2012
comment
в OpenGL вы сначала переводите (= сдвигаете) объект в исходное положение (0,0,0), затем поворачиваете его, а затем переводите обратно в предполагаемое положение. OpenGL всегда вращается вокруг начала координат, если вы не переместите его туда, ваш объект будет вращаться вокруг начала координат, но не будет вращаться, как ожидалось, вокруг себя.   -  person 最白目    schedule 05.01.2012
comment
Примечание. Если вы, например, хотите вращаться только вокруг оси Y, достаточно перевести его на Y = 0 и т. д. Надеюсь, я смогу вам помочь.   -  person 最白目    schedule 05.01.2012
comment
Я уже перевожу его в ориджин на самом деле. Модель GLKMatrix4ViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -3.5f);   -  person Adam    schedule 05.01.2012


Ответы (2)


Потому что вы говорите ему вращаться как по x, так и по y :)

Попробуй это :

modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, startPoint.x, 1.0f, 0.0f, 0.0f);

Это повернет startPoint.x в радианах вокруг оси X.

Вы можете вращаться вокруг любой оси, которую хотите, изменив последние 3 параметра (т.е. 0,1,0 будет вращаться вокруг оси Y, 1,1,0 будет вращаться вокруг оси на 45° между x и y).

NB Спасибо @Marcelo Cantos за разъяснение :)

person deanWombourne    schedule 05.01.2012
comment
Спасибо за ответ. Я понимаю ваши рассуждения, и это имеет смысл. Я попробовал, но теперь он вообще не двигается. - person Adam; 05.01.2012
comment
Я понял. Вы были на правильном пути. Я точно не знаю, почему то, что у меня было, до сих пор не работает, но я нашел кое-что, что работает. Вместо одновременного выполнения обоих движений с помощью GLKMatrix4Rotate() я использую GLKMatrix4RotateX() и GLKMatrix4RotateY(). - person Adam; 05.01.2012
comment
Извините, я неправильно прочитал сигнатуру метода и перепутал оси/радианы - извините! Смотрите мое редактирование для лучшего ответа! - person deanWombourne; 05.01.2012
comment
@deanWombourne: Ваше объяснение вводит в заблуждение. Создается впечатление, что, например, установка последнего параметра на 1.0f будет вращать startPoint.x вокруг оси x и оси z (что бы это ни повлекло за собой). Повороты всегда выражаются вокруг одной оси, определяемой произвольным вектором. В этом случае ось вращения совпадает с осью x. Если бы вы действительно изменили последний аргумент на 1.0f, вы бы получили один поворот вокруг вектора, который составляет 45° между осями x и z (а не два поворота). - person Marcelo Cantos; 12.01.2012
comment
@Marcelo Cantos - О, я не думал, что это так читают; Я отредактировал свой ответ :) Спасибо. - person deanWombourne; 12.01.2012

Согласно deanWombourne, вы используете GLKMatrix4Rotate неправильно. Когда вы выполняете:

GLKMatrix4Rotate(modelViewMatrix, -1, startPoint.x, startPoint.y, 0.0f);

Вы поворачиваете -1 радиан вокруг оси (startPoint.x, startPoint.y, 0.0f). Это больше похоже на то, что вы хотите повернуть радианы startPoint.x вокруг (1, 0, 0) и радианы startPoint.y вокруг (0, 1, 0). Так, например:

modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, startPoint.x, 1.0f, 0.0f 0.0f);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, startPoint.y, 0.0f, 1.0f 0.0f);

Или вы, вероятно, захотите разделить startPoint.x и startPoint.y, потому что это будет сверхчувствительным к прикосновениям.

У него также будут некоторые проблемы с блокировкой подвеса — в основном потому, что если вы сначала вращаетесь вокруг x, то ось y не обязательно будет там, где вы думаете, и если вы сначала вращаете вокруг y, то ось x не обязательно там, где вы думаете. Это. Это то, что вас беспокоит?

person Tommy    schedule 05.01.2012
comment
Спасибо. Теперь я вижу более ясно. Я заметил, что проблема с startPoint очень отзывчива. Я делю его вниз. Я бы хотел, чтобы модель двигалась, как ваш палец. Если вы двигаетесь под углом, я бы хотел, чтобы он вращался вверх и назад. Мой отдельный код с использованием RotateX и RotateY, похоже, работает именно так. Я не могу понять, как заставить его перестать щелкать пальцем. - person Adam; 05.01.2012