/* jCAE stand for Java Computer Aided Engineering. Features are : Small CAD
modeler, Finite element mesher, Plugin architecture.
Copyright (C) 2003,2004,2005, by EADS CRC
Copyright (C) 2008, by EADS France
This library 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 library 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 library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
package org.jcae.mesh.amibe.patch;
import java.awt.event.*;
import java.awt.BorderLayout;
import javax.swing.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.picking.*;
import com.sun.j3d.utils.behaviors.vp.*;
import java.util.logging.Logger;
/** This is the panel which include the J3DCanvas for 3D display. It should be set
* in an independant Windows (JDialog, JFrame), to avoid averlaping with swing
* component.
* @author Jerome Robert
*/
public class Viewer extends JFrame
{
private static final Logger logger=Logger.getLogger(Viewer.class.getName());
private final BorderLayout borderLayout = new BorderLayout();
private final Canvas3D canvas3D;
private final SimpleUniverse universe;
private final BranchGroup mainBranchGroup;
private double [] lastClick = null;
private char lastKey = 0;
/** The constructor */
public Viewer()
{
getContentPane().setLayout(borderLayout);
canvas3D=new Canvas3D(SimpleUniverse.getPreferredConfiguration());
canvas3D.addMouseListener(new java.awt.event.MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
canvas3D_mouseClicked(e);
}
});
canvas3D.addKeyListener(new java.awt.event.KeyAdapter()
{
@Override
public void keyPressed(KeyEvent e)
{
canvas3D_keyPressed(e);
}
});
getContentPane().add(canvas3D,BorderLayout.CENTER);
universe=new SimpleUniverse(canvas3D);
mainBranchGroup=new BranchGroup();
mainBranchGroup.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
mainBranchGroup.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
mainBranchGroup.setCapability(BranchGroup.ALLOW_DETACH);
mainBranchGroup.setCapability(BranchGroup.ALLOW_BOUNDS_READ);
universe.addBranchGraph(createLights(new BoundingSphere(new Point3d(),Double.MAX_VALUE)));
universe.addBranchGraph(mainBranchGroup);
setSize(800,600);
}
public final void addBranchGroup(BranchGroup branchGroup)
{
branchGroup.setCapability(BranchGroup.ALLOW_DETACH);
mainBranchGroup.addChild(branchGroup);
}
public final void removeAllBranchGroup()
{
mainBranchGroup.removeAllChildren();
}
public Runnable callBack = null;
final void canvas3D_mouseClicked(MouseEvent e)
{
try
{
PickCanvas pickCanvas = new PickCanvas(canvas3D,universe.getLocale());
pickCanvas.setTolerance(0);
pickCanvas.setShapeLocation(e);
pickCanvas.setMode(PickTool.GEOMETRY_INTERSECT_INFO);
PickResult pr=pickCanvas.pickClosest();
if(pr!=null)
{
double distmin=pr.getIntersection(0).getDistance();
int closest=0;
for (int t=1;t<pr.numIntersections();t++)
{
double dist = pr.getIntersection(t).getDistance();
if (dist < distmin)
{
dist = distmin;
closest = t;
}
}
PickIntersection pi=pr.getIntersection(closest);
logger.fine("closest vertex index="+closest);
Point3d pickPoint=pi.getPointCoordinates();
lastClick = new double[3];
lastClick[0] = pickPoint.x;
lastClick[1] = pickPoint.y;
lastClick[2] = pickPoint.z;
if (callBack != null)
callBack.run();
lastClick = null;
}
}
catch(Exception ex)
{
ex.printStackTrace(System.out);
}
}
/** Return the position of last click */
public final double [] getLastClick()
{
return lastClick;
}
final void canvas3D_keyPressed(KeyEvent e)
{
try
{
lastKey = e.getKeyChar();
if (callBack != null)
callBack.run();
lastKey = 0;
}
catch(Exception ex)
{
ex.printStackTrace(System.out);
}
}
public char getLastKey()
{
return lastKey;
}
/** Fit all the scenes in the current view */
public final void zoomTo()
{
BoundingSphere b= (BoundingSphere)mainBranchGroup.getBounds();
Point3d c=new Point3d();
b.getCenter(c);
zoomTo((float)c.x,(float)c.y,(float)c.z,(float)b.getRadius());
}
/** Modify the view to best see what is include a given sphere
* @param x x coordinate of the center of the sphere
* @param y y coordinate of the center of the sphere
* @param z z coordinate of the center of the sphere
* @param radius radius of the sphere
*/
final void zoomTo(float x, float y, float z, float radius)
{
OrbitBehavior orbit;
Point3d c=new Point3d(x,y,z);
BoundingSphere b=new BoundingSphere(c,radius);
orbit = new OrbitBehavior(canvas3D, OrbitBehavior.REVERSE_ALL);
orbit.setBounds(b);
orbit.setRotationCenter(c);
orbit.setZoomFactor(b.getRadius());
orbit.setTransFactors(b.getRadius(),b.getRadius());
orbit.setSchedulingBounds(new BoundingSphere(c,b.getRadius()*100));
universe.getViewingPlatform().setViewPlatformBehavior(orbit);
View view=universe.getViewer().getView();
view.setFrontClipDistance(0.001*radius);
view.setBackClipDistance(10*radius);
Transform3D t3d = new Transform3D();
universe.getViewingPlatform().getViewPlatformTransform().getTransform(t3d);
//calculate the translation vector for a identity rotation matrix
Vector3f v=new Vector3f(x,y,3f*radius+z);
//rotate the translation vector
t3d.transform(v);
t3d.setTranslation(v);
universe.getViewingPlatform().getViewPlatformTransform().setTransform(t3d);
orbit.setViewingPlatform(universe.getViewingPlatform());
}
private BranchGroup createLights(Bounds bounds)
{
BranchGroup gp=new BranchGroup();
// Set up the ambient light
Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
AmbientLight ambientLightNode = new AmbientLight(ambientColor);
ambientLightNode.setInfluencingBounds(bounds);
gp.addChild(ambientLightNode);
// Set up the directional lights
Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f);
DirectionalLight light1 = new DirectionalLight(light1Color, light1Direction);
light1.setInfluencingBounds(bounds);
gp.addChild(light1);
Color3f light2Color = new Color3f(1.0f, 1.0f, 1.0f);
Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f);
DirectionalLight light2 = new DirectionalLight(light2Color, light2Direction);
light2.setInfluencingBounds(bounds);
light2.setCapability(DirectionalLight.ALLOW_INFLUENCING_BOUNDS_WRITE);
light2.setCapability(DirectionalLight.ALLOW_INFLUENCING_BOUNDS_READ);
gp.addChild(light2);
return gp;
}
}