motorXna

desarrollo y tutoriales

Subscribe to RSS feed

Nuevo blog !!!!

Me estoy mudando y voy a transcribir todos los tutoriales orientados a objetos y mas optimizados. Si porfavor pasen por la nueva URL:
http://aarcoraci.homeip.net/blog/

Muchas gracias por el aguante !

Novedades soon

Es probable que empiece con un proyectito en unos dias. Stay tunned.

articulo recomendado

Aca dejo un articulo para los mas nuevitos. Para los no tan nuevitos tiene algunas explicaciones de lo que son las matrices (view, projection y world).
Link:
http://www.nuclex.org/articles/using-xna-to-draw-a-rotating-triangle

Projection - The projection matrix is what transforms 3D coordinates into screen coordinates. It controls whether we do a perspective projection (things become smaller the farther away they are), an orthogonal projection (keeping objects at their original size as often seen in CAD and modelling tools) or some crazy other kind of projection.
View - The view matrix defines the position and orientation of the viewer (commonly referred to as the camera).
World - Before you draw a mesh in your scene, you will change the world matrix to control where the mesh is drawn. All meshes are (usually) modelled with coordinates around the coordinate system's center, so if you want to draw a tree and some specific position, you first set the world matrix to that position and then call the tree's drawing method.



  • Proyeccion: transforma las coordenadas 3d al sistema de la pantalla (osea 2d). Los objetos mas lejanos se ven mas chicos, etc.
  • View: punto de vista del "jugador" tambien referido como "camara".
  • World: Para dibujar cualquier objeto tenemos que cambiar esta matriz. Si queremos dibujar un objeto en cierta coordenada, primero cambiamos la matriz a esa posicion y luego llamamos la funcion "dibujar" de dicho objeto...

Nuevo foro de motorXna !!!

los invito a crear una comunidad:

http://motorxna.19.forumer.com/

motorXna crece !

He visto que varias paginas han linkeado estos tutoriales para que los usuarios puedan aprender esta tecnologia.
A partir de esto, quiero agradecer a dichas paginas y por otro lado, debido a que hay algun tipo de movimiento, que les parece la idea de abrir un foro de discucion ?

Me gustaria que voten para saber si esta iniciativa vale la pena.

Ah... otra cosa, para el proximo articulo estoy tratando de avanzar en algunos temas MUY importantes de la programacion 3d. Que temas ? esperen un tiempo y ya lo veran.

Porfavor dejen su voto !

Perdon por las demoras !

Hace mucho no he posteado, esto se debe a que empece a preparar una materia bastante larga y no he tenido mucho tiempo para investigar.
Otro factor importante fue que me compre una notebook que viene con Vista, y recien hoy salio el refresh de XNA con soporte para vista. Por ende, es factible que sigan los tutoriales.

Quiero agradecer a los visitantes del sitio, es bueno poder compartir los conocimientos ( y creanme, es muy satisfactorio ver que a mucha gente le sirve ).

No duden en preguntar ante cualquier duda.

Saludos, Angel.

Articulo - mundo 3d y transformaciones

En XNA ( y por lo general en cualquier entorno 3d ) tenemos que adaptar nuestra mente a visualizar las cosas antes de compilar y poder verlas. No es divertido hacer los calculos mal 100 veces e ir aprendiendo de cada compilada.
Para eso, es mejor entender el sistema antes de hacer experimentos.

El mundo 3d se parece mucho al mundo nuestro, los objetos (personas, cosas, etc) poseen alto, ancho y profundo. Obviamente tambien poseen una posicion.

Antes de mostrarles como posicionar un objeto en el mundo 3d, primero entiendan el eje cartesiano. Aunque no lo veamos, XNA lo tiene, y obviamente esta centrado en (0,0,0).

Vista de los ejes:


En la imagen se puede ver la representacion del mundo 3d. Las lineas verdes indican hacia donde aumentan los valores, los rojos donde disminuye.

Cuando iniciamos una vista en XNA empezamos en (0,0,0), esto es asi a menos que comencemos por defecto en otro punto. Esto significa que si queremos "avanzar" tendriamos que aumentar nuestra variable posicion sobre el eje Z.
Para tener una vista mas clara de esto, cuando iniciamos la camara sin cambiar la posicion inicial, vemos esto (mas o menos):



Sobre las transformaciones:

Cuando cargamos un modelo (por ejemplo) en XNA, este inicia por defecto en (0,0,0), sin ningun tipo de transformacion.
Recordemos que las transformaciones son: escala, posicion y orientacion o rotacion. Es muy importante tener en cuenta, que las transformaciones que aplicamos a los objetos son "ABSOLUTAS", osea, se guian por el centro del eje. Esto significa que si aplicamos una translacion de 20 unidades, va a ser respecto centro de cordenadas (0,0,0).
No se si se pueden aplicar transformaciones respecto otros objetos o valores, creo que si, pero no voy a investigar eso para este articulo.

Esto es muy importante, ya que por ejemplo, si primero aplicamos una translacion y luego una rotacion, vamos a conseguir un efecto del tipo "orbita" donde los objetos van a centrarse en el centro de cordenadas, con los objetos "mirando" hacia el.
Por lo contrario, si aplicamos una rotacion y despues una traslacion, vamos a tener un objeto desplazado apuntando respecto a la rotacion que le dimos.

Ojala que esto aclara las dudas de alguien, ya que a mi me costo horrores entenderlo.

Salu2 y hasta la proxima.

Tutorial 7 - como crear una camara y controlarla

ADVERTENCIA!
La nueva version de este tutorial (mejorado) esta en mi nuevo blog.

http://aarcoraci.homeip.net/blog/post/Tutorial-XNA---Camara-flotante.aspx


No voy a seguir la linea de desarrollo de los otros tutoriales por 2 motivos:
Primero, seguir tocando el codigo como lo venia haciendo va a ser mas confuso que educativo.
Segundo, creo que si llegaron hasta este tutorial son capaces de entender el modelo orientado a objetos y agregar la camara a sus proyectos sin mayores problemas.

Conceptos de la camara:
Vi muchos papers respecto a las camaras, y la mayoria o eran muy dificiles o no cumplian los objetivos que queria.
El ejemplo que presenta microsoft en msdn2 depende de un modelo o un "avatar" y no tiene movimiento arriba y abajo.
Otros ejemplos que si tienen movimiento arriba y abajo tienen el siguiente problema:
Si miro hacia arriba y luego hacia adelante, la camara viaja en esa direccion, cuando lo que yo quiero es que se camine hacia adelante mirando hacia arriba y no "nadar" en el espacio por asi decirlo.
De todas formas voy a cubrir ese tipo de camara en este tutorial.

Conceptos del mundo 3D - repaso
Recordemos que en XNA las cordenadas son como siguen:


Osea que:
Si quiero ir hacia adelante, aumento Z.
Si quiero girar sobre mi eje, aplico rotacion sobre Y.
Si quiero "volar" hacia arriba, aumento Y.

ejemplo:


Variables:
La camara sera la encargada de manejar las matrices view,world y projection.
La camara va a tener una posicion, un objetivo y una definicion de que eje apunta arriba (eje Y)
La camara va a manejar diferentes velocidades.


Codigo:
Primero que nada, este codigo es de un proyecto personal y yo siempre programo en ingles como norma, pero voy a explicar todo en español:

#region using
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
#endregion

namespace FantasyCamera
{
    public class camera
    {
        #region vars

        //matrices
        private Matrix view;
        public Matrix View
        {
            get { return view; }
        }
        private Matrix projection;
        public Matrix Projection
        {
            get { return projection; }
        }

        private Matrix world;
        public Matrix World
        {
            get { return world; }
        }

        //end matrices
        private Vector3 position;

        private float ratio;
        public float Ratio
        {
            set { ratio = value; }
        }

        private float nearClip = 1.0f;
        private float farClip = 1000.0f;
        private float fov = MathHelper.PiOver4;

        private float yaw;
        private float pitch;

        private float rotationSpeed = 1f / 160f;        
        private float forwardSpeed = 50f / 60f;
        
        #endregion vars

        public camera(int w, int h)
        {            
            ratio = w/h;          
        }

        public void update()
        {

            KeyboardState state = Keyboard.GetState();
            Vector3 movement = Vector3.Zero;

            //movement
            if (state.IsKeyDown(Keys.Up))
            {
                movement.Z -= forwardSpeed;
            }
            if (state.IsKeyDown(Keys.Down))
            {
                movement.Z += forwardSpeed;
            }
            if (state.IsKeyDown(Keys.W))
            {
                movement.Y += forwardSpeed;
            }
            if (state.IsKeyDown(Keys.S))
            {
                movement.Y -= forwardSpeed;
            }
            //lock sides            
            if (state.IsKeyDown(Keys.Left))
            {
                yaw += rotationSpeed;
            }
            if (state.IsKeyDown(Keys.Right))
            {
                yaw -= rotationSpeed;
            }

            //look up and down
            if (state.IsKeyDown(Keys.Q))
            {
                pitch -= rotationSpeed;
            }
            if (state.IsKeyDown(Keys.E))
            {
                pitch += rotationSpeed;
            }                        

            Matrix rotationMatrix = Matrix.CreateRotationY(yaw);
            Vector3.Transform(ref movement, ref rotationMatrix, out movement);
            position += movement;            

            // matrices           
            view = Matrix.CreateLookAt(position, position + rotationMatrix.Forward + new Vector3(0,pitch,0), Vector3.Up);
            projection = Matrix.CreatePerspectiveFieldOfView(fov, ratio, nearClip, farClip);
            world = Matrix.Identity;            

        }
    }
}


Explicacion:

        //matrices
        private Matrix view;
        public Matrix View
        {
            get { return view; }
        }

Aca tenemos un ejemplo de como tratar una variable con visibilidad privada, observen que cuando uso "public" cambia la mayuscula.

La variable ratio dice como dibujar los objetos dependiendo la resolucion.
farClip y nearClip indican el alcance de la camara, no se dibujara lo que este a menos de 1 unidad y mas lejos de 1000 unidades.

"fov" o Field of View o Campo de vision indica como vemos, piOver4 o pi/4 son 45 grados.


las variables yaw y pitch (no se si estos nombres estan bien) indican el movimiento hacia los lados y hacia arriba y abajo de la camara.

        private float rotationSpeed = 1f / 160f;        
        private float forwardSpeed = 50f / 60f;

Esas son faciles, son solo las variables de velocidad de rotacion y que tan rapido corremos.

        public camera(int w, int h)
        {            
            ratio = w/h;          
        }


El constructor es facil, solo necesitan pasarle el alto y ancho de la pantalla, si usan monitores regulares, pueden pasarle por ejemplo 800x600.

Lo que resta del codigo es facil, pero me voy a detener en la siguiente linea:

view = Matrix.CreateLookAt(position, position + rotationMatrix.Forward + new Vector3(0,pitch,0), Vector3.Up);


CreateLookAt recibe 3 valores, posicion de la camara, objetivo y el direccion arribe.
Si ven, en objetivo esta "posicion + rotationMatrix.Forward + " un nuevo vector.
Ese "nuevo vector" indica que se suma una rotacion sin desplazamiento hacia arriba y hacia abajo. Esto es para que la camara no salga flotando hacia arriba o abajo.
Imaginen en el quake 1 si cuando miramos para arriba el personaje empezara a volar, malisimo.

Ahora, para los que quieran estar en un ambiente submarino, remplacen el codigo como sigue:

            Matrix rotationMatrix = Matrix.CreateRotationY(yaw) *  Matrix.CreateRotationX(pitch);
            Vector3.Transform(ref movement, ref rotationMatrix, out movement);
            position += movement;            

            // matrices           
            view = Matrix.CreateLookAt(position, position + rotationMatrix.Forward, Vector3.Up);
            projection = Matrix.CreatePerspectiveFieldOfView(fov, ratio, nearClip, farClip);
            world = Matrix.Identity; 


Cualquier duda pregunten.

NOTA Recuerden que cuando necesiten las matrices world view y projection, se las tienen que "pedir" a camera.
Ejemplo si quieren dibujar un objeto:
objeto.draw( instanciaCamara.World, instanciaCamara.View, instanciaCamara.Projection )





DISCUTI ESTE ARTICULO ACA

almost done

casi termino el tutorial, me estoy demorando porque aparte de lo que muestra microsoft le estoy agregando movimiento vertical y rotacion, pero todavia no termino de cocinar algunos conceptos.
Quizas para mañana este todo listo.

Algunos retrasos

Se complico un poco el tutorial de la camara porque quiero hacerlo bien completo, aparte de que tengo muy poco tiempo porque empece a estudiar y estoy con unos proyectos.
Pero para no dejarlos con nada, les voy a compartir unos apuntes de computacion grafica y un tutorial de microsoft, como para que vayan entrando en calor.

Apuntes:
comp.ppt
Tutorial de microsoft, en ingles:
http://msdn2.microsoft.com/en-us/library/bb197901(d=printer).aspx