[Extensión] 3Dit, programar con Bennu 3D usando únicamente las LOCAL de Bennu 2D

Started by Windgate, February 02, 2010, 09:10:21 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Windgate

Gran sugerencia Grisendo.

Bennu 3D no es como Bennu 2D. Te sorprenderá, pero no es necesario un proceso activo para que el "graph" se mantenga en pantalla, aquí un sólo proceso puede gestionar miles de modelos a la vez.

Pero con una comprobación de si el padre muere en el proceso make_3dit ( ) y un ONEXIT encargado de destruir todo lo que ha creado sería suficiente. Gracias por su sugerencia y K++

Más sugerencias bienvenidas, esta última ha sido grande, estoy testeando ya con alumnos y no quisiera encontrarme con tremendas cagadas inesperadas como esta :S
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Windgate

- Añadida la funcionalidad de auto-remover el modelo cuando el proceso muere.
- Distintas funcionalidades de 3dit separadas en distintos módulos brevísimos.
- Añadido módulo para añadir cámaras estáticas y de autoseguimiento sencillísimas (p.ej add_follow_camera ( ogre ) donde ogre es el id de proceso a seguir).
- Añadido un doc con pruebas de rendimiento, probé a checkear cambios de valores antes de posicionar,rotar,escalar, el rendimiento empeora, supongo que las funciones 3D ya se encargaban de comprobar antes de cambiar.
- Añadido un Readme (En inglés) con instrucciones de uso, limitaciones, etc.

El código del dummy ya no realiza los test que ya estaban re-probados y funcionaban, el código que tiene movimiento, animación y gravedad queda así de sencillo:

PROCESS dummy ( )
BEGIN

make_3dit ( ); // Makes de process compatible with 3dit, let it use local 2d Bennu variables

// Loads a model file and a texture file
file = load_model ( "model/ogre/ogre.md2" );
graph = load_texture ( "model/ogre/ogre001.pcx" );

gravity ( map , 10 ); // Note that map is a GLOBAL with the terrain map loaded with load_terrain

LOOP

// Rotation test along y axis
IF ( key ( _A ) )
angle -= 2000;
ELSEIF ( key ( _D ) )
angle += 2000;
END

// Advance and animation test
IF ( key ( _W ) )
advance3d ( 4 );
flags = 1;
ELSEIF ( key ( _S ) )
advance3d ( -4 );
flags = 1;
ELSE
flags = 0;
END

FRAME;
END
END


DESCARGA: http://trinit.es/DescargaDirecta/Bennu3D/3Dit/3Dit%200.0.2.zip

EDIT: Por cierto, no recuerdo si añadí la prueba de 32K dummys:
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

grisendo

Ah! Se me olvidó comentarte, la gravedad lo que hace únicamente es mantenerte pegado al suelo, no? Porque hice un proceso-proyectil y estaba todo el rato al nivel del suelo, quité lo de "gravity" y entonces ya funcionó. Te paso el código que hice, por si te sirve o ves que no he entendido algo bien:

Código que aplica movimiento parabólico a un proceso, entradas: "proceso" - proceso a aplicar la parábola, "v0" - velocidad de lanzamiento, "a0" - ángulo del tiro con respecto al suelo, "b0" - ángulo de tiro izquierda-derecha (es decir, a donde está mirando el que lo lanza).

[code language="bennu"]PROCESS tiroParabolico3D(proceso, v0, a0, b0)
PRIVATE
   float t;
   float x0, y0, z0;
BEGIN
   t=0;
   x0=proceso.x;
   y0=proceso.y;
   z0=proceso.z;
   LOOP
       proceso.x=x0+v0*cos(a0)*sin(b0)*t;
       proceso.y=y0+v0*sin(a0)*t-(9.8*t*t/2); // 9.8m/s^2, o la gravedad que se quiera con un CONST
   proceso.z=z0+v0*cos(a0)*cos(b0)*t;
       t+=0.2;
       IF(proceso.y<0)
           signal(proceso, s_kill_tree); // TREE para matar al make_3dit, pero los objetos 3d se quedan ahí...
           BREAK;
       END
       FRAME;
   END
END[/code]

Y el proceso bala:

[code language="bennu"]PROCESS bala(x,y,z)
BEGIN
   make_3dit();
   // Sin gravity, o si no no vuela!!
   file=load_model("model/bullet/bullet.md2");
   graph=load_texture("model/bullet/bullet.pcx");
   LOOP
       FRAME;
   END
END[/code]

Forma de lanzarlo:
[code language="bennu"]tiroParabolico3D(bala(personaje.x, personaje.y, personaje.z), fuerza, angulo, personaje.angulo);[/code]

Windgate

La idea es buena grisendo, tenía en mente algo así pero pensaba basarlo en herencia, se hereda la rotación del emisor del disparo para que el tiro vaya en esa dirección, posiblemente reutilice tu código para la parábola, que es buena idea.

En cuanto a lo de matar el proceso con y<0 mejor usaré una función de cálculo de la altura del terreno en un punto, aunque eso implicaría que el terreno sea parámetro... No es bueno asumir la presencia de globales... Ya veremos como queda, de momento la eliminación de modelos al matar procesos debería funcionar con la 0.0.2

Próximos objetivos:


  • Gestión de modelos hijos: Poner armas y tal, además de disparos y otras modelos que heredan.
    Detección de colisiones para los muy muy burros :D
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

grisendo

Ok, reutiliza lo que quieras sí, y lo del y<0 era solo como prueba cutre (soy un poco maniático con la limpieza de memoria). Pero la idea es... debería funcionar la parábola con gravity o no? Lo digo porque vale, en este caso lo omites y ya está, pero en el caso de un personaje como el dummy que la utiliza para moverse por el suelo, si quieres hacerlo saltar, se podría?

Windgate

La gravity gestiona la y de forma que hagas lo que hagas con ellas la gravity es la que manda...

Para tener parábolsa no hay que poner gravity, hay que hacerla tú a mano o meter física con gravedad.

Es que es una historia compleja, actualmente la llamada gravity es un simple manejador rápido de colisiones con el terreno, por lo que mantiene los elementos pegados al terreno sin más.

Ya haré algo al respecto tranqui, en el tema de colisiones todavía no he terminado de investigar.
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

grisendo

Guapo, guapo, guapo esto del 3D... He probado la nueva versión, por fin desaparecen los muñecos 3D al matar su proceso correspondiente! :)

He notado cierto "atascamiento" en la animación de andar, pero debe ser porque estoy usando wine, el otro día utilicé windows con la segunda versión y funcionaba perfecto.

He de confesar una cosa, soy tan vago que mi personaje dispara lo primero que pillé por internet de md2: delfines (http://telias.free.fr/models_md2_menu.html) xDDD Bennu3D también carga como .obj, .3ds y tal, no?

Windgate

Sí, se lo traga todo Bennu 3D, te dejo la última versión de la documentación que estoy preparando, están todas las funciones descritas, en español, al 95% porque algunas todavía no he podido probarlas a fondo. También vienen los formatos soportados y alguna cosita más:

http://trinit.es/temario/Lista%20Funciones%20Bennu%203D.pdf

No es el 3dit, es el Bennu3D puro y su sintaxis es más fea que el Fary comiéndose un limón, pero bueno, cosas peores he visto.
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Windgate

Ayudenme ustedes por favor.

Como ya sabéis, la función make_3dit ( ) es la que prepara cualquier proceso para ser compatible con 3Dit y responder a las modificaciones en sus variables locales:

x,y,z - posición en 3D.
angle - rotación (En milésimas de grado) en el eje y.
size - tamaño en tanto por ciento, en los 3 ejes.
file - modelo 3D.
graph - textura.
flags - estado de animación.

El caso es que tengo un problema con flags:

Cuando cargamos una md2 flags = 0 se ocupa de asignar el estado "quieto" y flags = 1 asigna el estado "andar", pero resulta que si cargamos un modelo que no sea .md2 el programa da un error de ejecución al intentar aplicar animación md2 a un modelo que no la soporta (p.ej una esfera).

De momento voy a tomar una solución que espero se pueda mejorar:

Los procesos tendrán flags = -1 de serie y serán ellos los que deban asignar flags = 0 para que comiencen en estado quieto. Mientras flags valga -1 no se aplicará ninguna animación para evitar ese problemita...

Si alguien se ha enterado de algo y puede echar un cable se agradece :P

EDIT: Pregunta fácil:

He determinado que es necesario "avisar" a 3Dit si se trata de un modelo .md2 animado o de otro tipo de modelo estático:

¿Qué os parece más razonable?, ¿Que haya que asignar siempre flags = 0 a los modelos md2 para que 3Dit se encargue de dejarlos quietos o que haya que asignar flags = -1 a los modelos estáticos para que 3Dit no se moleste en aplicarles animación? :S

Y OTRO EDIT: Ahora estoy con el módulo de herencia, de forma que un proceso disparo (Por ejemplo) pueda tomar la posición y rotación de su padre y sólo preocuparse de avanzar, así:

PROCESS shoot ( )
// Inheritance test getting position and rotation from father
BEGIN
make_3dit ( );

get_father_position ( );
get_father_rotation ( );

file = M8E_LOADSPHEREMODEL ( 10 );

LOOP
advance3d ( 10 );
FRAME;
END
END


El caso es que he comprobado que cuando un proceso se encuentra sobre un terreno siempre se obtiene de él la posición y=0. Esto me impide poder heredar correctamente la y del padre... Una solución "cutre" sería obtener la altura del terreno en el punto donde se encuentra el padre, pero no sería correcto asumir que hay terreno porque puede no haberlo, ni sería limpio tener una GLOBAL donde guardar el terreno si lo hay... Quizás sea un fallo de Bullet, ya que a mi manera de verlo M8E_GETPOSMODEL debería obtener la posición real, ya se encuentre sobre un mapa de terreno o se encuentre bajo los efectos de un animador de movimiento... Creo que voy a mandar un mail a l1nk a ver qué me dice :( agradezco ideas, creo que no voy a hacer nada más con 3Dit hasta resolver estas 2 últimas dudas, son peludas...
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Windgate

Solucionado el extraño problema de animación, ahora a los modelos estáticos no se les aplica animación :D pero ahora es necesario que se asigne un valor a flags para indicar el estado de animación inicial de todo modelo md2, en otro caso realizan todas sus animaciones, esto sucedía así también en Bennu3D así que no perdemos nada.


Añadido:


  • Gestión de modelos hijo con add_to_father ( ) que se ocupa automáticamente de seguir las animaciones, movimientos, rotaciones, etc. del padre y mueren con él.

    Módulo de captura de screenshots que las nombra automáticamente con la fecha.

    collision EXACTAMENTE igual que en Bennu 2D, pero ahora en 3D :O

    Todo modelo cargado ahora tiene asociado el id del proceso que lo gobierna, vendrá bien a largo plazo para usar collision.

    Carga fácil de cielo, ya veréis qué belleza...

    Recién comenzado un módulo de trabajo con la GUI que implementará un write_var exactamente igual que el de Bennu 2D pero en 3D.

    Diversas mejoras puntuales...

DESCARGAR: http://trinit.es/DescargaDirecta/Bennu3D/3Dit/3Dit%200.0.4.zip
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

Windgate

Nueva versión:

http://trinit.es/DescargaDirecta/Bennu3D/3Dit/3Dit%200.1.2.zip

El módulo de GUI ya está terminado, implementa write_gui ( ), write_var_gui ( ), delete_text_gui ( ) con un funcionamiento idéntico a Bennu 2D, incluido el manejo de all_text para borrar todos los textos.

Nuevo módulo de rendimiento para 3dit, tiene una función make_efficient ( ) que puede ser lanzada por un proceso y se encarga de ocultar su modelo cuando se encuentra a cierta distancia global CAM_FAR. También otra función única optimize_fps ( ) que evalúa el FPS y se encarga de reducir CAM_FAR cuando no se alcanza cierto % del fps deseado y subirlo gradualmente hasta el valor original de CAM_FAR en caso contrario, cojonudo xD

Solucionados los problemas para distinguir modelos estáticos y animados que comenté hace 2 posts.

Próximos objetivos:

Un módulo de sonido que hará que todo play_wav ( ) lanzado por un proceso que tiene cargado un modelo calcule su posición respecto a la cámara y utilice el estéreo para dar sensación espacial.

Al igual que ocurre en Bennu 3D, en la carga de texturas 3Dit no se preocupa de controlar si la textura ya ha sido cargada previamente, había planteado tener una lista/árbol de búsqueda que obtenga/añada el id de la textura cargada dependiendo de si es la primera vez que se carga... Como se imaginarán esto será a largo plazo, ya que la lista/árbol sería algo dinámico y primero tendría que hacer un módulo de uso general para ello.

Una función saltar que se ocupe del salto sin complicaciones adicionales... Aunque para esto necesitaré una pequeña ayuda de l1nk3rn3l y Prg, uso terrain maps y ya he leído varias veces que el salto es prácticamente incompatible con ellos.
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

SplinterGU

muy buen trabajo windgate... imagina que teniendo esto modulo desde codigo bennu, es muy simple armar luego un modulo C que evite tener que hacer el proceso auxiliar, etc... todo desde el core...

nuevamente, muy buen trabajo...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Windgate

¿Sugieres modificar Bennu para que integre esta "cosa", hacer una variante de Bennu o una simple .dll de Bennu?

No sería mala idea empezar a meterme con el código fuente de Bennu con este proyecto como motivación... :D
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

SplinterGU

modificar no, hacer un nuevo modulo... (modulo = dll, lo que siempre debio haber sido la bennu3d)
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Prg

Quote from: Windgate on February 08, 2010, 08:15:28 AM
Nueva versión:

http://trinit.es/DescargaDirecta/Bennu3D/3Dit/3Dit%200.1.2.zip

El módulo de GUI ya está terminado, implementa write_gui ( ), write_var_gui ( ), delete_text_gui ( ) con un funcionamiento idéntico a Bennu 2D, incluido el manejo de all_text para borrar todos los textos.

Nuevo módulo de rendimiento para 3dit, tiene una función make_efficient ( ) que puede ser lanzada por un proceso y se encarga de ocultar su modelo cuando se encuentra a cierta distancia global CAM_FAR. También otra función única optimize_fps ( ) que evalúa el FPS y se encarga de reducir CAM_FAR cuando no se alcanza cierto % del fps deseado y subirlo gradualmente hasta el valor original de CAM_FAR en caso contrario, cojonudo xD

Solucionados los problemas para distinguir modelos estáticos y animados que comenté hace 2 posts.

Próximos objetivos:

Un módulo de sonido que hará que todo play_wav ( ) lanzado por un proceso que tiene cargado un modelo calcule su posición respecto a la cámara y utilice el estéreo para dar sensación espacial.

Al igual que ocurre en Bennu 3D, en la carga de texturas 3Dit no se preocupa de controlar si la textura ya ha sido cargada previamente, había planteado tener una lista/árbol de búsqueda que obtenga/añada el id de la textura cargada dependiendo de si es la primera vez que se carga... Como se imaginarán esto será a largo plazo, ya que la lista/árbol sería algo dinámico y primero tendría que hacer un módulo de uso general para ello.

Una función saltar que se ocupe del salto sin complicaciones adicionales... Aunque para esto necesitaré una pequeña ayuda de l1nk3rn3l y Prg, uso terrain maps y ya he leído varias veces que el salto es prácticamente incompatible con ellos.
je je, no había leido reciente mente el tema... has avanzado mucho :)

el salto ya es compatible con los terrenos, si usas la gravedad m8e_addcolterrainfast o algo así, solo tienes que poner a true el parámetro para saltar, y luego ya puedes moverte por el eje "y" como siempre, si lo pones en false no te puedes separar del piso. también hay nuevas funciones para saber si colisionas con el piso en mapas que no son terrains y para saltar. también puedes usar la función de obtener altura de terrain en una coordenada para hacer tu propia gravedad. :)
en humos puedes mover la camara con los cursores. es necesario para los niveles a partir del dos :)