viernes, 14 de mayo de 2010

MOC, Minimal Ogre Collision 1.0

Vamos a intentar explicar, esta librería o utilidad, para realizar colisiones un poco mas complejas en Ogre. No veremos en su totalidad su funcionamiento en este tutorial, pero si lo mas fundamental, para realizar colisiones un poco mas complejas. Lo primero es poner en conocimiento que las imágenes y mayoría de información esta sacada de la Wiki de MOC.

Para empezar vamos a entender la diferencia de la Colisión simple explicada en el tutorial anterior con esta, y del por que de su uso. En la colisión simple por AABB, este método consistía en envolver con una caja de coordenadas la entidad y sobre dicha caja de coordenadas, preguntar sobre colisiones, pero que ocurre si la entidad no tiene la misma forma que la caja de coordenadas, la colisión no sería exacta a la entidad si no sería sobre la caja de coordenadas que la envuelve. Con esta imagen se entederá mejor lo que quiero explicar:



MOC usa el metodo del rayo,  como bien se ve en la imagen de la izquierda. Dicha colision se basa en un rayo que va dede el punto de origen al punto de destino, y colisionando sobre el objeto. Este metodo del rayo está en Raycasting_to_polygon_level. Para saber si el rayo ha colisionado en el objeto y no en su eje, este metodo, tambien necesita del metodo que devuelve la informacion de la entidad, este metodo está en RetrieveVertexData, aqui hay un metodo GetInformationMesh(...) .

Mesh es la malla que esta compuesto cualquier modelo tratado en Ogre. Cuando exportamos un modelo y lo convertimos a un fichero .Mesh, entre otras cosas, lo que se hace en dicha exportación es convertir toda la formación del objeto creado en nuestro 3dstudio, en mallas, con muchos vertices, para así despues poder leerlo. Si no se a entendido lo que he querido explicar (que será lo mas evidente :P ) un dibujo para salir de dudas:



En la imagen el Mesh sería la de la izquierda el resultado de la trasformación del dibujo de la derecha. Retomando lo que queriamos explicar, el metodo GetInformationMesh, basicamente devuelve la cantidad de vertices de un objeto,  un array con la informacion de en coordenadas de los vertices....

Una vez sabido esta informacion es preguntar con el metodo Ogre::Math::intersects, pasandole como parametros el rayo y los puntos Z,Y y Z, para saber si dicho rayo a llegado al objeto. Basicamente preguntariamos por la distancia de este rayo para saber si ha colisionado o no con el objeto.
Una vez explicado como funciona el metodo del Rayo, ya entendemos de manera basica como funciona MOC, para realizar las coslisiones.

Lo primero que debemos hacer es bajar l versión de MOC que viene en la Wiki de MOC, una vez descargada la version 1.0, desmcomprimimos el RAR, y aparece un CollisionTool.H y CollisioTool.CPP, los cojemos y lo colocamos en sus respectivas carpetas de nuestro proyecto, y ya solo con esto podemos empezar a funcionar con MOC. Vamos a intenar explicar un poco sus metodos:

Los metodos mas importantes son ()->raycast(...) y GetInformationMesh, todos los demas metodos del MOC llaman a estos dos, par devolver calculos.

  • rayCastFromCamera, -> saca un rayo desde la camara y devuelve una Entidad, con la cual a colisionado, este metodo esta bien para seleccionar objetos de la pantalla, tal cual como un juego de estrategia, que con el raton eliges un objetivo. Este metodo y el showBoundingBox del nodo podemos marcar una entidad u otra.
  • CollidesWithEntity-> devuelve un booleano, para saber si ha colisionado con un objeto o no, es un metodo facil, pero no devuelve ninguna otra informacion.
  • getTSMHeightAt y calculateY, son metodos usados, con terrenos, para saber la distancia hasta el terreno y calcular la y para saber si la camara esta por encima de un monticulo o no. Lo veremos mas adelante, en otros tutoriales de terreno.

Veamso un ejemplo de colisión con MOC:

//Resultado de la colisión, donde el rayo intercepta los verttices que componen el objeto
Ogre::Vector3 results = Ogre::Vector3::ZERO; 
//El objeto que ha sido colisionado
Ogre::Entity *tmpE = NULL;  
//Distancia hasa la colisión
float distToColl = 0; 

//Este metodo devuelve un boolean, para que sepamos cuando ha colisonado
if(col->raycast(Ogre::Ray(mSceneMgr->getSceneNode("PELOTA")->getPosition(),mSceneMgr->getSceneNode("PARED")->getPosition()),results,tmpE,distToColl,Ogre::SceneManager::ENTITY_TYPE_MASK)){
FKT::TextRenderer::getSingleton().setText("texto","Colision "+tmpE->getName());

}


Todos los demas metodos del MOC, llaman a este para reealizar las operaciones.
Con este tutoral ya podemos saber cuando un objeto  ha colsionado con otro y donde.

Hasta la proxima.

miércoles, 12 de mayo de 2010

Colisiones Simples AABB

En este tutorial, vamos abarcar la colisión, a mi manera de ver la mas simple que se puede hacer con Ogre, con la AABB, Axis Aligned Bounding Box, el eje de la caja dde coordenadas, toda esta informacion te la puedes encontrar en la Wiki de Ogre, aqui vamos a explicarla un poco y sacarle uso. En el proyecto del TENIS que estamos realizando, no vamos a incluir este tipo de Colisión, ya que utilizaremos MOC, una libreria, que explicaremos en el siguiente Tutorial.

Bueno, la caja de ejes de coordenadas, se genera el cualquier entidad generada en nuestro proyecto, podemos mostrarla para verla, con la propiedad showBoundingBox(true); del nodo asociado a esta entidad. En la sguiente imagen vemos como la caja de coordenadas envuelve a toda la entidad.


Para saber recoger esta caja, el mismo nodo que contiene la entidad nos ofrece un metodo llamado _getWorldAABB(), que nos devuelve un objeto de tipo: AxisAlignedBox, con algunos metodos interesantes

  • getMaximun(), getMinimun() -> devuelve un Vector3 con los valores maximos y minimos de esta caja.
  • getCenter() -> nos devuelve un Vector3 con el centro de la caja.
  • intersection -> pide como parametro otro AABB, y devuelve el resultante, de dicha intersección o colisión.

Ogre::AxisAlignedBox aabResultado = mSceneMgr->getSceneNode("nodo1")->_getWorldAABB().intersection(mSceneMgr->getSceneNode("nodo2")->_getWorldAABB());
if(!aabResultado.isNull())
{


" Ha habido una colision ubicada en"+aabResultado->getMaximun()->getCenter();


}

Realizando calculos, respecto a un eje, podriamos saber donde ha colisionado, por ejemplo en el tenis podriamos saber si ha colisionado en la parte de arriba centro o abajo.

  • contains -> Este metodo devuelve true o false para saber si un AABB contiene a otro.

Este metodo es muy util para saber si un objeto se encuentra o se ha encontrado alguna vez dentro de otro en su totalidad. Por ejemplo podriamos saber en el Juego del tenis si la pelota a traspasado la paleta.

En definitiva con el metodo _getWorldAABB() de los nodos, podremos saber de manera simple y facil si ha habido alguna colision entre objetos, para saber mas mirar el ejemplo creado de CuboLoco v2.

martes, 11 de mayo de 2010

FKT Utilidades

/*
-----------------------------------------------------------------------------
Filename: FKT.cpp
-----------------------------------------------------------------------------


This source file is generated by the

Ogre 1.7.x Application Wizard for VC9 (Mayo 2010)
http://www.freakteamdev.tk
-----------------------------------------------------------------------------
*/

Para hacer uso mejor de las utilidades que nos vamos encontrado por la red, vamos a publicar un .H y .CPP,
para reunirlas, con añadidos de otros compañeros que por afición van dejando esos trozos de codigo que en algun momento pueden ser muy utiles. Estará en continuos cambios en funcion del proyecto que estemos abarcando. Aqui os paso el link para la descarga del FKT.h y FKT.cpp, con dos utilidades usadas, en CuboLoco v2. Download FKTUtils

  1. EntityUtil, es una clase para recojer esa información que se encuentra en los SceneNode y tenemos que ir guardando en las variables que vamos creando en nuestro codigo, por ejemplo la variable de incremento de escala, o guardar la posicion de algun momento de la aplicacion, o un boolean para darleotro tipo de estado a un nodo o entidad, este EntityUtil se enlaza con el nombre del Nodo.
  2. TextRenderer es una utilidad muy util para realizar muestras de texto por pantalla, sin tener que utilizar el log o un label.

Su uso:

Tenemos que declararlo en cualquier parte del codigo, por ejemplo en createScene()

new FKT::TextRenderer(); // Solo lo instanciamos una vez

Y ya podemos usarlo

FKT::TextRenderer::getSingleton().addTextBox("texto","",0,0,100,200,Ogre::ColourValue::Green);

Y asi podemos hacer un Update del texto

FKT::TextRenderer::getSingleton().setText("texto",Ogre::StringConverter::toString(aab.getSize()));

Este texto debes de tener instalado en los archivos OGRE_HOME/media/fonts/sample.fontdef el Font Starwars, es el tipo de letra que usa.

domingo, 9 de mayo de 2010

2º Versión del CuboLoco, ahora con colisiones

Aqui presentamos la 2º version del CuboLoco, ahora con colisiones simples, utilizando la AABB, Eje Coordenadas de la Caja Alineados.


Siguientes tutoriales explicaremos colisiones simples....

sábado, 1 de mayo de 2010

Rotate, position y Scale


Ampliando el tutorial primero de la wiki de Ogre, vamos a realizar un ejercicio de un Cubo, rotando sobre si mismo y chocandose, con las paredes de la ventana, para ir reforzando los tutoriales anteriores con este. Basicamente es un ejemplo de reocjer los enventos de los botones, hacer operaciones basicas sobre un cubo.

En la version de codigo fuente, está la carpeta del projecto en VS2008, mas una carpeta media, que deberis copiar y pegar en OGRE_HOME, que son los modelos, el archivo material y el png del logo.


En la version ejecutable del ejemplo, se ejecutará solo en modo OpenGL, para verlo en con DirectX, necesitas tener instalada la verson DirectX, la misma que desatives en puglins.cfg.