This is a much bigger commit than I like to make, and will result in a much bigger

PR than I like as well.  All I can do is apologize...

Fixes length calculation in RocketPanel.

(1) Finished switching over from deprecated getBounds() function to getBoundingBox().
getBounds() function is removed.

(2) 3D rendering code had its own getBounds().  Switched this over to
RocketComponent:getBoundingBox() as well

(3) Made getBoundingBox() consistently get the bounding box relative to the component.
Implementations for some components were calculating box relative to start of rocket

(4) Used InstanceMap to iterate through all instances of components in creating bounding box.
This commit is contained in:
JoePfeiffer 2019-06-17 15:19:08 -06:00
parent 1b188e20be
commit 85c21e5812
24 changed files with 61 additions and 361 deletions

View File

@ -2,7 +2,6 @@ package net.sf.openrocket.aerodynamics;
import static net.sf.openrocket.util.MathUtil.pow2; import static net.sf.openrocket.util.MathUtil.pow2;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@ -23,6 +22,7 @@ import net.sf.openrocket.rocketcomponent.InstanceMap;
import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.rocketcomponent.SymmetricComponent; import net.sf.openrocket.rocketcomponent.SymmetricComponent;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.MathUtil;
import net.sf.openrocket.util.PolyInterpolator; import net.sf.openrocket.util.PolyInterpolator;
@ -96,7 +96,6 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
// Calculate non-axial force data // Calculate non-axial force data
AerodynamicForces total = calculateNonAxialForces(configuration, conditions, map, warnings); AerodynamicForces total = calculateNonAxialForces(configuration, conditions, map, warnings);
// Calculate friction data // Calculate friction data
total.setFrictionCD(calculateFrictionDrag(configuration, conditions, map, warnings)); total.setFrictionCD(calculateFrictionDrag(configuration, conditions, map, warnings));
total.setPressureCD(calculatePressureDrag(configuration, conditions, map, warnings)); total.setPressureCD(calculatePressureDrag(configuration, conditions, map, warnings));
@ -174,7 +173,6 @@ public class BarrowmanCalculator extends AbstractAerodynamicCalculator {
if (calcMap == null) if (calcMap == null)
buildCalcMap(configuration); buildCalcMap(configuration);
if( ! isContinuous( configuration.getRocket() ) ){ if( ! isContinuous( configuration.getRocket() ) ){
warnings.add( Warning.DIAMETER_DISCONTINUITY); warnings.add( Warning.DIAMETER_DISCONTINUITY);
} }

View File

@ -55,24 +55,6 @@ public class AxialStage extends ComponentAssembly implements FlightConfigurableC
separations.reset(fcid); separations.reset(fcid);
} }
/**
* {@inheritDoc}
* not strictly accurate, but this should provide an acceptable estimate for total vehicle size
*/
/* @Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(8);
Coordinate[] instanceLocations = this.getInstanceLocations();
double x_min = instanceLocations[0].x;
double x_max = x_min + this.length;
double r_max = 0;
addBound(bounds, x_min, r_max);
addBound(bounds, x_max, r_max);
return bounds;
}
*/
/** /**
* Check whether the given type can be added to this component. A Stage allows * Check whether the given type can be added to this component. A Stage allows
* only BodyComponents to be added. * only BodyComponents to be added.

View File

@ -298,22 +298,6 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial
return Math.PI * r * r * l; return Math.PI * r * r * l;
} }
/**
* Adds bounding coordinates to the given set. The body tube will fit within the
* convex hull of the points.
*
* Currently the points are simply a rectangular box around the body tube.
*/
/* @Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(2);
addBoundingBox(bounds, 0, length, getOuterRadius());
return bounds;
}*/
/** /**
* Check whether the given type can be added to this component. BodyTubes allow any * Check whether the given type can be added to this component. BodyTubes allow any
* InternalComponents or ExternalComponents, excluding BodyComponents, to be added. * InternalComponents or ExternalComponents, excluding BodyComponents, to be added.

View File

@ -710,53 +710,16 @@ public abstract class FinSet extends ExternalComponent implements RingInstanceab
final double finLength = singleFinBounds.max.x; final double finLength = singleFinBounds.max.x;
final double finHeight = singleFinBounds.max.y; final double finHeight = singleFinBounds.max.y;
/*
BoundingBox compBox = new BoundingBox().update(getComponentLocations()); BoundingBox compBox = new BoundingBox().update(getComponentLocations());
BoundingBox finSetBox = new BoundingBox( compBox.min.sub( 0, finHeight, finHeight ), BoundingBox finSetBox = new BoundingBox( compBox.min.sub( 0, finHeight, finHeight ),
compBox.max.add( finLength, finHeight, finHeight )); compBox.max.add( finLength, finHeight, finHeight ));
return finSetBox; return finSetBox;
}
/**
* Adds bounding coordinates to the given set. The body tube will fit within the
* convex hull of the points.
*
* Currently the points are simply a rectangular box around the body tube.
*/ */
/*@Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(8);
// should simply return this component's bounds in this component's body frame. return new BoundingBox(0.0, finLength, finHeight);
double x_min = Double.MAX_VALUE;
double x_max = Double.MIN_VALUE;
double r_max = 0.0;
for (Coordinate point : getFinPoints()) {
double hypot = MathUtil.hypot(point.y, point.z);
double x_cur = point.x;
if (x_min > x_cur) {
x_min = x_cur;
} }
if (x_max < x_cur) {
x_max = x_cur;
}
if (r_max < hypot) {
r_max = hypot;
}
}
Coordinate location = this.getLocations()[0];
x_max += location.x;
if( parent instanceof SymmetricComponent){
r_max += ((SymmetricComponent)parent).getRadius(0);
}
addBoundingBox(bounds, x_min, x_max, r_max);
return bounds;
}*/
@Override @Override
public void componentChanged(ComponentChangeEvent e) { public void componentChanged(ComponentChangeEvent e) {

View File

@ -63,7 +63,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
final protected HashMap<MotorConfigurationId, MotorConfiguration> motors = new HashMap<MotorConfigurationId, MotorConfiguration>(); final protected HashMap<MotorConfigurationId, MotorConfiguration> motors = new HashMap<MotorConfigurationId, MotorConfiguration>();
private int boundsModID = -1; private int boundsModID = -1;
private BoundingBox cachedBounds = new BoundingBox(); private BoundingBox cachedBoundingBox = new BoundingBox();
private double cachedLength = -1; private double cachedLength = -1;
private int refLengthModID = -1; private int refLengthModID = -1;
@ -501,18 +501,6 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
return isComponentActive( (RocketComponent) c); return isComponentActive( (RocketComponent) c);
} }
/**
* Return the bounds of the current configuration. The bounds are cached.
*
* @return a <code>Collection</code> containing coordinates bounding the rocket.
*
* @deprecated Migrate to <FlightConfiguration>.getBoundingBox(), when practical.
*/
@Deprecated
public Collection<Coordinate> getBounds() {
return getBoundingBox().toCollection();
}
/** /**
* Return the bounding box of the current configuration. * Return the bounding box of the current configuration.
* *
@ -520,22 +508,34 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
*/ */
public BoundingBox getBoundingBox() { public BoundingBox getBoundingBox() {
if (rocket.getModID() != boundsModID) { if (rocket.getModID() != boundsModID) {
calculateBounds(); calculateBoundingBox();
} }
return cachedBounds; return cachedBoundingBox;
} }
private void calculateBounds(){ private void calculateBoundingBox(){
BoundingBox bounds = new BoundingBox(); BoundingBox bounds = new BoundingBox();
for (RocketComponent component : this.getActiveComponents()) { // iterate through all components
BoundingBox componentBounds = new BoundingBox().update(component.getBoundingBox()); final InstanceMap imap = this.getActiveInstances();
bounds.update( componentBounds ); for(Map.Entry<RocketComponent, ArrayList<InstanceContext>> entry: imap.entrySet() ) {
final RocketComponent comp = entry.getKey();
if (this.isComponentActive(comp)) {
// iterate across all componenent instances
final ArrayList<InstanceContext> contextList = entry.getValue();
for(InstanceContext context: contextList ) {
BoundingBox instanceBox = new BoundingBox(context.transform.transform(comp.getBoundingBox().min),
context.transform.transform(comp.getBoundingBox().max));
bounds.update(instanceBox);
}
}
} }
boundsModID = rocket.getModID(); boundsModID = rocket.getModID();
cachedLength = bounds.span().x; cachedLength = bounds.span().x;
cachedBounds.update( bounds ); cachedBoundingBox.update( bounds );
} }
/** /**
@ -546,7 +546,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
*/ */
public double getLength() { public double getLength() {
if (rocket.getModID() != boundsModID) { if (rocket.getModID() != boundsModID) {
calculateBounds(); calculateBoundingBox();
} }
return cachedLength; return cachedLength;
} }
@ -567,7 +567,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
FlightConfiguration clone = new FlightConfiguration( this.rocket, this.fcid ); FlightConfiguration clone = new FlightConfiguration( this.rocket, this.fcid );
clone.setName(configurationName); clone.setName(configurationName);
clone.cachedBounds = this.cachedBounds.clone(); clone.cachedBoundingBox = this.cachedBoundingBox.clone();
clone.modID = this.modID; clone.modID = this.modID;
clone.boundsModID = -1; clone.boundsModID = -1;
clone.refLengthModID = -1; clone.refLengthModID = -1;
@ -594,7 +594,7 @@ public class FlightConfiguration implements FlightConfigurableParameter<FlightCo
cloneMotor.getMount().setMotorConfig(cloneMotor, copyId); cloneMotor.getMount().setMotorConfig(cloneMotor, copyId);
} }
copy.cachedBounds = this.cachedBounds.clone(); copy.cachedBoundingBox = this.cachedBoundingBox.clone();
copy.modID = this.modID; copy.modID = this.modID;
copy.boundsModID = -1; copy.boundsModID = -1;
copy.refLengthModID = -1; copy.refLengthModID = -1;

View File

@ -1,10 +1,10 @@
package net.sf.openrocket.rocketcomponent; package net.sf.openrocket.rocketcomponent;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.Transformation; import net.sf.openrocket.util.Transformation;

View File

@ -188,13 +188,6 @@ public class LaunchLug extends ExternalComponent implements AnglePositionable, C
return length * Math.PI * (MathUtil.pow2(radius) - MathUtil.pow2(radius - thickness)); return length * Math.PI * (MathUtil.pow2(radius) - MathUtil.pow2(radius - thickness));
} }
/* @Override
public Collection<Coordinate> getComponentBounds() {
ArrayList<Coordinate> bounds = new ArrayList<Coordinate>(2);
addBoundingBox(bounds, 0, length, radius);
return bounds;
}
*/
@Override @Override
public BoundingBox getBoundingBox() { public BoundingBox getBoundingBox() {
return new BoundingBox(0, length, radius); return new BoundingBox(0, length, radius);

View File

@ -133,13 +133,4 @@ public abstract class MassObject extends InternalComponent {
public final double getRotationalUnitInertia() { public final double getRotationalUnitInertia() {
return pow2(radius) / 2; return pow2(radius) / 2;
} }
/*
@Override
public final Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> c = new ArrayList<Coordinate>();
addBound(c, 0, radius);
addBound(c, length, radius);
return c;
}*/
} }

View File

@ -45,34 +45,6 @@ public class PodSet extends ComponentAssembly implements RingInstanceable {
} }
// not strictly accurate, but this should provide an acceptable estimate for total vehicle size
/* @Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = new ArrayList<Coordinate>(8);
double x_min = Double.MAX_VALUE;
double x_max = Double.MIN_VALUE;
double r_max = 0;
Coordinate[] instanceLocations = this.getComponentLocations();
for (Coordinate currentInstanceLocation : instanceLocations) {
if (x_min > (currentInstanceLocation.x)) {
x_min = currentInstanceLocation.x;
}
if (x_max < (currentInstanceLocation.x + this.length)) {
x_max = currentInstanceLocation.x + this.length;
}
if (r_max < (this.getRadiusOffset())) {
r_max = this.getRadiusOffset();
}
}
addBound(bounds, x_min, r_max);
addBound(bounds, x_max, r_max);
return bounds;
}
*/
/** /**
* Check whether the given type can be added to this component. A Stage allows * Check whether the given type can be added to this component. A Stage allows
* only BodyComponents to be added. * only BodyComponents to be added.

View File

@ -295,22 +295,7 @@ public class RailButton extends ExternalComponent implements AnglePositionable,
public String getPatternName(){ public String getPatternName(){
return (this.getInstanceCount() + "-Line"); return (this.getInstanceCount() + "-Line");
} }
/*
@Override
public Collection<Coordinate> getComponentBounds() {
final double r = outerDiameter_m / 2.0;
ArrayList<Coordinate> set = new ArrayList<Coordinate>();
set.add(new Coordinate(r, totalHeight_m, r));
set.add(new Coordinate(r, totalHeight_m, -r));
set.add(new Coordinate(r, 0, r));
set.add(new Coordinate(r, 0, -r));
set.add(new Coordinate(-r, 0, r));
set.add(new Coordinate(-r, 0, -r));
set.add(new Coordinate(-r, totalHeight_m, r));
set.add(new Coordinate(-r, totalHeight_m, -r));
return set;
}
*/
@Override @Override
public Coordinate getComponentCG() { public Coordinate getComponentCG() {
// Math.PI and density are assumed constant through calculation, and thus may be factored out. // Math.PI and density are assumed constant through calculation, and thus may be factored out.

View File

@ -162,14 +162,6 @@ public abstract class RingComponent extends StructuralComponent implements Coaxi
fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE); fireComponentChangeEvent(ComponentChangeEvent.MASS_CHANGE);
} }
/* @Override
public Collection<Coordinate> getComponentBounds() {
List<Coordinate> bounds = new ArrayList<Coordinate>();
addBound(bounds, 0, getOuterRadius());
addBound(bounds, length, getOuterRadius());
return bounds;
}*/
@Override @Override
public Coordinate getComponentCG() { public Coordinate getComponentCG() {
Coordinate cg = Coordinate.ZERO; Coordinate cg = Coordinate.ZERO;

View File

@ -1,26 +0,0 @@
package net.sf.openrocket.rocketcomponent;
import java.util.Collection;
import net.sf.openrocket.util.Coordinate;
public abstract class RocketUtils {
public static double getLength(Rocket rocket) {
double length = 0;
Collection<Coordinate> bounds = rocket.getSelectedConfiguration().getBounds();
if (!bounds.isEmpty()) {
double minX = Double.POSITIVE_INFINITY, maxX = Double.NEGATIVE_INFINITY;
for (Coordinate c : bounds) {
if (c.x < minX)
minX = c.x;
if (c.x > maxX)
maxX = c.x;
}
length = maxX - minX;
}
return length;
}
}

View File

@ -135,21 +135,6 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial
clearPreset(); clearPreset();
} }
/**
* Adds component bounds at a number of points between 0...length.
*/
/* @Override
public Collection<Coordinate> getComponentBounds() {
List<Coordinate> list = new ArrayList<Coordinate>(20);
for (int n = 0; n <= 5; n++) {
double x = n * length / 5;
double r = getRadius(x);
addBound(list, x, r);
}
return list;
}*/
/** /**
* Are there any components whose max diameter isn't at either the * Are there any components whose max diameter isn't at either the
* fore or aft end? I don't know of any. * fore or aft end? I don't know of any.

View File

@ -434,18 +434,6 @@ public class Transition extends SymmetricComponent {
return Math.max(getRadius(x) - thickness, 0); return Math.max(getRadius(x) - thickness, 0);
} }
/* @Override
public Collection<Coordinate> getComponentBounds() {
Collection<Coordinate> bounds = super.getComponentBounds();
if (foreShoulderLength > 0.001)
addBound(bounds, -foreShoulderLength, foreShoulderRadius);
if (aftShoulderLength > 0.001)
addBound(bounds, getLength() + aftShoulderLength, aftShoulderRadius);
return bounds;
}*/
/** /**
* bounding box of transition * bounding box of transition
* *

View File

@ -306,15 +306,6 @@ public class TubeFinSet extends ExternalComponent implements AxialPositionable {
return false; return false;
} }
/* @Override
public Collection<Coordinate> getComponentBounds() {
List<Coordinate> bounds = new ArrayList<Coordinate>(2);
addBoundingBox(bounds, 0, length, outerRadius);
return bounds;
}*/
@Override @Override
public BoundingBox getBoundingBox() { public BoundingBox getBoundingBox() {
return new BoundingBox(0, length, outerRadius); return new BoundingBox(0, length, outerRadius);

View File

@ -127,11 +127,7 @@ public class SimulationStatus implements Monitorable {
} }
} }
if (!Double.isNaN(lugPosition)) { if (!Double.isNaN(lugPosition)) {
double maxX = 0; double maxX = this.configuration.getBoundingBox().max.x;
for (Coordinate c : this.configuration.getBounds()) {
if (c.x > maxX)
maxX = c.x;
}
if (maxX >= lugPosition) { if (maxX >= lugPosition) {
length = Math.max(0, length - (maxX - lugPosition)); length = Math.max(0, length - (maxX - lugPosition));
} }

View File

@ -119,7 +119,13 @@ public class BoundingBox {
return this; return this;
} }
public Coordinate span() { return max.sub( min ); } public Coordinate span() {
Coordinate tmp = max.sub( min );
return new Coordinate(Math.max(tmp.x, 0.0),
Math.max(tmp.y, 0.0),
Math.max(tmp.z, 0.0),
Math.max(tmp.weight, 0.0));
}
public Coordinate[] toArray() { public Coordinate[] toArray() {
return new Coordinate[] { this.min, this.max }; return new Coordinate[] { this.min, this.max };

View File

@ -1 +0,0 @@
Error: Unable to access jarfile OpenRocket.jar

View File

@ -49,6 +49,7 @@ import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.startup.Preferences; import net.sf.openrocket.startup.Preferences;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.MathUtil;
@ -468,64 +469,21 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
redrawExtras = true; redrawExtras = true;
} }
@SuppressWarnings("unused")
private static class Bounds {
double xMin, xMax, xSize;
double yMin, yMax, ySize;
double zMin, zMax, zSize;
double rMax;
}
private Bounds cachedBounds = null;
/**
* Calculates the bounds for the current configuration
*
* @return
*/
private Bounds calculateBounds() {
if (cachedBounds != null) {
return cachedBounds;
} else {
final Bounds b = new Bounds();
final FlightConfiguration configuration = rkt.getSelectedConfiguration();
final Collection<Coordinate> bounds = configuration.getBounds();
for (Coordinate c : bounds) {
b.xMax = Math.max(b.xMax, c.x);
b.xMin = Math.min(b.xMin, c.x);
b.yMax = Math.max(b.yMax, c.y);
b.yMin = Math.min(b.yMin, c.y);
b.zMax = Math.max(b.zMax, c.z);
b.zMin = Math.min(b.zMin, c.z);
double r = MathUtil.hypot(c.y, c.z);
b.rMax = Math.max(b.rMax, r);
}
b.xSize = b.xMax - b.xMin;
b.ySize = b.yMax - b.yMin;
b.zSize = b.zMax - b.zMin;
cachedBounds = b;
return b;
}
}
private void setupView(final GL2 gl, final GLU glu) { private void setupView(final GL2 gl, final GLU glu) {
gl.glLoadIdentity(); gl.glLoadIdentity();
gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_POSITION, gl.glLightfv(GLLightingFunc.GL_LIGHT1, GLLightingFunc.GL_POSITION,
lightPosition, 0); lightPosition, 0);
// Get the bounds // Get the bounding box
final Bounds b = calculateBounds(); final BoundingBox b = rkt.getSelectedConfiguration().getBoundingBox();
// Calculate the distance needed to fit the bounds in both the X and Y // Calculate the distance needed to fit the bounds in both the X and Y
// direction // direction
// Add 10% for space around it. // Add 10% for space around it.
final double dX = (b.xSize * 1.2 / 2.0) final double dX = (b.max.x * 1.2 / 2.0)
/ Math.tan(Math.toRadians(fovX / 2.0)); / Math.tan(Math.toRadians(fovX / 2.0));
final double dY = (b.rMax * 2.0 * 1.2 / 2.0) final double dY = (b.max.y * 2.0 * 1.2 / 2.0)
/ Math.tan(Math.toRadians(fovY / 2.0)); / Math.tan(Math.toRadians(fovY / 2.0));
// Move back the greater of the 2 distances // Move back the greater of the 2 distances
@ -535,7 +493,8 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
gl.glRotated(roll * (180.0 / Math.PI), 1, 0, 0); gl.glRotated(roll * (180.0 / Math.PI), 1, 0, 0);
// Center the rocket in the view. // Center the rocket in the view.
gl.glTranslated(-b.xMin - b.xSize / 2.0, 0, 0); // gl.glTranslated(-b.xMin - b.xSize / 2.0, 0, 0);
gl.glTranslated((b.min.x - b.max.x) / 2.0, 0, 0);
//Change to LEFT Handed coordinates //Change to LEFT Handed coordinates
gl.glScaled(1, 1, -1); gl.glScaled(1, 1, -1);
@ -554,7 +513,6 @@ public class RocketFigure3d extends JPanel implements GLEventListener {
*/ */
public void updateFigure() { public void updateFigure() {
log.debug("3D Figure Updated"); log.debug("3D Figure Updated");
cachedBounds = null;
if (canvas != null) { if (canvas != null) {
((GLAutoDrawable) canvas).invoke(true, new GLRunnable() { ((GLAutoDrawable) canvas).invoke(true, new GLRunnable() {
@Override @Override

View File

@ -2,7 +2,6 @@ package net.sf.openrocket.gui.figure3d;
import java.awt.Point; import java.awt.Point;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -28,6 +27,7 @@ import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.InstanceMap; import net.sf.openrocket.rocketcomponent.InstanceMap;
import net.sf.openrocket.rocketcomponent.MotorMount; import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.Transformation; import net.sf.openrocket.util.Transformation;

View File

@ -52,6 +52,7 @@ import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.startup.Preferences; import net.sf.openrocket.startup.Preferences;
import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.Color; import net.sf.openrocket.util.Color;
import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.MathUtil;
@ -92,7 +93,6 @@ public class PhotoPanel extends JPanel implements GLEventListener {
@Override @Override
public boolean run(final GLAutoDrawable drawable) { public boolean run(final GLAutoDrawable drawable) {
PhotoPanel.this.configuration = doc.getSelectedConfiguration(); PhotoPanel.this.configuration = doc.getSelectedConfiguration();
cachedBounds = null;
rr = new RealisticRenderer(doc); rr = new RealisticRenderer(doc);
rr.init(drawable); rr.init(drawable);
@ -246,11 +246,11 @@ public class PhotoPanel extends JPanel implements GLEventListener {
draw(drawable, 0); draw(drawable, 0);
if (p.isMotionBlurred()) { if (p.isMotionBlurred()) {
Bounds b = calculateBounds(); BoundingBox b = configuration.getBoundingBox();
float m = .6f; float m = .6f;
int c = 10; int c = 10;
float d = (float) b.xSize / 25.0f; float d = (float) (b.max.x - b.min.x) / 25.0f;
gl.glAccum(GL2.GL_LOAD, m); gl.glAccum(GL2.GL_LOAD, m);
@ -391,11 +391,11 @@ public class PhotoPanel extends JPanel implements GLEventListener {
gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_SPECULAR, gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_SPECULAR,
new float[] { color[0], color[1], color[2], 1 }, 0); new float[] { color[0], color[1], color[2], 1 }, 0);
Bounds b = calculateBounds(); BoundingBox b = configuration.getBoundingBox();
gl.glLightf(GLLightingFunc.GL_LIGHT2, gl.glLightf(GLLightingFunc.GL_LIGHT2,
GLLightingFunc.GL_QUADRATIC_ATTENUATION, 20f); GLLightingFunc.GL_QUADRATIC_ATTENUATION, 20f);
gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_POSITION, gl.glLightfv(GLLightingFunc.GL_LIGHT2, GLLightingFunc.GL_POSITION,
new float[] { (float) (b.xMax + .1f), 0, 0, 1 }, 0); new float[] { (float) (b.max.x + .1f), 0, 0, 1 }, 0);
gl.glEnable(GLLightingFunc.GL_LIGHT2); gl.glEnable(GLLightingFunc.GL_LIGHT2);
} else { } else {
gl.glDisable(GLLightingFunc.GL_LIGHT2); gl.glDisable(GLLightingFunc.GL_LIGHT2);
@ -478,56 +478,14 @@ public class PhotoPanel extends JPanel implements GLEventListener {
ratio = (double) w / (double) h; ratio = (double) w / (double) h;
} }
@SuppressWarnings("unused")
private static class Bounds {
double xMin, xMax, xSize;
double yMin, yMax, ySize;
double zMin, zMax, zSize;
double rMax;
}
private Bounds cachedBounds = null;
/**
* Calculates the bounds for the current configuration
*
* @return
*/
private Bounds calculateBounds() {
if (cachedBounds != null) {
return cachedBounds;
} else {
final Bounds b = new Bounds();
final Collection<Coordinate> bounds = configuration.getBounds();
for (Coordinate c : bounds) {
b.xMax = Math.max(b.xMax, c.x);
b.xMin = Math.min(b.xMin, c.x);
b.yMax = Math.max(b.yMax, c.y);
b.yMin = Math.min(b.yMin, c.y);
b.zMax = Math.max(b.zMax, c.z);
b.zMin = Math.min(b.zMin, c.z);
double r = MathUtil.hypot(c.y, c.z);
b.rMax = Math.max(b.rMax, r);
}
b.xSize = b.xMax - b.xMin;
b.ySize = b.yMax - b.yMin;
b.zSize = b.zMax - b.zMin;
cachedBounds = b;
return b;
}
}
private void setupModel(final GL2 gl) { private void setupModel(final GL2 gl) {
// Get the bounds
final Bounds b = calculateBounds();
gl.glRotated(-p.getPitch() * (180.0 / Math.PI), 0, 0, 1); gl.glRotated(-p.getPitch() * (180.0 / Math.PI), 0, 0, 1);
gl.glRotated(p.getYaw() * (180.0 / Math.PI), 0, 1, 0); gl.glRotated(p.getYaw() * (180.0 / Math.PI), 0, 1, 0);
gl.glRotated(p.getRoll() * (180.0 / Math.PI), 1, 0, 0); gl.glRotated(p.getRoll() * (180.0 / Math.PI), 1, 0, 0);
// Center the rocket in the view. // Center the rocket in the view.
gl.glTranslated(-b.xMin - b.xSize / 2.0, 0, 0); final BoundingBox b = configuration.getBoundingBox();
gl.glTranslated((b.min.x - b.max.x) / 2.0, 0, 0);
} }
} }

View File

@ -61,10 +61,6 @@ public class RocketInfo implements FigureElement {
private float line = 0; private float line = 0;
private float x1, x2, y1, y2; private float x1, x2, y1, y2;
public RocketInfo(FlightConfiguration configuration) { public RocketInfo(FlightConfiguration configuration) {
this.configuration = configuration; this.configuration = configuration;
this.stabilityUnits = UnitGroup.stabilityUnits(configuration); this.stabilityUnits = UnitGroup.stabilityUnits(configuration);

View File

@ -14,7 +14,6 @@ import java.awt.geom.Ellipse2D;
import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -34,6 +33,7 @@ import net.sf.openrocket.rocketcomponent.MotorMount;
import net.sf.openrocket.rocketcomponent.Rocket; import net.sf.openrocket.rocketcomponent.Rocket;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.ArrayList;
import net.sf.openrocket.util.BoundingBox; import net.sf.openrocket.util.BoundingBox;
import net.sf.openrocket.util.BugException; import net.sf.openrocket.util.BugException;
import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Coordinate;

View File

@ -67,12 +67,12 @@ import net.sf.openrocket.simulation.listeners.SimulationListener;
import net.sf.openrocket.simulation.listeners.system.ApogeeEndListener; import net.sf.openrocket.simulation.listeners.system.ApogeeEndListener;
import net.sf.openrocket.simulation.listeners.system.InterruptListener; import net.sf.openrocket.simulation.listeners.system.InterruptListener;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
import net.sf.openrocket.util.ChangeSource; import net.sf.openrocket.util.ChangeSource;
import net.sf.openrocket.util.Chars; import net.sf.openrocket.util.Chars;
import net.sf.openrocket.util.Coordinate; import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.MathUtil; import net.sf.openrocket.util.MathUtil;
import net.sf.openrocket.util.StateChangeListener; import net.sf.openrocket.util.StateChangeListener;
import net.sf.openrocket.unit.UnitGroup;
/** /**
@ -607,18 +607,7 @@ public class RocketPanel extends JPanel implements TreeSelectionListener, Change
figure3d.setCP(cp); figure3d.setCP(cp);
// Length bound is assumed to be tight // Length bound is assumed to be tight
double length = 0; double length = curConfig.getLength();
Collection<Coordinate> bounds = curConfig.getBounds();
if (!bounds.isEmpty()) {
double minX = Double.POSITIVE_INFINITY, maxX = Double.NEGATIVE_INFINITY;
for (Coordinate c : bounds) {
if (c.x < minX)
minX = c.x;
if (c.x > maxX)
maxX = c.x;
}
length = maxX - minX;
}
double diameter = Double.NaN; double diameter = Double.NaN;
for (RocketComponent c : curConfig.getCoreComponents()) { for (RocketComponent c : curConfig.getCoreComponents()) {