X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=core%2Fsrc%2Fnet%2Fsf%2Fopenrocket%2Ffile%2Frocksim%2Fimportt%2FMassObjectHandler.java;h=2d918af9a4c49bc5d7951c51967228b364e25014;hb=9349577cdfdff682b2aabd6daa24fdc3a7449b58;hp=ee8cd22db4aeb7977234aa6632c1c9cbd12b6a0f;hpb=da1c2a7f13fc0e3e84f36981a3bb996f2254f766;p=debian%2Fopenrocket diff --git a/core/src/net/sf/openrocket/file/rocksim/importt/MassObjectHandler.java b/core/src/net/sf/openrocket/file/rocksim/importt/MassObjectHandler.java index ee8cd22d..2d918af9 100644 --- a/core/src/net/sf/openrocket/file/rocksim/importt/MassObjectHandler.java +++ b/core/src/net/sf/openrocket/file/rocksim/importt/MassObjectHandler.java @@ -5,9 +5,11 @@ package net.sf.openrocket.file.rocksim.importt; import net.sf.openrocket.aerodynamics.WarningSet; import net.sf.openrocket.file.rocksim.RocksimCommonConstants; +import net.sf.openrocket.file.rocksim.RocksimDensityType; import net.sf.openrocket.file.simplesax.ElementHandler; import net.sf.openrocket.file.simplesax.PlainTextHandler; import net.sf.openrocket.material.Material; +import net.sf.openrocket.rocketcomponent.Coaxial; import net.sf.openrocket.rocketcomponent.MassComponent; import net.sf.openrocket.rocketcomponent.MassObject; import net.sf.openrocket.rocketcomponent.RocketComponent; @@ -21,12 +23,12 @@ import java.util.HashMap; */ class MassObjectHandler extends PositionDependentHandler { - /** + /** * The Rocksim Mass length fudge factor. Rocksim completely exaggerates the length of a mass object to the point * that it looks ridiculous in OpenRocket. This fudge factor is here merely to get the typical mass object to - * render in the OpenRocket UI with it's bounds mostly inside it's parent. The odd thing about it is that - * Rocksim does not expose the length of a mass object in the UI and actually treats mass objects as point objects - - * not 3 or even 2 dimensional. + * render in the OpenRocket UI with it's bounds mostly inside it's parent. The odd thing about it is that Rocksim + * does not expose the length of a mass object in the UI and actually treats mass objects as point objects - not 3 + * or even 2 dimensional. */ public static final int MASS_LEN_FUDGE_FACTOR = 100; @@ -51,12 +53,12 @@ class MassObjectHandler extends PositionDependentHandler { private int typeCode = 0; /** - * Constructor. - *l - * @param c the parent component - * @param warnings the warning set - * - * @throws IllegalArgumentException thrown if c is null + * Constructor. l + * + * @param c the parent component + * @param warnings the warning set + * + * @throws IllegalArgumentException thrown if c is null */ public MassObjectHandler(RocketComponent c, WarningSet warnings) throws IllegalArgumentException { if (c == null) { @@ -89,7 +91,7 @@ class MassObjectHandler extends PositionDependentHandler { //length) and because Rocksim sets the CG of the mass object to really be relative to the front of //the parent. But that value is already assumed in the position and position value for the component. //Thus it needs to be set to 0 to say that the mass object's CG is at the point of the mass object. - super.setCG(0); + super.setCG(0); } if (RocksimCommonConstants.TYPE_CODE.equals(element)) { typeCode = Integer.parseInt(content); @@ -104,32 +106,68 @@ class MassObjectHandler extends PositionDependentHandler { } @Override - public void endHandler(String element, HashMap attributes, String content, WarningSet warnings) throws SAXException { - if (typeCode == 0) { //General Mass Object + public void endHandler(String element, HashMap attributes, String content, WarningSet warnings) throws + SAXException { + if (inferAsShockCord(typeCode, warnings)) { //Shock Cord + mapMassObjectAsShockCord(element, attributes, content, warnings); + } + else { // typeCode == 0 General Mass Object if (isCompatible(parent, MassComponent.class, warnings)) { parent.addChild(mass); } super.endHandler(element, attributes, content, warnings); } - else if (typeCode == 1) { //Shock Cord - ShockCord cord = new ShockCord(); - current = cord; - if (isCompatible(parent, ShockCord.class, warnings)) { - parent.addChild(cord); - } - super.endHandler(element, attributes, content, warnings); - cord.setName(mass.getName()); - - setOverride(cord, mass.isMassOverridden(), mass.getOverrideMass(), mass.getOverrideCGX()); + } - cord.setRadialDirection(mass.getRadialDirection()); - cord.setRadialPosition(mass.getRadialPosition()); - cord.setRadius(mass.getRadius()); + /** + * Rocksim does not have a separate entity for Shock Cords. It has to be inferred. Sometimes the typeCode + * indicates it's a shock cord, but most times it does not. This is due to bugs in the Rocksim Component and + * Material databases. Try to infer a shock cord based on it's length and it's material type. It's somewhat + * arbitrary, but if the mass object's length is more than twice the length of it's parent component and it's a LINE + * material, then assume a shock cord. + * + * @param theTypeCode the code from the RKT XML file + * + * @return true if we think it's a shock cord + */ + private boolean inferAsShockCord(int theTypeCode, WarningSet warnings) { + return (theTypeCode == 1 || (mass.getLength() >= 2 * parent.getLength() && RocksimDensityType.ROCKSIM_LINE + .equals(getDensityType()))) && isCompatible(parent, ShockCord.class, warnings, true); + } - //Rocksim does not distinguish between total length of the cord and the packed length. Fudge the - //packed length and set the real length. - cord.setCordLength(mass.getLength()); - cord.setLength(cord.getCordLength()/MASS_LEN_FUDGE_FACTOR); + /** + * If it appears that the mass object is a shock cord, then create an OR shock cord instance. + * + * @param element the element name + * @param attributes the attributes + * @param content the content of the element + * @param warnings the warning set to store warnings in. + * + * @throws org.xml.sax.SAXException not thrown + */ + private void mapMassObjectAsShockCord(final String element, final HashMap attributes, + final String content, final WarningSet warnings) throws SAXException { + ShockCord cord = new ShockCord(); + current = cord; + if (isCompatible(parent, ShockCord.class, warnings)) { + parent.addChild(cord); + } + super.endHandler(element, attributes, content, warnings); + cord.setName(mass.getName()); + + setOverride(cord, mass.isMassOverridden(), mass.getOverrideMass(), mass.getOverrideCGX()); + + cord.setRadialDirection(mass.getRadialDirection()); + cord.setRadialPosition(mass.getRadialPosition()); + cord.setRadius(mass.getRadius()); + + //Rocksim does not distinguish between total length of the cord and the packed length. Fudge the + //packed length and set the real length. + cord.setCordLength(mass.getLength()); + cord.setLength(cord.getCordLength() / MASS_LEN_FUDGE_FACTOR); + if (parent instanceof Coaxial) { + Coaxial parentCoaxial = (Coaxial) parent; + cord.setRadius(parentCoaxial.getInnerRadius()); } } @@ -154,7 +192,8 @@ class MassObjectHandler extends PositionDependentHandler { } /** - * Get the required type of material for this component. Does not apply to MassComponents, but does apply to Shock Cords. + * Get the required type of material for this component. Does not apply to MassComponents, but does apply to Shock + * Cords. * * @return LINE */