diff --git a/core/src/net/sf/openrocket/gui/dialogs/MotorDatabaseLoadingDialog.java b/core/src/net/sf/openrocket/gui/dialogs/MotorDatabaseLoadingDialog.java index f19e590d3..5a26d018b 100644 --- a/core/src/net/sf/openrocket/gui/dialogs/MotorDatabaseLoadingDialog.java +++ b/core/src/net/sf/openrocket/gui/dialogs/MotorDatabaseLoadingDialog.java @@ -13,6 +13,7 @@ import javax.swing.Timer; import net.miginfocom.swing.MigLayout; import net.sf.openrocket.database.ThrustCurveMotorSetDatabase; +import net.sf.openrocket.gui.main.Splash; import net.sf.openrocket.gui.util.GUIUtil; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.logging.LogHelper; @@ -61,7 +62,8 @@ public class MotorDatabaseLoadingDialog extends JDialog { if (db.isLoaded()) return; - if (SplashScreen.getSplashScreen() == null) { + SplashScreen splash = Splash.getSplashScreen(); + if (splash == null || !splash.isVisible()) { log.info(1, "Motor database not loaded yet, displaying dialog"); diff --git a/core/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java b/core/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java index 8df1e8508..3cae27189 100644 --- a/core/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java +++ b/core/src/net/sf/openrocket/gui/figure3d/RocketFigure3d.java @@ -34,6 +34,7 @@ import javax.swing.event.MouseInputAdapter; import net.sf.openrocket.gui.figureelements.CGCaret; import net.sf.openrocket.gui.figureelements.CPCaret; import net.sf.openrocket.gui.figureelements.FigureElement; +import net.sf.openrocket.gui.main.Splash; import net.sf.openrocket.logging.LogHelper; import net.sf.openrocket.rocketcomponent.Configuration; import net.sf.openrocket.rocketcomponent.RocketComponent; @@ -55,42 +56,42 @@ public class RocketFigure3d extends JPanel implements GLEventListener { //drop down to z-order themselves. JPopupMenu.setDefaultLightWeightPopupEnabled(false); } - + private static final double fovY = 15.0; private static double fovX = Double.NaN; private static final int CARET_SIZE = 20; private Configuration configuration; private GLCanvas canvas; - - + + private Overlay extrasOverlay, caretOverlay; private BufferedImage cgCaretRaster, cpCaretRaster; private volatile boolean redrawExtras = true; - + private final ArrayList relativeExtra = new ArrayList(); private final ArrayList absoluteExtra = new ArrayList(); - + private double roll = 0; private double yaw = 0; - + Point pickPoint = null; MouseEvent pickEvent; - + float[] lightPosition = new float[] { 1, 4, 1, 0 }; - + RocketRenderer rr = new RocketRenderer(); - + public RocketFigure3d(Configuration config) { this.configuration = config; this.setLayout(new BorderLayout()); //Only initizlize GL if 3d is enabled. - if ( is3dEnabled() ){ + if (is3dEnabled()) { //Fixes a linux / X bug: Splash must be closed before GL Init - SplashScreen splash = SplashScreen.getSplashScreen(); - if ( splash != null ) + SplashScreen splash = Splash.getSplashScreen(); + if (splash != null && splash.isVisible()) splash.close(); initGLCanvas(); @@ -102,11 +103,11 @@ public class RocketFigure3d extends JPanel implements GLEventListener { * launch time. * @return */ - public static boolean is3dEnabled(){ + public static boolean is3dEnabled() { return System.getProperty("openrocket.3d.disable") == null; } - private void initGLCanvas(){ + private void initGLCanvas() { log.debug("Initializing RocketFigure3D OpenGL Canvas"); try { log.debug("Setting up GL capabilities..."); @@ -125,16 +126,16 @@ public class RocketFigure3d extends JPanel implements GLEventListener { log.verbose("GL - setStencilBits"); caps.setStencilBits(1); - + log.verbose("GL - Creating Canvas"); canvas = new GLCanvas(caps); - + log.verbose("GL - Registering as GLEventListener on canvas"); canvas.addGLEventListener(this); log.verbose("GL - Adding canvas to this JPanel"); this.add(canvas, BorderLayout.CENTER); - + log.verbose("GL - Setting up mouse listeners"); setupMouseListeners(); @@ -152,7 +153,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener { /** * Set up the standard rendering hints on the Graphics2D */ - private static void setRenderingHints(Graphics2D g){ + private static void setRenderingHints(Graphics2D g) { g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); g.setRenderingHint(RenderingHints.KEY_RENDERING, @@ -165,7 +166,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener { * Rasterize the carets into 2 buffered images that I can blit onto the * 3d display every redraw without all of the caret shape rendering overhead */ - private void rasterizeCarets(){ + private void rasterizeCarets() { Graphics2D g2d; //Rasterize a CG Caret @@ -176,10 +177,10 @@ public class RocketFigure3d extends JPanel implements GLEventListener { g2d.setBackground(new Color(0, 0, 0, 0)); g2d.clearRect(0, 0, CARET_SIZE, CARET_SIZE); - new CGCaret(CARET_SIZE/2,CARET_SIZE/2).paint(g2d, 1.0); + new CGCaret(CARET_SIZE / 2, CARET_SIZE / 2).paint(g2d, 1.0); g2d.dispose(); - + //Rasterize a CP Caret cpCaretRaster = new BufferedImage(CARET_SIZE, CARET_SIZE, BufferedImage.TYPE_4BYTE_ABGR); g2d = cpCaretRaster.createGraphics(); @@ -188,47 +189,47 @@ public class RocketFigure3d extends JPanel implements GLEventListener { g2d.setBackground(new Color(0, 0, 0, 0)); g2d.clearRect(0, 0, CARET_SIZE, CARET_SIZE); - new CPCaret(CARET_SIZE/2,CARET_SIZE/2).paint(g2d, 1.0); + new CPCaret(CARET_SIZE / 2, CARET_SIZE / 2).paint(g2d, 1.0); g2d.dispose(); } - + private void setupMouseListeners() { MouseInputAdapter a = new MouseInputAdapter() { int lastX; int lastY; MouseEvent pressEvent; - + @Override public void mousePressed(MouseEvent e) { lastX = e.getX(); lastY = e.getY(); pressEvent = e; } - + @Override public void mouseClicked(MouseEvent e) { pickPoint = new Point(lastX, canvas.getHeight() - lastY); pickEvent = e; internalRepaint(); } - + @Override public void mouseDragged(MouseEvent e) { int dx = lastX - e.getX(); int dy = lastY - e.getY(); lastX = e.getX(); lastY = e.getY(); - + if (pressEvent.getButton() == MouseEvent.BUTTON1) { if (Math.abs(dx) > Math.abs(dy)) { - setYaw(yaw - (float) dx / 100.0); + setYaw(yaw - dx / 100.0); } else { - if ( yaw > Math.PI/2.0 && yaw < 3.0*Math.PI/2.0 ){ + if (yaw > Math.PI / 2.0 && yaw < 3.0 * Math.PI / 2.0) { dy = -dy; } - setRoll(roll - (float) dy / 100.0); + setRoll(roll - dy / 100.0); } } else { lightPosition[0] -= 0.1f * dx; @@ -240,28 +241,28 @@ public class RocketFigure3d extends JPanel implements GLEventListener { canvas.addMouseMotionListener(a); canvas.addMouseListener(a); } - + public void setConfiguration(Configuration configuration) { this.configuration = configuration; updateFigure(); } - + @Override public void display(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); GLU glu = new GLU(); - + gl.glEnable(GL.GL_MULTISAMPLE); - + gl.glClearColor(1, 1, 1, 1); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - + setupView(gl, glu); - + if (pickPoint != null) { gl.glDisable(GLLightingFunc.GL_LIGHTING); final RocketComponent picked = rr.pick(drawable, configuration, - pickPoint, pickEvent.isShiftDown()?selection:null ); + pickPoint, pickEvent.isShiftDown() ? selection : null); if (csl != null && picked != null) { final MouseEvent e = pickEvent; SwingUtilities.invokeLater(new Runnable() { @@ -271,13 +272,13 @@ public class RocketFigure3d extends JPanel implements GLEventListener { e); } }); - + } pickPoint = null; - + gl.glClearColor(1, 1, 1, 1); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); - + gl.glEnable(GLLightingFunc.GL_LIGHTING); } rr.render(drawable, configuration, selection); @@ -285,7 +286,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener { drawExtras(gl, glu); drawCarets(gl, glu); } - + private void drawCarets(GL2 gl, GLU glu) { final Graphics2D og2d = caretOverlay.createGraphics(); @@ -294,12 +295,12 @@ public class RocketFigure3d extends JPanel implements GLEventListener { og2d.setBackground(new Color(0, 0, 0, 0)); og2d.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); caretOverlay.markDirty(0, 0, canvas.getWidth(), canvas.getHeight()); - + // The existing relative Extras don't really work right for 3d. Coordinate pCP = project(cp, gl, glu); Coordinate pCG = project(cg, gl, glu); - - final int d = CARET_SIZE/2; + + final int d = CARET_SIZE / 2; //z order the carets if (pCG.z < pCP.z) { @@ -335,18 +336,18 @@ 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(GL2 gl, GLU glu) { //Only re-render if needed // redrawExtras: Some external change (new simulation data) means // the data is out of date. // extrasOverlay.contentsLost(): For some reason the buffer with this // data is lost. - if ( redrawExtras || extrasOverlay.contentsLost() ){ + if (redrawExtras || extrasOverlay.contentsLost()) { log.debug("Redrawing Overlay"); - final Graphics2D og2d = extrasOverlay.createGraphics(); + final Graphics2D og2d = extrasOverlay.createGraphics(); setRenderingHints(og2d); - + og2d.setBackground(new Color(0, 0, 0, 0)); og2d.clearRect(0, 0, canvas.getWidth(), canvas.getHeight()); extrasOverlay.markDirty(0, 0, canvas.getWidth(), canvas.getHeight()); @@ -355,7 +356,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener { e.paint(og2d, 1); } Rectangle rect = this.getVisibleRect(); - + for (FigureElement e : absoluteExtra) { e.paint(og2d, 1.0, rect); } @@ -363,28 +364,28 @@ public class RocketFigure3d extends JPanel implements GLEventListener { redrawExtras = false; } - + //Re-blit to gl canvas every time gl.glEnable(GL.GL_BLEND); extrasOverlay.drawAll(); gl.glDisable(GL.GL_BLEND); } - + @Override public void dispose(GLAutoDrawable drawable) { log.verbose("GL - dispose() called"); } - + @Override public void init(GLAutoDrawable drawable) { log.verbose("GL - init() called"); rr.init(drawable); - + GL2 gl = drawable.getGL().getGL2(); gl.glClearDepth(1.0f); // clear z-buffer to the farthest - + gl.glDepthFunc(GL.GL_LEQUAL); // the type of depth test to do - + float amb = 0.5f; float dif = 1.0f; gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_AMBIENT, @@ -393,28 +394,28 @@ public class RocketFigure3d extends JPanel implements GLEventListener { new float[] { dif, dif, dif, 1 }, 0); gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_SPECULAR, new float[] { dif, dif, dif, 1 }, 0); - + gl.glEnable(GLLightingFunc.GL_LIGHT1); gl.glEnable(GLLightingFunc.GL_LIGHTING); gl.glShadeModel(GLLightingFunc.GL_SMOOTH); - + gl.glEnable(GLLightingFunc.GL_NORMALIZE); - + extrasOverlay = new Overlay(drawable); caretOverlay = new Overlay(drawable); log.verbose("GL - init() complete"); } - + @Override public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { log.verbose("GL - reshape() called"); GL2 gl = drawable.getGL().getGL2(); GLU glu = new GLU(); - + double ratio = (double) w / (double) h; fovX = fovY * ratio; - + gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective(fovY, ratio, 0.05f, 100f); @@ -423,7 +424,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener { redrawExtras = true; log.verbose("GL - reshape() complete"); } - + @SuppressWarnings("unused") private static class Bounds { double xMin, xMax, xSize; @@ -431,7 +432,7 @@ public class RocketFigure3d extends JPanel implements GLEventListener { double zMin, zMax, zSize; double rMax; } - + /** * Calculates the bounds for the current configuration * @@ -443,13 +444,13 @@ public class RocketFigure3d extends JPanel implements GLEventListener { for (Coordinate c : bounds) { ret.xMax = Math.max(ret.xMax, c.x); ret.xMin = Math.min(ret.xMin, c.x); - + ret.yMax = Math.max(ret.yMax, c.y); ret.yMin = Math.min(ret.yMin, c.y); - + ret.zMax = Math.max(ret.zMax, c.z); ret.zMin = Math.min(ret.zMin, c.z); - + double r = MathUtil.hypot(c.y, c.z); ret.rMax = Math.max(ret.rMax, r); } @@ -458,17 +459,17 @@ public class RocketFigure3d extends JPanel implements GLEventListener { ret.zSize = ret.zMax - ret.zMin; return ret; } - + private void setupView(GL2 gl, GLU glu) { log.verbose("GL - setupView() called"); gl.glLoadIdentity(); - + gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_POSITION, lightPosition, 0); - + // Get the bounds Bounds b = calculateBounds(); - + // Calculate the distance needed to fit the bounds in both the X and Y // direction // Add 10% for space around it. @@ -476,13 +477,13 @@ public class RocketFigure3d extends JPanel implements GLEventListener { / Math.tan(Math.toRadians(fovX / 2.0)); 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 glu.gluLookAt(0, 0, Math.max(dX, dY), 0, 0, 0, 0, 1, 0); - + gl.glRotated(yaw * (180.0 / Math.PI), 0, 1, 0); gl.glRotated(roll * (180.0 / Math.PI), 1, 0, 0); - + // Center the rocket in the view. gl.glTranslated(-b.xMin - b.xSize / 2.0, 0, 0); @@ -493,13 +494,13 @@ public class RocketFigure3d extends JPanel implements GLEventListener { //Flip textures for LEFT handed coords gl.glMatrixMode(GL.GL_TEXTURE); gl.glLoadIdentity(); - gl.glScaled(-1,1,1); - gl.glTranslated(-1,0,0); + gl.glScaled(-1, 1, 1); + gl.glTranslated(-1, 0, 0); gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); log.verbose("GL - setupView() complete"); } - + /** * Call when the rocket has changed */ @@ -508,8 +509,8 @@ public class RocketFigure3d extends JPanel implements GLEventListener { rr.updateFigure(); internalRepaint(); } - - private void internalRepaint(){ + + private void internalRepaint() { log.verbose("GL - internalRepaint() called"); super.repaint(); if (canvas != null) @@ -524,9 +525,9 @@ public class RocketFigure3d extends JPanel implements GLEventListener { internalRepaint(); log.verbose("GL - repaint() complete"); } - + private Set selection = new HashSet(); - + public void setSelection(RocketComponent[] selection) { this.selection.clear(); if (selection != null) { @@ -535,33 +536,33 @@ public class RocketFigure3d extends JPanel implements GLEventListener { } internalRepaint(); } - + private void setRoll(double rot) { if (MathUtil.equals(roll, rot)) return; this.roll = MathUtil.reduce360(rot); internalRepaint(); } - + private void setYaw(double rot) { if (MathUtil.equals(yaw, rot)) return; this.yaw = MathUtil.reduce360(rot); internalRepaint(); } - + // ///////////// Extra methods - + private Coordinate project(Coordinate c, GL2 gl, GLU glu) { log.verbose("GL - project() called"); double[] mvmatrix = new double[16]; double[] projmatrix = new double[16]; 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]; glu.gluProject(c.x, c.y, c.z, mvmatrix, 0, projmatrix, 0, viewport, 0, out, 0); @@ -570,59 +571,59 @@ public class RocketFigure3d extends JPanel implements GLEventListener { return new Coordinate(out[0], out[1], out[2]); } - + private Coordinate cp = new Coordinate(0, 0, 0); private Coordinate cg = new Coordinate(0, 0, 0); - + public void setCG(Coordinate cg) { this.cg = cg; redrawExtras = true; } - + public void setCP(Coordinate cp) { this.cp = cp; redrawExtras = true; } - + public void addRelativeExtra(FigureElement p) { relativeExtra.add(p); redrawExtras = true; } - + public void removeRelativeExtra(FigureElement p) { relativeExtra.remove(p); redrawExtras = true; } - + public void clearRelativeExtra() { relativeExtra.clear(); redrawExtras = true; } - + public void addAbsoluteExtra(FigureElement p) { absoluteExtra.add(p); redrawExtras = true; } - + public void removeAbsoluteExtra(FigureElement p) { absoluteExtra.remove(p); redrawExtras = true; } - + public void clearAbsoluteExtra() { absoluteExtra.clear(); redrawExtras = true; } - + private ComponentSelectionListener csl; - + public static interface ComponentSelectionListener { public void componentClicked(RocketComponent[] components, MouseEvent e); } - + public void addComponentSelectionListener( ComponentSelectionListener newListener) { this.csl = newListener; } - + } diff --git a/core/src/net/sf/openrocket/gui/main/Splash.java b/core/src/net/sf/openrocket/gui/main/Splash.java index 4d9b68a56..c3ef0bf64 100644 --- a/core/src/net/sf/openrocket/gui/main/Splash.java +++ b/core/src/net/sf/openrocket/gui/main/Splash.java @@ -38,7 +38,7 @@ public class Splash { */ public static boolean init() { // Get the splash screen - SplashScreen s = getSplash(); + SplashScreen s = getSplashScreen(); if (s == null) return false; @@ -75,14 +75,19 @@ public class Splash { /** - * Return the current splash screen or null if not available. + * Return the current splash screen or null if not available or already closed. * This method catches the possible exceptions and returns null if they occur. * - * @return the current splash screen, or null. + * @return the current (visible) splash screen, or null. */ - private static SplashScreen getSplash() { + public static SplashScreen getSplashScreen() { try { - return SplashScreen.getSplashScreen(); + SplashScreen splash = SplashScreen.getSplashScreen(); + if (splash != null && splash.isVisible()) { + return splash; + } else { + return null; + } } catch (RuntimeException e) { return null; }