You are on page 1of 6

Programowanie grafiki

Janusz Godasz

Java 3D i Python

ava 3D powstaa przy udziale konsorcjum zoonego z firm: Intel, SGI, Apple oraz Sun w poowie lat 90-tych. W obecnym czasie kady z tych producentw posiada ju wasne rodowisko graficzne 3D, lecz byy one ograniczone a sposb obsugi dosy zoony. Zadaniem konsorcjum byo stworzenie wersji dla powszechnego odbiorcy takiego rodowiska na platform Java i tym samym rozszerzenie jej moliwoci. W wyniku wsplnych prac konsorcjum powstaa Java 3D. Od 2004 Java 3D staa si oprogramowaniem typu open source rozwijanym w dalszym cigu przez Sun-a i rzesze developerw ochotnikw. W rwnym stopniu wspierany jest zarwno OpenGL jak i DirectX. Nie naley myli Javy 3D z mobiln platform Suna o skrtowej nazwie M3G dla J2ME do rozwijania trjwymiarowych aplikacji graficznych na urzdzenia w rodzaju: telefony komrkowe, PDA, itp. Java 3D w obecnej postaci oferuje przenon platform dziaajca w oparciu o maszyn wirtualn Java. Jak prawie kade rodowisko graficzne Java 3D pozwala na tworzenie grafiki trjwymiarowej w oparciu o hierarchiczn struktur grafu, w ktrego wzach znajdowa si bd wszystkie elementy wirtualnego wiata (tj. geometria obiektw, przeksztacenia, kamery, owietlenia, animatory, etc.) konieczne do naleytej reprezentacji projektowanej sceny. Celem artykuu jest prezentacja niektrych moliwoci, jakie moe da Java 3D programistom tworzcym przestrzenne aplikacje graficzne (niekoniecznie przy uyciu tylko i wycznie samej Javy !). Zaczynamy od krtkiej charakterystyki kluczowych pakietw biblioteki, aby nastpnie przej do napisania prostej aplikacji typu Hello3D. W dalszym cigu artykuu skupimy si na integracji Javy 3D ze Swing oraz generowaniu sceny przy uyciu skryptw Pythona, a cilej mwic, jego implementacji na maszyn wirtualn Javy (Jython) i integracji Java 3D z tym rodowiskiem.

Rysunek 1. Pierwsza aplikacja: Hello3D tw, budow sceny zawarte s w kilku pakietach uytkowych, np. com.sun.j3d.utils, a w javax.vecmath znajduj si klasy wspomagajce operacje na wsprzdnych, wektorach i macierzach. Oglnie, mamy do dyspozycji klasy suce tworzeniu geometrii (brak krzywych i powierzchni typu NURBS), animacji, detekcji kolizji, owietleniu i teksturowaniu. Java 3D, w przeciwiestwie do innych rodowisk typu OpenSceneGraph czy Open Inventor, nie posiada natywnego formatu do zapisu/odczytu sceny, w zwizku z czym, chcc nie chcc, musimy w sytuacji, gdy np. konieczny jest import sceny do naszej aplikacji polega na odpowiednich konwerterach dla 3ds Max, VRML, itp. Najczciej spotyka si konwertery formatw .obj i .vrml, ale wspierany jest take w pewnym ograniczonym zakresie .vtk (Virtual Toolkit), .lwo (LightWave) czy te popularny .dxf. Interaktywno, w oglnym tego sowa znaczeniu, sprowadza si do moliwoci zaprogramowania reakcji okrelonego obiektu na zewntrzne bodce. W Java 3D przyjto zasad, i reakcje te wykonywane s zawsze wtedy, gdy bodziec ma miejsce w okrelonych granicach wok obiektu. Zalet takiego rozwizania jest to, i aplikacje jest w stanie zignorowa zdarzenie majce miejsce poza zdefiniowanym dla danego obiektu zakresem. Definiowanie zakresw zdarze jest konieczne do okrelenie przez aplikacje, na ktre bodce powinna zareagowa. Reakcje mona powiza z dowoln liczb zdarze, np. zblienie do okrelonego obiektu moe powodowa zmian w kolorze, obrt, etc. Co wicej, wiele reakcji mona kontrolowa przy uyciu tzw. interpolatorw (np. przemieszczanie si obiektu wzdu okrelonej trajektorii). Software Developers Journal 6/2006

Java 3D opis

API Java 3D stanowi kilka pakietw, z ktrych najwaniejsze to jdro: javax.media.j3d.org. Klasy zwizane z konstrukcj i opisem geometrii obiekAutor jest pracownikiem Centrum Technicznego firmy Delphi Poland w Krakowie. Kontakt z autorem: janusz.goldasz@delphi.com

42

www.sdjournal.org

Java 3D i Python

Listing 1. Pierwsze kroki Hello3D


import java.applet.Applet; import java.awt.BorderLayout; import java.awt.event.*; import java.awt.GraphicsConfiguration; import com.sun.j3d.utils.applet.MainFrame; import com.sun.j3d.utils.geometry.*; import com.sun.j3d.utils.universe.*; import javax.media.j3d.*; import javax.vecmath.*; import com.sun.j3d.utils.behaviors.mouse.*; import com.sun.j3d.utils.behaviors.vp.*; import com.sun.j3d.loaders.objectfile.ObjectFile; import com.sun.j3d.loaders.ParsingErrorException; import com.sun.j3d.loaders.IncorrectFormatException; import com.sun.j3d.loaders.Scene; import java.io.*; public class Hello3D extends Applet { TransformGroup.ALLOW_TRANSFORM_READ); objRoot.addChild(objTransform1); objRoot.addChild(objTransform2); Sphere sphere = new Sphere(0.5f);

ColorCube cube = new ColorCube(0.5f); Color3f sphereColor =

Appearance appearance = new Appearance(); new Color3f(1.0f, 0.2f, 0.4f);

app.setMaterial(new Material(sphereColor, new Color3f(0f,0f,0f), sphereColor, new Color3f(1f,1f,1f), 10));

sphere.setAppearance(appearance); objTransform1.addChild(sphere); objTransform2.addChild(cube); MouseRotate rotate = new MouseRotate(objTransform2);

private SimpleUniverse universe = null;

objRoot.addChild(rotate);

public BranchGroup createSceneGraph() {

rotate.setSchedulingBounds(bounds); objRoot.addChild(zoom);

BranchGroup objRoot = new BranchGroup(); new Point3d(0,0,0),100);

MouseZoom zoom = new MouseZoom(objTransform2); zoom.setSchedulingBounds(bounds); int flags = ObjectFile.RESIZE; Scene model = null; ObjectFile file = new ObjectFile(flags); model = file.load("model.obj");

BoundingSphere bounds = new BoundingSphere( Background background = new Background(); background.setApplicationBounds(bounds); objRoot.addChild(background); Color3f lightColor1 = new Color3f(0.7f, 0.7f, 0.7f); new Vector3f(1.0f, .0f, .0f); new Color3f(0.2f, 0.2f, 0.2f); new AmbientLight(ambientLightColor); } =

background.setColor(new Color3f(0.0f,0.0f,1.0f));

Transform3D mdlTransform = new Transform3D(); mdlTransform.set(new Vector3f(0f,0f,0f)); mdlTransform.setScale(0.5f); TransformGroup objTransform3 = objTransform3.setTransform(mdlTransform); objTransform3.addChild(model.getSceneGroup()); objRoot.addChild(objTransform3); objRoot.compile(); return objRoot; new TransformGroup();

Vector3f lightDirection1

Color3f ambientLightColor = AmbientLight ambientLight =

ambientLight.setInfluencingBounds(bounds); DirectionalLight dirLight = new DirectionalLight( lightColor1, lightDirection1); dirLight.setInfluencingBounds(bounds); objRoot.addChild(ambientLight); objRoot.addChild(dirLight); sphereTransform.set( Transform3D sphereTransform = new Transform3D(); new Vector3f(0.5f,0.0f,-0.25f));

public Hello3D() { } public void init() {

setLayout(new BorderLayout()); GraphicsConfiguration config = Canvas3D c = new Canvas3D(config); add("Center", c); SimpleUniverse.getPreferredConfiguration();

sphereTransform.setScale(0.5f); TransformGroup objTransform1 = new TransformGroup();

BranchGroup scene = createSceneGraph(); universe = new SimpleUniverse(c); universe.getViewingPlatform().

objTrans1.setTransform(sphereTransform);

Transform3D cubeTransform = new Transform3D(); cubeTransform.setScale(0.5f); TransformGroup objTransform2 = objTransform2.setTransform(cubeTransform); objTransform2.setCapability( TransformGroup.ALLOW_TRANSFORM_WRITE); objTransform2.setCapability( new TransformGroup();

setNominalViewingTransform(); universe.addBranchGraph(scene); } public void destroy() { u.cleanup(); }

cubeTransform.set(new Vector3f(-0.5f,0f,0.25f));

public static void main(String[] args) { } }

new MainFrame(new Hello3D(), 256, 256);

Software Developers Journal 6/2006

www.sdjournal.org

43

Programowanie grafiki
Listing 2. Przykad uycia obiektu Canvas3D ze Swing
class Panel3D extends JPanel{ public Panel3D(){ } } this.add(new Canvas3D(config));

Listing 3. Rysunkowa para JTabbedPane Canvas3D


class Tabbed extends JTabbedPane{ public Tabbed(){ // // Gotowe: Java 3D wewntrz Swing this.addPage(new Panel3D()); // } }

Pierwsze kroki

Tworzenie aplikacji w oparciu o Java 3D pokaemy na raczej typowym dla tej biblioteki przykadzie zawierajcym kilka najczciej spotykanych elementw (prymitywy, komponowanie sceny, wczytanie modelu z zewntrznego pliku, reakcje) na ekranie (Rysunek 1) pojawi si kula, szecian i (wczytany z pliku .obj) obiekt 3D. Kula i obiekt pozostan nieruchome, a uytkownik moe manipulowa jedynie szecianem. Na pocztek przyjrzyjmy si implementacji klasy Hello3D w Listingu 1. Nasza aplikacja to typowy applet, w zwizku z czym konieczne jest dziedziczenie po klasie Applet i implementacja metody init(). Do rysowania wykorzystujemy odpowiednio skonfigurowane okno klasy Canvas3D klasa Canvas3D dziedziczy po awt.Canvas. Kluczowa dla zawartoci trjwymiarowej sceny jest stworzona przez nas metoda createScene(), zwracajca korze sceny ( scene ) klasy BranchGroup (javax.media.j3d.BranchGroup ). Chcc stworzon scen wywietli, w dalszej czci metody musimy doczy korze do naszego wszechwiata ( universe ). W metodzie createScene(), na pocztek musimy zainicjowa korze drzewa ( root), do ktrego bdziemy dokada kolejne elementy sceny. Kolejno ustawiamy: to ( background ), wiato otoczenia ( ambientLight) i kierunkowe ( dirLight). Granice sceny ustalamy tworzc instancj klasy BoundingSphere ( bounds ). Chcc manipulowa jedynie szecianem, musimy stworzy dla niego osobn ga (grup) i w rezultacie do korzenia doczy trzy oddzielne instancje klasy TransformGroup ( objTransform1 dla kuli, objTransform2 dla szecianu i objTransform3 dla sceny, ktr wczytywa bdziemy z pliku) tylko objTransform2 w kocowym efekcie bdzie posiada mechanizm obsugi zdarze myszki. Tak kul jak i szecian przesuwamy i skaluje-

my uywajc metod set(Vector3f x) i setScale(float scale) klasy Transform3D. W przypadku kuli i modelu dziaamy odpowiednio na instancjach sphereTransform oraz mdlTransform , dla szecianu natomiast na instancji cubeTransform (w gazi objTransform2). Dodatkowo, kula jest kolorowana ( sphere.setAppearance(appearance)). Do manipulowania szecianem myszk potrzebne s nam jeszcze instancje klasy MouseZoom (zoom) i MouseRotate (rotate). Obydwie przyjmuj objTransform2. Dla wczytania zewntrznego modelu (sceny) kluczowy jest nastpujcy fragment
ObjectFile file = new ObjectFile(flags); Scene model = null; model = file.load("model.obj");

Tak wczytany model wystarczy tylko umieci w przeznaczonej dla niego gazi i doczeniu jej do korzenia:
objTrans3.addChild(model.getSceneGroup()); objRoot.addChild(objTrans3);

Musimy jeszcze tylko pamita o biecym modyfikowaniu treci drugiej grupy


objTransform2.setCapability( TransformGroup.ALLOW_TRANSFORM_WRITE) objTransform2.setCapability( TransformGroup.ALLOW_TRANSFORM_READ);

doczeniu wszystkich potrzebnych elementw do korzenia i pierwsza aplikacja jest gotowa.

Rysunek 2. Przykad importu do Java 3D powierzchni wygenerowanej w Blenderze

Rysunek 3. Przykad poczenia GUI z Java 3D symulator czsteczek

44

www.sdjournal.org

Software Developers Journal 6/2006

Java 3D i Python

Listing 4. Java 3D w Jythonie


import java.awt.GraphicsConfiguration from java.applet import Applet from java.awt import BorderLayout from java.awt.event import * from com.sun.j3d.utils.geometry import * from com.sun.j3d.utils.universe import * from javax.media.j3d import * from javax.vecmath import * from com.sun.j3d.utils.behaviors.mouse import * from com.sun.j3d.utils.behaviors.vp import * # Tworzymy applet class Hello3D(Applet): def init(self): self.setLayout(BorderLayout()) self._bounds = BoundingSphere(Point3d(0.0,0.0,0.0), 100.0) config = SimpleUniverse.getPreferredConfiguration() c = Canvas3D(config) self.add("Center", c) self._scene = self.createScene() self._universe = SimpleUniverse(c) self._viewingPlatform = self._universe.getViewingPlatform(); self._viewingPlatform.setNominalViewingTransform(); self._universe.addBranchGraph(self._ scene) # Kolej na tworzenie sceny def createScene(self): # korze objRoot = BranchGroup() background = Background() background.setColor(Color3f(0,0,1)) background.setApplicationBounds(self._bounds) objRoot.addChild(background) lightColor1 = Color3f(0.7, 0.7, 0.7) lightDirection1 = Vector3f(1.0, .0, .0) ambientColor = Color3f(0.2, 0.2, 0.2) ambientLight = AmbientLight(alColor) ambientLight.setInfluencingBounds(self._bounds) dirLight = DirectionalLight(lightColor1, lightDir1) dirLight.setInfluencingBounds(self._bounds) objRoot.addChild(ambientLight) # Testujemy applet if __name__ == '__main__': import pawt pawt.test(Hello3D()) # Koniec objRoot.addChild(dirLight) sphereTransform = Transform3D() sphereTransform.set(Vector3f(0.,0.5,-0.25)) sphereTransform.setScale(0.5) objTransform1 = TransformGroup() objTransform1.setTransform(sphereTransform) cubeTransform = Transform3D() cubeTransform.set(Vector3f(0.,-0.5,0.25)) cubeTransform.setScale(0.5) objTransform2 = TransformGroup() objTransform2.setCapability( TransformGroup.ALLOW_TRANSFORM_WRITE) objTransform2.setCapability( TransformGroup.ALLOW_TRANSFORM_READ) objTransform2.setTransform(cubeTransform) objRoot.addChild(objTransform1) objRoot.addChild(objTransform2) sphere = Sphere(0.5) cube = ColorCube(0.5) appearance = Appearance() objColor = Color3f(1.0, 0.2, 0.4) appearance.setMaterial(Material( objColor, Color3f(0,0,0), objColor, Color3f(1,1,1), 10)) sphere.setAppearance(appearance) objTransform1.addChild(sphere) objTransform2.addChild(cube) rotate = MouseRotate(objTransform2) objRoot.addChild(rotate) rotate.setSchedulingBounds(self._bounds) zoom = MouseZoom(objTransform2) objRoot.addChild(zoom) zoom.setSchedulingBounds(self._bounds) objRoot.compile() return objRoot # koniec metody createScene

Zwrmy uwag, e informacja o tworzywie wczytanego modelu moe znajdowa si w zewntrznej bibliotece materiaowej. W przypadku plikw .obj jest to zwykle tekstowy plik z rozszerzeniem .mtl generowany przy okazji tworzenia samego modelu. Aby mc z niego skorzysta, wystarczy w naszym modelu (w formacie .obj) umieci dwie instrukcje
mtllib model.mtl usemtl 20

rzywa, ktrym kolorujemy albo cay model albo wybran grup. W tym wypadku spada z nas np. caa odpowiedzialno za kolor obiektu, przezroczysto, itp. Trzeba pamita, e wikszo istniejcych w konwerter plikw .obj, a take .lwo zwykle nie obsuguje caoci specyfikacji okrelonego formatu. W ekstremalnych sytuacjach konieczna jest edycja pliku i usunicie kopotliwych elementw. Z istniejcych modelerw open source dobre wyniki daj Blender oraz Wings zob. Rysunek 2.

Pierwsza z nich okrela zewntrzn bibliotek, z ktrej moemy pobra odpowiednie tworzywa, a druga indeks twoSoftware Developers Journal 6/2006

Okienka

Integracja Javy 3D ze Swing nie jest bezproblemowa. Poprawnie Java 3D pracuje jedynie ze starszymi kontenera-

www.sdjournal.org

45

Programowanie grafiki
Listing 5. Wykorzystanie klasy PythonInterpreter
// Import klas Java 3D import org.python.core.PyObject; // Jython import org.python.util.PythonInterpreter; // interpreter // Klasa dziedziczy po JFrame - Swing public class embDemo extends JFrame { // pola prywatne, etc. public embDemo(String source) { // // Dodajemy do ramki nasz panel 3D this.getContentPane().add(new Tabbed(source)); // } // Panel dziedziczy po klasie JPanel class Panel3D extends JPanel { // // Scena i wirtualny wszechwiat BranchGroup scene; SimpleUniverse sUniverse = new SimpleUniverse(can vas3D); scene = createSceneGraph(source); sUniverse.addBranchGraph(scene); // this.setLayout(new BorderLayout()); this.setOpaque(false); } this.add("Center", canvas3D); } // Dziedziczymy po klasie JTabbedPane class Tabbed extends JTabbedPane { // source to nazwa skryptu Pythona // Metoda createSceneGraph() jest inna ni zwykle.. private BranchGroup createSceneGraph(String source) { BranchGroup objRoot = new BranchGroup(); TransformGroup mainGroup = new TransformGroup(); // // Python: uruchamiamy interpreter // Tutaj embeddedWorld zwraca wczytan // z zewntrz scen BranchGroup embedded = embeddedWorld(source); } } public Tabbed(String source) { // Zakadka z panelem 3D } } this.addTab("View", new Panel3D(source)); } public Panel3D(String source) { } mainGroup.addChild(embedded); // Python: KONIEC objRoot.addChild(mainGroup); return objRoot;

private BranchGroup embeddedWorld(String source) { Object input = null; BranchGroup root = new BranchGroup(); // Inicjujemy interpreter PythonInterpreter interp = new PythonInterpreter(); // ...i wczytujemy do niego tre skryptu try { DataInputStream in = new DataInputStream( interp.execfile(in); new FileInputStream( source ));

// Pobieramy okrelony obiekt - scene } catch (FileNotFoundException E) { E.printStackTrace(System.err); } // Rzutujemy - input jest instancj klasy Object return (BranchGroup) input; input = interp.get("scene",BranchGroup.class);

public static void main(String[] args) { new embDemo(args[0]);

mi AWT. Powszechnym problem jest przerysowywanie i zakrywanie kontrolek Swingowych przez Jav 3D ( Canvas3D ), co powoduje, e uycie wikszoci kontrolek Swingowych jest praktycznie niemoliwe. Najlepsze wyniki, jak pokaemy na przykadzie, daje para JTabbedPane Canvas3D i dziedziczenie po klasie JPanel, np. w sposb pokazany w Listingu 2 i 3. Teraz wystarczy ju tylko Rysunkowa para JTabbedPane Canvas3D, przedstawiona na Listigu 3. Dziki takiemu rozwizaniu mona w atwy sposb tworzy rozbudowane aplikacje z typowym dla Swingowych aplikacji interfejsem uytkownika, jak np. ta zilustrowana na Rysunku 3 przedstawiajc symulator czsteczek.

Java 3D a Jython

Ciekaw alternatyw dla programistw uywajcych obiektowe jzyki skryptowe wysokiego poziomu (np. Python) jest moliwo integracji Javy 3D z Pythonem, a konkretnie z im-

plementacj Pythona o nazwie Jython na maszyn wirtualn Javy. Zalet tworzenia aplikacji przy uyciu jzykw skryptowych w rodzaju Pythona jest wiele np. obecno typw danych wysokiego poziomu (listy, sowniki) przyspieszajca tworzenie aplikacji, dynamiczne typowanie, oszczdno kodu, interpretowanie zamiast kompilacji. Jython w wersji 2.1 jest zgodny z J2SE, dziki czemu korzystanie w nim ze rodowiska Java 3D w obecnej wersji (1.3.1) jest bezproblemowe Jython jest w 100% napisany w Javie, co daje moliwo importowania klas Javy do tworzonych przez nas skryptw. Dla porwnania z poprzednim kodem, poniej przykad skryptu/appletu stworzonego w Pythonie. Aplikacja jest identyczna z opisan na wstpie aplikacj Hello3D poza fragmentem dotyczcym wczytania elementu sceny z zewntrz. Odpowiednie moduy Javy i Javy 3D importujemy, uywajc typowej konstrukcji Pythona
from com.sun.j3d.utils.behaviors.mouse import *

46

www.sdjournal.org

Software Developers Journal 6/2006

Java 3D i Python

W Sieci
niezalene forum developerw Java 3D, JOGL http://www.j3d.org strona domowa Javy http://www.javasoft.com strona domowa Eclipse IDE http://www.eclipse.org strona domowa programu Blender http://www.blender.org

Struktura appletu (w Pythonie !) jest w zasadzie identyczna z pierwszym przykadem (Java). Do naszego przykadu stosuj si, oczywicie wszystkie charakterystyczne cechy Pythona, a wic oszczdno kodu, typowanie, etc. Wskazwka dla osb nie majcych stycznoci z Pythonem: sowo self jest odpowiednikiem this Javy, ale w Pythonie self musi by uyte jawnie w treci klasy. W aspekcie korzystania z Pythona, pojawia si te moliwo rozszerzania funkcjonalnoci naszej aplikacji skryptami Pythona (Jythona), co w wielu przypadkach jest rzecz nie do pogardzenia. Oglnie rzecz ujmujc, para Java-Jython daje dwie moliwoci: kompilacja kodu Pythona do postaci klasy Javy i wywoanie go w tworzonej aplikacji w postaci klasy lub wykorzystanie interpretera polece Pythona (klasa PythonInterpreter) do wywoania zewntrznego skryptu generujcego np. geometri. Jak sprawdzilimy w praktyce, pierwsze rozwizanie nie zawsze dziaa, natomiast korzystanie z interpretera jest o wiele bardziej niezawodne i czytelne. Integracj Java (i Java 3D) z Pythonem (Jythonem) pokaemy na przykadzie nieskomplikowanej aplikacji okienListing 6. Fragment importowanego skryptu Jythona (brak listy moduw Java 3D)
# Lista moduw Java 3D # funkcja createScene() def createScene(): # Tradycyjnie, korzen objRoot = BranchGroup() bounds = BoundingSphere(Point3d(0.0,0.0,0.0), 100.0) background = Background() background.setColor(Color3f(0,0,1)) background.setApplicationBounds(bounds) objRoot.addChild(background) objTransform = TransformGroup() objTransform.setCapability(TransformGroup.ALLOW_ TRANSFORM_READ) objRoot.addChild(objTransform) objTransform.addChild(ColorCube(0.4)) return objRoot # koniec funkcji # Wywoujemy createScene() i wynik przypisujemy # do zwracanej zmiennej scene scene = createScene() # Koniec

Rysunek 4. Jython zanurzony kowej (zob. Rysunek 4), skonstruowanej w opisany w Listingach 2 i 3 sposb. Tym razem jednak zamiast skazywa si tylko i wycznie na towarzystwo Javy w treci metody createSceneGraph() pojawi si wywoanie skryptu Jythona o okrelonej zawartoci (Listingi 5 i 6). W Listingu 5 brak czci powtarzajcych si fragmentw kodu. Najwaniejsza zmiana w treci klasy to nowa metoda o nazwie emebeddedWorld(String source), ktrej parametrem jest nazwa zewntrznego skryptu Jythona source aplikacj wywoujemy z parametrem w postaci nazwy skryptu. Do zinterpretowania treci skryptu w sposb zrozumiay dla naszej aplikacji konieczne jest utworzenie obiektu klasy PythonInterpreter (Klasa ta posiada metod execfile(), przyjmujc instancj klasy FileInputStream (skrypt), ktrej wykonanie powoduje przetworzenie treci skryptu oraz metod get(), ktrej pierwszym parametrem jest nazwa pobieranego obiektu Pythona ( scene ), a drugim odpowiednia klasa Java 3D. W naszym przypadku jest to klasa BranchGroup konieczne jest rzutowanie do klasy BranchGroup.

Oprogramowanie

Wszystkie omwione w niniejszym artykule przykady powstay przy uyciu Java 3D w wersji 1.3.1, Java 2 SE, Jython 2.1 oraz rodowiska Eclipse w wersji 3.1 z wtyczk PyDev (Python/Jython). Wykorzystany w pierwszym przykadzie model jest czci dystrybucji Java 3D. Minimalne zasoby potrzebne do utworzenia opisanych aplikacji s jednak znacznie mniejsze i mog ogranicza si do koniecznoci zainstalowania Javy (J2SE) wraz z Java 3D oraz Jythona i tworzeniu opisanych aplikacji przy pomocy dowolnego edytora tekstowego.

Podsumowanie

Java 3D jest, pomimo pewnych swoich niedocigni (kiepska wsppraca ze Swing, brak bezporedniego dostpu do funkcji OpenGL, prosty model owietlenia) i wieku, stosunkowo atrakcyjnym rozwizaniem dla programistw WWW i gier Java. W dalszym cigu posiada duy potencja i moliwoci pozwalajce programistom na umieszczanie niewielkim nakadem pracy elementw grafiki 3D w appletach i aplikacjach Java, cho obecnie popularniejszym rozwizaniem, np. w sferze gier Java, wydaj si by dedykowane rozwizania, np. oparta na JOGL biblioteka Xijth3D. Java 3D chyba jednak najbardziej wpasowuje si w model przeznaczony dla rednio-wymagajcego uytkownika. n www.sdjournal.org

Software Developers Journal 6/2006

47

You might also like