Merge branch 'unstable' into fix-954

This commit is contained in:
Miacid 2021-06-26 21:10:44 -07:00
commit 54332d4355
11 changed files with 214 additions and 67 deletions

View File

@ -1066,6 +1066,11 @@ ShockCordCfg.lbl.Posrelativeto = Position relative to:
ShockCordCfg.lbl.plus = plus ShockCordCfg.lbl.plus = plus
ShockCordCfg.lbl.Packedlength = Packed length: ShockCordCfg.lbl.Packedlength = Packed length:
ShockCordCfg.lbl.Packeddiam = Packed diameter: ShockCordCfg.lbl.Packeddiam = Packed diameter:
ShockCordCfg.tab.Radialpos = Radial position
ShockCordCfg.tab.ttip.Radialpos = Radial position configuration
ShockCordCfg.lbl.Radialdistance = Radial distance:
ShockCordCfg.lbl.Radialdirection = Radial direction:
ShockCordCfg.but.Reset = Reset
ShockCordCfg.tab.General = General ShockCordCfg.tab.General = General
ShockCordCfg.tab.ttip.General = General properties ShockCordCfg.tab.ttip.General = General properties

View File

@ -21,7 +21,7 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, B
private double radius; private double radius;
private double thickness; private double thickness;
private double angleOffsetRadians = 0; private double angleOffsetRadians = Math.PI;
private double radialOffset = 0; private double radialOffset = 0;
private int instanceCount = 1; private int instanceCount = 1;

View File

@ -56,7 +56,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
private double radialDistance_m=0; private double radialDistance_m=0;
protected static final AngleMethod angleMethod = AngleMethod.RELATIVE; protected static final AngleMethod angleMethod = AngleMethod.RELATIVE;
private double angle_rad = 0; private double angle_rad = Math.PI;
private int instanceCount = 1; private int instanceCount = 1;
private double instanceSeparation = 0; // front-front along the positive rocket axis. i.e. [1,0,0]; private double instanceSeparation = 0; // front-front along the positive rocket axis. i.e. [1,0,0];

View File

@ -22,7 +22,7 @@ public class LaunchLugTest extends BaseTestCase {
lug.setInstanceCount(2); lug.setInstanceCount(2);
double expX = 0.111 + body.getLocations()[0].x; double expX = 0.111 + body.getLocations()[0].x;
double expR = body.getOuterRadius()+lug.getOuterRadius(); double expR = -(body.getOuterRadius()+lug.getOuterRadius());
Coordinate expPos = new Coordinate( expX, expR, 0, 0); Coordinate expPos = new Coordinate( expX, expR, 0, 0);
Coordinate actPos[] = lug.getLocations(); Coordinate actPos[] = lug.getLocations();
assertEquals(" LaunchLug has the wrong x value: ", expPos.x, actPos[0].x, EPSILON); assertEquals(" LaunchLug has the wrong x value: ", expPos.x, actPos[0].x, EPSILON);

View File

@ -89,7 +89,7 @@ public class RocketTest extends BaseTestCase {
} }
LaunchLug lugs = (LaunchLug)body.getChild(1); LaunchLug lugs = (LaunchLug)body.getChild(1);
expLoc = new Coordinate(0.181, 0.015, 0); expLoc = new Coordinate(0.181, -0.015, 0);
assertThat(lugs.getName()+" have incorrect count: ", lugs.getInstanceCount(), equalTo(1)); assertThat(lugs.getName()+" have incorrect count: ", lugs.getInstanceCount(), equalTo(1));
actLocs = lugs.getComponentLocations(); actLocs = lugs.getComponentLocations();
{ // singular instance: { // singular instance:

View File

@ -0,0 +1,28 @@
package net.sf.openrocket.gui.components;
import javax.swing.JSpinner;
import javax.swing.SpinnerModel;
import net.sf.openrocket.gui.SpinnerEditor;
/**
* A JSpinner that allows edits.
*
* @author Billy Olsen
*/
public class EditableSpinner extends JSpinner {
private static final long serialVersionUID = 1L;
/**
* Creates a new EditableSpinner for the SpinnerModel
*
* @param model
*/
public EditableSpinner(SpinnerModel model) {
super(model);
this.setEditor(new SpinnerEditor(this));
}
}

View File

@ -20,6 +20,9 @@ import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.unit.UnitGroup;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class LaunchLugConfig extends RocketComponentConfig { public class LaunchLugConfig extends RocketComponentConfig {
@ -108,28 +111,33 @@ public class LaunchLugConfig extends RocketComponentConfig {
// create a new panel for the right column // create a new panel for the right column
panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", "")); panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
//// Position relative to: //// Position relative to:
panel.add(new JLabel(trans.get("LaunchLugCfg.lbl.Posrelativeto"))); panel.add(new JLabel(trans.get("LaunchLugCfg.lbl.Posrelativeto")));
EnumModel<AxialMethod> positionModel = new EnumModel<AxialMethod>(component, "AxialMethod", AxialMethod.axialOffsetMethods ); EnumModel<AxialMethod> positionModel = new EnumModel<AxialMethod>(component, "AxialMethod", AxialMethod.axialOffsetMethods );
JComboBox<AxialMethod> positionCombo = new JComboBox<AxialMethod>( positionModel ); JComboBox<AxialMethod> positionCombo = new JComboBox<AxialMethod>( positionModel );
panel.add( positionCombo, "spanx, growx, wrap"); panel.add(positionCombo, "spanx, growx, wrap");
//// plus //// plus
final DoubleModel mAxOff = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH);
panel.add(new JLabel(trans.get("LaunchLugCfg.lbl.plus")), "right"); panel.add(new JLabel(trans.get("LaunchLugCfg.lbl.plus")), "right");
spin = new JSpinner(mAxOff.getSpinnerModel()); // Plus quantity input
m = new DoubleModel(component, "AxialOffset", UnitGroup.UNITS_LENGTH);
spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin)); spin.setEditor(new SpinnerEditor(spin));
panel.add(spin, "growx"); panel.add(spin, "growx");
panel.add(new UnitSelector(m), "growx"); panel.add(new UnitSelector(mAxOff), "growx"); // Unity selection
panel.add(new BasicSlider(m.getSliderModel( panel.add(new BasicSlider(mAxOff.getSliderModel( // Plus quantity slider
new DoubleModel(component.getParent(), "Length", -1.0, UnitGroup.UNITS_NONE), new DoubleModel(component.getParent(), "Length", -1.0, UnitGroup.UNITS_NONE),
new DoubleModel(component.getParent(), "Length"))), new DoubleModel(component.getParent(), "Length"))),
"w 100lp, wrap para"); "w 100lp, wrap para");
// Add an action listener to update the plus quantity, based on the selected reference point
positionCombo.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
mAxOff.stateChanged(e);
}
});
//// Material //// Material
panel.add(materialPanel( Material.Type.BULK), "span, wrap"); panel.add(materialPanel( Material.Type.BULK), "span, wrap");

View File

@ -1,10 +1,7 @@
package net.sf.openrocket.gui.configdialog; package net.sf.openrocket.gui.configdialog;
import javax.swing.JComboBox; import javax.swing.*;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.OpenRocketDocument;
@ -15,11 +12,16 @@ import net.sf.openrocket.gui.components.BasicSlider;
import net.sf.openrocket.gui.components.UnitSelector; import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.material.Material; import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.MassComponent;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.ShockCord;
import net.sf.openrocket.rocketcomponent.position.AxialMethod; import net.sf.openrocket.rocketcomponent.position.AxialMethod;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.unit.UnitGroup;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@SuppressWarnings("serial") @SuppressWarnings("serial")
public class ShockCordConfig extends RocketComponentConfig { public class ShockCordConfig extends RocketComponentConfig {
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
@ -114,11 +116,56 @@ public class ShockCordConfig extends RocketComponentConfig {
//// General and General properties //// General and General properties
tabbedPane.insertTab(trans.get("ShockCordCfg.tab.General"), null, panel, trans.get("ShockCordCfg.tab.ttip.General"), 0); tabbedPane.insertTab(trans.get("ShockCordCfg.tab.General"), null, panel,
// tabbedPane.insertTab("Radial position", null, positionTab(), trans.get("ShockCordCfg.tab.ttip.General"), 0);
// "Radial position configuration", 1); //// Radial position and Radial position configuration
tabbedPane.insertTab(trans.get("ShockCordCfg.tab.Radialpos"), null, positionTab(),
trans.get("ShockCordCfg.tab.ttip.Radialpos"), 1);
tabbedPane.setSelectedIndex(0); tabbedPane.setSelectedIndex(0);
} }
// TODO: LOW: there is a lot of duplicate code here with other mass components... (e.g. in MassComponentConfig or ParachuteConfig)
protected JPanel positionTab() {
JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::]", ""));
//// Radial position
//// Radial distance:
panel.add(new JLabel(trans.get("ShockCordCfg.lbl.Radialdistance")));
DoubleModel m = new DoubleModel(component, "RadialPosition", UnitGroup.UNITS_LENGTH, 0);
JSpinner spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
panel.add(spin, "growx");
panel.add(new UnitSelector(m), "growx");
panel.add(new BasicSlider(m.getSliderModel(0, 0.1, 1.0)), "w 100lp, wrap");
//// Radial direction:
panel.add(new JLabel(trans.get("ShockCordCfg.lbl.Radialdirection")));
m = new DoubleModel(component, "RadialDirection", UnitGroup.UNITS_ANGLE);
spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
panel.add(spin, "growx");
panel.add(new UnitSelector(m), "growx");
panel.add(new BasicSlider(m.getSliderModel(-Math.PI, Math.PI)), "w 100lp, wrap");
//// Reset button
JButton button = new JButton(trans.get("ShockCordCfg.but.Reset"));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
((ShockCord) component).setRadialDirection(0.0);
((ShockCord) component).setRadialPosition(0.0);
}
});
panel.add(button, "spanx, right");
return panel;
}
} }

View File

@ -124,12 +124,20 @@ final class MassObjectRenderer {
private MassObjectRenderer() { private MassObjectRenderer() {
} }
/**
* Draw the mass object as a 3D figure.
*
* @param gl OpenGL object
* @param o mass object to draw (e.g. Parachute or Mass Component)
* @param slices number of slices for the 3D object (kind of like subdivision surface)
* @param stacks number of stacks for the 3D object (kind of like subdivision surface)
*/
static final void drawMassObject(final GL2 gl, final MassObject o, static final void drawMassObject(final GL2 gl, final MassObject o,
final int slices, final int stacks) { final int slices, final int stacks) {
double da, r, dz; double da, r, dz; // Axial length per slice, radius & length per stack
double x, y, z; double x, y, z; // X-, y- and z-position
int i, j; int i, j;
da = 2.0f * PI / slices; da = 2.0f * PI / slices;
@ -156,20 +164,24 @@ final class MassObjectRenderer {
x = sin((i * da)); x = sin((i * da));
y = cos((i * da)); y = cos((i * da));
} }
// Add radial offset
double xOffset = o.getRadialPosition() * sin(o.getRadialDirection());
double yOffset = o.getRadialPosition() * cos(o.getRadialDirection());
if (r == 0) if (r == 0)
normal3d(gl, 0, 0, 1); normal3d(gl, 0, 0, 1);
else else
normal3d(gl, x, y, z); normal3d(gl, x, y, z);
TXTR_COORD(gl, s, t); TXTR_COORD(gl, s, t);
glVertex3d(gl, (x * r), (y * r), z); glVertex3d(gl, (x * r) + xOffset, (y * r) + yOffset, z);
if (rNext == 0) if (rNext == 0)
normal3d(gl, 0, 0, -1); normal3d(gl, 0, 0, -1);
else else
normal3d(gl, x, y, z); normal3d(gl, x, y, z);
TXTR_COORD(gl, s, t + dt); TXTR_COORD(gl, s, t + dt);
glVertex3d(gl, (x * rNext), (y * rNext), (z + dz)); glVertex3d(gl, (x * rNext) + xOffset, (y * rNext) + yOffset, (z + dz));
s += ds; s += ds;
} // for slices } // for slices

View File

@ -16,15 +16,18 @@ import javax.swing.JDialog;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JSeparator; import javax.swing.JSeparator;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane; import javax.swing.JTabbedPane;
import javax.swing.JTextArea; import javax.swing.JTextArea;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import javax.swing.colorchooser.ColorSelectionModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.gui.adaptors.BooleanModel; import net.sf.openrocket.gui.adaptors.BooleanModel;
import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.components.ColorIcon; import net.sf.openrocket.gui.components.ColorIcon;
import net.sf.openrocket.gui.components.EditableSpinner;
import net.sf.openrocket.gui.components.StyledLabel; import net.sf.openrocket.gui.components.StyledLabel;
import net.sf.openrocket.gui.components.StyledLabel.Style; import net.sf.openrocket.gui.components.StyledLabel.Style;
import net.sf.openrocket.gui.components.UnitSelector; import net.sf.openrocket.gui.components.UnitSelector;
@ -57,28 +60,61 @@ public class PhotoSettingsConfig extends JTabbedPane {
this.o = o; this.o = o;
} }
/**
Changes the color of the selected component to <color>
@param color: color to change the component to
*/
private void changeComponentColor(Color color) {
try {
final Method setMethod = o.getClass().getMethod("set" + valueName, net.sf.openrocket.util.Color.class);
if (color == null)
return;
try {
setMethod.invoke(o, ColorConversion.fromAwtColor(color));
} catch (Throwable e1) {
Application.getExceptionHandler().handleErrorCondition(e1);
}
} catch (Throwable e1) {
Application.getExceptionHandler().handleErrorCondition(e1);
}
}
@Override @Override
public void actionPerformed(ActionEvent colorClickEvent) { public void actionPerformed(ActionEvent colorClickEvent) {
try { try {
final Method getMethod = o.getClass().getMethod("get" + valueName); final Method getMethod = o.getClass().getMethod("get" + valueName);
final Method setMethod = o.getClass().getMethod("set" + valueName, net.sf.openrocket.util.Color.class);
net.sf.openrocket.util.Color c = (net.sf.openrocket.util.Color) getMethod.invoke(o); net.sf.openrocket.util.Color c = (net.sf.openrocket.util.Color) getMethod.invoke(o);
Color awtColor = ColorConversion.toAwtColor(c); Color awtColor = ColorConversion.toAwtColor(c);
colorChooser.setColor(awtColor); colorChooser.setColor(awtColor);
// Bind a change of color selection to a change in the components color
ColorSelectionModel model = colorChooser.getSelectionModel();
ChangeListener changeListener = new ChangeListener() {
public void stateChanged(ChangeEvent changeEvent) {
Color selected = colorChooser.getColor();
changeComponentColor(selected);
}
};
model.addChangeListener(changeListener);
JDialog d = JColorChooser.createDialog(PhotoSettingsConfig.this, JDialog d = JColorChooser.createDialog(PhotoSettingsConfig.this,
trans.get("PhotoSettingsConfig.colorChooser.title"), true, colorChooser, new ActionListener() { trans.get("PhotoSettingsConfig.colorChooser.title"), true, colorChooser, new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent okEvent) { public void actionPerformed(ActionEvent okEvent) {
Color selected = colorChooser.getColor(); changeComponentColor(colorChooser.getColor());
if (selected == null) // Unbind listener to avoid the current component's appearance to change with other components
return; model.removeChangeListener(changeListener);
try {
setMethod.invoke(o, ColorConversion.fromAwtColor(selected));
} catch (Throwable e1) {
Application.getExceptionHandler().handleErrorCondition(e1);
}
} }
}, null); }, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
changeComponentColor(awtColor);
// Unbind listener to avoid the current component's appearance to change with other components
model.removeChangeListener(changeListener);
}
});
d.setVisible(true); d.setVisible(true);
} catch (Throwable e1) { } catch (Throwable e1) {
Application.getExceptionHandler().handleErrorCondition(e1); Application.getExceptionHandler().handleErrorCondition(e1);
@ -128,22 +164,22 @@ public class PhotoSettingsConfig extends JTabbedPane {
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.pitch"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.pitch")));
DoubleModel pitchModel = new DoubleModel(p, "Pitch", UnitGroup.UNITS_ANGLE); DoubleModel pitchModel = new DoubleModel(p, "Pitch", UnitGroup.UNITS_ANGLE);
add(new JSpinner(pitchModel.getSpinnerModel()), "w 40"); add(new EditableSpinner(pitchModel.getSpinnerModel()), "w 40");
add(new UnitSelector(pitchModel), "wrap"); add(new UnitSelector(pitchModel), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.yaw"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.yaw")));
DoubleModel yawModel = new DoubleModel(p, "Yaw", UnitGroup.UNITS_ANGLE); DoubleModel yawModel = new DoubleModel(p, "Yaw", UnitGroup.UNITS_ANGLE);
add(new JSpinner(yawModel.getSpinnerModel()), "w 40"); add(new EditableSpinner(yawModel.getSpinnerModel()), "w 40");
add(new UnitSelector(yawModel), "wrap"); add(new UnitSelector(yawModel), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.roll"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.roll")));
DoubleModel rollModel = new DoubleModel(p, "Roll", UnitGroup.UNITS_ANGLE); DoubleModel rollModel = new DoubleModel(p, "Roll", UnitGroup.UNITS_ANGLE);
add(new JSpinner(rollModel.getSpinnerModel()), "w 40"); add(new EditableSpinner(rollModel.getSpinnerModel()), "w 40");
add(new UnitSelector(rollModel), "wrap"); add(new UnitSelector(rollModel), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.advance"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.advance")));
DoubleModel advanceModel = new DoubleModel(p, "Advance", UnitGroup.UNITS_LENGTH); DoubleModel advanceModel = new DoubleModel(p, "Advance", UnitGroup.UNITS_LENGTH);
add(new JSpinner(advanceModel.getSpinnerModel()), "w 40"); add(new EditableSpinner(advanceModel.getSpinnerModel()), "w 40");
add(new UnitSelector(advanceModel), "wrap"); add(new UnitSelector(advanceModel), "wrap");
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.camera"), Style.BOLD)); add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.camera"), Style.BOLD));
@ -151,22 +187,22 @@ public class PhotoSettingsConfig extends JTabbedPane {
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vAz"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vAz")));
DoubleModel viewAzModel = new DoubleModel(p, "ViewAz", UnitGroup.UNITS_ANGLE); DoubleModel viewAzModel = new DoubleModel(p, "ViewAz", UnitGroup.UNITS_ANGLE);
add(new JSpinner(viewAzModel.getSpinnerModel()), "w 40"); add(new EditableSpinner(viewAzModel.getSpinnerModel()), "w 40");
add(new UnitSelector(viewAzModel), "wrap"); add(new UnitSelector(viewAzModel), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vAlt"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vAlt")));
DoubleModel viewAltModle = new DoubleModel(p, "ViewAlt", UnitGroup.UNITS_ANGLE); DoubleModel viewAltModle = new DoubleModel(p, "ViewAlt", UnitGroup.UNITS_ANGLE);
add(new JSpinner(viewAltModle.getSpinnerModel()), "w 40"); add(new EditableSpinner(viewAltModle.getSpinnerModel()), "w 40");
add(new UnitSelector(viewAltModle), "wrap"); add(new UnitSelector(viewAltModle), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vDist"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.vDist")));
DoubleModel viewDistanceModel = new DoubleModel(p, "ViewDistance", UnitGroup.UNITS_LENGTH); DoubleModel viewDistanceModel = new DoubleModel(p, "ViewDistance", UnitGroup.UNITS_LENGTH);
add(new JSpinner(viewDistanceModel.getSpinnerModel()), "w 40"); add(new EditableSpinner(viewDistanceModel.getSpinnerModel()), "w 40");
add(new UnitSelector(viewDistanceModel), "wrap"); add(new UnitSelector(viewDistanceModel), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.fov"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.fov")));
DoubleModel fovModel = new DoubleModel(p, "Fov", UnitGroup.UNITS_ANGLE); DoubleModel fovModel = new DoubleModel(p, "Fov", UnitGroup.UNITS_ANGLE);
add(new JSpinner(fovModel.getSpinnerModel()), "w 40"); add(new EditableSpinner(fovModel.getSpinnerModel()), "w 40");
add(new UnitSelector(fovModel), "wrap"); add(new UnitSelector(fovModel), "wrap");
} }
}); });
@ -181,16 +217,16 @@ public class PhotoSettingsConfig extends JTabbedPane {
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.amb"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.amb")));
DoubleModel ambianceModel = new DoubleModel(p, "Ambiance", 100, UnitGroup.UNITS_NONE, 0, 100); DoubleModel ambianceModel = new DoubleModel(p, "Ambiance", 100, UnitGroup.UNITS_NONE, 0, 100);
add(new JSpinner(ambianceModel.getSpinnerModel()), "wrap"); add(new EditableSpinner(ambianceModel.getSpinnerModel()), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.lightAz"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.lightAz")));
DoubleModel lightAzModel = new DoubleModel(p, "LightAz", UnitGroup.UNITS_ANGLE); DoubleModel lightAzModel = new DoubleModel(p, "LightAz", UnitGroup.UNITS_ANGLE);
add(new JSpinner(lightAzModel.getSpinnerModel()), "w 40"); add(new EditableSpinner(lightAzModel.getSpinnerModel()), "w 40");
add(new UnitSelector(lightAzModel), "wrap"); add(new UnitSelector(lightAzModel), "wrap");
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.lightAlt"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.lightAlt")));
DoubleModel lightAltModle = new DoubleModel(p, "LightAlt", UnitGroup.UNITS_ANGLE); DoubleModel lightAltModle = new DoubleModel(p, "LightAlt", UnitGroup.UNITS_ANGLE);
add(new JSpinner(lightAltModle.getSpinnerModel()), "wrap"); add(new EditableSpinner(lightAltModle.getSpinnerModel()), "wrap");
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.sky"), Style.BOLD)); add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.sky"), Style.BOLD));
add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx"); add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx");
@ -265,7 +301,7 @@ public class PhotoSettingsConfig extends JTabbedPane {
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.smokeOpacity"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.smokeOpacity")));
DoubleModel smokeAlphaModel = new DoubleModel(p, "SmokeAlpha", 100, UnitGroup.UNITS_NONE, 0, 100); DoubleModel smokeAlphaModel = new DoubleModel(p, "SmokeAlpha", 100, UnitGroup.UNITS_NONE, 0, 100);
JSpinner opacitySpinner = new JSpinner(smokeAlphaModel.getSpinnerModel()); EditableSpinner opacitySpinner = new EditableSpinner(smokeAlphaModel.getSpinnerModel());
add(opacitySpinner, "wrap"); add(opacitySpinner, "wrap");
smokeModel.addEnableComponent(opacitySpinner); smokeModel.addEnableComponent(opacitySpinner);
@ -279,7 +315,7 @@ public class PhotoSettingsConfig extends JTabbedPane {
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.flameAspect"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.flameAspect")));
DoubleModel flameAspectModel = new DoubleModel(p, "FlameAspectRatio", 100, UnitGroup.UNITS_NONE, 25, DoubleModel flameAspectModel = new DoubleModel(p, "FlameAspectRatio", 100, UnitGroup.UNITS_NONE, 25,
250); 250);
JSpinner flameAspectSpinner = new JSpinner(flameAspectModel.getSpinnerModel()); EditableSpinner flameAspectSpinner = new EditableSpinner(flameAspectModel.getSpinnerModel());
add(flameAspectSpinner, "wrap"); add(flameAspectSpinner, "wrap");
fireModel.addEnableComponent(flameAspectSpinner); fireModel.addEnableComponent(flameAspectSpinner);
@ -292,19 +328,19 @@ public class PhotoSettingsConfig extends JTabbedPane {
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.sparkConcentration"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.sparkConcentration")));
DoubleModel sparkConcentrationModel = new DoubleModel(p, "SparkConcentration", 100, DoubleModel sparkConcentrationModel = new DoubleModel(p, "SparkConcentration", 100,
UnitGroup.UNITS_NONE, 0, 100); UnitGroup.UNITS_NONE, 0, 100);
JSpinner sparkConcentrationSpinner = new JSpinner(sparkConcentrationModel.getSpinnerModel()); EditableSpinner sparkConcentrationSpinner = new EditableSpinner(sparkConcentrationModel.getSpinnerModel());
add(sparkConcentrationSpinner, "wrap"); add(sparkConcentrationSpinner, "wrap");
sparksModel.addEnableComponent(sparkConcentrationSpinner); sparksModel.addEnableComponent(sparkConcentrationSpinner);
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.sparkWeight"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.sparkWeight")));
DoubleModel sparkWeightModel = new DoubleModel(p, "SparkWeight", 100, UnitGroup.UNITS_NONE, 0, 100); DoubleModel sparkWeightModel = new DoubleModel(p, "SparkWeight", 100, UnitGroup.UNITS_NONE, 0, 100);
JSpinner sparkWeightSpinner = new JSpinner(sparkWeightModel.getSpinnerModel()); EditableSpinner sparkWeightSpinner = new EditableSpinner(sparkWeightModel.getSpinnerModel());
add(sparkWeightSpinner, "wrap"); add(sparkWeightSpinner, "wrap");
sparksModel.addEnableComponent(sparkWeightSpinner); sparksModel.addEnableComponent(sparkWeightSpinner);
add(new JLabel(trans.get("PhotoSettingsConfig.lbl.exhaustScale"))); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.exhaustScale")));
DoubleModel exhaustScaleModel = new DoubleModel(p, "ExhaustScale", 100, UnitGroup.UNITS_NONE, 0, 1000); DoubleModel exhaustScaleModel = new DoubleModel(p, "ExhaustScale", 100, UnitGroup.UNITS_NONE, 0, 1000);
add(new JSpinner(exhaustScaleModel.getSpinnerModel()), "wrap"); add(new EditableSpinner(exhaustScaleModel.getSpinnerModel()), "wrap");
add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.effects"), Style.BOLD)); add(new StyledLabel(trans.get("PhotoSettingsConfig.lbl.effects"), Style.BOLD));
add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx"); add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx");

View File

@ -1,6 +1,9 @@
package net.sf.openrocket.gui.rocketfigure; package net.sf.openrocket.gui.rocketfigure;
import net.sf.openrocket.rocketcomponent.MassComponent;
import net.sf.openrocket.rocketcomponent.MassObject;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.ShockCord;
import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Transformation; import net.sf.openrocket.util.Transformation;
@ -13,33 +16,41 @@ import java.awt.geom.RoundRectangle2D;
public class ShockCordShapes extends RocketComponentShape { public class ShockCordShapes extends RocketComponentShape {
public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) { public static RocketComponentShape[] getShapesSide( final RocketComponent component, final Transformation transformation) {
final ShockCord massObj = (ShockCord)component;
net.sf.openrocket.rocketcomponent.MassObject massObj = (net.sf.openrocket.rocketcomponent.MassObject)component;
double length = massObj.getLength(); double length = massObj.getLength();
double radius = massObj.getRadius(); double radius = massObj.getRadius();
double arc = Math.min(length, 2*radius) * 0.7; double arc = Math.min(length, 2*radius) * 0.7;
final double radialDistance = massObj.getRadialPosition();
Coordinate start = transformation.transform(Coordinate.ZERO); final double radialAngleRadians = massObj.getRadialDirection();
final Coordinate localPosition = new Coordinate(0,
radialDistance * Math.cos(radialAngleRadians),
radialDistance * Math.sin(radialAngleRadians));
final Coordinate renderPosition = transformation.transform(localPosition);
Shape[] s = new Shape[1]; Shape[] s = new Shape[1];
s[0] = new RoundRectangle2D.Double(start.x,(start.y-radius), s[0] = new RoundRectangle2D.Double(renderPosition.x,(renderPosition.y-radius),
length,2*radius,arc,arc); length,2*radius,arc,arc);
return RocketComponentShape.toArray( addSymbol(s), component); return RocketComponentShape.toArray(addSymbol(s), component);
} }
public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) { public static RocketComponentShape[] getShapesBack( final RocketComponent component, final Transformation transformation) {
final ShockCord massObj = (ShockCord)component;
net.sf.openrocket.rocketcomponent.MassObject tube = (net.sf.openrocket.rocketcomponent.MassObject)component;
double or = tube.getRadius(); double or = massObj.getRadius();
final double radialDistance = massObj.getRadialPosition();
final double radialAngleRadians = massObj.getRadialDirection();
final Coordinate localPosition = new Coordinate(0,
radialDistance * Math.cos(radialAngleRadians),
radialDistance * Math.sin(radialAngleRadians));
final Coordinate renderPosition = transformation.transform(localPosition);
Shape[] s = new Shape[1]; Shape[] s = new Shape[1];
Coordinate start = transformation.transform(Coordinate.ZERO);
s[0] = new Ellipse2D.Double((start.z-or),(start.y-or),2*or,2*or); s[0] = new Ellipse2D.Double((renderPosition.z-or),(renderPosition.y-or),2*or,2*or);
// Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset)); // Coordinate[] start = transformation.transform(tube.toAbsolute(instanceOffset));
// //