Implement toggle to remove hidden edges from objects

pull/53/head
James Ball 2022-04-04 22:06:56 +01:00
rodzic a039583e68
commit 8ac9cf1104
9 zmienionych plików z 126 dodań i 88 usunięć

Wyświetl plik

@ -6,7 +6,7 @@
<groupId>sh.ball</groupId> <groupId>sh.ball</groupId>
<artifactId>osci-render</artifactId> <artifactId>osci-render</artifactId>
<version>1.20.3</version> <version>1.21.3</version>
<name>osci-render</name> <name>osci-render</name>

Wyświetl plik

@ -28,6 +28,7 @@ public class CameraDrawKernel extends Kernel {
private float cameraPosY; private float cameraPosY;
private float cameraPosZ; private float cameraPosZ;
private float focalLength; private float focalLength;
private int hideEdges = 0;
public CameraDrawKernel() {} public CameraDrawKernel() {}
@ -45,6 +46,7 @@ public class CameraDrawKernel extends Kernel {
} }
} }
prevObject = object; prevObject = object;
hideEdges = object.edgesHidden() ? 1 : 0;
Vector3 rotation = object.getRotation(); Vector3 rotation = object.getRotation();
Vector3 position = object.getPosition(); Vector3 position = object.getPosition();
this.rotationX = (float) rotation.x; this.rotationX = (float) rotation.x;
@ -70,11 +72,15 @@ public class CameraDrawKernel extends Kernel {
linesList = new ArrayList<>(); linesList = new ArrayList<>();
for (int i = 0; i < vertices.length / 3; i += 2) { for (int i = 0; i < vertices.length / 3; i++) {
if (!Float.isNaN(vertexResult[2 * i]) && !Float.isNaN(vertexResult[2 * i + 2])) { int nextOffset = 0;
if (i < vertices.length / 3 - 1) {
nextOffset = 2 * i + 2;
}
if (!Float.isNaN(vertexResult[2 * i]) && !Float.isNaN(vertexResult[nextOffset])) {
linesList.add(new Line( linesList.add(new Line(
new Vector2(vertexResult[2 * i], vertexResult[2 * i + 1]), new Vector2(vertexResult[2 * i], vertexResult[2 * i + 1]),
new Vector2(vertexResult[2 * i + 2], vertexResult[2 * i + 3]) new Vector2(vertexResult[nextOffset], vertexResult[nextOffset + 1])
)); ));
} }
} }
@ -127,6 +133,9 @@ public class CameraDrawKernel extends Kernel {
float rotatedY = y3 + positionY; float rotatedY = y3 + positionY;
float rotatedZ = z3 + positionZ; float rotatedZ = z3 + positionZ;
boolean intersects = false;
if (hideEdges == 1) {
float rotatedCameraPosX = cameraPosX - positionX; float rotatedCameraPosX = cameraPosX - positionX;
float rotatedCameraPosY = cameraPosY - positionY; float rotatedCameraPosY = cameraPosY - positionY;
float rotatedCameraPosZ = cameraPosZ - positionZ; float rotatedCameraPosZ = cameraPosZ - positionZ;
@ -154,8 +163,6 @@ public class CameraDrawKernel extends Kernel {
diry /= length; diry /= length;
dirz /= length; dirz /= length;
boolean intersects = false;
for (int j = 0; j < triangles.length / 9 && !intersects; j++) { for (int j = 0; j < triangles.length / 9 && !intersects; j++) {
float v1x = triangles[9 * j]; float v1x = triangles[9 * j];
float v1y = triangles[9 * j + 1]; float v1y = triangles[9 * j + 1];
@ -218,6 +225,7 @@ public class CameraDrawKernel extends Kernel {
intersects = true; intersects = true;
} }
} }
}
if (intersects) { if (intersects) {
vertexResult[2 * i] = Float.NaN; vertexResult[2 * i] = Float.NaN;

Wyświetl plik

@ -22,6 +22,7 @@ public class WorldObject {
private List<Vector3> vertexPath; private List<Vector3> vertexPath;
private Vector3 position; private Vector3 position;
private Vector3 rotation; private Vector3 rotation;
private boolean hideEdges = false;
private WorldObject(List<Vector3> objVertices, List<Vector3> vertexPath, Vector3 position, private WorldObject(List<Vector3> objVertices, List<Vector3> vertexPath, Vector3 position,
Vector3 rotation) { Vector3 rotation) {
@ -56,8 +57,6 @@ public class WorldObject {
Graph<Vector3, DefaultWeightedEdge> graph = new DefaultUndirectedWeightedGraph<>( Graph<Vector3, DefaultWeightedEdge> graph = new DefaultUndirectedWeightedGraph<>(
DefaultWeightedEdge.class); DefaultWeightedEdge.class);
vertexPath = new ArrayList<>();
// Add all lines in frame to graph as vertices and edges. Edge weight is determined by the // Add all lines in frame to graph as vertices and edges. Edge weight is determined by the
// length of the line as this is directly proportional to draw time. // length of the line as this is directly proportional to draw time.
for (Line3D edge : edges) { for (Line3D edge : edges) {
@ -79,12 +78,7 @@ public class WorldObject {
for (Set<Vector3> vertices : inspector.connectedSets()) { for (Set<Vector3> vertices : inspector.connectedSets()) {
AsSubgraph<Vector3, DefaultWeightedEdge> subgraph = new AsSubgraph<>(graph, vertices); AsSubgraph<Vector3, DefaultWeightedEdge> subgraph = new AsSubgraph<>(graph, vertices);
ChinesePostman<Vector3, DefaultWeightedEdge> cp = new ChinesePostman<>(); ChinesePostman<Vector3, DefaultWeightedEdge> cp = new ChinesePostman<>();
List<Vector3> path = cp.getCPPSolution(subgraph).getVertexList(); vertexPath.addAll(cp.getCPPSolution(subgraph).getVertexList());
for (int i = 1; i < path.size(); i++) {
vertexPath.add(path.get(i - 1));
vertexPath.add(path.get(i));
}
} }
} }
@ -215,4 +209,12 @@ public class WorldObject {
return new WorldObject(new ArrayList<>(objVertices), new ArrayList<>(vertexPath), position, return new WorldObject(new ArrayList<>(objVertices), new ArrayList<>(vertexPath), position,
rotation); rotation);
} }
public void hideEdges(boolean hideEdges) {
this.hideEdges = hideEdges;
}
public boolean edgesHidden() {
return hideEdges;
}
} }

Wyświetl plik

@ -122,6 +122,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
@FXML @FXML
private CheckMenuItem flipYCheckMenuItem; private CheckMenuItem flipYCheckMenuItem;
@FXML @FXML
private CheckMenuItem hideHiddenMeshesCheckMenuItem;
@FXML
private Spinner<Integer> midiChannelSpinner; private Spinner<Integer> midiChannelSpinner;
@FXML @FXML
private Spinner<Double> translationIncrementSpinner; private Spinner<Double> translationIncrementSpinner;
@ -268,6 +270,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
flipXCheckMenuItem.selectedProperty().addListener((e, old, flip) -> audioPlayer.flipXChannel(flip)); flipXCheckMenuItem.selectedProperty().addListener((e, old, flip) -> audioPlayer.flipXChannel(flip));
flipYCheckMenuItem.selectedProperty().addListener((e, old, flip) -> audioPlayer.flipYChannel(flip)); flipYCheckMenuItem.selectedProperty().addListener((e, old, flip) -> audioPlayer.flipYChannel(flip));
hideHiddenMeshesCheckMenuItem.selectedProperty().addListener((e, old, hidden) -> objController.hideHiddenMeshes(hidden));
NumberFormat format = NumberFormat.getIntegerInstance(); NumberFormat format = NumberFormat.getIntegerInstance();
UnaryOperator<TextFormatter.Change> filter = c -> { UnaryOperator<TextFormatter.Change> filter = c -> {
if (c.isContentChange()) { if (c.isContentChange()) {
@ -404,6 +408,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
objController.updateFocalLength(); objController.updateFocalLength();
if (oldSettings instanceof ObjFrameSettings settings) { if (oldSettings instanceof ObjFrameSettings settings) {
objController.setObjRotate(settings.baseRotation, settings.currentRotation); objController.setObjRotate(settings.baseRotation, settings.currentRotation);
objController.hideHiddenMeshes(settings.hideEdges);
} }
executor.submit(producer); executor.submit(producer);
effectsController.restartEffects(); effectsController.restartEffects();
@ -718,6 +723,10 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
root.appendChild(flipX); root.appendChild(flipX);
root.appendChild(flipY); root.appendChild(flipY);
Element hiddenEdges = document.createElement("hiddenEdges");
hiddenEdges.appendChild(document.createTextNode(String.valueOf(hideHiddenMeshesCheckMenuItem.isSelected())));
root.appendChild(hiddenEdges);
Element translationIncrement = document.createElement("translationIncrement"); Element translationIncrement = document.createElement("translationIncrement");
translationIncrement.appendChild(document.createTextNode(translationIncrementSpinner.getValue().toString())); translationIncrement.appendChild(document.createTextNode(translationIncrementSpinner.getValue().toString()));
root.appendChild(translationIncrement); root.appendChild(translationIncrement);
@ -814,6 +823,11 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
flipYCheckMenuItem.setSelected(Boolean.parseBoolean(flipY.getTextContent())); flipYCheckMenuItem.setSelected(Boolean.parseBoolean(flipY.getTextContent()));
} }
Element hiddenEdges = (Element) root.getElementsByTagName("hiddenEdges").item(0);
if (hiddenEdges != null) {
hideHiddenMeshesCheckMenuItem.setSelected(Boolean.parseBoolean(hiddenEdges.getTextContent()));
}
Element translationIncrement = (Element) root.getElementsByTagName("translationIncrement").item(0); Element translationIncrement = (Element) root.getElementsByTagName("translationIncrement").item(0);
if (translationIncrement != null) { if (translationIncrement != null) {
translationIncrementSpinner.getValueFactory().setValue(Double.parseDouble(translationIncrement.getTextContent())); translationIncrementSpinner.getValueFactory().setValue(Double.parseDouble(translationIncrement.getTextContent()));

Wyświetl plik

@ -121,6 +121,10 @@ public class ObjController implements Initializable, SubController {
producer.setFrameSettings(ObjSettingsFactory.rotation(baseRotation, currentRotation)); producer.setFrameSettings(ObjSettingsFactory.rotation(baseRotation, currentRotation));
} }
public void hideHiddenMeshes(Boolean hidden) {
producer.setFrameSettings(ObjSettingsFactory.hideEdges(hidden));
}
@Override @Override
public void initialize(URL url, ResourceBundle resourceBundle) { public void initialize(URL url, ResourceBundle resourceBundle) {
focalLengthSlider.valueProperty().addListener((source, oldValue, newValue) -> focalLengthSlider.valueProperty().addListener((source, oldValue, newValue) ->

Wyświetl plik

@ -10,14 +10,16 @@ public class ObjFrameSettings {
public Vector3 currentRotation; public Vector3 currentRotation;
public Double rotateSpeed; public Double rotateSpeed;
public boolean resetRotation = false; public boolean resetRotation = false;
public Boolean hideEdges = null;
protected ObjFrameSettings(Double focalLength, Vector3 cameraPos, Vector3 baseRotation, Vector3 currentRotation, Double rotateSpeed, boolean resetRotation) { protected ObjFrameSettings(Double focalLength, Vector3 cameraPos, Vector3 baseRotation, Vector3 currentRotation, Double rotateSpeed, boolean resetRotation, Boolean hideEdges) {
this.focalLength = focalLength; this.focalLength = focalLength;
this.cameraPos = cameraPos; this.cameraPos = cameraPos;
this.baseRotation = baseRotation; this.baseRotation = baseRotation;
this.currentRotation = currentRotation; this.currentRotation = currentRotation;
this.rotateSpeed = rotateSpeed; this.rotateSpeed = rotateSpeed;
this.resetRotation = resetRotation; this.resetRotation = resetRotation;
this.hideEdges = hideEdges;
} }
protected ObjFrameSettings(double focalLength) { protected ObjFrameSettings(double focalLength) {

Wyświetl plik

@ -67,12 +67,15 @@ public class ObjFrameSource implements FrameSource<List<Shape>> {
if (obj.resetRotation) { if (obj.resetRotation) {
object.resetRotation(); object.resetRotation();
} }
if (obj.hideEdges != null) {
object.hideEdges(obj.hideEdges);
}
} }
} }
// TODO: Refactor! // TODO: Refactor!
@Override @Override
public Object getFrameSettings() { public Object getFrameSettings() {
return ObjSettingsFactory.rotation(baseRotation, currentRotation); return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false, object.edgesHidden());
} }
} }

Wyświetl plik

@ -17,7 +17,7 @@ public class ObjSettingsFactory {
} }
public static ObjFrameSettings rotation(Vector3 baseRotation, Vector3 currentRotation) { public static ObjFrameSettings rotation(Vector3 baseRotation, Vector3 currentRotation) {
return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false); return new ObjFrameSettings(null, null, baseRotation, currentRotation, null, false, null);
} }
public static ObjFrameSettings rotateSpeed(double rotateSpeed) { public static ObjFrameSettings rotateSpeed(double rotateSpeed) {
@ -27,4 +27,8 @@ public class ObjSettingsFactory {
public static ObjFrameSettings resetRotation() { public static ObjFrameSettings resetRotation() {
return new ObjFrameSettings(true); return new ObjFrameSettings(true);
} }
public static ObjFrameSettings hideEdges(Boolean hideEdges) {
return new ObjFrameSettings(null, null, null, null, null, false, hideEdges);
}
} }

Wyświetl plik

@ -70,6 +70,7 @@
<items> <items>
<CheckMenuItem fx:id="flipXCheckMenuItem" mnemonicParsing="false" text="Flip X Direction" /> <CheckMenuItem fx:id="flipXCheckMenuItem" mnemonicParsing="false" text="Flip X Direction" />
<CheckMenuItem fx:id="flipYCheckMenuItem" mnemonicParsing="false" text="Flip Y Direction" /> <CheckMenuItem fx:id="flipYCheckMenuItem" mnemonicParsing="false" text="Flip Y Direction" />
<CheckMenuItem fx:id="hideHiddenMeshesCheckMenuItem" mnemonicParsing="false" text="Hide Hidden Meshes" />
</items> </items>
</Menu> </Menu>
<Menu mnemonicParsing="false" text="Controls"> <Menu mnemonicParsing="false" text="Controls">