2012-04-10 25 views
3

Ich versuche, eine 3D-Benutzeroberfläche mit CALayer 3D-Transformationen zu erstellen. Ich habe die grundlegende Technik dafür herausgefunden, aber meine Echtzeitleistung ist ziemlich schlecht. Insbesondere sollte der Benutzer in der Lage sein, die Schnittstelle "Szene" interaktiv zu "schwenken".Schlechte Leistung mit CATransform3D

Im folgenden Ausschnitt ist "Modell" der Layer, den ich zu animieren versuche. "camera" ist eine CATransform3D-Matrix, die ich kontinuierlich durch Touch-Übersetzungen aktualisiere.

Der Ansatz funktioniert, aber das Schwenken ist sehr träge. Wenn ich das Teil mit der CGAffineTransform auskommentiere, bekomme ich schnelles und reaktionsschnelles Panning - aber ich verliere die Änderung der Perspektive, die beim Panning auftreten sollte.

- (void)didPan:(UIPanGestureRecognizer*)pan 
{ 
    if (pan.state==UIGestureRecognizerStateChanged) 
    { 
     CGPoint p = [pan translationInView:self.view.window]; 

     camera = CATransform3DTranslate(camera, p.y, 0, -p.x); 
     model.transform = CATransform3DConcat(camera, modelView); 

     // CGAffineTransform tA = self.view.transform; 
     // tA = CGAffineTransformTranslate(tA, p.x, p.y); 
     // self.view.transform = tA; 

     [pan setTranslation:CGPointZero inView:self.view.window]; 
    } 
} 

Wie kann ich die Renderleistung verbessern?

Antwort

4

Okay, ich habe es selbst gelöst: das Problem waren implizite Animationen. Jeder Aufruf von model.transform = ... löste eine implizite Animation aus, was zu einem sehr trägen Verhalten führte. Deaktivieren des impliziten Animationen für den Schlüssel verwandeln, wenn die „Modell“ Schicht zu schaffen, löste das Problem:

model.actions = [NSDictionary dictionaryWithObjectsAndKeys: 
        [NSNull null], @"transform", 
        nil]; 

Jetzt ist alles bissig und schnell.

3

Ich dachte auch eine sauberere Weg aus der Kamera verwandeln, wie diese anzuwenden:

camera = CATransform3DTranslate(camera, p.x, p.y, 0); 
mainLayer.sublayerTransform = CATransform3DConcat(camera, CATransform3DPerspective); 

wo mainLayer mein Ansichtsfenster ist, und CATransform3DPerspective ist eine Konstante CATransform3D wie folgt definiert:

CATransform3D const CATransform3DPerspective = { 
    1.0, 0.0, 0.0, 0.0, 
    0.0, 1.0, 0.0, 0.0, 
    0.0, 0.0, 1.0, -1.0/500.0, 
    0.0, 0.0, 0.0, 1.0 
}; 

Auf diese Weise muss ich die impliziten Animationen nicht mehr deaktivieren - es funktioniert einfach.