Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Menu

Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menu

Mensajes - TrOnTxU

#136
Gracias Vicente!!!
:o

Creia haberlo oido en tu charla del CDV, pero no estaba seguro :-[

Me voy a ahorrar varios cambios de lineas   ^_^
#137
Hola, llevaré sin postear, .... ufff , (más o menos), pero weno, esperemos que alguien se moleste en echarle una ojeada a esto  8)

Pues como no, mi post es para consultar opiniones y buscar alternativas.
El tema es que me he vuelto loco y me he puesto a programar un "engine" (por llamarlo de alguna manera) para XNA en C#.

Cuando llegamos al tema de manejo de GameObjects, me decanto por el planteamiento de Chris Stoy en el Game Programming Gems6, el llamado "Game Object Component System", donde cada objeto de juego esta compuesto por una serie de componentes individuales, que tienen una función especifica y que permiten "separar" el código de los gameObjects en clases más pequeñas, y , bla, bla, bla ...

No sé si alguien a probado el Unity, pero la verdad es que a mi me parece una muy buena implementación de un motor multi-plataforma, sencillo y a la vez potente y versatil. (tampoco me he probado todos los motores del mundo, asi que puede que lo que diga lo tengan más de uno, y asi lo creo yo aunque no lo puedo demostrar).
Por lo que he podido observar los gameObjects estan formados por componentes, y además son scriptables (SIIIII  :D), ... vamos, hoy en dia todo el mundo diria: lo típico. Pero hay una cosa que me gusta en especial manera y es el Transform.
Desde el nivel de script en unity Transform es una clase linkada (siempre, no como un componente que se puede añadir o quitar) a un GameObject. Con ella puedes modificar la posición, rotación y escala (si vamos, lo típico) de un objeto.
Pero con la peculiaridad de que la transformación tiene jerarquia, hijos, un padre y un root de escena, lo que le da un cierto aspecto de nodo de un scene graph, pero solo con transformaciones.

Lo que veo bueno en el Transform de Unity es una cosa que he visto en muy pocos motores, y es que puedes modificar la posicion/rotacion/escala de un objeto, tanto local, como global directamente. Me explico:
- si un objeto esta en la posicion (0,0,10) y tiene un hijo con posicion local (0,0,0) el hijo ocupará la posición "real" (0,0,10).
- si modificamos la posicion del padre a (0,0,8) el hijo se moverá a la posción (0,0,8)
- si modificamos la posición LOCAL del hijo a (0,4,0) su posicion en GLOBAL será (0,4,8).
- pero si modificamos la posicion GLOBAL (o de mundo) del hijo a (0,4,0) su posicion será (0,4,0) y su posicion local se recalculará respecto a la posicion del padre.

A alguien le puede parecer una chorrada, pero para mi es super-importante que quede tan "sencillo" el trabajar con coordenas locales y de mundo, ya que facilita el código de lógica de juego, tanto a nivel de implementación como de comprensión/depuración.

Asi que me he puesto a programar lo mismo. Lo he probado y mola  :o Pero claro, lo he echo de manera rápida y sin optimizar.

Mi primera aproximación personal al tema ha sido crearme mi Manager de Entidades (GameObjects pero si es mi motor yo lo llamo como quiero  ;) )la Entidad en si (con la lista de componentes y tal) y el Transform.

El transform almacena posicion/rotacion y una escala proporcional (o sea un solo float) local, y otros tantos para global. Asi es rapido obtener la pos/rot/escala y establecerla, ... en teoria, porque tambien tenemos que actualizar las coordenadas locales/globales dependiendo del tipo de parametro que cambiemos.
Tambien he acabado por incluir las matrices local y global en la clase, y las mantengo actualizadas, con lo que la lectura de los parametros de la transformacion(usease pos/rot/escala) sique siendo directo, pero establecer nuevos parametros no lo es, ya que hemos de actualizar varias cosas: parametros locales o globales y sus respectivas matrices.
Además de esto, si optamos por mantener las transformaciones siempre actualizadas (en vez de "a la antigua usanza" que era recorrer el grafo de escena al dibujar e ir apilando/desapilando las transformaciones), cada vez que actualizamos un nodo hemos de actualizar también los hijos.

Como ventaja, al dibujar ya tenemos todas las matrices de mundo actualizadas, y solo hemos de recorrer la lista de objetos "visibles" (podemos hacernos una lista con las entidades que tienen el componente IRender, por ejemplo) y aplicar esa matriz al shader antes de comenzar a dibujar.

Por ejemplo, el código de una propiedad como la posicion global seria algo asi:

/// <summary>
/// Escala local
/// </summary>
public float LocalScale
{
    get { return localScale; }
    set
    {
        localScale = value;
        _updateValues(UpdateValuesMode.GLOBAL_COORDS);
    }
}


Esto es: si pido la escala local simplemente me devuelve la variable correspondiente, pero cuando hago un "set" de ese valor, primero le pone el nuevo valor a la variable y seguidamente actualiza las coordenadas globales, para que sean coherentes con el cambio.
Ahora el código de _updateValues:
...
if (((int)mode & (int)UpdateValuesMode.GLOBAL_COORDS) != 0)
{
    localMatrix =
        Matrix.CreateFromQuaternion(localRotation) *
        Matrix.CreateScale(localScale) *
        Matrix.CreateTranslation(localPosition);

    Matrix parentWorldMatrix = (Parent == null) ? Matrix.Identity : Parent.worldMatrix;
    worldMatrix = localMatrix * parentWorldMatrix;
    Vector3 outScale;
    worldMatrix.Decompose(out outScale, out globalRotation, out globalPosition);
    globalScale = outScale.X;
}
...
foreach (XutiTransform childTransform in this.childs)
{
    childTransform._updateFromParent();
}
...

Antes que nada, SE QUE NO SE HAN DE UTILIZAR SOBRECARGAS DE OPERADORES PORQUE EL COMPILER NO LO OPTIMIZA, es simplemente para que el código quede más legible, y os prometo que los sustituiré por las funciones correspondientes con paso por referencia.
Explicando lo que hace el código, por si alguien se pierde, es crear la matriz de transformacion local a partir de los parametros (pos/rot/escala) locales. Seguidamente se multiplica por la matriz del padre para obtener la matriz de mundo (la transformacion final del objeto antes de dibujar).
En tercer lugar se extraen los parametros globales. Y por ultimo llamamos a _updateFromParent en todos los hijos, funcion que detallo aqui:
private void _updateFromParent()
{
    Matrix parentWorldMatrix = (Parent == null)?Matrix.Identity:Parent.worldMatrix;
    worldMatrix = localMatrix * parentWorldMatrix;
    Vector3 outScale;
    worldMatrix.Decompose(out outScale, out globalRotation, out globalPosition);
    globalScale = outScale.X;

    foreach (XutiTransform childTransform in this.childs)
    {
        childTransform._updateFromParent();
    }
}

Que de echo es muy parecida a la parte de actualizar coordenadas globales, pero sin tanto código, para que sea mas ligera y actualizar una larga serie de hijos sea lo menos costoso posible.
El tema de modificar las coordenadas gobales es un poco mas complicado porque actualizar los valores locales se vuelve un poco más complicado, basicamente porque hay que obtener la inversa de la matriz global del padre, algo asi:
this.worldMatrix =
    Matrix.CreateFromQuaternion(globalRotation) *
    Matrix.CreateScale(globalScale) *
    Matrix.CreateTranslation(globalPosition);

localMatrix = worldMatrix * Matrix.Invert(Parent.worldMatrix);
Vector3 outScale;
localMatrix.Decompose(out outScale, out localRotation, out localPosition);
localScale = outScale.X;


Bueno, pues después de este tostón mis preguntas:

1) ¿Creeis que es una buena solucion mantener tantos valores actualizados? (La verdad es que modificar la transformacion de un objeto es sencillo a nivel de programacion, pero costoso a nivel de computación, eso sin contar la cantidad de memoria que consume una transformación)
2) ¿Se os ocurre alguna alternativa para mejorar el rendimiento y que la clase siga cumpliendo los requisitos?

Bueno, espero que alguien pueda comentarme sus opiniones, y podamos intercambiar experiencias sobre este tema, que me parece bastante fundamental a la hora de diseñar un "motor".

Pues nada, un saludo, y gracias por leerte esto. XD
Adew!
#138
Yo estoy totalmente de acuerdo con sés.

Basate en las resoluciones que te ha dicho.
Tres versiones escaladas de gráficos (generalmente), y los pequeños cambios (el móvil que no soporte full-screeen, o los motorola que suelen ser un poco más pequeños de altura para su "categoria") a mano.

El pre-procesado es casi indipensable.
#139
General Programadores / Overlays en Ogre
09 de Septiembre de 2007, 11:37:05 PM
Tienes el codigo mal. Susutituyelo por esto:
Overlay *Hagen = OverlayManager::getOverlayByName("BlackEngine/GUIinGame");
Hagen->show();


Estabas obteniendo un elemento, y debes obtener el overlay entero.
Espero que te sirva de ayuda.
Un saludo.
#140
Proyectos / -Wind Warriors-
05 de Septiembre de 2007, 02:38:45 PM
Cita de: "Tei"Los shaders han nacido para este tipo de juegos.
Animo y buen trabajo hasta ahora.
¿A que le pondrias tu shaders en un windjammers?
¿Halos y efectos del disco? ¿normal map? ¿alguna cosa más?
¿Y si quieres hacerlo correr tb en una maquina que no tiene shaders? ¿Quitarias efectos y normal cuando no dispones de ellos?

Solo curiosidad, ... menos mal que no soy un gato :P
#141
General Programadores / Cliente/servidor en J2ME
04 de Agosto de 2007, 04:20:51 PM
Si te instalas el tomcat, o pones el servlet en internet, puedes hacer las pruebas desde los emuladores.

Utiliza las pruebas en dispositivo lo menos frecuentemente que puedas (solo cuando sea imprescindible) si no dispones de fondos suficientes, pero como siempre, se trabaja mejor con un buen presupuesto :-/

En cuanto a lo de bluetooth, no lo tengo muy claro, y no te puedo ayudar, lo siento :S

1 saludo
#142
El tema de los diseñadores está muy mal ... para encontrar alguno que valga la pena.

Tres cuartas partes de la gente que conozco que se autodenominan diseñadores (esto incluye tb a los diseñadores "profesionales") tienen el glamour en las siestas que se echan en horas de trabajo, o sea, que un tio que dice que diseña un videojuego (como el típico amigo que te dice: tengo una idea para un juego, si lo haces quiero el 25%) te da la "idea", que suele ser el 99% de las veces: Pues el juego de va un muñeco que tal y cual. Ale machote hazlo!

Diseñador, productor, .... demasiados cargos para después tener que machacar a los grafos y los programadores. Que por cierto no lo tenemos tan bien como se pinta, sobretodo porque nos toca hacer el juego, y encima como a otros (diseñadores y productores) les da la gana.

Un diseñador vale la pena si está pendiente del desarrollo durante todo el proceso y tiene conocimientos o se permite indagar en como se hacen las cosas (conozco bastantes de estos, pero menos de los que me gustaria), además de intentar coordinar a la gente para conseguir previews, mock-ups, esbozos, art-work, etc que de una idea lo más documentada posible del juego y ganas de trabajar al resto de gente del grupo.

En resumen, para mi el 75% de los diseñadores intentan vivir del cuento, punto y pelota, por eso está tan mal.

Espero no haber ofendido a nadie, si es asi, el que se sienta ofendido que se auto-incluya en el 25% restante.

Hasta lego.

[\MODO IRONICO ON] PS: si tu haces una carera de informatica entras de programador en una empresa de videojuegos, sin ningún problema, además todo lo que necesitas lo das en la carrera, jajajajajajajaaja [\MODO IRONICO OFF]
#143
Lens Flare?

En un Game Programming Gems hay un artículo bastante bueno al respecto.
#144
Programación de audio / Delay / Buffering
28 de Mayo de 2007, 06:03:37 PM
Solo para windows:
El directShow y/o directInput soportan efectos como Reverb, delay, distorsión, etc.
Bajaté el SDK y echale un vistazo a los ejemplos.

Si lo que necesitas es algo multiplataforma, supongo que tendrás que mirar OpenAl y averiguar como aplicar efectos, se que tiene alguna historia de extensiones, etc, algo similar a las extensiones de OpenGl (por ejemplo).

Un saludo, espero servirte de ayuda.
#145
Programación gráfica / Proyecto de Grafico
25 de Mayo de 2007, 04:00:15 PM
Hola, queria saber si alguien me haria la cena des esta noche, acabaria el trabajo que me queda todavia, y se presentaria por mi a los examenes (solo si sabe que va a aprobar con 10).

Interesados enviar sus códigos fuentes (comentados y documentados, por favor) a aqui@pring.ao

Muchas gracias por su colaboración, que ustedes vuelen bien.
#146
General / Tenencia de armas y videojuegos
20 de Abril de 2007, 02:01:42 PM
Para que luego digan el Levante es de "izquierdas" y progresista XDXDXD

Jose Vicente tiene razón:
- 47 muertos y 43 heridos (conocidos mios entre ellos, si ello tuviese más importancia)  en la misma València en un accidente de metro por negligencia de estafadores que se llenan los bolsillos todos los dias (encima tiene el morro de cerrar el caso y decir que la culpa era del conductor, que está muerto no puede reclamar ni defenderse).
- Espacios naturales protegidos bajo una enorme desvastación natural (veasé albufera, punta, horta, etc)
- Especulación y agresiones "expropiatorias" contra gente que vive en sus casas.
- Gente con pistolas (policia) que disuelve a ostia limpia concentraciones de estudiantes.
- Fallas y demás eventos donde se estafan millonadas.
- Copas Americas y mierdas en bote pa dejarnos si un duro pero con cuarenta bloques más de viviendas que venderan "ellos".
- etc, etc , etc

Mi conclusión señores directivos del "Mercantil Valenciano":
LOS POLITICOS JUEGAN A VIDEOJUEGOS

Un saludo
#147
General Programadores / Problemas con los combates xD
17 de Abril de 2007, 11:03:13 AM
Juer, cuando yo pregunto nadie contesta tanto :P
#148
Cita de: "fjfnaranjo"
Cita de: "tamat"Lo bueno de usar matrices es que engloban las tres transformaciones básicas que puede recibir un objeto, que son rotacion, traslacion y escalado.

Y no nos olvidemos de lo ULTRA caras que son las operaciones trigonométricas (cos, sin, tan) en lo que a tiempo de procesador se refiere ;)

No entiendo tu puntualización. Para construir las matrices de rotación a partir de un angulo (Euler) hay que realizar las mismas operaciones trigonométricas (sin y cos).

Si lo que quieres es velocidad mi recomendación es que decidas cuantas particiones (secciones) de la circunferencia quieres crear (por ejemplo 360 como los grados), luego creas dos arrays con el tamaño de esas particones y precalculas senos y cosenos. Para acceder solo tienes que buscar en la posición del array los valores que quieres.

Por otra parte, puedes ahorrarte espacio y ver las relaciones entre senos y cosenos y los grados o radianes. Quiero decir que da lo mismo seno de 0 que cos de pi, etc. Puedes un solo array con pocos valores y hacer una funcion para cada "funcion trigonometrica" que busque el valor adecuado en el array. Esto se llaman tablas precalculadas.

Un saludo.
#149
General Programadores / Problemas con los combates xD
16 de Abril de 2007, 03:56:38 AM
No sé si te he entendido bien, porque mi respuesta sigue siendo la misma: estados.

Cuando la CPU tenga que mover pasarás al estado E_MUEVE_CPU (por ejemplo) y pones un contador de enemigos actualizados a 0 (una variable). En tu trozo de código de lógica (en el procedimiento o donde lo tengas hecho) actualizas la acción de un enemigo, incrementas la variable de contador y continuas (ejecutas la parte de dibujado y das otra vuelta al bucle principal).
Asegurate de que a la salida de tu bucle se compruebe si has actualizado todos los enemigos, si es asi cambia de nuevo de estado al correspondiente.
En caso de que el cambio de estado provocara (eso es como tu te organices el código, pero por si acaso) que la animación del ultimo enemigo actualizado no se realizara, tendrias que hacer la comprobación antes del procedimiento de lógica, asi evitarias este problema, pero no tiene porque ser un problema si controlas correctamente los estado en todas las partes del código (logica, input y render) que lo necesiten.

Si este no es el problema, por favor, intenta explicarte un poco mejor, ya que no lo pillo.

Un saludo.
#150
General Programadores / Problemas con los combates xD
15 de Abril de 2007, 10:21:06 PM
Hola, me parece que lo que tu necesitas es una maquina de estados.
No he entenido muy bien tu problema, pero creo que el problema es que no separas la lógica por estados. La forma más fácil (rápida de programarlo) es con una variable, no recuerdo muchas cosas de BASIC asi que lo escribiré en una especie pseudo-código:

definir { E_SALIR = 0, E_MUEVE_PLAYER = 1, E_ANIMACION = 2, E_COMBATE = 3, ...}
declarar varible estado = E_MUEVE_PLAYER // por ejemplo
// Bucle principal
mientras(estado <> E_SALIR) {
 // Input
 si estado == E_MUEVE_PLAYER entonces
   // Procesar código de entrada
   ....
 final si

 // Logica
 si estado == E_ANIMACION entonces
   // Ejecuta el código de animacion
   ...
   si animacion concluye entonces
     estado = E_... // el estado al que quieras cambiar
   final si
   ...
 sino si estado == E_MUEVE_PLAYER entonces
 ...
 sino si estado == E_COMBATE entonces
 ...
 final si
 // Comprobar final del juego
 si juego acaba entonces
   estado = E_SALIR
 final si

 // Dibujar
 ...
}


En el trozo de dibujar tambien puedes poner sentencias condicionales para seleccionar que dibujar en cada estado del juego.

Espero que esa sea tu pregunta y que hayas entendido el concepto.
Sino he sabido contestarte bien o no te queda algo claro dimelo e intentaré echarte una mano.

Un saludo