Package syn3d.ui.xith3d

Source Code of syn3d.ui.xith3d.Frame3DXith3D$AutoRepaintFrame

/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info:  http://jsynoptic.sourceforge.net/index.html
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2004, by :
*     Corporate:
*         Astrium SAS
*     Individual:
*         Claude Cazenave
*
* $Id: Frame3DXith3D.java,v 1.16 2005/06/14 13:10:35 ogor Exp $
*
* Changes
* -------
* 9-Dec-2003 : Creation date (CC);
*
*/
package syn3d.ui.xith3d;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.HeadlessException;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.awt.event.WindowListener;
import java.util.ArrayList;

import javax.vecmath.Color3f;
import javax.vecmath.Matrix4f;
import javax.vecmath.Vector3f;

import syn3d.base.ActiveNode;
import syn3d.nodes.SceneNode;
import syn3d.nodes.xith3d.SceneNodeXith3D;
import syn3d.ui.Frame3DBase;
import syn3d.base.PluginManager;
import syn3d.base.java3d.Java3DPluginManager;

import com.xith3d.picking.PickRenderResult;
import com.xith3d.render.CanvasPeer;
import com.xith3d.render.RenderPeer;
import com.xith3d.scenegraph.AmbientLight;
import com.xith3d.scenegraph.Appearance;
import com.xith3d.scenegraph.Bounds;
import com.xith3d.scenegraph.BranchGroup;
import com.xith3d.scenegraph.Canvas3D;
import com.xith3d.scenegraph.DirectionalLight;
import com.xith3d.scenegraph.Locale;
import com.xith3d.scenegraph.Node;
import com.xith3d.scenegraph.PolygonAttributes;
import com.xith3d.scenegraph.Shape3D;
import com.xith3d.scenegraph.Transform3D;
import com.xith3d.scenegraph.TransformGroup;
import com.xith3d.scenegraph.View;
import com.xith3d.scenegraph.VirtualUniverse;
import com.xith3d.spatial.bounds.Sphere;
import com.xith3d.test.TestUtils;

/**
* Class description ...
*
* @author Claude CAZENAVE
*
*/
public class Frame3DXith3D extends Frame3DBase {

  private static boolean init=false;
  private static boolean useJogl=true;
 
  protected RenderPeer peer;
  protected CanvasPeer canvasPeer;
  protected Canvas3D canvas;
  protected View view;
  protected Transform3D sceneTransform = new Transform3D();
  protected Matrix4f sceneMatrix = new Matrix4f();
  protected Transform3D transform;
  protected Transform3D tempTransform;
  protected ArrayList lastPickSelection = new ArrayList();
  protected int lastMouseX = -1, lastMouseY = -1;
  protected SceneNodeXith3D scene;
 
  public SceneNode getScene() {
    return scene;
  }

  /**
     * @return Returns the view.
     */
    public View getView() {
        return view;
    }
  /**
   * @param owner
   * @param x
   * @param y
   * @param width
   * @param height
   */
  public Frame3DXith3D(SceneNodeXith3D scene, Object owner, String t, int x, int y, int width, int height, PluginManager pm) {
    super(owner, t, x, y, width, height, pm);
    this.scene = scene;
  }

  protected void internalMakePeer(Object owner) {
    if (!init) {
      try {
        peer = new com.xith3d.render.jogl.RenderPeerImpl();
        canvasPeer =
          peer.makeCanvas(owner, width, height, 16, false);
        useJogl = true;
      } catch (Throwable e) {
        peer = new com.xith3d.render.lwjgl.RenderPeerImpl();
        canvasPeer =
          peer.makeCanvas(owner, width, height, 16, false);
        useJogl = false;
      }
      init = true;
    } else {
      if (useJogl) {
        peer = new com.xith3d.render.jogl.RenderPeerImpl();
        canvasPeer =
          peer.makeCanvas(owner, width, height, 16, false);
      } else {
        peer = new com.xith3d.render.lwjgl.RenderPeerImpl();
        canvasPeer =
          peer.makeCanvas(owner, width, height, 16, false);
      }
    }
  }
 

  protected void createPeer(Object owner){
     
    transform=new Transform3D();
    tempTransform=new Transform3D();

    internalMakePeer(owner);
   
    peerWindow=canvasPeer.getWindow();
    if (peerWindow!=null) {
        WindowListener[] listeners = peerWindow.getWindowListeners();
        // Remove application exit listener
        for (int i=0; i<listeners.length; ++i) {
            peerWindow.removeWindowListener(listeners[i]);
        }
      peerWindow.dispose();
    }
   
    AutoRepaintFrame arf = new AutoRepaintFrame();
    arf.setBounds(x,y,width,height);
    arf.setLayout(new BorderLayout(0,0));

    peerComponent=canvasPeer.getComponent();
   
    if (peerComponent==null) {
        internalMakePeer(arf);
      peerComponent=canvasPeer.getComponent();
    } else arf.add(peerComponent, BorderLayout.CENTER);
   
    peerWindow = arf;
    peerWindow.show();
   
    if (canvasPeer instanceof com.xith3d.render.jogl.CanvasPeerImpl)
        ((com.xith3d.render.jogl.CanvasPeerImpl)canvasPeer).setWindow(peerWindow);
   
    // Add Listener to set the window invisible instead of exiting the application
    peerWindow.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                peerWindow.setVisible(false);
            }
    });
   
    if(peerWindow!=null){
        peerWindow.setLocation(x, y);
    }
    canvas=new Canvas3D();
    canvas.set3DPeer(canvasPeer);
    view = new View();
   
    view.addCanvas3D(canvas);

    if(peerComponent!=null){
      peerComponent.addMouseListener(this);
      peerComponent.addMouseMotionListener(this);
      peerComponent.addMouseWheelListener(this);
      peerComponent.addKeyListener(this);
    }
  }
 
  public void setPerspective(boolean p){
    super.setPerspective(p);
    if (perspective)
      view.setProjectionPolicy(View.PERSPECTIVE_PROJECTION);
    else
      view.setProjectionPolicy(View.PARALLEL_PROJECTION);
  }

 
  public void rotate2D(int newX, int newY) {
   
    int mode;
   
    if (scene!=null) mode = scene.getLightRotationMode();
    else mode = -1;
   
    // rotate only one light, view is fixed
    if (mode != -1) {
      float dx=(float)(newX-pos2DX)/wsize;
      float dy=(float)(newY-pos2DY)/wsize;
          drotX.rotX(dy * 2 * (float)Math.PI);
      drotY.rotY(dx * 2 * (float)Math.PI);

      Matrix4f transform = new Matrix4f(rot);
      transform.mul(drotX);
      transform.mul(drotY);
      Matrix4f tmp = new Matrix4f(rot);
      tmp.invert();
      transform.mul(tmp);

      DirectionalLight light = scene.getLights()[mode];
      Vector3f direction = light.getDirection();
      transform.transform(direction);
      light.setDirection(direction);
      scene.showLightVector(direction.x,direction.y,direction.z);
     
      // update pos, don't move view
          pos2DX = newX;
          pos2DY = newY;
          peerWindow.repaint();
          return;
    }

    // rotate all lights together with view
    if (scene!=null) {
     
      float dx=(float)(newX-pos2DX)/wsize;
      float dy=(float)(newY-pos2DY)/wsize;
          drotX.rotX(-dy * 2 * (float)Math.PI);
      drotY.rotY(-dx * 2 * (float)Math.PI);
     
      Matrix4f transform = new Matrix4f(rot);
      transform.mul(drotX);
      transform.mul(drotY);
      Matrix4f tmp = new Matrix4f(rot);
      tmp.invert();
      transform.mul(tmp);

      DirectionalLight[] lights = scene.getLights();
      for (int i=0; i<lights.length; ++i) {
        Vector3f direction = lights[i].getDirection();
        transform.transform(direction);
        lights[i].setDirection(direction);
      }
      // don't update pos for super implementation call

    }
   
    super.rotate2D(newX,newY);
   
  }
 
  public void applyTransform(){
    super.applyTransform();
   
    transform.set(rot);
    tempTransform.set(trans);
    transform.mul(tempTransform);
    tempTransform.set(zoom);
    transform.mul(tempTransform);
    view.setTransform(transform);
    peerWindow.repaint();
  }
   
  protected float getSceneSize() {
    boolean autocompute = scene.getBranchgroup().getBoundsAutoCompute();
    scene.getBranchgroup().setBoundsAutoCompute(true);
    scene.getBranchgroup().updateBounds(true);
    scene.getBranchgroup().setBoundsAutoCompute(autocompute);
    Bounds bounds = scene.getBranchgroup().getBounds();
    // Should be the case for xith3d
    if (bounds instanceof Sphere) {
      return ((Sphere)bounds).getRadius();
    }
    // else, include this bounds object in a bounding sphere and get radius
    return 0;
  }
 
  /*
//   TODO: use such a code to find intersection with the shape
      private PickRay createPickRay(Canvas3D canvas, int x, int y)
      {
        Point3d eye_pos = new Point3d();
        Point3d mouse_pos = new Point3d();

        canvas.getCenterEyeInImagePlate(eye_pos);
        canvas.getPixelLocationInImagePlate(x, y, mouse_pos);

        Transform3D motion = new Transform3D();
        canvas.getImagePlateToVworld(motion);
        motion.transform(eye_pos);
        motion.transform(mouse_pos);

        Vector3d direction = new Vector3d(mouse_pos);
        direction.sub(eye_pos);

        return new PickRay(eye_pos, direction);
      }
  */

  /**
     * Adds or removes a single pick at the given position to the selected objects.
     * @param posX the 2D X position where to do the picking  
     * @param posY the 2D Y position where to do the picking
     * @return Returns the current selection, possibly an empy array
     * @see ActiveNode.higlight(boolean,Object) 
     */
    public ArrayList toggleSinglePick(int posX, int posY) {
    lastMouseX = posX;
      lastMouseY = posY;
      PickRenderResult[] results = view.pick(canvas, posX, posY, 3, 3);
 
    if ((results!=null) && (results.length>0)) {
      Node nodes[] = results[0].getNodes();
      if (nodes!=null) {
            Object o = nodes[0].getUserData();
            if (o instanceof ActiveNode) {
                  ((ActiveNode)o).highlight(true,nodes[0]);
                  lastPickSelection.add(o);
                  lastPickSelection.add(nodes[0]);
                  System.out.println(((ActiveNode)o).getName());
            }
          }
    }
     
      return lastPickSelection;
    }

    /**
     * Adds or removes all picks between the given position and the last position,
     * to the selected objects.
     * @param posX the 2D X position defining a region with the last position. All objects in this region should be picked.    
     * @param posX the 2D Y position defining a region with the last position. All objects in this region should be picked.    
     * @return Returns the current selection, possibly an empy array 
     * @see ActiveNode.higlight(boolean,Object) 
     */
    public ArrayList toggleAllPicks(int posX, int posY) {

      // do not update last mouse XY position, so user can refine selection from the same point
      int x = (posX + lastMouseX) / 2;
      int y = (posY + lastMouseY) / 2;
      int dx = Math.abs(posX - lastMouseX) / 2;
      int dy = Math.abs(posY - lastMouseY) / 2;
      PickRenderResult[] results = view.pick(canvas, x, y, dx, dy);

      // TODO : find the closest in all pick paths, loop on all closests
    if ((results!=null) && (results.length>0)) {
      Node nodes[] = results[0].getNodes();
      if (nodes!=null) {
            Object o = nodes[0].getUserData();
            if (o instanceof ActiveNode) {
                  ((ActiveNode)o).highlight(true,nodes[0]);
                  lastPickSelection.add(o);
                  lastPickSelection.add(nodes[0]);
                  System.out.println(((ActiveNode)o).getName());
            }
          }
    }

    /*   
        for (int i=0; i<results.length; ++i) {
            Node nodes[] = results[i].getNodes();
            for (int j=0; j<nodes.length; ++j) {
                Object o = nodes[j].getUserData();
                if (o instanceof ActiveNode) {
                    ((ActiveNode)o).highlight(true,nodes[j]);
                    lastPickSelection.add(o);
                    lastPickSelection.add(nodes[j]);
                }
            }
        }
        */
     
      return lastPickSelection;
    }

    /**
     * Selects a single pick at the given position.
     * @param posX the 2D X position where to do the picking  
     * @param posY the 2D Y position where to do the picking  
     * @return Returns the picked node or possibly a null object if there was nothing to pick at this position 
     * @see ActiveNode.higlight(boolean,Object) 
     */
    public ActiveNode pick(int posX, int posY) {

        int s = lastPickSelection.size();
        for (int i=0; i<s; i+=2) {
            ActiveNode node = (ActiveNode)lastPickSelection.get(i);
            node.highlight(false,lastPickSelection.get(i+1));
        }
        lastPickSelection.clear();
        toggleSinglePick(posX,posY);
        if (lastPickSelection.size()>0) return (ActiveNode)lastPickSelection.get(0);
        return null;
    }
 
 
  public class AutoRepaintFrame extends Frame implements WindowFocusListener {
     
        /**
         * @throws java.awt.HeadlessException
         */
        public AutoRepaintFrame() throws HeadlessException {
            addWindowFocusListener(this);
        }
       
       
        // Hook to insert a frame rendering
        public void paint(Graphics g) {
            super.paint(g);
            if (init) view.renderOnce();
        }

        // Hook to redraw the scene when the window appears on the screen
        public void windowGainedFocus(WindowEvent e) {
            if (init) view.renderOnce();
        }

        public void windowLostFocus(WindowEvent e) {
            // don't care
        }
  }
 
 
  /**
   * Main function to test navigation
   * @param args
   */
  public static void main(String[] args) {
    VirtualUniverse universe = new VirtualUniverse();
    Locale locale = new Locale();
    universe.addLocale(locale);

    BranchGroup objRoot = new BranchGroup();

    Appearance a = new Appearance();
    a.setPolygonAttributes(new PolygonAttributes(PolygonAttributes.POLYGON_LINE, PolygonAttributes.CULL_NONE, 0));
    Shape3D sph = new Shape3D(TestUtils.createSphere(1.0f, 20), a);
    TransformGroup sphereTrans = new TransformGroup();
    sphereTrans.addChild(sph);

    objRoot.addChild(sphereTrans);

    AmbientLight aLgt = new AmbientLight(new Color3f(0.2f, 0.2f, 0.2f));
    objRoot.addChild(aLgt);

    locale.addBranchGraph(objRoot);
   
   
    PluginManager pluginManager = (PluginManager) new Java3DPluginManager();
    
   
   
    Frame3DXith3D f1=new Frame3DXith3D(null, null,"Test1",-1,-1,600,400,pluginManager);
    // TODO Frame3D f2=new Frame3D(null,"Test2",-1,-1,300,300);
    universe.addView(f1.view);
    // TODO universe.addView(f2.view);
       
    while(true){
      f1.view.renderOnce();
      // TODO ! f2.view.renderOnce();
      try{
        Thread.sleep(10);
      }
      catch(InterruptedException e){
      }
    }
  }


}
TOP

Related Classes of syn3d.ui.xith3d.Frame3DXith3D$AutoRepaintFrame

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.