Merge remote-tracking branch 'origin' into fix-prev-next-component
This commit is contained in:
commit
7778d9ff02
@ -1880,7 +1880,7 @@ Warning.RECOVERY_HIGH_SPEED = Recovery device deployment at high speed
|
|||||||
Warning.NO_RECOVERY_DEVICE = No recovery device defined in the simulation.
|
Warning.NO_RECOVERY_DEVICE = No recovery device defined in the simulation.
|
||||||
Warning.TUMBLE_UNDER_THRUST = Stage began to tumble under thrust.
|
Warning.TUMBLE_UNDER_THRUST = Stage began to tumble under thrust.
|
||||||
Warning.EVENT_AFTER_LANDING = Flight Event occurred after landing:
|
Warning.EVENT_AFTER_LANDING = Flight Event occurred after landing:
|
||||||
Warning.ZERO_VOLUME_BODY = Zero-volume bodies may not simulate accurately.
|
Warning.ZERO_VOLUME_BODY = Zero-volume bodies may not simulate accurately
|
||||||
Warning.TUBE_SEPARATION = Space between tube fins may not simulate accurately.
|
Warning.TUBE_SEPARATION = Space between tube fins may not simulate accurately.
|
||||||
Warning.TUBE_OVERLAP = Overlapping tube fins may not simulate accurately.
|
Warning.TUBE_OVERLAP = Overlapping tube fins may not simulate accurately.
|
||||||
Warning.EMPTY_BRANCH = Simulation branch contains no data
|
Warning.EMPTY_BRANCH = Simulation branch contains no data
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.sf.openrocket.aerodynamics;
|
package net.sf.openrocket.aerodynamics;
|
||||||
|
|
||||||
|
import static net.sf.openrocket.util.MathUtil.EPSILON;
|
||||||
import static net.sf.openrocket.util.MathUtil.pow2;
|
import static net.sf.openrocket.util.MathUtil.pow2;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -324,8 +325,14 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
|
|||||||
.equals(UnitGroup.UNITS_LENGTH.getDefaultUnit().toStringUnit(2.0*prevComp.getAftRadius()))) {
|
.equals(UnitGroup.UNITS_LENGTH.getDefaultUnit().toStringUnit(2.0*prevComp.getAftRadius()))) {
|
||||||
warnings.add( Warning.DIAMETER_DISCONTINUITY, prevComp + ", " + sym);
|
warnings.add( Warning.DIAMETER_DISCONTINUITY, prevComp + ", " + sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for phantom tube
|
||||||
|
if ((sym.getLength() < MathUtil.EPSILON) ||
|
||||||
|
(sym.getAftRadius() < MathUtil.EPSILON && sym.getForeRadius() < MathUtil.EPSILON)) {
|
||||||
|
warnings.add(Warning.ZERO_VOLUME_BODY, sym.getName());
|
||||||
|
}
|
||||||
|
|
||||||
// check for gap gap or overlap in airframe. We'll use a textual comparison to see if there is a
|
// check for gap or overlap in airframe. We'll use a textual comparison to see if there is a
|
||||||
// gap or overlap, then use arithmetic comparison to see which it is. This won't be quite as reliable
|
// gap or overlap, then use arithmetic comparison to see which it is. This won't be quite as reliable
|
||||||
// as the case for radius, since we never actually display the absolute X position
|
// as the case for radius, since we never actually display the absolute X position
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ public class WarningSet extends AbstractSet<Warning> implements Cloneable, Monit
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public boolean add (Warning w, String d) {
|
public boolean add (Warning w, String d) {
|
||||||
return this.add(w.toString() + ": " + d);
|
return this.add(w.toString() + ": \"" + d + "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -46,10 +46,9 @@ public class FinSetCalc extends RocketComponentCalc {
|
|||||||
protected final WarningSet geometryWarnings = new WarningSet();
|
protected final WarningSet geometryWarnings = new WarningSet();
|
||||||
|
|
||||||
private final double[] poly = new double[6];
|
private final double[] poly = new double[6];
|
||||||
|
|
||||||
private final double thickness;
|
private final double thickness;
|
||||||
private final double bodyRadius;
|
private final double bodyRadius;
|
||||||
private final double bodyLength;
|
|
||||||
private final int finCount;
|
private final int finCount;
|
||||||
private final double cantAngle;
|
private final double cantAngle;
|
||||||
private final FinSet.CrossSection crossSection;
|
private final FinSet.CrossSection crossSection;
|
||||||
@ -62,20 +61,17 @@ public class FinSetCalc extends RocketComponentCalc {
|
|||||||
///why not put FinSet in the parameter instead?
|
///why not put FinSet in the parameter instead?
|
||||||
public FinSetCalc(FinSet component) {
|
public FinSetCalc(FinSet component) {
|
||||||
super(component);
|
super(component);
|
||||||
|
|
||||||
FinSet fin = component;
|
|
||||||
|
|
||||||
thickness = fin.getThickness();
|
this.thickness = component.getThickness();
|
||||||
bodyLength = component.getParent().getLength();
|
this.bodyRadius = component.getBodyRadius();
|
||||||
bodyRadius = fin.getBodyRadius();
|
this.finCount = component.getFinCount();
|
||||||
finCount = fin.getFinCount();
|
|
||||||
|
this.cantAngle = component.getCantAngle();
|
||||||
|
this.span = component.getSpan();
|
||||||
|
this.finArea = component.getPlanformArea();
|
||||||
|
this.crossSection = component.getCrossSection();
|
||||||
|
|
||||||
cantAngle = fin.getCantAngle();
|
calculateFinGeometry(component);
|
||||||
span = fin.getSpan();
|
|
||||||
finArea = fin.getPlanformArea();
|
|
||||||
crossSection = fin.getCrossSection();
|
|
||||||
|
|
||||||
calculateFinGeometry(fin);
|
|
||||||
calculatePoly();
|
calculatePoly();
|
||||||
calculateInterferenceFinCount(component);
|
calculateInterferenceFinCount(component);
|
||||||
}
|
}
|
||||||
@ -101,10 +97,7 @@ public class FinSetCalc extends RocketComponentCalc {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((bodyLength < EPSILON) || (bodyRadius < EPSILON)) {
|
if ((bodyRadius > 0) && (thickness > bodyRadius / 2)){
|
||||||
// Add warnings: Phantom Body
|
|
||||||
warnings.add(Warning.ZERO_VOLUME_BODY);
|
|
||||||
}else if( (0 < bodyRadius) && (thickness > bodyRadius / 2)){
|
|
||||||
// Add warnings (radius/2 == diameter/4)
|
// Add warnings (radius/2 == diameter/4)
|
||||||
warnings.add(Warning.THICK_FIN);
|
warnings.add(Warning.THICK_FIN);
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ public class Simulation implements ChangeSource, Cloneable {
|
|||||||
|
|
||||||
private String name = "";
|
private String name = "";
|
||||||
|
|
||||||
private Status status = Status.NOT_SIMULATED;
|
private Status status;
|
||||||
|
|
||||||
/** The conditions to use */
|
/** The conditions to use */
|
||||||
// TODO: HIGH: Change to use actual conditions class??
|
// TODO: HIGH: Change to use actual conditions class??
|
||||||
@ -98,7 +98,7 @@ public class Simulation implements ChangeSource, Cloneable {
|
|||||||
private SimulationOptions simulatedConditions = null;
|
private SimulationOptions simulatedConditions = null;
|
||||||
private String simulatedConfigurationDescription = null;
|
private String simulatedConfigurationDescription = null;
|
||||||
private FlightData simulatedData = null;
|
private FlightData simulatedData = null;
|
||||||
private int simulatedRocketID = -1;
|
private int simulatedConfigurationID = -1;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,7 +147,8 @@ public class Simulation implements ChangeSource, Cloneable {
|
|||||||
|
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
|
||||||
this.setFlightConfigurationId( rocket.getSelectedConfiguration().getFlightConfigurationID());
|
final FlightConfiguration config = rocket.getSelectedConfiguration();
|
||||||
|
this.setFlightConfigurationId(config.getFlightConfigurationID());
|
||||||
|
|
||||||
options.addChangeListener(new ConditionListener());
|
options.addChangeListener(new ConditionListener());
|
||||||
|
|
||||||
@ -160,7 +161,7 @@ public class Simulation implements ChangeSource, Cloneable {
|
|||||||
simulatedData = data;
|
simulatedData = data;
|
||||||
if (this.status == Status.LOADED) {
|
if (this.status == Status.LOADED) {
|
||||||
simulatedConditions = options.clone();
|
simulatedConditions = options.clone();
|
||||||
simulatedRocketID = rocket.getModID();
|
simulatedConfigurationID = config.getModID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,8 +309,10 @@ public class Simulation implements ChangeSource, Cloneable {
|
|||||||
*/
|
*/
|
||||||
public Status getStatus() {
|
public Status getStatus() {
|
||||||
mutex.verify();
|
mutex.verify();
|
||||||
|
final FlightConfiguration config = rocket.getFlightConfiguration(this.getId()).clone();
|
||||||
|
|
||||||
if (isStatusUpToDate(status)) {
|
if (isStatusUpToDate(status)) {
|
||||||
if (rocket.getFunctionalModID() != simulatedRocketID || !options.equals(simulatedConditions)) {
|
if (config.getModID() != simulatedConfigurationID || !options.equals(simulatedConditions)) {
|
||||||
status = Status.OUTDATED;
|
status = Status.OUTDATED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -320,8 +323,6 @@ public class Simulation implements ChangeSource, Cloneable {
|
|||||||
status = Status.CANT_RUN;
|
status = Status.CANT_RUN;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlightConfiguration config = rocket.getFlightConfiguration( this.getId()).clone();
|
|
||||||
|
|
||||||
//Make sure this simulation has motors.
|
//Make sure this simulation has motors.
|
||||||
if ( ! config.hasMotors() ){
|
if ( ! config.hasMotors() ){
|
||||||
@ -338,7 +339,13 @@ public class Simulation implements ChangeSource, Cloneable {
|
|||||||
public static boolean isStatusUpToDate(Status status) {
|
public static boolean isStatusUpToDate(Status status) {
|
||||||
return status == Status.UPTODATE || status == Status.LOADED || status == Status.EXTERNAL;
|
return status == Status.UPTODATE || status == Status.LOADED || status == Status.EXTERNAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Syncs the modID with its flight configuration.
|
||||||
|
*/
|
||||||
|
public void syncModID() {
|
||||||
|
this.simulatedConfigurationID = getActiveConfiguration().getModID();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -392,7 +399,7 @@ public class Simulation implements ChangeSource, Cloneable {
|
|||||||
// Set simulated info after simulation
|
// Set simulated info after simulation
|
||||||
simulatedConditions = options.clone();
|
simulatedConditions = options.clone();
|
||||||
simulatedConfigurationDescription = descriptor.format( this.rocket, getId());
|
simulatedConfigurationDescription = descriptor.format( this.rocket, getId());
|
||||||
simulatedRocketID = rocket.getFunctionalModID();
|
simulatedConfigurationID = getActiveConfiguration().getModID();
|
||||||
|
|
||||||
status = Status.UPTODATE;
|
status = Status.UPTODATE;
|
||||||
fireChangeEvent();
|
fireChangeEvent();
|
||||||
@ -492,7 +499,7 @@ public class Simulation implements ChangeSource, Cloneable {
|
|||||||
copy.simulatedConditions = null;
|
copy.simulatedConditions = null;
|
||||||
copy.simulatedConfigurationDescription = null;
|
copy.simulatedConfigurationDescription = null;
|
||||||
copy.simulatedData = null;
|
copy.simulatedData = null;
|
||||||
copy.simulatedRocketID = -1;
|
copy.simulatedConfigurationID = -1;
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||||
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@ -62,6 +63,7 @@ public class OpenRocketLoader extends AbstractRocketLoader {
|
|||||||
// Deduce suitable time skip
|
// Deduce suitable time skip
|
||||||
double timeSkip = StorageOptions.SIMULATION_DATA_NONE;
|
double timeSkip = StorageOptions.SIMULATION_DATA_NONE;
|
||||||
for (Simulation s : doc.getSimulations()) {
|
for (Simulation s : doc.getSimulations()) {
|
||||||
|
s.syncModID(); // The config's modID can be out of sync with the simulation's after the whole loading process
|
||||||
if (s.getStatus() == Simulation.Status.EXTERNAL ||
|
if (s.getStatus() == Simulation.Status.EXTERNAL ||
|
||||||
s.getStatus() == Simulation.Status.NOT_SIMULATED)
|
s.getStatus() == Simulation.Status.NOT_SIMULATED)
|
||||||
continue;
|
continue;
|
||||||
|
@ -67,6 +67,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
|||||||
private Map<Integer, Boolean> preloadStageActiveness = null;
|
private Map<Integer, Boolean> preloadStageActiveness = null;
|
||||||
final private Collection<MotorConfiguration> activeMotors = new ConcurrentLinkedQueue<MotorConfiguration>();
|
final private Collection<MotorConfiguration> activeMotors = new ConcurrentLinkedQueue<MotorConfiguration>();
|
||||||
final private InstanceMap activeInstances = new InstanceMap();
|
final private InstanceMap activeInstances = new InstanceMap();
|
||||||
|
final private InstanceMap extraRenderInstances = new InstanceMap(); // Extra instances to be rendered, besides the active instances
|
||||||
|
|
||||||
private int boundsModID = -1;
|
private int boundsModID = -1;
|
||||||
private BoundingBox cachedBoundsAerodynamic = new BoundingBox(); // Bounding box of all aerodynamic components
|
private BoundingBox cachedBoundsAerodynamic = new BoundingBox(); // Bounding box of all aerodynamic components
|
||||||
@ -159,8 +160,6 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
|||||||
*/
|
*/
|
||||||
public void clearStage(final int stageNumber) {
|
public void clearStage(final int stageNumber) {
|
||||||
_setStageActive( stageNumber, false );
|
_setStageActive( stageNumber, false );
|
||||||
updateMotors();
|
|
||||||
updateActiveInstances();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -174,8 +173,6 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
|||||||
for (int i = stageNumber; i < rocket.getStageCount(); i++) {
|
for (int i = stageNumber; i < rocket.getStageCount(); i++) {
|
||||||
_setStageActive(i, false, false);
|
_setStageActive(i, false, false);
|
||||||
}
|
}
|
||||||
updateMotors();
|
|
||||||
updateActiveInstances();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -187,8 +184,6 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
|||||||
for (int i = 0; i < stageNumber; i++) {
|
for (int i = 0; i < stageNumber; i++) {
|
||||||
_setStageActive(i, false, false);
|
_setStageActive(i, false, false);
|
||||||
}
|
}
|
||||||
updateMotors();
|
|
||||||
updateActiveInstances();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -214,8 +209,6 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
|||||||
for (int i=0; i <= stage.getStageNumber(); i++) {
|
for (int i=0; i <= stage.getStageNumber(); i++) {
|
||||||
_setStageActive(i, true);
|
_setStageActive(i, true);
|
||||||
}
|
}
|
||||||
updateMotors();
|
|
||||||
updateActiveInstances();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -226,8 +219,6 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
|||||||
public void setOnlyStage(final int stageNumber) {
|
public void setOnlyStage(final int stageNumber) {
|
||||||
_setAllStages(false);
|
_setAllStages(false);
|
||||||
_setStageActive(stageNumber, true, false);
|
_setStageActive(stageNumber, true, false);
|
||||||
updateMotors();
|
|
||||||
updateActiveInstances();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -288,7 +279,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
|||||||
}
|
}
|
||||||
|
|
||||||
AxialStage stage = rocket.getStage(stageNumber);
|
AxialStage stage = rocket.getStage(stageNumber);
|
||||||
return stage != null && stage.getChildCount() > 0 &&
|
return stage != null && stage.getChildCount() > 0 && // Stages with no children are marked as inactive
|
||||||
stages.get(stageNumber) != null && stages.get(stageNumber).active;
|
stages.get(stageNumber) != null && stages.get(stageNumber).active;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,6 +389,15 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
|||||||
public InstanceMap getActiveInstances() {
|
public InstanceMap getActiveInstances() {
|
||||||
return activeInstances;
|
return activeInstances;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the InstanceMap of instances that need to be rendered, but are not present in {@link #getActiveInstances()}.
|
||||||
|
* This is the case for example for a booster that has no children. It is marked as an inactive stage, but it still needs to be rendered.
|
||||||
|
* @return the InstanceMap of instances that need to be rendered, but are not present in {@link #getActiveInstances()}.
|
||||||
|
*/
|
||||||
|
public InstanceMap getExtraRenderInstances() {
|
||||||
|
return extraRenderInstances;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generates a read-only, instance-aware collection of the components for this rocket & configuration
|
* Generates a read-only, instance-aware collection of the components for this rocket & configuration
|
||||||
@ -406,7 +406,8 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
|||||||
*/
|
*/
|
||||||
private void updateActiveInstances() {
|
private void updateActiveInstances() {
|
||||||
activeInstances.clear();
|
activeInstances.clear();
|
||||||
getActiveContextListAt( this.rocket, activeInstances, Transformation.IDENTITY);
|
extraRenderInstances.clear();
|
||||||
|
getActiveContextListAt(this.rocket, activeInstances, Transformation.IDENTITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private InstanceMap getActiveContextListAt(final RocketComponent component, final InstanceMap results, final Transformation parentTransform ){
|
private InstanceMap getActiveContextListAt(final RocketComponent component, final InstanceMap results, final Transformation parentTransform ){
|
||||||
@ -427,7 +428,11 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
|||||||
|
|
||||||
// constructs entry in-place if this component is active
|
// constructs entry in-place if this component is active
|
||||||
if (this.isComponentActive(component)) {
|
if (this.isComponentActive(component)) {
|
||||||
results.emplace(component, this.isComponentActive(component), currentInstanceNumber, currentTransform);
|
results.emplace(component, currentInstanceNumber, currentTransform);
|
||||||
|
} else if (component instanceof ParallelStage && stages.get(component.getStageNumber()).active) {
|
||||||
|
// Boosters with no children are marked as inactive, but still need to be rendered.
|
||||||
|
// See GitHub issue #1980 for more information.
|
||||||
|
extraRenderInstances.emplace(component, currentInstanceNumber, currentTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(RocketComponent child : component.getChildren()) {
|
for(RocketComponent child : component.getChildren()) {
|
||||||
@ -525,6 +530,13 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
|||||||
updateMotors();
|
updateMotors();
|
||||||
updateActiveInstances();
|
updateActiveInstances();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the configuration's modID, thus staging it in need to update.
|
||||||
|
*/
|
||||||
|
public void updateModID() {
|
||||||
|
this.modID++;
|
||||||
|
}
|
||||||
|
|
||||||
private void updateStages() {
|
private void updateStages() {
|
||||||
Map<Integer, FlightConfiguration.StageFlags> stagesBackup = new HashMap<>(this.stages);
|
Map<Integer, FlightConfiguration.StageFlags> stagesBackup = new HashMap<>(this.stages);
|
||||||
@ -893,13 +905,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getModID() {
|
public int getModID() {
|
||||||
// TODO: this doesn't seem consistent...
|
return modID;
|
||||||
int id = modID;
|
|
||||||
// for (MotorInstance motor : motors.values()) {
|
|
||||||
// id += motor.getModID();
|
|
||||||
// }
|
|
||||||
id += rocket.getModID();
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(final String newName) {
|
public void setName(final String newName) {
|
||||||
|
@ -27,15 +27,13 @@ public class InstanceMap extends ConcurrentHashMap<RocketComponent, ArrayList<In
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void emplace(final RocketComponent component, boolean active, int number, final Transformation xform) {
|
public void emplace(final RocketComponent component, int number, final Transformation transform) {
|
||||||
final RocketComponent key = component;
|
if (!containsKey(component)) {
|
||||||
|
put(component, new ArrayList<>());
|
||||||
if(!containsKey(component)) {
|
|
||||||
put(key, new ArrayList<InstanceContext>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final InstanceContext context = new InstanceContext(component, number, xform);
|
final InstanceContext context = new InstanceContext(component, number, transform);
|
||||||
get(key).add(context);
|
get(component).add(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<InstanceContext> getInstanceContexts(final RocketComponent key) {
|
public List<InstanceContext> getInstanceContexts(final RocketComponent key) {
|
||||||
|
@ -485,17 +485,40 @@ public class Rocket extends ComponentAssembly {
|
|||||||
listenerList.remove(l);
|
listenerList.remove(l);
|
||||||
log.trace("Removed ComponentChangeListener " + l + ", current number of listeners is " + listenerList.size());
|
log.trace("Removed ComponentChangeListener " + l + ", current number of listeners is " + listenerList.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
protected void fireComponentChangeEvent(ComponentChangeEvent cce) {
|
* Fires a ComponentChangeEvent of the given type. The source of the event is set to
|
||||||
if( ! this.eventsEnabled ){
|
* this rocket.
|
||||||
|
*
|
||||||
|
* @param type Type of event
|
||||||
|
* @param ids IDs of the flight configurations to update, or null to update all.
|
||||||
|
* @see #fireComponentChangeEvent(ComponentChangeEvent)
|
||||||
|
*/
|
||||||
|
public void fireComponentChangeEvent(int type, final FlightConfigurationId[] ids) {
|
||||||
|
fireComponentChangeEvent(new ComponentChangeEvent(this, type), ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fires a ComponentChangeEvent of the given type. The source of the event is set to
|
||||||
|
* this rocket.
|
||||||
|
*
|
||||||
|
* @param type Type of event
|
||||||
|
* @param id ID of the flight configurations to update, or null to update all.
|
||||||
|
* @see #fireComponentChangeEvent(ComponentChangeEvent)
|
||||||
|
*/
|
||||||
|
public void fireComponentChangeEvent(int type, FlightConfigurationId id) {
|
||||||
|
fireComponentChangeEvent(type, new FlightConfigurationId[]{ id });
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void fireComponentChangeEvent(ComponentChangeEvent cce, final FlightConfigurationId[] ids) {
|
||||||
|
if (!this.eventsEnabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex.lock("fireComponentChangeEvent");
|
mutex.lock("fireComponentChangeEvent");
|
||||||
try {
|
try {
|
||||||
checkState();
|
checkState();
|
||||||
|
|
||||||
// Update modification ID's only for normal (not undo/redo) events
|
// Update modification ID's only for normal (not undo/redo) events
|
||||||
if (!cce.isUndoChange()) {
|
if (!cce.isUndoChange()) {
|
||||||
modID = UniqueID.next();
|
modID = UniqueID.next();
|
||||||
@ -505,32 +528,39 @@ public class Rocket extends ComponentAssembly {
|
|||||||
aeroModID = modID;
|
aeroModID = modID;
|
||||||
if (cce.isTreeChange())
|
if (cce.isTreeChange())
|
||||||
treeModID = modID;
|
treeModID = modID;
|
||||||
if (cce.isFunctionalChange())
|
if (cce.isFunctionalChange()) {
|
||||||
functionalModID = modID;
|
functionalModID = modID;
|
||||||
|
updateConfigurationsModID(ids);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether frozen
|
// Check whether frozen
|
||||||
if (freezeList != null) {
|
if (freezeList != null) {
|
||||||
log.debug("Rocket is in frozen state, adding event " + cce + " info freeze list");
|
log.debug("Rocket is in frozen state, adding event " + cce + " info freeze list");
|
||||||
freezeList.add(cce);
|
freezeList.add(cce);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify all components first
|
// Notify all components first
|
||||||
Iterator<RocketComponent> iterator = this.iterator(true);
|
Iterator<RocketComponent> iterator = this.iterator(true);
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
RocketComponent next = iterator.next();
|
RocketComponent next = iterator.next();
|
||||||
next.componentChanged(cce);
|
next.componentChanged(cce);
|
||||||
}
|
}
|
||||||
updateConfigurations();
|
updateConfigurations(ids);
|
||||||
|
|
||||||
notifyAllListeners(cce);
|
notifyAllListeners(cce);
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
mutex.unlock("fireComponentChangeEvent");
|
mutex.unlock("fireComponentChangeEvent");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void fireComponentChangeEvent(ComponentChangeEvent cce) {
|
||||||
|
fireComponentChangeEvent(cce, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
updateStageNumbers();
|
updateStageNumbers();
|
||||||
@ -555,11 +585,51 @@ public class Rocket extends ComponentAssembly {
|
|||||||
trackStage(stage);
|
trackStage(stage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateConfigurations(){
|
/**
|
||||||
for( FlightConfiguration config : configSet ){
|
* Update the modIDs of the supplied flight configurations.
|
||||||
config.update();
|
* @param ids IDs of the flight configurations to update, or null to update all.
|
||||||
|
*/
|
||||||
|
private void updateConfigurationsModID(FlightConfigurationId[] ids) {
|
||||||
|
if (ids == null) {
|
||||||
|
for (FlightConfiguration config : configSet) {
|
||||||
|
config.updateModID();
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
for (FlightConfiguration config : configSet) {
|
||||||
|
for (FlightConfigurationId id : ids) {
|
||||||
|
if (config.getId().equals(id)) {
|
||||||
|
config.updateModID();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the flight configurations.
|
||||||
|
* @param ids IDs of the flight configurations to update, or null to update all.
|
||||||
|
*/
|
||||||
|
private void updateConfigurations(FlightConfigurationId[] ids) {
|
||||||
|
if (ids == null) {
|
||||||
|
for (FlightConfiguration config : configSet) {
|
||||||
|
config.update();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (FlightConfiguration config : configSet) {
|
||||||
|
for (FlightConfigurationId id : ids) {
|
||||||
|
if (config.getId().equals(id)) {
|
||||||
|
config.update();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateConfigurations() {
|
||||||
|
updateConfigurations(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -696,8 +766,8 @@ public class Rocket extends ComponentAssembly {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get current configuration:
|
// Get current configuration:
|
||||||
this.configSet.reset( fcid);
|
this.configSet.reset(fcid);
|
||||||
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
|
fireComponentChangeEvent(ComponentChangeEvent.NONFUNCTIONAL_CHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,8 +33,7 @@ import net.sf.openrocket.util.WorldCoordinate;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public class SimulationStatus implements Monitorable {
|
public class SimulationStatus implements Monitorable {
|
||||||
private static final Logger log = LoggerFactory.getLogger(SimulationStatus.class);
|
|
||||||
|
|
||||||
private SimulationConditions simulationConditions;
|
private SimulationConditions simulationConditions;
|
||||||
private FlightConfiguration configuration;
|
private FlightConfiguration configuration;
|
||||||
private FlightDataBranch flightData;
|
private FlightDataBranch flightData;
|
||||||
|
@ -96,8 +96,10 @@ public class StageSelector extends JPanel implements StateChangeListener {
|
|||||||
setEnabled(true);
|
setEnabled(true);
|
||||||
putValue(SHORT_DESCRIPTION, trans.get("RocketPanel.btn.Stages.Toggle.ttip"));
|
putValue(SHORT_DESCRIPTION, trans.get("RocketPanel.btn.Stages.Toggle.ttip"));
|
||||||
}
|
}
|
||||||
rocket.getSelectedConfiguration().toggleStage(stage.getStageNumber());
|
FlightConfiguration config = rocket.getSelectedConfiguration();
|
||||||
rocket.fireComponentChangeEvent(ComponentChangeEvent.AEROMASS_CHANGE | ComponentChangeEvent.MOTOR_CHANGE );
|
config.toggleStage(stage.getStageNumber());
|
||||||
|
rocket.fireComponentChangeEvent(ComponentChangeEvent.AEROMASS_CHANGE | ComponentChangeEvent.MOTOR_CHANGE,
|
||||||
|
config.getFlightConfigurationID());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package net.sf.openrocket.gui.main;
|
|||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.EventObject;
|
import java.util.EventObject;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -156,8 +157,9 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
|||||||
* @param duplicate if True, then duplicate configuration operation, if False then create a new configuration
|
* @param duplicate if True, then duplicate configuration operation, if False then create a new configuration
|
||||||
*/
|
*/
|
||||||
private void newOrDuplicateConfigAction(boolean duplicate) {
|
private void newOrDuplicateConfigAction(boolean duplicate) {
|
||||||
addOrDuplicateConfiguration(duplicate);
|
Map<FlightConfigurationId, FlightConfiguration> newConfigs = addOrDuplicateConfiguration(duplicate);
|
||||||
configurationChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
FlightConfigurationId[] ids = newConfigs.keySet().toArray(new FlightConfigurationId[0]);
|
||||||
|
configurationChanged(ComponentChangeEvent.MOTOR_CHANGE, ids);
|
||||||
stateChanged(null);
|
stateChanged(null);
|
||||||
if (!duplicate) {
|
if (!duplicate) {
|
||||||
switch (tabs.getSelectedIndex()) {
|
switch (tabs.getSelectedIndex()) {
|
||||||
@ -179,14 +181,16 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
|||||||
* either create or duplicate configuration
|
* either create or duplicate configuration
|
||||||
* set new configuration as current
|
* set new configuration as current
|
||||||
* create simulation for new configuration
|
* create simulation for new configuration
|
||||||
|
*
|
||||||
|
* @return the new/duplicated configurations
|
||||||
*/
|
*/
|
||||||
private void addOrDuplicateConfiguration(boolean duplicate) {
|
private Map<FlightConfigurationId, FlightConfiguration> addOrDuplicateConfiguration(boolean duplicate) {
|
||||||
final Map<FlightConfigurationId, FlightConfiguration> newConfigs = new LinkedHashMap<>();
|
final Map<FlightConfigurationId, FlightConfiguration> newConfigs = new LinkedHashMap<>();
|
||||||
|
|
||||||
// create or duplicate configuration
|
// create or duplicate configuration
|
||||||
if (duplicate) {
|
if (duplicate) {
|
||||||
List<FlightConfigurationId> oldIds = getSelectedConfigurationIds();
|
List<FlightConfigurationId> oldIds = getSelectedConfigurationIds();
|
||||||
if (oldIds == null || oldIds.size() == 0) return;
|
if (oldIds == null || oldIds.size() == 0) return Collections.emptyMap();
|
||||||
|
|
||||||
for (FlightConfigurationId oldId : oldIds) {
|
for (FlightConfigurationId oldId : oldIds) {
|
||||||
final FlightConfiguration oldConfig = rocket.getFlightConfiguration(oldId);
|
final FlightConfiguration oldConfig = rocket.getFlightConfiguration(oldId);
|
||||||
@ -210,7 +214,7 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
|||||||
}
|
}
|
||||||
|
|
||||||
OpenRocketDocument doc = BasicFrame.findDocument(rocket);
|
OpenRocketDocument doc = BasicFrame.findDocument(rocket);
|
||||||
if (doc == null) return;
|
if (doc == null) return Collections.emptyMap();
|
||||||
|
|
||||||
for (Map.Entry<FlightConfigurationId, FlightConfiguration> config : newConfigs.entrySet()) {
|
for (Map.Entry<FlightConfigurationId, FlightConfiguration> config : newConfigs.entrySet()) {
|
||||||
// associate configuration with Id and select it
|
// associate configuration with Id and select it
|
||||||
@ -226,6 +230,7 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
|||||||
|
|
||||||
// Reset to first selected flight config
|
// Reset to first selected flight config
|
||||||
rocket.setSelectedConfiguration((FlightConfigurationId) newConfigs.keySet().toArray()[0]);
|
rocket.setSelectedConfiguration((FlightConfigurationId) newConfigs.keySet().toArray()[0]);
|
||||||
|
return newConfigs;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renameConfigurationAction() {
|
private void renameConfigurationAction() {
|
||||||
@ -273,10 +278,14 @@ public class FlightConfigurationPanel extends JPanel implements StateChangeListe
|
|||||||
return duplicateConfigAction;
|
return duplicateConfigAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void configurationChanged(int cce, FlightConfigurationId[] ids) {
|
||||||
|
motorConfigurationPanel.fireTableDataChanged(cce, ids);
|
||||||
|
recoveryConfigurationPanel.fireTableDataChanged(cce, ids);
|
||||||
|
separationConfigurationPanel.fireTableDataChanged(cce, ids);
|
||||||
|
}
|
||||||
|
|
||||||
private void configurationChanged(int cce) {
|
private void configurationChanged(int cce) {
|
||||||
motorConfigurationPanel.fireTableDataChanged(cce);
|
configurationChanged(cce, null);
|
||||||
recoveryConfigurationPanel.fireTableDataChanged(cce);
|
|
||||||
separationConfigurationPanel.fireTableDataChanged(cce);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateButtonState() {
|
private void updateButtonState() {
|
||||||
|
@ -64,11 +64,12 @@ public abstract class FlightConfigurablePanel<T extends FlightConfigurableCompon
|
|||||||
/**
|
/**
|
||||||
* Update the data in the table, with component change event type {cce}
|
* Update the data in the table, with component change event type {cce}
|
||||||
* @param cce index of the ComponentChangeEvent to use (e.g. ComponentChangeEvent.NONFUNCTIONAL_CHANGE)
|
* @param cce index of the ComponentChangeEvent to use (e.g. ComponentChangeEvent.NONFUNCTIONAL_CHANGE)
|
||||||
|
* @param ids: the IDs of the flight configurations that are affected by the change
|
||||||
*/
|
*/
|
||||||
public void fireTableDataChanged(int cce) {
|
public void fireTableDataChanged(int cce, FlightConfigurationId[] ids) {
|
||||||
int selectedRow = table.getSelectedRow();
|
int selectedRow = table.getSelectedRow();
|
||||||
int selectedColumn = table.getSelectedColumn();
|
int selectedColumn = table.getSelectedColumn();
|
||||||
this.rocket.fireComponentChangeEvent(cce);
|
this.rocket.fireComponentChangeEvent(cce, ids);
|
||||||
((AbstractTableModel)table.getModel()).fireTableDataChanged();
|
((AbstractTableModel)table.getModel()).fireTableDataChanged();
|
||||||
restoreSelection(selectedRow,selectedColumn);
|
restoreSelection(selectedRow,selectedColumn);
|
||||||
updateButtonState();
|
updateButtonState();
|
||||||
|
@ -330,7 +330,7 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (update) {
|
if (update) {
|
||||||
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE, fcIds.toArray(new FlightConfigurationId[0]));
|
||||||
} else {
|
} else {
|
||||||
table.requestFocusInWindow();
|
table.requestFocusInWindow();
|
||||||
}
|
}
|
||||||
@ -349,7 +349,7 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE, fcIds.toArray(new FlightConfigurationId[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectIgnition() {
|
private void selectIgnition() {
|
||||||
@ -396,7 +396,7 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (update) {
|
if (update) {
|
||||||
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE, fcIds.toArray(new FlightConfigurationId[0]));
|
||||||
} else {
|
} else {
|
||||||
table.requestFocusInWindow();
|
table.requestFocusInWindow();
|
||||||
}
|
}
|
||||||
@ -426,7 +426,7 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (update) {
|
if (update) {
|
||||||
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE);
|
fireTableDataChanged(ComponentChangeEvent.MOTOR_CHANGE, fcIds.toArray(new FlightConfigurationId[0]));
|
||||||
} else {
|
} else {
|
||||||
table.requestFocusInWindow();
|
table.requestFocusInWindow();
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (update) {
|
if (update) {
|
||||||
fireTableDataChanged(ComponentChangeEvent.AERODYNAMIC_CHANGE);
|
fireTableDataChanged(ComponentChangeEvent.AERODYNAMIC_CHANGE, fcIds.toArray(new FlightConfigurationId[0]));
|
||||||
} else {
|
} else {
|
||||||
table.requestFocusInWindow();
|
table.requestFocusInWindow();
|
||||||
}
|
}
|
||||||
@ -235,7 +235,7 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (update) {
|
if (update) {
|
||||||
fireTableDataChanged(ComponentChangeEvent.AERODYNAMIC_CHANGE);
|
fireTableDataChanged(ComponentChangeEvent.AERODYNAMIC_CHANGE, fcIds.toArray(new FlightConfigurationId[0]));
|
||||||
} else {
|
} else {
|
||||||
table.requestFocusInWindow();
|
table.requestFocusInWindow();
|
||||||
}
|
}
|
||||||
|
@ -219,7 +219,7 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (update) {
|
if (update) {
|
||||||
fireTableDataChanged(ComponentChangeEvent.AEROMASS_CHANGE);
|
fireTableDataChanged(ComponentChangeEvent.AEROMASS_CHANGE, fcIds.toArray(new FlightConfigurationId[0]));
|
||||||
} else {
|
} else {
|
||||||
table.requestFocusInWindow();
|
table.requestFocusInWindow();
|
||||||
}
|
}
|
||||||
@ -245,7 +245,7 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (update) {
|
if (update) {
|
||||||
fireTableDataChanged(ComponentChangeEvent.AEROMASS_CHANGE);
|
fireTableDataChanged(ComponentChangeEvent.AEROMASS_CHANGE, fcIds.toArray(new FlightConfigurationId[0]));
|
||||||
} else {
|
} else {
|
||||||
table.requestFocusInWindow();
|
table.requestFocusInWindow();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,92 @@
|
|||||||
|
package net.sf.openrocket.gui.rocketfigure;
|
||||||
|
|
||||||
|
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||||
|
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.AxialMethod;
|
||||||
|
import net.sf.openrocket.util.Color;
|
||||||
|
import net.sf.openrocket.util.Transformation;
|
||||||
|
|
||||||
|
import java.awt.Shape;
|
||||||
|
|
||||||
|
public class ComponentAssemblyShapes extends RocketComponentShape {
|
||||||
|
|
||||||
|
public static RocketComponentShape[] getShapesSide(final RocketComponent component, final Transformation transformation) {
|
||||||
|
// Ignore normal stages
|
||||||
|
if (component instanceof AxialStage && !(component instanceof ParallelStage)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComponentAssembly assembly = (ComponentAssembly) component;
|
||||||
|
|
||||||
|
// Update the marker location based on the axial method. The axial method changes the "reference point" of the component.
|
||||||
|
Transformation correctedTransform = transformation;
|
||||||
|
if (assembly.getAxialMethod() == AxialMethod.BOTTOM) {
|
||||||
|
correctedTransform = transformation.applyTransformation(new Transformation(assembly.getLength(), 0, 0));
|
||||||
|
} else if (assembly.getAxialMethod() == AxialMethod.MIDDLE) {
|
||||||
|
correctedTransform = transformation.applyTransformation(new Transformation(assembly.getLength() / 2, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Correct the radius to be at the "reference point" dictated by the component's radius offset.
|
||||||
|
double boundingRadius = assembly.getBoundingRadius();
|
||||||
|
correctedTransform = correctedTransform.applyTransformation(new Transformation(0, -boundingRadius, 0));
|
||||||
|
|
||||||
|
double markerRadius = getDisplayRadius(component);
|
||||||
|
Shape[] s = EmptyShapes.getShapesSideWithSelectionSquare(correctedTransform, markerRadius);
|
||||||
|
RocketComponentShape[] shapes = RocketComponentShape.toArray(s, component);
|
||||||
|
|
||||||
|
// Set the color of the shapes
|
||||||
|
Color color = getColor(component);
|
||||||
|
for (int i = 0; i < shapes.length - 1; i++) {
|
||||||
|
shapes[i].setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shapes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RocketComponentShape[] getShapesBack(final RocketComponent component, final Transformation transformation) {
|
||||||
|
// Ignore normal stages
|
||||||
|
if (component instanceof AxialStage && !(component instanceof ParallelStage)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComponentAssembly assembly = (ComponentAssembly) component;
|
||||||
|
|
||||||
|
// Correct the radius to be at the "reference point" dictated by the component's radius offset.
|
||||||
|
double boundingRadius = assembly.getBoundingRadius();
|
||||||
|
Transformation correctedTransform = transformation.applyTransformation(new Transformation(0, -boundingRadius, 0));
|
||||||
|
|
||||||
|
double markerRadius = getDisplayRadius(component);
|
||||||
|
Shape[] s = EmptyShapes.getShapesBackWithSelectionSquare(correctedTransform, markerRadius);
|
||||||
|
RocketComponentShape[] shapes = RocketComponentShape.toArray(s, component);
|
||||||
|
|
||||||
|
// Set the color of the shapes
|
||||||
|
Color color = getColor(component);
|
||||||
|
for (int i = 0; i < shapes.length - 1; i++) {
|
||||||
|
shapes[i].setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shapes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the radius of the marker (i.e. the marker size), based on the rocket size.
|
||||||
|
* @param component this component
|
||||||
|
* @return the radius to draw the marker with
|
||||||
|
*/
|
||||||
|
private static double getDisplayRadius(RocketComponent component) {
|
||||||
|
return component.getRocket().getBoundingRadius() * 0.03;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Color getColor(RocketComponent component) {
|
||||||
|
if (component instanceof PodSet) {
|
||||||
|
return new Color(160,160,215);
|
||||||
|
} else if (component instanceof ParallelStage) {
|
||||||
|
return new Color(198,163,184);
|
||||||
|
} else {
|
||||||
|
return new Color(160, 160, 160);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,48 +0,0 @@
|
|||||||
package net.sf.openrocket.gui.rocketfigure;
|
|
||||||
|
|
||||||
import net.sf.openrocket.rocketcomponent.ParallelStage;
|
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
|
||||||
import net.sf.openrocket.util.Color;
|
|
||||||
import net.sf.openrocket.util.Transformation;
|
|
||||||
|
|
||||||
import java.awt.Shape;
|
|
||||||
|
|
||||||
public class ParallelStageShapes extends RocketComponentShape {
|
|
||||||
public static final Color boosterColor = new Color(198,163,184);
|
|
||||||
|
|
||||||
public static RocketComponentShape[] getShapesSide(final RocketComponent component, final Transformation transformation) {
|
|
||||||
ParallelStage booster = (ParallelStage)component;
|
|
||||||
double radius = getDisplayRadius(booster);
|
|
||||||
|
|
||||||
Shape[] s = EmptyShapes.getShapesSideWithSelectionSquare(transformation, radius);
|
|
||||||
RocketComponentShape[] shapes = RocketComponentShape.toArray(s, component);
|
|
||||||
|
|
||||||
// Set the color of the shapes
|
|
||||||
for (int i = 0; i < shapes.length - 1; i++) {
|
|
||||||
shapes[i].setColor(boosterColor);
|
|
||||||
}
|
|
||||||
shapes[shapes.length - 1].setColor(Color.INVISIBLE);
|
|
||||||
|
|
||||||
return shapes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RocketComponentShape[] getShapesBack(final RocketComponent component, final Transformation transformation) {
|
|
||||||
ParallelStage booster = (ParallelStage)component;
|
|
||||||
double radius = getDisplayRadius(booster);
|
|
||||||
|
|
||||||
Shape[] s = EmptyShapes.getShapesBackWithSelectionSquare(transformation, radius);
|
|
||||||
RocketComponentShape[] shapes = RocketComponentShape.toArray(s, component);
|
|
||||||
|
|
||||||
// Set the color of the shapes
|
|
||||||
for (int i = 0; i < shapes.length - 1; i++) {
|
|
||||||
shapes[i].setColor(boosterColor);
|
|
||||||
}
|
|
||||||
shapes[shapes.length - 1].setColor(Color.INVISIBLE);
|
|
||||||
|
|
||||||
return shapes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static double getDisplayRadius(ParallelStage booster) {
|
|
||||||
return booster.getRocket().getBoundingRadius() * 0.03;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package net.sf.openrocket.gui.rocketfigure;
|
|
||||||
|
|
||||||
import net.sf.openrocket.rocketcomponent.PodSet;
|
|
||||||
import net.sf.openrocket.rocketcomponent.RocketComponent;
|
|
||||||
import net.sf.openrocket.util.Color;
|
|
||||||
import net.sf.openrocket.util.Transformation;
|
|
||||||
|
|
||||||
import java.awt.Shape;
|
|
||||||
|
|
||||||
public class PodSetShapes extends RocketComponentShape {
|
|
||||||
public static final Color podsetColor = new Color(160,160,215);
|
|
||||||
|
|
||||||
public static RocketComponentShape[] getShapesSide(final RocketComponent component, final Transformation transformation) {
|
|
||||||
PodSet podset = (PodSet)component;
|
|
||||||
double radius = getDisplayRadius(podset);
|
|
||||||
|
|
||||||
Shape[] s = EmptyShapes.getShapesSideWithSelectionSquare(transformation, radius);
|
|
||||||
RocketComponentShape[] shapes = RocketComponentShape.toArray(s, component);
|
|
||||||
|
|
||||||
// Set the color of the shapes
|
|
||||||
for (int i = 0; i < shapes.length - 1; i++) {
|
|
||||||
shapes[i].setColor(podsetColor);
|
|
||||||
}
|
|
||||||
shapes[shapes.length - 1].setColor(Color.INVISIBLE);
|
|
||||||
|
|
||||||
return shapes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RocketComponentShape[] getShapesBack(final RocketComponent component, final Transformation transformation) {
|
|
||||||
PodSet podset = (PodSet)component;
|
|
||||||
double radius = getDisplayRadius(podset);
|
|
||||||
|
|
||||||
Shape[] s = EmptyShapes.getShapesBackWithSelectionSquare(transformation, radius);
|
|
||||||
RocketComponentShape[] shapes = RocketComponentShape.toArray(s, component);
|
|
||||||
|
|
||||||
// Set the color of the shapes
|
|
||||||
for (int i = 0; i < shapes.length - 1; i++) {
|
|
||||||
shapes[i].setColor(podsetColor);
|
|
||||||
}
|
|
||||||
shapes[shapes.length - 1].setColor(Color.INVISIBLE);
|
|
||||||
|
|
||||||
return shapes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static double getDisplayRadius(PodSet podset) {
|
|
||||||
return podset.getRocket().getBoundingRadius() * 0.03;
|
|
||||||
}
|
|
||||||
}
|
|
@ -384,11 +384,16 @@ public class RocketFigure extends AbstractScaleFigure {
|
|||||||
// allShapes is an output buffer -- it stores all the generated shapes
|
// allShapes is an output buffer -- it stores all the generated shapes
|
||||||
allShapes.clear();
|
allShapes.clear();
|
||||||
|
|
||||||
for (Entry<RocketComponent, ArrayList<InstanceContext>> entry : config.getActiveInstances().entrySet()) {
|
addShapesFromInstanceEntries(allShapes, config.getActiveInstances().entrySet());
|
||||||
|
addShapesFromInstanceEntries(allShapes, config.getExtraRenderInstances().entrySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addShapesFromInstanceEntries(PriorityQueue<RocketComponentShape> allShapes, Set<Entry<RocketComponent, ArrayList<InstanceContext>>> entries) {
|
||||||
|
for (Entry<RocketComponent, ArrayList<InstanceContext>> entry : entries) {
|
||||||
final RocketComponent comp = entry.getKey();
|
final RocketComponent comp = entry.getKey();
|
||||||
|
|
||||||
// Only draw podsets when they are selected
|
// Only draw pod sets and boosters when they are selected
|
||||||
if ((comp instanceof PodSet || comp instanceof ParallelStage) && preferences.isShowMarkers()) {
|
if (preferences.isShowMarkers() && (comp instanceof PodSet || comp instanceof ParallelStage)) {
|
||||||
boolean selected = false;
|
boolean selected = false;
|
||||||
|
|
||||||
// Check if component is in the selection
|
// Check if component is in the selection
|
||||||
@ -409,7 +414,7 @@ public class RocketFigure extends AbstractScaleFigure {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the shapes required to draw the component.
|
* Gets the shapes required to draw the component.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user