import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;

import javax.media.j3d.AmbientLight;
import javax.media.j3d.Background;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.TriangleArray;
import javax.swing.JFrame;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3d;

import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.universe.ViewingPlatform;

public class SSEE extends JFrame {

	private static final long serialVersionUID = 1L;
	
	private SimpleUniverse su;
	private BranchGroup sceneBG;
	private BoundingSphere bounds;

	public SSEE() {
		super("Demo");

		GraphicsConfiguration config = SimpleUniverse
				.getPreferredConfiguration();
		Canvas3D canvas3D = new Canvas3D(config);
		canvas3D.setFocusable(true);
		canvas3D.requestFocus();

		su = new SimpleUniverse(canvas3D);
		sceneBG = new BranchGroup();
		bounds = new BoundingSphere(new Point3d(0, 0, 0), 100);
		ViewingPlatform vp = su.getViewingPlatform();

		// -------------------
		// Create scene
		
		lightScene(); 
		addBackground();
		sceneBG.addChild(createContent());
		sceneBG.compile();
		
		// -------------------
		// Set user's position
		
		TransformGroup steerTG = vp.getViewPlatformTransform();

		Transform3D t3d = new Transform3D();
		steerTG.getTransform(t3d);
		t3d.lookAt(new Point3d(0, 5, 20), new Point3d(0, 0, 0), new Vector3d(0, 1, 0));
		t3d.invert();

		steerTG.setTransform(t3d);
		
		// -------------------
		// Rotation and zoom
		
		OrbitBehavior orbit = new OrbitBehavior(canvas3D, OrbitBehavior.REVERSE_ALL);
		orbit.setSchedulingBounds(bounds);
		vp.setViewPlatformBehavior(orbit);

		su.addBranchGraph(sceneBG);

		add(canvas3D, BorderLayout.CENTER);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(800, 600);
		setResizable(false);
		setVisible(true);
	}

	private BranchGroup createContent() {
		BranchGroup objRoot = new BranchGroup();
		Shape3D shape = new Shape3D();

		Point3f e = new Point3f(1.0f, 0.0f, 0.0f); // east
		Point3f s = new Point3f(0.0f, 0.0f, 1.0f); // south
		Point3f w = new Point3f(-1.0f, 0.0f, 0.0f); // west
		Point3f n = new Point3f(0.0f, 0.0f, -1.0f); // north
		Point3f t = new Point3f(0.0f, 0.721f, 0.0f); // top

		TriangleArray pyramidGeometry = new TriangleArray(18,
				TriangleArray.COORDINATES);
		pyramidGeometry.setCoordinate(0, e);
		pyramidGeometry.setCoordinate(1, t);
		pyramidGeometry.setCoordinate(2, s);

		pyramidGeometry.setCoordinate(3, s);
		pyramidGeometry.setCoordinate(4, t);
		pyramidGeometry.setCoordinate(5, w);

		pyramidGeometry.setCoordinate(6, w);
		pyramidGeometry.setCoordinate(7, t);
		pyramidGeometry.setCoordinate(8, n);

		pyramidGeometry.setCoordinate(9, n);
		pyramidGeometry.setCoordinate(10, t);
		pyramidGeometry.setCoordinate(11, e);

		pyramidGeometry.setCoordinate(12, e);
		pyramidGeometry.setCoordinate(13, s);
		pyramidGeometry.setCoordinate(14, w);

		pyramidGeometry.setCoordinate(15, w);
		pyramidGeometry.setCoordinate(16, n);
		pyramidGeometry.setCoordinate(17, e);
		
		
		shape.setGeometry(pyramidGeometry);
		objRoot.addChild(shape);

		return objRoot;
	}

	private void lightScene() {
		Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
		AmbientLight ambientLightNode = new AmbientLight(white);
		ambientLightNode.setInfluencingBounds(bounds);
		sceneBG.addChild(ambientLightNode);
	}

	private void addBackground() {
		Background back = new Background();
		back.setApplicationBounds(bounds);
		back.setColor(0.1f, 0.6f, 0.9f);
		sceneBG.addChild(back);
	}

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

}
