Я делаю 2D-приложение OpenGL на iPad. И мне нужно реализовать щипок/масштабирование.
Я хочу переместить камеру в плоскости (x,y)
и управлять значением камеры x,y
и z
жестом щипка.
Каждый кадр в методе update
я делаю матрицу вида (камеру) такой
lookAt = GLKMatrix4MakeLookAt(view_x, view_y, view_z, view_x, view_y, 0.0f, 0.0f, 1.0f, 0.0f);
где view_x, view_y и view_z определяются при запуске программы следующим образом: view_x = view_y = 0.0f; view_z = kStartZoom;
kStartZoom равно 3000. Таким образом, камера находится в точке (0,0,3000) и смотрит на (0,0,0)
Практически работающее решение для обработки событий захвата:
- (IBAction) handlePinch:(UIPinchGestureRecognizer*) recognizer {
switch (recognizer.state)
{
case UIGestureRecognizerStateBegan:
{
if (recognizer.numberOfTouches == 2)
{
prevTouchOrigin1 = [recognizer locationOfTouch:0 inView:self.view];
prevTouchOrigin2 = [recognizer locationOfTouch:1 inView:self.view];
}
} break;
case UIGestureRecognizerStateChanged:
{
if (recognizer.numberOfTouches == 2)
{
CGFloat newDistance, oldDistance;
oldDistance = distanceBetweenTwoCGPoints(&prevTouchOrigin1, &prevTouchOrigin2);
currTouchOrigin1 = [recognizer locationOfTouch:0 inView:self.view];
currTouchOrigin2 = [recognizer locationOfTouch:1 inView:self.view];
newDistance = distanceBetweenTwoCGPoints(&currTouchOrigin1, &currTouchOrigin2);
if (newDistance == 0 || oldDistance == 0)
{
scaleFactor = 1;
} else {
scaleFactor = oldDistance / newDistance;
}
GLfloat check = view_z * scaleFactor;
if (check < kMinZoom || check > kMaxZoom)
return;
view_z *= scaleFactor;
// translate
// formula: newPos = currTouchOrigin + (objectOrigin - prevTouchOrigin) * scaleFactor
static CGPoint translationDelta;
GLfloat z_ratio = view_z_old / view_z;
newPos1.x = currTouchOrigin1.x - ((prevTouchOrigin1.x - view_x) * scaleFactor);
newPos1.y = currTouchOrigin1.y - ((prevTouchOrigin1.y - view_y) * scaleFactor);
newPos2.x = currTouchOrigin2.x - ((prevTouchOrigin2.x - view_x) * scaleFactor);
newPos2.y = currTouchOrigin2.y - ((prevTouchOrigin2.y - view_y) * scaleFactor);
midpoint = CGPointMidpoint(&newPos1, &newPos2);
translationDelta = CGPointMake(midpoint.x - view_x, midpoint.y - view_y);
view_x += translationDelta.x;
view_y -= translationDelta.y;
prevTouchOrigin1 = currTouchOrigin1;
prevTouchOrigin2 = currTouchOrigin2;
}
} break;
case UIGestureRecognizerStateEnded:
{
} break;
default :
{
}
}}
Почти рабочий.
У меня больше движения по x, y, чем мне нужно, поэтому камера вертится.
Проблема в том, что я не применяю некоторые преобразования из координат экрана в мировые координаты?
В чем может быть проблема? Другие примеры, которые я рассматривал, изменяют только положение камеры в зависимости от расстояния между предыдущим и последним положениями пальцев, что я и делаю.