import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.universe.SimpleUniverse;
-import tim.prune.App;
+import tim.prune.FunctionLibrary;
import tim.prune.I18nManager;
-import tim.prune.data.Altitude;
import tim.prune.data.Track;
+import tim.prune.function.Export3dFunction;
/**
*/
public class Java3DWindow implements ThreeDWindow
{
- private App _app = null;
private Track _track = null;
private JFrame _parentFrame = null;
private JFrame _frame = null;
private ThreeDModel _model = null;
private OrbitBehavior _orbit = null;
- private int _altitudeCap = ThreeDModel.MINIMUM_ALTITUDE_CAP;
+ private double _altFactor = 50.0;
/** only prompt about big track size once */
private static boolean TRACK_SIZE_WARNING_GIVEN = false;
/**
* Constructor
- * @param inApp App object to use for callbacks
* @param inFrame parent frame
*/
- public Java3DWindow(App inApp, JFrame inFrame)
+ public Java3DWindow(JFrame inFrame)
{
- _app = inApp;
_parentFrame = inFrame;
}
*/
public void show() throws ThreeDException
{
- // Get the altitude cap to use
- String altitudeUnits = getAltitudeUnitsLabel(_track);
- Object altCapString = JOptionPane.showInputDialog(_parentFrame,
- I18nManager.getText("dialog.3d.altitudecap") + " (" + altitudeUnits + ")",
+ // Get the altitude exaggeration to use
+ Object factorString = JOptionPane.showInputDialog(_parentFrame,
+ I18nManager.getText("dialog.3d.altitudefactor"),
I18nManager.getText("dialog.3d.title"),
- JOptionPane.QUESTION_MESSAGE, null, null, "" + _altitudeCap);
- if (altCapString == null) return;
- try
- {
- _altitudeCap = Integer.parseInt(altCapString.toString());
+ JOptionPane.QUESTION_MESSAGE, null, null, _altFactor);
+ if (factorString == null) return;
+ try {
+ _altFactor = Double.parseDouble(factorString.toString());
}
catch (Exception e) {} // Ignore parse errors
+ if (_altFactor < 1.0) {_altFactor = 1.0;}
// Set up the graphics config
GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
{
if (JOptionPane.showOptionDialog(_frame,
I18nManager.getText("dialog.exportpov.warningtracksize"),
- I18nManager.getText("dialog.exportpov.title"), JOptionPane.OK_CANCEL_OPTION,
+ I18nManager.getText("function.exportpov"), JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE, null, buttonTexts, buttonTexts[1])
== JOptionPane.OK_OPTION)
{
// opted to continue, don't show warning again
TRACK_SIZE_WARNING_GIVEN = true;
}
- else
- {
+ else {
// opted to cancel - show warning again next time
return;
}
u.getViewingPlatform().setNominalViewingTransform();
// Add behaviour to rotate using mouse
- _orbit = new OrbitBehavior(canvas, OrbitBehavior.REVERSE_ALL |
- OrbitBehavior.STOP_ZOOM);
+ _orbit = new OrbitBehavior(canvas, OrbitBehavior.REVERSE_ALL | OrbitBehavior.STOP_ZOOM);
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
_orbit.setSchedulingBounds(bounds);
u.getViewingPlatform().setViewPlatformBehavior(_orbit);
_frame = new JFrame(I18nManager.getText("dialog.3d.title"));
_frame.getContentPane().setLayout(new BorderLayout());
_frame.getContentPane().add(canvas, BorderLayout.CENTER);
+ _frame.setIconImage(_parentFrame.getIconImage());
// Make panel for render, close buttons
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.RIGHT));
- // Add callback button for render
- JButton renderButton = new JButton(I18nManager.getText("menu.file.exportpov"));
- renderButton.addActionListener(new ActionListener()
- {
- /** Render button pressed */
+ // Add button for exporting pov
+ JButton povButton = new JButton(I18nManager.getText("function.exportpov"));
+ povButton.addActionListener(new ActionListener() {
+ /** Export pov button pressed */
+ public void actionPerformed(ActionEvent e)
+ {
+ if (_orbit != null) {
+ callbackRender(FunctionLibrary.FUNCTION_POVEXPORT);
+ }
+ }});
+ panel.add(povButton);
+ // Add button for exporting svg
+ JButton svgButton = new JButton(I18nManager.getText("function.exportsvg"));
+ svgButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
- if (_orbit != null)
- {
- callbackRender();
+ if (_orbit != null) {
+ callbackRender(FunctionLibrary.FUNCTION_SVGEXPORT);
}
}});
- panel.add(renderButton);
+ panel.add(svgButton);
// Display coordinates of lat/long lines of 3d graph in separate dialog
JButton showLinesButton = new JButton(I18nManager.getText("button.showlines"));
showLinesButton.addActionListener(new ActionListener() {
closeButton.addActionListener(new ActionListener()
{
/** Close button pressed - clean up */
- public void actionPerformed(ActionEvent e)
- {
- _frame.dispose();
- _frame = null;
+ public void actionPerformed(ActionEvent e) {
+ dispose();
_orbit = null;
}
});
_frame.pack();
// Add a listener to clean up when window closed
_frame.addWindowListener(new WindowAdapter() {
- public void windowClosing(WindowEvent e)
- {
+ public void windowClosing(WindowEvent e) {
dispose();
}
});
// show frame
- _frame.show();
- if (_frame.getState() == JFrame.ICONIFIED)
- {
+ _frame.setVisible(true);
+ if (_frame.getState() == JFrame.ICONIFIED) {
_frame.setState(JFrame.NORMAL);
}
}
Box plane = null;
planeAppearance = new Appearance();
planeAppearance.setMaterial(new Material(new Color3f(0.1f, 0.2f, 0.2f),
- new Color3f(0.0f, 0.0f, 0.0f), new Color3f(0.3f, 0.4f, 0.4f),
- new Color3f(0.3f, 0.3f, 0.3f), 0.0f));
+ new Color3f(0.0f, 0.0f, 0.0f), new Color3f(0.3f, 0.4f, 0.4f),
+ new Color3f(0.3f, 0.3f, 0.3f), 0.0f));
plane = new Box(10f, 0.04f, 10f, planeAppearance);
objTrans.addChild(plane);
// N, S, E, W
GeneralPath bevelPath = new GeneralPath();
bevelPath.moveTo(0.0f, 0.0f);
- for (int i=0; i<91; i+= 5)
+ for (int i=0; i<91; i+= 5) {
bevelPath.lineTo((float) (0.1 - 0.1 * Math.cos(Math.toRadians(i))),
(float) (0.1 * Math.sin(Math.toRadians(i))));
- for (int i=90; i>0; i-=5)
+ }
+ for (int i=90; i>0; i-=5) {
bevelPath.lineTo((float) (0.3 + 0.1 * Math.cos(Math.toRadians(i))),
(float) (0.1 * Math.sin(Math.toRadians(i))));
+ }
Font3D compassFont = new Font3D(
new Font(CARDINALS_FONT, Font.PLAIN, 1),
new FontExtrusion(bevelPath));
// create and scale model
_model = new ThreeDModel(_track);
- _model.setAltitudeCap(_altitudeCap);
+ _model.setAltitudeFactor(_altFactor);
_model.scale();
// Lat/Long lines
objTrans.addChild(createDataPoints(_model));
// Create lights
- BoundingSphere bounds =
- new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
+ BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
AmbientLight aLgt = new AmbientLight(new Color3f(1.0f, 1.0f, 1.0f));
aLgt.setInfluencingBounds(bounds);
objTrans.addChild(aLgt);
PointLight pLgt = new PointLight(new Color3f(1.0f, 1.0f, 1.0f),
- new Point3f(0f, 0f, 2f),
- new Point3f(0.25f, 0.05f, 0.0f) );
+ new Point3f(0f, 0f, 2f), new Point3f(0.25f, 0.05f, 0.0f) );
pLgt.setInfluencingBounds(bounds);
objTrans.addChild(pLgt);
PointLight pl2 = new PointLight(new Color3f(0.8f, 0.9f, 0.4f),
- new Point3f(6f, 1f, 6f),
- new Point3f(0.2f, 0.1f, 0.05f) );
+ new Point3f(6f, 1f, 6f), new Point3f(0.2f, 0.1f, 0.05f) );
pl2.setInfluencingBounds(bounds);
objTrans.addChild(pl2);
PointLight pl3 = new PointLight(new Color3f(0.7f, 0.7f, 0.7f),
- new Point3f(0.0f, 12f, -2f),
- new Point3f(0.1f, 0.1f, 0.0f) );
+ new Point3f(0.0f, 12f, -2f), new Point3f(0.1f, 0.1f, 0.0f) );
pl3.setInfluencingBounds(bounds);
objTrans.addChild(pl3);
{
Text3D txt = new Text3D(inFont, inText, inLocn, Text3D.ALIGN_FIRST, Text3D.PATH_RIGHT);
Material mat = new Material(new Color3f(0.5f, 0.5f, 0.55f),
- new Color3f(0.05f, 0.05f, 0.1f), new Color3f(0.3f, 0.4f, 0.5f),
- new Color3f(0.4f, 0.5f, 0.7f), 70.0f);
+ new Color3f(0.05f, 0.05f, 0.1f), new Color3f(0.3f, 0.4f, 0.5f),
+ new Color3f(0.4f, 0.5f, 0.7f), 70.0f);
mat.setLightingEnable(true);
Appearance app = new Appearance();
app.setMaterial(mat);
{
Cylinder latline = new Cylinder(0.1f, (float) (inSize*2));
Transform3D horizShift = new Transform3D();
- horizShift.setTranslation(new Vector3d(0.0, 0.0, inLatitude));
+ horizShift.setTranslation(new Vector3d(0.0, 0.0, -inLatitude));
TransformGroup horizTrans = new TransformGroup(horizShift);
Transform3D zRot = new Transform3D();
zRot.rotZ(Math.toRadians(90.0));
private static Group createWaypoint(Point3d inPointPos)
{
Material mat = getWaypointMaterial();
- // TODO: sort symbol scaling
+ // MAYBE: sort symbol scaling
Sphere dot = new Sphere(0.35f); // * symbolScaling / 100f);
return createBall(inPointPos, dot, mat);
}
}
+ /** @return track point object */
private static Group createTrackpoint(Point3d inPointPos, byte inHeightCode)
{
Material mat = getTrackpointMaterial(inHeightCode);
- // TODO: sort symbol scaling
- Sphere dot = new Sphere(0.2f); // * symbolScaling / 100f);
+ // MAYBE: sort symbol scaling
+ Sphere dot = new Sphere(0.2f);
return createBall(inPointPos, dot, mat);
}
+ /** @return Material object for track points with the appropriate colour for the height */
private static Material getTrackpointMaterial(byte inHeightCode)
{
// create default material
new Color3f(1.0f, 0.6f, 0.6f), 70.0f);
// change colour according to height code
if (inHeightCode == 1) mat.setDiffuseColor(new Color3f(0.4f, 0.9f, 0.2f));
- if (inHeightCode == 2) mat.setDiffuseColor(new Color3f(0.7f, 0.8f, 0.2f));
- if (inHeightCode == 3) mat.setDiffuseColor(new Color3f(0.5f, 0.85f, 0.95f));
- if (inHeightCode == 4) mat.setDiffuseColor(new Color3f(0.1f, 0.9f, 0.9f));
- if (inHeightCode >= 5) mat.setDiffuseColor(new Color3f(1.0f, 1.0f, 1.0f));
+ else if (inHeightCode == 2) mat.setDiffuseColor(new Color3f(0.7f, 0.8f, 0.2f));
+ else if (inHeightCode == 3) mat.setDiffuseColor(new Color3f(0.3f, 0.6f, 0.4f));
+ else if (inHeightCode == 4) mat.setDiffuseColor(new Color3f(0.1f, 0.9f, 0.9f));
+ else if (inHeightCode >= 5) mat.setDiffuseColor(new Color3f(1.0f, 1.0f, 1.0f));
// return object
return mat;
}
// Also create rod for ball to sit on
Cylinder rod = new Cylinder(0.1f, (float) inPosition.y);
Material rodMat = new Material(new Color3f(0.2f, 0.2f, 0.2f),
- new Color3f(0.0f, 0.0f, 0.0f), new Color3f(0.2f, 0.2f, 0.2f),
- new Color3f(0.05f, 0.05f, 0.05f), 0.4f);
+ new Color3f(0.0f, 0.0f, 0.0f), new Color3f(0.2f, 0.2f, 0.2f),
+ new Color3f(0.05f, 0.05f, 0.05f), 0.4f);
rodMat.setLightingEnable(true);
Appearance rodApp = new Appearance();
rodApp.setMaterial(rodMat);
rod.setAppearance(rodApp);
Transform3D rodShift = new Transform3D();
- rodShift.setTranslation(new Vector3d(inPosition.x,
- inPosition.y/2.0, inPosition.z));
+ rodShift.setTranslation(new Vector3d(inPosition.x, inPosition.y/2.0, inPosition.z));
TransformGroup rodShiftTrans = new TransformGroup(rodShift);
rodShiftTrans.addChild(rod);
group.addChild(rodShiftTrans);
/**
* Calculate the angles and call them back to the app
+ * @param inFunction function to call (either pov or svg)
*/
- private void callbackRender()
+ private void callbackRender(Export3dFunction inFunction)
{
Transform3D trans3d = new Transform3D();
_orbit.getViewingPlatform().getViewPlatformTransform().getTransform(trans3d);
firstTran.rotY(Math.toRadians(-INITIAL_Y_ROTATION));
Transform3D secondTran = new Transform3D();
secondTran.rotX(Math.toRadians(-INITIAL_X_ROTATION));
- // Apply inverse rotations in reverse order to test point
+ // Apply inverse rotations in reverse order to the test point
Point3d result = new Point3d();
secondTran.transform(point, result);
firstTran.transform(result);
- // Callback settings to App
- _app.exportPov(result.x, result.y, result.z, _altitudeCap);
- }
-
-
- /**
- * Get a units label for the altitudes in the given Track
- * @param inTrack Track object
- * @return units label for altitude used in Track
- */
- private static String getAltitudeUnitsLabel(Track inTrack)
- {
- int altitudeFormat = inTrack.getAltitudeRange().getFormat();
- if (altitudeFormat == Altitude.FORMAT_METRES)
- return I18nManager.getText("units.metres.short");
- return I18nManager.getText("units.feet.short");
+ // Callback settings to pov export function
+ inFunction.setCameraCoordinates(result.x, result.y, result.z);
+ inFunction.setAltitudeExaggeration(_altFactor);
+ inFunction.begin();
}
-
}