/*
Supports Camera viewing. The Camera is never rotated - it has always the top faced at the 
y-axis, away from the ground.
example:
	protected void buildUniverse( )
	{
		SimpleUniverse universe = new SimpleUniverse(
			null,          // Hi-res coordinate for the origin - use default
			1,             // Number of transforms in MultiTransformGroup
			exampleCanvas, // Canvas3D into which to draw
			null );        // URL for user configuration file - use defaults
		ViewingPlatform viewingPlatform = universe.getViewingPlatform( );
		exampleViewTransform = viewingPlatform.getViewPlatformTransform( );
		Transform3D viewTransform = new Transform3D();
		Viewer myViewer = universe.getViewer();
		View myView = myViewer.getView();
		myView.setFieldOfView(Math.PI/6); //30 degrees
		Point3d eyePoint = new Point3d( 5.0, 5.0, -20.0 );
		Point3d centerPoint = new Point3d( 0.0, 0.0, 0.0 );
		Camera aCamera = new Camera(exampleViewTransform, eyePoint, centerPoint);

*/
import java.util.*;
import javax.media.j3d.*;
import javax.vecmath.*;

public class Camera
{	
	private Point3d center;
	private Point3d eye;	
	private TransformGroup myTransformGroup;

public Camera( TransformGroup aTransformGroup , Point3d aEye, Point3d aCenter) 
{
	myTransformGroup = aTransformGroup;
	center = aCenter;
	eye = aEye;
	Update();
}

public void SetPosition( Point3d aPoint)
{	
	eye = aPoint;
	Update();
}

public Point3d GetPosition()
{	
	return eye;
}

public void LookAt(Point3d aPoint)
{
	center = aPoint;
	Update();
}

public Point3d GetLookAt()
{	
	return center;
}

private void Update()
{
// Camera up direction is eyeToCenter vector rotated 90 degrees against y-axis ( not around y )
// Calculate up-vector:
// rot.axis = normal vector to plane defined by eyeToCenter vector and y axis.
// rotate eyeToCenter vector 90 degrees.

	Vector3d eyeToCenter = new Vector3d();
	eyeToCenter.sub(center,eye);
	Vector3d yAxis = new Vector3d(0,1,0);
	Vector3d rotAxis = new Vector3d();
	rotAxis.cross(yAxis, eyeToCenter);
	rotAxis.normalize();
	AxisAngle4d rotation = new AxisAngle4d(	rotAxis.x,
								rotAxis.y,
								rotAxis.z,
								Math.PI/2 );
	Transform3D upTrans = new Transform3D();
	upTrans.setRotation( rotation );
	Vector3d up = new Vector3d( 	-eyeToCenter.x,
						-eyeToCenter.y,
						-eyeToCenter.z );

	upTrans.transform( up );
	Transform3D lookAtTrans = new Transform3D();
	lookAtTrans.lookAt( eye, center, up);
	lookAtTrans.invert();
	myTransformGroup.setTransform(lookAtTrans);
}
} //end Camera