2012-09-26 21 views
6

¿Cuál es el método estándar para un movimiento suave de la cámara dentro de SceneKit (OpenGL)? El cambio manual de x, y no es lo suficientemente uniforme, aunque el uso de CoreAnimation crea un movimiento de "pulsación". Los documentos sobre SceneKit parecen ser muy limitada por lo que cualquier ejemplos serían apreciadas, actualmente estoy haciendo esto:Movimiento suave de la cámara SceneKit

- (void)keyDown:(NSEvent *)theEvent { 
    int key = [theEvent keyCode]; 
    int x = cameraNode.position.x; 
    int y = cameraNode.position.y; 
    int z = cameraNode.position.z; 
    int speed = 4; 
    if (key==123) {//left 
     x-=speed; 
    } else if (key==124) {//right 
     x+=speed; 
    } else if (key==125) {//down 
     y-=speed; 
    } else if (key==126) {//up 
     y+=speed; 
    } 
    //move the camera 
    [SCNTransaction begin]; 
    [SCNTransaction setAnimationDuration: 1.0]; 
    // Change properties 
    cameraNode.position = SCNVector3Make(x, y, z); 
    [SCNTransaction commit]; 
} 
+0

Pruebe cambiar la velocidad a un valor menor, y también marque 'animationTimingFunction' de SCNTransaction. Asegúrese de que el nombre de la función 'CAMediaTimingFunction' sea kCAMediaTimingFunctionLinear para que no emita pulsos. – TheAmateurProgrammer

Respuesta

1

He estado experimentando con esto. Lo mejor que he encontrado hasta ahora es registrar el estado de las teclas de entrada en estado interno, modificado por keyDown: y keyUp :, y ejecutar un NSTimer para aplicarlas. El temporizador usa el delta de tiempo medido real entre disparos para determinar qué tan lejos mover la cámara. De esta forma, los tiempos irregulares no tienen demasiado efecto (y puedo llamar a mi método para actualizar la posición de la cámara en cualquier momento sin preocuparme por cambiar su velocidad de movimiento).

Sin embargo, lleva un poco de esfuerzo hacer que esto se comporte correctamente. keyDown: y keyUp: tienen algunos comportamientos desagradables cuando se trata de la entrada del juego. Por ejemplo, repetir claves. Además, pueden disparar incluso después de que su vista pierda el foco o su aplicación quede en segundo plano, si las teclas se mantienen presionadas durante la transición. Etc. No es insuperable, pero es molesto.

Lo que aún no he hecho es agregar aceleración y desaceleración, lo que creo que ayudará a la percepción de que es suave. De lo contrario, se siente bastante bien.

+0

De alguna manera hice un enfoque similar, excepto que no usé el temporizador. Acabo de actualizar la posición de la cámara dentro del delegado de actualización. Funcionó bastante bien la mayoría de las veces. Sin embargo, cuando el FPS cae, el movimiento no es uniforme cuando se usa Metal como renderizador - cuando se utiliza OpenGL como procesador de imágenes, siempre es fluido, pero el FPS cae con mayor frecuencia en OpenGL ... – ColdSteel

8

Para reducir al mínimo los movimientos pulsantes (debido a la repetición de teclas) se puede utilizar un timingFunction "easeOut" :

//move the camera 
[SCNTransaction begin]; 
[SCNTransaction setAnimationDuration: 1.0]; 
[SCNTransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]]; 
// Change properties 
cameraNode.position = SCNVector3Make(x, y, z); 
[SCNTransaction commit]; 

dicho esto, lo mejor que puede hacer aquí es, probablemente, para gestionar una posición de destino (un vector3) se y actualizar la posición de la cámara en cada cuadro para ir a este objetivo sin problemas.

Cuestiones relacionadas