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.ElementHandler;
|
||||||
import net.sf.openrocket.file.simplesax.PlainTextHandler;
|
import net.sf.openrocket.file.simplesax.PlainTextHandler;
|
||||||
import net.sf.openrocket.material.Material;
|
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.PodSet;
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
||||||
|
import net.sf.openrocket.rocketcomponent.position.AnglePositionable;
|
||||||
import net.sf.openrocket.rocketcomponent.position.RadiusMethod;
|
import net.sf.openrocket.rocketcomponent.position.RadiusMethod;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
public class PodHandler extends PositionDependentHandler<PodSet> {
|
public class PodHandler extends PositionDependentHandler<ComponentAssembly> {
|
||||||
/**
|
/**
|
||||||
* The OpenRocket BodyTube.
|
* The OpenRocket BodyTube.
|
||||||
*/
|
*/
|
||||||
|
private final RocketComponent parent;
|
||||||
private final PodSet podSet;
|
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) {
|
public PodHandler(DocumentLoadingContext context, RocketComponent c, WarningSet warnings) {
|
||||||
super(context);
|
super(context);
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
throw new IllegalArgumentException("The parent component of a pod set may not be null.");
|
throw new IllegalArgumentException("The parent component of a pod set may not be null.");
|
||||||
}
|
}
|
||||||
|
this.parent = c;
|
||||||
podSet = new PodSet();
|
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.setInstanceCount(1); // RockSim only supports one pod instance
|
||||||
podSet.setRadiusMethod(RadiusMethod.FREE); // RockSim radial offset is relative to the center of the parent
|
podSet.setRadiusMethod(RadiusMethod.FREE); // RockSim radial offset is relative to the center of the parent
|
||||||
if (isCompatible(c, PodSet.class, warnings)) {
|
if (isCompatible(c, PodSet.class, warnings)) {
|
||||||
c.addChild(podSet);
|
c.addChild(podSet);
|
||||||
}
|
}
|
||||||
|
if (isCompatible(c, ParallelStage.class, warnings)) {
|
||||||
|
c.addChild(parallelStage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -52,10 +65,71 @@ public class PodHandler extends PositionDependentHandler<PodSet> {
|
|||||||
if (RockSimCommonConstants.RADIAL_LOC.equals(element)) {
|
if (RockSimCommonConstants.RADIAL_LOC.equals(element)) {
|
||||||
podSet.setRadiusOffset(Double.parseDouble(content) / RockSimCommonConstants.ROCKSIM_TO_OPENROCKET_LENGTH);
|
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
|
@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;
|
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 component the component to move
|
||||||
* @param index the component's new position
|
* @param index the component's new position
|
||||||
|
Loading…
x
Reference in New Issue
Block a user