import javax.swing.*;
import java.awt.GraphicsEnvironment;
import java.awt.event.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.universe.*; //SimpleUniverse
import com.sun.j3d.utils.geometry.*;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.behaviors.mouse.MouseRotate;
import com.sun.j3d.utils.behaviors.mouse.MouseZoom;
import com.sun.j3d.utils.behaviors.vp.*;
import java.util.*;
import java.awt.Color;
public class KugelSimulation 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 KugelSimulation()
{
super ("Bla");
setSize (800, 600);
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
createScene (bg);
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);
bg.compile(); //Optimiert das Rendern
simpleU.addBranchGraph (bg); //Fügt den SceneGraph hinzu
Transform3D cam = new Transform3D();
cam.setTranslation (new Vector3f (0, 0, 60));
simpleU.getViewingPlatform().getViewPlatformTransform().setTransform(cam);
c3d.getView().setBackClipDistance(150);
add (c3d); //Vor 1.5: getContentPane().add
setVisible (true);
}
private Kugel[] spheres;
private int anzahl = 500;
private boolean mitte = true;
private int groesse = 100;
private void createScene (BranchGroup scene)
{
BoundingSphere bounds = new BoundingSphere(new Point3d(), Double.MAX_VALUE);
Appearance appKugel = new Appearance(); // Aussehen der Kugeln
appKugel.setMaterial(new Material(new Color3f(0.1f,0.1f,0.1f), new Color3f(0.1f,0.1f,0.1f), new Color3f(0.7f,0.7f,0.7f), new Color3f(1,1,1), 64));
spheres = new Kugel[anzahl];
for (int i = 0; i < anzahl; i++){
Kugel k = new Kugel();
spheres[i] = k;
Vector3f pos = new Vector3f();
pos.x = k.point.x;
pos.y = k.point.y;
pos.z = k.point.z;
k.direction.normalize();
k.direction.scale (0.25f); //hier indirekt geschwindigkeit bestimmen
Transform3D t3d1 = new Transform3D();
t3d1.setTranslation(pos);
TransformGroup transTG = new TransformGroup (t3d1);
scene.addChild (transTG);
TransformGroup move = new TransformGroup();
k.move = move;
move.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
transTG.addChild (move);
Sphere s = new Sphere (1, Primitive.GENERATE_NORMALS, 100, appKugel);
move.addChild (s);
}
Mover m = new Mover();
// Sonne (Mittelkugel):
Appearance appSun = new Appearance(); // Aussehen der Sonne
appSun.setTexture( new TextureLoader("sun.jpg", this).getTexture());
TransformGroup tgSun = new TransformGroup();
Sphere Sun = new Sphere(1, Primitive.GENERATE_TEXTURE_COORDS, 100, appSun );
tgSun.addChild(Sun);
TransformGroup all = new TransformGroup();
all.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
all.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
MouseRotate mouseRotate = new MouseRotate();
MouseZoom mouseZoom = new MouseZoom(all);
mouseRotate.setTransformGroup(all);
mouseRotate.setSchedulingBounds(bounds);
mouseZoom.setSchedulingBounds(bounds);
// Licht
PointLight sunlight = new PointLight();
sunlight.setInfluencingBounds(bounds);
PointLight camLight1 = new PointLight();
camLight1.setPosition(0, 0, 60);
camLight1.setInfluencingBounds(bounds);
PointLight camLight2 = new PointLight();
camLight2.setPosition(0, 0, -60);
camLight2.setInfluencingBounds(bounds);
scene.addChild(all);
all.addChild(mouseRotate);
all.addChild(mouseZoom);
all.addChild(m);
all.addChild(tgSun);
all.addChild(sunlight);
all.addChild(camLight1);
all.addChild(camLight2);
}
//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 KugelSimulation();
}
private class Kugel
{
public Kugel() {
double rnd;
rnd = (java.lang.Math.random() * 2 * groesse) - groesse;
point.x = (int) rnd;
rnd = (java.lang.Math.random() * 2 * groesse) - groesse;
point.y = (int) rnd;
rnd = (java.lang.Math.random() * 2 * groesse) - groesse;
point.z = (int) rnd;
/*if(i == 1) {
point.x = 1;
point.y = 0;
point.z = 0;
} else {
point.x = 7;
point.y = 0;
point.z = 0;
}*/
start.x = point.x;
start.y = point.y;
start.z = point.z;
if (mitte == false) {
rnd = (java.lang.Math.random() * groesse);
direction.x = (int) rnd;
rnd = (java.lang.Math.random() * groesse);
direction.y = (int) rnd;
rnd = (java.lang.Math.random() * groesse);
direction.z = (int) rnd;
} else {
direction.x = -point.x;
direction.y = -point.y;
direction.z = -point.z;
}
//if(i == 1)
//direction.x = 1;
}
public Point3f point = new Point3f();
public Vector3f direction = new Vector3f();
public TransformGroup move;
public Point3f start = new Point3f();
public boolean collided = false;
public boolean collide(float bx, float by, float bz) {
float ax = point.x;
float ay = point.y;
float az = point.z;
//System.out.println(Math.sqrt((ax + start.x - bx) * (ax + start.x - bx) + (ay + start.y - by) * (ay + start.y - by) + (az + start.z - bz) * (az + start.z - bz)));
if(Math.sqrt((ax + start.x - bx) * (ax + start.x - bx) + (ay + start.y - by) * (ay + start.y - by) + (az + start.z - bz) * (az + start.z - bz)) <= 2) {
collided = true;
return true;
} else {
return false;
}
}
}
private class Mover extends Behavior
{
public Mover ()
{
setSchedulingBounds (new BoundingSphere(new Point3d(), Double.MAX_VALUE));
}
private WakeupCondition wc = new WakeupOnElapsedTime(20);
public void initialize()
{
wakeupOn (wc);
}
public void processStimulus (Enumeration criteria)
{
for(int i = 0; i < spheres.length; i++){
if(spheres[i].collided == false) {
for(int j = 0; j < spheres.length; j++) {
if( i != j) {
spheres[i].collide(spheres[j].point.x + spheres[j].start.x, spheres[j].point.y + spheres[j].start.y, spheres[j].point.z + spheres[j].start.z);
}
}
spheres[i].collide(0, 0, 0);
if(spheres[i].collided == false) {
spheres[i].point.add (spheres[i].direction);
Transform3D t3d = new Transform3D();
t3d.setTranslation (new Vector3f(spheres[i].point));
spheres[i].move.setTransform (t3d);
}
}
}
wakeupOn (wc);
}
}
}