Para vincularse con nuestro regalo de Papervision3D Essentials, el tutorial de hoy también incluye un tema de PV3D.
Este tutorial de dos partes le mostrará cómo comenzar con el motor Papervision3D, y luego cómo hacer que su creación salte de la pantalla utilizando un efecto anaglifo en combinación con gafas 3D..
¿Tienes un par de gafas 3D por ahí? Aquí en el Reino Unido, el Canal 4 está ejecutando una Semana 3D especial: siete días de programas de televisión transmitidos en 3D, así que mucha gente lo hace. Vamos a ponerlos en uso..
Este tutorial de dos partes le mostrará cómo comenzar con el motor Papervision3D y luego cómo hacer que su creación salte de la pantalla..
En esta primera parte, aprenderá los conceptos básicos de PV3D y terminará con algo como esto:
... y en la segunda parte, aprenderá sobre el efecto anaglifo de las gafas 3D y lo aplicará a lo que ha creado así:
Si está utilizando Flash, cree un nuevo archivo ActionScript 3.0 Flash. Establezca el tamaño del escenario para que sea lo que desee: me quedo con el valor predeterminado de 550 por 400 píxeles.
Mientras esté en ello, cree un nuevo archivo ActionScript y guárdelo como Main.as en la misma carpeta que tu FLA. Vamos a utilizar este archivo AS como FLA's clase de documento, así que haga clic en un espacio en blanco en su archivo FLA e ingrese Principal en el cuadro "Clase de documento" del panel Propiedades.
(Si no está utilizando el IDE de Flash, simplemente cree un nuevo proyecto de AS3).
Dirígete a la página de descarga de Papervision. Hay muchas versiones diferentes y algunos tipos diferentes de archivos (zip, swc, mxp). Solo toma el último archivo .zip (debería decir Destacados junto a él). El que estoy usando se llama Papervision3D 2.1.920.zip (para usar con el libro "Papervision3D Essentials").
Extraiga el archivo zip que acaba de descargar en cualquier lugar de su disco duro. Me gusta mantener todos los motores diferentes que uso en la misma carpeta, pero depende de ti.
Flash necesita saber dónde extrajo Papervision antes de poder usarlo. Usamos un ruta de clase para esto: click Editar> Preferencias, seleccionar ActionScript, luego haga clic Configuración de ActionScript 3.0 ... .
En el cuadro que aparece, haga clic en el pequeño icono de "punto de mira", busque la carpeta donde descomprimió Papervision y haga clic en Aceptar. Haga clic en Aceptar en los otros cuadros hasta que vuelva a la FLA.
Si no está utilizando el IDE de Flash, tendrá que configurar esto de una manera diferente. Por ejemplo, en FlashDevelop, debe hacer clic Herramientas> Classpaths globales.
En Papervision, todos sus objetos 3D deben colocarse dentro de un escena. Es algo así como el escenario en ActionScript regular. Entonces, antes de hacer cualquier cosa, necesitamos crear una Scene3D Objeto que contendrá todo lo demás..
Cambie a su archivo Main.as. Agreguemos rápidamente el código base necesario para cualquier clase de documento:
paquete import flash.display.MovieClip; clase pública principal extiende MovieClip función pública principal ()
El objeto Scene3D está en org.papervision3d.scenes.Scene3D, así que necesitamos importar eso, entonces crea un nuevo var público para mantener la escena, y finalmente crear el objeto de escena real: (líneas 4, 8 y 12)
paquete import flash.display.MovieClip; importar org.papervision3d.scenes.Scene3D; Clase pública principal extiende MovieClip escena de var pública: Scene3D; función pública Main () scene = new Scene3D ();
Para empezar, creemos un gran cubo liso sentado en nuestra escena..
Seguiremos el mismo tipo de pasos que el anterior para crearlo, luego lo agregaremos a nuestra escena: (líneas 5, 10, 15, 16)
paquete import flash.display.MovieClip; importar org.papervision3d.scenes.Scene3D; importar org.papervision3d.objects.primitives.Cube; Clase pública principal extiende MovieClip escena de var pública: Scene3D; cubo var público: Cubo; función pública Main () scene = new Scene3D (); cubo = nuevo cubo (); scene.addChild (cubo);
Tenga en cuenta que usamos "addChild ()" para agregar el cubo a la escena, tal como lo hacemos al agregar un MovieClip al escenario.
El código anterior le dará un error si intenta ejecutarlo. Eso es porque no le hemos dicho al cubo cómo deben verse las superficies de su cara.
Usos de papervision materiales para describir cómo se ve una superficie. Podemos hacer un material muy simple, de un solo color usando un Colormaterial:
var grayMaterial: ColorMaterial = nuevo ColorMaterial (0xCCCCCC);
El "0xCCCCCC" representa el color gris; simplemente toma el código de color de cualquier color y reemplaza el # con 0x:
Debido a que un cubo tiene seis caras, necesitamos darle seis materiales. Para ello ponemos los seis en una lista:
var materialsList: MaterialsList = new MaterialsList (); materialsList.addMaterial (grayMaterial, "front"); materialsList.addMaterial (grayMaterial, "back"); materialsList.addMaterial (grayMaterial, "left"); materialsList.addMaterial (grayMaterial, "right"); materialsList.addMaterial (grayMaterial, "top"); materialsList.addMaterial (grayMaterial, "bottom");
... y luego pasar esa lista al cubo cuando lo creamos:
cubo = nuevo cubo (lista de materiales);
Entonces, todo tu código debería terminar pareciéndose a esto: (no olvides el importar declaraciones!)
paquete import flash.display.MovieClip; importar org.papervision3d.scenes.Scene3D; importar org.papervision3d.objects.primitives.Cube; importar org.papervision3d.materials.ColorMaterial; importar org.papervision3d.materials.utils.MaterialsList; Clase pública principal extiende MovieClip escena de var pública: Scene3D; cubo var público: Cubo; función pública Main () var grayMaterial: ColorMaterial = new ColorMaterial (0xCCCCCC); var materialsList: MaterialsList = new MaterialsList (); materialsList.addMaterial (grayMaterial, "front"); materialsList.addMaterial (grayMaterial, "back"); materialsList.addMaterial (grayMaterial, "left"); materialsList.addMaterial (grayMaterial, "right"); materialsList.addMaterial (grayMaterial, "top"); materialsList.addMaterial (grayMaterial, "bottom"); escena = nueva Scene3D (); cubo = nuevo cubo (lista de materiales); scene.addChild (cubo);
Así que no tenemos errores, pero para ver algo, necesitamos agregar un cámara a la escena Veremos todo a través de la "lente" de la cámara..
Agregar una cámara es tan simple como agregar un cubo; de hecho, es más simple, ya que no tenemos que agregar Child () a la escena:
importar org.papervision3d.cameras.Camera3D;
cámara de var público: Camera3D;
escena = nueva Scene3D (); cubo = nuevo cubo (lista de materiales); scene.addChild (cubo); cámara = nueva Camera3D (); // esta es la nueva linea en Main ()
Ahora hay una cámara en la escena, pero no está conectada a ninguna salida, así que todavía no podemos ver el cubo!
De forma predeterminada, el cubo se coloca justo en el centro de la escena (en x = 0, y = 0, z = 0), y la cámara se coloca a 1000 unidades de distancia (en x = 0, y = 0, z = -1000).
¿Cómo podemos obtener la imagen que la cámara ve en la ventana de Flash Player??
La respuesta es, usamos un vista. Este es un tipo de DisplayObject, como un MovieClip, por lo que podemos agregarChild () al escenario. Pero también podemos hacer Papervision. hacer (es decir, dibuje) la vista de la cámara en esta ventana gráfica: es un poco como que un artista dibuje lo que puede ver a través de la lente de una cámara, luego tome su dibujo y lo pegue a un televisor. Excepto mas rapido.
Entonces necesitamos crear una ventana gráfica y un renderizador:
importar org.papervision3d.view.Viewport3D; importar org.papervision3d.render.BasicRenderEngine;
public var viewport: Viewport3D; público var renderer: BasicRenderEngine;
// coloca esto al final de Main () viewport = new Viewport3D (); viewport.autoScaleToStage = true; // esto hará que la ventana gráfica sea tan grande como el escenario addChild (ventana gráfica); renderer = new BasicRenderEngine ();
Ahora todo lo que tenemos que hacer es hacer que el renderizador haga la representación real. Para esto, necesita conocer la escena, la cámara y la ventana gráfica:
renderer.renderScene (escena, cámara, ventana gráfica);
¡Al final! Finalmente podemos probar el SWF. Redoble de tambores por favor…
¡Increíble! ¡Asombroso! OK bien, en realidad es bastante escaso. ¿Cómo podemos decir que es un cubo? Parece un cuadrado.
Si rotamos el cubo, podremos decir si es realmente un cubo o no.
Dado que el cubo está en tres dimensiones, la palabra "rotar" es un poco confusa: ¿a qué dirección nos referimos? Necesitamos especificar si estamos girando alrededor del eje x, eje y o eje z.
los Cubo El objeto tiene tres propiedades que podemos usar para definir esto, llamadas (como era de esperar) rotaciónX, rotaciónY y rotación z. Vamos a cambiar un par de ellos:
escena = nueva Scene3D (); cubo = nuevo cubo (lista de materiales); cube.rotationX = 25; // cambio de rotación cube.rotationY = 40; // cambiar rotación scene.addChild (cubo); cámara = nueva Camera3D ();
Es mejor, pero como todas las caras son exactamente del mismo color, simplemente se fusionan unas con otras. Vamos a arreglar eso.
En lugar de gris, voy a pintar los lados con el logotipo de ActiveTuts +.
Si está utilizando el IDE de Flash, cree un nuevo clip de película y dibuje o pegue la imagen que desea usar. He incluido el logo en la biblioteca de mi FLA dentro de la cremallera.
Haga clic derecho en su clip de película y seleccione Propiedades. Marque "exportar para ActionScript" y asígnele un nombre de clase. Esto le permitirá acceder a él utilizando el código. (Si no está utilizando el IDE de Flash, el zip también contiene un SWC con un MovieClip llamado ActiveTutsLogo que puede usar. O, puede crear un nuevo MovieClip en código y agregarle su imagen. No voy a entrar en los detalles de eso aquí, sin embargo.)
En vez de una Colormaterial vamos a utilizar un Material de pelicula, y en lugar de especificar un color, especificaremos un clip de película. Así que reemplaza esto:
var grayMaterial: ColorMaterial = nuevo ColorMaterial (0xCCCCCC); var materialsList: MaterialsList = new MaterialsList (); materialsList.addMaterial (grayMaterial, "front"); materialsList.addMaterial (grayMaterial, "back"); materialsList.addMaterial (grayMaterial, "left"); materialsList.addMaterial (grayMaterial, "right"); materialsList.addMaterial (grayMaterial, "top"); materialsList.addMaterial (grayMaterial, "bottom");
… con este:
var logoMaterial: MovieMaterial = new MovieMaterial (new ActiveTutsLogo ()); // reemplace "ActiveTutsLogo" arriba con el nombre de clase de su clip de película var materialsList: MaterialsList = new MaterialsList (); materialsList.addMaterial (logoMaterial, "front"); materialsList.addMaterial (logoMaterial, "back"); materialsList.addMaterial (logoMaterial, "left"); materialsList.addMaterial (logoMaterial, "right"); materialsList.addMaterial (logoMaterial, "top"); materialsList.addMaterial (logoMaterial, "bottom");
También necesitarás importar el MovieMaterial:
importar org.papervision3d.materials.MovieMaterial;
Prueba de nuevo:
Bueno, funciona, pero se ve un poco abollado..
El aspecto "abollado" se debe a que Papervision está configurado de forma predeterminada para dibujar cosas rápidamente en lugar de hacerlo con precisión. Quiero asegurarme de que este tutorial se ejecute en computadoras más lentas, así que lo dejaré así, pero aquí está cómo puede mejorarlo:
Cuando creas el cubo, puedes pasarle parámetros para definir cuántos segmentos cada cara está dividida en. Cuantos más segmentos elijas, más preciso se verá el cubo, pero más lento será el renderizado..
He encontrado que 10 es un buen número de segmentos para usar en cada dirección. Así es como se ve el código para eso:
cubo = cubo nuevo (lista de materiales, 500, 500, 500, 10, 10, 10);
Los parámetros quinto, sexto y séptimo definen el número de segmentos utilizados en cada dirección. Para establecerlos, sin embargo, tenemos que especificar todos los parámetros. antes de el quinto tambien.
Ya estamos especificando el primer parámetro, esa es la lista de materiales. Los parámetros segundo, tercero y cuarto definen el ancho, la profundidad y la altura del cubo. Estos están configurados en 500 por defecto, por lo que los he mantenido igual aquí.
Si usas la línea de código anterior, tu cubo se verá así:
Mucho más ordenado!
Podemos hacer un giro de MovieClip regular aumentando su rotación propiedad de cada fotograma, y por supuesto, podemos hacer lo mismo con el cubo y sus valores de rotación X / Y / Z.
Cree un detector de eventos ENTER_FRAME, que ejecutará cada fotograma:
import flash.events.Event;
// en la parte inferior de Main () addEventListener (Event.ENTER_FRAME, onEnterFrame);
// como una nueva función // dentro de la clase Main pero fuera de la función main () public function onEnterFrame (evt: Event): void cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5;
Esto hará que el cubo gire un poco más cada cuadro. Entonces, si prueba el SWF ahora ... el cubo se mantendrá completamente inmóvil. Eh?
Piensa en el pintor. Todavía estamos viendo su imagen anterior. Necesitamos que nos dibuje una nueva en cada cuadro, o no veremos ningún cambio.!
Entonces, modifique la función onEnterFrame ():
función pública onEnterFrame (evt: Event): void cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5; renderer.renderScene (escena, cámara, ventana gráfica);
Échale un vistazo ahora:
Un cubo es genial, pero como Roman ya te mostró cómo hacerlo con Away3D, vamos a llevar las cosas un poco más lejos.
Añadamos unos cuantos más, para formar una línea horizontal de cubos. Podemos usar un simple para bucle para hacer eso simplemente reemplaza este código:
cubo = nuevo cubo (lista de materiales); cube.rotationX = 25; // cambio de rotación cube.rotationY = 40; // cambiar rotación scene.addChild (cubo);
… con este:
para (var i: int = -1; i <= 1; i++ ) cube = new Cube( materialsList ); cube.x = i * 350; cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube );
Tenga en cuenta que estoy haciendo que la posición x de cada cubo dependa de lo lejos que estemos a través del bucle. Si ejecuta esto, obtendrá lo siguiente:
Vaya, los cubos están demasiado juntos. Podemos reducirlos para evitar esto; solo cambia el escala Propiedad de cada cubo:
para (var i: int = -1; i <= 1; i++ ) cube = new Cube( materialsList ); cube.x = i * 350; cube.scale = 0.40; //make the cubes 40% of original size cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube );
Así que eso soluciona el problema de la intersección, pero solo uno de nuestros cubos está girando. Cómo?
Es porque el cubo variable siempre se refiere solo a la último cubo creado - y nuestra función onEnterFrame () solo cambia las rotaciones de ese cubo.
Así que para arreglar esto, necesitaremos un Array. Así como nuestra lista de materiales almacenó varios materiales, nuestra matriz almacenará varios cubos..
public var cubeArray: Array;
cubeArray = new Array (); // crea la nueva matriz para (var i: int = -1; i <= 1; i++ ) cube = new Cube( materialsList ); cube.x = i * 350; cube.scale = 0.40; cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube ); cubeArray.push( cube ); //add the new cube to the array
("Push" solo significa "agregar al final de la lista".)
Ahora que cada cubo está en la matriz, podemos recorrer cada matriz y rotar cada uno de ellos:
función pública onEnterFrame (evt: Event): void para cada (cube en cubeArray) cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5; renderer.renderScene (escena, cámara, ventana gráfica);
El bucle "para cada" hace que el cubo las variables se refieren a cada cubo, uno a la vez, en lugar de solo al último cubo creado como lo hizo antes. Aquí está el resultado:
Éxito!
Hemos hecho una línea de cubos, por lo que un cuadrado no va a ser difícil. En lugar de solo hacer tres cubos, haremos tres líneas de tres cubos.
Para hacer esto, podemos usar un bucle dentro de un bucle, así:
para (var i: int = -1; i <= 1; i++ ) for ( var j:int = -1; j <= 1; j++ ) //loop inside a loop cube = new Cube( materialsList ); cube.x = i * 350; cube.y = j * 350; //don't forget to change j! cube.scale = 0.40; cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube ); cubeArray.push( cube ); //don't forget this closing bracket either
Pruébalo
Bonito. Y tenga en cuenta que no tuvimos que cambiar el código dentro de onEnterFrame () en absoluto; el bucle que se ejecuta en cada fotograma simplemente gira cada cubo dentro de la matriz, y todavía estamos presionando cada cubo en la matriz.
Bueno, sería decepcionante detenerse en una plaza, ¿no? Después de todo, este es un tutorial 3D..
Espero que puedas descubrir cómo hacer este paso por tu cuenta. Pero en caso de que quieras comparar:
para (var i: int = -1; i <= 1; i++ ) for ( var j:int = -1; j <= 1; j++ ) for ( var k:int = 0; k <= 2; k++ ) cube = new Cube( materialsList ); cube.x = i * 350; cube.y = j * 350; cube.z = k * 350; cube.scale = 0.40; cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube ); cubeArray.push( cube );
He sido un poco astuto aquí. Comencé k en 0 en lugar de en -1, porque de lo contrario, la capa de cubos que se encuentra más al frente estaría demasiado cerca de la cámara. Por supuesto, puedes usar los números que quieras.
Oye, ¿notaste que el efecto "abollado" básicamente se ha desvanecido ahora que estamos usando cubos más pequeños??
Increíble!
Esto es solo arañar la superficie de lo que puede hacer con Papervision3D. Antes de pasar a las gafas 3D, he aquí algunas cosas con las que puedes experimentar:
En la segunda parte, aprenderá cómo hacer que su escena funcione con gafas 3D. Así que si tienes un par, no los deseches.!
Mientras tanto, gracias por leer la primera parte. Espero que hayas encontrado útil. Si tiene alguna pregunta, o si algo fue confuso, publique un comentario a continuación.