From 48b177688ea2ad003a126b609ad51f8a31723571 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Tue, 6 Sep 2022 23:03:37 +0200 Subject: [PATCH 1/5] [#1646] Increase fin root resolution --- core/src/net/sf/openrocket/rocketcomponent/FinSet.java | 2 +- .../net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java index 107383c16..56fb0a31c 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java @@ -1073,7 +1073,7 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona // for anything more complicated, increase the count: if ((body instanceof Transition) && (((Transition)body).getType() != Shape.CONICAL)) { // the maximum precision to enforce when calculating the areas of fins (especially on curved parent bodies) - final double xWidth = 0.0025; // width (in meters) of each individual iteration + final double xWidth = 0.005; // width (in meters) of each individual iteration divisionCount = (int) Math.ceil(intervalLength / xWidth); // When creating body curves, don't create more than this many divisions. -- only relevant on very large components diff --git a/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java index f4d828093..33c453338 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java @@ -34,8 +34,9 @@ public class FinRenderer { gl.glTranslated(-bounds.min.x, -bounds.min.y - finSet.getBodyRadius(), 0); gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); - Coordinate finPoints[] = finSet.getFinPointsWithRoot(); - Coordinate tabPoints[] = finSet.getTabPoints(); + Coordinate[] finPoints = finSet.getFinPointsWithRoot(); + Coordinate[] tabPoints = finSet.getTabPoints(); + { gl.glPushMatrix(); From 6b153a5ef5a925d5f5a48532d2d7bd129b4e14e8 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 7 Sep 2022 10:39:19 +0200 Subject: [PATCH 2/5] Limit maximum fin root division count --- core/src/net/sf/openrocket/rocketcomponent/FinSet.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java index 56fb0a31c..60ec23a18 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java @@ -1073,11 +1073,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona // for anything more complicated, increase the count: if ((body instanceof Transition) && (((Transition)body).getType() != Shape.CONICAL)) { // the maximum precision to enforce when calculating the areas of fins (especially on curved parent bodies) - final double xWidth = 0.005; // width (in meters) of each individual iteration + final double xWidth = 0.0025; // width (in meters) of each individual iteration divisionCount = (int) Math.ceil(intervalLength / xWidth); // When creating body curves, don't create more than this many divisions. -- only relevant on very large components - final int maximumBodyDivisionCount = 100; + // a too high division count will cause the 3D render to have invisible faces because it can't deal with the geometry. + final int maximumBodyDivisionCount = 20; divisionCount = Math.min(maximumBodyDivisionCount, divisionCount); } From b806ed2948b54b3b94604ed4aaadc7be1db1ab53 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 7 Sep 2022 10:52:13 +0200 Subject: [PATCH 3/5] Use low-res root geometry for 3D rendering --- .../sf/openrocket/rocketcomponent/FinSet.java | 34 +++++++++++++++++-- .../gui/figure3d/geometry/FinRenderer.java | 2 +- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java index 60ec23a18..e43cb944d 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java @@ -961,6 +961,22 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona */ public abstract Coordinate[] getFinPoints(); + /** + * used to get body points for the profile design view + * + * @return points representing the fin-root points, relative to ( x: fin-front, y: centerline ) i.e. relto: fin Component reference point + */ + public Coordinate[] getRootPoints(final int maximumBodyDivisionCount) { + if( null == parent){ + return new Coordinate[]{Coordinate.ZERO}; + } + + final Coordinate finLead = getFinFront(); + final double xFinEnd = finLead.x + getLength(); + + return getMountPoints( finLead.x, xFinEnd, -finLead.x, -finLead.y, maximumBodyDivisionCount); + } + /** * used to get body points for the profile design view * @@ -984,6 +1000,16 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona return combineCurves(getFinPoints(), getRootPoints()); } + /** + * Return a list of coordinates defining the geometry of a single fin, including the parent's body points . + * + * This low res version is for 3D rendering, as a too high resolution would cause clipping and invisible fin faces. + * This should at one point be solved by rendering the fin faces using triangulation, instead of how it's currently implemented. + */ + public Coordinate[] getFinPointsWithLowResRoot() { + return combineCurves(getFinPoints(), getRootPoints(20)); + } + /** * Return a list of X,Y coordinates defining the geometry of a single fin tab. * The origin is the leading root edge, and the tab height (or 'depth') is @@ -1060,7 +1086,8 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona * * @return points representing the mount's points */ - private Coordinate[] getMountPoints(final double xStart, final double xEnd, final double xOffset, final double yOffset) { + private Coordinate[] getMountPoints(final double xStart, final double xEnd, final double xOffset, final double yOffset, + final int maximumBodyDivisionCount) { if (parent == null) { return new Coordinate[]{Coordinate.ZERO}; } @@ -1078,7 +1105,6 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona // When creating body curves, don't create more than this many divisions. -- only relevant on very large components // a too high division count will cause the 3D render to have invisible faces because it can't deal with the geometry. - final int maximumBodyDivisionCount = 20; divisionCount = Math.min(maximumBodyDivisionCount, divisionCount); } @@ -1108,6 +1134,10 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona return points; } + + private Coordinate[] getMountPoints(final double xStart, final double xEnd, final double xOffset, final double yOffset) { + return getMountPoints(xStart, xEnd, xOffset, yOffset, 100); + } @Override public double getAngleOffset() { diff --git a/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java index 33c453338..8beb2c16d 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java @@ -34,7 +34,7 @@ public class FinRenderer { gl.glTranslated(-bounds.min.x, -bounds.min.y - finSet.getBodyRadius(), 0); gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); - Coordinate[] finPoints = finSet.getFinPointsWithRoot(); + Coordinate[] finPoints = finSet.getFinPointsWithLowResRoot(); Coordinate[] tabPoints = finSet.getTabPoints(); { From db16ebc99414b3c3996d05b61741fb6440d2e00b Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 7 Sep 2022 11:01:26 +0200 Subject: [PATCH 4/5] Use low-res tab geometry for fin 3D rendering --- .../sf/openrocket/rocketcomponent/FinSet.java | 58 +++++++++++++++++-- .../gui/figure3d/geometry/FinRenderer.java | 2 +- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java index e43cb944d..544a93d77 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java @@ -29,6 +29,12 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona */ public static final double MAX_CANT_RADIANS = (15.0 * Math.PI / 180); + /** + * Maximum number of root points in the root geometry. + */ + private static final int MAX_ROOT_DIVISIONS = 100; + private static final int MAX_ROOT_DIVISIONS_LOW_RES = 20; + public void setOverrideMass() { } @@ -1007,7 +1013,7 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona * This should at one point be solved by rendering the fin faces using triangulation, instead of how it's currently implemented. */ public Coordinate[] getFinPointsWithLowResRoot() { - return combineCurves(getFinPoints(), getRootPoints(20)); + return combineCurves(getFinPoints(), getRootPoints(MAX_ROOT_DIVISIONS_LOW_RES)); } /** @@ -1023,7 +1029,6 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona * @return List of XY-coordinates. */ public Coordinate[] getTabPoints() { - if (MathUtil.equals(getTabHeight(), 0) || MathUtil.equals(getTabLength(), 0)){ return new Coordinate[]{}; @@ -1039,9 +1044,50 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona } } + return generateTabPointsWithRoot(rootPoints); + } + + /** + * Return a list of X,Y coordinates defining the geometry of a single fin tab. + * The origin is the leading root edge, and the tab height (or 'depth') is + * the radial distance inwards from the reference point, depending on positioning method: + * if via TOP: tab front edge + * if via MIDDLE: tab middle + * if via BOTTOM: tab trailing edge + * + * The tab coordinates will generally have negative y values. + * + * This low res version is for 3D rendering, as a too high resolution would cause clipping and invisible fin faces. + * This should at one point be solved by rendering the fin faces using triangulation, instead of how it's currently implemented. + * + * @return List of XY-coordinates. + */ + public Coordinate[] getTabPointsLowRes() { + if (MathUtil.equals(getTabHeight(), 0) || + MathUtil.equals(getTabLength(), 0)){ + return new Coordinate[]{}; + } + + final double xTabFront = getTabFrontEdge(); + final double xTabTrail = getTabTrailingEdge(); + + List rootPoints = new ArrayList<>(); + for (Coordinate point : getRootPoints(MAX_ROOT_DIVISIONS_LOW_RES)) { + if (point.x > xTabFront && point.x < xTabTrail) { + rootPoints.add(point); + } + } + + return generateTabPointsWithRoot(rootPoints); + } + + private Coordinate[] generateTabPointsWithRoot(List rootPoints) { + final double xTabFront = getTabFrontEdge(); + final double xTabTrail = getTabTrailingEdge(); + Coordinate[] tabPoints = new Coordinate[4]; final Coordinate finFront = this.getFinFront(); - + final SymmetricComponent body = (SymmetricComponent)this.getParent(); // // limit the new heights to be no greater than the current body radius. @@ -1049,8 +1095,8 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona double yTabTrail = Double.NaN; double yTabBottom = Double.NaN; if( null != body ){ - yTabFront = body.getRadius( finFront.x + xTabFront ) - finFront.y; - yTabTrail = body.getRadius( finFront.x + xTabTrail ) - finFront.y; + yTabFront = body.getRadius( finFront.x + xTabFront) - finFront.y; + yTabTrail = body.getRadius( finFront.x + xTabTrail) - finFront.y; yTabBottom = MathUtil.min(yTabFront, yTabTrail) - tabHeight; } @@ -1136,7 +1182,7 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona } private Coordinate[] getMountPoints(final double xStart, final double xEnd, final double xOffset, final double yOffset) { - return getMountPoints(xStart, xEnd, xOffset, yOffset, 100); + return getMountPoints(xStart, xEnd, xOffset, yOffset, MAX_ROOT_DIVISIONS); } @Override diff --git a/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java b/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java index 8beb2c16d..c4b1e2c4a 100644 --- a/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java +++ b/swing/src/net/sf/openrocket/gui/figure3d/geometry/FinRenderer.java @@ -35,7 +35,7 @@ public class FinRenderer { gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); Coordinate[] finPoints = finSet.getFinPointsWithLowResRoot(); - Coordinate[] tabPoints = finSet.getTabPoints(); + Coordinate[] tabPoints = finSet.getTabPointsLowRes(); { gl.glPushMatrix(); From 58c2809ee401952145bd5ea9c354c46795ffb9d0 Mon Sep 17 00:00:00 2001 From: SiboVG Date: Wed, 7 Sep 2022 21:43:04 +0200 Subject: [PATCH 5/5] Limit low res root geometry to 15 points Because otherwise you would still get 3D issues on large rockets --- core/src/net/sf/openrocket/rocketcomponent/FinSet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java index 544a93d77..4f9d3e635 100644 --- a/core/src/net/sf/openrocket/rocketcomponent/FinSet.java +++ b/core/src/net/sf/openrocket/rocketcomponent/FinSet.java @@ -33,7 +33,7 @@ public abstract class FinSet extends ExternalComponent implements AxialPositiona * Maximum number of root points in the root geometry. */ private static final int MAX_ROOT_DIVISIONS = 100; - private static final int MAX_ROOT_DIVISIONS_LOW_RES = 20; + private static final int MAX_ROOT_DIVISIONS_LOW_RES = 15; public void setOverrideMass() { }