kopia lustrzana https://github.com/jameshball/osci-render
Fix line endings, add ObjController, move save/load logic to sub-controllers
rodzic
e2b6a1e9ee
commit
ccd65ea3bf
|
@ -1,214 +1,241 @@
|
|||
package sh.ball.gui.controller;
|
||||
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Slider;
|
||||
import javafx.scene.shape.SVGPath;
|
||||
import javafx.util.Duration;
|
||||
import sh.ball.audio.FrequencyAnalyser;
|
||||
import sh.ball.audio.ShapeAudioPlayer;
|
||||
import sh.ball.audio.effect.*;
|
||||
import sh.ball.audio.engine.AudioDevice;
|
||||
import sh.ball.shapes.Shape;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class EffectsController implements Initializable {
|
||||
|
||||
private ShapeAudioPlayer audioPlayer;
|
||||
|
||||
private Map<EffectType, Slider> effectTypes;
|
||||
|
||||
private final SmoothEffect smoothEffect;
|
||||
private WobbleEffect wobbleEffect;
|
||||
|
||||
@FXML
|
||||
private CheckBox vectorCancellingCheckBox;
|
||||
@FXML
|
||||
private Slider vectorCancellingSlider;
|
||||
@FXML
|
||||
private SVGPath vectorCancellingMidi;
|
||||
@FXML
|
||||
private CheckBox bitCrushCheckBox;
|
||||
@FXML
|
||||
private Slider bitCrushSlider;
|
||||
@FXML
|
||||
private SVGPath bitCrushMidi;
|
||||
@FXML
|
||||
private CheckBox verticalDistortCheckBox;
|
||||
@FXML
|
||||
private Slider verticalDistortSlider;
|
||||
@FXML
|
||||
private SVGPath verticalDistortMidi;
|
||||
@FXML
|
||||
private CheckBox horizontalDistortCheckBox;
|
||||
@FXML
|
||||
private Slider horizontalDistortSlider;
|
||||
@FXML
|
||||
private SVGPath horizontalDistortMidi;
|
||||
@FXML
|
||||
private CheckBox wobbleCheckBox;
|
||||
@FXML
|
||||
private Slider wobbleSlider;
|
||||
@FXML
|
||||
private SVGPath wobbleMidi;
|
||||
@FXML
|
||||
private CheckBox smoothCheckBox;
|
||||
@FXML
|
||||
private Slider smoothSlider;
|
||||
@FXML
|
||||
private SVGPath smoothMidi;
|
||||
@FXML
|
||||
private CheckBox traceCheckBox;
|
||||
@FXML
|
||||
private Slider traceSlider;
|
||||
@FXML
|
||||
private SVGPath traceMidi;
|
||||
|
||||
public EffectsController() {
|
||||
this.smoothEffect = new SmoothEffect(1);
|
||||
}
|
||||
|
||||
public Map<SVGPath, Slider> getMidiButtonMap() {
|
||||
Map<SVGPath, Slider> midiMap = new HashMap<>();
|
||||
midiMap.put(vectorCancellingMidi, vectorCancellingSlider);
|
||||
midiMap.put(bitCrushMidi, bitCrushSlider);
|
||||
midiMap.put(wobbleMidi, wobbleSlider);
|
||||
midiMap.put(smoothMidi, smoothSlider);
|
||||
midiMap.put(traceMidi, traceSlider);
|
||||
midiMap.put(verticalDistortMidi, verticalDistortSlider);
|
||||
midiMap.put(horizontalDistortMidi, horizontalDistortSlider);
|
||||
return midiMap;
|
||||
}
|
||||
|
||||
// Maps EffectTypes to the slider that controls the effect so that they can be
|
||||
// toggled when the appropriate checkbox is ticked.
|
||||
private void initializeEffectTypes() {
|
||||
effectTypes = Map.of(
|
||||
EffectType.VECTOR_CANCELLING,
|
||||
vectorCancellingSlider,
|
||||
EffectType.BIT_CRUSH,
|
||||
bitCrushSlider,
|
||||
EffectType.VERTICAL_DISTORT,
|
||||
verticalDistortSlider,
|
||||
EffectType.HORIZONTAL_DISTORT,
|
||||
horizontalDistortSlider,
|
||||
EffectType.WOBBLE,
|
||||
wobbleSlider,
|
||||
EffectType.SMOOTH,
|
||||
smoothSlider
|
||||
);
|
||||
}
|
||||
|
||||
// selects or deselects the given audio effect
|
||||
private void updateEffect(EffectType type, boolean checked, Effect effect) {
|
||||
if (checked) {
|
||||
audioPlayer.addEffect(type, effect);
|
||||
if (effectTypes.containsKey(type)) {
|
||||
effectTypes.get(type).setDisable(false);
|
||||
}
|
||||
} else {
|
||||
audioPlayer.removeEffect(type);
|
||||
if (effectTypes.containsKey(type)) {
|
||||
effectTypes.get(type).setDisable(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setAudioPlayer(ShapeAudioPlayer audioPlayer) {
|
||||
this.audioPlayer = audioPlayer;
|
||||
}
|
||||
|
||||
public void setAudioDevice(AudioDevice device) {
|
||||
this.wobbleEffect = new WobbleEffect(device.sampleRate());
|
||||
updateEffect(EffectType.WOBBLE, wobbleCheckBox.isSelected(), wobbleEffect);
|
||||
restartEffects();
|
||||
}
|
||||
|
||||
public void setFrequencyAnalyser(FrequencyAnalyser<List<Shape>> analyser) {
|
||||
analyser.addListener(wobbleEffect);
|
||||
}
|
||||
|
||||
public void restartEffects() {
|
||||
// apply the wobble effect after a second as the frequency of the audio takes a while to
|
||||
// propagate and send to its listeners.
|
||||
KeyFrame kf1 = new KeyFrame(Duration.seconds(0), e -> wobbleEffect.setVolume(0));
|
||||
KeyFrame kf2 = new KeyFrame(Duration.seconds(1), e -> {
|
||||
wobbleEffect.update();
|
||||
wobbleEffect.setVolume(wobbleSlider.getValue());
|
||||
});
|
||||
Timeline timeline = new Timeline(kf1, kf2);
|
||||
Platform.runLater(timeline::play);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
initializeEffectTypes();
|
||||
|
||||
InvalidationListener vectorCancellingListener = e ->
|
||||
updateEffect(EffectType.VECTOR_CANCELLING, vectorCancellingCheckBox.isSelected(),
|
||||
EffectFactory.vectorCancelling((int) vectorCancellingSlider.getValue()));
|
||||
InvalidationListener bitCrushListener = e ->
|
||||
updateEffect(EffectType.BIT_CRUSH, bitCrushCheckBox.isSelected(),
|
||||
EffectFactory.bitCrush(bitCrushSlider.getValue()));
|
||||
InvalidationListener verticalDistortListener = e ->
|
||||
updateEffect(EffectType.VERTICAL_DISTORT, verticalDistortCheckBox.isSelected(),
|
||||
EffectFactory.verticalDistort(verticalDistortSlider.getValue()));
|
||||
InvalidationListener horizontalDistortListener = e ->
|
||||
updateEffect(EffectType.HORIZONTAL_DISTORT, horizontalDistortCheckBox.isSelected(),
|
||||
EffectFactory.horizontalDistort(horizontalDistortSlider.getValue()));
|
||||
InvalidationListener wobbleListener = e -> {
|
||||
wobbleEffect.setVolume(wobbleSlider.getValue());
|
||||
updateEffect(EffectType.WOBBLE, wobbleCheckBox.isSelected(), wobbleEffect);
|
||||
};
|
||||
InvalidationListener smoothListener = e -> {
|
||||
smoothEffect.setWindowSize((int) smoothSlider.getValue());
|
||||
updateEffect(EffectType.SMOOTH, smoothCheckBox.isSelected(), smoothEffect);
|
||||
};
|
||||
InvalidationListener traceListener = e -> {
|
||||
double trace = traceCheckBox.isSelected() ? traceSlider.valueProperty().getValue() : 1;
|
||||
audioPlayer.setTrace(trace);
|
||||
traceSlider.setDisable(!traceCheckBox.isSelected());
|
||||
};
|
||||
|
||||
vectorCancellingSlider.valueProperty().addListener(vectorCancellingListener);
|
||||
vectorCancellingCheckBox.selectedProperty().addListener(vectorCancellingListener);
|
||||
|
||||
bitCrushSlider.valueProperty().addListener(bitCrushListener);
|
||||
bitCrushCheckBox.selectedProperty().addListener(bitCrushListener);
|
||||
|
||||
verticalDistortSlider.valueProperty().addListener(verticalDistortListener);
|
||||
verticalDistortCheckBox.selectedProperty().addListener(verticalDistortListener);
|
||||
|
||||
horizontalDistortSlider.valueProperty().addListener(horizontalDistortListener);
|
||||
horizontalDistortCheckBox.selectedProperty().addListener(horizontalDistortListener);
|
||||
|
||||
wobbleSlider.valueProperty().addListener(wobbleListener);
|
||||
wobbleCheckBox.selectedProperty().addListener(wobbleListener);
|
||||
wobbleCheckBox.selectedProperty().addListener(e -> wobbleEffect.update());
|
||||
|
||||
smoothSlider.valueProperty().addListener(smoothListener);
|
||||
smoothCheckBox.selectedProperty().addListener(smoothListener);
|
||||
|
||||
traceSlider.valueProperty().addListener(traceListener);
|
||||
traceCheckBox.selectedProperty().addListener(traceListener);
|
||||
}
|
||||
|
||||
public List<CheckBox> effectCheckBoxes() {
|
||||
return List.of(vectorCancellingCheckBox, bitCrushCheckBox, verticalDistortCheckBox,
|
||||
horizontalDistortCheckBox, wobbleCheckBox, smoothCheckBox, traceCheckBox);
|
||||
}
|
||||
public List<Slider> effectSliders() {
|
||||
return List.of(vectorCancellingSlider, bitCrushSlider, verticalDistortSlider,
|
||||
horizontalDistortSlider, wobbleSlider, smoothSlider, traceSlider);
|
||||
}
|
||||
}
|
||||
package sh.ball.gui.controller;
|
||||
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Slider;
|
||||
import javafx.scene.shape.SVGPath;
|
||||
import javafx.util.Duration;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import sh.ball.audio.FrequencyAnalyser;
|
||||
import sh.ball.audio.ShapeAudioPlayer;
|
||||
import sh.ball.audio.effect.*;
|
||||
import sh.ball.audio.engine.AudioDevice;
|
||||
import sh.ball.shapes.Shape;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
|
||||
public class EffectsController implements Initializable {
|
||||
|
||||
private ShapeAudioPlayer audioPlayer;
|
||||
|
||||
private Map<EffectType, Slider> effectTypes;
|
||||
|
||||
private final SmoothEffect smoothEffect;
|
||||
private WobbleEffect wobbleEffect;
|
||||
|
||||
@FXML
|
||||
private CheckBox vectorCancellingCheckBox;
|
||||
@FXML
|
||||
private Slider vectorCancellingSlider;
|
||||
@FXML
|
||||
private SVGPath vectorCancellingMidi;
|
||||
@FXML
|
||||
private CheckBox bitCrushCheckBox;
|
||||
@FXML
|
||||
private Slider bitCrushSlider;
|
||||
@FXML
|
||||
private SVGPath bitCrushMidi;
|
||||
@FXML
|
||||
private CheckBox verticalDistortCheckBox;
|
||||
@FXML
|
||||
private Slider verticalDistortSlider;
|
||||
@FXML
|
||||
private SVGPath verticalDistortMidi;
|
||||
@FXML
|
||||
private CheckBox horizontalDistortCheckBox;
|
||||
@FXML
|
||||
private Slider horizontalDistortSlider;
|
||||
@FXML
|
||||
private SVGPath horizontalDistortMidi;
|
||||
@FXML
|
||||
private CheckBox wobbleCheckBox;
|
||||
@FXML
|
||||
private Slider wobbleSlider;
|
||||
@FXML
|
||||
private SVGPath wobbleMidi;
|
||||
@FXML
|
||||
private CheckBox smoothCheckBox;
|
||||
@FXML
|
||||
private Slider smoothSlider;
|
||||
@FXML
|
||||
private SVGPath smoothMidi;
|
||||
@FXML
|
||||
private CheckBox traceCheckBox;
|
||||
@FXML
|
||||
private Slider traceSlider;
|
||||
@FXML
|
||||
private SVGPath traceMidi;
|
||||
|
||||
public EffectsController() {
|
||||
this.smoothEffect = new SmoothEffect(1);
|
||||
}
|
||||
|
||||
public Map<SVGPath, Slider> getMidiButtonMap() {
|
||||
Map<SVGPath, Slider> midiMap = new HashMap<>();
|
||||
midiMap.put(vectorCancellingMidi, vectorCancellingSlider);
|
||||
midiMap.put(bitCrushMidi, bitCrushSlider);
|
||||
midiMap.put(wobbleMidi, wobbleSlider);
|
||||
midiMap.put(smoothMidi, smoothSlider);
|
||||
midiMap.put(traceMidi, traceSlider);
|
||||
midiMap.put(verticalDistortMidi, verticalDistortSlider);
|
||||
midiMap.put(horizontalDistortMidi, horizontalDistortSlider);
|
||||
return midiMap;
|
||||
}
|
||||
|
||||
// Maps EffectTypes to the slider that controls the effect so that they can be
|
||||
// toggled when the appropriate checkbox is ticked.
|
||||
private void initializeEffectTypes() {
|
||||
effectTypes = Map.of(
|
||||
EffectType.VECTOR_CANCELLING,
|
||||
vectorCancellingSlider,
|
||||
EffectType.BIT_CRUSH,
|
||||
bitCrushSlider,
|
||||
EffectType.VERTICAL_DISTORT,
|
||||
verticalDistortSlider,
|
||||
EffectType.HORIZONTAL_DISTORT,
|
||||
horizontalDistortSlider,
|
||||
EffectType.WOBBLE,
|
||||
wobbleSlider,
|
||||
EffectType.SMOOTH,
|
||||
smoothSlider
|
||||
);
|
||||
}
|
||||
|
||||
// selects or deselects the given audio effect
|
||||
private void updateEffect(EffectType type, boolean checked, Effect effect) {
|
||||
if (checked) {
|
||||
audioPlayer.addEffect(type, effect);
|
||||
if (effectTypes.containsKey(type)) {
|
||||
effectTypes.get(type).setDisable(false);
|
||||
}
|
||||
} else {
|
||||
audioPlayer.removeEffect(type);
|
||||
if (effectTypes.containsKey(type)) {
|
||||
effectTypes.get(type).setDisable(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setAudioPlayer(ShapeAudioPlayer audioPlayer) {
|
||||
this.audioPlayer = audioPlayer;
|
||||
}
|
||||
|
||||
public void setAudioDevice(AudioDevice device) {
|
||||
this.wobbleEffect = new WobbleEffect(device.sampleRate());
|
||||
updateEffect(EffectType.WOBBLE, wobbleCheckBox.isSelected(), wobbleEffect);
|
||||
restartEffects();
|
||||
}
|
||||
|
||||
public void setFrequencyAnalyser(FrequencyAnalyser<List<Shape>> analyser) {
|
||||
analyser.addListener(wobbleEffect);
|
||||
}
|
||||
|
||||
public void restartEffects() {
|
||||
// apply the wobble effect after a second as the frequency of the audio takes a while to
|
||||
// propagate and send to its listeners.
|
||||
KeyFrame kf1 = new KeyFrame(Duration.seconds(0), e -> wobbleEffect.setVolume(0));
|
||||
KeyFrame kf2 = new KeyFrame(Duration.seconds(1), e -> {
|
||||
wobbleEffect.update();
|
||||
wobbleEffect.setVolume(wobbleSlider.getValue());
|
||||
});
|
||||
Timeline timeline = new Timeline(kf1, kf2);
|
||||
Platform.runLater(timeline::play);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
initializeEffectTypes();
|
||||
|
||||
InvalidationListener vectorCancellingListener = e ->
|
||||
updateEffect(EffectType.VECTOR_CANCELLING, vectorCancellingCheckBox.isSelected(),
|
||||
EffectFactory.vectorCancelling((int) vectorCancellingSlider.getValue()));
|
||||
InvalidationListener bitCrushListener = e ->
|
||||
updateEffect(EffectType.BIT_CRUSH, bitCrushCheckBox.isSelected(),
|
||||
EffectFactory.bitCrush(bitCrushSlider.getValue()));
|
||||
InvalidationListener verticalDistortListener = e ->
|
||||
updateEffect(EffectType.VERTICAL_DISTORT, verticalDistortCheckBox.isSelected(),
|
||||
EffectFactory.verticalDistort(verticalDistortSlider.getValue()));
|
||||
InvalidationListener horizontalDistortListener = e ->
|
||||
updateEffect(EffectType.HORIZONTAL_DISTORT, horizontalDistortCheckBox.isSelected(),
|
||||
EffectFactory.horizontalDistort(horizontalDistortSlider.getValue()));
|
||||
InvalidationListener wobbleListener = e -> {
|
||||
wobbleEffect.setVolume(wobbleSlider.getValue());
|
||||
updateEffect(EffectType.WOBBLE, wobbleCheckBox.isSelected(), wobbleEffect);
|
||||
};
|
||||
InvalidationListener smoothListener = e -> {
|
||||
smoothEffect.setWindowSize((int) smoothSlider.getValue());
|
||||
updateEffect(EffectType.SMOOTH, smoothCheckBox.isSelected(), smoothEffect);
|
||||
};
|
||||
InvalidationListener traceListener = e -> {
|
||||
double trace = traceCheckBox.isSelected() ? traceSlider.valueProperty().getValue() : 1;
|
||||
audioPlayer.setTrace(trace);
|
||||
traceSlider.setDisable(!traceCheckBox.isSelected());
|
||||
};
|
||||
|
||||
vectorCancellingSlider.valueProperty().addListener(vectorCancellingListener);
|
||||
vectorCancellingCheckBox.selectedProperty().addListener(vectorCancellingListener);
|
||||
|
||||
bitCrushSlider.valueProperty().addListener(bitCrushListener);
|
||||
bitCrushCheckBox.selectedProperty().addListener(bitCrushListener);
|
||||
|
||||
verticalDistortSlider.valueProperty().addListener(verticalDistortListener);
|
||||
verticalDistortCheckBox.selectedProperty().addListener(verticalDistortListener);
|
||||
|
||||
horizontalDistortSlider.valueProperty().addListener(horizontalDistortListener);
|
||||
horizontalDistortCheckBox.selectedProperty().addListener(horizontalDistortListener);
|
||||
|
||||
wobbleSlider.valueProperty().addListener(wobbleListener);
|
||||
wobbleCheckBox.selectedProperty().addListener(wobbleListener);
|
||||
wobbleCheckBox.selectedProperty().addListener(e -> wobbleEffect.update());
|
||||
|
||||
smoothSlider.valueProperty().addListener(smoothListener);
|
||||
smoothCheckBox.selectedProperty().addListener(smoothListener);
|
||||
|
||||
traceSlider.valueProperty().addListener(traceListener);
|
||||
traceCheckBox.selectedProperty().addListener(traceListener);
|
||||
}
|
||||
|
||||
public List<CheckBox> checkBoxes() {
|
||||
return List.of(vectorCancellingCheckBox, bitCrushCheckBox, verticalDistortCheckBox,
|
||||
horizontalDistortCheckBox, wobbleCheckBox, smoothCheckBox, traceCheckBox);
|
||||
}
|
||||
public List<Slider> sliders() {
|
||||
return List.of(vectorCancellingSlider, bitCrushSlider, verticalDistortSlider,
|
||||
horizontalDistortSlider, wobbleSlider, smoothSlider, traceSlider);
|
||||
}
|
||||
public List<String> labels() {
|
||||
return List.of("vectorCancelling", "bitCrush", "verticalDistort", "horizontalDistort",
|
||||
"wobble", "smooth", "trace");
|
||||
}
|
||||
|
||||
public Element save(Document document) {
|
||||
Element element = document.createElement("checkBoxes");
|
||||
List<CheckBox> checkBoxes = checkBoxes();
|
||||
List<String> labels = labels();
|
||||
for (int i = 0; i < checkBoxes.size(); i++) {
|
||||
Element checkBox = document.createElement(labels.get(i));
|
||||
checkBox.appendChild(
|
||||
document.createTextNode(checkBoxes.get(i).selectedProperty().getValue().toString())
|
||||
);
|
||||
element.appendChild(checkBox);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
public void load(Element root) {
|
||||
Element element = (Element) root.getElementsByTagName("checkBoxes").item(0);
|
||||
List<CheckBox> checkBoxes = checkBoxes();
|
||||
List<String> labels = labels();
|
||||
for (int i = 0; i < checkBoxes.size(); i++) {
|
||||
String value = element.getElementsByTagName(labels.get(i)).item(0).getTextContent();
|
||||
checkBoxes.get(i).setSelected(Boolean.parseBoolean(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import javafx.beans.property.DoubleProperty;
|
|||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.scene.paint.Paint;
|
||||
import javafx.scene.shape.SVGPath;
|
||||
|
@ -26,7 +25,6 @@ import java.util.*;
|
|||
import java.util.concurrent.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javafx.beans.InvalidationListener;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.stage.FileChooser;
|
||||
|
@ -47,7 +45,6 @@ import javax.xml.transform.dom.DOMSource;
|
|||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
import sh.ball.audio.effect.Effect;
|
||||
import sh.ball.audio.effect.EffectType;
|
||||
import sh.ball.audio.engine.AudioDevice;
|
||||
import sh.ball.audio.engine.ConglomerateAudioEngine;
|
||||
|
@ -94,7 +91,6 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
private List<FrameSource<List<Shape>>> frameSources = new ArrayList<>();
|
||||
private FrameProducer<List<Shape>> producer;
|
||||
private int currentFrameSource;
|
||||
private Vector3 rotation = new Vector3();
|
||||
|
||||
// frame playback (code by DJ_Level_3)
|
||||
private static final int MAX_FRAME_RATE = 120;
|
||||
|
@ -112,6 +108,8 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
@FXML
|
||||
private EffectsController effectsController;
|
||||
@FXML
|
||||
private ObjController objController;
|
||||
@FXML
|
||||
private Label frequencyLabel;
|
||||
@FXML
|
||||
private Button chooseFileButton;
|
||||
|
@ -154,16 +152,6 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
@FXML
|
||||
private TitledPane objTitledPane;
|
||||
@FXML
|
||||
private Slider focalLengthSlider;
|
||||
@FXML
|
||||
private SVGPath focalLengthMidi;
|
||||
@FXML
|
||||
private Slider objectRotateSpeedSlider;
|
||||
@FXML
|
||||
private SVGPath objectRotateSpeedMidi;
|
||||
@FXML
|
||||
private CheckBox rotateCheckBox;
|
||||
@FXML
|
||||
private Slider octaveSlider;
|
||||
@FXML
|
||||
private SVGPath octaveMidi;
|
||||
|
@ -217,10 +205,9 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
midiMap.put(rotateSpeedMidi, rotateSpeedSlider);
|
||||
midiMap.put(translationSpeedMidi, translationSpeedSlider);
|
||||
midiMap.put(volumeMidi, volumeSlider);
|
||||
midiMap.put(focalLengthMidi, focalLengthSlider);
|
||||
midiMap.put(objectRotateSpeedMidi, objectRotateSpeedSlider);
|
||||
midiMap.put(octaveMidi, octaveSlider);
|
||||
midiMap.put(visibilityMidi, visibilitySlider);
|
||||
midiMap.putAll(objController.getMidiButtonMap());
|
||||
midiMap.putAll(effectsController.getMidiButtonMap());
|
||||
return midiMap;
|
||||
}
|
||||
|
@ -231,8 +218,6 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
return Map.of(
|
||||
rotateSpeedSlider, rotateEffect::setSpeed,
|
||||
translationSpeedSlider, translateEffect::setSpeed,
|
||||
focalLengthSlider, this::updateFocalLength,
|
||||
objectRotateSpeedSlider, this::updateObjectRotateSpeed,
|
||||
visibilitySlider, audioPlayer::setMainFrequencyScale
|
||||
);
|
||||
}
|
||||
|
@ -249,6 +234,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
audioPlayer.setVolume(volumeSlider.valueProperty());
|
||||
|
||||
effectsController.setAudioPlayer(audioPlayer);
|
||||
objController.setAudioProducer(producer);
|
||||
|
||||
this.midiButtonMap = initializeMidiButtonMap();
|
||||
|
||||
|
@ -350,7 +336,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
recordTextField.setDisable(!newVal);
|
||||
});
|
||||
|
||||
updateObjectRotateSpeed(rotateSpeedSlider.getValue());
|
||||
objController.updateObjectRotateSpeed();
|
||||
|
||||
audioPlayer.addEffect(EffectType.ROTATE, rotateEffect);
|
||||
audioPlayer.addEffect(EffectType.TRANSLATE, translateEffect);
|
||||
|
@ -488,18 +474,6 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
}
|
||||
}
|
||||
|
||||
// changes the focalLength of the FrameProducer
|
||||
private void updateFocalLength(double focalLength) {
|
||||
producer.setFrameSettings(ObjSettingsFactory.focalLength(focalLength));
|
||||
}
|
||||
|
||||
// changes the rotateSpeed of the FrameProducer
|
||||
private void updateObjectRotateSpeed(double rotateSpeed) {
|
||||
producer.setFrameSettings(
|
||||
ObjSettingsFactory.rotateSpeed((Math.exp(3 * rotateSpeed) - 1) / 50)
|
||||
);
|
||||
}
|
||||
|
||||
// changes the sinusoidal translation of the image rendered
|
||||
private void updateTranslation() {
|
||||
translateEffect.setTranslation(new Vector2(
|
||||
|
@ -520,10 +494,11 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
|
||||
Object oldSettings = producer.getFrameSettings();
|
||||
producer = new FrameProducer<>(audioPlayer, frames);
|
||||
objController.setAudioProducer(producer);
|
||||
|
||||
// Apply the same settings that the previous frameSource had
|
||||
updateObjectRotateSpeed(objectRotateSpeedSlider.getValue());
|
||||
updateFocalLength(focalLengthSlider.getValue());
|
||||
objController.updateObjectRotateSpeed();
|
||||
objController.updateFocalLength();
|
||||
if (oldSettings instanceof ObjFrameSettings settings) {
|
||||
setObjRotate(settings.baseRotation, settings.currentRotation);
|
||||
}
|
||||
|
@ -701,24 +676,23 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
|
||||
// determines whether the mouse is being used to rotate a 3D object
|
||||
public boolean mouseRotate() {
|
||||
return rotateCheckBox.isSelected();
|
||||
return objController.mouseRotate();
|
||||
}
|
||||
|
||||
// stops the mouse rotating the 3D object when ESC is pressed or checkbox is
|
||||
// unchecked
|
||||
public void disableMouseRotate() {
|
||||
rotateCheckBox.setSelected(false);
|
||||
objController.disableMouseRotate();
|
||||
}
|
||||
|
||||
// updates the 3D object base rotation angle
|
||||
public void setObjRotate(Vector3 vector) {
|
||||
rotation = vector;
|
||||
producer.setFrameSettings(ObjSettingsFactory.baseRotation(vector));
|
||||
objController.setObjRotate(vector);
|
||||
}
|
||||
|
||||
// updates the 3D object base and current rotation angle
|
||||
protected void setObjRotate(Vector3 baseRotation, Vector3 currentRotation) {
|
||||
producer.setFrameSettings(ObjSettingsFactory.rotation(baseRotation, currentRotation));
|
||||
objController.setObjRotate(baseRotation, currentRotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -787,25 +761,25 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
}
|
||||
|
||||
// must be functions, otherwise they are not initialised
|
||||
private List<String> checkBoxLabels() {
|
||||
return List.of("vectorCancelling", "bitCrush", "verticalDistort", "horizontalDistort",
|
||||
"wobble", "smooth", "trace");
|
||||
}
|
||||
private List<Slider> otherSliders() {
|
||||
return List.of(octaveSlider, frequencySlider, rotateSpeedSlider, translationSpeedSlider,
|
||||
volumeSlider, visibilitySlider, focalLengthSlider, objectRotateSpeedSlider);
|
||||
List<Slider> sliders = new ArrayList<>(List.of(octaveSlider, frequencySlider, rotateSpeedSlider, translationSpeedSlider,
|
||||
volumeSlider, visibilitySlider));
|
||||
sliders.addAll(objController.sliders());
|
||||
return sliders;
|
||||
}
|
||||
private List<String> otherLabels() {
|
||||
return List.of("octave", "frequency", "rotateSpeed", "translationSpeed", "volume",
|
||||
"visibility", "focalLength", "objectRotateSpeed");
|
||||
List<String> labels = new ArrayList<>(List.of("octave", "frequency", "rotateSpeed", "translationSpeed", "volume",
|
||||
"visibility"));
|
||||
labels.addAll(objController.labels());
|
||||
return labels;
|
||||
}
|
||||
private List<Slider> allSliders() {
|
||||
List<Slider> sliders = new ArrayList<>(effectsController.effectSliders());
|
||||
List<Slider> sliders = new ArrayList<>(effectsController.sliders());
|
||||
sliders.addAll(otherSliders());
|
||||
return sliders;
|
||||
}
|
||||
private List<String> allLabels() {
|
||||
List<String> labels = new ArrayList<>(checkBoxLabels());
|
||||
List<String> labels = new ArrayList<>(effectsController.labels());
|
||||
labels.addAll(otherLabels());
|
||||
return labels;
|
||||
}
|
||||
|
@ -836,29 +810,14 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
Element root = document.createElement("project");
|
||||
document.appendChild(root);
|
||||
|
||||
// Is there a nicer way of doing this?!
|
||||
List<CheckBox> checkBoxes = effectsController.effectCheckBoxes();
|
||||
List<Slider> checkBoxSliders = effectsController.effectSliders();
|
||||
List<String> checkBoxLabels = checkBoxLabels();
|
||||
List<Slider> otherSliders = otherSliders();
|
||||
List<String> otherLabels = otherLabels();
|
||||
List<Slider> sliders = allSliders();
|
||||
List<String> labels = allLabels();
|
||||
|
||||
Element slidersElement = document.createElement("sliders");
|
||||
appendSliders(checkBoxSliders, checkBoxLabels, slidersElement, document);
|
||||
appendSliders(otherSliders, otherLabels, slidersElement, document);
|
||||
appendSliders(sliders, labels, slidersElement, document);
|
||||
root.appendChild(slidersElement);
|
||||
|
||||
Element checkBoxesElement = document.createElement("checkBoxes");
|
||||
for (int i = 0; i < checkBoxes.size(); i++) {
|
||||
Element checkBox = document.createElement(checkBoxLabels.get(i));
|
||||
checkBox.appendChild(
|
||||
document.createTextNode(checkBoxes.get(i).selectedProperty().getValue().toString())
|
||||
);
|
||||
checkBoxesElement.appendChild(checkBox);
|
||||
}
|
||||
root.appendChild(checkBoxesElement);
|
||||
root.appendChild(effectsController.save(document));
|
||||
|
||||
Element midiElement = document.createElement("midi");
|
||||
for (Map.Entry<Integer, SVGPath> entry : CCMap.entrySet()) {
|
||||
|
@ -880,17 +839,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
translationElement.appendChild(translationYElement);
|
||||
root.appendChild(translationElement);
|
||||
|
||||
Element objectRotationElement = document.createElement("objectRotation");
|
||||
Element objectRotationXElement = document.createElement("x");
|
||||
objectRotationXElement.appendChild(document.createTextNode(Double.toString(rotation.getX())));
|
||||
Element objectRotationYElement = document.createElement("y");
|
||||
objectRotationYElement.appendChild(document.createTextNode(Double.toString(rotation.getY())));
|
||||
Element objectRotationZElement = document.createElement("z");
|
||||
objectRotationZElement.appendChild(document.createTextNode(Double.toString(rotation.getZ())));
|
||||
objectRotationElement.appendChild(objectRotationXElement);
|
||||
objectRotationElement.appendChild(objectRotationYElement);
|
||||
objectRotationElement.appendChild(objectRotationZElement);
|
||||
root.appendChild(objectRotationElement);
|
||||
root.appendChild(objController.save(document));
|
||||
|
||||
Element filesElement = document.createElement("files");
|
||||
for (int i = 0; i < openFiles.size(); i++) {
|
||||
|
@ -934,11 +883,6 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
Document document = documentBuilder.parse(new File(projectFileName));
|
||||
document.getDocumentElement().normalize();
|
||||
|
||||
List<CheckBox> checkBoxes = effectsController.effectCheckBoxes();
|
||||
List<Slider> checkBoxSliders = effectsController.effectSliders();
|
||||
List<String> checkBoxLabels = checkBoxLabels();
|
||||
List<Slider> otherSliders = otherSliders();
|
||||
List<String> otherLabels = otherLabels();
|
||||
List<Slider> sliders = allSliders();
|
||||
List<String> labels = allLabels();
|
||||
|
||||
|
@ -947,14 +891,9 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
|
||||
Element root = document.getDocumentElement();
|
||||
Element slidersElement = (Element) root.getElementsByTagName("sliders").item(0);
|
||||
loadSliderValues(checkBoxSliders, checkBoxLabels, slidersElement);
|
||||
loadSliderValues(otherSliders, otherLabels, slidersElement);
|
||||
loadSliderValues(sliders, labels, slidersElement);
|
||||
|
||||
Element checkBoxesElement = (Element) root.getElementsByTagName("checkBoxes").item(0);
|
||||
for (int i = 0; i < checkBoxes.size(); i++) {
|
||||
String value = checkBoxesElement.getElementsByTagName(checkBoxLabels.get(i)).item(0).getTextContent();
|
||||
checkBoxes.get(i).setSelected(Boolean.parseBoolean(value));
|
||||
}
|
||||
effectsController.load(root);
|
||||
|
||||
Element midiElement = (Element) root.getElementsByTagName("midi").item(0);
|
||||
resetCCMap();
|
||||
|
@ -978,16 +917,7 @@ public class MainController implements Initializable, FrequencyListener, MidiLis
|
|||
translationXTextField.setText(translationXElement.getTextContent());
|
||||
translationYTextField.setText(translationYElement.getTextContent());
|
||||
|
||||
Element objectRotationElement = (Element) root.getElementsByTagName("objectRotation").item(0);
|
||||
Element objectRotationXElement = (Element) objectRotationElement.getElementsByTagName("x").item(0);
|
||||
Element objectRotationYElement = (Element) objectRotationElement.getElementsByTagName("y").item(0);
|
||||
Element objectRotationZElement = (Element) objectRotationElement.getElementsByTagName("z").item(0);
|
||||
rotation = new Vector3(
|
||||
Double.parseDouble(objectRotationXElement.getTextContent()),
|
||||
Double.parseDouble(objectRotationYElement.getTextContent()),
|
||||
Double.parseDouble(objectRotationZElement.getTextContent())
|
||||
);
|
||||
setObjRotate(rotation);
|
||||
objController.load(root);
|
||||
|
||||
Element filesElement = (Element) root.getElementsByTagName("files").item(0);
|
||||
List<byte[]> files = new ArrayList<>();
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
package sh.ball.gui.controller;
|
||||
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.control.CheckBox;
|
||||
import javafx.scene.control.Slider;
|
||||
import javafx.scene.shape.SVGPath;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import sh.ball.audio.FrameProducer;
|
||||
import sh.ball.engine.Vector3;
|
||||
import sh.ball.parser.obj.ObjSettingsFactory;
|
||||
import sh.ball.shapes.Shape;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
|
||||
public class ObjController implements Initializable {
|
||||
|
||||
private Vector3 rotation = new Vector3(2 * Math.PI, 2 * Math.PI, 0);
|
||||
private FrameProducer<List<Shape>> producer;
|
||||
|
||||
@FXML
|
||||
private Slider focalLengthSlider;
|
||||
@FXML
|
||||
private SVGPath focalLengthMidi;
|
||||
@FXML
|
||||
private Slider objectRotateSpeedSlider;
|
||||
@FXML
|
||||
private SVGPath objectRotateSpeedMidi;
|
||||
@FXML
|
||||
private CheckBox rotateCheckBox;
|
||||
|
||||
public Map<SVGPath, Slider> getMidiButtonMap() {
|
||||
Map<SVGPath, Slider> midiMap = new HashMap<>();
|
||||
midiMap.put(focalLengthMidi, focalLengthSlider);
|
||||
midiMap.put(objectRotateSpeedMidi, objectRotateSpeedSlider);
|
||||
return midiMap;
|
||||
}
|
||||
|
||||
public void updateFocalLength() {
|
||||
setFocalLength(focalLengthSlider.getValue());
|
||||
}
|
||||
|
||||
public void setAudioProducer(FrameProducer<List<Shape>> producer) {
|
||||
this.producer = producer;
|
||||
}
|
||||
|
||||
// changes the focalLength of the FrameProducer
|
||||
public void setFocalLength(double focalLength) {
|
||||
producer.setFrameSettings(ObjSettingsFactory.focalLength(focalLength));
|
||||
}
|
||||
|
||||
public void updateObjectRotateSpeed() {
|
||||
setObjectRotateSpeed(objectRotateSpeedSlider.getValue());
|
||||
}
|
||||
|
||||
// changes the rotateSpeed of the FrameProducer
|
||||
public void setObjectRotateSpeed(double rotateSpeed) {
|
||||
producer.setFrameSettings(
|
||||
ObjSettingsFactory.rotateSpeed((Math.exp(3 * rotateSpeed) - 1) / 50)
|
||||
);
|
||||
}
|
||||
|
||||
// determines whether the mouse is being used to rotate a 3D object
|
||||
public boolean mouseRotate() {
|
||||
return rotateCheckBox.isSelected();
|
||||
}
|
||||
|
||||
// stops the mouse rotating the 3D object when ESC is pressed or checkbox is
|
||||
// unchecked
|
||||
public void disableMouseRotate() {
|
||||
rotateCheckBox.setSelected(false);
|
||||
}
|
||||
|
||||
// updates the 3D object base rotation angle
|
||||
public void setObjRotate(Vector3 vector) {
|
||||
rotation = vector;
|
||||
producer.setFrameSettings(ObjSettingsFactory.baseRotation(vector));
|
||||
}
|
||||
|
||||
// updates the 3D object base and current rotation angle
|
||||
public void setObjRotate(Vector3 baseRotation, Vector3 currentRotation) {
|
||||
producer.setFrameSettings(ObjSettingsFactory.rotation(baseRotation, currentRotation));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle resourceBundle) {
|
||||
focalLengthSlider.valueProperty().addListener((source, oldValue, newValue) ->
|
||||
setFocalLength(newValue.doubleValue())
|
||||
);
|
||||
objectRotateSpeedSlider.valueProperty().addListener((source, oldValue, newValue) ->
|
||||
setObjectRotateSpeed(newValue.doubleValue())
|
||||
);
|
||||
}
|
||||
|
||||
public List<Slider> sliders() {
|
||||
return List.of(focalLengthSlider, objectRotateSpeedSlider);
|
||||
}
|
||||
|
||||
public List<String> labels() {
|
||||
return List.of("focalLength", "objectRotateSpeed");
|
||||
}
|
||||
|
||||
public Element save(Document document) {
|
||||
Element element = document.createElement("objectRotation");
|
||||
Element x = document.createElement("x");
|
||||
x.appendChild(document.createTextNode(Double.toString(rotation.getX())));
|
||||
Element y = document.createElement("y");
|
||||
y.appendChild(document.createTextNode(Double.toString(rotation.getY())));
|
||||
Element z = document.createElement("z");
|
||||
z.appendChild(document.createTextNode(Double.toString(rotation.getZ())));
|
||||
element.appendChild(x);
|
||||
element.appendChild(y);
|
||||
element.appendChild(z);
|
||||
return element;
|
||||
}
|
||||
|
||||
public void load(Element root) {
|
||||
Element element = (Element) root.getElementsByTagName("objectRotation").item(0);
|
||||
Element x = (Element) element.getElementsByTagName("x").item(0);
|
||||
Element y = (Element) element.getElementsByTagName("y").item(0);
|
||||
Element z = (Element) element.getElementsByTagName("z").item(0);
|
||||
rotation = new Vector3(
|
||||
Double.parseDouble(x.getTextContent()),
|
||||
Double.parseDouble(y.getTextContent()),
|
||||
Double.parseDouble(z.getTextContent())
|
||||
);
|
||||
setObjRotate(rotation);
|
||||
}
|
||||
}
|
|
@ -1,32 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.control.Slider?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.shape.SVGPath?>
|
||||
|
||||
<AnchorPane fx:id="effects" minHeight="0.0" minWidth="0.0" prefHeight="262.0" prefWidth="402.0" stylesheets="@../css/main.css" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sh.ball.gui.controller.EffectsController">
|
||||
<children>
|
||||
<CheckBox fx:id="vectorCancellingCheckBox" layoutX="14.0" layoutY="15.0" mnemonicParsing="false" text="Vector cancelling" />
|
||||
<Slider fx:id="vectorCancellingSlider" blockIncrement="0.05" disable="true" layoutX="154.0" layoutY="16.0" majorTickUnit="1.0" max="10.0" min="2.0" minorTickCount="0" prefHeight="42.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" value="2.0" />
|
||||
<CheckBox fx:id="bitCrushCheckBox" layoutX="14.0" layoutY="62.0" mnemonicParsing="false" text="Bit crush" />
|
||||
<Slider fx:id="bitCrushSlider" blockIncrement="0.01" disable="true" layoutX="154.0" layoutY="64.0" majorTickUnit="0.5" max="3.0" prefHeight="42.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="2.0" />
|
||||
<CheckBox fx:id="verticalDistortCheckBox" layoutX="14.0" layoutY="110.0" mnemonicParsing="false" text="Vertical Distort" />
|
||||
<Slider fx:id="verticalDistortSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="112.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.2" />
|
||||
<CheckBox fx:id="horizontalDistortCheckBox" layoutX="14.0" layoutY="159.0" mnemonicParsing="false" text="Horizontal Distort" />
|
||||
<Slider fx:id="horizontalDistortSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="161.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.2" />
|
||||
<CheckBox fx:id="wobbleCheckBox" layoutX="14.0" layoutY="208.0" mnemonicParsing="false" text="Wobble" />
|
||||
<Slider fx:id="wobbleSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="210.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.2" />
|
||||
<SVGPath fx:id="vectorCancellingMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="13.0" pickOnBounds="true" />
|
||||
<SVGPath fx:id="bitCrushMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="61.0" pickOnBounds="true" />
|
||||
<SVGPath fx:id="verticalDistortMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="108.0" pickOnBounds="true" />
|
||||
<SVGPath fx:id="horizontalDistortMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="157.0" pickOnBounds="true" />
|
||||
<SVGPath fx:id="wobbleMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="206.0" pickOnBounds="true" />
|
||||
<CheckBox fx:id="smoothCheckBox" layoutX="14.0" layoutY="255.0" mnemonicParsing="false" text="Smoothing" />
|
||||
<Slider fx:id="smoothSlider" blockIncrement="1.0" disable="true" layoutX="154.0" layoutY="257.0" majorTickUnit="128.0" max="1024.0" minorTickCount="1" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="128.0" />
|
||||
<SVGPath fx:id="smoothMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="253.0" pickOnBounds="true" />
|
||||
<CheckBox fx:id="traceCheckBox" layoutX="14.0" layoutY="304.0" mnemonicParsing="false" text="Trace" />
|
||||
<Slider fx:id="traceSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="306.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.5" />
|
||||
<SVGPath fx:id="traceMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="302.0" pickOnBounds="true" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.control.Slider?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.shape.SVGPath?>
|
||||
|
||||
<AnchorPane fx:id="effects" minHeight="0.0" minWidth="0.0" prefHeight="262.0" prefWidth="402.0" stylesheets="@../css/main.css" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sh.ball.gui.controller.EffectsController">
|
||||
<children>
|
||||
<CheckBox fx:id="vectorCancellingCheckBox" layoutX="14.0" layoutY="15.0" mnemonicParsing="false" text="Vector cancelling" />
|
||||
<Slider fx:id="vectorCancellingSlider" blockIncrement="0.05" disable="true" layoutX="154.0" layoutY="16.0" majorTickUnit="1.0" max="10.0" min="2.0" minorTickCount="0" prefHeight="42.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" value="2.0" />
|
||||
<CheckBox fx:id="bitCrushCheckBox" layoutX="14.0" layoutY="62.0" mnemonicParsing="false" text="Bit crush" />
|
||||
<Slider fx:id="bitCrushSlider" blockIncrement="0.01" disable="true" layoutX="154.0" layoutY="64.0" majorTickUnit="0.5" max="3.0" prefHeight="42.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="2.0" />
|
||||
<CheckBox fx:id="verticalDistortCheckBox" layoutX="14.0" layoutY="110.0" mnemonicParsing="false" text="Vertical Distort" />
|
||||
<Slider fx:id="verticalDistortSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="112.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.2" />
|
||||
<CheckBox fx:id="horizontalDistortCheckBox" layoutX="14.0" layoutY="159.0" mnemonicParsing="false" text="Horizontal Distort" />
|
||||
<Slider fx:id="horizontalDistortSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="161.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.2" />
|
||||
<CheckBox fx:id="wobbleCheckBox" layoutX="14.0" layoutY="208.0" mnemonicParsing="false" text="Wobble" />
|
||||
<Slider fx:id="wobbleSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="210.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.2" />
|
||||
<SVGPath fx:id="vectorCancellingMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="13.0" pickOnBounds="true" />
|
||||
<SVGPath fx:id="bitCrushMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="61.0" pickOnBounds="true" />
|
||||
<SVGPath fx:id="verticalDistortMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="108.0" pickOnBounds="true" />
|
||||
<SVGPath fx:id="horizontalDistortMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="157.0" pickOnBounds="true" />
|
||||
<SVGPath fx:id="wobbleMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="206.0" pickOnBounds="true" />
|
||||
<CheckBox fx:id="smoothCheckBox" layoutX="14.0" layoutY="255.0" mnemonicParsing="false" text="Smoothing" />
|
||||
<Slider fx:id="smoothSlider" blockIncrement="1.0" disable="true" layoutX="154.0" layoutY="257.0" majorTickUnit="128.0" max="1024.0" minorTickCount="1" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="128.0" />
|
||||
<SVGPath fx:id="smoothMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="253.0" pickOnBounds="true" />
|
||||
<CheckBox fx:id="traceCheckBox" layoutX="14.0" layoutY="304.0" mnemonicParsing="false" text="Trace" />
|
||||
<Slider fx:id="traceSlider" blockIncrement="0.005" disable="true" layoutX="154.0" layoutY="306.0" majorTickUnit="0.1" max="1.0" prefHeight="38.0" prefWidth="219.0" showTickLabels="true" showTickMarks="true" value="0.5" />
|
||||
<SVGPath fx:id="traceMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="373.0" layoutY="302.0" pickOnBounds="true" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
|
|
|
@ -22,15 +22,7 @@
|
|||
<fx:include fx:id="effects" source="effects.fxml"/>
|
||||
</TitledPane>
|
||||
<TitledPane fx:id="objTitledPane" animated="false" collapsible="false" layoutX="424.0" layoutY="436.0" maxHeight="-Infinity" maxWidth="-Infinity" prefHeight="213.0" prefWidth="402.0" text="3D .obj file settings">
|
||||
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="359.0">
|
||||
<Slider fx:id="focalLengthSlider" blockIncrement="0.01" layoutX="116.0" layoutY="22.0" majorTickUnit="0.2" max="2.0" min="1.0E-5" prefHeight="42.0" prefWidth="258.0" showTickLabels="true" showTickMarks="true" value="1.0" />
|
||||
<Label layoutX="34.0" layoutY="21.0" text="Focal length" />
|
||||
<Slider fx:id="objectRotateSpeedSlider" blockIncrement="0.005" layoutX="116.0" layoutY="81.0" majorTickUnit="0.1" max="1.0" prefHeight="42.0" prefWidth="258.0" showTickLabels="true" showTickMarks="true" />
|
||||
<Label layoutX="9.0" layoutY="80.0" text="3D Rotate speed" />
|
||||
<CheckBox fx:id="rotateCheckBox" layoutX="90.0" layoutY="143.0" mnemonicParsing="false" text="Rotate with Mouse (Esc to disable)" />
|
||||
<SVGPath fx:id="focalLengthMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="374.0" layoutY="19.0" pickOnBounds="true" />
|
||||
<SVGPath fx:id="objectRotateSpeedMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="374.0" layoutY="78.0" pickOnBounds="true" />
|
||||
</AnchorPane>
|
||||
<fx:include fx:id="obj" source="obj.fxml"/>
|
||||
</TitledPane>
|
||||
<AnchorPane id="control-pane" layoutX="10.0" layoutY="37.0" prefHeight="313.0" prefWidth="402.0">
|
||||
<children>
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.CheckBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.Slider?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.shape.SVGPath?>
|
||||
|
||||
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="359.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sh.ball.gui.controller.ObjController">
|
||||
<Slider fx:id="focalLengthSlider" blockIncrement="0.01" layoutX="116.0" layoutY="22.0" majorTickUnit="0.2" max="2.0" min="1.0E-5" prefHeight="42.0" prefWidth="258.0" showTickLabels="true" showTickMarks="true" value="1.0" />
|
||||
<Label layoutX="34.0" layoutY="21.0" text="Focal length" />
|
||||
<Slider fx:id="objectRotateSpeedSlider" blockIncrement="0.005" layoutX="116.0" layoutY="81.0" majorTickUnit="0.1" max="1.0" prefHeight="42.0" prefWidth="258.0" showTickLabels="true" showTickMarks="true" />
|
||||
<Label layoutX="9.0" layoutY="80.0" text="3D Rotate speed" />
|
||||
<CheckBox fx:id="rotateCheckBox" layoutX="90.0" layoutY="143.0" mnemonicParsing="false" text="Rotate with Mouse (Esc to disable)" />
|
||||
<SVGPath fx:id="focalLengthMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="374.0" layoutY="19.0" pickOnBounds="true" />
|
||||
<SVGPath fx:id="objectRotateSpeedMidi" content="M20.15 8.26H22V15.74H20.15M13 8.26H18.43C19 8.26 19.3 8.74 19.3 9.3V14.81C19.3 15.5 19 15.74 18.38 15.74H13V11H14.87V13.91H17.5V9.95H13M10.32 8.26H12.14V15.74H10.32M2 8.26H8.55C9.1 8.26 9.41 8.74 9.41 9.3V15.74H7.59V10.15H6.5V15.74H4.87V10.15H3.83V15.74H2Z" fill="WHITE" layoutX="374.0" layoutY="78.0" pickOnBounds="true" />
|
||||
</AnchorPane>
|
Ładowanie…
Reference in New Issue