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

Temas - TrOnTxU

#1
General / Esto da vergüenza
19 de Junio de 2012, 11:48:01 PM
Se que quizás no sea un buen sitio para poner esto. Y que estando las cosas como están hay cogerse a un clavo ardiendo. Pero a mi me da VERGÜENZA que algun "desarrollador" pueda tomar parte en la siguiente aberración (que parece que se llama "campaña de publicidad"): http://www.youtube.com/watch?feature=player_embedded&v=bEXcCXyA__Q


A algunos les podrá hacer gracia, otros invocarán a la libertad de expresión.
Pero el que avisa no es traidor: Si hay aqui algun listillo que tenia pensado ir a ver los "cochecitos de los "h****s" a València, y se quiere hacer el "gracioso" con la p**a m****a esta (cosa que dudo mucho), que tenga en cuenta que los valencianos somo "tontos" pero no tanto, si alguien acabase ingeriendo por "accidente" su "terminal" no seria nada de extrañar.

Por cierto la empresa que lo ha "ideado" (que ya es mala idea) se llama PubliPS, y el "individuo" llamado a si mismo "Social Manager" toma el nombre de: Sergio Gabaldón. Hay una etiqueta de twitter #ninanonihòsties en protesta, por si a alguien más le ofende esta b*s*ra.


Un saludo y gracias por aguantar mi "rabieta" :)
#2
Hola, hace tiempo que tenia en mente abrir un blog con mis "ralladas" sobre programación.

No lo he echo hasta ahora, porque hay mogollón de blogs de gente con más experiencia y talento que tratan los mismos temas que yo tengo pensado tratar. Aún así, muy pocos he encontrado que estén en castellano, así que quizás esa sea la parte buena, y puede que alguien llegue a estar interesado en leer y comentar.

De momento en el primer post trato el tema de la memoria principal, y he puesto algun ejemplo sencillito y alguna captura de pantalla. Lo malo es que creo que me he pasado posteando todo el código, y igual queda muy largo (aunque la mayoria es source code).


Os animo a que le echeeis un vistazo y comenteeis (aqui o en el blog) lo que opinais. Si veo que a alguien le puede interesar el tema, seguiré con el siguiente post explicando como manejo el tema de la memoria principal en el Typhoeus.

Aqui esta el enlace: http://typhoeus-sdk.blogspot.com.es/2012/06/problemas-de-memoria-no-lo-se-no-me.html


Un saludo
#3
Hola!

Sigo trasteando con C# y la maquina Mono (para scripting de entidades como siempre). Y me han vuelto a salir problemillas :)

1) Primero como llamar a un metodo sobreescrito de una clase base que no sea directamente la del "padre" de la clase, sino más bien el "abuelo", y me explico con un ejemplo tonto.
En C++ haria algo asi (lo escribo sobre la marcha, la implementacion en el mismo archivo que la declaracion y sin comprobar) pero la idea es esta:

class ClaseA {
  public:
    virtual void Escribe() { printf("Hola soy clase A\n"); }
}

class ClaseB : public ClaseA {
  public:
    virtual void Escribe() { printf("Hola soy clase B\n"); }
}

class ClaseC : public ClaseB {
  public:
    virtual void Escribe() {
      printf("Hola soy clase C\n");
      printf("Ahora muestro la clase base:\n");
      ClaseA::Escribe();
    }
}


El rollo es que ClaseC claseC(); claseC.Escribe(); esto deberia mostrar:
Hola soy clase C
Ahora muestro la clase base:
Hola soy clase A


Si esto lo hago en C#

public class ClaseA {
public virtual void Escribe() { Console.WriteLine("Hola soy clase A"); }
}

public class ClaseB : ClaseA {
public override void Escribe() { Console.WriteLine("Hola soy clase B"); }
}

class ClaseC : ClaseB {
public override void Escribe() {
Console.WriteLine("Hola soy clase C");
Console.WriteLine("Ahora muestro la clase base:");
base.Escribe();
}
}


Para el siguiente código de ejecucion:
ClaseA ca = new ClaseA();ca.Escribe();
ClaseC cc = new ClaseC(); cc.Escribe();


Obtengo la salida:
Hola soy clase A
Hola soy clase C
Ahora muestro la clase base:
Hola soy clase B


Con lo que mi problema es poder llamar al metodo "ClaseA.Escribe" desde "ClaseC.Escribe", sin pasar por el metodo "ClaseB.Escribe".
Supongo que será una chorrada como un piano pero mira que he "googleado" y no encontrado ningun ejemplo, lo más chungo es que me parece que alguna vez lo tengo que haber echo ya, pero ahora no caigo si se puede y como.


2) Y paso a la segunda pregunta chorra. Esto viene del tema de optimizaciones del compilador, y sobretodo el tema de metodos inline.
Para liar más la cosa ahora compilo las DLL de los scripts con el compilador de MonoDevelop, aunque no tendria que haber problemas en que lo compilara con el VS y luego copiar la DLL al directorio de ejecucion.

En C# no hay ninguna "palabra reservada" que inidique al compilador tu preferencia por hacer inline de una funcion, aunque por el contrario si que puedes darle un atributo a un metodo para indicarle que "no haga nunca un inline" de dicho metodo.
En un principio un metodo que ocupe menos de x bytes de codigo IL (creo que son 32) y no se llame recursivamente es firme candidato para este tipo de optimizacion.
Vale, hasta aqui todo OK. Mi problema actual: los arboles de comportamiento que he implementado para la IA utilizan un "yield return [Xe2BTResult]" como "retorno" de un metodo "IEnumerable<Xe2BTResult>", con lo que utlizo los iteradores para "simular" código de corrutinas.
Pero si quiero trazar el arbol (ver en tiempo de ejecucion que nodos estan activos y en que estado), debo guardar la informacion de estado de la "corrutina" con lo que hago esto: yield return Trazar([Xe2BTResult]). Donde Xe2BTResult es un enum y Trazar es un metodo "no estatico" de la clase nodo con una implementacion parecida a esto:
Xe2BTResult Trazar(Xe2BTResult  result)
{
#ifdef DEBUG
    m_blackboard.ChangeState(m_nodeID, result);
#endif
    return result;
}


En C++ si quisiera que en "Release" se obviara el registro del estado en la blackboard y el "jump" a la funcion implementaria Trazar como un macro "#define" sin pensarmelo dos veces.
Mi problema es saber si "Trazar" (al menos en Release cuando el #ifdef no se cumple) es candidato a optimizar mediante inline de forma que el código quedara de la siguiente manera:
En DEBUG: yield return Trazar([Xe2BTResult]); (o con toda la funcion Trazar "inlineada")
Y en RELEASE: yield return [Xe2BTResult];

Supongo que me puedo poner a decompilar IL y examinar el codigo resultante pero me gustaria que si alguien tiene experiencia con esto me comentara su opinion.
Tanto para compilador .NET como Mono.

Como alternativa he leido que algunos "Delegates" o funciones anonimas o algo asi, en C# se "desplegan" en tiempo de compilacion como funciones "inline" con lo que sustituyendo el metodo "Trazar" por algun tipo de funcion anonima podia conseguir el mismo resultado que con un "#define" o un "inline" de C++.
¿Alguna ayudita u opinión al respecto? (por cierto, me gustaria no pasar de 2.0, por lo que supongo que "Action" no funcionaria).


3) Y por fin la ultima pregunta.
En consolas Next-Gen (si suponemos la 360 y la PS3) se acabo el "codigo dinámico", todo codigo nativo no firmado no se puede ejecutar.
La maquina de .NET en un principio (y segun tengo entendido) genera "codigo maquina nativo" sobre a marcha (conforme se necesitan) a partir del codigo IL.
En XNA supongo que la solución es generar ese "codigo nativo" en el proceso de compilacion, en vez de "conforme se necesita". Y por supuesto eliminar el JIT de las features del lenguaje.
Si tengo que utilizar la maquina Mono en estas consolas:
¿la solucion que he propuesto seria la correcta?
¿opiniones al respecto?
¿alguna ayudita XD?


Bueno pues muchas gracias por anticipado, y perdonar por los "tostones" de post que pongo (ya vienen siendo habituales en mi).

ADEW!!
#4
General Programadores / Control de versiones y Assets
09 de Enero de 2011, 07:31:31 PM
Esta es la eterna pregunta: ¿Como manejar el versionado de los assets de un juego?

Normalmente siempre he utilizado el mismo VCS (Subversion por norma general) que tengo para el código para almacenar los assets.
Pero solo los finales (resultado final de la tuberia de importacion), los binarios que se cargaran directamente por el motor.
Los grafistas y diseñadores se suelen guardar sus propias copias de los documentos (con guardado incremental generalmente) y suelen tener un ftp para subir copias de seguridad. El documento se exporta al binario final, y este es el que incluyo yo en el control de versiones.

Esto me ha funcionado bien en "antiguos" proyectos de PC, moviles e incluso en la DS.
En mi último proyecto de Wii ya me ha costado bastante mantener coherencia en los archivos por el movimiento que representa: el asset va del modelador, al texturizador, luego al animador, y si hay que cambiar algo vuelta para atrás, y en medio estas tu exportando el asset a mitad del desarrollo para que el jefe "vea el muñequito en la pantalla".

Me ha pasado de todo, el grafista te da el fbx exportado y dice haber subido el .max al ftp. Cuando el fbx demuestra algun fallo y se tiene que corregir no se encuentra por ninguna parte el .max original que contenia la ultima version y hay que hacer "maravillas" para solucionarlo, etc, etc, etc.


Ahora todavia es peor, se supone que voy a tener que manejar una cantidad cada vez más grande de assets, y vamos a gestionar una cantidad de datos bastante pesada, que se tiene que ir moviendo arriba y abajo.
Para que la organización sea medianamente aceptable veo totalmente necesario el uso de control de versiones en los documentos binarios (al menos los principales que sirvan de fuente para exportar los assets al motor), con un repositorio (incluso un sistema) diferente del usado para el código fuente.
Para colmo, el editor genera los datos del proyecto, y he de integrar algun tipo de wrapper o front-end para un control de versiones de archivos COLLADA, PSD, .doc, .cls, FBX, DDS, .CG, etc, etc, en el mismo editor.

Las opciones que estoy evaluando:

1) Perforce. El standard de la industria, tan bueno como caro. (creo que paso por el precio) No lo he probado, aunque he oido hablar mucho de él. Segun cuentan las malas lenguas es probablemente el mejor VCS actual, sobretodo si estas trabajando con archvos binarios (desde documentos office, a archivos Maya, pasando por PSDs). Utiliza deltas para almacenar diferencias entre binarios, logrando que las revisiones de los binarios ocupen muy poco espacio (relativamente) en el repositorio, y parece ser extremadamente rápido.

2) Subversion. A mi no me ha ido mal con los binarios, excepto cuando he intentado implantar un sistema completo de versionado de archivos binarios on candados, etc. Generalmente los "no programadores" se vuelven un poco locos. El problema viene al tener muchos archivos, y archivos grandes. Es lento comparado con Mercurial, Git o Bazaar, y el repositorio crece bastante rápido al meter actualizaciones de assets binarios.

3) Mercurial, Bazaar, Git. De entrada son distribuidos, lo que implica que almacenarian una copia de toda la historia de la branch en el "working directory", aunque se pueden podar (al menos en Git) no es la configuracion por defecto. Pienso que para gestionar los assets quizas seria mejor un repositorio centralizado que ir juntando branches, ya que los branches de los binarios ...
Aun asi, se puede hacer que estos sistemas funcionen "emulando" un repositorio centralizado. Mercurial y Bazaar son los más rápidos, si contamos que Git tiene que hacer un "pack" del repositorio, o este crece hasta niveles desmesurados. A pesar de esto ultimo un repositorio de Git  lleno de binarios con cambios en el historial y acabado de "empaquetar" puede llegar a ocupar la mitad que el mismo repositorio en svn. Mercurial y Bazaar generan repositorios ligeramente más pequeños que Svn, aunque no tanto como Git.

4) Gestionar los assets con un sistema propio, ya sea basado en bases de datos, etc. (ni de coña tengo tiempo ahora mismo, ..., y creo que nunca)

5) Big files for ... hay una modificacion (fork) de Git, llamada Git for Big Files, la tengo que probar y medir todavia, pero puede que funcione mejor que Git a secas. Hay otro Big Files para mercurial pero no lo he mirado.


Conclusion:
- Perforce es demasiado caro.
- Svn no es lo mejor para grandes cantidades de datos binarios. Pero tiene soporte para candados.
- Parece que Git se defiende bien, pero tendria que estudiar las posibilidades de configurarlo lo más parecido a un sistema con repositorio centralizado. Es el que produce repositorios más pequeños (aunque haya que hacer un pack del mismo)
- Mercurial y Bazaar son otras dos opciones a estudiar.

- El problema de que dos personas modifiquen "a la vez" un mismo asset y luego intenten subir los cambios creando conflictos, es una cosa que no se como solucionara Perforce, pero que a mi me trae de cabeza (los candados no son siempre la solución), asi que supongo que será cuestión de establecer una "rigurosa" politica de comunicacion y notificación entre el equipo.



¿Opiniones? ¿Sugerencias? ¿insultos?

Bueno gracias a los que lo leais (a los que no, no ;) )
Un saludo
#5
General Programadores / Proteccion de Licencia para Software .NET
26 de Noviembre de 2010, 07:35:26 PM
Wenas.

Puede que hace unos años no me imaginara nunca haciendo esta pregunta, pero después de haber pasado por diferentes y variadas empresas (siempre que hicieran juegos, si es que eso se puede considerar variación XD), y haber visto lo que se cuece ...

El tema es que estoy desarrollando en casa un frame-work multiplataforma para PC y consolas next-gen (si, ya se que soy muy original). Basicamente se compone de una aplicacion/editor con soporte para plug-ins (de echo la mayoria de la funcionalidad está alojada en las .dll de los plugins) en C# (winforms/.NET), una serie de wrappers C++/CLR, y un player en C++ (bueno, uno para cada plataforma).

Mi problema ahora es como licenciarlo (entregar el software) y no arriesgarme a que me hagan la 3-14 (tb conocida en mi pueblo como: "la jugada fosca").

Para simplificarlo he decidido varias cosas:

* No distribuir el source de nada.
* Se podrian seguir desarrollando plug-ins para ampliar el editor.
* La "programación" seria completamente en script (de momento soporto Lua, aunque estoy pensando en integrar Python y Squirrell)
* El player siempre tiene la pantalla de splash, de modo que solo sirva de visualizador (tanto en el PC de desarrollo, como en la consola target)
* El editor no permita realizar el "empaquetado final" de los assets
* Para los masters o candidates versions que se deban enviar para checking a la compañia de la consola seria imprescindible que realizara yo la build final.
* El sistema de control de licencia solo esta instalado en el editor (desarrollarlo en C# es muchisimo más comodo).


El problema es que por mucho que le meto (y se me ocurre poner) al control de licencia:
* Guardado de datos sensibles encriptados
* Creación de Bulk Keys y License Keys
* Trial versions
* Caducidad de la licencia
* Control de cambio de fechas
* Verificación de licencia por servidor
* Grabacion y comprobacion de datos en registro de windows.

No me quito la sensacion que todo parece resumirse en que como alguien se salte el "if (LicenseManager.ChekValid())" que hay cuando arranca el editor todo esfuerzo es inutil.

He estado indagando en programas comerciales que te ofrecen soluciones en apariencia muy completas, pero a la hora de integrar (por los ejemplos que he visto) en tu programa es lo mismo, si alguien se salta el if ... hasta luego lucas.

He pensado en poner mas comprobaciones de licencia durante la ejecución de la aplicación, pero poca cosa más se me ocurre.

¿ Alguien está más familiarizado con esto?

Se que Vicente tiene idea (por no decir que es Dios) de todo el tema del .NET, el codigo que se produce al compilar, como decompilarlo, que si CLR, que si CLI, y todo eso que practicamente desconozco.
Mi pregunta tb seria como de facil es "reventar" una aplicacion de .NET para saltarse el if, o intentar trazar el comportamiento de la aplicacion, para descifrar  los algoritmos, claves y procedimientos del sistema de licencia. Sobretodo comparado con c++, porque tb habia pensado en hacer el sistema en c++ y ponerlo tanto en el player como en el editor (para lo que seguramente haria un wrapper C++/CLR y una bonita .dll).

Gracias de antemano a todos y un saludo.
#6
Hola, me encontrao con un problemilla scriptando algunas cosas del editor de arboles de comportamiento de nuestro ultimo juego.
Espero que alguien con más conocimientos de c# que yo me pueda decir si lo que quiero se puedo hacer.

Tengo una jerarquia de clases parecida a esta:
BehaivourTree (arbol generico)
-> Malo1BT ( deriva de BehaivourTree )
-> Malo2BT ( deriva de BehaivourTree )
-> ...

En mi editor por cada nodo me tienen que salir una lista de acciones y condiciones disponibles.
El problema viene cuando cada clase derivada (Malo1BT, Malo2BT, ...) tiene una lista de acciones y condiciones diferente.

En un principio (en teoria) tendria que tener el objeto final (Malo1BT, ...), entonces bastaria con que esta clase tuviera implementado un metodo ObtenAcciones/Condiciones que fuera abstracto (preferiblemente) enla clase genérica BehaivourTree.

Pues bien, el tema es que he implementado que cualquier clase derivada pueda cargar cualquier tipo de arbol. Por tanto en mi editor tengo un BehaivourTree genérico (no puedo hacerlo abstract), luego el arbol se graba como una serie de indices (int) en disco, y se carga en tiempo de ejcución ( ... y si, funciona bastante, bastante bien  ;) )

Pues bien, para que en el editor se sustituyan los indices por los nombres de las acciones y condiciones disponibles he pensao en obtener dos arrays de strings (1 x acciones y otro para condiciones). En el editor (parte superior izq) debe haber una lista con los tipos de arboles (por enemigo), y que indique que arrays de strings tenemos que obtener.

Por tanto para cada TIPO clase (Malo1BT, MaloBT2, ...) tengo dos arrays de strings ( acciones / condiciones ). Que se corresponden con los indices de un enum que tiene cada clase con sus acciones/condiciones.

Como obtenerlos:
1) Clase estatica "BehaivourTreeHelper" que contiene métodos estaticos para listar los tipos de enemigos ( string [] ObtenerTiposEnemigos() ). Y metodos para obtener acciones/condiciones por tipo de clase ( string [] ObtenerAcciones(Type p) o ObtenerAcciones(string nombreClase) ).

2) Mi problema es que defino enums con las acciones dentro de cada clase derivada (Malo1BT por ejemplo).
Y mantener los indices del array de strings en una clase diferente me parece un poco lioso.
Asi que preferiria escribir un método estático en cada clase que obtenga el array. Pero al ser estatico no puedo aplicar ningun tipo de polimorfismo (creo) para decir: todas las clases q derivan de BehaivourTree tiene ue tener un metodo ObtenAcciones, y luego obtener estas acciones dependiendo del tipo.

3) Lo cojonudo del todo seria poder además utilizar Reflexion (pensar que el coste me la suda un poco, porque estoy en el editor, no en el runtime del juego ni en el engine) y obtener las listas de strings a partir de los enums. Pero no tengo mucha idea. Quizás alguien (seguro) ha echo algo parecido y me puede dar una idea de como abordarlo.


Bueno, que opinais al respecto, ¿a alguien se le ocurre una solución?
Pues nada gracias a todos de antemano.

Nos vemos!!!
#7
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!
#8
General Programadores / Newton u ODE (integración en Ogre)
08 de Abril de 2007, 08:37:06 PM
Hola, estoy con un nuevo proyecto (nuevo porque todavia no hemos empezado en serio, pero llevamos tiempo planeando el tema) en 3D. Para la parte gráfica utilizaremos Ogre, y los dos SDKs de fisicas más conocidos que tienen integración con este motor gráfico son el ODE y el Newton.

He recibido referencias de ambos, pero todavia no tengo claro cual es mejor. Supongo que cada uno tendrá su pros y sus contras pero las cosas a evaluar, pienso yo, son las siguientes:

- Necesitamos fisica de solido-rigido.
- Necesitamo aplicar IK a alguna cadena de bones (no muy larga espero).
- Queremos (claramente) velocidad.
- Queremos sencillez de uso (ya sé que todo no puede ser ^^).

Bueno, espero que podais aportar experiencias o referencias.
Gracias por adelantado y un saludo.
#9
General Programadores / CVS vs SVN
08 de Marzo de 2007, 02:11:00 PM
Hola, estaba pensando en comenzar a utilizar un control de versiones para un proyecto que estoy iniciando con unos amigos.

En casa probé a instalar un CVS en linux, y funcionaba bien. Luego lo hice con WinXP, y también. Lo bueno es que NetBeans lo soporta de maravilla, y es el IDE con el que estamos trabajando.
Queria saber como de seguro seria tener un CVS fuera de una red local, quiero decir teniendo un ordenador conectado a internet que haga de servidor (en Windows en un principio).

Tambien he leído algo del SVN o algo asi, no sé en que difiere del CVS, ni cual de los dos serà mejor utilizar.

¿Alguien me puede orientar?

Muchas gracias por anticipado.  :D





Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.