Make photo more suitable for launching from OR UI

This commit is contained in:
bkuker 2013-12-04 16:19:46 -05:00
parent e9a75b1111
commit 830fe96115
2 changed files with 244 additions and 235 deletions

View File

@ -2,6 +2,7 @@ package net.sf.openrocket.gui.figure3d.photo;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
@ -41,31 +42,31 @@ import com.google.inject.Injector;
import com.google.inject.Module;
@SuppressWarnings("serial")
public class PhotoApp extends JFrame {
private static final Logger log = LoggerFactory.getLogger(PhotoApp.class);
public class PhotoFrame extends JFrame {
private static final Logger log = LoggerFactory.getLogger(PhotoFrame.class);
private final int SHORTCUT_KEY = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
private final Translator trans = Application.getTranslator();
private PhotoPanel photoPanel;
private JDialog settings;
private final PhotoPanel photoPanel;
private final JDialog settings;
public PhotoApp() {
public PhotoFrame(OpenRocketDocument document, Window parent) {
this(false);
setTitle("Photo - " + document.getRocket().getName());
photoPanel.setDoc(document);
}
public PhotoFrame(boolean app) {
setSize(1024, 768);
this.setMinimumSize(new Dimension(160, 150));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
photoPanel = new PhotoPanel();
setJMenuBar(getMenu());
setJMenuBar(getMenu(app));
setContentPane(photoPanel);
GUIUtil.rememberWindowSize(this);
this.setLocationByPlatform(true);
GUIUtil.setWindowIcons(this);
setTitle("OpenRocket - Photo Studio Alpha");
setVisible(true);
settings = new JDialog(this, "Settings") {
{
setContentPane(new PhotoSettingsConfig(photoPanel.getSettings()));
@ -76,62 +77,63 @@ public class PhotoApp extends JFrame {
};
}
JMenuBar getMenu() {
private JMenuBar getMenu(final boolean showFileMenu) {
JMenuBar menubar = new JMenuBar();
JMenu menu;
JMenuItem item;
//// File
menu = new JMenu(trans.get("main.menu.file"));
menu.setMnemonic(KeyEvent.VK_F);
//// File-handling related tasks
menu.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.desc"));
menubar.add(menu);
// // File
if (showFileMenu) {
menu = new JMenu(trans.get("main.menu.file"));
menu.setMnemonic(KeyEvent.VK_F);
// // File-handling related tasks
menu.getAccessibleContext().setAccessibleDescription(trans.get("main.menu.file.desc"));
menubar.add(menu);
item = new JMenuItem(trans.get("main.menu.file.open"), KeyEvent.VK_O);
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_KEY));
//// Open a rocket design
item.getAccessibleContext().setAccessibleDescription(trans.get("BasicFrame.item.Openrocketdesign"));
item.setIcon(Icons.FILE_OPEN);
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
log.info(Markers.USER_MARKER, "Open... selected");
item = new JMenuItem(trans.get("main.menu.file.open"), KeyEvent.VK_O);
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, SHORTCUT_KEY));
// // Open a rocket design
item.getAccessibleContext().setAccessibleDescription(trans.get("BasicFrame.item.Openrocketdesign"));
item.setIcon(Icons.FILE_OPEN);
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
log.info(Markers.USER_MARKER, "Open... selected");
JFileChooser chooser = new JFileChooser();
JFileChooser chooser = new JFileChooser();
chooser.addChoosableFileFilter(FileHelper.ALL_DESIGNS_FILTER);
chooser.addChoosableFileFilter(FileHelper.OPENROCKET_DESIGN_FILTER);
chooser.addChoosableFileFilter(FileHelper.ROCKSIM_DESIGN_FILTER);
chooser.setFileFilter(FileHelper.ALL_DESIGNS_FILTER);
chooser.addChoosableFileFilter(FileHelper.ALL_DESIGNS_FILTER);
chooser.addChoosableFileFilter(FileHelper.OPENROCKET_DESIGN_FILTER);
chooser.addChoosableFileFilter(FileHelper.ROCKSIM_DESIGN_FILTER);
chooser.setFileFilter(FileHelper.ALL_DESIGNS_FILTER);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
int option = chooser.showOpenDialog(PhotoApp.this);
if (option == JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
log.debug("Opening File " + file.getAbsolutePath());
GeneralRocketLoader grl = new GeneralRocketLoader(file);
try {
OpenRocketDocument doc = grl.load();
photoPanel.setDoc(doc);
} catch (RocketLoadException e1) {
e1.printStackTrace();
chooser.setCurrentDirectory(((SwingPreferences) Application.getPreferences()).getDefaultDirectory());
int option = chooser.showOpenDialog(PhotoFrame.this);
if (option == JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
log.debug("Opening File " + file.getAbsolutePath());
GeneralRocketLoader grl = new GeneralRocketLoader(file);
try {
OpenRocketDocument doc = grl.load();
photoPanel.setDoc(doc);
} catch (RocketLoadException e1) {
e1.printStackTrace();
}
}
}
}
});
menu.add(item);
});
menu.add(item);
}
//// Edit
// // Edit
menu = new JMenu(trans.get("main.menu.edit"));
menu.setMnemonic(KeyEvent.VK_E);
//// Rocket editing
// // Rocket editing
menu.getAccessibleContext().setAccessibleDescription(trans.get("BasicFrame.menu.Rocketedt"));
menubar.add(menu);
Action action = new AbstractAction("Copy") {
@Override
public void actionPerformed(ActionEvent e) {
@ -151,7 +153,7 @@ public class PhotoApp extends JFrame {
}
}));
//Window
// Window
menu = new JMenu("Window");
menubar.add(menu);
JMenu sizeMenu = new JMenu("Size");
@ -188,12 +190,11 @@ public class PhotoApp extends JFrame {
@Override
public void actionPerformed(ActionEvent e) {
photoPanel.setPreferredSize(new Dimension(w, h));
PhotoApp.this.pack();
PhotoFrame.this.pack();
}
}
public static void main(String args[]) throws Exception {
LoggingSystemSetup.setupLoggingAppender();
@ -224,20 +225,10 @@ public class PhotoApp extends JFrame {
Databases.fakeMethod();
new PhotoApp();
/*
if (true) {
Thread.sleep(1);
//String f = "C:\\Users\\bkuker\\git\\openrocket\\core\\resources\\datafiles\\examples\\Simulation Listeners.ork";
//String f = "C:\\Users\\bkuker\\git\\openrocket\\core\\resources\\datafiles\\examples\\High Power Airstart.ork";
String f = "C:\\Users\\bkuker\\git\\openrocket\\core\\resources\\datafiles\\examples\\A simple model rocket.ork";
//String f = "C:\\Users\\bkuker\\git\\openrocket\\core\\resources\\datafiles\\examples\\Clustered rocket design.ork";
//String f = "C:\\Users\\bkuker\\git\\openrocket\\core\\resources\\datafiles\\examples\\Boosted Dart.ork";
GeneralRocketLoader grl = new GeneralRocketLoader(new File(f));
OpenRocketDocument doc = grl.load();
pb.setDoc(doc);
}*/
PhotoFrame pa = new PhotoFrame(true);
pa.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pa.setTitle("OpenRocket - Photo Studio Alpha");
pa.setVisible(true);
}
}

View File

@ -34,6 +34,8 @@ import javax.swing.JPopupMenu;
import javax.swing.event.MouseInputAdapter;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.events.DocumentChangeEvent;
import net.sf.openrocket.document.events.DocumentChangeListener;
import net.sf.openrocket.gui.figure3d.RealisticRenderer;
import net.sf.openrocket.gui.figure3d.RocketRenderer;
import net.sf.openrocket.gui.figure3d.TextureCache;
@ -60,8 +62,8 @@ public class PhotoPanel extends JPanel implements GLEventListener {
private static final Logger log = LoggerFactory.getLogger(PhotoPanel.class);
static {
//this allows the GL canvas and things like the motor selection
//drop down to z-order themselves.
// this allows the GL canvas and things like the motor selection
// drop down to z-order themselves.
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
}
@ -70,39 +72,59 @@ public class PhotoPanel extends JPanel implements GLEventListener {
private TextureCache textureCache = new TextureCache();
private double ratio;
private boolean doCopy = false;
private boolean needUpdate = false;
private RocketRenderer rr;
private PhotoSettings p;
private Trackball trackball = new Trackball();
public void setDoc(final OpenRocketDocument doc) {
((GLAutoDrawable) canvas).invoke(true, new GLRunnable() {
void setDoc(final OpenRocketDocument doc) {
((GLAutoDrawable) canvas).invoke(false, new GLRunnable() {
@Override
public boolean run(GLAutoDrawable drawable) {
public boolean run(final GLAutoDrawable drawable) {
PhotoPanel.this.configuration = doc.getDefaultConfiguration();
cachedBounds = null;
rr = new RealisticRenderer(doc);
rr.init(drawable);
doc.getDefaultConfiguration().addChangeListener(new StateChangeListener() {
@Override
public void stateChanged(EventObject e) {
log.debug("Repainting on config state change");
needUpdate = true;
PhotoPanel.this.repaint();
}
});
doc.addDocumentChangeListener(new DocumentChangeListener() {
@Override
public void documentChanged(DocumentChangeEvent event) {
log.debug("Repainting on document change");
needUpdate = true;
PhotoPanel.this.repaint();
}
});
return false;
}
});
}
public void doCopy() {
void doCopy() {
doCopy = true;
repaint();
}
public PhotoSettings getSettings() {
PhotoSettings getSettings() {
return p;
}
public PhotoPanel() {
PhotoPanel() {
this.setLayout(new BorderLayout());
p = new PhotoSettings();
//Fixes a linux / X bug: Splash must be closed before GL Init
// Fixes a linux / X bug: Splash must be closed before GL Init
SplashScreen splash = Splash.getSplashScreen();
if (splash != null && splash.isVisible())
splash.close();
@ -127,7 +149,6 @@ public class PhotoPanel extends JPanel implements GLEventListener {
final GLCapabilities caps = new GLCapabilities(glp);
if (Application.getPreferences().getBoolean(Preferences.OPENGL_ENABLE_AA, true)) {
caps.setSampleBuffers(true);
caps.setNumSamples(6);
@ -148,8 +169,7 @@ public class PhotoPanel extends JPanel implements GLEventListener {
} catch (Throwable t) {
log.error("An error occurred creating 3d View", t);
canvas = null;
this.add(new JLabel("Unable to load 3d Libraries: "
+ t.getMessage()));
this.add(new JLabel("Unable to load 3d Libraries: " + t.getMessage()));
}
}
@ -173,7 +193,8 @@ public class PhotoPanel extends JPanel implements GLEventListener {
@Override
public void mouseDragged(final MouseEvent e) {
//You can get a drag without a press while a modal dialog is shown
// You can get a drag without a press while a modal dialog is
// shown
if (pressEvent == null)
return;
@ -209,12 +230,15 @@ public class PhotoPanel extends JPanel implements GLEventListener {
super.repaint();
}
@Override
public void display(final GLAutoDrawable drawable) {
GL2 gl = drawable.getGL().getGL2();
d(drawable, 0);
if (needUpdate)
rr.updateFigure(drawable);
needUpdate = false;
draw(drawable, 0);
if (p.isMotionBlurred()) {
Bounds b = calculateBounds();
@ -226,14 +250,13 @@ public class PhotoPanel extends JPanel implements GLEventListener {
gl.glAccum(GL2.GL_LOAD, m);
for (int i = 1; i <= c; i++) {
d(drawable, d / c * i);
draw(drawable, d / c * i);
gl.glAccum(GL2.GL_ACCUM, (1.0f - m) / c);
}
gl.glAccum(GL2.GL_RETURN, 1.0f);
}
if (doCopy) {
copy(drawable);
doCopy = false;
@ -241,7 +264,7 @@ public class PhotoPanel extends JPanel implements GLEventListener {
}
protected static void convertColor(Color color, float[] out) {
private static void convertColor(Color color, float[] out) {
if (color == null) {
out[0] = 1;
out[1] = 1;
@ -253,7 +276,7 @@ public class PhotoPanel extends JPanel implements GLEventListener {
}
}
public void d(final GLAutoDrawable drawable, float dx) {
private void draw(final GLAutoDrawable drawable, float dx) {
GL2 gl = drawable.getGL().getGL2();
GLU glu = new GLU();
@ -265,10 +288,12 @@ public class PhotoPanel extends JPanel implements GLEventListener {
float amb = (float) p.getAmbiance();
float dif = 1.0f - amb;
float spc = 1.0f;
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_AMBIENT, new float[] { amb * color[0], amb * color[1], amb * color[2], 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_DIFFUSE, new float[] { dif * color[0], dif * color[1], dif * color[2], 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_SPECULAR, new float[] { spc * color[0], spc * color[1], spc * color[2], 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_AMBIENT, new float[] { amb * color[0], amb * color[1],
amb * color[2], 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_DIFFUSE, new float[] { dif * color[0], dif * color[1],
dif * color[2], 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_SPECULAR, new float[] { spc * color[0],
spc * color[1], spc * color[2], 1 }, 0);
convertColor(p.getSkyColor(), color);
gl.glClearColor(color[0], color[1], color[2], 1);
@ -279,7 +304,7 @@ public class PhotoPanel extends JPanel implements GLEventListener {
glu.gluPerspective(p.getFov() * (180.0 / Math.PI), ratio, 0.1f, 50f);
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
//Flip textures for LEFT handed coords
// Flip textures for LEFT handed coords
gl.glMatrixMode(GL.GL_TEXTURE);
gl.glLoadIdentity();
gl.glScaled(-1, 1, 1);
@ -292,7 +317,7 @@ public class PhotoPanel extends JPanel implements GLEventListener {
gl.glCullFace(GL.GL_BACK);
gl.glFrontFace(GL.GL_CCW);
//Draw the sky
// Draw the sky
gl.glPushMatrix();
gl.glDisable(GLLightingFunc.GL_LIGHTING);
gl.glDepthMask(false);
@ -309,48 +334,45 @@ public class PhotoPanel extends JPanel implements GLEventListener {
if (rr == null)
return;
glu.gluLookAt(0, 0, p.getViewDistance(), 0, 0, 0, 0, 1, 0);
gl.glRotated(p.getViewAlt() * (180.0 / Math.PI), 1, 0, 0);
gl.glRotated(p.getViewAz() * (180.0 / Math.PI), 0, 1, 0);
float[] lightPosition = new float[] {
(float) Math.cos(p.getLightAlt()) * (float) Math.sin(p.getLightAz()),//
float[] lightPosition = new float[] { (float) Math.cos(p.getLightAlt()) * (float) Math.sin(p.getLightAz()),//
(float) Math.sin(p.getLightAlt()),//
(float) Math.cos(p.getLightAlt()) * (float) Math.cos(p.getLightAz()), //
0
};
0 };
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_POSITION,
lightPosition, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_POSITION, lightPosition, 0);
//Change to LEFT Handed coordinates
// Change to LEFT Handed coordinates
gl.glScaled(1, 1, -1);
gl.glFrontFace(GL.GL_CW);
setupModel(gl);
gl.glTranslated(dx - p.getAdvance(), 0, 0);
if (p.isFlame()) {
convertColor(p.getFlameColor(), color);
gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_AMBIENT, new float[] { 0, 0, 0, 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_DIFFUSE, new float[] { color[0], color[1], color[2], 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_SPECULAR, new float[] { color[0], color[1], color[2], 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_DIFFUSE, new float[] { color[0], color[1],
color[2], 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_SPECULAR, new float[] { color[0], color[1],
color[2], 1 }, 0);
Bounds b = calculateBounds();
gl.glLightf(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_QUADRATIC_ATTENUATION, 20f);
gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_POSITION, new float[] { (float) (b.xMax + .1f), 0, 0, 1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_POSITION, new float[] { (float) (b.xMax + .1f), 0,
0, 1 }, 0);
gl.glEnable(GLLightingFunc.GL_LIGHT2);
} else {
gl.glDisable(GLLightingFunc.GL_LIGHT2);
gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_DIFFUSE, new float[] { 0,0,0,1 }, 0);
gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_DIFFUSE, new float[] { 0, 0, 0, 1 }, 0);
}
rr.render(drawable, configuration, new HashSet<RocketComponent>());
//glu.gluSphere(new GLUquadricImpl(gl, false), .2, 10, 10);
// glu.gluSphere(new GLUquadricImpl(gl, false), .2, 10, 10);
String motorID = configuration.getFlightConfigurationID();
Iterator<MotorMount> iterator = configuration.motorIterator();
@ -392,10 +414,9 @@ public class PhotoPanel extends JPanel implements GLEventListener {
gl.glClearDepth(1.0f); // clear z-buffer to the farthest
gl.glDepthFunc(GL.GL_LESS); // the type of depth test to do
textureCache.init(drawable);
//gl.glDisable(GLLightingFunc.GL_LIGHT1);
// gl.glDisable(GLLightingFunc.GL_LIGHT1);
FlameRenderer.init(gl);
@ -464,15 +485,12 @@ public class PhotoPanel extends JPanel implements GLEventListener {
final BufferedImage image = (new AWTGLReadBufferUtil(GLProfile.get(GLProfile.GL2), false))
.readPixelsToBufferedImage(drawable.getGL(), 0, 0, drawable.getWidth(), drawable.getHeight(), true);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new Transferable() {
@Override
public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException, IOException {
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if (flavor.equals(DataFlavor.imageFlavor) && image != null) {
return image;
}
else {
} else {
throw new UnsupportedFlavorException(flavor);
}
}