Java3D-Tutorial, die zweite.

Status
Nicht offen für weitere Antworten.

Illuvatar

Top Contributor
Nachdem hoon seine Starthilfe nicht mehr fortzuführen scheint, hab ich mir gedacht, ich schreib auch mal so was in der Art.
Ich werde allerdings noch einmal von vorne anfangen, und mich enger an das englische Java3D-Tutorial von Sun halten.
Bei den Tutorials will ich auch das hier erwähnen, woran Oxygenic mich erinnert hat:
Oxygenic hat gesagt.:

Let's start:

1. Installation
Ihr benötigt natürlich ein Java-SDK und ein Java3D-SDK. Die neueste Version ist 1.3.1, ob noch mehr kommt, ist fraglich. Die API-Dokumentation ist natürlich auch nützlich.
Das Java3D-SDK gibt es in zwei Versionen: OpenGL und DirectX. Ich habe die Erfahrung gemacht, dass DirectX performancemäßig um einiges besser ist, aber OpenGL ist eben plattformunabhängig. Diese Beschreibung ist über DirectX, OpenGL ist aber sehr ähnlich.

2. Grundlagen
Die Pakete, die mitgeliefert werden:
javax.media.j3d: Das wichtigste Paket, in der API dokumentiert, enthält die grungliegenden Klassen.
javax.vecmath: Enthält Klassen für 2- bis 4-Dimensionale Punkte/Farben/Vectoren/Matrizen u.ä., auch in der API dokumentiert.
com.sun.j3d.utils und Unterpakete: Enthält viele nützliche Hilfsklassen, allerdings nur hier dokumentiert (den Link habe ich dank Oxygenic hier gefunden), und das recht schlecht.

Der SceneGraph:
In jedem Java3d-Programm gibt es ein javax.media.j3d.Canvas3D (bei allen Klassen muss man aufpassen, das D von 3d groß zu schreiben). Dieses Canvas3D besitzt einen javax.media.j3d.View. Dieser gehört zu einem javax.media.j3d.VirtualUniverse. Damit man nicht in jedem Programm ein VirtualUniverse machen muss, gibt es die Klasse com.sun.j3d.utils.universe.SimpleUniverse. Wenn man dieses benutzt, muss man nicht mehr machen, als ein neues SimpleUniverse zu instanzieren, dieses erhält im Konstruktor ein Canvas3D, der View wird automatisch hinzugefügt. Ein SimpleUniverse kann allerdings nur ein View (also sozusagen eine Kamera) im Geschehen haben, in den Java XTools gibt es eine Klasse MultiUniverse, mit der auch mehrere Views möglich sind, dazu komme ich später nochmal zurück.
Der SceneGraph ist dann das, was sämtliche Objekte im VirtualUniverse enthält. Ein VirtualUniverse hat mehrere javax.media.j3d.Locales, an die javax.media.j3d.BranchGroups gehängt werden können.
BranchGroup ist von javax.media.j3d.Node abgeleitet, d.h. es kann in der parent-child-Beziehung eines SceneGraphs/einer Locale hinzugefügt werden. Jedes Node kann nur ein Parent-Node haben; außerdem ist BranchGroup aus javax.media.j3d.Group abgeleitet, Group ist ein Node, welches child-Nodes haben kann, BranchGroup ist eine Standard-Implementierung von Group, BranchGroup hat keine speziellen Eigenschaften. BranchGroups haben die Methode detach, mit der sie (und alle Kindknoten) äußerst komfortabel entfernt werden können.
Genug damit fürs erste. :D Kapiert? :wink:

Capabilities:
Ein wichtiges Konzept in Java3d sind die Capabilities. Bevor ein SceneGraph live, also auf dem Bildschirm, ist können Capabilities gesetzt werden, die später bestimmte Veränderungen zulassen.
Sie können über die Methode SceneGraphObject(Node ist aus dieser Klasse abgeleitet)#setCapability bzw clearCapability gesetzt werden. |-Verknüpfungen funktionieren nicht, jedes Capability-Bit muss einzeln gesetzt werden.
Wenn bestimmte Capabilities nicht gesetzt sind, kann Java3d Optimierungen vornehmen (z.B. mehrere Groups zu einer zusammenfassen).

Das erste Programm:
Damit kann man jetzt das erste Programm schreiben (es ist ein ähnlich wie das HelloJava3Da-Programm)(Ich merke gerade, hoon hat damals übrigens ein ziemlich ähnliches Beispielprogramm geschrieben):
Code:
import javax.swing.*;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.universe.*;  //SimpleUniverse
import com.sun.j3d.utils.geometry.ColorCube;  //Ein vorgefertigtes Test-SceneGraphObject, das hier benutzt werden wird.

public class First3DProgram extends JFrame implements ActionListener  //JFrame um Vermischung von Swing <-> Canvas3D (AWT) zu zeigen
{
  public static final long serialVersionUID = 121121112l;  //Für Java1.5-Unterstützung
  //Konstruktor
  public First3DProgram()
  {
    super ("Ein ColorCube");
    setSize (500, 500);
    setLocationRelativeTo (null);  //zentrieren
    setDefaultCloseOperation (DO_NOTHING_ON_CLOSE);  //Schließen soll im Menu geschehen
    JPopupMenu.setDefaultLightWeightPopupEnabled (false);  //Damit das Menu funktioniert, lassts mal zum Test weg
    setCloseMenuBar (this);
    //Jetzt kommt der 3D-Teil
    Canvas3D c3d = new Canvas3D (SimpleUniverse.getPreferredConfiguration());  //So am besten
    SimpleUniverse simpleU = new SimpleUniverse (c3d);  //Das VirtualUniverse, hier wird auch schon der View hinzugefügt
    BranchGroup bg = new BranchGroup();  //Haupt-BranchGroup
    bg.addChild (new ColorCube (0.4f/*Größe*/));  //ColorCube wird hinzugefügt
    bg.compile();  //Optimiert das Rendern
    simpleU.addBranchGraph (bg);  //Fügt den SceneGraph hinzu
    simpleU.getViewingPlatform().setNominalViewingTransform();  //Versetzt die Kamera so, dass man gleich etwas sehen kann
    //So einfach war das :)
    add (c3d);  //Vor 1.5: getContentPane().add
    setVisible (true);
  }
  //Beenden-Menu
  private void setCloseMenuBar (JFrame f)
  {
    JMenuBar jmb = new JMenuBar();
    JMenu jm = new JMenu ("Datei");
    jmb.add (jm);
    JMenuItem close = new JMenuItem ("Beenden");
    jm.add (close);
    close.addActionListener (this);
    f.setJMenuBar (jmb);
  }
  public void actionPerformed (ActionEvent evt)
  {
    System.exit (0);
  }
  //Startmethode
  public static void main (String[]args)
  {
    new First3DProgram();  //An "Insider": Ich werde nicht auf die Klasse MainFrame eingehen.
  }
}

Na gut, sehr interessant ist das Programm noch nicht, aber wenn man den Würfel dann dreht, sieht das schon ganz gut aus.
Ein kleiner Vorgeschmack:
Fügt mal vor der compile-Methode
Code:
     OrbitBehavior orbit = new OrbitBehavior(c3d, OrbitBehavior.REVERSE_ALL);  //OrbitBehavior liegt in dem Paket com.sun.j3d.utils.behaviors.vp
      orbit.setSchedulingBounds (new BoundingSphere ());
      simpleU.getViewingPlatform().setViewPlatformBehavior (orbit);
ein, dann könnt ihr den Würfel mit der Maus drehen.

Ich werde jetzt die nächsten zwei Wochen weg sein, aber dann mache ich natürlich weiter.

In der Hoffnung, das Java3D-Forum damit etwas anzuregen

Illuvatar
 

Illuvatar

Top Contributor
Na ja, mach doch heute noch bissle was :wink: :

3. TransformGroups
Wenn Bewegung oder einfach nur eine Anordnung der SceneGraphObjects ins Spiel kommen soll, sind javax.media.j3d.TransformGroups das wichtigste. Sie werden im SceneGraph zwischen eine BranchGroup und Leaves(=Nodes, die keine Childnodes haben können) / Groups platziert. Eine TransformGroup hat ein javax.media.j3d.Transform3D, das bestimmte Eigenschaften wie Translation / Verschiebung im 3-dimensionalen Raum und Rotation / Drehung hat, das mit setTransform gesetzt werden kann. Transform3Ds können zudem über die Methode Transform3D#mul (Transform3D) zusammengefasst werden. Es bietet sich allerdings an, z.B., sowohl für X-, als auch für Y- als auch für Z-Drehung als auch für Verschiebung eigene TransformGroups zu machen. Das ist übersichtlicher, und wenn kein ALLOW_TRANSFORM_READ bzw. ALLOW_TRANSFORM_WRITE Capability gesetzt ist, werden die Transform3Ds von der compile()-Methode in eine TransformGroup geschrieben.
Übrigens: bei der Drehung ist Math.PI eine halbe Drehung.
Dann können wir ja den Code etwas ändern:
Code:
   //Jetzt kommt der 3D-Teil
    Canvas3D c3d = new Canvas3D (SimpleUniverse.getPreferredConfiguration());  //So am besten
    SimpleUniverse simpleU = new SimpleUniverse (c3d);  //Das VirtualUniverse, hier wird auch schon der View hinzugefügt
    BranchGroup scene = new BranchGroup();  //Haupt-BranchGroup, SceneGraph
    TransformGroup rotX = new TransformGroup();
    TransformGroup rotY = new TransformGroup();
    TransformGroup trans = new TransformGroup();
    Transform3D t3d_rotx = new Transform3D();
    t3d_rotx.rotX (Math.PI / 4);  //Achtel-Drehung
    rotX.setTransform (t3d_rotx);
    Transform3D t3d_roty = new Transform3D();  //Nur X- und Y-Achse
    t3d_roty.rotY (Math.PI / 4);  //Achtel-Drehung
    rotY.setTransform (t3d_roty);
    scene.addChild (rotX);  //Erstellung des parent-child-Konstruktes
    rotX.addChild (rotY);
    Transform3D t3d_trans = new Transform3D();
    t3d_trans.setTranslation (new Vector3f (0, 0.3f, 0));  //javax.vecmath.Vector3f, Zahlen in "Meter" (Haupteinheit in Java3d)
    //Wie man sieht, geht die Y-Achse von unten nach oben
    trans.setTransform (t3d_trans);
    rotY.addChild (trans);
    trans.addChild (new ColorCube (0.4f/*Größe*/));  //ColorCube wird hinzugefügt
    scene.compile();  //Optimiert das Rendern
    simpleU.addBranchGraph (scene);  //Fügt den SceneGraph hinzu
    simpleU.getViewingPlatform().setNominalViewingTransform();  //Versetzt die Kamera so, dass man gleich etwas sehen kann
    //Nicht mehr ganz so simpel, aber auch nicht schwer, oder? :)

Transform3D hat noch viel mehr Methoden, die kann man aber in der API nachlesen. Interessant ist vor allem noch Transform3D#lookAt (Point3d, Point3d, Vector3d). Wobei mir auffällt: Point3d is richtig, in den javax.vecmath-Klassen ist das d kleingeschrieben.

Behaviors:
Durch Behaviors wird dem Programmierer die Möglichkeit gegeben, die virtuelle Welt zu verändern. Sun rät dazu, dies nie außerhalb von Behaviors zu tun. Dies kann, nach meiner Erfahrung, zu Exceptions irgendwo im J3D-Thread führen, durch die das ganze Programm crasht, oder massiv Performance kosten. Ein Behavior funktioniert so:
Behavior ist auch aus javax.media.j3d.Node abgeleitet, d.h. man kann ihn wie jedes beliebige andere Objektin den Scenegraph hängen. Um genau zu sein muss man das sogar, damit der Behavior arbeitet, die Bedingungen werden später nochmal zusammengefasst. Behavior hat zwei abstrakte Methoden, die überschrieben werden wollen. Die erste ist initialize(). Diese Methode wird einmal aufgerufen, sobald 1. der Behavior "live", also in den SceneGraph eingehängt wird und 2. die ViewPlatform, also die Kamera, innerhalb der SchedulingBounds des Behaviors ist (setSchedulingBounds, nicht setBounds, häufiger Fehler!). Hier können Initialisierungen vorgenommen werden. Außerdem wird eine WakeupCondition festgelegt, die besagt, wann der Behavior das nächste Mal aufgerufen werden soll. Im Normalfall wird man hier die 14 Subklassen von WakeupCriterion benötigen, die anderen WakeupConditions dienen dazu, WakeupCriteria zu verknüpfen. Die Criteria beinhalten z.B. Zeit in Millisekunden, abgelaufene Frames (Zeichnungen des Canvas3D), Kollisionen oder AWTEvents. Genauer kann man das hier nachlesen. Wenn nun also die WakeupCondition eintritt (und die beiden obigen Punkte erfüllt sind), wird die processStimulus-Methode von J3D-Thread aufgerufen. Es empfiehlt sich also nicht, hier lange Pausen einzubauen, die Methode muss schnell zurückkehren. Am Ende muss wieder eine WakeupCondition gesetzt werden.

Es gibt allerdings auch bereits viele vorgefertigte Behavior-Klassen. Diese teilen sich in 3 Hauptgruppen auf:

Billboard:

Rotiert eine TransformGroup anhand einer Achse oder eines Punktes, so dass bei dem Hauptview immer die selbe Seite zu sehen ist. Btw. für Fortgeschrittene: Es gibt auch die Klasse OrientedShape3D, die einen Shape3D darstellt, der eben dieses Verhalten hat.

LOD (Level of detail):

Verändern die Detailstufe einer TransformGroup auf Grund beliebiger Parameter. Im Moment ist die einzige Subklasse DistanceLOD, die die Veränderung auf Grund der Enfernung vornimmt.

Interpolatoren:

Interpolators verändern in der Zeit, die von einem javax.media.j3d.Alpha (da kommt noch was) vorgegeben wird, eine TransformGroup, zum Beispiel in Ort, Drehung oder Farbe.
Am besten kann ich das mit einem Beispiel erklären: Ein sich drehender ColorCube:
Code:
import javax.swing.*;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.universe.*;  //SimpleUniverse
import com.sun.j3d.utils.geometry.ColorCube;  //Ein vorgefertigtes Test-SceneGraphObject, das hier benutzt werden wird.

public class My3DProgram extends JFrame implements ActionListener  //JFrame um Vermischung von Swing <-> Canvas3D (AWT) zu zeigen
{
  public static final long serialVersionUID = 121121112l;  //Für Java1.5-Unterstützung
  //Konstruktor
  public My3DProgram()
  {
    super ("Ein ColorCube");
    setSize (500, 500);
    setLocationRelativeTo (null);  //zentrieren
    setDefaultCloseOperation (DO_NOTHING_ON_CLOSE);  //Schließen soll im Menu geschehen
    JPopupMenu.setDefaultLightWeightPopupEnabled (false);  //Damit das Menu funktioniert, lassts mal zum Test weg
    setCloseMenuBar (this);
     //Jetzt kommt der 3D-Teil
    Canvas3D c3d = new Canvas3D (SimpleUniverse.getPreferredConfiguration());  //So am besten
    SimpleUniverse simpleU = new SimpleUniverse (c3d);  //Das VirtualUniverse, hier wird auch schon der View hinzugefügt
    BranchGroup scene = createSceneGraph();
    simpleU.addBranchGraph (scene);  //Fügt den SceneGraph hinzu
    simpleU.getViewingPlatform().setNominalViewingTransform();  //Versetzt die Kamera so, dass man gleich etwas sehen kann
    //Nicht mehr ganz so simpel, aber auch nicht schwer, oder? :)
    add (c3d);  //Vor 1.5: getContentPane().add
    setVisible (true);
  }
  public BranchGroup createSceneGraph() {  //Methode aus Java3D-Examples von Sun
    BranchGroup objRoot = new BranchGroup();
    TransformGroup objSpin = new TransformGroup();
    objSpin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    objRoot.addChild(objSpin);
    objSpin.addChild(new ColorCube(0.1));
    Alpha rotationAlpha = new Alpha(-1, 4000); //Unendlich oft drehen, einmal in 4000 ms
    RotationInterpolator rotator =
       new RotationInterpolator(rotationAlpha, objSpin);
    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100);  //Unbedingt benötigt: Die BoundingSphere
    rotator.setSchedulingBounds(bounds);
    objSpin.addChild(rotator);
    objRoot.compile ();
    return objRoot;
  }
  //Beenden-Menu
  private void setCloseMenuBar (JFrame f)
  {
    JMenuBar jmb = new JMenuBar();
    JMenu jm = new JMenu ("Datei");
    jmb.add (jm);
    JMenuItem close = new JMenuItem ("Beenden");
    jm.add (close);
    close.addActionListener (this);
    f.setJMenuBar (jmb);
  }
  public void actionPerformed (ActionEvent evt)
  {
    System.exit (0);
  }
  //Startmethode
  public static void main (String[]args)
  {
    new My3DProgram();
  }
}
Das wichtigste an Interpolatoren ist eigentlich das Alpha-Objekt. Es macht eigentlich nicht mehr, als anhand der Zeit einen Wert von 0 bis 1 darzustellen, den der Interpolator dann umsetzt. Alpha bietet vier Konstruktoren. Dieser beinhaltet alle möglichen Parameter:
Alpha(int loopCount, int mode, long triggerTime, long phaseDelayDuration, long increasingAlphaDuration, long increasingAlphaRampDuration, long alphaAtOneDuration, long decreasingAlphaDuration, long decreasingAlphaRampDuration, long alphaAtZeroDuration)
In den anderen werden für die fehlenden Parameter Standardwerte eingesetzt. loopCount ist die Anzahl, wie oft das Objekt ausgeführt werden soll. mode kann festelegen, ob der Wert nur abnehmen, nur zunehmen oder beides abwechselnd soll. Dafür gibt es die Konstanten INCREASING_ENABLE und DECREASING_ENABLE, die geORed werden können ( | Operator). triggerTime und phaseDelayDuration ergeben zusammen die Zeit, die vor dem Ausführen gewartet wreden soll. IncreasingAlphaDuration ist die Zeit, die das Objekt von 0 bis 1 braucht und alphaAtOneDuration ist die Zeit, die es vor dem Runterzählen wartet. increasingAlphaRampDuration ist etwas trickreich, dieser Wert gibt die Zeit an, in der das Alpha-Objekt am anfang langsam beschleunigt um am Ende ebenso abbremst. Für die decreasing-Werte gilt das selbe, nur andersherum.

4. 2d-Graphik
Es ist auch möhlich, über/unter die 3D-Graphik mit javax.media.j3d.J3DGraphics2D zu zeichnen, welche aus java.awt.Graphics2d abgeleitet sind. [edit]Man bekommt sie über Canvas3d#getGraphics2D()[/edit] Dies muss in den Methoden preRender() oder postRender() aus Canvas3D geschehen, deshalb wird es nötig, eine eigene Klasse aus Canvas3D abzuleiten. Nach dem Zeichnen sollte die Methode J3DGraphics2D#flush(true) aufgerufen werden.
Siehe auch hier.

Genug für heute.
 

Illuvatar

Top Contributor
Es geht weiter... :meld:

5. javax.media.j3d.Shape3D
Shape3D ist aus Leaf abgeleitet. Sämtliche sichtbaren Vordergrund-Objekte der Szene sind Shape3Ds (übrigens auch ein ColorCube). Ein Shape3D hat sowohl einen Verweis auf eine javax.media.j3d.Geometry, die sozusagen das "Drahtgittermodell" darstellt, als auch auf eine javax.media.j3d.Appearance (Vorsicht beim Schreiben!), die das äußere Erscheinungsbild darstellt, aber nicht vorhanden sein muss.

Appearance
Eine Appearance hat folgende Merkmale:
Java3dTutorial von Sun hat gesagt.:
· PointAttributes
· LineAttributes
· PolygonAttributes
· ColoringAttributes
· TransparencyAttributes
· RenderingAttributes
· Material
· TextureAttributes
· Texture
· TexCoordGeneration
wobei im Moment nur die oberen 6 Punkte wichtig sind. Diese 6 Klassen befinden sich alle im Paket javax.media.j3d und können über entsprechende Methoden zu einer Appearance hinzugefügt werden (Appearance#addLineAttributes, Appearance#addPolygonAttributes usw), die Appearance wird entweder über den Konstruktor oder über die Methode setAppearance zum Shape3D hinzugefügt.
Die Attribute-Klassen im Einzelnen (nur die einzelnen Variablen der Klassen werden beschrieben, wie die Methoden zur Veränderung heißen, kann in der API nachgelesen werden, normalerweise sind es einfache setter-Methoden):
PointAttributes
float pointSize: Die Größe der Punkte, funktioniert nicht unter DirectX
boolean state: Zeigt an, ob Antialiasing auf die Punkte angewandt werden soll. Nur wichtig bei Punktgrößen > 1.0f
LineAttributes
float pointSize: Dicke der Linien, funktioniert nicht unter DirectX
boolean state: Zeigt an, ob Antialiasing auf die Linien angewandt werden soll.
int linePattern: PATTERN_SOLID (standard), PATTERN_DASH, PATTERN_DOT, oder PATTERN_DASH_DOT, Beschreibt, wie die Pixel einer Linie gezeichnet werden sollen
PolygonAttributes
int cullFace: "cull" bedeutet "nicht rendern". Kann auf eine der folgenden Konstanten gesetzt werden: CULL_FRONT, CULL_BACK (standard), oder CULL_NONE
int polygonMode: folgende Konstanten stehen zur Auswahl: POLYGON_POINT (nur Punkte werden angezeigt), POLYGON_LINE (Punkte und Linien werden angezeigt), oder POLYGON_FILL (standard, Punkte, Linien und Flächen werden angezeigt)
float polygonOffset: Das Shape3D wird um so viel auf der z-Achse des VirtualUniverse verschoben
boolean backFaceNormalFlip: Wenn CULL_BACK nicht aktiv ist, werden die "normals" der Rückseite umgekehrt (mehr dazu später)
ColoringAttributes
Color3f color: Die Farbe
int shadeModel: SHADE_GOURAUD, SHADE_FLAT, FASTEST oder NICEST
TransparencyAttributes
float tVal: 0.0 ist total undurchsichtig, 1.0 total transparent
int tMode: BLENDED, SCREEN_DOOR, FASTEST, NICEST, oder NONE

Geometry-Hilfsklassen
Um ganz einfach Szeneninhalt zu erstellen, gibt es vier "Geometric Utility Classes" im Paket com.sun.j3d.utils.geometry. Sie können wie ein Shape3D, dass bereits eine Geometry hat, verwendet werden. Es sind die Klassen Box (Quader), Cone (Kegel), Cylinder (Zylinder) und Sphere (Kugel).
Ein Beispiel zur Verdeutlichung:
Code:
import javax.swing.*;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.universe.*;  //SimpleUniverse
import com.sun.j3d.utils.geometry.*;  //Die Geometry-Utility-Klassen
import static java.awt.Color.*;  //Vor 1.5 import java.awt.Color;

public class Jojo extends JFrame implements ActionListener
{
  public static final long serialVersionUID = 121121112l;  //Für Java1.5-Unterstützung
  //Konstruktor
  public Jojo()
  {
    super ("Ein Jojo");
    setSize (500, 500);
    setLocationRelativeTo (null);  //zentrieren
    setDefaultCloseOperation (DO_NOTHING_ON_CLOSE);  //Schließen soll im Menu geschehen
    JPopupMenu.setDefaultLightWeightPopupEnabled (false);  //Damit das Menu funktioniert
    setCloseMenuBar (this);
     //Jetzt kommt der 3D-Teil
    Canvas3D c3d = new Canvas3D (SimpleUniverse.getPreferredConfiguration());  //So am besten
    SimpleUniverse simpleU = new SimpleUniverse (c3d);  //Das VirtualUniverse
    BranchGroup scene = createSceneGraph(); //In eigene Methode auslagern
    simpleU.addBranchGraph (scene);  //Fügt den SceneGraph hinzu
    simpleU.getViewingPlatform().setNominalViewingTransform();  //Versetzt die Kamera so, dass man gleich etwas sehen kann
    //Bewegt die Kamera etwas weg
    TransformGroup camTG = simpleU.getViewingPlatform().getViewPlatformTransform();  //TransformGroup steht für Kamera
    Transform3D t3d = new Transform3D();
    t3d.setTranslation (new Vector3f (0, 0, 7));  //neue Veränderung
    Transform3D t3d2 = new Transform3D();
    camTG.getTransform (t3d2);  //alte Veränderung
    t3d.mul (t3d2);  //beide Veränderungen zusammen
    camTG.setTransform (t3d);
    //Antialiasing aktivieren
    c3d.getView().setSceneAntialiasingEnable (true);
    //3D-Teil Ende. Soweit verstanden?
    add (c3d);  //Vor 1.5: getContentPane().add
    setVisible (true);
  }
  public BranchGroup createSceneGraph() {
    BranchGroup objRoot = new BranchGroup();
    TransformGroup objSpin = new TransformGroup();
    objSpin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    objRoot.addChild(objSpin);
    Alpha rotationAlpha = new Alpha(-1, 8000); //Das gesamte unendlich oft drehen, einmal in 8000 ms
    RotationInterpolator rotator =
       new RotationInterpolator(rotationAlpha, objSpin);
    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100);
    rotator.setSchedulingBounds(bounds);
    objSpin.addChild(rotator);
    //Hier wirds neu
    //linke Hälfte
    TransformGroup leftCone = getCone (new Color3f (RED/*vor 1.5: Color.RED*/), true);
    objSpin.addChild (leftCone);
    //rechte Hälfte
    TransformGroup rightCone = getCone (new Color3f (BLUE/*vor 1.5: Color.BLUE*/), false);
    objSpin.addChild (rightCone);  //Cones stecken übrigens ineinander
    objRoot.compile ();
    return objRoot;
  }
  private TransformGroup getCone (Color3f col, boolean leftSide)
  {
    Cone cone = new Cone (1/*radius*/, 3/*height*/); //default wäre: height: 2.0, radius: 1.0
    Appearance coneApp = new Appearance();
    coneApp.setColoringAttributes (new ColoringAttributes (col, ColoringAttributes.NICEST));
    coneApp.setPolygonAttributes (new PolygonAttributes (PolygonAttributes.POLYGON_FILL/*Testet auch mal _LINE und _POINT*/, PolygonAttributes.CULL_BACK, 0));
    coneApp.setTransparencyAttributes (new TransparencyAttributes (TransparencyAttributes.NICEST, 0.3f/*Hier könnt ihr auch mal rumspielen*/));
    //Wenn ich bei den TransparencyAttributes zuwenig nehme, gibt es Darstellungsfehler
    cone.setAppearance (coneApp);
    Transform3D trans = new Transform3D();
    trans.rotZ (Math.PI / (leftSide ? -2 : 2));
    TransformGroup TG = new TransformGroup (trans);
    TransformGroup move = new TransformGroup();
    PositionPathInterpolator pi = new PositionPathInterpolator
(new Alpha (-1, 3000), move, new Transform3D(), new float[]{0, 0.5f, 1}, new Point3f[]{new Point3f (), new Point3f (leftSide ? 2 : -2, 0, 0), new Point3f ()});
 //Vorgegebener Behavior, einfach API schauen, im Paket javax.media.j3d
    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100);
    pi.setSchedulingBounds(bounds);
    move.addChild (pi);
    move.setCapability (TransformGroup.ALLOW_TRANSFORM_WRITE);
    move.addChild (cone);
    //Der jetzt folgende Teil wird nächstes mal erklärt, es ist eine drei-D-Linie, die sich zwar mitbewegt, aber so lang ist, dass man es nicht merkt :)
    if (leftSide){  //eine reicht
      LineArray la = new LineArray (2, LineArray.COORDINATES | LineArray.COLOR_3);
      la.setCoordinate (0, new Point3f (-20, 0, 0));
      la.setCoordinate (1, new Point3f ());
      la.setColor (0, new Color3f (WHITE/*bzw. Color.WHITE*/));
      la.setColor (1, new Color3f (WHITE/*bzw. Color.WHITE*/));
      move.addChild (new Shape3D (la));
    }
    TG.addChild (move);
    return TG;
  }
  //Beenden-Menu
  private void setCloseMenuBar (JFrame f)
  {
    JMenuBar jmb = new JMenuBar();
    JMenu jm = new JMenu ("Datei");
    jmb.add (jm);
    JMenuItem close = new JMenuItem ("Beenden");
    jm.add (close);
    close.addActionListener (this);
    f.setJMenuBar (jmb);
  }
  public void actionPerformed (ActionEvent evt)
  {
    System.exit (0);
  }
  //Startmethode
  public static void main (String[]args)
  {
    new Jojo();
  }
}

So, das war erstmal lang genug. :D
 

Oxygenic

Bekanntes Mitglied
Ein paar Review-Kommentare (nur so beim Überfliegen aufgefallen):

Zu den Capabilities wäre anzumerken, dass die nicht nur irgend ein Gag sind, die den User grundlos dazu zwingen, diese zu setzen. Vielmehr führen die Optimierungen, die Java3D auf Basis der nicht gesetzten Capabilities macht, zu spürbaren Geschwindigkeitsvorteilen. Auch empfehle ich einen Blick auf setCapabilityIsFreqent().

Ob jemand die Behaviors so ohne ausführliche Erklärung versteht wage ich zu bezweifeln.

Die TransformGroup-Methode mul() heißt übrigens nicht deswegen mul(tipliziere), weil damit eine Addition ausgeführt wird. Über die Empfehlung, für X-, Y-, und Z-Rotationen je eine eigene TransformGroup einzurichten kann man trefflich streiten. Der Sinn dahinter ist mir nicht klar, auf alle Fälle kostet es Speicher und Compilezeit, denn die J3D-internen Optimierungen fassen sie dann eh wieder zusammen.

PointAttributes/LineAttributes: dass diese nur bei der Darstellung von Punktwolken / Drahtgittermodellen Sinn machen, sollte vielleicht erwähnt werden.

Primitives als Geometry-Hilfsklassen unter der Überschrift Shape3D zu erwähnen ist IMHO ziemlich verwirrend. Sie sind nämlich in keinster Weise mit den Shape3Ds verwandt und auch an ihre Geometriedaten kommt man nicht so ohne weiteres - schon gar nicht mit den Methoden die von Shape3D her bekannt sind.
 

Illuvatar

Top Contributor
Oxygenic hat gesagt.:
Zu den Capabilities wäre anzumerken, dass die nicht nur irgend ein Gag sind, die den User grundlos dazu zwingen, diese zu setzen. Vielmehr führen die Optimierungen, die Java3D auf Basis der nicht gesetzten Capabilities macht, zu spürbaren Geschwindigkeitsvorteilen. Auch empfehle ich einen Blick auf setCapabilityIsFreqent().
Hab ich doch geschrieben
Illuvatar hat gesagt.:
Wenn bestimmte Capabilities nicht gesetzt sind, kann Java3d Optimierungen vornehmen (z.B. mehrere Groups zu einer zusammenfassen).

Oxygenic hat gesagt.:
Ob jemand die Behaviors so ohne ausführliche Erklärung versteht wage ich zu bezweifeln.
Ich, beim erneuten Durchlesen, auch, werd ich noch mal überarbeiten :)

Oxygenic hat gesagt.:
Die TransformGroup-Methode mul() heißt übrigens nicht deswegen mul(tipliziere), weil damit eine Addition ausgeführt wird. Über die Empfehlung, für X-, Y-, und Z-Rotationen je eine eigene TransformGroup einzurichten kann man trefflich streiten. Der Sinn dahinter ist mir nicht klar, auf alle Fälle kostet es Speicher und Compilezeit, denn die J3D-internen Optimierungen fassen sie dann eh wieder zusammen.
Ich hatte gar nicht bewusst an multiplizieren gedacht, addieren fand ich einfach ein passendes Wort dafür. Habs jetzt aber überarbeitet und schreibe jetzt zusammenfassen.
Das mit den Rotationen finde ich übersichtlicher und einfacher, weil die Achsen ja mitrotiert werden, und da sie zusammengefasst werden, hält sich der benötigte Speicher ja wohl auch in Grenzen.

Oxygenic hat gesagt.:
PointAttributes/LineAttributes: dass diese nur bei der Darstellung von Punktwolken / Drahtgittermodellen Sinn machen, sollte vielleicht erwähnt werden.
Dafür hast du ja jetzt gesorgt :) . Ich hab mich wegen meiner DirectX-Version noch nicht näher damit befasst.

Oxygenic hat gesagt.:
Primitives als Geometry-Hilfsklassen unter der Überschrift Shape3D zu erwähnen ist IMHO ziemlich verwirrend. Sie sind nämlich in keinster Weise mit den Shape3Ds verwandt und auch an ihre Geometriedaten kommt man nicht so ohne weiteres - schon gar nicht mit den Methoden die von Shape3D her bekannt sind.
Mir ist keine bessere Überschrift als Shape3D eigefallen, im Englischen hätte ich Easier Content Creation genommen, noch mal nachdenken. Außerdem hatte ich am Anfang noch vor, noch in diesem Teil mit den GeometryArray-Klassen anzufangen, und es somit ein bisschen zu entwirren, aber es war mir dann doch zu viel auf einmal.

Edit: PS: Falls noch jemand Kritik oder Verbesserungsvorschläge hat, darf er/sie gerne posten.
 
D

doop

Gast
Was ist eigentlich mit dem Tutorial - ist es schon bei Teil zwei gestorben?
 
V

Vorbote der Apokalypse

Gast
Danke fürs Forum ich habe sehr lange nach einem Tutorial für java3D gesucht hab aber nichts gefunden.
Ich werd öfter mal hier hingucken
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
Ruvok Java3D Tutorial gesucht Spiele- und Multimedia-Programmierung 5
A Java3D tutorial? Spiele- und Multimedia-Programmierung 3
N Java3d in Eclipse einbinden Spiele- und Multimedia-Programmierung 4
Neumi5694 Java3D Viewer Beschriftung Spiele- und Multimedia-Programmierung 1
C Java3D Transformieren von obj. Datein Spiele- und Multimedia-Programmierung 0
M Cylinder anhand eines Vektors ausrichten (Java3d) Spiele- und Multimedia-Programmierung 0
U Hilfe bei Implementierung eines PointSounds in Java3D Spiele- und Multimedia-Programmierung 1
R Java3d ViewingPlatform erst Verschieben und dann RotationsInterpolator Spiele- und Multimedia-Programmierung 0
D Java3D - Blickfeld Spiele- und Multimedia-Programmierung 1
P Java3D Box Dimensionen und Positionierung Spiele- und Multimedia-Programmierung 1
E Java3D Objekt skalieren per JSlider/JButton Spiele- und Multimedia-Programmierung 10
S Java3D: Primitives zu einem Objekt kombinieren Spiele- und Multimedia-Programmierung 7
J Java3D - Textur laden geht nicht Spiele- und Multimedia-Programmierung 9
J Java3D - Farben vermischen sich Spiele- und Multimedia-Programmierung 7
T Java3D Rendering Problem Spiele- und Multimedia-Programmierung 7
S Java3D oder JMonkey? Spiele- und Multimedia-Programmierung 17
H Java3D - Textur aufs innere einer Sphere mappen Spiele- und Multimedia-Programmierung 9
C java 3d ohne Java3d Spiele- und Multimedia-Programmierung 28
Maxim6394 [Java3D] Probleme bei Kollision Spiele- und Multimedia-Programmierung 7
Maxim6394 [Java3D] lookAt Mausposition Spiele- und Multimedia-Programmierung 17
Maxim6394 [Java3D] Probleme mit KeyFrame Animationen Spiele- und Multimedia-Programmierung 9
K Java3D als Applet ohne Installation von Java3d Spiele- und Multimedia-Programmierung 6
D Java3D Installation: package javax.media.j3d not found Spiele- und Multimedia-Programmierung 5
C Java3D Texture Mapping Spiele- und Multimedia-Programmierung 2
W Java3D: Kanten die hinter einem Objekt liegen werden gezeigt Spiele- und Multimedia-Programmierung 2
W Java3D: Farbe von Objekten stimmt nicht mit übergebenem RGB-Wert überein Spiele- und Multimedia-Programmierung 9
M Eigene Renderengine ohne Java3D,etc. Spiele- und Multimedia-Programmierung 19
C Java3D Sound spielt nur einen Sound ab. Spiele- und Multimedia-Programmierung 8
A JAVA3D TransformGroup <--> Group Problem Spiele- und Multimedia-Programmierung 3
M [Java3D] Animation von mehreren Objekten Spiele- und Multimedia-Programmierung 7
W Java3D: Eckkoordinaten einer Box herausfinden Spiele- und Multimedia-Programmierung 18
T Java3D: Objekte platzieren und entfernen? Spiele- und Multimedia-Programmierung 7
T Java3D: Nur die Kanten des Würfels rendern? Spiele- und Multimedia-Programmierung 4
W Java3D setBounds(BoundingBox) Spiele- und Multimedia-Programmierung 6
T [gelöst] Java3D: Unerwünschte Rotation um die 3.Achse vermeiden? Spiele- und Multimedia-Programmierung 3
Bastie JAVA3D - WRL Transform Spiele- und Multimedia-Programmierung 9
G Eclipse Problem mit Java3d Spiele- und Multimedia-Programmierung 3
T Java3D - Lichtquelle einbauen Spiele- und Multimedia-Programmierung 7
jemandzehage java3d parallel und perspective view Spiele- und Multimedia-Programmierung 5
H Cinema 4D in Java3D importieren Spiele- und Multimedia-Programmierung 2
1 [Java3D] komplexes Projekt? Spiele- und Multimedia-Programmierung 10
P .obj-Datei in Java3D laden: ParsingErrorException Spiele- und Multimedia-Programmierung 7
C Java3D Lichtquelle beim Beobachter Spiele- und Multimedia-Programmierung 2
C Java3D Interaktion während Animation Spiele- und Multimedia-Programmierung 3
aze Java3D: Flächen teilen Spiele- und Multimedia-Programmierung 15
P Java3D Textur verzerrt Spiele- und Multimedia-Programmierung 3
aze Java3D: Gegenstände aufeinander zubewegen ohne Kollision Spiele- und Multimedia-Programmierung 4
D [JAVA3D] Es werden 2 Fenster erzeugt und auf dem falschen gezeichnet Spiele- und Multimedia-Programmierung 3
aze Java3D: leere Räume füllen Spiele- und Multimedia-Programmierung 2
aze Java3d:Helligkeit von Shape3D ändern Spiele- und Multimedia-Programmierung 2
S Einschätzung zu Java3D-Einstieg Spiele- und Multimedia-Programmierung 3
F Programm mit Java3D unter Linux laufen lassen Spiele- und Multimedia-Programmierung 3
I Vergleich von Java3D und OpenGL Spiele- und Multimedia-Programmierung 17
W Waterslide mit Java3D Spiele- und Multimedia-Programmierung 11
M Java3D Picking - falsche Objekte werden gepickt Spiele- und Multimedia-Programmierung 3
M [Java3D] Rotieren der Scene NICHT des POV Spiele- und Multimedia-Programmierung 4
F Jogl oder Java3D ? Spiele- und Multimedia-Programmierung 20
K Java3D Abfängerfrage Spiele- und Multimedia-Programmierung 3
aze Java3D:Farbige Flächen verschwinden lassen(Transparenz- oder Colorinterpolator?)) Spiele- und Multimedia-Programmierung 5
C Java3D PositionInterpolator Spiele- und Multimedia-Programmierung 3
G [Java3D] Probleme bei Animation Spiele- und Multimedia-Programmierung 4
E [JAVA3D] Kamerasteuerung Spiele- und Multimedia-Programmierung 3
E [JAVA3D] Schattenstrich durch die Szene Spiele- und Multimedia-Programmierung 4
M Grundsätzliche Java3D Fragen Spiele- und Multimedia-Programmierung 2
C Java3D SceneGraohPath Spiele- und Multimedia-Programmierung 2
C Java3D Rotation um einen Punkt (y-achse) Spiele- und Multimedia-Programmierung 2
G Java3D plattformunabhängig bundeln Spiele- und Multimedia-Programmierung 3
TheKing Java3D-Shooter View Spiele- und Multimedia-Programmierung 2
R Java3D Kollisionserkennung und Schwerkraft Spiele- und Multimedia-Programmierung 17
M Java3D Objekte entfernen und hinzufügen Spiele- und Multimedia-Programmierung 10
J Java3d Schnelle Geschosse Spiele- und Multimedia-Programmierung 12
D Kann ich mit Java3D 2D Daten als 3D surfaceplot plotten? Spiele- und Multimedia-Programmierung 5
J Java3d setTextureTransform verändert J3DGraphics2D Spiele- und Multimedia-Programmierung 4
J Hilfe: Rotation X und Y Achse (Java3d) Spiele- und Multimedia-Programmierung 12
K Java3D: LineStripArray Spiele- und Multimedia-Programmierung 2
P Java3D - Zylinder genau wie Vektor ausrichten Spiele- und Multimedia-Programmierung 5
Developer_X Java3D Mensch Ärgere Dich nicht. Spiele- und Multimedia-Programmierung 10
C JAVA3D Rotation um einen bestimmten Punkt Spiele- und Multimedia-Programmierung 20
Developer_X Java3D-Ungeeignet für 3D Spiele wegen Heap Space=? Spiele- und Multimedia-Programmierung 23
Developer_X Java3D Canvas post Renderer und? Spiele- und Multimedia-Programmierung 5
A Java3D Sichtweite Spiele- und Multimedia-Programmierung 2
"Er" Kamera rotation in Java3D Spiele- und Multimedia-Programmierung 2
A Java3D: Behavior scheduling bounds Spiele- und Multimedia-Programmierung 3
Developer_X THE BALL (needs Java3D) Spiele- und Multimedia-Programmierung 34
Developer_X Java3D Game_(die erste) Spiele- und Multimedia-Programmierung 2
Developer_X Java3D und while schleifen Spiele- und Multimedia-Programmierung 4
Developer_X Collisionserkennung in Java3D Spiele- und Multimedia-Programmierung 3
Developer_X Java3D Node -> Obj Data Spiele- und Multimedia-Programmierung 2
Developer_X Figuren werden nicht angezeigt (Java3D) Spiele- und Multimedia-Programmierung 5
S PDFRenderer und Java3D Spiele- und Multimedia-Programmierung 2
Developer_X Java3D- der Mausklick auf Nodes Spiele- und Multimedia-Programmierung 3
Developer_X Java3D Point Sound Spiele- und Multimedia-Programmierung 71
Developer_X Lines in Java3D Spiele- und Multimedia-Programmierung 4
V Java3D: HUD erstellen Spiele- und Multimedia-Programmierung 2
V Java3D: scheinende Sonne Spiele- und Multimedia-Programmierung 4
V Java3D: Ringe für Saturn erstellen Spiele- und Multimedia-Programmierung 8
V Java3D: automatisches Bewegen der Kamera Spiele- und Multimedia-Programmierung 19
V Java3D: mehrere ViewingPlaforms in Sonnensystem Spiele- und Multimedia-Programmierung 8
Developer_X Thread in Java3D Spiele- und Multimedia-Programmierung 8
B Java3D .obj dateien Spiele- und Multimedia-Programmierung 2

Ähnliche Java Themen

Neue Themen


Oben