create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / file / rocksim / export / InnerBodyTubeDTO.java
1 package net.sf.openrocket.file.rocksim.export;
2
3 import net.sf.openrocket.file.rocksim.RocksimCommonConstants;
4 import net.sf.openrocket.gui.configdialog.InnerTubeConfig;
5 import net.sf.openrocket.rocketcomponent.BodyTube;
6 import net.sf.openrocket.rocketcomponent.Bulkhead;
7 import net.sf.openrocket.rocketcomponent.CenteringRing;
8 import net.sf.openrocket.rocketcomponent.EngineBlock;
9 import net.sf.openrocket.rocketcomponent.InnerTube;
10 import net.sf.openrocket.rocketcomponent.MassObject;
11 import net.sf.openrocket.rocketcomponent.Parachute;
12 import net.sf.openrocket.rocketcomponent.RocketComponent;
13 import net.sf.openrocket.rocketcomponent.Streamer;
14 import net.sf.openrocket.rocketcomponent.Transition;
15 import net.sf.openrocket.rocketcomponent.TubeCoupler;
16 import net.sf.openrocket.util.Coordinate;
17
18 import javax.xml.bind.annotation.XmlAccessType;
19 import javax.xml.bind.annotation.XmlAccessorType;
20 import javax.xml.bind.annotation.XmlRootElement;
21 import java.util.List;
22
23 /**
24  * This class models the XML element for a Rocksim inside tube.
25  */
26 @XmlRootElement(name = RocksimCommonConstants.BODY_TUBE)
27 @XmlAccessorType(XmlAccessType.FIELD)
28 public class InnerBodyTubeDTO extends BodyTubeDTO implements AttachableParts {
29
30     /**
31      * Constructor.
32      */
33     public InnerBodyTubeDTO() {
34         super.setInsideTube(true);
35     }
36
37     /**
38      * Full copy constructor.
39      *
40      * @param bt     the corresponding OR inner body tube
41      * @param parent the attached parts (subcomponents in Rocksim speak) of the InnerTube's parent.  This instance
42      *               is a member of those attached parts, as well as all sibling components.  This is passed in the
43      *               event that the inner tube is a cluster.  In that situation this instance will be removed and
44      *               individual instances for each cluster member will be added.
45      */
46     public InnerBodyTubeDTO(InnerTube bt, AttachableParts parent) {
47         super(bt);
48         setEngineOverhang(bt.getMotorOverhang() * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH);
49         setID(bt.getInnerRadius() * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS);
50         setOD(bt.getOuterRadius() * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS);
51         setMotorDia((bt.getMotorMountDiameter() / 2) * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_RADIUS);
52         setMotorMount(bt.isMotorMount());
53         setInsideTube(true);
54         setRadialAngle(bt.getRadialDirection());
55         setRadialLoc(bt.getRadialPosition() * RocksimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH);
56
57         List<RocketComponent> children = bt.getChildren();
58         for (int i = 0; i < children.size(); i++) {
59             RocketComponent rocketComponents = children.get(i);
60             if (rocketComponents instanceof InnerTube) {
61                 final InnerTube innerTube = (InnerTube) rocketComponents;
62                 //Only if the inner tube is NOT a cluster, then create the corresponding Rocksim DTO and add it
63                 //to the list of attached parts.  If it is a cluster, then it is handled specially outside of this
64                 //loop.
65                 if (innerTube.getClusterCount() == 1) {
66                     attachedParts.add(new InnerBodyTubeDTO(innerTube, this));
67                 }
68             } else if (rocketComponents instanceof BodyTube) {
69                 attachedParts.add(new BodyTubeDTO((BodyTube) rocketComponents));
70             } else if (rocketComponents instanceof Transition) {
71                 attachedParts.add(new TransitionDTO((Transition) rocketComponents));
72             } else if (rocketComponents instanceof EngineBlock) {
73                 attachedParts.add(new EngineBlockDTO((EngineBlock) rocketComponents));
74             } else if (rocketComponents instanceof TubeCoupler) {
75                 attachedParts.add(new TubeCouplerDTO((TubeCoupler) rocketComponents));
76             } else if (rocketComponents instanceof CenteringRing) {
77                 attachedParts.add(new CenteringRingDTO((CenteringRing) rocketComponents));
78             } else if (rocketComponents instanceof Bulkhead) {
79                 attachedParts.add(new BulkheadDTO((Bulkhead) rocketComponents));
80             } else if (rocketComponents instanceof Streamer) {
81                 attachedParts.add(new StreamerDTO((Streamer) rocketComponents));
82             } else if (rocketComponents instanceof Parachute) {
83                 attachedParts.add(new ParachuteDTO((Parachute) rocketComponents));
84             } else if (rocketComponents instanceof MassObject) {
85                 attachedParts.add(new MassObjectDTO((MassObject) rocketComponents));
86             }
87         }
88         //Do the cluster.  For now this splits the cluster into separate tubes, which is how Rocksim represents it.
89         //The import (from Rocksim to OR) could be augmented to be more intelligent and try to determine if the
90         //co-located tubes are a cluster.
91         if (bt.getClusterConfiguration().getClusterCount() > 1) {
92             handleCluster(bt, parent);
93             parent.removeAttachedPart(this);
94         }
95     }
96
97
98     /**
99      * Handle the inner tube as a cluster.  This amounts to splitting it up so that each motor mount in the cluster
100      * is created individually to support Rocksim's view of clusters.
101      *
102      * @param it  the clustered tube
103      * @param p   the collection (parent's attached parts really) to which all cluster tubes will be added
104      */
105     private void handleCluster(InnerTube it, AttachableParts p) {
106
107         Coordinate[] coords = {Coordinate.NUL};
108         coords = it.shiftCoordinates(coords);
109         for (int x = 0; x < coords.length; x++) {
110             InnerTube partialClone = InnerTubeConfig.makeIndividualClusterComponent(coords[x], it.getName() + " #" + (x + 1), it);
111             p.addAttachedPart(new InnerBodyTubeDTO(partialClone, p));
112         }
113     }
114
115     @Override
116     public void addAttachedPart(BasePartDTO part) {
117         attachedParts.add(part);
118     }
119
120     @Override
121     public void removeAttachedPart(BasePartDTO part) {
122         attachedParts.remove(part);
123     }
124 }