/*
 *      @(#)GeometryByReferenceTest.java 1.12 02/10/21 13:41:27
 *
 * Copyright (c) 1996-2002 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistribution in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 *
 * Neither the name of Sun Microsystems, Inc. or the names of
 * contributors may be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * This software is provided "AS IS," without a warranty of any
 * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
 * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
 * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
 * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
 * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
 * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *
 * You acknowledge that Software is not designed,licensed or intended
 * for use in the design, construction, operation or maintenance of
 * any nuclear facility.
 */


import java.awt.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import javax.swing.*;

import com.sun.j3d.utils.behaviors.vp.*;




public class GeometryByReferenceTest
        extends JApplet
        implements GeometryUpdater {

        RenderingAttributes ra;
        ColoringAttributes ca;
        Material mat;
        Appearance app;


        Shape3D shape;
        TransparencyAttributes transp;
        int updateIndex = 0;
        int colorCount = 0, vertexCount = 0;
        int vertexIndex = 0, colorIndex = 0;

        GeometryArray tetraIndexed ;

        private static final float sqrt3 = (float) Math.sqrt(3.0);
        private static final float sqrt3_3 = sqrt3 / 3.0f;
        private static final float sqrt24_3 = (float) Math.sqrt(24.0) / 3.0f;

        private static final float ycenter = 0.5f * sqrt24_3;
        private static final float zcenter = -sqrt3_3;

        private static final Point3f p1 = new Point3f(-1.0f, -ycenter, -zcenter);
        private static final Point3f p2 = new Point3f(1.0f, -ycenter, -zcenter);
        private static final Point3f p3 = new Point3f(0.0f, -ycenter, -sqrt3 - zcenter);
        private static final Point3f p4 = new Point3f(0.0f, sqrt24_3 - ycenter, 0.0f);


        private static final Color3f c1 = new Color3f(0.6f, 0.0f, 0.0f);
        private static final Color3f c2 = new Color3f(0.0f, 0.6f, 0.0f);
        private static final Color3f c3 = new Color3f(0.0f, 0.6f, 0.6f);
        private static final Color3f c4 = new Color3f(0.6f, 0.6f, 0.0f);


        private static final float[] indexedFloatVerts =
                {
                        p1.x,
                        p1.y,
                        p1.z,
                        p2.x,
                        p2.y,
                        p2.z,
                        p3.x,
                        p3.y,
                        p3.z,
                        p4.x,
                        p4.y,
                        p4.z,
                        };
        private static final float[] indexedFloatClrs =
                {
                        c1.x,
                        c1.y,
                        c1.z,
                        c2.x,
                        c2.y,
                        c2.z,
                        c3.x,
                        c3.y,
                        c3.z,
                        c4.x,
                        c4.y,
                        c4.z,
                        };

        private static final Point3f[] indexedP3fVerts = { p1, p2, p3, p4 };


        private static final Color3f[] indexedC3fClrs = { c1, c2, c3, c4 };

        private static final int[] indices = { 0, 1, 3, 0, 3, 2, 1, 2, 3, 0, 2, 1 };

        private SimpleUniverse u;
	
	
        public Transform3D t3D= null ;
        public TransformGroup trans = null; 
	
	
        /**
         * Default Constructor
         */	
        public GeometryByReferenceTest() {
        }

	
        /**
         * Create the scene graph for the test... IndexedTriangle
         * @return BranchGroup
         */

        BranchGroup createSceneGraph() {
                BranchGroup objRoot = new BranchGroup();

                // Set up attributes to render lines
                app = new Appearance();

                transp = new TransparencyAttributes();
                transp.setTransparency(0.5f);
                transp.setCapability(TransparencyAttributes.ALLOW_MODE_WRITE);
                transp.setTransparencyMode(TransparencyAttributes.NONE);
                app.setTransparencyAttributes(transp);

                tetraIndexed = createGeometry( );

                shape = new Shape3D(tetraIndexed, app);
                shape.setCapability(Shape3D.ALLOW_GEOMETRY_WRITE);
                shape.setCapability(Shape3D.ALLOW_GEOMETRY_READ);

                t3D = new Transform3D();

                trans = new TransformGroup(t3D);
                trans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
                trans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

                objRoot.addChild(trans);
                trans.addChild(shape);

                BoundingSphere bounds =
                        new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);

                // Add the Null update Behavior  --- THis will cause the shape to updateData  every frame
                NullUpdateBehavior badBehavior = new NullUpdateBehavior(this);
                badBehavior.setSchedulingBounds(bounds);
                objRoot.addChild(badBehavior);

                // Set up the global lights
                Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
                Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
                Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);

                AmbientLight aLgt = new AmbientLight(alColor);
                aLgt.setInfluencingBounds(bounds);
                DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
                lgt1.setInfluencingBounds(bounds);
                objRoot.addChild(aLgt);
                objRoot.addChild(lgt1);

                // Let Java 3D perform optimizations on this scene graph.
                objRoot.compile();

                return objRoot;
        }
	
	
        /**
         *  Rotate  the object around the X and Y axis .. just to give it some
         *  motion.    Also apply default scale and translate to place it on the
         *  screen.
         */ 
	
        public void rotateShape ( float angle) {
                // move the object upwards
                t3D.set(new Vector3f(0.0f, 0.3f, 0.0f));

                // rotate the shape
                Transform3D temp = new Transform3D();
                temp.rotX(angle );
                t3D.mul(temp);
                temp.rotY(angle );
                t3D.mul(temp);

                // Shrink the object 
                t3D.setScale(0.6);
                trans.setTransform( t3D);

        }
	

        public void init() {
                Container contentPane = getContentPane();

                Canvas3D c = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
                contentPane.add("Center", c);

                BranchGroup scene = createSceneGraph();
                // SimpleUniverse is a Convenience Utility class
                u = new SimpleUniverse(c);

                // add mouse behaviors to the viewingPlatform
                ViewingPlatform viewingPlatform = u.getViewingPlatform();

                // This will move the ViewPlatform back a bit so the
                // objects in the scene can be viewed.
                viewingPlatform.setNominalViewingTransform();
                u.addBranchGraph(scene);

                // add Orbit behavior to the ViewingPlatform
                OrbitBehavior orbit = new OrbitBehavior(c, OrbitBehavior.REVERSE_ALL);

                BoundingSphere bounds =
                        new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
                orbit.setSchedulingBounds(bounds);
                viewingPlatform.setViewPlatformBehavior(orbit);
        }

        public void destroy() {
                u.cleanup();
        }


        public GeometryArray createGeometry() {
                GeometryArray tetra = null;

                tetra =
                        new IndexedTriangleArray(
                                4,
                                IndexedTriangleArray.COORDINATES
                                        | IndexedTriangleArray.COLOR_3
                                        | IndexedTriangleArray.BY_REFERENCE,
                                12);
                tetra.setCoordRefFloat(indexedFloatVerts);
                tetra.setColorRefFloat(indexedFloatClrs);
                ((IndexedTriangleArray) tetra).setCoordinateIndices(0, indices);
                ((IndexedTriangleArray) tetra).setColorIndices(0, indices);

                if (tetra != null)
                        tetra.setCapability(GeometryArray.ALLOW_REF_DATA_WRITE);
                return tetra;
        }



        /*
         * This is the updateData interface ... don't do anything for this test  
         */
        public void updateData(Geometry geometry) {

        }
	
	
        public static void main(String[] args) {
                Frame frame = new MainFrame(new GeometryByReferenceTest(), 800, 800);
        }

	
	

}
