Merge pull request #39 from bkuker/kruland-integration-defaults

Add Default appearances
This commit is contained in:
Bill Kuker 2013-02-01 15:36:08 -08:00
commit 405f0db1b7
24 changed files with 390 additions and 106 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@ -47,7 +47,8 @@ RocketActions.MoveDownAct.ttip.Movedown = Move this component downwards.
RocketPanel.FigTypeAct.Sideview = Side view
RocketPanel.FigTypeAct.Backview = Back view
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:

View File

@ -10,19 +10,19 @@ import net.sf.openrocket.util.MathUtil;
* @author Bill Kuker <bkuker@billkuker.com>
*/
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 double shine;
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.shine = MathUtil.clamp(shine, 0, 1);
this.texture = texture;
}
Appearance(final Color paint, final double shine) {
public Appearance(final Color paint, final double shine) {
this.paint = paint;
this.shine = MathUtil.clamp(shine, 0, 1);
this.texture = null;

View File

@ -9,25 +9,27 @@ import net.sf.openrocket.util.Coordinate;
* @author Bill Kuker <bkuker@billkuker.com>
*/
public class Decal {
public static enum EdgeMode {
REPEAT("TextureWrap.Repeat"), MIRROR("TextureWrap.Mirror"), CLAMP("TextureWrap.Clamp"), STICKER("TextureWrap.Sticker");
private final String transName;
EdgeMode(final String name){
EdgeMode(final String name) {
this.transName = name;
}
@Override
public String toString(){
public String toString() {
return Application.getTranslator().get(transName);
}
}
private final Coordinate offset, center, scale;
private final double rotation;
private final DecalImage image;
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) {
this.offset = offset;
this.center = center;
@ -36,35 +38,35 @@ public class Decal {
this.image = image;
this.mode = mode;
}
public Coordinate getOffset() {
return offset;
}
public Coordinate getCenter() {
return center;
}
public Coordinate getScale() {
return scale;
}
public double getRotation() {
return rotation;
}
public EdgeMode getEdgeMode() {
return mode;
}
public DecalImage getImage() {
return image;
}
@Override
public String toString() {
return "Texture [offset=" + offset + ", center=" + center + ", scale=" + scale + ", rotation=" + rotation
+ ", image=" + image + "]";
}
}

View File

@ -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;
}
}

View File

@ -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
}
}

View File

@ -23,6 +23,7 @@ import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.appearance.AppearanceBuilder;
import net.sf.openrocket.appearance.Decal.EdgeMode;
import net.sf.openrocket.appearance.defaults.DefaultAppearance;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.BooleanModel;
@ -116,7 +117,7 @@ public class AppearancePanel extends JPanel {
public AppearancePanel(final OpenRocketDocument document, final RocketComponent c) {
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();
if (figureColor == null) {
@ -151,6 +152,7 @@ public class AppearancePanel extends JPanel {
figureColorButton.addActionListener(new ColorActionListener(c, "Color"));
colorButton.addActionListener(new ColorActionListener(ab, "Paint"));
BooleanModel mDefault = new BooleanModel(c.getAppearance() == 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");
{// 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
add(new JLabel(trans.get("AppearanceCfg.lbl.Texture")));
JPanel p = new JPanel(new MigLayout("fill, ins 0", "[grow][]"));
mDefault.addEnableComponent(textureDropDown, false);
p.add(textureDropDown, "grow");
add(p, "span 3, growx, wrap");
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);
}
{ // Color
add(new JLabel(trans.get("AppearanceCfg.lbl.color.Color")));
//mDefault.addEnableComponent(colorButton, false);
mDefault.addEnableComponent(colorButton, false);
add(colorButton);
}
@ -258,11 +275,13 @@ public class AppearancePanel extends JPanel {
add(new JLabel("x:"), "split 4");
JSpinner scaleU = new JSpinner(new DoubleModel(ab, "ScaleX", TEXTURE_UNIT).getSpinnerModel());
scaleU.setEditor(new SpinnerEditor(scaleU));
mDefault.addEnableComponent(scaleU, false);
add(scaleU, "w 40");
add(new JLabel("y:"));
JSpinner scaleV = new JSpinner(new DoubleModel(ab, "ScaleY", TEXTURE_UNIT).getSpinnerModel());
scaleV.setEditor(new SpinnerEditor(scaleV));
mDefault.addEnableComponent(scaleV, false);
add(scaleV, "wrap, w 40");
}
@ -274,6 +293,10 @@ public class AppearancePanel extends JPanel {
JSlider slide = new JSlider(shineModel.getSliderModel(0, 1));
UnitSelector unit = new UnitSelector(shineModel);
mDefault.addEnableComponent(slide, false);
mDefault.addEnableComponent(spin, false);
mDefault.addEnableComponent(unit, false);
add(spin, "split 3, w 50");
add(unit);
add(slide, "w 50");
@ -286,11 +309,13 @@ public class AppearancePanel extends JPanel {
add(new JLabel("x:"), "split 4");
JSpinner offsetU = new JSpinner(new DoubleModel(ab, "OffsetU", TEXTURE_UNIT).getSpinnerModel());
offsetU.setEditor(new SpinnerEditor(offsetU));
mDefault.addEnableComponent(offsetU, false);
add(offsetU, "w 40");
add(new JLabel("y:"));
JSpinner offsetV = new JSpinner(new DoubleModel(ab, "OffsetV", TEXTURE_UNIT).getSpinnerModel());
offsetV.setEditor(new SpinnerEditor(offsetV));
mDefault.addEnableComponent(offsetV, false);
add(offsetV, "wrap, w 40");
}
@ -299,6 +324,7 @@ public class AppearancePanel extends JPanel {
EdgeMode[] list = new EdgeMode[EdgeMode.values().length + 1];
System.arraycopy(EdgeMode.values(), 0, list, 1, EdgeMode.values().length);
JComboBox combo = new JComboBox(new EnumModel<EdgeMode>(ab, "EdgeMode", list));
mDefault.addEnableComponent(combo, false);
add(combo);
}
@ -308,9 +334,11 @@ public class AppearancePanel extends JPanel {
DoubleModel rotationModel = new DoubleModel(ab, "Rotation", UnitGroup.UNITS_ANGLE);
JSpinner rotation = new JSpinner(rotationModel.getSpinnerModel());
rotation.setEditor(new SpinnerEditor(rotation));
mDefault.addEnableComponent(rotation, false);
add(rotation, "split 3, w 50");
add(new UnitSelector(rotationModel));
BasicSlider bs = new BasicSlider(rotationModel.getSliderModel(-Math.PI, Math.PI));
mDefault.addEnableComponent(bs, false);
add(bs, "w 50, wrap");
}

View File

@ -15,6 +15,7 @@ import javax.media.opengl.glu.GLUtessellatorCallback;
import javax.media.opengl.glu.GLUtessellatorCallbackAdapter;
import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.EllipticalFinSet;
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) {
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);
public void renderMotor(final GL2 gl, final Coordinate c, Motor motor) {
double l = motor.getLength();
double r = motor.getDiameter() / 2;
gl.glPushMatrix();
@ -325,15 +325,48 @@ public class ComponentRenderer {
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.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.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();
}
}

View File

@ -8,6 +8,7 @@ import javax.media.opengl.GL2ES1;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.fixedfunc.GLLightingFunc;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.ExternalComponent;
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.startup.Application;
import net.sf.openrocket.util.Color;
import net.sf.openrocket.util.Coordinate;
public class FigureRenderer extends RocketRenderer {
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;
}
}
@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);
}
}

View File

@ -14,9 +14,12 @@ import javax.media.opengl.fixedfunc.GLMatrixFunc;
import net.sf.openrocket.appearance.Appearance;
import net.sf.openrocket.appearance.Decal;
import net.sf.openrocket.appearance.defaults.DefaultAppearance;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.motor.Motor;
import net.sf.openrocket.rocketcomponent.RocketComponent;
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.TextureData;
@ -92,8 +95,26 @@ public class RealisticRenderer extends RocketRenderer {
}
@Override
public void renderComponent(GL2 gl, RocketComponent c, float alpha) {
final Appearance a = getAppearance(c);
protected void renderMotor(final GL2 gl, final Coordinate c, final Motor motor) {
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 Texture tex = getTexture(t);
@ -116,7 +137,7 @@ public class RealisticRenderer extends RocketRenderer {
gl.glMaterialfv(GL.GL_BACK, GLLightingFunc.GL_SPECULAR, colorBlack, 0);
gl.glMateriali(GL.GL_BACK, GLLightingFunc.GL_SHININESS, 0);
cr.renderGeometry(gl, c);
g.run();
if (t != null && tex != null) {
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);
}
cr.renderGeometry(gl, c);
g.run();
if (t.getEdgeMode() == Decal.EdgeMode.STICKER) {
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();
if (ret == null) {
ret = Appearance.MISSING;
ret = DefaultAppearance.getDefaultAppearance(c);
}
return ret;
}

View File

@ -51,8 +51,9 @@ import com.jogamp.opengl.util.awt.Overlay;
*/
public class RocketFigure3d extends JPanel implements GLEventListener {
public static final int TYPE_REALISTIC = 0;
public static final int TYPE_FIGURE = 1;
public static final int TYPE_FIGURE = 0;
public static final int TYPE_UNFINISHED = 1;
public static final int TYPE_FINISHED = 2;
private static final long serialVersionUID = 1L;
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 final int CARET_SIZE = 20;
private OpenRocketDocument document;
private Configuration configuration;
private final OpenRocketDocument document;
private final Configuration configuration;
private GLCanvas canvas;
@ -90,7 +91,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
RocketRenderer rr = new FigureRenderer();
public RocketFigure3d(OpenRocketDocument document, Configuration config) {
public RocketFigure3d(final OpenRocketDocument document, final Configuration config) {
this.document = document;
this.configuration = config;
this.setLayout(new BorderLayout());
@ -131,10 +132,10 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
log.debug("Setting up GL capabilities...");
log.verbose("GL - Getting Default Profile");
GLProfile glp = GLProfile.get(GLProfile.GL2);
final GLProfile glp = GLProfile.get(GLProfile.GL2);
log.verbose("GL - creating GLCapabilities");
GLCapabilities caps = new GLCapabilities(glp);
final GLCapabilities caps = new GLCapabilities(glp);
log.verbose("GL - setSampleBuffers");
caps.setSampleBuffers(true);
@ -217,21 +218,21 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
MouseEvent pressEvent;
@Override
public void mousePressed(MouseEvent e) {
public void mousePressed(final MouseEvent e) {
lastX = e.getX();
lastY = e.getY();
pressEvent = e;
}
@Override
public void mouseClicked(MouseEvent e) {
public void mouseClicked(final MouseEvent e) {
pickPoint = new Point(lastX, canvas.getHeight() - lastY);
pickEvent = e;
internalRepaint();
}
@Override
public void mouseDragged(MouseEvent e) {
public void mouseDragged(final MouseEvent e) {
int dx = lastX - e.getX();
int dy = lastY - e.getY();
lastX = e.getX();
@ -257,13 +258,9 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
canvas.addMouseListener(a);
}
public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
updateFigure();
}
@Override
public void display(GLAutoDrawable drawable) {
public void display(final GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
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();
setRenderingHints(og2d);
@ -355,7 +352,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
* Re-blits the overlay every frame. Only re-renders the overlay
* when needed.
*/
private void drawExtras(GL2 gl, GLU glu) {
private void drawExtras(final GL2 gl, final GLU glu) {
//Only re-render if needed
// redrawExtras: Some external change (new simulation data) means
// the data is out of date.
@ -391,17 +388,17 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
}
@Override
public void dispose(GLAutoDrawable drawable) {
public void dispose(final GLAutoDrawable drawable) {
log.verbose("GL - dispose() called");
rr.dispose(drawable);
}
@Override
public void init(GLAutoDrawable drawable) {
public void init(final GLAutoDrawable drawable) {
log.verbose("GL - init()");
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.glDepthFunc(GL.GL_LESS); // the type of depth test to do
@ -426,12 +423,12 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
}
@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()");
GL2 gl = drawable.getGL().getGL2();
GLU glu = new GLU();
final GL2 gl = drawable.getGL().getGL2();
final GLU glu = new GLU();
double ratio = (double) w / (double) h;
final double ratio = (double) w / (double) h;
fovX = fovY * ratio;
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
@ -461,8 +458,8 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
if (cachedBounds != null) {
return cachedBounds;
} else {
Bounds b = new Bounds();
Collection<Coordinate> bounds = configuration.getBounds();
final Bounds b = new Bounds();
final Collection<Coordinate> bounds = configuration.getBounds();
for (Coordinate c : bounds) {
b.xMax = Math.max(b.xMax, 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.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_POSITION,
lightPosition, 0);
// Get the bounds
Bounds b = calculateBounds();
final Bounds b = calculateBounds();
// Calculate the distance needed to fit the bounds in both the X and Y
// direction
// 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));
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));
// 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>();
public void setSelection(RocketComponent[] selection) {
public void setSelection(final RocketComponent[] selection) {
this.selection.clear();
if (selection != null) {
for (RocketComponent c : selection)
@ -560,14 +557,14 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
internalRepaint();
}
private void setRoll(double rot) {
private void setRoll(final double rot) {
if (MathUtil.equals(roll, rot))
return;
this.roll = MathUtil.reduce360(rot);
internalRepaint();
}
private void setYaw(double rot) {
private void setYaw(final double rot) {
if (MathUtil.equals(yaw, rot))
return;
this.yaw = MathUtil.reduce360(rot);
@ -576,16 +573,16 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
// ///////////// Extra methods
private Coordinate project(Coordinate c, GL2 gl, GLU glu) {
double[] mvmatrix = new double[16];
double[] projmatrix = new double[16];
int[] viewport = new int[4];
private Coordinate project(final Coordinate c, final GL2 gl, final GLU glu) {
final double[] mvmatrix = new double[16];
final double[] projmatrix = new double[16];
final int[] viewport = new int[4];
gl.glGetIntegerv(GL.GL_VIEWPORT, viewport, 0);
gl.glGetDoublev(GLMatrixFunc.GL_MODELVIEW_MATRIX, mvmatrix, 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,
out, 0);
@ -596,22 +593,22 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
private Coordinate cp = 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;
redrawExtras = true;
}
public void setCP(Coordinate cp) {
public void setCP(final Coordinate cp) {
this.cp = cp;
redrawExtras = true;
}
public void addRelativeExtra(FigureElement p) {
public void addRelativeExtra(final FigureElement p) {
relativeExtra.add(p);
redrawExtras = true;
}
public void removeRelativeExtra(FigureElement p) {
public void removeRelativeExtra(final FigureElement p) {
relativeExtra.remove(p);
redrawExtras = true;
}
@ -621,12 +618,12 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
redrawExtras = true;
}
public void addAbsoluteExtra(FigureElement p) {
public void addAbsoluteExtra(final FigureElement p) {
absoluteExtra.add(p);
redrawExtras = true;
}
public void removeAbsoluteExtra(FigureElement p) {
public void removeAbsoluteExtra(final FigureElement p) {
absoluteExtra.remove(p);
redrawExtras = true;
}
@ -654,8 +651,10 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
rr.dispose(drawable);
if (t == TYPE_FIGURE) {
rr = new FigureRenderer();
} else {
} else if (t == TYPE_FINISHED) {
rr = new RealisticRenderer(document);
} else if (t == TYPE_UNFINISHED) {
rr = new UnfinishedRenderer(document);
}
rr.init(drawable);
return false;

View File

@ -178,16 +178,19 @@ public abstract class RocketRenderer {
MotorMount mount = iterator.next();
Motor motor = mount.getMotor(motorID);
double length = motor.getLength();
double radius = motor.getDiameter() / 2;
Coordinate[] position = ((RocketComponent) mount).toAbsolute(new Coordinate(((RocketComponent) mount)
.getLength() + mount.getMotorOverhang() - length));
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);
}
}

View File

@ -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);
}
}

View File

@ -91,16 +91,21 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
private static final Translator trans = Application.getTranslator();
/*RocketPanel.FigTypeAct.Sideview = Side view
RocketPanel.FigTypeAct.Backview = Back view
RocketPanel.FigViewAct.3DFigure = 3D Figure
RocketPanel.FigViewAct.3DRealistic = 3D Realistic*/
private static enum VIEW_TYPE {
Sideview,
Backview,
Figure3D,
Realistic3D;
public static enum VIEW_TYPE {
Sideview(false, RocketFigure.TYPE_SIDE),
Backview(false, RocketFigure.TYPE_BACK),
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;
};
@Override
public String 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) {
super.setSelectedItem(o);
VIEW_TYPE v = (VIEW_TYPE) o;
switch (v) {
case Sideview:
figure.setType(RocketFigure.TYPE_SIDE);
go2D();
break;
case Backview:
figure.setType(RocketFigure.TYPE_BACK);
go2D();
break;
case Realistic3D:
figure3d.setType(RocketFigure3d.TYPE_REALISTIC);
if (v.is3d) {
figure3d.setType(v.type);
go3D();
break;
case Figure3D:
figure3d.setType(RocketFigure3d.TYPE_FIGURE);
go3D();
break;
} else {
figure.setType(v.type);
go2D();
}
}
};