Mega Code Archive

 
Categories / Java / 3D Graphics
 

Human Animation

/*  * %Z%%M% %I% %E% %U%  *   * ************************************************************** "Copyright (c)  * 2001 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.applet.Applet; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GraphicsConfiguration; import java.awt.GridLayout; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.text.NumberFormat; import javax.media.j3d.AmbientLight; import javax.media.j3d.Appearance; import javax.media.j3d.Background; import javax.media.j3d.BoundingSphere; import javax.media.j3d.BranchGroup; import javax.media.j3d.Canvas3D; import javax.media.j3d.DirectionalLight; import javax.media.j3d.ImageComponent; import javax.media.j3d.ImageComponent2D; import javax.media.j3d.Material; import javax.media.j3d.Screen3D; import javax.media.j3d.Transform3D; import javax.media.j3d.TransformGroup; import javax.media.j3d.View; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.JTabbedPane; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.vecmath.AxisAngle4f; import javax.vecmath.Color3f; import javax.vecmath.Point3d; import javax.vecmath.Point3f; import javax.vecmath.Vector3f; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGEncodeParam; import com.sun.image.codec.jpeg.JPEGImageEncoder; import com.sun.j3d.utils.applet.MainFrame; import com.sun.j3d.utils.behaviors.mouse.MouseRotate; import com.sun.j3d.utils.geometry.Cylinder; import com.sun.j3d.utils.geometry.Sphere; import com.sun.j3d.utils.universe.SimpleUniverse; public class Human1 extends Applet implements ChangeListener, ActionListener {   SimpleUniverse u;   boolean isApplication;   Canvas3D canvas;   OffScreenCanvas3D offScreenCanvas;   View view;   // These names correspond to the H-Anim names   TransformGroup Human_body;   TransformGroup Human_r_shoulder;   TransformGroup Human_r_elbow;   TransformGroup Human_l_shoulder;   TransformGroup Human_l_elbow;   TransformGroup Human_skullbase;   // these set up the transformations   int rShoulderRot = 0;   AxisAngle4f rShoulderAA = new AxisAngle4f(0.0f, 0.0f, -1.0f, 0.0f);   JSlider rShoulderSlider;   JLabel rShoulderSliderLabel;   int rElbowRot = 0;   AxisAngle4f rElbowAA = new AxisAngle4f(0.0f, 0.0f, -1.0f, 0.0f);   JSlider rElbowSlider;   JLabel rElbowSliderLabel;   int lShoulderRot = 0;   AxisAngle4f lShoulderAA = new AxisAngle4f(0.0f, 0.0f, 1.0f, 0.0f);   JSlider lShoulderSlider;   JLabel lShoulderSliderLabel;   int lElbowRot = 0;   AxisAngle4f lElbowAA = new AxisAngle4f(0.0f, 0.0f, 1.0f, 0.0f);   JSlider lElbowSlider;   JLabel lElbowSliderLabel;   String snapImageString = "Snap Image";   String outFileBase = "human";   int outFileSeq = 0;   float offScreenScale = 1.5f;   // GUI elements   JTabbedPane tabbedPane;   // Temporaries that are reused   Transform3D tmpTrans = new Transform3D();   Vector3f tmpVector = new Vector3f();   AxisAngle4f tmpAxisAngle = new AxisAngle4f();   // These will be created, attached the scene graph and then the variable   // will be reused to initialize other sections of the scene graph.   Cylinder tmpCyl;   Sphere tmpSphere;   TransformGroup tmpTG;   // colors for use in the cones   Color3f red = new Color3f(1.0f, 0.0f, 0.0f);   Color3f black = new Color3f(0.0f, 0.0f, 0.0f);   Color3f white = new Color3f(1.0f, 1.0f, 1.0f);   // geometric constant   Point3f origin = new Point3f();   Vector3f yAxis = new Vector3f(0.0f, 1.0f, 0.0f);   // NumberFormat to print out floats with only two digits   NumberFormat nf;   // Returns the TransformGroup we will be editing to change the tranform   // on the cone   void createHuman() {     Human_body = new TransformGroup();     // center the body     tmpVector.set(0.0f, -1.5f, 0.0f);     tmpTrans.set(tmpVector);     Human_body.setTransform(tmpTrans);     // Set up an appearance to make the body with red ambient,     // black emmissive, red diffuse and white specular coloring     Material material = new Material(red, black, red, white, 64);     Appearance appearance = new Appearance();     appearance.setMaterial(material);     // offset and place the cylinder for the body     tmpTG = new TransformGroup();     // offset the shape     tmpVector.set(0.0f, 1.5f, 0.0f);     tmpTrans.set(tmpVector);     tmpTG.setTransform(tmpTrans);     tmpCyl = new Cylinder(0.75f, 3.0f, appearance);     tmpTG.addChild(tmpCyl);     // add the shape to the body     Human_body.addChild(tmpTG);     // create the r_shoulder TransformGroup     Human_r_shoulder = new TransformGroup();     Human_r_shoulder.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);     Human_r_shoulder.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);     // translate from the waist     tmpVector.set(-0.95f, 2.9f, -0.2f);     tmpTrans.set(tmpVector);     Human_r_shoulder.setTransform(tmpTrans);     // place the sphere for the r_shoulder     tmpSphere = new Sphere(0.22f, appearance);     Human_r_shoulder.addChild(tmpSphere);     // offset and place the cylinder for the r_shoulder     tmpTG = new TransformGroup();     // offset the shape     tmpVector.set(0.0f, -0.5f, 0.0f);     tmpTrans.set(tmpVector);     tmpTG.setTransform(tmpTrans);     tmpCyl = new Cylinder(0.2f, 1.0f, appearance);     tmpTG.addChild(tmpCyl);     // add the shape to the r_shoulder     Human_r_shoulder.addChild(tmpTG);     // add the shoulder to the body group     Human_body.addChild(Human_r_shoulder);     // create the r_elbow TransformGroup     Human_r_elbow = new TransformGroup();     Human_r_elbow.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);     Human_r_elbow.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);     tmpVector.set(0.0f, -1.054f, 0.0f);     tmpTrans.set(tmpVector);     Human_r_elbow.setTransform(tmpTrans);     // place the sphere for the r_elbow     tmpSphere = new Sphere(0.22f, appearance);     Human_r_elbow.addChild(tmpSphere);     // offset and place the cylinder for the r_shoulder     tmpTG = new TransformGroup();     // offset the shape     tmpVector.set(0.0f, -0.5f, 0.0f);     tmpTrans.set(tmpVector);     tmpTG.setTransform(tmpTrans);     tmpCyl = new Cylinder(0.2f, 1.0f, appearance);     tmpTG.addChild(tmpCyl);     // add the shape to the r_shoulder     Human_r_elbow.addChild(tmpTG);     // add the elbow to the shoulder group     Human_r_shoulder.addChild(Human_r_elbow);     // create the l_shoulder TransformGroup     Human_l_shoulder = new TransformGroup();     Human_l_shoulder.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);     Human_l_shoulder.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);     tmpVector.set(0.95f, 2.9f, -0.2f);     tmpTrans.set(tmpVector);     Human_l_shoulder.setTransform(tmpTrans);     // place the sphere for the l_shoulder     tmpSphere = new Sphere(0.22f, appearance);     Human_l_shoulder.addChild(tmpSphere);     // offset and place the cylinder for the l_shoulder     tmpTG = new TransformGroup();     // offset the shape     tmpVector.set(0.0f, -0.5f, 0.0f);     tmpTrans.set(tmpVector);     tmpTG.setTransform(tmpTrans);     tmpCyl = new Cylinder(0.2f, 1.0f, appearance);     tmpTG.addChild(tmpCyl);     // add the shape to the l_shoulder     Human_l_shoulder.addChild(tmpTG);     // add the shoulder to the body group     Human_body.addChild(Human_l_shoulder);     // create the r_elbow TransformGroup     Human_l_elbow = new TransformGroup();     Human_l_elbow.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);     Human_l_elbow.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);     tmpVector.set(0.0f, -1.054f, 0.0f);     tmpTrans.set(tmpVector);     Human_l_elbow.setTransform(tmpTrans);     // place the sphere for the l_elbow     tmpSphere = new Sphere(0.22f, appearance);     Human_l_elbow.addChild(tmpSphere);     // offset and place the cylinder for the l_elbow     tmpTG = new TransformGroup();     // offset the shape     tmpVector.set(0.0f, -0.5f, 0.0f);     tmpTrans.set(tmpVector);     tmpTG.setTransform(tmpTrans);     tmpCyl = new Cylinder(0.2f, 1.0f, appearance);     tmpTG.addChild(tmpCyl);     // add the shape to the l_elbow     Human_l_elbow.addChild(tmpTG);     // add the shoulder to the body group     Human_l_shoulder.addChild(Human_l_elbow);     // create the skullbase TransformGroup     Human_skullbase = new TransformGroup();     tmpVector.set(0.0f, 3.632f, 0.0f);     tmpTrans.set(tmpVector);     Human_skullbase.setTransform(tmpTrans);     // offset and place the sphere for the skull     tmpSphere = new Sphere(0.5f, appearance);     // add the shape to the l_shoulder     Human_skullbase.addChild(tmpSphere);     // add the shoulder to the body group     Human_body.addChild(Human_skullbase);   }   public void actionPerformed(ActionEvent e) {     String action = e.getActionCommand();     Object source = e.getSource();     if (action == snapImageString) {       Point loc = canvas.getLocationOnScreen();       offScreenCanvas.setOffScreenLocation(loc);       Dimension dim = canvas.getSize();       dim.width *= offScreenScale;       dim.height *= offScreenScale;       nf.setMinimumIntegerDigits(3);       offScreenCanvas.snapImageFile(           outFileBase + nf.format(outFileSeq++), dim.width,           dim.height);       nf.setMinimumIntegerDigits(0);     }   }   public void setRShoulderRot(int rotation) {     rShoulderRot = rotation;     rShoulderAA.angle = (float) Math.toRadians(rShoulderRot);     Human_r_shoulder.getTransform(tmpTrans);     tmpTrans.setRotation(rShoulderAA);     Human_r_shoulder.setTransform(tmpTrans);   }   public void setRElbowRot(int rotation) {     float angle = (float) Math.toRadians(rotation);     rElbowRot = rotation;     rElbowAA.angle = (float) Math.toRadians(rElbowRot);     Human_r_elbow.getTransform(tmpTrans);     tmpTrans.setRotation(rElbowAA);     Human_r_elbow.setTransform(tmpTrans);   }   public void setLShoulderRot(int rotation) {     lShoulderRot = rotation;     lShoulderAA.angle = (float) Math.toRadians(lShoulderRot);     Human_l_shoulder.getTransform(tmpTrans);     tmpTrans.setRotation(lShoulderAA);     Human_l_shoulder.setTransform(tmpTrans);   }   public void setLElbowRot(int rotation) {     float angle = (float) Math.toRadians(rotation);     lElbowRot = rotation;     lElbowAA.angle = (float) Math.toRadians(lElbowRot);     Human_l_elbow.getTransform(tmpTrans);     tmpTrans.setRotation(lElbowAA);     Human_l_elbow.setTransform(tmpTrans);   }   public void stateChanged(ChangeEvent e) {     JSlider source = (JSlider) e.getSource();     int value = source.getValue();     if (source == rShoulderSlider) {       setRShoulderRot(value);       rShoulderSliderLabel.setText(Integer.toString(value));     } else if (source == rElbowSlider) {       setRElbowRot(value);       rElbowSliderLabel.setText(Integer.toString(value));     } else if (source == lShoulderSlider) {       setLShoulderRot(value);       lShoulderSliderLabel.setText(Integer.toString(value));     } else if (source == lElbowSlider) {       setLElbowRot(value);       lElbowSliderLabel.setText(Integer.toString(value));     }   }   BranchGroup createSceneGraph() {     // Create the root of the branch graph     BranchGroup objRoot = new BranchGroup();     // Create a TransformGroup to scale the scene down by 3.5x     // TODO: move view platform instead of scene using orbit behavior     TransformGroup objScale = new TransformGroup();     Transform3D scaleTrans = new Transform3D();     scaleTrans.set(1 / 3.5f); // scale down by 3.5x     objScale.setTransform(scaleTrans);     objRoot.addChild(objScale);     // Create a TransformGroup and initialize it to the     // identity. Enable the TRANSFORM_WRITE capability so that     // the mouse behaviors code can modify it at runtime. Add it to the     // root of the subgraph.     TransformGroup objTrans = new TransformGroup();     objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);     objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);     objScale.addChild(objTrans);     // Add the primitives to the scene     createHuman(); // the human     objTrans.addChild(Human_body);     BoundingSphere bounds = new BoundingSphere(new Point3d(), 100.0);     Background bg = new Background(new Color3f(1.0f, 1.0f, 1.0f));     bg.setApplicationBounds(bounds);     objTrans.addChild(bg);     // set up the mouse rotation behavior     MouseRotate mr = new MouseRotate();     mr.setTransformGroup(objTrans);     mr.setSchedulingBounds(bounds);     mr.setFactor(0.007);     objTrans.addChild(mr);     // Set up the ambient light     Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);     AmbientLight ambientLightNode = new AmbientLight(ambientColor);     ambientLightNode.setInfluencingBounds(bounds);     objRoot.addChild(ambientLightNode);     // Set up the directional lights     Color3f light1Color = new Color3f(1.0f, 1.0f, 1.0f);     Vector3f light1Direction = new Vector3f(0.0f, -0.2f, -1.0f);     DirectionalLight light1 = new DirectionalLight(light1Color,         light1Direction);     light1.setInfluencingBounds(bounds);     objRoot.addChild(light1);     return objRoot;   }   public Human1() {     this(false, 1.0f);   }   public Human1(boolean isApplication, float initOffScreenScale) {     this.isApplication = isApplication;     this.offScreenScale = initOffScreenScale;   }   public void init() {     // set up a NumFormat object to print out float with only 3 fraction     // digits     nf = NumberFormat.getInstance();     nf.setMaximumFractionDigits(3);     setLayout(new BorderLayout());     GraphicsConfiguration config = SimpleUniverse         .getPreferredConfiguration();     canvas = new Canvas3D(config);     add("Center", canvas);     u = new SimpleUniverse(canvas);     if (isApplication) {       offScreenCanvas = new OffScreenCanvas3D(config, true);       // set the size of the off-screen canvas based on a scale       // of the on-screen size       Screen3D sOn = canvas.getScreen3D();       Screen3D sOff = offScreenCanvas.getScreen3D();       Dimension dim = sOn.getSize();       dim.width *= offScreenScale;       dim.height *= offScreenScale;       sOff.setSize(dim);       sOff.setPhysicalScreenWidth(sOn.getPhysicalScreenWidth()           * offScreenScale);       sOff.setPhysicalScreenHeight(sOn.getPhysicalScreenHeight()           * offScreenScale);       // attach the offscreen canvas to the view       u.getViewer().getView().addCanvas3D(offScreenCanvas);     }     // Create a simple scene and attach it to the virtual universe     BranchGroup scene = createSceneGraph();     // This will move the ViewPlatform back a bit so the     // objects in the scene can be viewed.     u.getViewingPlatform().setNominalViewingTransform();     u.addBranchGraph(scene);     view = u.getViewer().getView();     add("East", guiPanel());   }   // create a panel with a tabbed pane holding each of the edit panels   JPanel guiPanel() {     JPanel panel = new JPanel();     panel.setLayout(new GridLayout(0, 1));     // Human_r_shoulder rotation     panel.add(new JLabel("Right Shoulder rotation"));     rShoulderSlider = new JSlider(JSlider.HORIZONTAL, 0, 180, rShoulderRot);     rShoulderSlider.addChangeListener(this);     rShoulderSliderLabel = new JLabel(Integer.toString(rShoulderRot));     panel.add(rShoulderSlider);     panel.add(rShoulderSliderLabel);     // Human_r_elbow rotation     panel.add(new JLabel("Right Elbow rotation"));     rElbowSlider = new JSlider(JSlider.HORIZONTAL, 0, 180, rElbowRot);     rElbowSlider.addChangeListener(this);     rElbowSliderLabel = new JLabel(Integer.toString(rElbowRot));     panel.add(rElbowSlider);     panel.add(rElbowSliderLabel);     // Human_l_shoulder rotation     panel.add(new JLabel("Left Shoulder rotation"));     lShoulderSlider = new JSlider(JSlider.HORIZONTAL, 0, 180, lShoulderRot);     lShoulderSlider.addChangeListener(this);     lShoulderSliderLabel = new JLabel(Integer.toString(lShoulderRot));     panel.add(lShoulderSlider);     panel.add(lShoulderSliderLabel);     // Human_l_elbow rotation     panel.add(new JLabel("Left Elbow rotation"));     lElbowSlider = new JSlider(JSlider.HORIZONTAL, 0, 180, lElbowRot);     lElbowSlider.addChangeListener(this);     lElbowSliderLabel = new JLabel(Integer.toString(lElbowRot));     panel.add(lElbowSlider);     panel.add(rElbowSliderLabel);     if (isApplication) {       JButton snapButton = new JButton(snapImageString);       snapButton.setActionCommand(snapImageString);       snapButton.addActionListener(this);       panel.add(snapButton);     }     return panel;   }   public void destroy() {     u.removeAllLocales();   }   // The following allows Human to be run as an application   // as well as an applet   //   public static void main(String[] args) {     float initOffScreenScale = 2.5f;     for (int i = 0; i < args.length; i++) {       if (args[i].equals("-s")) {         if (args.length >= (i + 1)) {           initOffScreenScale = Float.parseFloat(args[i + 1]);           i++;         }       }     }     new MainFrame(new Human1(true, initOffScreenScale), 950, 600);   } } class OffScreenCanvas3D extends Canvas3D {   OffScreenCanvas3D(GraphicsConfiguration graphicsConfiguration,       boolean offScreen) {     super(graphicsConfiguration, offScreen);   }   private BufferedImage doRender(int width, int height) {     BufferedImage bImage = new BufferedImage(width, height,         BufferedImage.TYPE_INT_RGB);     ImageComponent2D buffer = new ImageComponent2D(         ImageComponent.FORMAT_RGB, bImage);     //buffer.setYUp(true);     setOffScreenBuffer(buffer);     renderOffScreenBuffer();     waitForOffScreenRendering();     bImage = getOffScreenBuffer().getImage();     return bImage;   }   void snapImageFile(String filename, int width, int height) {     BufferedImage bImage = doRender(width, height);     /*      * JAI: RenderedImage fImage = JAI.create("format", bImage,      * DataBuffer.TYPE_BYTE); JAI.create("filestore", fImage, filename +      * ".tif", "tiff", null);      */     /* No JAI: */     try {       FileOutputStream fos = new FileOutputStream(filename + ".jpg");       BufferedOutputStream bos = new BufferedOutputStream(fos);       JPEGImageEncoder jie = JPEGCodec.createJPEGEncoder(bos);       JPEGEncodeParam param = jie.getDefaultJPEGEncodeParam(bImage);       param.setQuality(1.0f, true);       jie.setJPEGEncodeParam(param);       jie.encode(bImage);       bos.flush();       fos.close();     } catch (Exception e) {       System.out.println(e);     }   } }