Práctica 6 Animación. Interpolación 6.1. Introducción En esta primera práctica sobre animación, se aborda el movimiento de los objetos. Tenemos la intención de, dados un punto de partida Pinicial y de llegada Pf inal , mover el objeto desde el punto de partida hasta el de llegada, en una trayectoria lineal, con la ~ = Pf inal − Pinicial , y con un movimiento que bien puede orientación definida por el vector O ser lineal o senoidal. El posicionamiento y orientación de los objetos se ha visto en las anteriores prácticas. Solamente hay que indicar que cada objeto leído de un fichero .ply tiene su propia orientación (lo que es “hacia adelante”). Esto debe ser tenido en cuenta cuando se calculan y aplican los ángulos pues sino afectará a la correcta visualización. Por ejemplo, la hormiga tiene una orientación “hacia adelante” (0, 0, 1), mientras que la del coche es (1, 0, 0) Veamos en que consisten las dos formas de movimiento. Teniendo en cuenta que la trayectoria es lineal (véase que para ir de un punto a otro se pueden escoger infinitas trayectorias), el movimiento nos dice cómo, en relación al tiempo, se va a recorrer dicha trayectoria. Por ejemplo, dado un camino o trayectoria, una coche puede recorrerla avanzando el mismo espacio en cada periodo de tiempo. En este caso hablaríamos de un movimiento uniforme, que se describe con una función lineal (Figura 6.1, a). Si, en cambio, el coche comienza con una velocidad pequeña, la cual va aumentado, hata que se estabiliza, y a continuación invierte el proceso, decreciendo la velocidad al aproximarse al destino, hablaríamos de un movimiento con aceleración y desaceleración, que se puede describir con una función senoidal (Figura 6.1, b). 6.2. Objetivos Se incluirá en la práctica anterior el código que permita generar una escena con un objeto .ply (p.e. la hormiga). El mismo se moverá con trayectoria lineal, con la orientación de dicha trayectoria, y con el movimiento controlado por funciones lineales o senoidales. Se podrá cambiar a movimiento lineal pulsando la tecla l, y a movimiento senoidal con la tecla k. Para activar la animación se apretará la tecla F12. c Domingo Martín Perandrés 66 Animación. Interpolación (a) (b) Figura 6.1: (a) Movimiento lineal. (b) Movimiento senoidal 6.3. Desarrollo Dado que esta práctica es la base de la siguiente, es conveniente realizar el desarrollo de la misma teniendolo en cuenta. En la próxima práctica será necesario crear un conjunto de “particulas”, entidades con atributos. En esta práctica vamos a facilitar su desarrollo mediante la creación de una párticula. En la anterior práctica se han podido visulizar varias instancias del objeto leido. Aunque el resultado visual es similar, la codificación propuesta hasta ahora no es la más óptima para la aplicación que se pretende realizar: no existe el concepto de entidad con atributos. Como se ha hecho anteriormente, la solucion consiste en crear una clase que permita encapsular los atributos y la funcionalidad. Por ejemplo, se tendran variables para indicar la posición, la orientación el color, etc., y funcionalidad para dibujarse, calcular las posiciones, etc. Ya que el objeto se tiene que visualizar, y su aspecto dependera del fichero ply leido, se debe incluir en el objeto una referencia (puntero) al objeto leido. Esto es, sólo se lee un objeto, pero se puede visualizar varias veces. La otra idea importante se refiere a la pregunta ¿cómo puedo simular el paso del tiempo en una aplicación controlada por eventos?; cada vez que el objeto cambia debe ser dibujado ¿donde (en que función) se cambia el objeto?. La solución está en dos tipos de eventos: el evento reloj (Timers) y el evento desocupado (Chore). Mediante el evento reloj puedo indicar a la aplicación una función que será llamada cuando el contador que se ha definido llegue a 0. Este reloj-contador es controlado por el bucle de eventos. Su uso sería el siguiente: cada vez que se produce un evento de reloj, se cambia la posición del objeto y se indica que se debe dibujar. Aunque es una posible solución tiene el problema de establecer un intervalo de tiempo fijo. Esto supone saber cuánto tiempo se va a consumir en hacer todos los procesos necesarios, sin que los mismos sean interrumpidos. Esto no suele ser eficiente. La solución se encuentra en el evento desocupado. Como su propio nombre indica, este evento ocurre cuando todos los demás han sido atendidos. Por tanto, es independiente de lo que duren el resto de procesos, y se garantiza su llamada de forma cíclica. Al igual que con los otros eventos, se debe asignar una función a este evento. Para Fox, los pasos a realizar son los siguientes: c Domingo Martín Perandrés 6.4 Evaluación 67 1. Se define el identificador del evecto. Por ejemplo, ID_CHORE 2. Se define la función que tratará el evento. Por ejemplo: long on_chore(FXObject *sender,FXSelector message,void *ptr); 3. Se establece la relación entre el mensaje y su función. Por ejemplo: FXMAPFUNC(SEL_CHORE,_gl_window::ID_CHORE,_gl_window::on_chore) 4. Se activa el funcionamiento del evento con: getApp()->addChore(this,ID_CHORE); Una característica importante a tener en cuenta es que una vez que el evento ha sido tratado por la función el mismo es deshabilitado. Esto supone que si queremos volver a usarlo (como es en este caso), hay que volver a activarlo. Dado que queremos que el objeto se mueva desde una posición a otra a partir de que se active la animación, tendremos que indicar una posición inicial (la original del modelo) y una posición final, y en la función que trata el evento desocupado, controlar cuando el objeto llega a la posición final. Cuando esto ocurre, la que era posición inicial toma los valores de la posición final, y se calcula una nueva posición final (entiéndase que cuando se habla de posición, no solo se refiere a la misma si no también la orientación). Veamos cómo se implementa el movimiento desde una posición inicial a otra final. Uno de los parámetros que se debe definir para el objeto es la velocidad, dada como la cantidad de espacio recorrido por unidad de tiempo, o tick. Hay que tener claro que para nuestro ejemplo la unidad de tiempo o tick es cada vez que ocurre el evento desocupado; es un tiempo discreto. Con este parámetro, podemos calcular el número de ticks que son necesarios para ir de una posición a otra. Por último, debemos añadir un contador de ticks, que se inicializa a cero cuando se calcula un nuevo punto final, y que cada vez que se obtiene una nueva posición se incrementa en 1, hasta llegar al número de ticks necesarios. Estas dos variables se usan en una función paramétrica. Veamos el caso del movimiento lineal. t=(float) Contador_ticks++/(float) Numero_ticks; Posicion_actual=Posicion_inicial*(1-t)+Posicion_final*t; De esta manera tan simple se implementa el movimiento lineal. Véase lo fácil que es detectar si el objeto ha llegado a la posición final. Para el caso del movimiento con aceleración y desaceleración, utilizaremos una función coseno. Se debe buscar la zona de la función en la que se cumpla que comienza con un cambio pequeño, pero que se va acelerando, para llegar de nuevo a un cambio lento en la desaceleración. Por último, se debe poder controlar la velocidad mediante las teclas +, para aumentarla, y -, para reducirla. 6.4. Evaluación Se evaluarán los siguientes puntos: Creación de una clase para el objeto animado. Al objeto se le podrá asignar cualquier objeto geométrico de tipo .ply, cargado al comenzar el programa. El objeto se moverá desde una posición inicial a otra final, con la orientación de la trayectoria. La animación se activará con la tecla F12. c Domingo Martín Perandrés 68 Animación. Interpolación Figura 6.2: Uso de la hormiga como modelo y diferente fotogramas del movimiento. Se podrá cambiar el tipo de movimiento a lineal (l) o senoidal (k) Se podrá controlar la velocidad (teclas + y -) 6.5. Temporización: 4h 6.6. Mejoras 6.7. Bibliografía Mark Segal y Kurt Akeley;The OpenGL Graphics System: A Specification (version 1.5); http://www.opengl.org/ Edward Angel;Interactive Computer Graphics. A top-down approach with OpenGl; Addison-Wesley, 2000 J. Foley, A. van Dam, S. Feiner y J. F. Hughes; Computer Graphics: Principles And Practice, 2 Edition; Addison-Wesley,1992 c Domingo Martín Perandrés 6.7 Bibliografía 69 A. Watt y M. Watt; Advanced Animation And Rendering Techniques. Theory And Practice; Addison-Wesley, 1992 c Domingo Martín Perandrés 70 c Domingo Martín Perandrés Animación. Interpolación