Resan till nästa dimension med Papervision3D Del 1

För att koppla ihop med våra Papervision3D Essentials giveaway, har dagens handledning också ett PV3D-tema.

Den här tvådelade handledningen visar hur du kommer igång med Papervision3D-motorn, hur du gör din skapning hoppa ur skärmen med en anaglyph-effekt i kombination med 3D-glasögon.




Introduktion

Fick ett par 3D-glasögon liggande? Här i Storbritannien kör Channel 4 en speciell 3D-vecka - sju dagar av TV-program sänds i 3D - så mycket folk gör här. Låt oss sätta dem att använda.

Den här tvådelade handledningen visar hur du kommer igång med Papervision3D-motorn, och sedan hur du gör din skapning hoppa ur skärmen.

I den här första delen lär du dig grunderna för PV3D och slutar med något som detta:

... och i den andra delen lär du dig information om anaglyph-effekten för 3D-glasögon och tillämpa den på vad du har gjort så här:

Steg 1: Installationen

Om du använder Flash skapar du en ny Flash-fil för ActionScript 3.0. Ställ in scenens storlek för att vara vad du vill - Jag håller med standard 550 med 400 pixlar.

Medan du är på den, skapa en ny ActionScript-fil och spara den som Main.as i samma mapp som din FLA. Vi ska använda denna AS-fil som FLA: n dokument klass, klicka så på ett tomt utrymme i din FLA-fil och skriv in Huvudsaklig i rutan "Dokumentklass" på Egenskaper-panelen.

(Om du inte använder Flash IDE, skapa bara ett nytt AS3-projekt.)

Steg 2: Hämta Papervision3D

Gå över till Papervisions nedladdningssida. Det finns många olika versioner och några olika typer av filer (zip, swc, mxp). Ta bara den senaste .zip-filen (det borde säga Dagens bredvid den). Den jag använder heter Papervision3D 2.1.920.zip (för användning med "Papervision3D Essentials" bok).

Steg 3: Ta ut Zip

Ta ut zip-filen du bara laddade ner till var som helst på hårddisken. Jag gillar att behålla alla de olika motorerna jag använder i samma mapp, men det är upp till dig.

Steg 4: Ställ in en klassväg

Flash behöver veta var du extraherade Papervision innan den kan använda den. Vi använder en classpath för detta: klicka Redigera> Inställningar, Välj Action, Klicka sedan ActionScript 3.0-inställningar ... .

I rutan som visas klickar du på den lilla "crosshair" -ikonen och hittar sedan mappen där du plockade ut Papervision och klickar på OK. Klicka på OK i de andra rutorna tills du kommer tillbaka till FLA.

Om du inte använder Flash IDE måste du ange det på ett annat sätt. I FlashDevelop bör du till exempel klicka på Verktyg> Global Classpaths.

Steg 5: Ställ in scenen i Papervision

I Papervision måste alla dina 3D-objekt placeras inuti a scen. Det är typiskt som scenen i vanliga ActionScript. Så innan vi gör någonting behöver vi skapa en Scene3D objekt som innehåller allt annat.

Byt till din Main.as-fil. Låt oss snabbt lägga till baskoden som behövs för någon dokumentklass:

 paket import flash.display.MovieClip; public class Main utökar MovieClip public function Main () 

Scene3D-objektet är i org.papervision3d.scenes.Scene3D, så måste vi göra det importera så skapar du en ny offentlig var att hålla scenen och slutligen skapa det aktuella scenobjektet: (linjerna 4, 8 och 12)

 paket import flash.display.MovieClip; importera org.papervision3d.scenes.Scene3D; public class Main utökar MovieClip public var scene: Scene3D; allmän funktion Main () scene = new Scene3D (); 

Steg 6: Lägg till en kub

Till att börja med, låt oss bara skapa en stor vanlig kubssitta i vår scen.

Vi följer samma slags steg som ovan för att skapa det och lägg sedan till det i vår scen: (linjerna 5, 10, 15, 16)

 paket import flash.display.MovieClip; importera org.papervision3d.scenes.Scene3D; importera org.papervision3d.objects.primitives.Cube; public class Main utökar MovieClip public var scene: Scene3D; offentlig var kub: kub; allmän funktion Main () scene = new Scene3D (); kub = ny kub (); scene.addChild (kub); 

Observera att vi använder "addChild ()" för att lägga till kuben på scenen, precis som vi gör när vi lägger till en MovieClip på scenen.

Steg 7: Färg kuben

Ovanstående kod kommer att ge dig ett fel om du försöker köra den. Det beror på att vi inte har sagt kuben hur ansiktsytorna ska se ut.

Papervision använder material för att beskriva hur en yta ser ut. Vi kan göra ett mycket enkelt, enkelfärgat material med hjälp av a ColorMaterial:

 var grå Material: ColorMaterial = nytt ColorMaterial (0xCCCCCC);

"0xCCCCCC" representerar färgen grå; Ta bara färgkoden av vilken som helst färg och ersätt den # med 0x:

Eftersom en kub har sex ansikten behöver vi ge det sex material. För att göra detta sätter vi alla sex i en 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");

... och skicka sedan den listan till kuben när vi skapar den:

 kub = ny kub (materiallista);

Så hela din kod ska äntligen se ut så här: (glöm inte importera uttalanden!)

 paket import flash.display.MovieClip; importera org.papervision3d.scenes.Scene3D; importera org.papervision3d.objects.primitives.Cube; importera org.papervision3d.materials.ColorMaterial; importera org.papervision3d.materials.utils.MaterialsList; public class Main utökar MovieClip public var scene: Scene3D; offentlig var kub: kub; allmän funktion 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"); scen = ny Scene3D (); kub = ny kub (materiallista); scene.addChild (kub); 

Steg 8: Lägg till en kamera

Så vi har inga fel, men för att se någonting behöver vi lägga till en kamera till scenen. Vi ser allt genom kamerans "objektiv".

Att lägga till en kamera är lika enkelt som att lägga till en kub - enklare, eftersom vi inte behöver lägga tillChild () till scenen:

 importera org.papervision3d.cameras.Camera3D;
 public var kamera: Camera3D;
 scen = ny Scene3D (); kub = ny kub (materiallista); scene.addChild (kub); kamera = ny Camera3D (); // Detta är den nya raden i Main ()

Nu är en kamera på scenen, men den är inte ansluten till någon utgång, så vi kan fortfarande inte se kuben!

Steg 9: Lägg till en Viewport och en Renderer

Som standard placeras kuben högerklump i mitten av scenen (vid x = 0, y = 0, z = 0) och kameran är placerad 1000 enheter tillbaka från den (vid x = 0, y = 0, z = -1000).

Hur kan vi få den bild som kameran ser i Flash Player-fönstret?

Svaret är, vi använder en visningsområde. Det här är en typ av DisplayObject, som en MovieClip, så vi kan läggaChild () till scenen. Men vi kan också göra Papervision göra (dvs teckna) kamerans syn på den här utsikten - det är lite som att en konstnär ritar vad han kan se genom en kameralins, sedan tar sin ritning och klibbar den till en TV-apparat. Utom snabbare.

Så vi behöver skapa en visningsport och en renderer:

 importera org.papervision3d.view.Viewport3D; importera org.papervision3d.render.BasicRenderEngine;
 public var viewport: Viewport3D; public var renderer: BasicRenderEngine;
 // sätt detta i slutet av Main () viewport = nytt Viewport3D (); viewport.autoScaleToStage = true; // detta kommer att göra visningsporten så stor som scenen addChild (viewport); renderer = ny BasicRenderEngine ();

Steg 10: Återställ scenen

Nu är allt vi behöver göra för att göra renderaren göra den verkliga rendering. För detta behöver den känna till scenen, kameran och visningsporten:

 renderer.renderScene (scen, kamera, visningsport);

Äntligen! Vi kan äntligen testa SWF. Trumvirvel, tack…

Otrolig! Förvånande! OK bra, det är faktiskt ganska lamt. Hur kan vi till och med säga att det är en kub? Det ser ut som en fyrkant.

Steg 11: Vrid kuben

Om vi ​​roterar kuben kan vi berätta om det verkligen är en kub eller inte.

Eftersom kuben är i tre dimensioner är ordet "rotera" lite förvirrande - vilken riktning menar vi? Vi måste ange huruvida vi roterar runt x-axeln, y-axeln eller z-axeln.

De Kub objektet har tre egenskaper som vi kan använda för att definiera detta, kallat (överraskande) rotationX, rotationY och rotationZ. Låt oss ändra ett par av dem:

 scen = ny Scene3D (); kub = ny kub (materiallista); kub.rotationX = 25; // ändra rotation cube.rotationY = 40; // ändra rotation scen.addChild (kub); kamera = ny Camera3D ();

Det är bättre, men eftersom alla ansikten är exakt samma färg, går de bara in i varandra. Låt oss fixa det.

Steg 12: Reskin kuben

Istället för grått ska jag måla sidorna med ActiveTuts + -logotypen.

Om du använder Flash IDE, skapa ett nytt filmklipp och dra eller klistra in den bild du vill använda. Jag har tagit med logotypen i mitt FLA-bibliotek inom zip.

Högerklicka på ditt filmklipp och välj Egenskaper. Markera "exportera till ActionScript" och ge det ett klassnamn. Detta låter dig komma åt det med hjälp av kod. (Om du inte använder Flash IDE, innehåller zip också en SWC med en MovieClip som heter ActiveTutsLogo som du kan använda. Eller du kan skapa en ny MovieClip-kod och lägga till din bild till den. Jag ska inte gå in i detaljerna om det här, men.)

I stället för a ColorMaterial vi ska använda en MovieMaterial, och istället för att ange en färg ska vi ange ett filmklipp. Så ersätt det här:

 var grå Material: ColorMaterial = nytt 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");

… med detta:

 var logoMaterial: MovieMaterial = nytt MovieMaterial (nytt ActiveTutsLogo ()); // ersätt "ActiveTutsLogo" ovan med klassnamnet på ditt filmklipp 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");

Du måste också importera MovieMaterial:

 importera org.papervision3d.materials.MovieMaterial;

Testa det igen:

Tja, det fungerar, men det ser lite ut.

Steg 13 (Valfritt): Ta bort dammarna

Den "dämpade" utseendet är att Papervision är som standard för att rita saker snabbt snarare än exakt. Jag vill se till att denna handledning kommer att springa på långsammare datorer, så jag ska lämna den där, men här är hur du kan förbättra det:

När du skapar kuben kan du skicka det parametrar för att definiera hur många segment Varje ansikte delas upp i. Ju fler segment du väljer, desto mer exakt ser kuben ut - men desto långsammare blir den gjord.

Jag har funnit att 10 är ett bra antal segment att använda i varje riktning. Så här ser koden ut:

 kub = ny kub (materiallista, 500, 500, 500, 10, 10, 10);

Den femte, sjätte och sjunde parametern definierar antalet segment som används i varje riktning. För att ställa in dem måste vi dock ange alla parametrar innan den femte också.

Vi anger redan den första parametern - det är materiallistan. Den andra, tredje och fjärde parametern definierar kubens bredd, djup och höjd. Dessa är inställda till 500 som standard, så jag har hållit dem samma här.

Om du använder ovanstående kodregel kommer din kub att se ut så här:

Mycket snyggare!

Steg 14: Gör kubsspinnen

Vi kan göra en vanlig MovieClip spinn runt genom att öka dess rotation egendom varje ram - och vi kan naturligtvis göra samma sak med kuben och dess rotationX / Y / Z-värden.

Skapa en ENTER_FRAME händelse lyssnare, som kommer att köra varje ram:

 importera flash.events.Event;
 // längst ner i Main () addEventListener (Event.ENTER_FRAME, onEnterFrame);
 // som en ny funktion // i huvudklassen men utanför huvudfunktionen () funktionen public function onEnterFrame (evt: Event): void cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5; 

Detta gör att kuben vänder lite mer varje ram. Så om du testar SWF ut nu ... kommer kuben vara helt stilla. Huh?

Steg 15: Återställ scenen varje ram

Tänk tillbaka till målaren. Vi tittar fortfarande på hans gamla bild - vi behöver honom att dra oss en ny varje ram, eller vi kommer inte se några förändringar!

Så, ändra funktionen onEnterFrame ():

 offentlig funktion onEnterFrame (evt: Event): void cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5; renderer.renderScene (scen, kamera, visningsport); 

Kolla in det nu:

Steg 16: Lägg till fler kuber

En kub är stor, men som Roman redan visat dig hur man gör det med Away3D, låt oss ta saker lite längre.

Låt oss lägga till några fler, för att bilda en horisontell linje av kuber. Vi kan använda en enkel för loop för att göra det; ersätt bara den här koden:

 kub = ny kub (materiallista); kub.rotationX = 25; // ändra rotation cube.rotationY = 40; // ändra rotation scen.addChild (kub);

… med detta:

 för (var i: int = -1; i <= 1; i++ )  cube = new Cube( materialsList ); cube.x = i * 350; cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube ); 

Observera att jag gör x-positionen för varje kub beror på hur långt vi är genom slingan. Om du kör detta får du följande:

Steg 17: Krymp kubarna

Whoops, kuberna är för nära varandra. Vi kan krympa dem för att komma runt detta; ändra bara skala egenskapen hos varje kub:

 för (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 ); 

Steg 18: Lägg kubborna i en array

Så fixar skärningsproblemet, men bara en av våra kuber spinner. Hurså?

Det beror på att kub variabel hänvisar alltid endast till sista kub skapad - och vår funktion onEnterFrame () ändrar bara rotationerna i den där kuben.

Så för att fixa detta behöver vi en Array. Precis som vår materiallista har lagrat flera material, kommer vår Array att lagra flera kuber.

 public var cubeArray: Array;
 cubeArray = new Array (); // skapa den nya Array för (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" betyder bara "lägg till i slutet av listan".)

Steg 19: Gör alla kubbarna Spin

Nu när varje kub är i Array kan vi loopa genom Array varje ram och rotera var och en av dem:

 offentlig funktion onEnterFrame (evt: Event): void för varje (kub i cubeArray) cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5;  renderer.renderScene (scen, kamera, visningsport); 

"För varje" slinga gör kub variabel hänvisar till varje kub i sin tur, en i taget, snarare än bara till den sista kuben som skapades som den gjorde tidigare. Här är resultatet:

Framgång!

Steg 20: Gör en kvadrat av kuber

Vi har gjort en rad kuber, så en kvadrat kommer inte bli svårt. I stället för att bara göra tre kuber ska vi göra tre rader av tre kuber.

För att göra detta kan vi använda en loop-within-a-loop, så här:

 för (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 

Testa det:

Trevlig. Och notera att vi inte behövde ändra koden inuti onEnterFrame () alls; slingan som löper varje ram roterar bara varje kub inuti arrayen - och vi pressar fortfarande varje enskild kub på arrayen.

Steg 21: Gör en kub av kuber

Tja, det skulle vara en besvikelse att sluta på en torg, eller hur? Det här är trots allt en 3D-handledning.

Jag förväntar mig att du kan räkna ut hur man gör det här steget på egen hand. Men om du vill jämföra:

 för (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 );   

Jag har varit lite snuskig här. Jag har startat k vid 0 istället för vid -1, för annars skulle det främsta lagret av kuber vara för nära kameran. Naturligtvis kan du använda vilket nummer du vill ha.

Hej, märkte du att "dämpad" effekten i grunden har försvunnit nu att vi använder mindre kuber?

Grymt bra!

Ytterligare idéer att försöka

Detta skrapar bara ytan på vad du kan göra med Papervision3D. Innan vi går vidare till 3D-glasögon, är det några saker du kan experimentera med:

  • Flytta kuberna istället för att rotera dem: du kan bara ändra x-, y- och z-egenskaperna hos varje kub.
  • Byte av kuber med sfärer: om du importerar org.papervision3d.objects.primitives.Sphere du kan använda sfärklassen. Kolla in dokumenten på detta här.
  • Styrning av kameran med musen: Du kan när som helst få musens x- och y-position med mouseX och mouseY egenskaper. Du kan flytta kameran genom att ändra dess egenskaper x, y och z. Varför inte länka de två ihop?

Fortsättning följer…

I den andra delen lär du dig hur du gör din scen med 3D-glasögon. Så om du har ett par, släng dem inte bort!

Under tiden tack för att du läste den första delen. Jag hoppas att du fann det användbart. Om du har några frågor, eller om något var förvirrande, vänligen skriv en kommentar nedan.