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();
}
}