import	java.awt.*;
import	javax.vecmath.*;
import	javax.media.j3d.*;

class AppearanceDemo extends Frame
{
	public static void main(String[] args)
	{
		new AppearanceDemo();
	}

	public AppearanceDemo()
	{
		setTitle("AppearanceDemo");		

		setLayout(new BorderLayout());
		Canvas3D c = new Canvas3D(null);
		add("Center", c);

		UniverseBuilder u = new UniverseBuilder(c);
		BranchGroup scene = createSceneGraph();
		u.addBranchGraph(scene);

		setSize(400,300);
		show();
	}

	public BranchGroup createSceneGraph()
	{
		BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);		
		Color3f lColor1 = new Color3f(0.8f, 0.8f, 0.8f);
		Vector3f lDir1  = new Vector3f(-0.2f, 0.0f, -1.0f);
		Color3f alColor = new Color3f(0.4f, 0.4f, 0.4f);
		AmbientLight aLgt = new AmbientLight(alColor);
		aLgt.setInfluencingBounds(bounds);
		DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
		lgt1.setInfluencingBounds(bounds);

		BranchGroup branchGroup = new BranchGroup();
		branchGroup.addChild(aLgt);	
		branchGroup.addChild(lgt1);

		Transform3D tr1 = new Transform3D();
		tr1.set(0.8,new Vector3d(-2.0,0.0,0.0));
		TransformGroup trGroup1 = new TransformGroup(tr1);

		Transform3D tr2 = new Transform3D();
		tr2.set(1.0,new Vector3d(0.7,0.0,0.0));
		TransformGroup trGroup2 = new TransformGroup(tr2);

		Transform3D tr3 = new Transform3D();
		tr3.set(0.8,new Vector3d(3.0,0.0,1.0));
		TransformGroup trGroup3 = new TransformGroup(tr3);

		Appearance appearance2 = new Appearance();
		Material material2 = new Material();
		material2.setDiffuseColor(new Color3f(0.0f,0.5f,1.0f));
		appearance2.setMaterial(material2);

		Appearance appearance3 = new Appearance();
		Material material3 = new Material();
		material3.setDiffuseColor(new Color3f(1.0f,0.0f,1.0f));
		appearance3.setMaterial(material3);
		TransparencyAttributes transparency3 = new TransparencyAttributes();
		transparency3.setTransparency(0.6f);
		transparency3.setTransparencyMode(TransparencyAttributes.BLENDED);
		appearance3.setTransparencyAttributes(transparency3);
		
		trGroup1.addChild(new ColorCube(new Appearance()).getShape());
		branchGroup.addChild(trGroup1);

		trGroup2.addChild(new ColorCube(appearance2).getShape());
		branchGroup.addChild(trGroup2);

		trGroup3.addChild(new ColorCube(appearance3).getShape());
		branchGroup.addChild(trGroup3);

		return branchGroup;
	}
}

class UniverseBuilder extends Object
{
	Locale			locale;

	UniverseBuilder(Canvas3D c)
	{
		Transform3D t = new Transform3D();
		Transform3D t2 = new Transform3D();
		t2.setEuler( new Vector3d(-35.0*(Math.PI/180.0),45.0*(Math.PI/180.0),0.0));
		t.set(4,new Vector3d(6.0,5.0,6.0));
		t.mul(t,t2);

		VirtualUniverse	universe = new VirtualUniverse();
		locale = new Locale(universe);

		PhysicalBody body = new PhysicalBody();
		PhysicalEnvironment environment = new PhysicalEnvironment();
		BranchGroup viewPlatformBranchGroup = new BranchGroup();
		TransformGroup viewPlatformTransformGroup = new TransformGroup(t);
		ViewPlatform viewPlatform = new ViewPlatform();

		View view = new View();
		view.addCanvas3D(c);
		view.setPhysicalBody(body);
		view.setPhysicalEnvironment(environment);
		view.attachViewPlatform(viewPlatform);
		
		viewPlatformTransformGroup.addChild(viewPlatform);
		viewPlatformBranchGroup.addChild(viewPlatformTransformGroup);
		locale.addBranchGraph(viewPlatformBranchGroup);
	}

	void addBranchGraph(BranchGroup bg)
	{
		locale.addBranchGraph(bg);
	}
}

class ColorCube extends Object
{
	static double verts[] = {
		// elso lap
		1.0, -1.0,  1.0,	1.0,  1.0,  1.0,
		-1.0,  1.0,  1.0,	-1.0, -1.0,  1.0,
		// hatso lap
		-1.0, -1.0, -1.0,	-1.0,  1.0, -1.0,
		1.0,  1.0, -1.0,	1.0, -1.0, -1.0,
		// jobb lap
		1.0, -1.0, -1.0,	1.0,  1.0, -1.0,
		1.0,  1.0,  1.0,	1.0, -1.0,  1.0,
		// bal lap
		-1.0, -1.0,  1.0,	-1.0,  1.0,  1.0,
		-1.0,  1.0, -1.0,	-1.0, -1.0, -1.0,
		// fedo lap
		1.0,  1.0,  1.0,	1.0,  1.0, -1.0,
		-1.0,  1.0, -1.0,	-1.0,  1.0,  1.0,
		// alaplap
		-1.0, -1.0,  1.0,	-1.0, -1.0, -1.0,
		1.0, -1.0, -1.0,	1.0, -1.0,  1.0
	};

	static float normals[] = {
		0.0f, 0.0f, 1.0f,
		0.0f, 0.0f, 1.0f,
		0.0f, 0.0f, 1.0f,
		0.0f, 0.0f, 1.0f,

		0.0f, 0.0f, -1.0f,
		0.0f, 0.0f, -1.0f,
		0.0f, 0.0f, -1.0f,
		0.0f, 0.0f, -1.0f,

		1.0f, 0.0f, 0.0f,
		1.0f, 0.0f, 0.0f,
		1.0f, 0.0f, 0.0f,
		1.0f, 0.0f, 0.0f,

		-1.0f, 0.0f, 0.0f,
		-1.0f, 0.0f, 0.0f,
		-1.0f, 0.0f, 0.0f,
		-1.0f, 0.0f, 0.0f,

		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		0.0f, 1.0f, 0.0f,

		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
		0.0f, -1.0f, 0.0f,
	};



	private Shape3D shape;

	public ColorCube(Appearance appearance)
	{
		QuadArray cube = new QuadArray(24, QuadArray.COORDINATES |QuadArray.NORMALS);

		cube.setCoordinates(0, verts);
		cube.setNormals(0,normals);

		shape = new Shape3D(cube, appearance);
	}

	public Shape3D getShape()
	{
		return shape;
	}
}

