En dokumentation om Java 3D API Johan Pellbäck Inst för Data- och Systemvetenskap Stockholms Universitet 1. INLEDNING.................................................................................................... 1 1.1. 1.2. 1.3. 1.4. 2. NÅGRA KODEXEMPEL ............................................................................... 3 2.1. 2.2. 2.3. 3. VAD ÄR JAVA 3D API?............................................................................... 1 EN VIRTUELL, 3-DIMENSIONELL VÄRLD ....................................................... 1 EN HIERARKI AV KLASSER ........................................................................... 2 BESKRIVNING AV ETT ANTAL ANVÄNDBARA KLASSER .................................. 3 SKAPA ETT VIRTUELLT UNIVERSUM ............................................................. 3 KOPPLA SAMMAN DITT UNIVERSE MED EN BRANCHGROUP ............................ 4 ATT SKAPA RÖRELSE ................................................................................... 4 INSTALLATION OCH MILJÖ ..................................................................... 5 3.1. 3.2. 3.3. INSTALLERA JDK ....................................................................................... 5 INSTALLERA JAVA3D 1.3.1, DIRECTX......................................................... 6 TIPS OCH TRIX............................................................................................. 6 1. Inledning Detta dokument har till syfte att ge en inblick i funktionerna och användandet av Java 3D API. Förhoppningen med dokumentet är att minska tröskeln för studenter som snabbt vill komma igång med 3D-programmering och att ge en snabb överblick över de olika klasserna och hur de samarbetar. Dokumentet innehåller också en installationsanvisning och några kommentarer till vad man bör tänka på vid installation och exekvering av sina Java-program. Erfarenheterna, som ligger till grund för detta dokument, baserar sig på Java 3D version 1.3.1 och operativsystemet Windows 2000. 1.1. Vad är Java 3D API? Java 3D är utvecklat av Sun Microsystems som ett standardtillägg till Java 2 SDK. Det är alltså ett API med klasser som tillhandahåller funktionalitet för att skapa, manipulera och rendera 3 dimensionella geometriska objekt. 1.2. En virtuell, 3-dimensionell värld Att presentera ett 3-dimensionellt objekt på en 2-dimensionell yta, som datorns skärm faktiskt är, innebär i realiteten att man manipulerar med färg, ljus och form för att vårt öga skall uppfatta objektet i 3 dimensioner. För att få en konceptuell bild av det hela kan vi se det som att våra geometriska objekt existerar i två världar. Dels ett virtuellt 3-dimensionellt universum som beskriver våra geometriska objekt i 3 riktningar (X, Y, Z), detta kan vi inte riktigt avbilda på vår datorskärm. Dels en 2-dimensionell färgduk på vilken våra bilder av den virtuella världen projiceras, denna projicering kallas för rendering. I Java 3D API beskrivs dessa två miljöer som Virtual Universe och Image plate. Figur 1 – en konceptuell bild av Image plate och Virtual Universe 1 1.3. En hierarki av klasser Vårt 3-dimensionella universum, som vi nu kallar för scen, byggs upp med klasser ur Java 3D API i en sorts hierarki. Relationen dessa emellan bygger på konceptet parentchild där en nod i hierarkin kan ha flera childs men bara en parent. En leaf-node kan ha en parent men inga childs. Vår scen utgår från en root och det finns bara en väg genom grafen från root till varje leaf-node. Skall man vara noggrann så bör det tilläggas, eftersom det bara finns en enda väg från root till leaf-node, att det också finns en scen för varje leaf-node. VirtualUniv erse <<extend>> Canv as3D <<reference>> SimpleUniv erse - SceneGraphObject canvas: Canvas3D <<abstract>> Node <<abstract>> BranchGroup Group + + <<parent, child>> addChild() : void getChild() : Node Transform3D TransformGroup TransformGroup - + + + transform: Transform3D BoundingSphere rotX() : void rotY() : void rotZ() : void RotationInterpolator Shape3D Primitiv e <<Text2d etc.>> <<Box, Cone, Cylinder etc. >> - tg: TransformGroup bs: BoundingSphere transform : Transform3D + + setSchedulingBounds(BoundingSphere) : void setAxisOfRotation(Transform3D) : void Figur 2 – Klassdiagram Figur 2 visar en exemplifiering av ett virtuellt universum med klassen SimpleUniverse som root och klassen Canvas3D som Image plate. Ett virtuellt universum består i sin grundläggande del av två kategorier objekt, VirtualUniverse och SceneGraphObject. VirtualUniverse bildar root-objektet och fungerar som hållare av den 3-dimensionella scenen. SceneGraphObject består i sin tur av kategorierna Node och Group vilka utgör de vanligaste objekten i scenen. SceneGraphObject och Node är abstrakta klasser som definierar ett antal grundläggande metoder och attribut för sina subklasser. Group, här exemplifierade som BranchGroup och TransformGroup, är klasserna som specificerar och har ansvar för placering och form av visuella objekt i grafen. Detta var en grov beskrivning av generella klasser, de övriga klasserna i figur 2 beskrivs nedan. 2 1.4. Beskrivning av ett antal användbara klasser Canvas3D – denna klass är en gränssnittskomponent (UI component) och ärver sina egenskaper från komponenter ur AWT (Abstract Windowing Toolkit). Den används för att rendera 3D objekt. BranchGroup – denna klass används för att skapa 3D-scenens hierarki. En BranchGroup klass hålls av en VirtualUniverse klass och kan ha flera childs. TransformGroup – denna klass ingår också i 3D-scenens hierarki och är child till BranchGroup. Den ansvarar vanligtvis för transformering av objekt, exempelvis rotering, detta genom att hålla en referens till ett Transform3D objekt. Transform3D – denna klass ingår inte i scenens hierarki men används av TransformGroup för att transformera grafiska objekt, exempelvis genom att rotera en figur i någon riktning. När man specificerar en transformation, exempelvis en rotering, så gör man det i radianer. Cone – denna klass ingår i ett paket med geometriska objekt. Den specificerar en kon med radie och höjd. ColorCube - ett geometriskt objekt som specificerar en kub med sidor i olika färger. RotationInterpolator – en klass som sammankopplas med TransformGroup och Transform3D för att skapa rörelse hos geometriska objekt. Alpha – en klass som används för att definiera variationer i tiden. BoundingSphere – en klass som används för att definiera en gräns/region med hjälp av ett centrum och en radie. 2. Några kodexempel 2.1. Skapa ett virtuellt universum För att kunna köra sin 3D-rendering i både en webb-läsare (som applet), genom appletviewer eller som en separat Java-applikation kan det vara bra att först skapa en klass som är subklass till Applet. Denna klass implementerar en main-metod som använder sig av en MainFrame där man startar sin applet. import com.sun.j3d.utils.applet.MainFrame; public class Exempel3D extends Applet { public Exempel3d{ } publid static void main(String[] args{ Frame frame = new MainFrame(new Exempel3D(), 256, 256); } Kodexempel 1 – Klassdeklaration och main-metod Skapa sedan ett VirtualUniverse, ett Canvas3D för rendering och en BranchGroup i kontruktorn på din Applet klass. Canvas3D objektet kräver en instans av klassen GraphicsConfiguration vid instansiering, skapa denna klass genom att anropa den statiska metoden gerPreferredConfiguration i SimpleUniverse klassen. 3 public Exempel3d{ GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration(); canvas3D = new Canvas3D(config); this.add("Center", canvas3D); su = new SimpleUniverse(canvas3D); su.addBranchGraph(makeBranchGraph()); setSize(300,300); } Kodexempel 2 – konstruktorn 2.2. Koppla samman ditt Universe med en BranchGroup I exemplet ovan skapas BranchGroup i en separat metod, makeBranchGraph(). Låt denna metod skapa en BranchGroup med underliggande TransformGroup, eventuella geometriska objekt och ett Transform3D objekt som ansvarar för transformation av de geometriska objekten. private BranchGroup makeBranchGraph(){ BranchGraph returnobj = new BranchGraph(); Transform3D rotor1 = new Transform3D(); Transform3D rotor2 = new Transform3D(); rotor1.rotX(Math.PI/4.0d); rotor2.rotY(Match.PI/5.0d); rotor1.mul(rotor2); TransformGroup tg = new TransformGroup(rotor1); tg.addChild(new ColorCube(0.4)); returnobj.addChild(tg); return returnobj; } Kodexempel 3 – skapa Branchgroup Exemplet ovan skapar två olika Transform3D objekt, detta har effekten att kuben i detta exempel kommer att kunna rotera i två olika riktningar (X-led och Y-led). 2.3. Att skapa rörelse Att skapa rörelse i sin 3-D scen kan göras på många sätt. Som programmerare kan man välja att använda inbyggda beteenden och rörelsemönster hos objekten eller helt och hållet definiera egna. Beteendet hos objekten kan antingen definieras som en interaktion med användaren eller automatiskt utsträckt i tiden. Med hjälp av klassen RotationInterpolator kan man använda sig av de inbyggda beteenden som tillhandahålls i Java 3D API. Med hjälp av en tidsfunktion uppdaterar klassen automatiskt ett eller flera objekt i scenen. Med hjälp av en Transform3D, som skapats inom en TransformGroup, kan ett RotationInterpolator objekt manipulera alla de underliggande objekt som är underliggande childs till en viss TransformGroup. RotationInterpolator använder sig av klassen Alpha för att kunna bestämma ett beteende i tiden. Denna klass är komplex och någon ingående beskrivning av klassen ges inte här. 4 private BranchGroup makeBranchGraph(){ … Alpha alpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0, 5000, 0, 0, 0, 0, 0); RotaionInterpolator ri = new RotationInterpolator(alpha, tg); ri.setAxisOfRotation(rotor1); … } Kodexempel 4 – använding av RotationInterpolator och Alpha I ett virtuellt universum kan det tänkas att man definierar flera olika beteenden och kopplar dessa till flera olika objekt. Det finns då en risk för att systemet snabbt blir överbelastat. Därför är det bra att definiera en gräns eller region för en RotaionInterpolator, en BoundingSphere. private BranchGroup makeBranchGraph(){ … BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0); ri.setSchedulingBounds(bounds); … } Kodexempel 5 – använding av BoundingSphere Det finns mycket mer att fördjupa sig i angående rörelsebeteende, manipulation och interaktion med 3D-objekt. Denna dokumentation har dock inte för avsikt att gå särskilt djupt in på detta område, för en djupare genomgång hänvisas till dokumentation om Java 3D API. 3. Installation och miljö För dig som har tänkt att installera, programmera och köra Java 3D rendering på en egen dator kommer här en liten installationsanvisning samt några tips att tänka på innan du kör igång. 3.1. Installera JDK Om du inte sedan tidigare har JDK installerat på din dator bör du börja med att installera detta. Ladda hem senaste versionen från http://java.sun.com/downloads/. Lämpligtvis väljer du att installera Java 2 Standard Edition (J2SE). Var noga med att installera SDK (Software Development Kit) och inte bara JRE (Java Runtime Environment). När installationen är klar kan du verifiera att allting fungerar genom att starta kommandofönstret (Start – run – cmd) och skriva. java –version. Detta kommando visar vilken version av JDK som installerats och indikerar att ditt system hittar javatolken. Ett bra tips är att lägga till en punkt (.) till CLASSPATH, detta betyder att aktuell katalog alltid inkluderas i Javas sökväg. CLASSPATH inställningen är åtkomlig i Windows under ’System Properties’ och ’Environment Variables’. Genom att via kommandoprompten köra kommandot ”SET” kan du se dina olika miljöinställningar på systemet. 5 3.2. Installera Java3D 1.3.1, DirectX Börja med att ladda hem programfilerna för Java 3D från Sun’s hemsida. Dessa hittar du under http://java.sun.com/products/java-media/3D/. Var noga med att välja ”Java 3D for Windows (DirectX Version) SDK for the JDK (includes runtime)”. Starta installationen och se till att installera programpaketet på samma ställe som du tidigare installerat JDK. Om du installerar i samma bibliotek behöver du inte manipulera med CLASSPATH inställningarna på din dator. Ladda även hem API dokumentationen för Java 3D 1.3.1. Denna finner du under http://java.sun.com/products/java-media/3D/download.html. Denna laddas ner som en ZIP eller TAR och kräver därför WinZip. Packa upp denna fil i något lämpligt bibliotek på din dator. Du kommer att ha mycket nytta av att läsa API dokumentationen. Nu kan du verifiera att Java 3D fungerar genom att exempelvis köra något av de exempel som följer med installationen. Starta kommandofönstret och leta dig fram till JDK katalogen (exempelvis: cd\jdk\jdk1.4.0_01). Ställ dig i någon av katalogerna demo (exempelvis: cd demo\Java3d\Appearance). Prova att starta ett exempel med hjälp av AppletViewer (exempelvis: appletviewer AppearanceTest.html). 3.3. Tips och trix Testköra applikationer Det kan vara ganska knepigt att få applikationerna att fungera i alla olika miljöer och webbläsare. Ett bra tips är att under utvecklingsfasen bara köra koden i appletviewer. Då slipper du onödiga felkällor som kan uppstå i din webbläsare, dessa problem är bättre att tampas med när koden börjar bli färdig. Ett annat tips vid testning är att köra sin applet i com.sun.j3d.utils.applet.MainFrame. Då kan du under testfasen köra din kod i en vanlig java-applikation (se i exempelkoden i detta dokument). Inställningar i webbläsaren Om du har problem med att få din kod att fungera i webbläsaren så bör du först och främst provköra exemplen som installeras tillsammans med Java 3D API. Peka din webbläsare till den katalog där du tidigare installerat Java 3D API, exempelvis file:// C:\jdk\jdk1.4.0_01\demo\java3d\index.html. Var säker på att du alltid har den senaste versionen av JDK installerat. Kontrollera efter uppdateringar på Suns hemsida: http://java.sun.com/products/plugin/ Undvik att installera JDK och Java 3D API i en katalog som innehåller blanksteg, exempelvis C:\Program Files\Java. En del 3D-program kommer att kräva en större heap-size. Prova att ändra denna inställning genom att lägga till parametern ”mx64m” till körtidsparametrarna i kontrollpanelen för Java i Windows kontrollpanel. 6