Support RockSim booster importing
This commit is contained in:
parent
b5704c108c
commit
01df928f3c
@ -6,30 +6,43 @@ import net.sf.openrocket.file.rocksim.RockSimCommonConstants;
|
||||
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.ComponentAssembly;
|
||||
import net.sf.openrocket.rocketcomponent.ParallelStage;
|
||||
import net.sf.openrocket.rocketcomponent.PodSet;
|
||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||
import net.sf.openrocket.rocketcomponent.position.AnglePositionable;
|
||||
import net.sf.openrocket.rocketcomponent.position.RadiusMethod;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class PodHandler extends PositionDependentHandler<PodSet> {
|
||||
public class PodHandler extends PositionDependentHandler<ComponentAssembly> {
|
||||
/**
|
||||
* The OpenRocket BodyTube.
|
||||
*/
|
||||
private final RocketComponent parent;
|
||||
private final PodSet podSet;
|
||||
private final ParallelStage parallelStage; // A RockSim podset can be an OpenRocket PodSet, or a ParallelStage if it is detachable
|
||||
private boolean isDetachable = false;
|
||||
private boolean isEjected = false;
|
||||
|
||||
public PodHandler(DocumentLoadingContext context, RocketComponent c, WarningSet warnings) {
|
||||
super(context);
|
||||
if (c == null) {
|
||||
throw new IllegalArgumentException("The parent component of a pod set may not be null.");
|
||||
}
|
||||
this.parent = c;
|
||||
podSet = new PodSet();
|
||||
parallelStage = new ParallelStage();
|
||||
podSet.addConfigListener(parallelStage); // The booster will now follow the same config changes as the podset
|
||||
podSet.setInstanceCount(1); // RockSim only supports one pod instance
|
||||
podSet.setRadiusMethod(RadiusMethod.FREE); // RockSim radial offset is relative to the center of the parent
|
||||
if (isCompatible(c, PodSet.class, warnings)) {
|
||||
c.addChild(podSet);
|
||||
}
|
||||
if (isCompatible(c, ParallelStage.class, warnings)) {
|
||||
c.addChild(parallelStage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -52,10 +65,71 @@ public class PodHandler extends PositionDependentHandler<PodSet> {
|
||||
if (RockSimCommonConstants.RADIAL_LOC.equals(element)) {
|
||||
podSet.setRadiusOffset(Double.parseDouble(content) / RockSimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH);
|
||||
}
|
||||
if (RockSimCommonConstants.DETACHABLE.equals(element)) {
|
||||
int value = Integer.parseInt(content);
|
||||
isDetachable = value == 1;
|
||||
}
|
||||
if (RockSimCommonConstants.REMOVED.equals(element)) {
|
||||
int value = Integer.parseInt(content);
|
||||
isEjected = value == 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PodSet getComponent() {
|
||||
public void endHandler(String element, HashMap<String, String> attributes, String content, WarningSet warnings) throws SAXException {
|
||||
super.endHandler(element, attributes, content, warnings);
|
||||
|
||||
// Since RockSim stores the angle offset of pod children in absolute coordinates (not relative to the parent pod set),
|
||||
// we need to subtract the parent pod set angle offset from this component's offset
|
||||
subtractAngleOffset(podSet, podSet.getAngleOffset());
|
||||
|
||||
if (isDetachable || isEjected) {
|
||||
// The offsets of the parallel stage can change due to the children, so copy them from the podset and then apply
|
||||
// it later
|
||||
double axialOffset = podSet.getAxialOffset();
|
||||
double radiusOffset = podSet.getRadiusOffset();
|
||||
|
||||
// Copy the children from the pod to the booster
|
||||
int childCount = podSet.getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
RocketComponent child = podSet.getChild(0);
|
||||
podSet.removeChild(child);
|
||||
if (parallelStage.isCompatible(child)) {
|
||||
parallelStage.addChild(child);
|
||||
} else {
|
||||
warnings.add("The child component " + child.getName() + " of the podset " + podSet.getName() + " is not compatible with a parallel stage.");
|
||||
}
|
||||
}
|
||||
|
||||
// Apply the offsets
|
||||
parallelStage.setAxialOffset(axialOffset);
|
||||
parallelStage.setRadiusOffset(radiusOffset);
|
||||
|
||||
// Remove the podset from the parent
|
||||
parent.removeChild(podSet);
|
||||
|
||||
if (isEjected) {
|
||||
parent.getRocket().getSelectedConfiguration()._setStageActive(parallelStage.getStageNumber(), false);
|
||||
}
|
||||
} else {
|
||||
// It's a normal podset, so remove the booster placeholder
|
||||
parent.removeChild(parallelStage);
|
||||
}
|
||||
}
|
||||
|
||||
private void subtractAngleOffset(RocketComponent c, double angleOffset) {
|
||||
for (RocketComponent child : c.getChildren()) {
|
||||
if (child instanceof AnglePositionable anglePositionable) {
|
||||
anglePositionable.setAngleOffset(anglePositionable.getAngleOffset() - angleOffset);
|
||||
}
|
||||
if (!(child instanceof ComponentAssembly)) {
|
||||
subtractAngleOffset(child, angleOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ComponentAssembly getComponent() {
|
||||
return podSet;
|
||||
}
|
||||
|
||||
|
@ -2059,7 +2059,7 @@ public abstract class RocketComponent implements ChangeSource, Cloneable, Iterab
|
||||
|
||||
|
||||
/**
|
||||
* Move a child to another position.
|
||||
* Move a child to another position within this component.
|
||||
*
|
||||
* @param component the component to move
|
||||
* @param index the component's new position
|
||||
|
Loading…
x
Reference in New Issue
Block a user