martes, 14 de abril de 2015

Multirresolución

Olvidaba comentar una de las prácticas que más me ha gustado (y costado) del primer cuatrimestre. El trabajo era totalmente libre, pero tenía que ser algo sobre multirresolución, así que varios alumnos decidimos experimentar con algoritmos de multirresolución. Yo, en particular, con colapso de facetas y de aristas.


  • Colapso de facetas:
El algoritmo que desarrollé calcula el área media de todas las facetas de la malla, y colapsa todas aquellas facetas cuya área sea menor que el doble del valor del área media. Pero tiene un gran inconveniente: sólo sirve para mallas en las que sus facetas estén agrupadas de 4 en 4 de la siguiente forma:


Para mallas de este estilo, obtenemos los resultados deseados:


Pero habría que extender el algoritmo para mallas con facetas agrupadas de diferentes formas:




  • Colapso de aristas (1):
El algoritmo que desarrollé selecciona la menor arista de la malla, elimina uno de sus vértices, junto con todos los triángulos que lo contienen y retriangula el agujero; todos los triángulos que contenían el vértice eliminado pasan a contener el otro vértice de la arista colapsada:


Crea una segunda malla (malla simplificada que se va construyendo a partir de la original). Encuentra la arista más corta, selecciona el vértice a a eliminar y guarda en una lista todos sus vértices vecinos menos el vértice b que lo va a reemplazar. Elimina los vértices repetidos de la lista y los ordena de forma que cada uno sea vecino del anterior (formando el borde del agujero). Añade los nuevos triángulos (que taparían el agujero), formados por el vértice b y todos los pares de vértices consecutivos de la lista, así como todos los triángulos que no contienen el vértice a eliminado. Añade todos los vértices y elimina los no referenciados (el vértice a).

Da buenos resultados, pero es poco eficiente (tiene alto coste computacional):



  • Colapso de aristas (2):
Implementé un segundo algoritmo de colapso de aristas, mucho más eficiente. Funciona para cualquier número de iteraciones y para cualquier malla. Selecciona la arista a colapsar (según el criterio de selección elegido), formada por los vértices a y b. Para cada triángulo t: Si t contiene a a y a b, se elimina el triángulo t. Si t contiene a a pero no a b, sustituye a por b en el triángulo t.


Comparando distintos criterios de selección de arista:





  • Colapso de aristas (3):
Por último, desarrollé un tercer algoritmo de colapso de aristas más eficiente (a la tercera va la vencida), que tarda menos tiempo en simplificar una malla. Crea una lista de aristas a colapsar de una sola vez en lugar de colapsar una arista en cada iteración. Calcula el área media de todos los triángulos de la malla, y selecciona para colapsar toda arista que sea la menor de las aristas de cada triángulo que tenga menor área que el área media. Puede simplificar mallas mucho mayores mucho más rápido.




lunes, 9 de marzo de 2015

Otras prácticas del primer cuatrimestre

De nuevo ha pasado más de un mes desde la última entrada. Este segundo cuatrimestre está siendo demencial. Si algún futuro alumno del Máster me lee, que no se confíe. No dejan de repetirte que el segundo cuatrimestre está muy sobrecargado de trabajo, pero piensas "no será para tanto", y luego te pasas los fines de semana trabajando, sin dormir. Pero bueno, poco a poco van saliendo cosas chulas, así que merece la pena =D

Todavía hay alguna práctica del primer cuatrimestre que no he comentado aquí:

- Para Realidad Virtual e Interacción, 3 compañeros y yo diseñamos un simulador de escenarios virtuales con Realidad Aumentada y guantes hápticos para que el usuario pudiera visitar lugares ficticios (como los escenarios de sus películas o series favoritas) o reales (como ruinas y otros lugares históricos). Con el simulador, se podría ir a Nueva Zelanda a visitar la Comarca, recorrer un templo romano e incluso dar la mano al mismo Napoleón.

- Para la misma asignatura, también había que hacer un trabajo sobre usabilidad, eligiendo como ejemplo el software que quisiéramos; en mi caso, elegí el videojuego Heroes of the Storm (de Blizzard, que en ese momento estaba en fase alfa (a la que yo tenía acceso), gracias a lo que pude encontrar algún pequeño defecto de usabilidad. Así que busqué unos principios de usabilidad específicos para videojuegos. Pero quise ir más allá, y encontré también unos principios de usabilidad específicos para videojuegos online multijugador (MMO). No voy a comentar aquí más detalles, pero por si alguien quiere echarle un vistazo, los autores de estos principios son David Pinelle, Tadeusz Stach y Carl Gutwin.

- Para Modelado y Comportamiento de Personajes, he realizado cinco pequeños vídeos para mostrar los 12 principios de la animación, con un modelo de personaje bastante peculiar: un monstruo con forma de bola con una gran boca, brazos y patas, y con una antena con un ojo. Cuando tenga más tiempo, haré un pequeño montaje y lo subiré a youtube.

- También realizamos dos compañeras y yo una escena en OpenGL con iluminación de Phong, pero lo que debería ser un cubo rotando, en realidad mostraba un folio. No pudimos arreglarlo a tiempo, así que intentaremos mejorarlo (si nos da tiempo) para Junio.

Estos días, gracias a Rendering Avanzado, me he enganchado a la creación de texturas procedurales. Intentaré poner pronto algunos ejemplos! =D

jueves, 5 de febrero de 2015

Juegos de varias asignaturas

Hace más de un mes que no escribo ninguna entrada a causa de los exámenes y los trabajos de clase... pero tanto trabajo ha merecido la pena. He hecho varios juegos para prácticas de algunas asignaturas.

Para la asignatura de Animación por Computador, he hecho un pequeño juego de tipo runner con mi gata Sally como protagonista. Tiene un "modo normal", con un escenario relativamente corto para aprender a jugar, y un "modo infinito" donde los escenarios se van generando de forma aleatoria, y se van eliminando una vez son sobrepasados.



Para Fundamentos Matemáticos y Físicos para Informática Gráfica, he hecho dos prácticas:


1. Tiro parabólico: Aproveché esta práctica para hacer un pequeño minijuego en el que, con una catapulta, hay que lanzar proyectiles a unos orcos en el Abismo de Helm (el Señor de los Anillos). Se pueden cambiar la dirección, el ángulo y la velocidad del lanzamiento.



2. Masa-muelle: Aquí me inspiré en la típica caja sorpresa de la que sale un muelle con un payaso. Se pueden cambiar la posición y velocidad iniciales, la masa del objeto y el coeficiente del muelle.



Para Modelado y Comportamiento de Personajes, mi compañera Jessica y yo hicimos un minijuego en el que unos personajes se persiguen y huyen unos de otros. Para la inteligencia artificial, utilizamos la herramienta RAIN.


sábado, 20 de diciembre de 2014

PFM: Traducción de Java a C#

Una vez entendido su funcionamiento (y aprovechando las vacaciones), he empezado con la traducción del código, de Java a C#, empezando por la clase EEPEngine. A partir de esa clase, continué de forma fluida, introduciendo las clases (y métodos) que el propio Unity me iba avisando que necesitaban las demás clases. Así, continué hasta que Unity ya no me informó de ningún error, y ya tenía la siguiente jerarquía de clases:


Sin embargo, algunas clases estaban vacías. Así que continué completando todas las clases, y añadiendo más clases que se necesitaban, hasta la jerarquía de clases que tengo ahora mismo:



La traducción de Java a C# fue bastante sencilla. Los cambio más significativos son los siguientes:

  • El código original en Java utilizaba ArrayList. Yo en C# he usado List, porque he leído en los foros de Unity que es más útil y más cómodo, sobre todo porque le especificas el tipo de la lista, mientras que con ArrayList (en C#) no. Además, ArrayList en C# también puede generar otros problemas.
  • He utilizado float en vez de double (utilizado en el código original), recomendado por mi tutor porque todo el motor de Unity trabaja con float, y al utilizar Mathf (que necesita floats), al hacer cast se pierde precisión.
  • El código original utiliza HashMap. Yo he utilizado un equivalente en C#, Dictionary, al que se le especifica el tipo de Key y de Value, al igual que con HashMap (con Hashtable, sin embargo, no). Recorrer una colección de tipo Dictionary, es sencillo, utilizando: foreach (KeyValuePair p in ...).
  • La última diferencia es que en C# no hay que declarar las excepciones que lanza un método; las extrae directamente del cuerpo del método.

domingo, 14 de diciembre de 2014

Taller de texturado

Para el taller de texturado, tuvimos que ponerle texturas a la cabeza de un personaje con casco (con photoshop). Como quería hacer algo "original", decidí influirme en los marcianos de Mars Attacks:


Y el casco me quedó así (era la primera vez que usaba photoshop, así que aunque no lo parezca, me costó hacer el casco-cerebro):





Es difícil de reconocer con tanto retoque, pero con photoshop le puse la cara de un actor. Si te fijas mucho, y conoces bien al actor en cuestión, tal vez consigas reconocerlo ;)

jueves, 11 de diciembre de 2014

Taller de iluminación

En la asignatura Modelado Geométrico hemos tenido un taller de iluminación (utilizando Maya) y uno de texturizado (con Photoshop).

Para el taller de iluminación, tuvimos que renderizar unas escenas para mostrar lo que habíamos aprendido.

  • La primera escena trataba simplemente de una serie de esferas, y teníamos que crear una luz y jugar un poco con sus atributos:


  • Para la segunda escena teníamos que proyectar una imagen en la pared de una sala llena de sillas (como un gobo), y se me ocurrió simular una sala de cine en la que se proyecta una película antigua:


  • La tercera escena era a libre elección, utilizando Mentalray. Modelé mi habitación , y le añadí varias esferas distintas (unas de colores, una transparente y otra que emite luz de color verde claro) que se reflejan en la estantería y en la mesa. La lámpara de la mesilla de noche emite luz de color azul. Por la ventana, entra la luz del sol.





  • La última escena también era a libre elección, utilizando Maxwell. La escena contiene un cenador, unas esferas que podrían ser asientos de estilo moderno (aunque no parecen muy cómodas; las añadí para ver el reflejo de los demás objetos en ellas, e incluso el reflejo rojo de las esferas en las columnas del cenador), y una mesa con unas tazas y un tablero de ajedrez con piezas de cristal.


domingo, 30 de noviembre de 2014

PFM: Emotional Elicitation Process (EEP)

Mi primera tarea consistirá en traducir el modelo EEP, comentado en la entrada anterior de este blog, de Java a C#, para poder trabajar con él en el motor de juego (Game Engine) Unity3D. Para ello, primero es necesario comprender bien la arquitectura de EEP (que viene explicada en la tesis de Luis Peña, un profesor muy majo, y mi tutor de proyecto):

El modelo EEP (Emotional Elicitation Process) está dividido en cuatro componentes:
  • Diccionarios Conceptuales (Conceptual Dictionaries – CP): proporcionan las definiciones de los elementos generales necesitados por el motor para evaluar los eventos. Por ejemplo, el tipo de Acciones que el evento podría registrar. Estos diccionarios son distintos de los Diccionarios AGCBAR (Automatic Game Controllers Behaviors with Affect Responses) y están solo relacionados con los procesos internos del modelo EEP.
  • Perfil del Personaje (Character Profile – CP): define los parámetros numéricos que representan la definición general de la personalidad del personaje y la identificación del estado de ánimo (Mood State µi), en el espacio del ánimo (mood space, M). También proporciona la cuantificación de los elementos registrados por los diccionarios conceptuales. Por ejemplo, el valor que le da un personaje a la acción de Dar-Dinero registrada en los diccionarios.
  • Motor de proceso de provocación emocional (Emotional Elicitation Process Engine – EEPE): descompone, analiza y evalúa un evento. También analiza las emociones y sus niveles de intensidad como resultado de la evaluación de un evento Ei.
  • Espacio de vector de ánimo (Mood Vector Space – MVS): representa el estado de ánimo del personaje actual, µi. El MVS es un espacio tridimensional derivado del modelo PAD. Aquí, las emociones percibidas por un personaje son convertidas por el EEPE en vectores en este espacio, y traducen el estado de ánimo del personaje de un punto a otro dentro de los límites del MVS. Por ejemplo, un punto en concreto en este espacio puede representar un estado de ánimo de un personaje en particular en un momento en particular.


Por lo tanto, fuera del modelo, podemos implementar las interfaces que sintetizan los eventos generados por el entorno (Motor de Juego [Game Engine] en el caso de la Arquitectura de AGCBAR) para poder producir los ánimos indicados por el Motor Emocional:
  • Constructor de Eventos (Event Builder – EB): dados los eventos generados por el entorno, Ei, este componente se adapta a la estructura necesitada por el EEPE. Este componente puede ser definido como un envoltorio de los eventos entrantes. Cada evento entrante puede producir de 0 a N eventos internos de EEP {εj} ∈ ε, (por la relación causal entre los eventos y sus componentes).
  • Etiquetador de Ánimo (Mood Tagger – MT): los ánimos son un conjunto discreto de valores finitos que tienen su significado en el contexto del Motor de Juego. Sin embargo, el Modelo EEP opera sobre una representación continua del Estado de Ánimo, el cual está basado en la representación MVS. Es la responsabilidad del MT proyectar el estado de ánimo continuo, µi ∈ M, a uno de los valores discretos, Ti ∈ T. Este espacio de estado es la representación básica de la cual extraemos el estado de ánimo, para luego traducirlo a las etiquetas de estado de ánimo Ti ∈ T a través de la interfaz de ánimo en la arquitectura de AGCBAR.


Esta estructura de eventos es necesaria para el análisis balanceado de las emociones. También proporciona los parámetros cruciales para la clasificación y cuantificación de las emociones producidas por los eventos. Por ejemplo, los eventos están asociados conforme a sus fuentes y objetivos, y sus consecuencias causales son traducidas como eventos emocionales.

Además de esto, una representación continua del estado de ánimo permite al motor EEP operar con transiciones de grano fino (indicadas por los eventos). También permite la proyección del número discreto de etiquetas de ánimo definida por la arquitectura AGCBAR.