rss feed Contactar
Tutorial Papervision3D (III)
::: Continuamos con el tutorial :::
miércoles, 28/10/2009 Archivado en: tutoriales
     -  Papervision3D, parte 3.
     - Parte 1
     - Parte 2

     Seguimos con Papervision3D. En los dos últimos posts de este tutorial nos quedamos con una sosa esfera sobre un fondo blanco. Vamos a hacer algo con ella.

     Primero vamos a hacerla más grande, y a aumentar su número de segmentos de ancho y alto, para darle algo más de resolución.
     Si echamos un vistazo a la clase Sphere (Ctrl+click sobre la palabra Sphere en nuestra clase TutoPV3D01), vemos que el constructor tiene valores por defecto para todos sus parámetros:

     public function Sphere( material:MaterialObject3D=null, radius:Number=100, segmentsW:int=8, segmentsH:int=6 ) {
          ...


     Nosotros instanciábamos nuestro objeto primitivo de la siguiente manera: esfera=new Sphere();

     Nota:

     No es que la clase Sphere tenga sobrecargado el constructor, ActionScript 3 no admite la sobrecarga, si no le pasamos parámetros, toma los que tenga asignado el constructor en su definición.

     Si un objeto no tiene un material asignado, no se ve. Nosotros instanciábamos la esfera sin parámetros, con lo cual toma sus valores por defecto. Cuando el material de la esfera (o de cualquier otro objeto primitivo) es null, Papervision3D automáticamente le asigna un WireFrameMaterial, de ahí que al publicar viéramos las aristas de los triángulos de la esfera.
     Vamos a asignarle parámetros a nuestra esfera, sustituyendo la linea anterior por:

     esfera=new Sphere(null,500,16,12);

     Se le puede asignar el material a través del constructor, o después a través de la propiedad material del objeto Sphere. De momento, el material lo seguimos dejando a null (para que le asigne automáticamente WireFrameMaterial). Vamos a eliminar también la linea que modificaba la posición de la esfera en el método onRenderTick: Borramos esfera.x++;

     Si volvemos a ejecutar (Ctrl+F11), veremos que la esfera ha crecido (tiene un radio de 500 píxeles), tiene más triángulos y ya no se desplaza.

     A continuación vamos a darle un material con un determinado tipo de shader a la esfera, ahora explicaremos esto. Para ello antes necesitaremos crear una luz. Por costumbre, y para poder acceder a los objetos desde cualquier método, definiremos los objetos como variables de clase. Justo antes o después de la linea var esfera:Sphere; colocamos esta otra linea (acordarse de los imports, cada clase nueva que usemos hay que importarla):

     var luz:PointLight3D;

     Al principio del método init(), justo antes de crear la esfera, instanciamos nuestra luz de tipo PointLight3D, y de paso la colocamos en los ejes x, y, z de forma que ilumine nuestra esfera de manera adecuada:

     luz = new PointLight3D();
     luz.z = -400;
     luz.y = 300;
     luz.x = 0;

     Y la añadimos a la escena:

     scene.addChild(light);

     Por el momento, esta luz no nos va a servir para nada, la necesitaremos cuando añadamos un shader. Primero vamos a recubrir la esfera con un material bitmap, lo del shader lo dejamos para luego. Para esto nos servirá cualquier imagen. Yo voy a usar ésta.
     Para ello es conveniente copiar la imagen a nuestro proyecto. Vamos a crear una carpeta donde guardar nuestra imagen bajo nuestro directorio de fuentes. Botón derecho sobre la carpeta src, y creamos una nueva carpeta.

Creamos una carpeta donde guardar nuestra imagen.

     Por costumbre la llamamos assets (la podemos llamar de alguna otra forma) y copiamos dentro nuestra imagen. Debería quedar así:

Nuestra imagen en la carpeta assets.

     Hay varias formas de usar bitmaps como materiales, vamos a usar la más simple. En el método init(), justo antes de crear la esfera, creamos un objeto de tipo BitmapFileMaterial, y le pasamos la ruta relativa de nuestra imagen. Justo a continuación, modificamos la llamada al constructor de nuestra esfera y sustituimos null por nuestra variable material.

     var material:BitmapFileMaterial=new BitmapFileMaterial("assets/snowWhite.jpg");
     esfera=new Sphere(material,500,16,12);

     La clase BitmapFileMaterial hereda de BitmapMaterial, y ya se encarga por nosotros de cargar una imagen externa, sin que nos tengamos que preocupar de listener, loaders y URLRequest.

     Nuestra clase debería haber quedado así:


package{
     import flash.events.Event;

     import org.papervision3d.lights.PointLight3D;
     import org.papervision3d.materials.BitmapFileMaterial;
     import org.papervision3d.objects.primitives.Sphere;
     import org.papervision3d.view.BasicView;

     [SWF(width="800", height="600", backgroundColor="#FFFFFF")]

     public class TutoPV3D01 extends BasicView{

          var esfera:Sphere;
          var luz:PointLight3D;

          // Constructor:
          public function TutoPV3D01(){
               stage.frameRate=42;
               vinit();
               startRendering();
          }

          // Inicialización de objetos y propiedades
          private function init():void{
               luz = new PointLight3D();
               luz.z = -400;
               luz.y = 300;
               luz.x = 0;
               scene.addChild(luz);
               var material:BitmapFileMaterial=new BitmapFileMaterial("assets/snowWhite.jpg");
               esfera=new Sphere(material,500,16,12);
               scene.addChild(esfera);
          }

          // Método que estará continuamente ejecutándose
          override protected function onRenderTick(e:Event=null):void{
              esfera.rotationY++;
              super.onRenderTick();
          }
     }
}


     Si ejecutamos ahora (F11) , veremos nuestra esfera con el material aplicado.

Nuestra esfera con el BitmapFileMaterial

     Hay que tener en cuenta que estamos probando en nuestro ordenador local, con lo cual la imagen se cargará casi de forma inmediata. Si publicásemos esto en internet, la imagen tardaría en cargarse, y mientras se carga la esfera se mostraría de color negro. Esto se puede solucionar de varias formas, por el momento lo dejamos así.

     Llegados a este punto , creo que el shader lo dejaremos para el siguiente post de esta serie, con lo cual tenemos definida en nuestra clase una luz inútil, pero que ya usaremos.

     Para acabar, estableceremos un fondo de una forma un poco chapucera, pero que mejoraremos en siguientes posts. Elegimos cualquier imagen de fondo, yo he elegido una imagen de nubes que me he encontrado en Google Images.

     Como esto no es un tutorial de ActionScript, sino de Papervision3D, vamos a explicar lo siguiente un poco por encima.

     Copiamos la imagen a nuestra carpeta assets (o como la hayamos llamado), y usamos un objeto Loader para cargar la imagen. Le asignamos un listener para el evento COMPLETE, y cuando la carga esté completa, asignamos la imagen cargada a la variable fondo como un objeto Bitmap, le establecemos el mismo ancho y alto que nuestro stage (el de la película flash, no el scene de Papervision3D, la imagen de fondo no pertenecerá al espacio 3D), y la añadimos al stage con el index 0, para que la esfera se vea por encima.

     Nuestra clase TutoPV3D01 nos quedaría de la siguiente manera (se muestran en rojo las nuevas lineas añadidas):


package{
     import flash.display.Bitmap;
     import flash.display.Loader;
     import flash.net.URLRequest;

     import flash.events.Event;

     import org.papervision3d.lights.PointLight3D;
     import org.papervision3d.materials.BitmapFileMaterial;
     import org.papervision3d.objects.primitives.Sphere;
     import org.papervision3d.view.BasicView;

     [SWF(width="800", height="600", backgroundColor="#FFFFFF")]

     public class TutoPV3D01 extends BasicView{

          var esfera:Sphere;
          var luz:PointLight3D;

          // Constructor:
          public function TutoPV3D01(){
               stage.frameRate=42;
               init();
               startRendering();
          }

          // Inicialización de objetos y propiedades
          private function init():void{

               luz = new PointLight3D();
               luz.z = -400;
               luz.y = 300;
               luz.x = 0;
               scene.addChild(luz);

               // imagen de fondo
               var imgLoader:Loader = new Loader();
           imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,loadComplete);
               imgLoader.load(new URLRequest("assets/sky.jpg"));

               // material de esfera

               var material:BitmapFileMaterial=new BitmapFileMaterial("assets/snowWhite.jpg");
               esfera=new Sphere(material,500,16,12);
               scene.addChild(esfera);
          }

          // Método que estará continuamente ejecutándose
          override protected function onRenderTick(e:Event=null):void{
              esfera.rotationY++;
              super.onRenderTick();
          }

          private function loadComplete(e:Event):void{
              // cuando haya cargado la imagen
              var fondo=e.target.content as Bitmap;
              fondo.width=stage.width;
              fondo.height=stage.height;
              addChildAt(fondo,0);
          }

     }
}


     Si ahora ejecutamos, tendremos lo siguiente:

Esfera con material rotando sobre un fondo.

     En la próxima parte, shaders y bumps.
Share/Bookmark
2 comentarios
1 threshold - miércoles, 28/10/2009

Vaya, con algunos estilos, ahora los divs con el código no se ven. Texto blanco sobre fondo blanco. Ya lo arreglaré un día de estos, cuanto tenga un rato.
2 joseguaje - lunes, 17/05/2010
http://joseguaje.blogspot.com

me mola mogollón, quiero aprender... está chulo chulo

Si no escribes correctamente, los duendes del blog te borrarán el comentario.
Por lo demás, eres libre de expresar la opinión que quieras.

:Nombre *

:email

:web

Avatar:  
 
 

Texto del mensaje:


Últimos comentarios

  • Bueno, me ha parecido muy interesante, pero te propongo algo más... puedes perfectamente hacer un c(...)
    jose en
    FumeFx, burn the world
  • Joder es horripilante y inquetante no hay nada que  haya dejado sin quemar en el mismisimo azuf(...)
    carlis en
    FumeFx, burn the world
  • Hombre, conociendote me sorprende que aun con el desnudo integral no aceptaras.  No necesitará(...)
    star en
    FumeFx, burn the world
  • Penélope Cruz tuvo que aceptar el papel en Piratas del Caribe 4 cuando yo la rechazé para Threshol(...)
    threshold en
    FumeFx, burn the world
  • Um, interesante. No se por que los edificios del principio me han recordado al video de las ninjas, (...)
    star en
    FumeFx, burn the world

:Tu email (*)

:Asunto

Mensaje (*):

Enviar mensaje