Improve normals

This commit is contained in:
SiboVG 2023-08-17 02:47:30 +02:00
parent 353105d1bd
commit ea59b9d012
3 changed files with 37 additions and 19 deletions

View File

@ -226,7 +226,7 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
boolean isAftRing = Double.compare(x, (float) component.getLength()) == 0;
// Case 5: Add normal vertices
addQuadVertices(numSlices, foreRingVertices, aftRingVertices, r, rNext, x, isForeRing, isAftRing, isOutside);
addQuadVertices(numSlices, foreRingVertices, aftRingVertices, r, rNext, x, xNext, isForeRing, isAftRing, isOutside);
actualNumStacks++;
}
}
@ -296,7 +296,7 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
}
private void addQuadVertices(int numSlices, List<Integer> foreRingVertices, List<Integer> aftRingVertices,
double r, double rNext, float x, boolean isForeRing, boolean isAftRing, boolean isOutside) {
double r, double rNext, float x, float xNext, boolean isForeRing, boolean isAftRing, boolean isOutside) {
for (int i = 0; i < numSlices; i++) {
double angle = 2 * Math.PI * i / numSlices;
float y = (float) (r * Math.cos(angle));
@ -313,9 +313,20 @@ public class TransitionExporter extends RocketComponentExporter<Transition> {
}
// Calculate the normal
final float nx = isOutside ? (float) (r - rNext) : (float) (rNext -r);
final float ny = isOutside ? y : -y;
final float nz = isOutside ? z : -z;
// We need special nx normal when the radius changes
float nx;
if (Double.compare(r, rNext) != 0) {
final double slopeAngle = Math.atan(Math.abs(xNext - x) / (rNext - r));
nx = (float) Math.cos(Math.PI - slopeAngle);
} else {
nx = 0;
}
float ny = (float) Math.cos(angle);
float nz = (float) Math.sin(angle);
nx = isOutside ? nx : -nx;
ny = isOutside ? ny : -ny;
nz = isOutside ? nz : -nz;
obj.addNormal(transformer.convertLocWithoutOriginOffs(nx, ny, nz));
}
}

View File

@ -51,10 +51,10 @@ public class CylinderExporter {
}
// Generate side top vertices
generateRingVertices(obj, transformer, numSides, 0, foreRadius, isOutside, foreRingVertices, foreRingNormals);
generateRingVertices(obj, transformer, numSides, 0, length, foreRadius, aftRadius, isOutside, foreRingVertices, foreRingNormals);
// Generate side bottom vertices
generateRingVertices(obj, transformer, numSides, length, aftRadius, isOutside, aftRingVertices, aftRingNormals);
generateRingVertices(obj, transformer, numSides, length, 0, aftRadius, foreRadius, isOutside, aftRingVertices, aftRingNormals);
// Create faces for the bottom and top
if (solid) {
@ -134,12 +134,6 @@ public class CylinderExporter {
addCylinderMesh(obj, transformer, groupName, radius, length, numSides, solid, true, foreRingVertices, aftRingVertices);
}
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
float radius, float length, boolean solid, ObjUtils.LevelOfDetail LOD,
List<Integer> foreRingVertices, List<Integer> aftRingVertices) {
addCylinderMesh(obj, transformer, groupName, radius, length, LOD.getNrOfSides(radius), solid, foreRingVertices, aftRingVertices);
}
public static void addCylinderMesh(@NotNull DefaultObj obj, @NotNull CoordTransform transformer, String groupName,
float radius, float length, boolean solid, boolean isOutside, int nrOfSlices,
List<Integer> foreRingVertices, List<Integer> aftRingVertices) {
@ -153,8 +147,8 @@ public class CylinderExporter {
}
public static void generateRingVertices(DefaultObj obj, CoordTransform transformer,
int numSides, float x, float radius, boolean isOutside,
List<Integer> vertexList, List<Integer> normalList) {
int numSides, float x, float nextX, float radius, float nextRadius,
boolean isOutside, List<Integer> vertexList, List<Integer> normalList) {
int startIdx = obj.getNumVertices();
int normalsStartIdx = obj.getNumNormals();
@ -165,7 +159,23 @@ public class CylinderExporter {
// Side top vertices
obj.addVertex(transformer.convertLoc(x, y, z));
obj.addNormal(transformer.convertLocWithoutOriginOffs(0, isOutside ? y : -y, isOutside ? z : -z)); // This kind of normal ensures the object is smoothly rendered (like the 'Shade Smooth' option in Blender)
// We need special nx normal when the radius changes
float nx;
if (Float.compare(radius, nextRadius) != 0) {
final double slopeAngle = Math.atan(Math.abs(nextX - x) / (nextRadius - radius));
nx = (float) Math.cos(Math.PI - slopeAngle);
} else {
nx = 0;
}
float ny = (float) Math.cos(angle);
float nz = (float) Math.sin(angle);
nx = isOutside ? nx : -nx;
ny = isOutside ? ny : -ny;
nz = isOutside ? nz : -nz;
obj.addNormal(transformer.convertLocWithoutOriginOffs(nx, ny, nz)); // This kind of normal ensures the object is smoothly rendered (like the 'Shade Smooth' option in Blender)
if (vertexList != null) {
vertexList.add(startIdx + i);

View File

@ -3,14 +3,11 @@ package net.sf.openrocket.file.wavefrontobj.export.shapes;
import com.sun.istack.NotNull;
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 java.util.ArrayList;
import java.util.List;
import static net.sf.openrocket.file.wavefrontobj.export.shapes.CylinderExporter.generateRingVertices;
public class TubeExporter {
/**
* Add a tube mesh to the obj.