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.

No hay comentarios:

Publicar un comentario

Gracias por tu comentario! :)