Sobre Ogreros.Org

Hola a todos.
Mi nombre es Ib Quezada (ibito), y soy el que está al mando en el sitio, se (como algunos de ustedes) que casi no he venido por éstos rumbos, pero no es porque no quiera o no me interese, es sólo porque no he tenido el tiempo suficiente como para dedicarme a hacer mi hobby favorito. Sin embargo, si lo visito con regularidad y se que sucede por acá.
El motivo de éste texto es para agradecer a todos los usuarios que han sido activos, que han ayudado a los demás, sinceramente no me animo a dar nombres porque no quiero que me falte mencionar a ninguno, por lo tanto, gracias, gracias a ti por seguir con ésto. :)

Como muchos se habrán dado cuenta, he puesto un bloque de publicidad porque quiero poder pagar el dominio para seguir con ésta grandiosa comunidad, si todo va bien con la publicidad, compraré hosting, para poder instalar cuanta aplicación sea necesaria.
Tengo pensado poner un botón de donaciones, pero no quisiera que lo tomaran a mal, pero si lo pongo, cabe mencionar que no están obligados, y pueden llegar y pasearse por aquí sin ningún remordimiento :P .

En fin, otro de los motivos por los que escribo ésto, es porque necesito un poco de ideas, retroalimentación, qué les gusta, que no les gusta, que cambiarían del sitio. Si tienen alguna idea, no duden en comentar o enviarme un correo.
Gracias por leer :)
Ib Quezada a.k.a. ibito.

Animación 3D


El efecto óptico de imágenes animadas se debe al fenómeno fisiológico de la persistencia de la visión.
La animación tradicional y sus técnicas son el referente de la animación digital. Así, podemos encontrar en la animación digital, animación por interpolación de fotogramas clave, técnica base de la animación tradicional.
El caso de la animación 3D es más complejo. Las técnicas de animación 3D van desde la captura de movimiento hasta las técnicas utilizadas en robótica, tales como la cinemática directa e inversa.
La visión del cerebro humano

Cuando vamos a hablar de animación no podemos dejar de mencionar que una cámara cinematográfica rueda a una velocidad de 24 fotogramas por segundo. Cuando estos 24 fotogramas, o 24 fotografías de un determinado sujeto durante un segundo, se proyectan en una pantalla de cine producen la ilusión del movimiento natural.

El concepto de "ilusión de movimiento" hace referencia a la incapacidad del cerebro humano de ver estas 24 imágenes de forma separada. De hecho, el cerebro mezcla estas imágenes gracias a un proceso denominado "persistencia de visión". La visión continuada tiene lugar a partir de 24 imágenes por segundo. Por debajo de esta cifra el cerebro percibe los espacios en negros que existen entre una fotografía y la siguiente.

Los 12 principios de Isaac Kerlow

Los 12 principios fueron creados en los años 30 por animadores en los Estudios Walt Disney. Estas reglas básicas de animación se utilizaron para guiar las discusiones creativas y de producción y ayudaron a formar mejor, y más rápido, a los jóvenes animadores. Estos 12 principios también ayudaros a que el oficio de la animación pasara de ser algo novedoso a ser una forma de arte, y fueron aplicados inicialmente a los clásicos animados de Disney, como Blancanieves, en 1937, Pinocho y Fantasía, en el 40, Dumbo, en el 41 y Bambi, en 1942.
Estos 12 principios tratan principalmente de realizar la actuación, dirigir esta actuación, representar la realidad, ya sea dibujando, modelando,..., interpretar la física del mundo real, y editar una secuencia de acciones, el movimiento. Hoy en día siguen funcionando, ya que nos ayudan a crear personajes y situaciones más creíbles, y de mayor impacto. Eso sí, estos principios se han tenido que reinterpretar y expandir, e incluso se han tenido que añadir algunos principios adicionales que den soporte a los nuevos estilos y técnicas utilizados en la animación. Esto es debido a que, en los años 30, el estilo dominante, casi exclusivo, era la animación narrativa cartoon pose a pose. Durante este tiempo, las técnicas y los estilos de la animación, así como la magnitud de los proyectos, han cambiado enormemente. Durante los años 30, varias técnicas no se encontraban aún desarrolladas del todo, como los movimientos de cámara o la iluminación, o bien eran malentendidas, como el stop motion o la rotoscopia). Además, las cámaras no eran portátiles, no existía la edición no linear, ni la captura de movimiento, ni los videojuegos,... Otras formas de arte han evolucionado con la tecnología, creando nuevos lenguajes y principios, es por ello que estos 12 principios de la animación también han necesitado evolucionar.
Squash and Strech (Estirar y Encoger)
Éste es el primero de los 12 principios, y consiste en exagerar las deformaciones de los cuerpos flexibles, para lograr un efecto más cómico, o más dramático además de ayudar a la simulación de peso y velocidad.
Este principio puede ser también implementado en la animación 3D con varias técnicas: piel y músculos, resortes, morphing, manipulación directa de la malla,... También se puede experimentar con nuevas técnicas, algunas aún en desarrollo, como las simulaciones dinámicas con pesos (weighting) y nuevos sistemas de IK (Cinemática Inversa).
Anticipación
El principio de la anticipación ayuda a guiar la mirada del público al lugar donde está a punto de ocurrir la acción. Es ideal para 'anunciar la sorpresa'. Así, a mayor anticipación menor es la sorpresa, pero mayor el suspenso.
En cuanto a la animación 3D, se puede aumentar o disminuir la anticipación incluyendo retenciones de movimiento, y puede ser refinada con herramientas digitales de edición de tiempos, como editores de curvas, timelines o time sheets.
Puesta en Escena
Con este principio traducimos las intenciones y el ambiente de la escena a posiciones y acciones específicas de los personajes. Poniendo en escena las posiciones claves de los personajes definiremos la naturaleza de la acción. Hay varias técnicas de puesta en escena para contar una historia visualmente, esconder o revelar el punto de interés, o las acciones en cadena, acción - reacción, son dos ejemplos.
La puesta en escena se esboza antes de la animación primaria y secundaria, y la animación facial. Los animatics 3D son la mejor herramienta para previsualizar esta puesta en escena, comprobando así que todo funciona. Además podemos ayudarnos de técnicas cinemáticas contemporáneas, como la cámara lenta, el tiempo congelado, y el movimiento de cámara en los 3 ejes, o de cámara portátil.

Acción Directa y de Pose a Pose
Éstas son en realidad dos técnicas de animación diferentes. En la acción directa creamos una acción continua, paso a paso, hasta concluir una acción impredecible, y en la acción pose a pose desglosamos los movimientos en series estructuradas de poses clave.
La acción directa en el 3D sería la captura de movimiento, las simulaciones dinámicas, y la rotoscopia. Podemos utilizar canales para mezclar inteligentemente los distintos tipos de movimiento, incluyendo keyframes y mocap (captura de movimiento). Además, podemos utilizar las curvas para editar de manera no lineal, y por separado, el movimiento de distintas partes del cuerpo.
Acción Continuada y Superpuesta
Estas dos técnicas ayudan a enriquecer y dar detalle a la acción. En ellas el movimiento continúa hasta finalizar su curso. En la acción continuada, la reacción del personaje después de una acción nos dice cómo se siente el personaje. En la acción superpuesta, movimientos múltiples se mezclan, se superponen, e influyen en la posición del personaje.
En la animación 3D se utiliza mucho la acción continuada, por ejemplo en las simulaciones dinámicas de la ropa o el pelo. Las capas y canales en los softwares de animación 3D nos permiten mezclar diferentes movimientos superpuestos de diferentes partes del personaje.
Entradas Lentas y Salidas Lentas
Con este principio se consigue un efecto gracioso al acelerar el centro de la acción, mientras que se hacen más lentos el principio y el final.
En la animación 3D se puede obtener de una forma muy refinada con los editores de tiempo como las curvas. Si se utiliza captura de movimiento, se deberá recordar a los actores que hagan estas entradas y salidas lentas. En ocasiones también se utiliza el efecto contrario, sobretodo en anuncios o videos musicales, obteniendo un resultado surrealista, con entradas y salidas rápidas.
Arcos
Al utilizar los arcos para animar los movimientos del personaje le estaremos dando una apariencia natural, ya que la mayoría de las criaturas vivientes se mueven en trayectorias curvas, nunca en líneas perfectamente rectas. Si no utilizamos estos arcos, podemos dar un toque siniestro, robótico, a nuestra animación.
En el 3D, podemos utilizar los obligadores (constraints) para forzar que todo, o parte del movimiento, entre en trayectorias de arcos. Incluso la captura de movimiento se puede refinar con los editores de curvas, siempre que no sea editable.
Acción Secundaria
Este principio consiste en los pequeños movimientos que complementan a la acción dominante.
En cuanto a la animación 3D, se pueden utilizar simulaciones dinámicas y scripts para controlar mucha de la acción secundaria, y podemos aprovechar las capas y los canales para crear diferentes movimientos secundarios, una capa para el pelo, otro para la ropa,...
Timing
Es el momento preciso y el tiempo que tarda un personaje en realizar la acción, y que proporciona emoción e intención a la actuación. Las interrupciones de movimiento, las motion holds, son un fantástico recurso a la hora de contar historias.
La mayoría de herramientas de animación 3D nos permiten refinar el timing con editores no lineales, recortando o añadiendo frames. También podemos controlar el timing utilizando distintas pistas para personajes distintos, y subpistas para las partes de los personajes, como cabeza, torso, brazos,...

Exageración
Normalmente, la exageración ayuda a los personajes a reflejar la esencia de la acción. Una gran parte de esta exageración puede ser obtenida mediante el Squash and Strech.
En cuanto a la animación 3D, podemos utilizar técnicas procedurales, rangos de movimiento y scripts, para exagerar el movimiento. No solo disponemos de la actuación en sí para exagerar la acción, también podemos emplear la cinematografía y la edición para aumentar la intensidad emocional de un momento.
Modelado y esqueleto sólidos
Un modelado y un sistema de esqueleto sólido, o un dibujo sólido como se decía en los años 30, ayudarán al personaje a cobrar vida. El peso, la profundidad y el balance simplificarán posibles complicaciones en la producción debidas a personajes pobremente modelados. Además, hay que poner atención a las siluetas al alinear los personajes con la cámara.
En referencia a la animación 3D, tenemos que familiarizarnos con los esqueletos, y optimizarlos para personalidades y movimientos específicos de cada personaje.
Personalidad
La personalidad, o la apariencia, como se le llamó en un principio, facilita una conexión emocional entre el personaje y el público. Debemos desarrollar nuestros personajes hasta darles una personalidad interesante, con un conjunto de deseos y necesidades claras que marquen su comportamiento y sus acciones.
La complejidad y la consistencia del movimiento son dos elementos de la personalidad de un personaje que podemos desarrollar fácilmente en la animación 3D. Debemos comenzar definiendo por escrito la personalidad del personaje, cómo se mueve, cómo reacciona ante distintas situaciones, cómo se relaciona y reacciona con otros personajes,... Afinamos la personalidad de nuestro personaje a través de las poses clave.

Conclusiones

La reinterpretación de estos principios de la animación nos ayudarán a a crear personajes y situaciones contemporáneas, más actuales y creíbles. Planear y dirigir animación utilizando los principios tradicionales y los actuales harán que seamos más efectivos.

Instalación de OGRE sobre Ubuntu 8.10

Hola a todos, escribo esta entrada en el blog, para compartir con los demás mi experiencia a la hora de instalar OGRE sobre Ubuntu 8.10, la cual ha sido un poco frustrante, ya que he tardado bastante en conseguir compilar aplicaciones sobre esta plataforma a pesar de que sobre windows con Visual C++ y los SDK precompilados fue un juego de niños.
Para conseguir compilar sobre Ubuntu (debería funcionar sobre casi cualquier distribución), he seguido la magnifica guía que tiene jds en su blog, http://www.ogreros.org/node/40, aunque tras completarla, me he encontrado con algunos problemas que no me permitían compilar de manera adecuada. Paso a comentarlos así como la solución que les he dado.

He tratado de compilar en varios entornos, entre ellos Anjuta y kdevelop, pero mi experiencia no ha sido muy gratificante (probablemente debido a mi falta de experiencia en C++ sobre el que llevo mucho tiempo sin trabajar), ya que tienes que configurar el entorno para poder programar con OGRE y sinceramente no he sido capaz de hacerlo, animo a todo el que si se vea capaz a intentarlo y postear los resultados. Así que finalmente me he decidido por Code::Blocks:, ya que éste trae un asistente estupendo para crear proyectos de OGRE y configura él solo todos los parámetros del entorno.

Lo primero que tengo que decir es que la mejor fuente para encontrar los errores es el ogre.log que se genera tras cada ejecución. En él están los problemas que se encuentra OGRE a la hora de ejecutarse.

El primer problema que me encontré era referente al fichero plugins.cfg, ya que ogre.log insistía en decirme que no lo encontraba, copié y recopié en todos los lugares imaginables sin conseguir nada, al final la solución a este problema era más fácil de lo que parecía, mi fichero se llamaba Plugins.cfg, ojo con la mayúscula, ya que Linux distingue entre mayúsculas y minúsculas, por lo cual plugins.cfg, que era el que busca OGRE, no es lo mismo que Plugins.cfg. Problema de recién llegado a linux ;-)

El segundo problema que encontré era referente a la ubicación de los ficheros “ExampleApplication.h” y “ExampleFrameListener.h”, aunque tengo que reconocer que esto me pasó por no seguir los pasos que jds indica en su blog:
Por último falta copiar los archivos “ExampleApplication.h” y “ExampleFrameListener.h” en el directorio “include” donde se instaló Ogre, esto se hace para poder programar con las demos y ejemplos que se consiguen por algunos foros (es totalmente opcional, pero recomendado), personalmente prefiero copiar dichos archivos en los proyectos donde los necesite y así poder modificarlos como yo lo desee:

cd /home/usuario/ogre160/ogre/Samples/Common/include
sudo cp ExampleApplication.h /usr/local/include/OGRE/
sudo cp ExampleFrameListener.h /usr/local/include/OGRE/

Este problema se puede solucionar de las dos maneras que indica jds (copiándolos en /usr/local/include, o incluyéndolos en el proyecto), aunque probablemente también se pueda resolver modificando el directorio de ejecución de nuestro compilado y diciéndole que se ejecute donde tenemos el compilado de OGRE.

El segundo problema que me encontré fue que una vez instalado todo en su sitio, era capaz de compilar sin errores, pero cuando aparecía la ventana de configuración de OGRE, me aparecía con un fondo bastante extraño y en el desplegable de "Select Renderer", no me aparecía ninguno disponible, es más cuando pulsaba sobre el desplegable, la aplicación se cerraba. Mirando el ogre.log descubrí que se quejaba por no encontrar el RenderSystem_GL.so, buscándolo, lo encontré en /usr/local/lib/OGRE, así que lo copié en /usr/lib/OGRE y eso solucionó ese problema. Así que aquí copio el contenido de mis dos directorios:

/usr/local/lib/OGRE$

-rwxr-xr-x 1 root root 1222 2009-03-23 01:58 libPlugin_PCZSceneManager.la
-rwxr-xr-x 1 root root 3118903 2009-03-23 01:58 libPlugin_PCZSceneManager.so
-rwxr-xr-x 1 root root 1204 2009-03-23 01:58 Plugin_BSPSceneManager.la
-rwxr-xr-x 1 root root 2538419 2009-03-23 01:58 Plugin_BSPSceneManager.so
-rwxr-xr-x 1 root root 1210 2009-03-23 01:58 Plugin_CgProgramManager.la
-rwxr-xr-x 1 root root 743397 2009-03-23 01:58 Plugin_CgProgramManager.so
-rwxr-xr-x 1 root root 1222 2009-03-23 01:58 Plugin_OctreeSceneManager.la
-rwxr-xr-x 1 root root 3211817 2009-03-23 01:58 Plugin_OctreeSceneManager.so
-rwxr-xr-x 1 root root 1286 2009-03-23 01:58 Plugin_OctreeZone.la
-rwxr-xr-x 1 root root 2223751 2009-03-23 01:58 Plugin_OctreeZone.so
-rwxr-xr-x 1 root root 1174 2009-03-23 01:58 Plugin_ParticleFX.la
-rwxr-xr-x 1 root root 3000303 2009-03-23 01:58 Plugin_ParticleFX.so
-rw-r--r-- 1 root root 442 2009-03-21 18:45 plugins.cfg
-rwxr-xr-x 1 root root 1199 2009-03-23 01:58 RenderSystem_GL.la
-rwxr-xr-x 1 root root 7128346 2009-03-23 01:58 RenderSystem_GL.so

/usr/lib/OGRE/

-rwxr-xr-x 1 root root 2538419 2009-03-23 02:03 Plugin_BSPSceneManager.so
-rwxr-xr-x 1 root root 743405 2009-03-21 19:59 Plugin_CgProgramManager.so
-rwxr-xr-x 1 root root 3211817 2009-03-23 02:04 Plugin_OctreeSceneManager.so
-rwxr-xr-x 1 root root 3000303 2009-03-23 02:01 Plugin_ParticleFX.so
-rw-r--r-- 1 root root 442 2009-03-21 18:47 plugins.cfg
-rwxr-xr-x 1 root root 7128346 2009-03-23 02:00 RenderSystem_GL.so
drwxr-xr-x 7 root root 4096 2008-12-18 22:44 samples

Se que probablemente, tenga cosas que no necesite (probablemente el plugins.cfg, no tiene que estar en estos directorios, pero ya iré limpiando).

Una vez resuelto esto, me encontré con el problema más difícil de resolver, sobre todo porque tras googlear mucho, no encontré ninguna solución adecuada, tan solo algunas referencias en el foro oficial de OGRE, pero sin solución aparente (al menos nada que me sirviera a mi). El problema era según ogre.log que no conseguía encontrar un codec para los ficheros png, a pesar de que durante la inicialización de OGRE me decía que estaba usando Freeimage y uno de los ficheros que decía claramente soportar era el png. Por eso se veía mal el fondo de la ventana de configuración.
Para resolverlo, lo que hice fue desinstalar el Freeimage, mi gestor de paquetes (Synaptic), me decía que tenia que desinstalar varios paquetes que dependian de él, en concreto libogre14, libogre-dev y libogremain-1.4.9, lo cual hice.
Reinstalé Freeimage y después recompilé como dice jds en su blog y reinstalé OGRE. A partir de aquí todo perfecto, ya consigo compilar cualquier ejemplo sin problemas (por fin).
Creo que el problema es que las librerías que me proporciona Ubuntu están basadas en OGRE 1.4 y yo estaba compilando el 1.6 y realmente no entiendo muy bien porqué, tenía algún conflicto con freeimage. En realidad este problema creo que no se debería presentar si no instalamos nada referente a OGRE desde Synaptic, sino que compilamos nosotros el paquete.

Y eso es todo de momento, ya puedo compilar aplicaciones usando OGRE en linux.

Espero que sirva de ayuda para todo aquél que quiera usar OGRE en linux.

(También he de decir que al menos los ejemplos de OGRE me dan un framerate mayor en linux que en windows a pesar de tener Compiz funcionando, aunque espero hacer una comparativa más exhaustiva en un futuro que ya postearé)

Un saludo.

Tutoriales y recursos relacionados con OGRE

Esta es una lista de recursos en español (a menos que se especifique lo contrario), algunos de autoría de la comunidad ogrera. Si conoces material que deseas que se agregue a esta lista, o deseas hacer alguna corrección, por favor coméntalo en esta misma página.

O.G.R.E.

Iniciándose en OGRE (Autor: DanyAlejandro)

Una serie de guías (en orden) básicas para iniciarse en OGRE usando Code::Blocks como IDE de C++ en Windows. Incluye el procedimiento para instalar OGRE y configurar un proyecto de OGRE en Code::Blocks, así como conceptos básicos genéricos al IDE de C++ utilizado.

GNU / Linux (ubuntu) + Code::Blocks + Ogre (Autor: jds)

Tutorial que explica cómo instalar Code::Blocks, compilar e instalar Ogre 1.6.0, y realizar las configuraciones adicionales necesarias en GNU / Linux (Ubuntu 8.04) para comenzar a trabajar.

 Introducción a OGRE (Autor: TaMuDo)

Serie de tutoriales (algunos bastante teóricos) que sirven de introducción a OGRE. Cubre detalladamente los elementos básicos de OGRE, el método para usarlo con Visual C++ Express 2005 (Windows XP) y Eclipse 1.3 (Ubuntu 7.10), y algunas de las posibilidades del motor.

 Traducciónes de los tutoriales oficiales (Autor: Moncheta)

Traducción directa al español (en progreso) de los tutoriales oficiales de la wiki de OGRE, con leves modificaciones del traductor. La dinámica de los tutoriales es bastante rápida, y se cubren varios temas por práctica. Cada tutorial es descargable en formato pdf.

Blender

(Agradecimientos a jorgeclon por aportar los enlaces)

E-book: "Aprende Blender & Yafray en 24 horas" (Autor: Carlos Gonzales Morcillo)

Manual de Modelado de personajes con Blender (Autor: Guillermo Nasif)

Tutorial GNU/Linux (ubuntu) + Code::Blocks + Ogre

En este tutorial abarcaré como instalar Code::Blocks y como compilar e instalar Ogre 1.6.0 en GNU/Linux, de forma que quede todo listo para empezar a programar con Ogre.

La distribución de GNU/Linux que usé es Ubuntu 8.04, así que si se usa una diferente algunos pasos pueden cambiar ligeramente.

Los programas necesarios son los siguientes:

  • Code::Blocks
  • Compilador g++
  • OIS (opcional)
  • CEGUI (opcional)
  • OGRE 1.6

Compilador g++:
El primer paso y el más importante es instalar el compilador de C++, se puede hacer en el entorno gráfico o en la linea de comandos:
En modo gráfico: en Sistema->Administración->Gestor de paquetes Synaptic, se presiona buscar, se introduce g++, en la lista que aparecerá se selecciona el paquete g++ (con doble click, de forma que quede marcado), y se presiona el botón aplicar, el gestor de paquetes se encargará de instalar todo automáticamente.
En línea de comandos: sudo apt-get install g++ y se siguen las instrucciones, si no se posee apt-get se deberá usar el gestor de paquetes de la distribución de GNU/Linux que se esté usando.
NOTA: si no se tiene acceso a Internet, o por cualquier otro motivo, se pueden descargar los paquetes de http://packages.ubuntu.com/

Code::Blocks:
Para programar en Ogre lo más cómodo es usar un buen IDE, en este tutorial se usará Code::Blocks, por lo que habrá que descargarlo desde la siguiente dirección: http://downloads.sourceforge.net/codeblocks/codeblocks_8.02-0ubuntu1.deb...

Una vez que se ha descargado el archivo hay que descomprimirlo e instalarlo, una vez descomprimido los paquetes se deben instalar en el orden siguiente:

  • libcodeblocks0_8.02-0ubuntu1_i386.deb
  • codeblocks_8.02-0ubuntu1_i386.deb
  • libwxsmithlib0_8.02-0ubuntu1_i386.deb
  • a partir de este punto no importa el orden.

Se puede hacer en el entorno gráfico o en la linea de comandos:
Instalación en modo gráfico: para descomprimir el archivo descargado se puede usar el “Gestor de archivadores” que ya está incluido en Gnome, una vez descomprimido para instalar los paquetes simplemente se debe hacer doble click sobre los archivos, y seguir las instrucciones.
Instalación en linea de comandos:

tar -xvzf codeblocks_8.02-0ubuntu1.deb.tar.gz -C /tmp/
sudo gdebi "/tmp/libcodeblocks0_8.02-0ubuntu1_i386.deb"
sudo gdebi "/tmp/codeblocks_8.02-0ubuntu1_i386.deb"
sudo gdebi "/tmp/libwxsmithlib0_8.02-0ubuntu1_i386.deb"
sudo gdebi "/tmp/codeblocks-contrib_8.02-0ubuntu1_i386.deb"
sudo gdebi "/tmp/codeblocks-dbg_8.02-0ubuntu1_i386.deb"
sudo gdebi "/tmp/codeblocks-dev_8.02-0ubuntu1_i386.deb"
sudo gdebi "/tmp/libwxsmithlib0-dev_8.02-0ubuntu1_i386.deb"

Una vez instalado debe aparecer en el menú
Aplicaciones->Programación->Code::Blocks IDE.
NOTA: si no se tiene gdebi se puede usar el método clásico con dpkg (si se hace de esta forma habrá que instalar las dependencias de forma manual):
su
[se introduce la contraseña]
"archivodelpaquete.deb"

Ogre:
Para instalar Ogre, se puede usar el gestor de paquetes Synaptic sin embargo la versión suministrada por este es la 1.4.5 y seguramente se deseará usar una diferente, por lo que habrá que descargar el código fuente de la versión deseada para GNU/Linux y compilarla, en este tutorial se usará la versión de Ogre 1.6.0 final liberada el 4 de Noviembre de 2008, la cual ha sido descargada desde la siguiente dirección: http://downloads.sourceforge.net/ogre/ogre-v1-6-0.tar.bz2?use_mirror=, a partir de este punto se usará principalmente la terminal de linea de comandos:

El primer paso será crear una carpeta nueva donde se compilará ogre, de esta forma siempre se tendrá acceso a los datos de la versión de Ogre que se tenga instalado en el sistema, en este tutorial se asumirá que dicha carpeta está en el directorio del usuario actual y será llamada ogre160, para crearla se hará lo siguiente:

mkdir /home/usuario/ogre160

Ahora se procede a instalar las dependencias de Ogre, para ello en la linea de comandos se pone:

sudo apt-get install pkg-config build-essential autoconf automake libtool libzzip-dev libxt-dev libxaw-headers libxxf86vm-dev libxrandr-dev libfreeimage-dev nvidia-cg-toolkit checkinstall libfreetype6-dev libpcre3-dev libdevil-dev libxaw7-dev libopenexr-dev libtiff4-dev libglade2-dev libglademm-2.4-dev

acto seguido el sistema procederá a descargar e instalar las dependencias automáticamente.
NOTA: si se está usando una distribución de GNU/Linux sin apt-get, se deberá usar el gestor de paquetes especifico para la distribución que se esté usando.

Si se desea compilar las demos de Ogre será necesario instalar OIS y CEGUI (recomendado):

OIS: la versión usada en este tutorial es la 1.2.0 descargada desde la siguiente dirección: http://downloads.sourceforge.net/wgois/ois_1.2.0.tar.gz:
Ahora se debe descomprimir el archivo descargado al directorio de Ogre, compilarlo e instalarlo, para ello se pondrá en la línea de comandos lo siguiente:

cd /home/usuario
tar -xvzf ois_1.2.0.tar.gz -C /home/usuario/ogre160/
cd /home/usuario/ogre160/ois/
aclocal
./bootstrap
./configure
make
sudo make install

CEGUI: la versión usada es la 0.6.1 descargada desde la siguiente dirección: http://downloads.sourceforge.net/crayzedsgui/CEGUI-0.6.1.tar.gz:
Ahora se debe descomprimir el archivo descargado al directorio de Ogre, compilarlo e instalarlo, para ello se pondrá en la línea de comandos lo siguiente:

cd /home/usuario
tar -xvzf CEGUI-0.6.1.tar.gz -C /home/usuario/ogre160/
cd /home/usuario/ogre160/CEGUI-0.6.1/
aclocal
./bootstrap
./configure
make
sudo make install

Finalmente OGRE, ahora se debe descomprimir el archivo descargado al directorio de Ogre, compilarlo e instalarlo, para ello se pondrá en la línea de comandos lo siguiente:

cd /home/usuario
tar -xvjf ogre-v1-6-0.tar.bz2 -C /home/usuario/ogre160/
cd /home/usuario/ogre160/ogre/
aclocal
./bootstrap
./configure

al hacer esto último (./configure) se generará una salida, si por ejemplo hay una línea que pone lo siguiente: configure: error: Package requirements (zziplib) were not met. Significa que se debe instalar el paquete zziplib (por poner un ejemplo). Si por el contrario todo ha ido bien la salida será algo como esto:

--------=== Configuration summary ===--------
Target platform : GLX
OpenGL Ogre support : GLX
GUI library to use : gtk
Use double precision arithmetic : no
Support for threading : no
Use STLport : no
Use FreeType : yes
Use FreeImage : yes
Use DevIL : no
Build OGRE demos : yes
Build CEGUI demos : true
Build the OpenEXR plugin : no
Build the Cg plugin : yes
Build the DirectX 9 plugin : no
--------===============================--------

Ahora el paquete está listo para ser compilado e instalado:

make
sudo make install

NOTA: si se posee múltiples procesadores se puede usar make -j [procesos], donde [procesos] es el número de procesos que se desea, preferiblemente el doble del número de procesadores que se tiene, por ejemplo make -j 4 para un CPU de doble núcleo.

Por último falta copiar los archivos “ExampleApplication.h” y “ExampleFrameListener.h” en el directorio “include” donde se instaló Ogre, esto se hace para poder programar con las demos y ejemplos que se consiguen por algunos foros (es totalmente opcional, pero recomendado), personalmente prefiero copiar dichos archivos en los proyectos donde los necesite y así poder modificarlos como yo lo desee:

cd /home/usuario/ogre160/ogre/Samples/Common/include
sudo cp ExampleApplication.h /usr/local/include/OGRE/
sudo cp ExampleFrameListener.h /usr/local/include/OGRE/

Configuración de Code::Blocks:
Code::Blocks ya viene configurado para usar Ogre por lo cual solo hay que crear el proyecto, se ejecuta Code::Blocks (en el menú Aplicaciones->Programación->Code::Blocks IDE), se selecciona file->new->Project... en el dialogo de nuevo proyecto se elige el icono de Ogre project y se presiona el botón Go, se presiona Next, se elige el título del proyecto y el directorio donde se guardará se presiona Next, ahora se debe elegir “I have installed a pre-made OGRE SDK” y se presiona Next, se elige el compilador que deberá estar en “GNU GCC Compiler” y se presiona Finish.
Con esto ya se habrá creado un nuevo proyecto de Ogre, antes de compilar el proyecto se debe seleccionar el tipo de compilación en Build->select tarjet->Release, así se generará la versión final del proyecto no la de depuración. Se procede a compilar, en este punto todo debería estar bien, pero para ejecutar el programa se deben crear los típicos archivos necesarios para un proyecto de Ogre estos son “resources.cfg”, “plugins.cfg” y la carpeta “Media”, estos archivos se encuentran en donde se compiló Ogre, se copian los archivos “resources.cfg” y “plugins.cfg” (están en “/home/usuario/ogre160/ogre/Samples/Common/bin”) y también la carpeta Media (está en “/home/usuario/ogre160/ogre/Samples”) en el directorio del proyecto nuevo.
El archivo “resources.cfg” hay que editarlo para que las rutas apunten al lugar correcto por ejemplo se cambia “Zip=../../Media/packs/OgreCore.zip” por “Zip=./Media/packs/OgreCore.zip”.
El directorio raíz de un proyecto quedaría finalmente conformado de la siguiente forma:

Media [directorio]
[nombre del proyecto].cbp
[nombre del proyecto].depend
[nombre del proyecto].layout
main.cpp
plugins.cfg
resources.cfg

NOTA: Si después de haber compilado correctamente, y al momento de ejecutar el programa se cierra la ventana de configuración de Ogre, puede ser necesario copiar el archivo RenderSystem_GL.so que se encuentra en /usr/local/lib/OGRE al directorio /usr/lib/OGRE (se debe ver el archivo ogre.log para verificar si el problema se produce por la falta del RenderSystem_GL.so)
cd /usr/local/lib/OGRE
sudo cp RenderSystem_GL.so /usr/lib/OGRE/
Gracias a TvAn.H-T por esta nota. (http://www.ogreros.org/node/56)

Nota acerca del modo de depuración:
Este tutorial no cubre el como preparar Ogre para compilar en modo de depuración, personalmente no he tenido nunca la necesidad de depurar Ogre, sin embargo nuestros códigos se pueden depurar perfectamente, para ello en Code::Blocks seleccionaremos el menú Project->Build options... en la lista se selecciona Debug y se activa la pestaña “Linker settings”, en la lista se editan las entradas de la siguiente forma: “OgreMain_d” se cambia por “OgreMain” y “OIS_d” por “OIS”, una vez hecho esto ya se podrá depurar nuestro código, seleccionando Build->select tarjet->Debug. Esto significa que, de esta forma si ocurre algún error en el código de Ogre no se podrá determinar en que línea del código de Ogre se ha producido el error, pero si ocurre un error en nuestros códigos si se podrá depurar hasta ver en que línea se ha producido el error.

11 - Manipulación básica de la cámara

11 – Manipulación básica de la cámara

En el tutorial anterior vimos cómo agregar un terreno a nuestra escena. Usaremos este terreno (o cualquiera que se nos ocurra crear) como referencia para esta guía.

Lo primero que vamos a hacer, es mover la cámara para que apunte a un lugar favorable de nuestra escena desde el principio. La cámara en OGRE es un objeto especial, muy similar a un SceneNode, pero por supuesto tiene sus diferencias y métodos propios.

Podemos usar la cámara sin necesidad de anexarla a un SceneNode, y también podemos anexarla a un SceneNode (por ejemplo, si el SceneNode de un personaje se mueve, la cámara anexada se moverá tras él). Si queremos tener “tomas desde diferentes ángulos”, podemos poner diferentes SceneNodes en varios puntos del espacio, y “teletransportar” la cámara de uno a otro según corresponda (simplemente cambiar el nodo al que está anexada). También podemos tener varias cámaras, para varios ViewPorts, en un juego de varios jugadores.

En ExampleApplication existe un método en que se crea la cámara. Para re-implementarlo, agregamos el siguiente método protegido:

virtual void createCamera(void)
{

}

Al igual que el método chooseSceneManager, este método ya venía implementado y funcionando en nuestra herencia de ExampleApplication.

Dado que estamos re-implementando el método que creaba la cámara por nosotros, tendremos que hacerlo todo por nosotros mismos. Dentro del método que acabamos de agregar, escribimos la siguiente línea:

mCamera = mSceneMgr->createCamera("mi_camara");

Con esto invocamos el método “createCamera” de nuestro SceneManager. El parámetro es el nombre de la cámara, y retorna un objeto de tipo “Camera”, el cual es la representación de la cámara en el espacio 3D.

Dentro de este método también podemos cambiar la posición y orientación de la cámara. Agreguemos lo siguiente:

mCamera->setPosition(Vector3(0,100,0));
mCamera->lookAt(Vector3(500,0,500));

El método “setPosition” recibe como argumento un Vector3 que le indica el punto en el espacio en donde se debe posicionar la cámara. El método “lookAt” recibe también un Vector3 que le indica el punto del espacio al cual debe observar; la cámara se rotará automáticamente (lo cual resulta mucho más fácil que rotarla a mano).

Ya puedes correr la aplicación. Las coordenadas (0,100,0) y (500,0,500) funcionaron en mi caso, pero en tu escena deberás usar las que mejor te correspondan; puede que tengas que hacer varios intentos. Aprovecha para ir aprendiendo a guiarte en el espacio 3D (ten presente el sistema de coordenadas de OGRE discutido en una guía anterior). Si eres atento, notarás que el terreno se ha generado desde el origen (una de las esquinas) en dirección positiva de los ejes “X” y “Z”:

Ubicación del terreno por defecto

Actualizamos la documentación:

Application
void chooseSceneManager(void)
void createCamera(void)
void createScene(void)
 
SceneManager
Camera createCamera(String name)
Entity createEntity(string entityName, string meshName)
Light createLight(string name)
SceneNode getRootSceneNode()
void setAmbientLight(ColorValue color)
void setSkyBox(bool enable, string materialName)
void setWorldGeometry(String filename)
 
Camera
void setPosition(Vector3 position)
void lookAt(Vector3 position)

10 - Tipos de SceneManagers y Terrenos

10 - Tipos de SceneManagers y Terrenos

(Nota: se puede obtener más información en la página http://www.ogre3d.org/wiki/index.php/SceneManagersFAQ de la web oficial de OGRE)

Retomemos el SceneManager. Una escena puede consistir de geometría estática (terrenos, interiores de un edificio, etc.), modelos (personajes, enemigos, etc.), luces y cámaras. Según su uso, las escenas pueden ser de diferentes tipos: Una será una planicie gigantesca, llena de vegetación y agua, mientras que otras serán interiores de casas pequeñas.

Así también, tenemos diferentes SceneManager especializados, y hemos de elegir el que más nos convenga (algunos funcionan más rápido que otros en determinadas situaciones). Los más comunes son:

ST_GENERIC (Octree Scene Manager)
Básicamente es un SceneManager genérico, que funcionará bien en la mayoría de situaciones. No tiene ningún tipo de aceleración especial.

ST_EXTERIOR_CLOSE (Terrain Scene Manager)
Dirigido a escenas relativamente pequeñas con un terreno estático, que se pueden generar a partir de HeightMaps (mapas de altura – ver glosario).

ST_INTERIOR (BSP scene manager)
Dirigido a interiores (corredores, paredes, etc.). Es compatible con varios editores de niveles de juegos como Quake 3 (también admite escenas de Blender).

ST_EXTERIOR_REAL_FAR (Paging SceneManager)
Permite que las escenas se dividan en “páginas” (pedazos de un mapa muy grande se procesan uno a la vez, permitiendo escenas muy grandes). Cada página puede tener sus propios HeightMaps. Para partir una escena en “Páginas” se debe utilizar una herramienta especial (MapSplitter).

También existen otros muy interesantes que se pueden descargar de la página oficial de OGRE. Para la escena de esta guía (un terreno relativamente pequeño) usaremos el Terrain Scene Manager.

Para seleccionar el SceneManager, usaremos otro método diferente del createScene. Este método se heredó de ExampleApplication, y ha estado implementado y funcionando todo el tiempo. Básicamente, en este método se escoge qué SceneManager deseamos utilizar. A nuestra clase, le agregamos nuestra re-implementación de este método protegido:

void chooseSceneManager(void)
{
mSceneMgr = mRoot->createSceneManager(ST_EXTERIOR_CLOSE);
}

El código es bastante simple. Aquí nos hemos encontrado con otro objeto que heredamos de ExampleApplication: mRoot. mRoot es un objeto de clase Root, la cual es la clase raíz de OGRE. Cumple varias funciones fundamentales: provee la comunicación entre clases y sistemas de renderización, configuraciones, logs, y otras cosas. Todas las clases importantes de OGRE heredan la clase Root. Antes de poder usar OGRE debemos crear este objeto (ExampleApplication lo hace por nosotros).

Del objeto mRoot invocamos el método “createSceneManager”, el cual nos instancia el SceneManager (de aquí sale nuestro mSceneMgr). El parámetro es uno de los tipos de SceneManager que existan en nuestro OGRE (nótese que no lleva comillas; esto es válido para los tipos de SceneManager que OGRE trae por defecto. En otro caso se usará un tipo de dato String).

La implementación que veníamos usando hasta ahora (sin saberlo), es la misma pero en vez de “ST_EXTERIOR_CLOSE” usa “ST_GENERIC”.

Terrain Scene Manager

Terreno generado con el Terrain Scene Manager

Nuestro Terrain Scene Manager tiene algunas características especiales; entre otras cosas, nos permite crear un terreno a partir de un heightMap, y aplicarle texturas (para el ejemplo, te recomiendo que uses tus propias texturas por motivos didácticos. Es muy fácil conseguir texturas de terrenos en google. Además, estas texturas no son del tamaño adecuado).

Voy a usar el siguiente heightmap (puedo usar varias extensiones como PNG, JPG y BMP):

HeightMap (terreno_heightmap.jpg, escala de grises, 513x513) – Nótese la montaña representada en blanco

El heightMap deberá ser cuadrado; su lado deberá tener una longitud de (2n+1) pixeles, donde n es un entero positivo (algunos valores válidos son 257, 513, 1025). Entre más grande sea nuestro heightMap, mayor será el nivel de detalle (y mayor el consumo de recursos).

Ahora necesitaré una textura de terreno (terrain texture), la cual aparecerá estirada sobre todo el terreno y determinará la apariencia del terreno como un todo. La textura debe ser cuadrada, pero no es necesario un tamaño en particular (aunque usar el mismo tamaño del heightmap nos dará más control sobre dónde está cada cosa).
 
Terrain texture (terreno_tex.jpg, 513x513)

Finalmente, necesitaré una textura de detalle (detail texture) para que el terreno se vea más real (la terrain texture va estirada en todo el terreno y se verá algo borrosa). La textura de detalle se combina con la textura del terreno cuando se observa a corta distancia, mejorando notablemente el detalle del terreno.

Detali Texture (terreno_tex_det.jpg, 513x513)

La textura de detalle se repetirá varias veces sobre el terreno, así que es conveniente usar texturas “sin costuras” (seamless) para que no se note el patrón repetitivo. La textura que estoy usando la preparé con el filtro de mapa “Crear sin costuras” del GIMP.

En general, el terreno se dividirá en una cuadrícula de “baldosas” (“tiles”), lo cual le permite a OGRE saber cómo va a renderizar el terreno según esté cerca o lejos y de la topología en general. El número de baldosas influye mucho en que se note el patrón repetitivo en la textura de detalle (entre más número de baldosas, más se nota el patrón, pero mayor es el detalle de la textura del terreno).

Ya con esto preparado, ponemos los 3 archivos en la carpeta “OgreSDK\media\materials\textures”. La configuración del terreno la haremos editando el archivo “OgreSDK\media\terrain.cfg”. Es un archivo de texto en el que encontraremos los siguientes parámetros (entre otros):

WorldTexture: Archivo de la textura del terreno.
DetailTexture: Archivo de la textura del detalle del terreno.
DetailTile: Número de veces que la textura de detalle se repetirá en una baldosa del terreno (3 por defecto; si el número es 3, se repetirá en una cuadrícula de 3x3 veces la textura de detalle; es decir, aparecerá 9 veces por baldosa).
Heightmap.image: Archivo del heightMap del terreno.
PageSize: Número de vértices del terreno (por lado). Debe ser igual al lado (en pixeles) de la imagen del HeightMap.
TileSize: Tamaño de la baldosa. Debe ser uno de los valores de (2n+1), donde n es un entero positivo (por ejemplo: 65, 129, 513, etc.) y debe ser menor al PageSize. Este valor tiene un impacto en las FPS y el nivel de detalle de nuestro terreno, así que se pueden probar varios valores y escoger el que más nos convenga.
PageWorldX, PageWorldZ: Tamaño del terreno en 3D, en “World Units” (unidades globales). Aumentar el tamaño no aumentará el número de vértices de la malla del terreno, solo hará que sus caras sean más grandes.
MaxHeight: Altura máxima del terreno en 3D, en “World Units”. En el HeightMap equivale al blanco.
MaxMipMapLevel: Es el nivel de detalle con que se renderizará el terreno (5 por defecto). Lo podemos bajar donde no sea necesario mucho detalle.

Las otras opciones son más avanzadas y se pueden revisar en el sitio oficial de OGRE. En mi caso, usé los siguientes valores:

WorldTexture=terreno_tex.jpg
DetailTexture=terreno_tex_det.jpg
Heightmap.image=terreno_heightmap.jpg
PageSize=513

El resto de los valores los dejé por defecto. Luego de guardar los cambios, habremos terminado de configurar nuestro terreno. Sólo nos falta decirle a OGRE que incluya el terreno en nuestra escena. De vuelta en el método createScene, agregamos la siguiente línea de código:

mSceneMgr->setWorldGeometry("terrain.cfg");

Con esto invocamos el método “setWorldGeometry” del SceneManager de tipo ST_EXTERIOR_CLOSE (por ejemplo, el tipo genérico no puede hacer eso), el cual indica (en su argumento) el lugar de donde se van a cargar los datos de la geometría de nuestro “mundo” 3D; básicamente el terreno de la escena. Nótese que estamos cargando el archivo de configuración de terreno que acabamos de editar.

Eso es todo. Compilando y corriendo nuestra aplicación ya deberíamos poder ver nuestro terreno. Si no estás de acuerdo con el nivel de detalle de tu mapa, puede ser útil jugar con las propiedades del terreno (o cambiar las texturas). Por ejemplo, mi terreno era muy poco accidentado, así que aumenté en 50 unidades MaxHeight. El mapa cambió radicalmente:

Mismo mapa con MaxHeight ligeramente aumentado

Si alguno de los conceptos no ha quedado claro, es fácil experimentar utilizando texturas diferentes y observando el resultado. También podemos agregar letras o símbolos a las texturas para ver de qué manera se repiten en el producto final.

Sólo resta actualizar nuestra documentación:

Application
void chooseSceneManager(void)
void createScene(void)
Root
SceneManager createSceneManager(String typeName)
SceneManager
void setSkyBox(bool enable, string materialName)
SceneNode getRootSceneNode()
void setAmbientLight(ColorValue color)
void setWorldGeometry(String filename)
Entity createEntity(string entityName, string meshName)
Light createLight(string name)

9 - Vectores y Planos en el espacio

9 - Vectores y Planos en el espacio

En OGRE también podemos crear nuestras propias mallas con programación. Por supuesto, esto sólo conviene para usos simples (para propósitos más complejos debemos usar software de modelado 3D, aunque siempre podemos definir a mano los 500 vértices de nuestra malla… pero a estos valientes les dejo la investigación por su cuenta: “geometría estática”). Estas mallas son “especiales”: consumen poca memoria, y no las podemos mover (excelentes para partes del escenario como rocas y montañas).

Alerta de frustración inminente: En esta guía (y en OGRE en general) se usan conceptos básicos de Geometría Euclidiana, entre otros conceptos matemáticos de nivel universitario. Si no estás dispuesto a aprender al menos sobre vectores, olvídate del desarrollo de juegos 3D para siempre. En caso contrario, antes de proseguir asegúrate de entender lo que es:

  • Vector en espacio 3D.
  • Vector normal a una superficie.
  • Vector unitario.
  • Vectores paralelos y perpendiculares.

También se pueden encontrar en internet tutoriales sobre desarrollo de juegos 3D en general, que explican estos y otros conceptos sobre vectores 3D.

Internamente, OGRE calcula los sólidos como ecuaciones matemáticas. Los sólidos básicos que tratamos se representan por ecuaciones diferenciales que les representan (Por ejemplo, el plano se representa por una ecuación de 3 variables: Ax + By + Cz = 0). Por esta razón los argumentos de las funciones pueden resultar poco “intuitivos” para personas que no hayan tenido contacto con estas matemáticas.

El eje de coordenadas en OGRE

El espacio 3D en OGRE es representado por el siguiente sistema de coordenadas (agrego la pantalla para ilustrar cómo se ve desde la cámara inicial):

Eje de coordenadas, con la cámara por defecto

Cómo se puede observar, inicialmente nuestra cámara está mirando en dirección “-Z”.

Vectores unitarios en OGRE
 
La clase “Vector3” representa un vector en 3D, con sus 3 componentes “X”, ”Y” y “Z”. Los vectores los usaremos ahora y siempre para representar una posición en el espacio, o para determinar una orientación (dado que los vectores apuntan en cierta dirección). En el caso de la orientación, resulta útil tener los vectores unitarios a la mano:

Vector3::UNIT_X representa un vector unitario en dirección X (1,0,0)
Vector3::UNIT_Y representa un vector unitario en dirección Y (0,1,0)
Vector3::UNIT_Z representa un vector unitario en dirección Z (0,0,1)

Las versiones negativas de dichos vectores son, respectivamente Vector3::NEGATIVE_UNIT_X, Vector3::NEGATIVE_UNIT_Y y Vector3::NEGATIVE_UNIT_Z.

Finalmente, cuando queramos definir nuestros propios vectores usaremos:

Vector3(posiciónX, posiciónY, posiciónZ)

Los 3 argumentos son números reales.

Planos


Un plano en el espacio 3D

En nuestro primer ejemplo (el cielo sin nada) agreguemos en el método CreateScene el siguiente código:

Plane plane(Vector3::UNIT_Y, 0);

Con esto preparamos un objeto de tipo “Plane”, el cual define un plano en el espacio. Los argumentos son un vector normal al plano, y una distancia inicial a la cual podemos mover el plano desde el origen, en dirección de su normal.

 Luego agregamos esto para crear su malla correspondiente:

MeshManager::getSingleton().createPlane("mallaPlano",
        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
        100,100,20,20,true,1,5,5,Vector3::UNIT_Z);

El objeto MeshManager es el encargado de administrar los recursos que corresponden a las mallas. Podemos usarlo para crear nuestros sólidos básicos. Lo usamos de esta manera:

MeshManager::getSingleton()

, para que la plantilla “Singleton” sea compilada al momento de implementar la clase (La API tiene la explicación concreta, no le veo sentido a descifrar ese jeroglífico en un tutorial para novatos).

Del MeshManager usamos el método createPlane para crear la malla del plano, con los siguientes argumentos (en orden):

  1. Nombre de la malla resultante.
  2. Nombre del grupo de recursos al cual se asignará la malla (ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME pone el nombre por defecto).
  3. Objeto de tipo “Plane” al cual asociaremos la malla.
  4. Ancho.
  5. Alto.
  6. Número de segmentos del plano en dirección X.
  7. Número de segmentos del plano en dirección Y.
  8. Crear las normales perpendiculares al plano? (true o false).
  9. Número de sets de coordenadas para textura.
  10. Número de veces que se repite la textura en dirección u.
  11. Número de veces que se repite la textura en dirección v.
  12. Un vector que representa la dirección “hacia arriba” en la superficie del plano. No puede coincidir con la normal.

No es necesario entenderlos todos por ahora; solo nos importa el nombre, ancho, alto y el vector que representa “hacia arriba” (el resto lo copiamos tal cual). Básicamente, al crear un plano en OGRE debemos tener en cuenta su dirección normal (que será su orientación), sus dimensiones (ancho y alto) y su dirección “hacia arriba”, la cual siempre debe ser perpendicular la normal (probablemente este vector sea necesario cuando agreguemos texturas uv en el plano); en caso contrario nuestro plano se deformará. Por ejemplo:

Nótese que, en el ejemplo de la imagen, la dirección “Arriba de la superficie” es perpendicular a la normal (no importa hacia donde apunte siempre que sea perpendicular).

Habiendo creado nuestra malla del plano, la asociamos a una entidad de esta manera:

Entity *ent;
ent = mSceneMgr->createEntity("EntidadPlano", "mallaPlano");

Nótese que, en vez de poner el nombre de nuestro archivo de malla, hemos puesto directamente el nombre de la malla que hemos creado en OGRE. Esta es otra manera de usar createEntity.

Finalmente, creamos un nuevo nodo de escena y le anexamos la entidad igual que siempre:

mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);

Compilamos y corremos el programa. Después de tanto quilombo… ni siquiera podemos ver el plano! Lo que sucede es que el plano está en el origen de coordenadas, su superficie está mirando exactamente hacia arriba (normal en dirección “Y”) y el espesor de un plano ideal es infinitamente delgado. La cámara está mirando el plano exactamente de lado (si navegas con las flechas y el mouse podrás ver el plano desde arriba).

Observa detenidamente el plano. Dale algunas vueltas. Has notado que sólo lo puedes ver si lo miras desde arriba? Si lo ves desde abajo parece que el plano no está ahí. No se trata de un error; OGRE sólo muestra una superficie si la estamos viendo desde su dirección normal. Como la normal del plano apunta hacia arriba, sólo podemos ver el plano desde arriba.

Para poder ver el plano desde el inicio de la aplicación, debemos moverlo. Podemos aprovechar el segundo parámetro del constructor de Plane para poner el plano más debajo de la cámara:

Plane plane(Vector3::UNIT_Y, -120);

El plano ya aparece al momento de correr la aplicación. Otra manera es ponerle una normal en dirección Z (ya que la cámara inicialmente está mirando en dirección -Z) para que la superficie (visible) del plano aparezca directamente hacia nosotros:

Plane plane(Vector3::UNIT_Z, 0);
MeshManager::getSingleton().createPlane("mallaPlano",
        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
        100,100,20,20,true,1,5,5,Vector3::UNIT_Y);

Nótese que hemos cambiado la dirección “hacia arriba” de la superficie del plano para que no coincida con la normal.

También podemos poner un vector (de cualquier magnitud) que apunte en una dirección diagonal:

Plane plane(Vector3(1,1,1), 0);
MeshManager::getSingleton().createPlane("mallaPlano",
        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
        100,100,20,20,true,1,5,5,Vector3(-1,1,1));

Esta vez he puesto una dirección “hacia arriba” que apunta en una dirección perpendicular a la nueva normal. Obviamente el cálculo de dicho vector nos complica un poco las cosas.

Probablemente la solución más fácil sea:
  1. Crear el plano mirando hacia arriba (esto nos facilita imaginar los vectores que deseamos).
  2. Asociarlo a un SceneNode.
  3. Rotar el SceneNode (la entidad rotará completa con él).

En general, aplicamos transformaciones como “escalar”, “rotar” y “trasladar” al SceneNode en vez de a la Entidad que se le anexa. La manipulación de SceneNodes hace parte de otro tutorial. Por ahora, actualizamos la documentación:

Vector3
Vector3(Real x, Real y, Real z)

Plane
Plane(Vector3 normal, Real distance)

MeshManager
MeshPtr createPlane(String name, String groupName, Plane plane, Real width, Real height, int xsegments, int ysegments, bool normals, int numTexCoordSets, Real uTile, Real vTile, Vector3 upVector)

8 - Agregando una malla en OGRE

8 – Agregando una malla en OGRE

Malla insertada en la aplicación de ejemplo

Ya tratado el tema de preparar una malla de Blender para OGRE, veamos cómo se puede insertar en la aplicación de ejemplo que se explicó en el primer tutorial. Primero, veamos cómo entiende OGRE las mallas.

Como se dijo antes, el SceneManager es quien administra las mallas, luces y cámaras en su escena (por ejemplo, recuerda sus posiciones).

En la escena, a todo aquello que es representado por un objeto 3D (casas, muñecos, aviones, etc.) se le llama entity (entidad); si algo se puede renderizar, es una entidad. En OGRE, las entidades son solo “apariencias” (la idea de cómo se vería algo) que existen, pero no se sabe donde están, de qué tamaño son, etc.

La posición y la orientación de una entidad se representan en un SceneNode (nodo de escena). Son como espíritus que existen pero nadie los puede ver. Para agregar una malla a nuestra escena, primero agregamos un SceneNode, y a este se le anexa (asocia) su entidad correspondiente.

A los SceneNodes también les podemos anexar otros SceneNodes. Así, podríamos anexar al SceneNode de un niño, el SceneNode de su perro, y siempre estarían juntos.

Los SceneNodes siempre son “hijos” de otro SceneNode (que sería su “padre”). La única excepción es el Nodo raíz (rootNode). El nodo raíz es el “centro del universo”; las posiciones de sus nodos hijos siempre son relativas a la posición del nodo raíz (Es decir, donde esté el nodo raíz estará el punto (0,0,0) de nuestro sistema de coordenadas).

Haciendo la clásica analogía con Blender, tendremos algo como esto:

Analogía – Entity, SceneNode y Root Node

 Ahora vamos al código de ejemplo. Como se dijo antes, en el método createScene() es en donde se le dice a OGRE qué contiene nuestra escena. En el código de ejemplo tenemos el código que inserta una luz, y el que nos pone el cielo de fondo. En el mismo método, agregamos esto:

Entity *ent;
ent = mSceneMgr->createEntity("Muneco", "malla_muneco.mesh");
mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);

Revisemos línea por línea:

  • La primera línea nos declara el objeto “ent” de tipo Entidad.
  • En la segunda línea usamos el método createEntity de nuestro SceneManager, el cual devuelve un objeto de tipo entidad. Sus argumentos son el nombre que le ponemos a la entidad (“Muneco”) y el archivo de la malla .mesh que le corresponde. Dado que no hemos alterado el archivo resources.cfg, dicho archivo deberá estar en la carpeta models (como se dijo antes).
  • En la tercera línea suceden varias cosas al tiempo:
    mSceneMgr->getRootSceneNode()
    Obtenemos el objeto del nodo raíz de la escena del SceneManager. Retorna el objeto tipo SceneNode de dicho nodo.
     
    getRootSceneNode()->createChildSceneNode()
    Creamos un SceneNode “hijo” del nodo del cual estamos llamando este método (en este caso, el nodo raiz). El nuevo nodo tendrá la misma posición y orientación que su padre (en este caso, aparecerá en (0, 0, 0)). Retorna el nuevo objeto SceneNode que se creó.
     
    createChildSceneNode()->attachObject(ent)
    Este método del nodo creado hace que a dicho nodo le anexemos el objeto que le damos por parámetro (en este caso, le anexamos la entidad “ent”). No retorna nada.

Básicamente, lo que hemos hecho es agregar un nuevo nodo a la escena y anexarle una entidad ya creada, todo en una sola línea.

Eso es todo. Compila y corre el programa; la malla ya debería aparecer. Para acercarnos o alejarnos usaremos las flechas del teclado en conjunto con el mouse que controla la “mira”.

Puede que hallas notado que la malla está más iluminada de lo normal. Esto se debe a que inicialmente en la escena OGRE nos ha puesto una “luz ambiental” bastante fuerte (recuerda que estamos usando el SceneManager que se nos crea automáticamente). Agrega esta línea para cambiarle la intensidad:

mSceneMgr->setAmbientLight(ColourValue(0.2, 0.2, 0.2));

Esto pone la luz ambiental de la escena más tenue para que se puedan ver mejor los colores. Nótese que el argumento es un objeto de clase “ColourValue”, que es una manera de representar un color en OGRE (los parámetros son, igual que en las luces, la cantidad de rojo, verde y azul). Las luces hacen parte de otro tutorial, sin embargo ya puedes ir jugando con los parámetros para ver qué sucede.

Cómo vimos antes, en la carpeta “models” hay varias mallas; podrías probar con las otras a ver qué pasa. Por ejemplo, con “athene.mesh” obtenemos:

Eso es todo por ahora. Recuerda ir actualizando tu documentación:

SceneManager
 
void setSkyBox(bool enable, string materialName)
SceneNode getRootSceneNode()
void setAmbientLight(ColorValue color)
Entity createEntity(string entityName, string meshName)
Light createLight(string name)
SceneNode
 
SceneNode createChildSceneNode()
void attachObject(MovableObject object)
ColourValue
 
ColourValue(float red, float green, float blue)

7 - Preparando un modelo simple de Blender para trabajar con OGRE

7 – Preparando un modelo simple de Blender para trabajar con OGRE

(Nota: Para seguir esta guía es necesario haber realizado la guía “6 - Preparar Blender para exportar a OGRE.doc”).

En OGRE las mallas se representan como archivos de extensión “.mesh”. Dado que OGRE no incluye un editor de figuras 3D, recurrimos a software de terceros para crear los modelos, y posteriormente los transformamos en “.mesh” para que puedan ser interpretados por OGRE.

En esta guía vamos a preparar un modelo simple de Blender para trabajar con OGRE. Para el propósito he preparado un modelo antropomorfo color púrpura (sí, es un hombrecito):

(Horrendo) modelo en Blender

En fin, nada que un usuario de Blender no pueda lograr haciendo extrusión a un cubo durante un par de minutos (nótese que el modelo no tiene texturas, esqueleto, nada raro). Para pasarlo a OGRE, primero lo exportaremos mediante el script “Ogre Mesh Exporter” a un formato XML, y luego mediante la herramienta “OgreXmlConverter” lo pasaremos de XML a mesh:

Nota: Estas herramientas son producidas por terceros. En lo posible no hagamos modelos con errores, vértices raros, normales mal puestas etc. para que la exportación no falle (si, puede fallar). Si tu modelo es correcto no tendrás problemas.

Por conveniencia, le he puesto el nombre “malla_muneco” a la malla en Blender. Para transformarlo debemos:

  1. Con el modelo abierto en Blender, vamos a “File” -> “Export” -> “OGRE meshes”. Nos aparece esto:
    Exportador de mallas a OGRE
  2. En “Material File” ponemos “mat_azul.material”. Es el archivo con información del material.
  3. En “Path” ponemos la ruta de destino para los archivos exportados.
  4. Activamos “Fix up axis to Y” para intercambiar el eje Z (“arriba” en Blender) por el eje Y (“arriba” en OGRE).
  5. Desactivamos “Skeleton name follow mesh” porque no tenemos esqueleto.
  6. Clickeamos “Export”. En la carpeta de destino aparecerán los archivos “malla_muneco.mesh.xml” y “mat_azul.material”.
  7. En el explorador de Windows, arrastramos el archivo xml generado y lo soltamos sobre el acceso directo que le hicimos al “OgreXmlConverter”.
  8.  
    Arrastrando el XML al acceso directo de OgreXmlConverter
     
    Se generará el archivo .mesh en la carpeta de origen.

    En el ejemplo, se generó el archivo “malla_muneco.mesh”, el cual representa la malla que creamos en Blender, y el archivo “mat_azul.material”, el cual es un script que representa el material que teníamos asignado a esa malla.

    Para poder usar nuestros modelos en OGRE, debemos ponerlos en ciertas carpetas especiales (determinadas en el archivo “resources.cfg”). Por defecto, tendremos las siguientes carpetas (entre otras) en nuestro directorio de OGRE:

    En la carpeta “models” se encuentran los modelos (si la revisas en el explorador de Windows, encontrarás muchos archivos .mesh de ejemplo). En la carpeta “materials” se encuentran los materiales. Los materiales representados por un script (como el que acabamos de generar) se ponen en la carpeta “scripts”.

    Así, el archivo de la malla lo debemos copiar a la carpeta “OgreSDK\media\models”, y el material lo copiamos en “OgreSDK\media\materials\scripts”. Con esto ya tenemos todo listo para agregar nuestra malla a una escena de OGRE.
Distribuir contenido