Use instance context for orientation/position

Fixes issues with components in pods not being oriented correctly! :)
This commit is contained in:
SiboVG 2023-08-13 23:29:16 +02:00
parent fc7f71e11f
commit 87c4cbec97
10 changed files with 106 additions and 87 deletions

View File

@ -17,6 +17,8 @@ import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.ComponentAssembly;
import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.InstanceMap;
import net.sf.openrocket.rocketcomponent.LaunchLug;
import net.sf.openrocket.rocketcomponent.MassObject;
import net.sf.openrocket.rocketcomponent.RailButton;
@ -28,6 +30,7 @@ import net.sf.openrocket.rocketcomponent.TubeFinSet;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -132,8 +135,13 @@ public class OBJExporterFactory {
continue;
}
InstanceMap map = configuration.getActiveInstances();
ArrayList<InstanceContext> contexts = map.get(component);
contexts.get(0).transform.getXrotation();
String groupName = component.getName() + "_" + idx;
handleComponent(obj, this.transformer, component, groupName, this.LOD);
handleComponent(obj, this.configuration, this.transformer, component, groupName, this.LOD);
// TODO: motor rendering
@ -161,8 +169,8 @@ public class OBJExporterFactory {
}
@SuppressWarnings("unchecked") // This is safe because of the structure we set up.
private <T extends RocketComponent> void handleComponent(DefaultObj obj, CoordTransform transformer, T component,
String groupName, ObjUtils.LevelOfDetail LOD) {
private <T extends RocketComponent> void handleComponent(DefaultObj obj, FlightConfiguration config, CoordTransform transformer,
T component, String groupName, ObjUtils.LevelOfDetail LOD) {
ExporterFactory<T> factory = null;
Class<?> currentClass = component.getClass();
@ -176,12 +184,12 @@ public class OBJExporterFactory {
throw new IllegalArgumentException("Unsupported component type: " + component.getClass().getName());
}
final RocketComponentExporter<T> exporter = factory.create(obj, transformer, component, groupName, LOD);
final RocketComponentExporter<T> exporter = factory.create(obj, config, transformer, component, groupName, LOD);
exporter.addToObj();
}
interface ExporterFactory<T extends RocketComponent> {
RocketComponentExporter<T> create(DefaultObj obj, CoordTransform transformer, T component, String groupName,
ObjUtils.LevelOfDetail LOD);
RocketComponentExporter<T> create(DefaultObj obj, FlightConfiguration config, CoordTransform transformer,
T component, String groupName, ObjUtils.LevelOfDetail LOD);
}
}

View File

@ -6,12 +6,14 @@ import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.CylinderExporter;
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.util.Coordinate;
public class BodyTubeExporter extends RocketComponentExporter<BodyTube> {
public BodyTubeExporter(DefaultObj obj, CoordTransform transformer, BodyTube component, String groupName,
ObjUtils.LevelOfDetail LOD) {
super(obj, transformer, component, groupName, LOD);
public BodyTubeExporter(DefaultObj obj, FlightConfiguration config, CoordTransform transformer, BodyTube component,
String groupName, ObjUtils.LevelOfDetail LOD) {
super(obj, config, transformer, component, groupName, LOD);
}
@Override
@ -20,16 +22,15 @@ public class BodyTubeExporter extends RocketComponentExporter<BodyTube> {
final float innerRadius = (float) component.getInnerRadius();
final float length = (float) component.getLength();
final boolean isFilled = component.isFilled();
final Coordinate[] locations = component.getComponentLocations();
// Generate the mesh
for (Coordinate location : locations) {
generateMesh(outerRadius, innerRadius, length, isFilled, location);
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
generateMesh(outerRadius, innerRadius, length, isFilled, context);
}
}
private void generateMesh(float outerRadius, float innerRadius, float length, boolean isFilled,
Coordinate location) {
InstanceContext context) {
int startIdx = obj.getNumVertices();
if (isFilled || Float.compare(innerRadius, 0) == 0) {
@ -45,6 +46,7 @@ public class BodyTubeExporter extends RocketComponentExporter<BodyTube> {
int endIdx = Math.max(obj.getNumVertices() - 1, startIdx); // Clamp in case no vertices were added
// Translate the mesh to the position in the rocket
Coordinate location = context.getLocation();
ObjUtils.translateVerticesFromComponentLocation(obj, transformer, startIdx, endIdx, location);
}
}

View File

@ -7,15 +7,17 @@ import net.sf.openrocket.file.wavefrontobj.DefaultObj;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.PolygonExporter;
import net.sf.openrocket.rocketcomponent.FinSet;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.util.Coordinate;
import java.util.ArrayList;
import java.util.List;
public class FinSetExporter extends RocketComponentExporter<FinSet> {
public FinSetExporter(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, FinSet component,
String groupName, ObjUtils.LevelOfDetail LOD) {
super(obj, transformer, component, groupName, LOD);
public FinSetExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
FinSet component, String groupName, ObjUtils.LevelOfDetail LOD) {
super(obj, config, transformer, component, groupName, LOD);
}
@Override
@ -32,21 +34,15 @@ public class FinSetExporter extends RocketComponentExporter<FinSet> {
final FloatPoints floatTabPoints = getPointsAsFloat(tabPointsReversed);
final float thickness = (float) component.getThickness();
boolean hasTabs = component.getTabLength() > 0 && component.getTabHeight() > 0;
final Coordinate[] locations = component.getComponentLocations();
final Coordinate[] angles = component.getComponentAngles();
if (locations.length != angles.length) {
throw new IllegalArgumentException("Number of locations and angles must match");
}
// Generate the fin meshes
for (int i = 0; i < locations.length; i++) {
generateMesh(floatPoints, floatTabPoints, thickness, hasTabs, locations[i], angles[i]);
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
generateMesh(floatPoints, floatTabPoints, thickness, hasTabs, context);
}
}
private void generateMesh(FloatPoints floatPoints, FloatPoints floatTabPoints, float thickness,
boolean hasTabs, Coordinate location, Coordinate angle) {
boolean hasTabs, InstanceContext context) {
// Generate the mesh
final int startIdx = obj.getNumVertices();
final int normalsStartIdx = obj.getNumNormals();
@ -77,12 +73,16 @@ public class FinSetExporter extends RocketComponentExporter<FinSet> {
orig.getX(), orig.getY(), orig.getZ());
// Then do the component rotation (axial rotation)
rot = transformer.convertRot(angle.x, angle.y, angle.z);
final double rotX = context.transform.getXrotation();
final double rotY = context.transform.getYrotation();
final double rotZ = context.transform.getZrotation();
rot = transformer.convertRot(rotX, rotY, rotZ);
ObjUtils.rotateVertices(obj, startIdx, endIdx, normalsStartIdx, normalsEndIdx,
rot.getX(), rot.getY(), rot.getZ(),
orig.getX(), orig.getY(), orig.getZ());
// Translate the mesh to the position in the rocket
final Coordinate location = context.getLocation();
ObjUtils.translateVerticesFromComponentLocation(obj, transformer, startIdx, endIdx, location);
}

View File

@ -6,29 +6,30 @@ import net.sf.openrocket.file.wavefrontobj.DefaultObj;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.CylinderExporter;
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.LaunchLug;
import net.sf.openrocket.util.Coordinate;
public class LaunchLugExporter extends RocketComponentExporter<LaunchLug> {
public LaunchLugExporter(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, LaunchLug component,
String groupName, ObjUtils.LevelOfDetail LOD) {
super(obj, transformer, component, groupName, LOD);
public LaunchLugExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
LaunchLug component, String groupName, ObjUtils.LevelOfDetail LOD) {
super(obj, config, transformer, component, groupName, LOD);
}
@Override
public void addToObj() {
final Coordinate[] locations = component.getComponentLocations();
final float outerRadius = (float) component.getOuterRadius();
final float innerRadius = (float) component.getInnerRadius();
final float length = (float) component.getLength();
// Generate the mesh
for (Coordinate location : locations) {
generateMesh(outerRadius, innerRadius, length, location);
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
generateMesh(outerRadius, innerRadius, length, context);
}
}
private void generateMesh(float outerRadius, float innerRadius, float length, Coordinate location) {
private void generateMesh(float outerRadius, float innerRadius, float length, InstanceContext context) {
int startIdx = obj.getNumVertices();
// Generate the instance mesh
@ -45,6 +46,7 @@ public class LaunchLugExporter extends RocketComponentExporter<LaunchLug> {
int endIdx = Math.max(obj.getNumVertices() - 1, startIdx); // Clamp in case no vertices were added
// Translate the mesh to the position in the rocket
final Coordinate location = context.getLocation();
ObjUtils.translateVerticesFromComponentLocation(obj, transformer, startIdx, endIdx, location);
}
}

View File

@ -5,31 +5,32 @@ import net.sf.openrocket.file.wavefrontobj.CoordTransform;
import net.sf.openrocket.file.wavefrontobj.DefaultObj;
import net.sf.openrocket.file.wavefrontobj.DefaultObjFace;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.MassObject;
import net.sf.openrocket.util.Coordinate;
import net.sf.openrocket.util.RocketComponentUtils;
public class MassObjectExporter extends RocketComponentExporter<MassObject> {
public MassObjectExporter(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, MassObject component,
String groupName, ObjUtils.LevelOfDetail LOD) {
super(obj, transformer, component, groupName, LOD);
public MassObjectExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
MassObject component, String groupName, ObjUtils.LevelOfDetail LOD) {
super(obj, config, transformer, component, groupName, LOD);
}
@Override
public void addToObj() {
obj.setActiveGroupNames(groupName);
final Coordinate[] locations = component.getComponentLocations();
final int numSides = LOD.getValue() / 2;
final int numStacks = LOD.getValue() / 2;
// Generate the mesh
for (Coordinate location : locations) {
generateMesh(numSides, numStacks, location);
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
generateMesh(numSides, numStacks, context);
}
}
private void generateMesh(int numSides, int numStacks, Coordinate location) {
private void generateMesh(int numSides, int numStacks, InstanceContext context) {
// Other meshes may have been added to the obj, so we need to keep track of the starting indices
int startIdx = obj.getNumVertices();
int normalsStartIdx = obj.getNumNormals();
@ -134,6 +135,7 @@ public class MassObjectExporter extends RocketComponentExporter<MassObject> {
// Translate the mesh to the position in the rocket
// We will create an offset location that has the same effect as the axial rotation of the mass object
final Coordinate location = context.getLocation();
Coordinate offsetLocation = getOffsetLocation(location);
ObjUtils.translateVerticesFromComponentLocation(obj, transformer, startIdx, endIdx, offsetLocation);
}

View File

@ -8,6 +8,8 @@ import net.sf.openrocket.file.wavefrontobj.DefaultObjFace;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.CylinderExporter;
import net.sf.openrocket.file.wavefrontobj.export.shapes.DiskExporter;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.RailButton;
import net.sf.openrocket.util.Coordinate;
@ -23,9 +25,9 @@ public class RailButtonExporter extends RocketComponentExporter<RailButton> {
* @param groupName The name of the group to export to
* @param LOD Level of detail to use for the export (e.g. '80')
*/
public RailButtonExporter(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, RailButton component,
String groupName, ObjUtils.LevelOfDetail LOD) {
super(obj, transformer, component, groupName, LOD);
public RailButtonExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
RailButton component, String groupName, ObjUtils.LevelOfDetail LOD) {
super(obj, config, transformer, component, groupName, LOD);
}
@Override
@ -38,18 +40,15 @@ public class RailButtonExporter extends RocketComponentExporter<RailButton> {
final float innerHeight = (float) component.getInnerHeight();
final float flangeHeight = (float) component.getFlangeHeight();
final float screwHeight = (float) component.getScrewHeight();
final Coordinate[] locations = component.getComponentLocations();
final Coordinate[] angles = component.getComponentAngles();
// Generate the mesh
for (int i = 0; i < locations.length; i++) {
generateMesh(outerRadius, innerRadius, baseHeight, innerHeight, flangeHeight, screwHeight,
locations[i], angles[i]);
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
generateMesh(outerRadius, innerRadius, baseHeight, innerHeight, flangeHeight, screwHeight, context);
}
}
private void generateMesh(float outerRadius, float innerRadius, float baseHeight, float innerHeight, float flangeHeight,
float screwHeight, Coordinate location, Coordinate angle) {
float screwHeight, InstanceContext context) {
final int startIdx = obj.getNumVertices();
final int normalStartIdx = obj.getNumNormals();
@ -109,16 +108,17 @@ public class RailButtonExporter extends RocketComponentExporter<RailButton> {
rot.getX(), rot.getY(), rot.getZ(),
orig.getX(), orig.getY(), orig.getZ());
// Then do the axial rotation
rX = angle.x + component.getAngleOffset();
rY = 0;
rZ = 0;
rot = transformer.convertRot(rX, rY, rZ);
// Then do the component rotation (axial rotation)
final double rotX = context.transform.getXrotation() + component.getAngleOffset();
final double rotY = context.transform.getYrotation();
final double rotZ = context.transform.getZrotation();
rot = transformer.convertRot(rotX, rotY, rotZ);
ObjUtils.rotateVertices(obj, startIdx, endIdx, normalStartIdx, normalEndIdx,
rot.getX(), rot.getY(), rot.getZ(),
orig.getX(), orig.getY(), orig.getZ());
// Translate the mesh to the position in the rocket
final Coordinate location = context.getLocation();
ObjUtils.translateVerticesFromComponentLocation(obj, transformer, startIdx, endIdx, location);
}

View File

@ -6,13 +6,15 @@ import net.sf.openrocket.file.wavefrontobj.DefaultObj;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.CylinderExporter;
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.RingComponent;
import net.sf.openrocket.util.Coordinate;
public class RingComponentExporter extends RocketComponentExporter<RingComponent> {
public RingComponentExporter(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, RingComponent component,
String groupName, ObjUtils.LevelOfDetail LOD) {
super(obj, transformer, component, groupName, LOD);
public RingComponentExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
RingComponent component, String groupName, ObjUtils.LevelOfDetail LOD) {
super(obj, config, transformer, component, groupName, LOD);
}
@Override
@ -20,15 +22,14 @@ public class RingComponentExporter extends RocketComponentExporter<RingComponent
final float outerRadius = (float) component.getOuterRadius();
final float innerRadius = (float) component.getInnerRadius();
final float length = (float) component.getLength();
final Coordinate[] locations = component.getComponentLocations();
// Generate the mesh
for (Coordinate location : locations) {
generateMesh(outerRadius, innerRadius, length, location);
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
generateMesh(outerRadius, innerRadius, length, context);
}
}
private void generateMesh(float outerRadius, float innerRadius, float length, Coordinate location) {
private void generateMesh(float outerRadius, float innerRadius, float length, InstanceContext context) {
int startIdx = obj.getNumVertices();
if (Float.compare(innerRadius, 0) == 0) {
@ -44,6 +45,7 @@ public class RingComponentExporter extends RocketComponentExporter<RingComponent
int endIdx = Math.max(obj.getNumVertices() - 1, startIdx); // Clamp in case no vertices were added
// Translate the mesh to the position in the rocket
final Coordinate location = context.getLocation();
ObjUtils.translateVerticesFromComponentLocation(obj, transformer, startIdx, endIdx, location);
}
}

View File

@ -5,6 +5,7 @@ import net.sf.openrocket.file.wavefrontobj.CoordTransform;
import net.sf.openrocket.file.wavefrontobj.DefaultObj;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.OBJExporterFactory;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.RocketComponent;
/**
@ -15,6 +16,7 @@ import net.sf.openrocket.rocketcomponent.RocketComponent;
*/
public abstract class RocketComponentExporter<T extends RocketComponent> {
protected final DefaultObj obj;
protected final FlightConfiguration config;
protected final T component;
protected final String groupName;
protected final ObjUtils.LevelOfDetail LOD;
@ -23,14 +25,16 @@ public abstract class RocketComponentExporter<T extends RocketComponent> {
/**
* Wavefront OBJ exporter for a rocket component.
* @param obj The OBJ to export to
* @param config The flight configuration to use for the export
* @param transformer Coordinate system transformer to use to switch from the OpenRocket coordinate system to a custom OBJ coordinate system
* @param component The component to export
* @param groupName The name of the group to export to
* @param LOD Level of detail to use for the export (e.g. '80')
*/
public RocketComponentExporter(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, T component,
String groupName, ObjUtils.LevelOfDetail LOD) {
public RocketComponentExporter(@NotNull DefaultObj obj, @NotNull FlightConfiguration config, @NotNull CoordTransform transformer,
T component, String groupName, ObjUtils.LevelOfDetail LOD) {
this.obj = obj;
this.config = config;
this.component = component;
this.groupName = groupName;
this.LOD = LOD;

View File

@ -9,6 +9,8 @@ import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.CylinderExporter;
import net.sf.openrocket.file.wavefrontobj.export.shapes.DiskExporter;
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.Transition;
import net.sf.openrocket.util.Coordinate;
@ -19,9 +21,9 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
private static final double RADIUS_EPSILON = 1e-4;
private final int nrOfSides;
public TransitionExporter(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, Transition component,
String groupName, ObjUtils.LevelOfDetail LOD) {
super(obj, transformer, component, groupName, LOD);
public TransitionExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
Transition component, String groupName, ObjUtils.LevelOfDetail LOD) {
super(obj, config, transformer, component, groupName, LOD);
this.nrOfSides = LOD.getNrOfSides(Math.max(component.getForeRadius(), component.getAftRadius()));
}
@ -29,15 +31,13 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
public void addToObj() {
obj.setActiveGroupNames(groupName);
final Coordinate[] locations = component.getComponentLocations();
// Generate the mesh
for (Coordinate location : locations) {
generateMesh(location);
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
generateMesh(context);
}
}
private void generateMesh(Coordinate location) {
private void generateMesh(InstanceContext context) {
int startIdx = obj.getNumVertices();
final boolean hasForeShoulder = Double.compare(component.getForeShoulderRadius(), 0) > 0
@ -99,6 +99,7 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
int endIdx = Math.max(obj.getNumVertices() - 1, startIdx); // Clamp in case no vertices were added
// Translate the mesh to the position in the rocket
final Coordinate location = context.getLocation();
ObjUtils.translateVerticesFromComponentLocation(obj, transformer, startIdx, endIdx, location);
}

View File

@ -5,13 +5,15 @@ import net.sf.openrocket.file.wavefrontobj.CoordTransform;
import net.sf.openrocket.file.wavefrontobj.DefaultObj;
import net.sf.openrocket.file.wavefrontobj.ObjUtils;
import net.sf.openrocket.file.wavefrontobj.export.shapes.TubeExporter;
import net.sf.openrocket.rocketcomponent.FlightConfiguration;
import net.sf.openrocket.rocketcomponent.InstanceContext;
import net.sf.openrocket.rocketcomponent.TubeFinSet;
import net.sf.openrocket.util.Coordinate;
public class TubeFinSetExporter extends RocketComponentExporter<TubeFinSet> {
public TubeFinSetExporter(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, TubeFinSet component, String groupName,
ObjUtils.LevelOfDetail LOD) {
super(obj, transformer, component, groupName, LOD);
public TubeFinSetExporter(@NotNull DefaultObj obj, FlightConfiguration config, @NotNull CoordTransform transformer,
TubeFinSet component, String groupName, ObjUtils.LevelOfDetail LOD) {
super(obj, config, transformer, component, groupName, LOD);
}
@Override
@ -21,20 +23,14 @@ public class TubeFinSetExporter extends RocketComponentExporter<TubeFinSet> {
final float outerRadius = (float) component.getOuterRadius();
final float innerRadius = (float) component.getInnerRadius();
final float length = (float) component.getLength();
final Coordinate[] locations = component.getComponentLocations();
final double[] angles = component.getInstanceAngles();
if (locations.length != angles.length) {
throw new IllegalArgumentException("Number of locations and angles must match");
}
// Generate the fin meshes
for (int i = 0; i < locations.length; i++) {
generateMesh(outerRadius, innerRadius, length, locations[i], angles[i]);
for (InstanceContext context : config.getActiveInstances().getInstanceContexts(component)) {
generateMesh(outerRadius, innerRadius, length, context);
}
}
private void generateMesh(float outerRadius, float innerRadius, float length, Coordinate location, double angle) {
private void generateMesh(float outerRadius, float innerRadius, float length, InstanceContext context) {
// Create the fin meshes
final int startIdx = obj.getNumVertices();
@ -45,14 +41,16 @@ public class TubeFinSetExporter extends RocketComponentExporter<TubeFinSet> {
// Translate the mesh to the position in the rocket
// We will create an offset location that has the same effect as the axial rotation of the launch lug
Coordinate offsetLocation = getOffsetLocation(outerRadius, location, angle);
final double rotX = context.transform.getXrotation();
final Coordinate location = context.getLocation();
Coordinate offsetLocation = getOffsetLocation(outerRadius, location, rotX);
ObjUtils.translateVerticesFromComponentLocation(obj, transformer, startIdx, endIdx, offsetLocation);
}
private static Coordinate getOffsetLocation(float outerRadius, Coordinate location, double angle) {
private static Coordinate getOffsetLocation(float outerRadius, Coordinate location, double rotX) {
// ! This is all still referenced to the OpenRocket coordinate system, not the OBJ one
final float dy = outerRadius * (float) Math.cos(angle);
final float dz = outerRadius * (float) Math.sin(angle);
final float dy = outerRadius * (float) Math.cos(rotX);
final float dz = outerRadius * (float) Math.sin(rotX);
final double x = location.x;
final double y = location.y + dy;
final double z = location.z + dz;