rumboartfutura
Sunday, July 31, 2005
código del mes
En el juego que estamos preparando para art-futura05 tenemos que hacer un editor para que el usuario se construya sus propios objetos. El juego está fuertemente orientado al 3D, con lo cual el editor tiene que dar un interface sencillo pero que permita controlar perfectamente las 3 dimensiones. Lógicamente el objeto se construye en base a otros más simples que el usuario debe colocar. Aquí es cuando viene el problema, hay que diseñar un sistema que permita que el usuario con el ratón seleccione en su pantalla (un entorno 2D) un objeto que está en un entorno 3D. Para ello OpenGL aporta un mecanismo llamado picking, que dándole las coordenadas del ratón (x,y) te retorna el objeto que se ha pinchado. Dicho así resulta simple, pero tiene algunos escollos que conviene salvar antes de hacer algo decente.Para resolver el problema he creado una pequeña clase, que, aunque es muy simple, ayuda bastante:
class Picking:
def __init__(self):
pass;
self._buf = 1024*[1];
def Init(self, cursor):
#viewport = [0,0,0,0];
self._buf = glSelectBuffer(1024);
glRenderMode(GL_SELECT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
viewport = glGetInteger(GL_VIEWPORT);
gluPickMatrix(cursor[0],viewport[3]-cursor[1],
1,1,viewport);
gluPerspective(45,1.3333,0.2,200);
glMatrixMode(GL_MODELVIEW);
glInitNames();
def Push(self,i):
glPushName(i);
def Pop(self):
glPopName();
def End(self):
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glFlush();
return glRenderMode(GL_RENDER);
De esta forma le das las coordenadas del ratón, renderizas indicando los identificadores de los objetos y al terminar te retorna lo que has pinchado.
Lo paradójico del tema es que mirando después la documentación de pyopengl me doy cuenta que en GL__init__.py hay un wrapper muy parecido a este, pero que en vez de usar una clase, usa una función con un callback, que será la función de render.
En fins.. :_)
Editando
Bueno, teniendo la base (muy básica) del motor del juego, ahora empiezo a codear el editor para que el usuario cree sus propios ________. Como siempre, antes de empezar a hacer una cosa hay que pensar muy bien lo que se va hacer, y qué mejor que una imagen de coder para ver el diseño?
Además, mientras el usuario construye su ______ he decidido poner una vista en 3D, supongo que perpectiva isométrica, para ello después de hacer el render de la escena editada, haré lo siguiente:
1.- Reducción viewport a una de las esquinas de la pantalla
2.- poscionar la cámara
3.- Render del objeto
4.- Restaurar viewport
Incluso puedo hacer un render a textura, colocarlo en un quad y que el usuario pueda moverl la vista 3D por la pantalla. Esas florituras para cuando nos sobre tiempo, que no nos va a sobrar XD.
Thursday, July 21, 2005
Avanzamos: Controles
Bien, después de pegarme con ODE unos días he programado el primer prototipo controlado por el usuario. De momento tiene controles muy básicos, pero creo que se quedará así, ya que quiero que el resultado final sea muy simple de manejar (como mucho 4 teclas).ODE está funcionando a la perfección, sin utilizar el algoritmo quickstep va rápido y usándolo no hay ningún problema de estabilidad. Me queda por rematar el tema de las uniones rompibles. Tengo un pequeño prototipo, sin embargo no estoy muy contento porque, aunque es realista, no creo que aporte nada a la jugabilidad. Por eso creo que me voy a saltar a la torera la física real y voy a usar un algoritmo propio para añadirle jugabilidad y así dejarme una puerta abierta para modificar a mi gusto.
En cuanto a la parte gráfica aún no hay nada hecho, pero creo que a mediados del mes que viene tendré todo lo necesario para empezar a meter tema gráfico. Confío en la capacidad de zwitter para crear los gráficos necesarios, que creo que no serán demasiados (aunque hay que tener cuidado con los "creos").
Para terminar de rematar la planificación, creo que a partir de la fecha marcada se podrá empezar, además de meter tema gráfico, ajustar la jugabilidad que creo que será uno de los puntos fuertes del juego.
Diseño
Como siempre que se hace algo sin pensar demasiado en el diseño te encuentras problemas que no habías planteado que debes resolver. La cuestión aquí no es resolverlo, si no resolverlo o resolverlo bien.Recuerdo uno de mis primeros días de trabajo en el que me dijeron una frase que nunca olvidaré: "lo mejor es enemigo de lo bueno". La frase es la filosofía de una gran parte de empresas españolas, en especial las PYMES, y desde luego es la filosofía que llevaban en aquella empresa ( INTRAME S.A. ). Sin embargo esta vez voy a resolverlo por el camino de lo mejor, que en este caso será amigo de lo bueno.
Al grano, necesito tener una estructura que agrupe estructuras del mismo tipo, esto es, un árbol. Esto no es complejo de implementar en cualquier lenguaje, por ejemplo, C++:
class Foo
{
typedef std::vector < Foo > Container; //std::list, Foo*, etc
Container _childs;
};
o python:
class Foo:
def __init__(self):
self._childs = [];
El problema aquí es que por debajo tengo ODE y cada objeto tiene un BODY que representa el sólido rígido del mismo, por lo tanto las agrupaciones de objetos no tendrán BODY, ya que ODE calcula sus posiciones en función de esos BODY. A su vez tengo el problema de que algunos objetos pueden dividirse en muchos otros, cada uno con su BODY y a su vez puede que cada uno de esos BODY tengan varias geometrías agrupadas.
Un jaleo, veremos como lo resuelvo.
Por cierto, decir que el juego va tomando forma, ya se empiezan a ver formas que se "verán" al final del mismo.
problemas
Como comenté el otro día tuve problemas al intentar mover toda una estructura a base de uniones fijas, debido en principio a la inestablidad y posteriormente a problemas de velocidad. La aplicación dee moverse con soltura para que el juego tenga una jugabilidad aceptable, ya que se trata de un juego que tendrá acción.Después de leer la documentación y bucear por las listas de correo de ODE, encontré una forma que podría resolver mis problemas. Nada mas venir de sanfermines me puse a codear como un loco y después de una hora conseguí portar todo el código de la estructura la la nueva forma de definirlas. Los problemas surgieron por la visualización dummy que tengo hecha en base a cubos, esferas y cilindros, ya que no se adaptaban del todo bien a la física.
El siguiente paso es buscar unos puntos de soporte sobre el suelo, pero no puedo dar más datos. Como siempre, un screen, esta vez de una estructura creada en base a unos cuantos datos que tendré que aportar el usuario y unos cubos interaccionando con él. Una lástima que no pueda subir videos :/.
Wednesday, July 06, 2005
down2up
Habitualmente las cosas se construyen de un nivel de complejidad bajo a uno más alto uniendo pequeñas elementos simples para formar complejos. En este caso estoy creando estructuras en base a elementos simples, sin embargo estoy encontrando problema tras problema.El sistema usado es el siguiente: creo los objetos y posteriormente los uno mediante uniones fijas. Esto genera dos problemas, el primero son los problemas de que los objetos chocan continuamente y eso genera contactos que a su vez carga el sistema. Esto se resuelve fácilmente separando un poco los objetos entre si. El segundo problema es que si se aplica una fuerza débil a la estructura, ésta empieza a oscilar y termina por ser inestable. Este segundo problema se resuleva usado un sistema más complejo de integración (ODE provee dos, unos rápido y otro standard).
Me encuentro en una calle sin salida, por un lado no puedo usar el método standard porque resulta demasiado lento y por otro no puedo usar el rápido porque oscila. Es posible que el método que uso para conectar los objetos no sea el mejor para este caso, es por ello que estoy buscando salidas por otro lado. Esta salida es usar compositeobjects, que lo que viene a ser es un cuerpo formado por diferentes geometrías. Lo que debo estudiar es si con este tipo de estructuras es posible romper uniones sin demasiada complejidad, esto es, tener que volver a generar el cuerpo y calcular el centro de gravedad, etc.
arg!
Monday, July 04, 2005
gráficos de coder
Necesitaba saber a partir de un punto en coordeandas cartesianas (x,y,z), sus coordenadas polares (theta,rho, módulo). El problema es que cada vez uso una notación diferente y termino liándola, metiendo bugs y teniendo representaciones de objetos físicos sin sentido.Para evitarlo decidí hacer un esquema para añadirlo al documento de diseño (adaptativo, puesto que se va haciendo al aire XD). El descriptivo esquema es el siguiente:
arrancamos
Lo primero que hay que hacer después de tener la idea del juego es plantear un boceto técnico, un prototipo. Puesto que se trata de tener algo jugable para septiembre la decisión del lenguaje y librerías es fundamental. Para ello he elegido un lenguaje que conozco a la perfección y que tiene bindings a las librerías más importantes (opengl, ODE, etc), python.El siguiente paso es comprobar que python es capaz de mover todo el sistema. El juego promete tener alta carga, y aunque los módulos que carga python están en su mayoría implementados en C/C++, tenía que comprobar qué tal funcionaba. Manos a la obra me bajé las librerías necesarias y comencé a jugar con ODE, pygame y opengl para hacer una pequeña demo de físicas. Después de meter unos cuantos cubos, unas cuantas contraits, etc, vi que pyODE tenía la potencia suficiente para llevar a cabo el juego.
Aquí dejo una pequeña imagen:
