
import javax.media.j3d.*;
import javax.vecmath.*;

/**
 * Title: Tetraeder class
 * Description: This class contains a new 3d shape for drawing a tetraeder
 * Copyright: Copyright (c) 2001
 * Company: Uni Frankfurt
 * @author Martin Klossek
 * @version 1.0
 */

public class Tetraeder extends Shape3D {

	/**
	 * The constructor of the tetraeder class
	 *
	 * @param oAppearance The appearance node component which should be attached
	 * to this SceneGraphObject
	 */
        public Tetraeder(Appearance oAppearance) {

		/* create the geometry for the shape3d instancce */
	        TetraederGeometry geoTetraeder = new TetraederGeometry();

		/* add geometry and given appearance to tetraeder instancce */
		this.addGeometry(geoTetraeder);
		this.setAppearance(oAppearance);

        }

	/**
	 * Inner class for creating the geometry of the tetraeder shape3d
	 */
	class TetraederGeometry extends TriangleArray {

		private float[] m_afVerts = {
		        0.0f, 0.0f, 0.0f,
		        1.0f, 0.0f, 0.0f,
		        0.5f, 1.0f, -0.5f,

		        1.0f, 0.0f, 0.0f,
		        0.5f, 0.0f, -1.0f,
		        0.5f, 1.0f, -0.5f,

		        0.0f, 0.0f, 0.0f,
		        0.5f, 1.0f, -0.5f,
		        0.5f, 0.0f, -1.0f,

		        0.0f, 0.0f, 0.0f,
		        0.5f, 0.0f, -1.0f,
		        1.0f, 0.0f, 0.0f
		};

		private float[] m_afColors = {
			1.0f, 0.0f, 0.0f,
			1.0f, 0.0f, 0.0f,
			1.0f, 0.0f, 0.0f,

			1.0f, 1.0f, 0.0f,
			1.0f, 1.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, 0.0f, 1.0f,
			0.0f, 0.0f, 1.0f,
			0.0f, 0.0f, 1.0f
		};

		/* the two-dimensional texture coordinates */
		private TexCoord2f m_oTex1 = new TexCoord2f(0.0f, 0.0f);
		private TexCoord2f m_oTex2 = new TexCoord2f(1.0f, 0.0f);
		private TexCoord2f m_oTex3 = new TexCoord2f(0.5f, 0.85f);

		/* and the array with texture coordinates for each face */
		private TexCoord2f[] m_aoTextCoord = {
		        m_oTex1, m_oTex2, m_oTex3,
			m_oTex2, m_oTex3, m_oTex1,
			m_oTex3, m_oTex1, m_oTex2,
			m_oTex1, m_oTex2, m_oTex3,
		};

		/**
		 * The constructor of the inner geometry class
		 */
		public TetraederGeometry () {

			/* call the superclass with the parameters */
		        super ( 12, TriangleArray.COORDINATES |
				TriangleArray.NORMALS | TriangleArray.TEXTURE_COORDINATE_2 );

			/* set the coordinates */
			setCoordinates (0, m_afVerts);

			/* the texture coordinates */
			for (int i = 0; i < 12; i++) {
			        setTextureCoordinate(0, i, m_aoTextCoord[i]);
			}

		        /* calculate the normals of each tetraeder face with vector product */
			Vector3f v3Normal = new Vector3f();
			Vector3f v3Left = new Vector3f();
			Vector3f v3Right = new Vector3f();
			Point3f [] pts = new Point3f[3];
			for (int i = 0; i < 3; i++) pts[i] = new Point3f();

			/* do it for each face */
			for (int iFace = 0; iFace < 4; iFace++) {

				/* get coordinates for the face */
				this.getCoordinates(iFace*3, pts);

				/* calculate the normal vector as normal = v3Left x v3Right */
				v3Left.sub (pts[1], pts[0]);
				v3Right.sub (pts[2], pts[0]);
				v3Normal.cross(v3Left, v3Right);
				v3Normal.normalize();

				/* assign normal to each point of the face */
				for (int i = 0; i < 3; i++) {
				        this.setNormal ((iFace * 3 + i), v3Normal);
				}

			}

		}

	}

}