import java.util.ArrayList;
import java.util.Iterator;
+import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.SwingConstants;
import tim.prune.App;
-import tim.prune.Config;
-import tim.prune.GenericFunction;
import tim.prune.I18nManager;
import tim.prune.UpdateMessageBroker;
+import tim.prune.config.Config;
+import tim.prune.data.NumberUtils;
import tim.prune.data.Track;
+import tim.prune.function.Export3dFunction;
+import tim.prune.gui.DialogCloser;
import tim.prune.load.GenericFileFilter;
import tim.prune.threedee.LineDialog;
import tim.prune.threedee.ThreeDModel;
/**
- * Class to export track information
- * into a specified Pov file
+ * Class to export a 3d scene of the track to a specified Pov file
*/
-public class PovExporter extends GenericFunction
+public class PovExporter extends Export3dFunction
{
private Track _track = null;
private JDialog _dialog = null;
private JFileChooser _fileChooser = null;
private String _cameraX = null, _cameraY = null, _cameraZ = null;
private JTextField _cameraXField = null, _cameraYField = null, _cameraZField = null;
- private JTextField _fontName = null, _altitudeCapField = null;
- private int _altitudeCap = ThreeDModel.MINIMUM_ALTITUDE_CAP;
+ private JTextField _fontName = null, _altitudeFactorField = null;
private JRadioButton _ballsAndSticksButton = null;
// defaults
/**
- * Constructor giving frame and track
+ * Constructor
* @param inApp App object
*/
public PovExporter(App inApp)
double cameraDist = Math.sqrt(inX*inX + inY*inY + inZ*inZ);
if (cameraDist > 0.0)
{
- _cameraX = "" + (inX / cameraDist * DEFAULT_CAMERA_DISTANCE);
- _cameraY = "" + (inY / cameraDist * DEFAULT_CAMERA_DISTANCE);
+ _cameraX = NumberUtils.formatNumber(inX / cameraDist * DEFAULT_CAMERA_DISTANCE, 5);
+ _cameraY = NumberUtils.formatNumber(inY / cameraDist * DEFAULT_CAMERA_DISTANCE, 5);
// Careful! Need to convert from java3d (right-handed) to povray (left-handed) coordinate system!
- _cameraZ = "" + (-inZ / cameraDist * DEFAULT_CAMERA_DISTANCE);
- }
- }
-
-
- /**
- * @param inAltitudeCap altitude cap to use
- */
- public void setAltitudeCap(int inAltitudeCap)
- {
- _altitudeCap = inAltitudeCap;
- if (_altitudeCap < ThreeDModel.MINIMUM_ALTITUDE_CAP)
- {
- _altitudeCap = ThreeDModel.MINIMUM_ALTITUDE_CAP;
+ _cameraZ = NumberUtils.formatNumber(-inZ / cameraDist * DEFAULT_CAMERA_DISTANCE, 5);
}
}
_cameraXField.setText(_cameraX);
_cameraYField.setText(_cameraY);
_cameraZField.setText(_cameraZ);
- // Set vertical scale
- _altitudeCapField.setText("" + _altitudeCap);
+ _altitudeFactorField.setText("" + _altFactor);
// Show dialog
_dialog.pack();
_dialog.setVisible(true);
{
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
- panel.add(new JLabel(I18nManager.getText("dialog.exportpov.text")), BorderLayout.NORTH);
+ JLabel introLabel = new JLabel(I18nManager.getText("dialog.exportpov.text"));
+ introLabel.setBorder(BorderFactory.createEmptyBorder(4, 4, 6, 4));
+ panel.add(introLabel, BorderLayout.NORTH);
// OK, Cancel buttons
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
}
_fontName = new JTextField(defaultFont, 12);
_fontName.setAlignmentX(Component.LEFT_ALIGNMENT);
+ _fontName.addKeyListener(new DialogCloser(_dialog));
centralPanel.add(_fontName);
//coordinates of camera
JLabel cameraXLabel = new JLabel(I18nManager.getText("dialog.exportpov.camerax"));
centralPanel.add(cameraZLabel);
_cameraZField = new JTextField("" + _cameraZ);
centralPanel.add(_cameraZField);
- // Altitude capping
- JLabel altitudeCapLabel = new JLabel(I18nManager.getText("dialog.3d.altitudecap"));
+ // Altitude exaggeration
+ JLabel altitudeCapLabel = new JLabel(I18nManager.getText("dialog.3d.altitudefactor"));
altitudeCapLabel.setHorizontalAlignment(SwingConstants.TRAILING);
centralPanel.add(altitudeCapLabel);
- _altitudeCapField = new JTextField("" + _altitudeCap);
- centralPanel.add(_altitudeCapField);
+ _altitudeFactorField = new JTextField("1.0");
+ centralPanel.add(_altitudeFactorField);
// Radio buttons for style - balls on sticks or tubes
JPanel stylePanel = new JPanel();
{
FileWriter writer = null;
// find out the line separator for this system
- String lineSeparator = System.getProperty("line.separator");
+ final String lineSeparator = System.getProperty("line.separator");
try
{
// create and scale model
try
{
// try to use given altitude cap
- _altitudeCap = Integer.parseInt(_altitudeCapField.getText());
- model.setAltitudeCap(_altitudeCap);
+ double altFactor = Double.parseDouble(_altitudeFactorField.getText());
+ model.setAltitudeFactor(altFactor);
+ }
+ catch (NumberFormatException nfe) { // parse failed, reset
+ _altitudeFactorField.setText("1.0");
}
- catch (NumberFormatException nfe) {}
model.scale();
// Create file and write basics
private void writeStartOfFile(FileWriter inWriter, double inModelSize, String inLineSeparator)
throws IOException
{
- inWriter.write("// Pov file produced by Prune - see http://activityworkshop.net/");
+ inWriter.write("// Pov file produced by GpsPrune - see http://activityworkshop.net/");
inWriter.write(inLineSeparator);
inWriter.write(inLineSeparator);
// Select font based on user input
" sphere {",
" <0, 0, 0>, 0.3", // size should depend on model size
" texture {",
- " pigment {color rgb <0.2 1.0 0.2>}",
+ " pigment {color rgb <0.1 0.6 0.1>}", // dark green
" finish { phong 1 }",
" }",
" }",
" sphere {",
" <0, 0, 0>, 0.3", // size should depend on model size
" texture {",
- " pigment {color rgb <0.6 1.0 0.2>}",
+ " pigment {color rgb <0.4 0.9 0.2>}", // green
" finish { phong 1 }",
" }",
" }",
" sphere {",
" <0, 0, 0>, 0.3", // size should depend on model size
" texture {",
- " pigment {color rgb <1.0 1.0 0.1>}",
+ " pigment {color rgb <0.7 0.8 0.2>}", // yellow
" finish { phong 1 }",
" }",
" }",
" sphere {",
" <0, 0, 0>, 0.3", // size should depend on model size
" texture {",
- " pigment {color rgb <1.0 1.0 1.0>}",
+ " pigment {color rgb <0.5 0.8 0.6>}", // greeny
" finish { phong 1 }",
" }",
" }",
" sphere {",
" <0, 0, 0>, 0.3", // size should depend on model size
" texture {",
- " pigment {color rgb <0.1 1.0 1.0>}",
+ " pigment {color rgb <0.2 0.9 0.9>}", // cyan
+ " finish { phong 1 }",
+ " }",
+ " }",
+ "#declare track_sphere5 =",
+ " sphere {",
+ " <0, 0, 0>, 0.3", // size should depend on model size
+ " texture {",
+ " pigment {color rgb <1.0 1.0 1.0>}", // white
" finish { phong 1 }",
" }",
" }",
* @param inLineSeparator line separator to use
* @throws IOException on file writing error
*/
- private void writeLatLongLines(FileWriter inWriter, ThreeDModel inModel, String inLineSeparator)
+ private static void writeLatLongLines(FileWriter inWriter, ThreeDModel inModel, String inLineSeparator)
throws IOException
{
inWriter.write("// Latitude and longitude lines:");
* @param inLineSeparator line separator to use
* @throws IOException on file writing error
*/
- private void writeDataPointsBallsAndSticks(FileWriter inWriter, ThreeDModel inModel, String inLineSeparator)
+ private static void writeDataPointsBallsAndSticks(FileWriter inWriter, ThreeDModel inModel, String inLineSeparator)
throws IOException
{
inWriter.write("// Data points:");
* @param inLineSeparator line separator to use
* @throws IOException on file writing error
*/
- private void writeDataPointsTubesAndWalls(FileWriter inWriter, ThreeDModel inModel, String inLineSeparator)
+ private static void writeDataPointsTubesAndWalls(FileWriter inWriter, ThreeDModel inModel, String inLineSeparator)
throws IOException
{
inWriter.write("// Data points:");
*/
private static byte checkHeightCode(byte inCode)
{
- final byte maxHeightCode = 4;
+ final byte maxHeightCode = 5;
if (inCode < 0) return 0;
if (inCode > maxHeightCode) return maxHeightCode;
return inCode;