Merge pull request #39 from bkuker/kruland-integration-defaults
Add Default appearances
BIN
core/resources/datafiles/textures/balsa.png
Normal file
After Width: | Height: | Size: 553 KiB |
BIN
core/resources/datafiles/textures/cardboard.png
Normal file
After Width: | Height: | Size: 84 KiB |
BIN
core/resources/datafiles/textures/chute.png
Normal file
After Width: | Height: | Size: 144 KiB |
BIN
core/resources/datafiles/textures/hardboard.png
Normal file
After Width: | Height: | Size: 134 KiB |
BIN
core/resources/datafiles/textures/motors/aerotech.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
core/resources/datafiles/textures/motors/estes.png
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
core/resources/datafiles/textures/motors/reusable.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
core/resources/datafiles/textures/spiral-wound-alpha.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
core/resources/datafiles/textures/wadding.png
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
core/resources/datafiles/textures/wood.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
@ -47,7 +47,8 @@ RocketActions.MoveDownAct.ttip.Movedown = Move this component downwards.
|
|||||||
RocketPanel.FigTypeAct.Sideview = Side view
|
RocketPanel.FigTypeAct.Sideview = Side view
|
||||||
RocketPanel.FigTypeAct.Backview = Back view
|
RocketPanel.FigTypeAct.Backview = Back view
|
||||||
RocketPanel.FigTypeAct.Figure3D = 3D Figure
|
RocketPanel.FigTypeAct.Figure3D = 3D Figure
|
||||||
RocketPanel.FigTypeAct.Realistic3D = 3D Realistic
|
RocketPanel.FigTypeAct.Finished = 3D Finished
|
||||||
|
RocketPanel.FigTypeAct.Unfinished = 3D Unfinished
|
||||||
|
|
||||||
|
|
||||||
RocketPanel.lbl.Flightcfg = Flight configuration:
|
RocketPanel.lbl.Flightcfg = Flight configuration:
|
||||||
|
@ -10,19 +10,19 @@ import net.sf.openrocket.util.MathUtil;
|
|||||||
* @author Bill Kuker <bkuker@billkuker.com>
|
* @author Bill Kuker <bkuker@billkuker.com>
|
||||||
*/
|
*/
|
||||||
public class Appearance {
|
public class Appearance {
|
||||||
public static final Appearance MISSING = new Appearance(new Color(0, 0, 0), 100, null);
|
public static final Appearance MISSING = new Appearance(new Color(0, 0, 0), 1, null);
|
||||||
|
|
||||||
private final Color paint;
|
private final Color paint;
|
||||||
private final double shine;
|
private final double shine;
|
||||||
private final Decal texture;
|
private final Decal texture;
|
||||||
|
|
||||||
Appearance(final Color paint, final double shine, final Decal texture) {
|
public Appearance(final Color paint, final double shine, final Decal texture) {
|
||||||
this.paint = paint;
|
this.paint = paint;
|
||||||
this.shine = MathUtil.clamp(shine, 0, 1);
|
this.shine = MathUtil.clamp(shine, 0, 1);
|
||||||
this.texture = texture;
|
this.texture = texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
Appearance(final Color paint, final double shine) {
|
public Appearance(final Color paint, final double shine) {
|
||||||
this.paint = paint;
|
this.paint = paint;
|
||||||
this.shine = MathUtil.clamp(shine, 0, 1);
|
this.shine = MathUtil.clamp(shine, 0, 1);
|
||||||
this.texture = null;
|
this.texture = null;
|
||||||
|
@ -13,11 +13,13 @@ public class Decal {
|
|||||||
public static enum EdgeMode {
|
public static enum EdgeMode {
|
||||||
REPEAT("TextureWrap.Repeat"), MIRROR("TextureWrap.Mirror"), CLAMP("TextureWrap.Clamp"), STICKER("TextureWrap.Sticker");
|
REPEAT("TextureWrap.Repeat"), MIRROR("TextureWrap.Mirror"), CLAMP("TextureWrap.Clamp"), STICKER("TextureWrap.Sticker");
|
||||||
private final String transName;
|
private final String transName;
|
||||||
EdgeMode(final String name){
|
|
||||||
|
EdgeMode(final String name) {
|
||||||
this.transName = name;
|
this.transName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString() {
|
||||||
return Application.getTranslator().get(transName);
|
return Application.getTranslator().get(transName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -27,7 +29,7 @@ public class Decal {
|
|||||||
private final DecalImage image;
|
private final DecalImage image;
|
||||||
private final EdgeMode mode;
|
private final EdgeMode mode;
|
||||||
|
|
||||||
Decal(final Coordinate offset, final Coordinate center, final Coordinate scale, final double rotation,
|
public Decal(final Coordinate offset, final Coordinate center, final Coordinate scale, final double rotation,
|
||||||
final DecalImage image, final EdgeMode mode) {
|
final DecalImage image, final EdgeMode mode) {
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
this.center = center;
|
this.center = center;
|
||||||
|
@ -0,0 +1,111 @@
|
|||||||
|
package net.sf.openrocket.appearance.defaults;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import net.sf.openrocket.appearance.Appearance;
|
||||||
|
import net.sf.openrocket.appearance.Decal;
|
||||||
|
import net.sf.openrocket.appearance.Decal.EdgeMode;
|
||||||
|
import net.sf.openrocket.motor.Motor;
|
||||||
|
import net.sf.openrocket.motor.ThrustCurveMotor;
|
||||||
|
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||||
|
import net.sf.openrocket.rocketcomponent.EngineBlock;
|
||||||
|
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||||
|
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||||
|
import net.sf.openrocket.rocketcomponent.LaunchLug;
|
||||||
|
import net.sf.openrocket.rocketcomponent.MassObject;
|
||||||
|
import net.sf.openrocket.rocketcomponent.Parachute;
|
||||||
|
import net.sf.openrocket.rocketcomponent.RadiusRingComponent;
|
||||||
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
|
import net.sf.openrocket.rocketcomponent.Transition;
|
||||||
|
import net.sf.openrocket.rocketcomponent.TubeCoupler;
|
||||||
|
import net.sf.openrocket.util.Color;
|
||||||
|
import net.sf.openrocket.util.Coordinate;
|
||||||
|
|
||||||
|
public class DefaultAppearance {
|
||||||
|
|
||||||
|
private static Appearance simple(String resource) {
|
||||||
|
return new Appearance(
|
||||||
|
new Color(1, 1, 1),
|
||||||
|
0,
|
||||||
|
new Decal(
|
||||||
|
new Coordinate(0, 0),
|
||||||
|
new Coordinate(0, 0),
|
||||||
|
new Coordinate(1, 1),
|
||||||
|
0,
|
||||||
|
new ResourceDecalImage(resource), EdgeMode.REPEAT));
|
||||||
|
};
|
||||||
|
|
||||||
|
private static Appearance simpleAlpha(Color base, float shine, String resource) {
|
||||||
|
return new Appearance(
|
||||||
|
base,
|
||||||
|
shine,
|
||||||
|
new Decal(
|
||||||
|
new Coordinate(0, 0),
|
||||||
|
new Coordinate(0, 0),
|
||||||
|
new Coordinate(1, 1),
|
||||||
|
0,
|
||||||
|
new ResourceDecalImage(resource), EdgeMode.REPEAT));
|
||||||
|
};
|
||||||
|
|
||||||
|
private static Appearance BALSA = simple("/datafiles/textures/balsa.png");
|
||||||
|
private static Appearance WOOD = simple("/datafiles/textures/wood.png");
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private static Appearance CARDBOARD = simple("/datafiles/textures/cardboard.png");
|
||||||
|
private static Appearance HARDBOARD = simple("/datafiles/textures/hardboard.png");
|
||||||
|
private static Appearance WADDING = simple("/datafiles/textures/wadding.png");
|
||||||
|
private static Appearance CHUTE = simple("/datafiles/textures/chute.png");
|
||||||
|
|
||||||
|
|
||||||
|
private static final Appearance ESTES_BT = simpleAlpha(new Color(212, 185, 145), .3f, "/datafiles/textures/spiral-wound-alpha.png");
|
||||||
|
private static final Appearance ESTES_IT = simpleAlpha(new Color(168, 146, 116), .1f, "/datafiles/textures/spiral-wound-alpha.png");
|
||||||
|
private static final Appearance WHITE_BT = simpleAlpha(new Color(240, 240, 240), .3f, "/datafiles/textures/spiral-wound-alpha.png");
|
||||||
|
|
||||||
|
private static Appearance ESTES_MOTOR = simple("/datafiles/textures/motors/estes.png");
|
||||||
|
private static Appearance AEROTECH_MOTOR = simple("/datafiles/textures/motors/aerotech.png");
|
||||||
|
private static Appearance REUSABLE_MOTOR = simpleAlpha(new Color(195, 60, 50), .6f, "/datafiles/textures/motors/reusable.png");
|
||||||
|
|
||||||
|
private static HashMap<Color, Appearance> plastics = new HashMap<Color, Appearance>();
|
||||||
|
|
||||||
|
private static Appearance getPlastic(Color c) {
|
||||||
|
if (!plastics.containsKey(c)) {
|
||||||
|
plastics.put(c, new Appearance(c, .3));
|
||||||
|
}
|
||||||
|
return plastics.get(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Appearance getDefaultAppearance(RocketComponent c) {
|
||||||
|
if (c instanceof BodyTube)
|
||||||
|
return ESTES_BT;
|
||||||
|
if (c instanceof InnerTube || c instanceof TubeCoupler)
|
||||||
|
return ESTES_IT;
|
||||||
|
if (c instanceof FinSet)
|
||||||
|
return BALSA;
|
||||||
|
if (c instanceof LaunchLug)
|
||||||
|
return WHITE_BT;
|
||||||
|
if (c instanceof Transition)
|
||||||
|
return getPlastic(new Color(255, 255, 255));
|
||||||
|
if (c instanceof RadiusRingComponent)
|
||||||
|
return WOOD;
|
||||||
|
if (c instanceof Parachute)
|
||||||
|
return CHUTE;
|
||||||
|
if (c instanceof EngineBlock)
|
||||||
|
return HARDBOARD;
|
||||||
|
if (c instanceof MassObject)
|
||||||
|
return WADDING;
|
||||||
|
|
||||||
|
return Appearance.MISSING;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Appearance getDefaultAppearance(Motor m) {
|
||||||
|
if (m instanceof ThrustCurveMotor) {
|
||||||
|
ThrustCurveMotor tcm = (ThrustCurveMotor) m;
|
||||||
|
if ("Estes".equals(tcm.getManufacturer().getSimpleName())) {
|
||||||
|
return ESTES_MOTOR;
|
||||||
|
}
|
||||||
|
if ("AeroTech".equals(tcm.getManufacturer().getSimpleName())) {
|
||||||
|
return AEROTECH_MOTOR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return REUSABLE_MOTOR;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package net.sf.openrocket.appearance.defaults;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.EventListener;
|
||||||
|
|
||||||
|
import net.sf.openrocket.appearance.DecalImage;
|
||||||
|
import net.sf.openrocket.document.Attachment;
|
||||||
|
|
||||||
|
|
||||||
|
class ResourceDecalImage implements DecalImage {
|
||||||
|
|
||||||
|
final String resource;
|
||||||
|
|
||||||
|
ResourceDecalImage(final String resource) {
|
||||||
|
this.resource = resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getBytes() throws FileNotFoundException, IOException {
|
||||||
|
return this.getClass().getResourceAsStream(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exportImage(File file, boolean watchForChanges) throws IOException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(Attachment a) {
|
||||||
|
return this.hashCode() - a.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addChangeListener(EventListener listener) {
|
||||||
|
//Unimplemented, this can not change
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeChangeListener(EventListener listener) {
|
||||||
|
//Unimplemented, this can not change
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -23,6 +23,7 @@ import javax.swing.SwingUtilities;
|
|||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import net.sf.openrocket.appearance.AppearanceBuilder;
|
import net.sf.openrocket.appearance.AppearanceBuilder;
|
||||||
import net.sf.openrocket.appearance.Decal.EdgeMode;
|
import net.sf.openrocket.appearance.Decal.EdgeMode;
|
||||||
|
import net.sf.openrocket.appearance.defaults.DefaultAppearance;
|
||||||
import net.sf.openrocket.document.OpenRocketDocument;
|
import net.sf.openrocket.document.OpenRocketDocument;
|
||||||
import net.sf.openrocket.gui.SpinnerEditor;
|
import net.sf.openrocket.gui.SpinnerEditor;
|
||||||
import net.sf.openrocket.gui.adaptors.BooleanModel;
|
import net.sf.openrocket.gui.adaptors.BooleanModel;
|
||||||
@ -116,7 +117,7 @@ public class AppearancePanel extends JPanel {
|
|||||||
public AppearancePanel(final OpenRocketDocument document, final RocketComponent c) {
|
public AppearancePanel(final OpenRocketDocument document, final RocketComponent c) {
|
||||||
super(new MigLayout("fill", "[150][grow][150][grow]"));
|
super(new MigLayout("fill", "[150][grow][150][grow]"));
|
||||||
|
|
||||||
ab = new AppearanceBuilder(c.getAppearance());
|
ab = new AppearanceBuilder(c.getAppearance() != null ? c.getAppearance() : DefaultAppearance.getDefaultAppearance(c));
|
||||||
|
|
||||||
net.sf.openrocket.util.Color figureColor = c.getColor();
|
net.sf.openrocket.util.Color figureColor = c.getColor();
|
||||||
if (figureColor == null) {
|
if (figureColor == null) {
|
||||||
@ -151,6 +152,7 @@ public class AppearancePanel extends JPanel {
|
|||||||
figureColorButton.addActionListener(new ColorActionListener(c, "Color"));
|
figureColorButton.addActionListener(new ColorActionListener(c, "Color"));
|
||||||
colorButton.addActionListener(new ColorActionListener(ab, "Paint"));
|
colorButton.addActionListener(new ColorActionListener(ab, "Paint"));
|
||||||
|
|
||||||
|
BooleanModel mDefault = new BooleanModel(c.getAppearance() == null);
|
||||||
BooleanModel fDefault = new BooleanModel(c.getColor() == null);
|
BooleanModel fDefault = new BooleanModel(c.getColor() == null);
|
||||||
|
|
||||||
|
|
||||||
@ -215,12 +217,26 @@ public class AppearancePanel extends JPanel {
|
|||||||
add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx");
|
add(new JSeparator(SwingConstants.HORIZONTAL), "span, wrap, growx");
|
||||||
|
|
||||||
{// Texture Header Row
|
{// Texture Header Row
|
||||||
add(new StyledLabel(trans.get("AppearanceCfg.lbl.Appearance"), Style.BOLD), "wrap");
|
add(new StyledLabel(trans.get("AppearanceCfg.lbl.Appearance"), Style.BOLD));
|
||||||
|
final JCheckBox materialDefault = new JCheckBox(mDefault);
|
||||||
|
materialDefault.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if (materialDefault.isSelected()) {
|
||||||
|
c.setAppearance(null);
|
||||||
|
} else {
|
||||||
|
c.setAppearance(ab.getAppearance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
materialDefault.setText(trans.get("AppearanceCfg.lbl.Usedefault"));
|
||||||
|
add(materialDefault, "wrap");
|
||||||
}
|
}
|
||||||
|
|
||||||
{// Texture File
|
{// Texture File
|
||||||
add(new JLabel(trans.get("AppearanceCfg.lbl.Texture")));
|
add(new JLabel(trans.get("AppearanceCfg.lbl.Texture")));
|
||||||
JPanel p = new JPanel(new MigLayout("fill, ins 0", "[grow][]"));
|
JPanel p = new JPanel(new MigLayout("fill, ins 0", "[grow][]"));
|
||||||
|
mDefault.addEnableComponent(textureDropDown, false);
|
||||||
p.add(textureDropDown, "grow");
|
p.add(textureDropDown, "grow");
|
||||||
add(p, "span 3, growx, wrap");
|
add(p, "span 3, growx, wrap");
|
||||||
final JButton editBtn = new JButton(trans.get("AppearanceCfg.but.edit"));
|
final JButton editBtn = new JButton(trans.get("AppearanceCfg.but.edit"));
|
||||||
@ -243,12 +259,13 @@ public class AppearancePanel extends JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
mDefault.addEnableComponent(editBtn, false);
|
||||||
p.add(editBtn);
|
p.add(editBtn);
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Color
|
{ // Color
|
||||||
add(new JLabel(trans.get("AppearanceCfg.lbl.color.Color")));
|
add(new JLabel(trans.get("AppearanceCfg.lbl.color.Color")));
|
||||||
//mDefault.addEnableComponent(colorButton, false);
|
mDefault.addEnableComponent(colorButton, false);
|
||||||
add(colorButton);
|
add(colorButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,11 +275,13 @@ public class AppearancePanel extends JPanel {
|
|||||||
add(new JLabel("x:"), "split 4");
|
add(new JLabel("x:"), "split 4");
|
||||||
JSpinner scaleU = new JSpinner(new DoubleModel(ab, "ScaleX", TEXTURE_UNIT).getSpinnerModel());
|
JSpinner scaleU = new JSpinner(new DoubleModel(ab, "ScaleX", TEXTURE_UNIT).getSpinnerModel());
|
||||||
scaleU.setEditor(new SpinnerEditor(scaleU));
|
scaleU.setEditor(new SpinnerEditor(scaleU));
|
||||||
|
mDefault.addEnableComponent(scaleU, false);
|
||||||
add(scaleU, "w 40");
|
add(scaleU, "w 40");
|
||||||
|
|
||||||
add(new JLabel("y:"));
|
add(new JLabel("y:"));
|
||||||
JSpinner scaleV = new JSpinner(new DoubleModel(ab, "ScaleY", TEXTURE_UNIT).getSpinnerModel());
|
JSpinner scaleV = new JSpinner(new DoubleModel(ab, "ScaleY", TEXTURE_UNIT).getSpinnerModel());
|
||||||
scaleV.setEditor(new SpinnerEditor(scaleV));
|
scaleV.setEditor(new SpinnerEditor(scaleV));
|
||||||
|
mDefault.addEnableComponent(scaleV, false);
|
||||||
add(scaleV, "wrap, w 40");
|
add(scaleV, "wrap, w 40");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,6 +293,10 @@ public class AppearancePanel extends JPanel {
|
|||||||
JSlider slide = new JSlider(shineModel.getSliderModel(0, 1));
|
JSlider slide = new JSlider(shineModel.getSliderModel(0, 1));
|
||||||
UnitSelector unit = new UnitSelector(shineModel);
|
UnitSelector unit = new UnitSelector(shineModel);
|
||||||
|
|
||||||
|
mDefault.addEnableComponent(slide, false);
|
||||||
|
mDefault.addEnableComponent(spin, false);
|
||||||
|
mDefault.addEnableComponent(unit, false);
|
||||||
|
|
||||||
add(spin, "split 3, w 50");
|
add(spin, "split 3, w 50");
|
||||||
add(unit);
|
add(unit);
|
||||||
add(slide, "w 50");
|
add(slide, "w 50");
|
||||||
@ -286,11 +309,13 @@ public class AppearancePanel extends JPanel {
|
|||||||
add(new JLabel("x:"), "split 4");
|
add(new JLabel("x:"), "split 4");
|
||||||
JSpinner offsetU = new JSpinner(new DoubleModel(ab, "OffsetU", TEXTURE_UNIT).getSpinnerModel());
|
JSpinner offsetU = new JSpinner(new DoubleModel(ab, "OffsetU", TEXTURE_UNIT).getSpinnerModel());
|
||||||
offsetU.setEditor(new SpinnerEditor(offsetU));
|
offsetU.setEditor(new SpinnerEditor(offsetU));
|
||||||
|
mDefault.addEnableComponent(offsetU, false);
|
||||||
add(offsetU, "w 40");
|
add(offsetU, "w 40");
|
||||||
|
|
||||||
add(new JLabel("y:"));
|
add(new JLabel("y:"));
|
||||||
JSpinner offsetV = new JSpinner(new DoubleModel(ab, "OffsetV", TEXTURE_UNIT).getSpinnerModel());
|
JSpinner offsetV = new JSpinner(new DoubleModel(ab, "OffsetV", TEXTURE_UNIT).getSpinnerModel());
|
||||||
offsetV.setEditor(new SpinnerEditor(offsetV));
|
offsetV.setEditor(new SpinnerEditor(offsetV));
|
||||||
|
mDefault.addEnableComponent(offsetV, false);
|
||||||
add(offsetV, "wrap, w 40");
|
add(offsetV, "wrap, w 40");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,6 +324,7 @@ public class AppearancePanel extends JPanel {
|
|||||||
EdgeMode[] list = new EdgeMode[EdgeMode.values().length + 1];
|
EdgeMode[] list = new EdgeMode[EdgeMode.values().length + 1];
|
||||||
System.arraycopy(EdgeMode.values(), 0, list, 1, EdgeMode.values().length);
|
System.arraycopy(EdgeMode.values(), 0, list, 1, EdgeMode.values().length);
|
||||||
JComboBox combo = new JComboBox(new EnumModel<EdgeMode>(ab, "EdgeMode", list));
|
JComboBox combo = new JComboBox(new EnumModel<EdgeMode>(ab, "EdgeMode", list));
|
||||||
|
mDefault.addEnableComponent(combo, false);
|
||||||
add(combo);
|
add(combo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,9 +334,11 @@ public class AppearancePanel extends JPanel {
|
|||||||
DoubleModel rotationModel = new DoubleModel(ab, "Rotation", UnitGroup.UNITS_ANGLE);
|
DoubleModel rotationModel = new DoubleModel(ab, "Rotation", UnitGroup.UNITS_ANGLE);
|
||||||
JSpinner rotation = new JSpinner(rotationModel.getSpinnerModel());
|
JSpinner rotation = new JSpinner(rotationModel.getSpinnerModel());
|
||||||
rotation.setEditor(new SpinnerEditor(rotation));
|
rotation.setEditor(new SpinnerEditor(rotation));
|
||||||
|
mDefault.addEnableComponent(rotation, false);
|
||||||
add(rotation, "split 3, w 50");
|
add(rotation, "split 3, w 50");
|
||||||
add(new UnitSelector(rotationModel));
|
add(new UnitSelector(rotationModel));
|
||||||
BasicSlider bs = new BasicSlider(rotationModel.getSliderModel(-Math.PI, Math.PI));
|
BasicSlider bs = new BasicSlider(rotationModel.getSliderModel(-Math.PI, Math.PI));
|
||||||
|
mDefault.addEnableComponent(bs, false);
|
||||||
add(bs, "w 50, wrap");
|
add(bs, "w 50, wrap");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ import javax.media.opengl.glu.GLUtessellatorCallback;
|
|||||||
import javax.media.opengl.glu.GLUtessellatorCallbackAdapter;
|
import javax.media.opengl.glu.GLUtessellatorCallbackAdapter;
|
||||||
|
|
||||||
import net.sf.openrocket.logging.LogHelper;
|
import net.sf.openrocket.logging.LogHelper;
|
||||||
|
import net.sf.openrocket.motor.Motor;
|
||||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||||
import net.sf.openrocket.rocketcomponent.EllipticalFinSet;
|
import net.sf.openrocket.rocketcomponent.EllipticalFinSet;
|
||||||
import net.sf.openrocket.rocketcomponent.FinSet;
|
import net.sf.openrocket.rocketcomponent.FinSet;
|
||||||
@ -314,10 +315,9 @@ public class ComponentRenderer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void renderMotor(final GL2 gl, final Coordinate c, double l, double r) {
|
public void renderMotor(final GL2 gl, final Coordinate c, Motor motor) {
|
||||||
final float outside[] = { 0.2f, 0.2f, 0.2f, 1.0f };
|
double l = motor.getLength();
|
||||||
gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_DIFFUSE, outside, 0);
|
double r = motor.getDiameter() / 2;
|
||||||
gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_AMBIENT, outside, 0);
|
|
||||||
|
|
||||||
gl.glPushMatrix();
|
gl.glPushMatrix();
|
||||||
|
|
||||||
@ -325,15 +325,48 @@ public class ComponentRenderer {
|
|||||||
|
|
||||||
gl.glRotated(90, 0, 1.0, 0);
|
gl.glRotated(90, 0, 1.0, 0);
|
||||||
|
|
||||||
|
gl.glMatrixMode(GL.GL_TEXTURE);
|
||||||
|
gl.glPushMatrix();
|
||||||
|
gl.glTranslated(0, .125, 0);
|
||||||
|
gl.glScaled(1, .75, 0);
|
||||||
|
|
||||||
glu.gluCylinder(q, r, r, l, LOD, 1);
|
glu.gluCylinder(q, r, r, l, LOD, 1);
|
||||||
|
|
||||||
glu.gluDisk(q, r, 0, LOD, 2);
|
gl.glPopMatrix();
|
||||||
|
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
|
||||||
|
|
||||||
|
{
|
||||||
|
final double da = (2.0f * Math.PI) / LOD;
|
||||||
|
final double dt = 1.0 / LOD;
|
||||||
|
gl.glBegin(GL.GL_TRIANGLE_STRIP);
|
||||||
|
gl.glNormal3d(0, 0, 1);
|
||||||
|
for (int i = 0; i < LOD + 1; i++) {
|
||||||
|
gl.glTexCoord2d(i * dt, .125);
|
||||||
|
gl.glVertex3d(r * Math.cos(da * i), r * Math.sin(da * i), 0);
|
||||||
|
gl.glTexCoord2d(i * dt, 0);
|
||||||
|
gl.glVertex3d(0, 0, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
gl.glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
gl.glTranslated(0, 0, l);
|
gl.glTranslated(0, 0, l);
|
||||||
gl.glRotated(180, 0, 1.0, 0);
|
gl.glRotated(180, 0, 1.0, 0);
|
||||||
|
|
||||||
glu.gluDisk(q, r, 0, LOD, 2);
|
{
|
||||||
|
final double da = (2.0f * Math.PI) / LOD;
|
||||||
|
final double dt = 1.0 / LOD;
|
||||||
|
gl.glBegin(GL.GL_TRIANGLE_STRIP);
|
||||||
|
gl.glNormal3d(0, 0, 1);
|
||||||
|
for (int i = 0; i < LOD + 1; i++) {
|
||||||
|
gl.glTexCoord2d(i * dt, .875);
|
||||||
|
gl.glVertex3d(r * Math.cos(da * i), r * Math.sin(da * i), 0);
|
||||||
|
gl.glTexCoord2d(i * dt, 1);
|
||||||
|
gl.glVertex3d(0, 0, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
gl.glEnd();
|
||||||
|
}
|
||||||
gl.glPopMatrix();
|
gl.glPopMatrix();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import javax.media.opengl.GL2ES1;
|
|||||||
import javax.media.opengl.GLAutoDrawable;
|
import javax.media.opengl.GLAutoDrawable;
|
||||||
import javax.media.opengl.fixedfunc.GLLightingFunc;
|
import javax.media.opengl.fixedfunc.GLLightingFunc;
|
||||||
|
|
||||||
|
import net.sf.openrocket.motor.Motor;
|
||||||
import net.sf.openrocket.rocketcomponent.BodyTube;
|
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||||
import net.sf.openrocket.rocketcomponent.ExternalComponent;
|
import net.sf.openrocket.rocketcomponent.ExternalComponent;
|
||||||
import net.sf.openrocket.rocketcomponent.NoseCone;
|
import net.sf.openrocket.rocketcomponent.NoseCone;
|
||||||
@ -16,6 +17,7 @@ import net.sf.openrocket.rocketcomponent.SymmetricComponent;
|
|||||||
import net.sf.openrocket.rocketcomponent.Transition;
|
import net.sf.openrocket.rocketcomponent.Transition;
|
||||||
import net.sf.openrocket.startup.Application;
|
import net.sf.openrocket.startup.Application;
|
||||||
import net.sf.openrocket.util.Color;
|
import net.sf.openrocket.util.Color;
|
||||||
|
import net.sf.openrocket.util.Coordinate;
|
||||||
|
|
||||||
public class FigureRenderer extends RocketRenderer {
|
public class FigureRenderer extends RocketRenderer {
|
||||||
private final float[] color = new float[4];
|
private final float[] color = new float[4];
|
||||||
@ -156,4 +158,13 @@ public class FigureRenderer extends RocketRenderer {
|
|||||||
out[2] = Math.max(0.2f, (float) color.getBlue() / 255f) * 2;
|
out[2] = Math.max(0.2f, (float) color.getBlue() / 255f) * 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void renderMotor(GL2 gl, Coordinate c, Motor motor) {
|
||||||
|
final float outside[] = { 0.2f, 0.2f, 0.2f, 1.0f };
|
||||||
|
gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_DIFFUSE, outside, 0);
|
||||||
|
gl.glMaterialfv(GL.GL_FRONT, GLLightingFunc.GL_AMBIENT, outside, 0);
|
||||||
|
super.renderMotor(gl, c, motor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,12 @@ import javax.media.opengl.fixedfunc.GLMatrixFunc;
|
|||||||
|
|
||||||
import net.sf.openrocket.appearance.Appearance;
|
import net.sf.openrocket.appearance.Appearance;
|
||||||
import net.sf.openrocket.appearance.Decal;
|
import net.sf.openrocket.appearance.Decal;
|
||||||
|
import net.sf.openrocket.appearance.defaults.DefaultAppearance;
|
||||||
import net.sf.openrocket.document.OpenRocketDocument;
|
import net.sf.openrocket.document.OpenRocketDocument;
|
||||||
|
import net.sf.openrocket.motor.Motor;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
import net.sf.openrocket.util.Color;
|
import net.sf.openrocket.util.Color;
|
||||||
|
import net.sf.openrocket.util.Coordinate;
|
||||||
|
|
||||||
import com.jogamp.opengl.util.texture.Texture;
|
import com.jogamp.opengl.util.texture.Texture;
|
||||||
import com.jogamp.opengl.util.texture.TextureData;
|
import com.jogamp.opengl.util.texture.TextureData;
|
||||||
@ -92,8 +95,26 @@ public class RealisticRenderer extends RocketRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void renderComponent(GL2 gl, RocketComponent c, float alpha) {
|
protected void renderMotor(final GL2 gl, final Coordinate c, final Motor motor) {
|
||||||
final Appearance a = getAppearance(c);
|
render(gl, new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
cr.renderMotor(gl, c, motor);
|
||||||
|
}
|
||||||
|
}, DefaultAppearance.getDefaultAppearance(motor), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void renderComponent(final GL2 gl, final RocketComponent c, final float alpha) {
|
||||||
|
render(gl, new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
cr.renderGeometry(gl, c);
|
||||||
|
}
|
||||||
|
}, getAppearance(c), alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void render(GL2 gl, Runnable g, Appearance a, float alpha) {
|
||||||
final Decal t = a.getTexture();
|
final Decal t = a.getTexture();
|
||||||
final Texture tex = getTexture(t);
|
final Texture tex = getTexture(t);
|
||||||
|
|
||||||
@ -116,7 +137,7 @@ public class RealisticRenderer extends RocketRenderer {
|
|||||||
gl.glMaterialfv(GL.GL_BACK, GLLightingFunc.GL_SPECULAR, colorBlack, 0);
|
gl.glMaterialfv(GL.GL_BACK, GLLightingFunc.GL_SPECULAR, colorBlack, 0);
|
||||||
gl.glMateriali(GL.GL_BACK, GLLightingFunc.GL_SHININESS, 0);
|
gl.glMateriali(GL.GL_BACK, GLLightingFunc.GL_SHININESS, 0);
|
||||||
|
|
||||||
cr.renderGeometry(gl, c);
|
g.run();
|
||||||
|
|
||||||
if (t != null && tex != null) {
|
if (t != null && tex != null) {
|
||||||
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR);
|
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR_MIPMAP_LINEAR);
|
||||||
@ -155,7 +176,7 @@ public class RealisticRenderer extends RocketRenderer {
|
|||||||
gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotrophy);
|
gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotrophy);
|
||||||
}
|
}
|
||||||
|
|
||||||
cr.renderGeometry(gl, c);
|
g.run();
|
||||||
|
|
||||||
if (t.getEdgeMode() == Decal.EdgeMode.STICKER) {
|
if (t.getEdgeMode() == Decal.EdgeMode.STICKER) {
|
||||||
gl.glDepthFunc(GL.GL_LESS);
|
gl.glDepthFunc(GL.GL_LESS);
|
||||||
@ -220,10 +241,10 @@ public class RealisticRenderer extends RocketRenderer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Appearance getAppearance(RocketComponent c) {
|
protected Appearance getAppearance(RocketComponent c) {
|
||||||
Appearance ret = c.getAppearance();
|
Appearance ret = c.getAppearance();
|
||||||
if (ret == null) {
|
if (ret == null) {
|
||||||
ret = Appearance.MISSING;
|
ret = DefaultAppearance.getDefaultAppearance(c);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -51,8 +51,9 @@ import com.jogamp.opengl.util.awt.Overlay;
|
|||||||
*/
|
*/
|
||||||
public class RocketFigure3d extends JPanel implements GLEventListener {
|
public class RocketFigure3d extends JPanel implements GLEventListener {
|
||||||
|
|
||||||
public static final int TYPE_REALISTIC = 0;
|
public static final int TYPE_FIGURE = 0;
|
||||||
public static final int TYPE_FIGURE = 1;
|
public static final int TYPE_UNFINISHED = 1;
|
||||||
|
public static final int TYPE_FINISHED = 2;
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private static final LogHelper log = Application.getLogger();
|
private static final LogHelper log = Application.getLogger();
|
||||||
@ -67,8 +68,8 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
private static double fovX = Double.NaN;
|
private static double fovX = Double.NaN;
|
||||||
private static final int CARET_SIZE = 20;
|
private static final int CARET_SIZE = 20;
|
||||||
|
|
||||||
private OpenRocketDocument document;
|
private final OpenRocketDocument document;
|
||||||
private Configuration configuration;
|
private final Configuration configuration;
|
||||||
private GLCanvas canvas;
|
private GLCanvas canvas;
|
||||||
|
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
|
|
||||||
RocketRenderer rr = new FigureRenderer();
|
RocketRenderer rr = new FigureRenderer();
|
||||||
|
|
||||||
public RocketFigure3d(OpenRocketDocument document, Configuration config) {
|
public RocketFigure3d(final OpenRocketDocument document, final Configuration config) {
|
||||||
this.document = document;
|
this.document = document;
|
||||||
this.configuration = config;
|
this.configuration = config;
|
||||||
this.setLayout(new BorderLayout());
|
this.setLayout(new BorderLayout());
|
||||||
@ -131,10 +132,10 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
log.debug("Setting up GL capabilities...");
|
log.debug("Setting up GL capabilities...");
|
||||||
|
|
||||||
log.verbose("GL - Getting Default Profile");
|
log.verbose("GL - Getting Default Profile");
|
||||||
GLProfile glp = GLProfile.get(GLProfile.GL2);
|
final GLProfile glp = GLProfile.get(GLProfile.GL2);
|
||||||
|
|
||||||
log.verbose("GL - creating GLCapabilities");
|
log.verbose("GL - creating GLCapabilities");
|
||||||
GLCapabilities caps = new GLCapabilities(glp);
|
final GLCapabilities caps = new GLCapabilities(glp);
|
||||||
|
|
||||||
log.verbose("GL - setSampleBuffers");
|
log.verbose("GL - setSampleBuffers");
|
||||||
caps.setSampleBuffers(true);
|
caps.setSampleBuffers(true);
|
||||||
@ -217,21 +218,21 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
MouseEvent pressEvent;
|
MouseEvent pressEvent;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(final MouseEvent e) {
|
||||||
lastX = e.getX();
|
lastX = e.getX();
|
||||||
lastY = e.getY();
|
lastY = e.getY();
|
||||||
pressEvent = e;
|
pressEvent = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseClicked(MouseEvent e) {
|
public void mouseClicked(final MouseEvent e) {
|
||||||
pickPoint = new Point(lastX, canvas.getHeight() - lastY);
|
pickPoint = new Point(lastX, canvas.getHeight() - lastY);
|
||||||
pickEvent = e;
|
pickEvent = e;
|
||||||
internalRepaint();
|
internalRepaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseDragged(MouseEvent e) {
|
public void mouseDragged(final MouseEvent e) {
|
||||||
int dx = lastX - e.getX();
|
int dx = lastX - e.getX();
|
||||||
int dy = lastY - e.getY();
|
int dy = lastY - e.getY();
|
||||||
lastX = e.getX();
|
lastX = e.getX();
|
||||||
@ -257,13 +258,9 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
canvas.addMouseListener(a);
|
canvas.addMouseListener(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConfiguration(Configuration configuration) {
|
|
||||||
this.configuration = configuration;
|
|
||||||
updateFigure();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void display(GLAutoDrawable drawable) {
|
public void display(final GLAutoDrawable drawable) {
|
||||||
GL2 gl = drawable.getGL().getGL2();
|
GL2 gl = drawable.getGL().getGL2();
|
||||||
GLU glu = new GLU();
|
GLU glu = new GLU();
|
||||||
|
|
||||||
@ -307,7 +304,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void drawCarets(GL2 gl, GLU glu) {
|
private void drawCarets(final GL2 gl, final GLU glu) {
|
||||||
final Graphics2D og2d = caretOverlay.createGraphics();
|
final Graphics2D og2d = caretOverlay.createGraphics();
|
||||||
setRenderingHints(og2d);
|
setRenderingHints(og2d);
|
||||||
|
|
||||||
@ -355,7 +352,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
* Re-blits the overlay every frame. Only re-renders the overlay
|
* Re-blits the overlay every frame. Only re-renders the overlay
|
||||||
* when needed.
|
* when needed.
|
||||||
*/
|
*/
|
||||||
private void drawExtras(GL2 gl, GLU glu) {
|
private void drawExtras(final GL2 gl, final GLU glu) {
|
||||||
//Only re-render if needed
|
//Only re-render if needed
|
||||||
// redrawExtras: Some external change (new simulation data) means
|
// redrawExtras: Some external change (new simulation data) means
|
||||||
// the data is out of date.
|
// the data is out of date.
|
||||||
@ -391,17 +388,17 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose(GLAutoDrawable drawable) {
|
public void dispose(final GLAutoDrawable drawable) {
|
||||||
log.verbose("GL - dispose() called");
|
log.verbose("GL - dispose() called");
|
||||||
rr.dispose(drawable);
|
rr.dispose(drawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(GLAutoDrawable drawable) {
|
public void init(final GLAutoDrawable drawable) {
|
||||||
log.verbose("GL - init()");
|
log.verbose("GL - init()");
|
||||||
rr.init(drawable);
|
rr.init(drawable);
|
||||||
|
|
||||||
GL2 gl = drawable.getGL().getGL2();
|
final GL2 gl = drawable.getGL().getGL2();
|
||||||
gl.glClearDepth(1.0f); // clear z-buffer to the farthest
|
gl.glClearDepth(1.0f); // clear z-buffer to the farthest
|
||||||
|
|
||||||
gl.glDepthFunc(GL.GL_LESS); // the type of depth test to do
|
gl.glDepthFunc(GL.GL_LESS); // the type of depth test to do
|
||||||
@ -426,12 +423,12 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
|
public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int w, final int h) {
|
||||||
log.verbose("GL - reshape()");
|
log.verbose("GL - reshape()");
|
||||||
GL2 gl = drawable.getGL().getGL2();
|
final GL2 gl = drawable.getGL().getGL2();
|
||||||
GLU glu = new GLU();
|
final GLU glu = new GLU();
|
||||||
|
|
||||||
double ratio = (double) w / (double) h;
|
final double ratio = (double) w / (double) h;
|
||||||
fovX = fovY * ratio;
|
fovX = fovY * ratio;
|
||||||
|
|
||||||
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
|
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
|
||||||
@ -461,8 +458,8 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
if (cachedBounds != null) {
|
if (cachedBounds != null) {
|
||||||
return cachedBounds;
|
return cachedBounds;
|
||||||
} else {
|
} else {
|
||||||
Bounds b = new Bounds();
|
final Bounds b = new Bounds();
|
||||||
Collection<Coordinate> bounds = configuration.getBounds();
|
final Collection<Coordinate> bounds = configuration.getBounds();
|
||||||
for (Coordinate c : bounds) {
|
for (Coordinate c : bounds) {
|
||||||
b.xMax = Math.max(b.xMax, c.x);
|
b.xMax = Math.max(b.xMax, c.x);
|
||||||
b.xMin = Math.min(b.xMin, c.x);
|
b.xMin = Math.min(b.xMin, c.x);
|
||||||
@ -484,21 +481,21 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupView(GL2 gl, GLU glu) {
|
private void setupView(final GL2 gl, final GLU glu) {
|
||||||
gl.glLoadIdentity();
|
gl.glLoadIdentity();
|
||||||
|
|
||||||
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_POSITION,
|
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_POSITION,
|
||||||
lightPosition, 0);
|
lightPosition, 0);
|
||||||
|
|
||||||
// Get the bounds
|
// Get the bounds
|
||||||
Bounds b = calculateBounds();
|
final Bounds b = calculateBounds();
|
||||||
|
|
||||||
// Calculate the distance needed to fit the bounds in both the X and Y
|
// Calculate the distance needed to fit the bounds in both the X and Y
|
||||||
// direction
|
// direction
|
||||||
// Add 10% for space around it.
|
// Add 10% for space around it.
|
||||||
double dX = (b.xSize * 1.2 / 2.0)
|
final double dX = (b.xSize * 1.2 / 2.0)
|
||||||
/ Math.tan(Math.toRadians(fovX / 2.0));
|
/ Math.tan(Math.toRadians(fovX / 2.0));
|
||||||
double dY = (b.rMax * 2.0 * 1.2 / 2.0)
|
final double dY = (b.rMax * 2.0 * 1.2 / 2.0)
|
||||||
/ Math.tan(Math.toRadians(fovY / 2.0));
|
/ Math.tan(Math.toRadians(fovY / 2.0));
|
||||||
|
|
||||||
// Move back the greater of the 2 distances
|
// Move back the greater of the 2 distances
|
||||||
@ -551,7 +548,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
|
|
||||||
private Set<RocketComponent> selection = new HashSet<RocketComponent>();
|
private Set<RocketComponent> selection = new HashSet<RocketComponent>();
|
||||||
|
|
||||||
public void setSelection(RocketComponent[] selection) {
|
public void setSelection(final RocketComponent[] selection) {
|
||||||
this.selection.clear();
|
this.selection.clear();
|
||||||
if (selection != null) {
|
if (selection != null) {
|
||||||
for (RocketComponent c : selection)
|
for (RocketComponent c : selection)
|
||||||
@ -560,14 +557,14 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
internalRepaint();
|
internalRepaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setRoll(double rot) {
|
private void setRoll(final double rot) {
|
||||||
if (MathUtil.equals(roll, rot))
|
if (MathUtil.equals(roll, rot))
|
||||||
return;
|
return;
|
||||||
this.roll = MathUtil.reduce360(rot);
|
this.roll = MathUtil.reduce360(rot);
|
||||||
internalRepaint();
|
internalRepaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setYaw(double rot) {
|
private void setYaw(final double rot) {
|
||||||
if (MathUtil.equals(yaw, rot))
|
if (MathUtil.equals(yaw, rot))
|
||||||
return;
|
return;
|
||||||
this.yaw = MathUtil.reduce360(rot);
|
this.yaw = MathUtil.reduce360(rot);
|
||||||
@ -576,16 +573,16 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
|
|
||||||
// ///////////// Extra methods
|
// ///////////// Extra methods
|
||||||
|
|
||||||
private Coordinate project(Coordinate c, GL2 gl, GLU glu) {
|
private Coordinate project(final Coordinate c, final GL2 gl, final GLU glu) {
|
||||||
double[] mvmatrix = new double[16];
|
final double[] mvmatrix = new double[16];
|
||||||
double[] projmatrix = new double[16];
|
final double[] projmatrix = new double[16];
|
||||||
int[] viewport = new int[4];
|
final int[] viewport = new int[4];
|
||||||
|
|
||||||
gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
|
gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
|
||||||
gl.glGetDoublev(GLMatrixFunc.GL_MODELVIEW_MATRIX, mvmatrix, 0);
|
gl.glGetDoublev(GLMatrixFunc.GL_MODELVIEW_MATRIX, mvmatrix, 0);
|
||||||
gl.glGetDoublev(GLMatrixFunc.GL_PROJECTION_MATRIX, projmatrix, 0);
|
gl.glGetDoublev(GLMatrixFunc.GL_PROJECTION_MATRIX, projmatrix, 0);
|
||||||
|
|
||||||
double out[] = new double[4];
|
final double out[] = new double[4];
|
||||||
glu.gluProject(c.x, c.y, c.z, mvmatrix, 0, projmatrix, 0, viewport, 0,
|
glu.gluProject(c.x, c.y, c.z, mvmatrix, 0, projmatrix, 0, viewport, 0,
|
||||||
out, 0);
|
out, 0);
|
||||||
|
|
||||||
@ -596,22 +593,22 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
private Coordinate cp = new Coordinate(0, 0, 0);
|
private Coordinate cp = new Coordinate(0, 0, 0);
|
||||||
private Coordinate cg = new Coordinate(0, 0, 0);
|
private Coordinate cg = new Coordinate(0, 0, 0);
|
||||||
|
|
||||||
public void setCG(Coordinate cg) {
|
public void setCG(final Coordinate cg) {
|
||||||
this.cg = cg;
|
this.cg = cg;
|
||||||
redrawExtras = true;
|
redrawExtras = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCP(Coordinate cp) {
|
public void setCP(final Coordinate cp) {
|
||||||
this.cp = cp;
|
this.cp = cp;
|
||||||
redrawExtras = true;
|
redrawExtras = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRelativeExtra(FigureElement p) {
|
public void addRelativeExtra(final FigureElement p) {
|
||||||
relativeExtra.add(p);
|
relativeExtra.add(p);
|
||||||
redrawExtras = true;
|
redrawExtras = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeRelativeExtra(FigureElement p) {
|
public void removeRelativeExtra(final FigureElement p) {
|
||||||
relativeExtra.remove(p);
|
relativeExtra.remove(p);
|
||||||
redrawExtras = true;
|
redrawExtras = true;
|
||||||
}
|
}
|
||||||
@ -621,12 +618,12 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
redrawExtras = true;
|
redrawExtras = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAbsoluteExtra(FigureElement p) {
|
public void addAbsoluteExtra(final FigureElement p) {
|
||||||
absoluteExtra.add(p);
|
absoluteExtra.add(p);
|
||||||
redrawExtras = true;
|
redrawExtras = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAbsoluteExtra(FigureElement p) {
|
public void removeAbsoluteExtra(final FigureElement p) {
|
||||||
absoluteExtra.remove(p);
|
absoluteExtra.remove(p);
|
||||||
redrawExtras = true;
|
redrawExtras = true;
|
||||||
}
|
}
|
||||||
@ -654,8 +651,10 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
|
|||||||
rr.dispose(drawable);
|
rr.dispose(drawable);
|
||||||
if (t == TYPE_FIGURE) {
|
if (t == TYPE_FIGURE) {
|
||||||
rr = new FigureRenderer();
|
rr = new FigureRenderer();
|
||||||
} else {
|
} else if (t == TYPE_FINISHED) {
|
||||||
rr = new RealisticRenderer(document);
|
rr = new RealisticRenderer(document);
|
||||||
|
} else if (t == TYPE_UNFINISHED) {
|
||||||
|
rr = new UnfinishedRenderer(document);
|
||||||
}
|
}
|
||||||
rr.init(drawable);
|
rr.init(drawable);
|
||||||
return false;
|
return false;
|
||||||
|
@ -178,16 +178,19 @@ public abstract class RocketRenderer {
|
|||||||
MotorMount mount = iterator.next();
|
MotorMount mount = iterator.next();
|
||||||
Motor motor = mount.getMotor(motorID);
|
Motor motor = mount.getMotor(motorID);
|
||||||
double length = motor.getLength();
|
double length = motor.getLength();
|
||||||
double radius = motor.getDiameter() / 2;
|
|
||||||
|
|
||||||
Coordinate[] position = ((RocketComponent) mount).toAbsolute(new Coordinate(((RocketComponent) mount)
|
Coordinate[] position = ((RocketComponent) mount).toAbsolute(new Coordinate(((RocketComponent) mount)
|
||||||
.getLength() + mount.getMotorOverhang() - length));
|
.getLength() + mount.getMotorOverhang() - length));
|
||||||
|
|
||||||
for (int i = 0; i < position.length; i++) {
|
for (int i = 0; i < position.length; i++) {
|
||||||
cr.renderMotor(gl, position[i], length, radius);
|
renderMotor(gl, position[i], motor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void renderMotor(GL2 gl, Coordinate c, Motor motor) {
|
||||||
|
cr.renderMotor(gl, c, motor);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package net.sf.openrocket.gui.figure3d;
|
||||||
|
|
||||||
|
import net.sf.openrocket.appearance.Appearance;
|
||||||
|
import net.sf.openrocket.appearance.defaults.DefaultAppearance;
|
||||||
|
import net.sf.openrocket.document.OpenRocketDocument;
|
||||||
|
import net.sf.openrocket.rocketcomponent.BodyTube;
|
||||||
|
import net.sf.openrocket.rocketcomponent.InnerTube;
|
||||||
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
|
|
||||||
|
public class UnfinishedRenderer extends RealisticRenderer {
|
||||||
|
|
||||||
|
public UnfinishedRenderer(OpenRocketDocument document) {
|
||||||
|
super(document);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDrawnTransparent(RocketComponent c) {
|
||||||
|
return c instanceof BodyTube || c instanceof InnerTube;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Appearance getAppearance(RocketComponent c) {
|
||||||
|
return DefaultAppearance.getDefaultAppearance(c);
|
||||||
|
}
|
||||||
|
}
|
@ -91,16 +91,21 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
|
|
||||||
private static final Translator trans = Application.getTranslator();
|
private static final Translator trans = Application.getTranslator();
|
||||||
|
|
||||||
/*RocketPanel.FigTypeAct.Sideview = Side view
|
public static enum VIEW_TYPE {
|
||||||
RocketPanel.FigTypeAct.Backview = Back view
|
Sideview(false, RocketFigure.TYPE_SIDE),
|
||||||
RocketPanel.FigViewAct.3DFigure = 3D Figure
|
Backview(false, RocketFigure.TYPE_BACK),
|
||||||
RocketPanel.FigViewAct.3DRealistic = 3D Realistic*/
|
Figure3D(true, RocketFigure3d.TYPE_FIGURE),
|
||||||
|
Unfinished(true, RocketFigure3d.TYPE_UNFINISHED),
|
||||||
|
Finished(true, RocketFigure3d.TYPE_FINISHED);
|
||||||
|
|
||||||
|
public final boolean is3d;
|
||||||
|
private final int type;
|
||||||
|
|
||||||
|
private VIEW_TYPE(final boolean is3d, final int type) {
|
||||||
|
this.is3d = is3d;
|
||||||
|
this.type = type;
|
||||||
|
};
|
||||||
|
|
||||||
private static enum VIEW_TYPE {
|
|
||||||
Sideview,
|
|
||||||
Backview,
|
|
||||||
Figure3D,
|
|
||||||
Realistic3D;
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return trans.get("RocketPanel.FigTypeAct." + super.toString());
|
return trans.get("RocketPanel.FigTypeAct." + super.toString());
|
||||||
@ -280,23 +285,12 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
|
|||||||
public void setSelectedItem(Object o) {
|
public void setSelectedItem(Object o) {
|
||||||
super.setSelectedItem(o);
|
super.setSelectedItem(o);
|
||||||
VIEW_TYPE v = (VIEW_TYPE) o;
|
VIEW_TYPE v = (VIEW_TYPE) o;
|
||||||
switch (v) {
|
if (v.is3d) {
|
||||||
case Sideview:
|
figure3d.setType(v.type);
|
||||||
figure.setType(RocketFigure.TYPE_SIDE);
|
|
||||||
go2D();
|
|
||||||
break;
|
|
||||||
case Backview:
|
|
||||||
figure.setType(RocketFigure.TYPE_BACK);
|
|
||||||
go2D();
|
|
||||||
break;
|
|
||||||
case Realistic3D:
|
|
||||||
figure3d.setType(RocketFigure3d.TYPE_REALISTIC);
|
|
||||||
go3D();
|
go3D();
|
||||||
break;
|
} else {
|
||||||
case Figure3D:
|
figure.setType(v.type);
|
||||||
figure3d.setType(RocketFigure3d.TYPE_FIGURE);
|
go2D();
|
||||||
go3D();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|