Применение обратного CATransform3D к подуровням слоя CALay, который уже был преобразован - PullRequest
6 голосов
/ 09 ноября 2011

Я использую преобразование CATransform3D, чтобы применить псевдо 3D перспективный эффект к виду.

Я использую гироскоп в iPhone 4 для управления параметрами преобразования.

Представление, которое я трансформирую, имеет несколько подпредставлений:

View with subviews

Результат примерно такой:

3D transform in action

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

Моя цель состоит в том, чтобы каждое подпредставление было перпендикулярно суперпредставлению, создавая впечатление, что они «стоят».

Код, который я использую для преобразования:

- (void)update:(NSTimer *)timer
{
    roll = [[[_manager deviceMotion] attitude] roll];
    pitch = [[[_manager deviceMotion] attitude] pitch];
    yaw = [[[_manager deviceMotion] attitude] yaw];

    CALayer *layer = [self.view layer];
    CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;
    rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, -90 * M_PI / 180.0f, 0.0f, 0.0f, 1.0f); // make landscape again  
    rotationAndPerspectiveTransform.m34 = 1.0 / -500; // apply the perspective
    rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, roll, 1.0f, 0.0f, 0.0f);
    rotationAndPerspectiveTransform = CATransform3DRotate(rotationAndPerspectiveTransform, yaw, 0.0f, 0.0f, 1.0f);
    [layer setTransform:rotationAndPerspectiveTransform];       
}

Я попробовал следующий код в попытке инвертировать преобразование, применив поворот перспективы на 90 градусов к подпредставлению вокруг оси Y:

for (UIView *subview in [self.view subviews])
{
    CALayer *sublayer = [subview layer];
//CATransform3D inverseTransformation = [sublayer transform];
CATransform3D inverseTransformation = CATransform3DIdentity;
rotationAndPerspectiveTransform.m34 = 1.0 / -500; // apply perspective
inverseTransformation = CATransform3DRotate(inverseTransformation, 90 * M_PI / 180.0f, 0.0f, 1.0f, 0.0f);
[sublayer setTransform:inverseTransformation];
}

но все, что удается сделать - заставить исчезнуть подвиды. Если я попытаюсь использовать существующее преобразование из слоя с [sublayer transform] и применить к нему 3d-вращение, тогда подпредставления мерцают, но не вращаются.

Мои знания по математике не очень велики, поэтому я не знаю, правильный ли это подход.

Как сделать так, чтобы подпредставления располагались перпендикулярно суперпредставлению?

1 Ответ

1 голос
/ 11 ноября 2011

Я рекомендую не пытаться использовать базовый подход к вычислению каждого отдельного преобразования работы. Кроме того, было бы проще использовать CALayers для каждого из маленьких подвидов вместо объектов более высокого уровня UIView. Базовый подход построения 3D-модели и преобразования всей модели должен работать намного лучше для вас.

Начните с основного слоя, добавьте подслой для каждого из маленьких квадратов, преобразуйте эти подслои в положение, затем ваш метод update:, указанный в вашем вопросе, должен работать, чтобы преобразовать все без изменений. У Джона Блэкберна есть хороший маленький учебник , который должен очень помочь.

...