DGP - Fix to non-bulk densities
[debian/openrocket] / src / net / sf / openrocket / file / rocksim / ParachuteHandler.java
1 /*
2  * ParachuteHandler.java
3  */
4 package net.sf.openrocket.file.rocksim;
5
6 import net.sf.openrocket.aerodynamics.WarningSet;
7 import net.sf.openrocket.file.simplesax.ElementHandler;
8 import net.sf.openrocket.file.simplesax.PlainTextHandler;
9 import net.sf.openrocket.material.Material;
10 import net.sf.openrocket.rocketcomponent.BodyTube;
11 import net.sf.openrocket.rocketcomponent.InnerTube;
12 import net.sf.openrocket.rocketcomponent.Parachute;
13 import net.sf.openrocket.rocketcomponent.RocketComponent;
14 import org.xml.sax.SAXException;
15
16 import java.util.HashMap;
17
18 /**
19  * A SAX handler for Rocksim's Parachute XML type.
20  * <p/>
21  */
22 class ParachuteHandler extends PositionDependentHandler<Parachute> {
23     /**
24      * The OpenRocket Parachute instance
25      */
26     private final Parachute chute;
27     /**
28      * The shroud line density.
29      */
30     private double shroudLineDensity = 0.0d;
31
32     /**
33      * Constructor.
34      *
35      * @param c the parent component
36      * @throws IllegalArgumentException thrown if <code>c</code> is null
37      */
38     public ParachuteHandler(RocketComponent c) throws IllegalArgumentException {
39         if (c == null) {
40             throw new IllegalArgumentException("The parent of a parachute may not be null.");
41         }
42         chute = new Parachute();
43         c.addChild(chute);
44     }
45
46     @Override
47     public ElementHandler openElement(String element, HashMap<String, String> attributes, WarningSet warnings) {
48         return PlainTextHandler.INSTANCE;
49     }
50
51     @Override
52     public void closeElement(String element, HashMap<String, String> attributes, String content, WarningSet warnings)
53             throws SAXException {
54         super.closeElement(element, attributes, content, warnings);
55         try {
56             if ("Dia".equals(element)) {
57                 chute.setDiameter(Double.parseDouble(content) / RocksimHandler.ROCKSIM_TO_OPENROCKET_LENGTH);
58                 /* Rocksim doesn't have a packed parachute radius, so we approximate it. */
59                 double packed;
60                 RocketComponent parent = chute.getParent();
61                 if (parent instanceof BodyTube) {
62                     packed = ((BodyTube) parent).getRadius() * 0.9;
63                 }
64                 else if (parent instanceof InnerTube) {
65                     packed = ((InnerTube) parent).getInnerRadius() * 0.9;
66                 }
67                 else {
68                     packed = chute.getDiameter() * 0.025;
69                 }
70                 chute.setRadius(packed);
71             }
72             if ("ShroudLineCount".equals(element)) {
73                 chute.setLineCount(Math.max(0, Integer.parseInt(content)));
74             }
75             if ("ShroudLineLen".equals(element)) {
76                 chute.setLineLength(Math.max(0, Double.parseDouble(
77                         content) / RocksimHandler.ROCKSIM_TO_OPENROCKET_LENGTH));
78             }
79             if ("SpillHoleDia".equals(element)) {
80                 //Not supported in OpenRocket
81                 double spillHoleRadius = Double.parseDouble(content) / RocksimHandler.ROCKSIM_TO_OPENROCKET_RADIUS;
82                 warnings.add("Parachute spill holes are not supported. Ignoring.");
83             }
84             if ("ShroudLineMassPerMM".equals(element)) {
85                 shroudLineDensity = Double.parseDouble(content) / RocksimHandler.ROCKSIM_TO_OPENROCKET_LINE_DENSITY;
86             }
87             if ("ShroudLineMaterial".equals(element)) {
88                 chute.setLineMaterial(BaseHandler.createCustomMaterial(Material.Type.LINE, content, shroudLineDensity));
89             }
90             if ("DragCoefficient".equals(element)) {
91                 chute.setCD(Double.parseDouble(content));
92             }
93             if ("Material".equals(element)) {
94                 setMaterialName(content);
95             }
96         }
97         catch (NumberFormatException nfe) {
98             warnings.add("Could not convert " + element + " value of " + content + ".  It is expected to be a number.");
99         }
100     }
101
102     /**
103      * Get the component this handler is working upon.
104      *
105      * @return a component
106      */
107     public Parachute getComponent() {
108         return chute;
109     }
110
111     /**
112      * Set the relative position onto the component.  This cannot be done directly because setRelativePosition is not
113      * public in all components.
114      *
115      * @param position the OpenRocket position
116      */
117     public void setRelativePosition(RocketComponent.Position position) {
118         chute.setRelativePosition(position);
119     }
120
121     /**
122      * Get the required type of material for this component.
123      *
124      * @return BULK
125      */
126     @Override
127     public Material.Type getMaterialType() {
128         return Material.Type.SURFACE;
129     }
130
131 }
132