diff --git a/core/src/net/sf/openrocket/document/OpenRocketDocument.java b/core/src/net/sf/openrocket/document/OpenRocketDocument.java index 168702894..0670b80c7 100644 --- a/core/src/net/sf/openrocket/document/OpenRocketDocument.java +++ b/core/src/net/sf/openrocket/document/OpenRocketDocument.java @@ -60,6 +60,8 @@ public class OpenRocketDocument implements ComponentChangeListener { private final ArrayList simulations = new ArrayList(); private ArrayList customExpressions = new ArrayList(); + + private PhotoSettings photoSettings = new PhotoSettings(); /* * The undo/redo variables and mechanism are documented in doc/undo-redo-flow.* @@ -831,7 +833,12 @@ public class OpenRocketDocument implements ComponentChangeListener { return str.toString(); } - - - + + public PhotoSettings getPhotoSettings() { + return photoSettings; + } + + public void setPhotoSettings(PhotoSettings photoSettings) { + this.photoSettings = photoSettings; + } } diff --git a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettings.java b/core/src/net/sf/openrocket/document/PhotoSettings.java similarity index 94% rename from swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettings.java rename to core/src/net/sf/openrocket/document/PhotoSettings.java index 8cebe92dc..ccec6dcc9 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettings.java +++ b/core/src/net/sf/openrocket/document/PhotoSettings.java @@ -1,4 +1,4 @@ -package net.sf.openrocket.gui.figure3d.photo; +package net.sf.openrocket.document; import net.sf.openrocket.gui.figure3d.photo.exhaust.FlameRenderer.FlameSettings; import net.sf.openrocket.gui.figure3d.photo.sky.Sky; @@ -31,12 +31,13 @@ public class PhotoSettings extends AbstractChangeSource implements FlameSettings private Color flameColor = new Color(255, 100, 50); private boolean smoke = false; private Color smokeColor = new Color(230, 230, 230, 102); + private double smokeOpacity = 40; private boolean sparks = false; private double exhaustScale = 1.0; private double flameAspectRatio = 1.0; - private double sparkConcentration; - private double sparkWeight; + private double sparkConcentration = 0; + private double sparkWeight = 0; private Sky sky = Mountains.instance; @@ -270,4 +271,12 @@ public class PhotoSettings extends AbstractChangeSource implements FlameSettings this.sparkWeight = sparkWeight; fireChangeEvent(); } + + public double getSmokeOpacity() { + return smokeOpacity; + } + + public void setSmokeOpacity(double smokeOpacity) { + this.smokeOpacity = smokeOpacity; + } } \ No newline at end of file diff --git a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java index ce929e85f..cb77b3ab1 100644 --- a/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java +++ b/core/src/net/sf/openrocket/file/openrocket/OpenRocketSaver.java @@ -10,6 +10,8 @@ import java.util.Iterator; import java.util.List; import java.util.Locale; +import net.sf.openrocket.document.PhotoSettings; +import net.sf.openrocket.file.openrocket.savers.PhotoStudioSaver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -102,6 +104,9 @@ public class OpenRocketSaver extends RocketSaver { } indent--; writeln(""); + + // Save PhotoSettings + savePhotoSettings(document.getPhotoSettings()); indent--; writeln(""); @@ -421,6 +426,12 @@ public class OpenRocketSaver extends RocketSaver { writeln(""); } + + private void savePhotoSettings(PhotoSettings p) throws IOException { + log.debug("Saving Photo Settings"); + for (String s : PhotoStudioSaver.getElements(p)) + writeln(s); + } private void writeEntry(String key, Object value) throws IOException { diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketContentHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketContentHandler.java index 13b88bd5a..f4745bf16 100644 --- a/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketContentHandler.java +++ b/core/src/net/sf/openrocket/file/openrocket/importt/OpenRocketContentHandler.java @@ -63,6 +63,10 @@ class OpenRocketContentHandler extends AbstractElementHandler { simulationsDefined = true; return new SimulationsHandler(getDocument(), context); } + + if (element.equals("photostudio")) { + return new PhotoStudioHandler(context.getOpenRocketDocument().getPhotoSettings()); + } warnings.add(Warning.fromString("Unknown element " + element + ", ignoring.")); diff --git a/core/src/net/sf/openrocket/file/openrocket/importt/PhotoStudioHandler.java b/core/src/net/sf/openrocket/file/openrocket/importt/PhotoStudioHandler.java new file mode 100644 index 000000000..cc1385aea --- /dev/null +++ b/core/src/net/sf/openrocket/file/openrocket/importt/PhotoStudioHandler.java @@ -0,0 +1,222 @@ +package net.sf.openrocket.file.openrocket.importt; + +import net.sf.openrocket.aerodynamics.WarningSet; +import net.sf.openrocket.document.PhotoSettings; +import net.sf.openrocket.file.simplesax.AbstractElementHandler; +import net.sf.openrocket.file.simplesax.ElementHandler; +import net.sf.openrocket.file.simplesax.PlainTextHandler; +import net.sf.openrocket.gui.figure3d.TextureCache; +import net.sf.openrocket.gui.figure3d.photo.sky.Sky; +import net.sf.openrocket.gui.figure3d.photo.sky.SkyBox; +import net.sf.openrocket.gui.figure3d.photo.sky.builtin.*; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.util.Color; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.xml.sax.SAXException; + +import java.util.HashMap; + +/** + * File import handler for PhotoSettings + * + * @author Sibo Van Gool + */ +public class PhotoStudioHandler extends AbstractElementHandler { + private PhotoSettings p; + private static final Logger log = LoggerFactory.getLogger(OpenRocketHandler.class); + + public PhotoStudioHandler(PhotoSettings p) { + this.p = p; + } + + @Override + public ElementHandler openElement(String element, HashMap attributes, WarningSet warnings) throws SAXException { + return PlainTextHandler.INSTANCE; + } + + @Override + public void closeElement(String element, HashMap attributes, String content, WarningSet warnings) throws SAXException { + if ("roll".equals(element)) { + double roll = Double.parseDouble(content); + p.setRoll(roll); + return; + } + if ("yaw".equals(element)) { + double yaw = Double.parseDouble(content); + p.setYaw(yaw); + return; + } + if ("pitch".equals(element)) { + double pitch = Double.parseDouble(content); + p.setPitch(pitch); + return; + } + if ("advance".equals(element)) { + double advance = Double.parseDouble(content); + p.setAdvance(advance); + return; + } + + if ("viewAlt".equals(element)) { + double viewAlt = Double.parseDouble(content); + p.setViewAlt(viewAlt); + return; + } + if ("viewAz".equals(element)) { + double viewAz = Double.parseDouble(content); + p.setViewAz(viewAz); + return; + } + if ("viewDistance".equals(element)) { + double viewDistance = Double.parseDouble(content); + p.setViewDistance(viewDistance); + return; + } + if ("fov".equals(element)) { + double fov = Double.parseDouble(content); + p.setFov(fov); + return; + } + + if ("lightAlt".equals(element)) { + double lightAlt = Double.parseDouble(content); + p.setLightAlt(lightAlt); + return; + } + if ("lightAz".equals(element)) { + double lightAz = Double.parseDouble(content); + p.setLightAz(lightAz); + return; + } + if ("sunlight".equals(element)) { + Color sunlight = getColor(attributes); + p.setSunlight(sunlight); + return; + } + if ("ambiance".equals(element)) { + double ambiance = Double.parseDouble(content); + p.setAmbiance(ambiance); + return; + } + + if ("skyColor".equals(element)) { + Color skyColor = getColor(attributes); + p.setSkyColor(skyColor); + return; + } + + if ("motionBlurred".equals(element)) { + boolean motionBlurred = Boolean.parseBoolean(content); + p.setMotionBlurred(motionBlurred); + return; + } + if ("flame".equals(element)) { + boolean flame = Boolean.parseBoolean(content); + p.setFlame(flame); + return; + } + if ("flameColor".equals(element)) { + Color flameColor = getColor(attributes); + p.setFlameColor(flameColor); + return; + } + if ("smoke".equals(element)) { + boolean smoke = Boolean.parseBoolean(content); + p.setSmoke(smoke); + return; + } + if ("smokeColor".equals(element)) { + Color smokeColor = getColor(attributes); + p.setSmokeColor(smokeColor); + return; + } + if ("smokeOpacity".equals(element)) { + double smokeOpacity = Double.parseDouble(content); + p.setSmokeOpacity(smokeOpacity); + return; + } + if ("sparks".equals(element)) { + boolean sparks = Boolean.parseBoolean(content); + p.setSparks(sparks); + return; + } + if ("exhaustScale".equals(element)) { + double exhaustScale = Double.parseDouble(content); + p.setExhaustScale(exhaustScale); + return; + } + if ("flameAspectRatio".equals(element)) { + double flameAspectRatio = Double.parseDouble(content); + p.setFlameAspectRatio(flameAspectRatio); + return; + } + + if ("sparkConcentration".equals(element)) { + double sparkConcentration = Double.parseDouble(content); + p.setSparkConcentration(sparkConcentration); + return; + } + if ("sparkWeight".equals(element)) { + double sparkWeight = Double.parseDouble(content); + p.setSparkWeight(sparkWeight); + return; + } + + if ("sky".equals(element)) { + if (content.equals("")) { // Case where sky is null + p.setSky(null); + return; + } + Sky s = null; + try { + Class cl = Class.forName(content); + if (Mountains.class.isAssignableFrom(cl)) + s = Mountains.instance; + else if (Lake.class.isAssignableFrom(cl)) + s = Lake.instance; + else if (Meadow.class.isAssignableFrom(cl)) + s = Meadow.instance; + else if (Miramar.class.isAssignableFrom(cl)) + s = Miramar.instance; + else if (Orbit.class.isAssignableFrom(cl)) + s = Orbit.instance; + else if (Storm.class.isAssignableFrom(cl)) + s = Storm.instance; + else { + // Case where sky is a dummy sky, displaying + s = new Sky() { + @Override + public void draw(com.jogamp.opengl.GL2 gl, TextureCache cache) { } + + @Override + public String toString() { + return Application.getTranslator().get("DecalModel.lbl.select"); + } + }; + } + } + catch (ClassNotFoundException e) { + log.info("Could not load sky class '" + content + "'."); + } + p.setSky(s); + return; + } + + super.closeElement(element, attributes, content, warnings); + } + + private Color getColor(HashMap attributes) { + int red = Integer.parseInt(attributes.get("red")); + int green = Integer.parseInt(attributes.get("green")); + int blue = Integer.parseInt(attributes.get("blue")); + int alpha = 255;//set default + // add a test if "alpha" was added to the XML / backwards compatibility + String a = attributes.get("alpha"); + if (a != null){ + // "alpha" string was present so load the value + alpha = Integer.parseInt(a); + } + return new Color(red, green, blue, alpha); + } +} diff --git a/core/src/net/sf/openrocket/file/openrocket/savers/PhotoStudioSaver.java b/core/src/net/sf/openrocket/file/openrocket/savers/PhotoStudioSaver.java new file mode 100644 index 000000000..9ad8bf494 --- /dev/null +++ b/core/src/net/sf/openrocket/file/openrocket/savers/PhotoStudioSaver.java @@ -0,0 +1,62 @@ +package net.sf.openrocket.file.openrocket.savers; + +import net.sf.openrocket.document.PhotoSettings; +import net.sf.openrocket.util.Color; + +import java.util.ArrayList; +import java.util.List; + +public class PhotoStudioSaver { + public static List getElements(PhotoSettings p) { + List elements = new ArrayList(); + + elements.add(""); + + elements.add("" + p.getRoll() + ""); + elements.add("" + p.getYaw() + ""); + elements.add("" + p.getPitch() + ""); + elements.add("" + p.getAdvance() + ""); + + elements.add("" + p.getViewAlt() + ""); + elements.add("" + p.getViewAz() + ""); + elements.add("" + p.getViewDistance() + ""); + elements.add("" + p.getFov() + ""); + + elements.add("" + p.getLightAlt() + ""); + elements.add("" + p.getLightAz() + ""); + emitColor("sunlight", elements, p.getSunlight()); + elements.add("" + p.getAmbiance() + ""); + + emitColor("skyColor", elements, p.getSkyColor()); + + elements.add("" + p.isMotionBlurred() + ""); + elements.add("" + p.isFlame() + ""); + emitColor("flameColor", elements, p.getFlameColor()); + elements.add("" + p.isSmoke() + ""); + emitColor("smokeColor", elements, p.getSmokeColor()); + elements.add("" + p.getSmokeOpacity() + ""); + elements.add("" + p.isSparks() + ""); + elements.add("" + p.getExhaustScale() + ""); + elements.add("" + p.getFlameAspectRatio() + ""); + + elements.add("" + p.getSparkConcentration() + ""); + elements.add("" + p.getSparkWeight() + ""); + + if (p.getSky() != null) { + elements.add("" + p.getSky().getClass().getName() + ""); + } + else + elements.add(""); + + elements.add(""); + + return elements; + } + + private final static void emitColor(String elementName, List elements, Color color) { + if (color != null) { + elements.add("<" + elementName + " red=\"" + color.getRed() + "\" green=\"" + color.getGreen() + + "\" blue=\"" + color.getBlue() + "\" alpha=\"" + color.getAlpha() + "\"/>"); + } + } +} diff --git a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoFrame.java b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoFrame.java index a6f571644..600f99be4 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoFrame.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoFrame.java @@ -62,15 +62,15 @@ public class PhotoFrame extends JFrame { private final JDialog settings; public PhotoFrame(OpenRocketDocument document, Window parent) { - this(false); + this(false, document); setTitle(trans.get("PhotoFrame.title") + " - " + document.getRocket().getName()); - photoPanel.setDoc(document); } - public PhotoFrame(boolean app) { + public PhotoFrame(boolean app, OpenRocketDocument document) { setSize(1024, 768); this.setMinimumSize(new Dimension(160, 150)); - photoPanel = new PhotoPanel(); + photoPanel = new PhotoPanel(document); + photoPanel.setDoc(document); setJMenuBar(getMenu(app)); setContentPane(photoPanel); @@ -92,7 +92,7 @@ public class PhotoFrame extends JFrame { settings = new JDialog(this, trans.get("PhotoSettingsConfig.title")) { { - setContentPane(new PhotoSettingsConfig(photoPanel.getSettings())); + setContentPane(new PhotoSettingsConfig(document.getPhotoSettings())); pack(); this.setLocationByPlatform(true); GUIUtil.rememberWindowSize(this); @@ -353,14 +353,15 @@ public class PhotoFrame extends JFrame { Databases.fakeMethod(); - PhotoFrame pa = new PhotoFrame(true); + GeneralRocketLoader grl = new GeneralRocketLoader(new File( + "/Users/bkuker/git/openrocket/swing/resources/datafiles/examples/A simple model rocket.ork")); + OpenRocketDocument doc = grl.load(); + + PhotoFrame pa = new PhotoFrame(true, doc); pa.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pa.setTitle("OpenRocket - Photo Studio Alpha"); pa.setVisible(true); - GeneralRocketLoader grl = new GeneralRocketLoader(new File( - "/Users/bkuker/git/openrocket/swing/resources/datafiles/examples/A simple model rocket.ork")); - OpenRocketDocument doc = grl.load(); pa.photoPanel.setDoc(doc); } diff --git a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java index 3521ad373..cf81692e5 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoPanel.java @@ -31,6 +31,7 @@ import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.event.MouseInputAdapter; +import net.sf.openrocket.document.PhotoSettings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -116,20 +117,11 @@ public class PhotoPanel extends JPanel implements GLEventListener { }); } - void clearDoc() { - document.removeDocumentChangeListener(changeListener); - changeListener = null; - document = null; - } - - PhotoSettings getSettings() { - return p; - } - - PhotoPanel() { + PhotoPanel(OpenRocketDocument document) { this.setLayout(new BorderLayout()); + PhotoPanel.this.configuration = document.getSelectedConfiguration(); - p = new PhotoSettings(); + p = document.getPhotoSettings(); // Fixes a linux / X bug: Splash must be closed before GL Init SplashScreen splash = Splash.getSplashScreen(); diff --git a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettingsConfig.java b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettingsConfig.java index d0450d53e..f3f9928f6 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettingsConfig.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/photo/PhotoSettingsConfig.java @@ -25,6 +25,7 @@ import javax.swing.event.ChangeListener; import com.jogamp.opengl.GL2; import net.miginfocom.swing.MigLayout; +import net.sf.openrocket.document.PhotoSettings; import net.sf.openrocket.gui.adaptors.BooleanModel; import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.components.ColorIcon; @@ -125,7 +126,7 @@ public class PhotoSettingsConfig extends JTabbedPane { } } - public PhotoSettingsConfig(final PhotoSettings p) { + public PhotoSettingsConfig(PhotoSettings p) { super(); setPreferredSize(new Dimension(240, 320)); @@ -312,8 +313,8 @@ public class PhotoSettingsConfig extends JTabbedPane { smokeModel.addEnableComponent(smokeColorButton); add(new JLabel(trans.get("PhotoSettingsConfig.lbl.smokeOpacity"))); - DoubleModel smokeAlphaModel = new DoubleModel(p, "SmokeAlpha", 100, UnitGroup.UNITS_NONE, 0, 100); - EditableSpinner opacitySpinner = new EditableSpinner(smokeAlphaModel.getSpinnerModel()); + DoubleModel smokeOpacityModel = new DoubleModel(p, "SmokeOpacity", 100, UnitGroup.UNITS_NONE, 0, 100); + EditableSpinner opacitySpinner = new EditableSpinner(smokeOpacityModel.getSpinnerModel()); add(opacitySpinner, "wrap"); smokeModel.addEnableComponent(opacitySpinner);