osci-render/src/main/java/sh/ball/gui/Controller.java

165 wiersze
5.0 KiB
Java
Czysty Zwykły widok Historia

package sh.ball.gui;
2020-11-22 14:39:38 +00:00
import sh.ball.audio.AudioPlayer;
import sh.ball.audio.FrameProducer;
import sh.ball.engine.Vector3;
import java.io.File;
import java.io.IOException;
2020-11-22 18:03:20 +00:00
import java.net.URL;
import java.util.List;
import java.util.Map;
2020-11-22 18:03:20 +00:00
import java.util.ResourceBundle;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import javafx.beans.InvalidationListener;
2020-11-22 18:03:20 +00:00
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
2020-11-22 18:03:20 +00:00
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import sh.ball.parser.ObjParser;
import sh.ball.shapes.Shape;
import sh.ball.shapes.Vector2;
2020-11-22 18:03:20 +00:00
public class Controller implements Initializable {
private static final int BUFFER_SIZE = 20;
2020-12-04 22:33:41 +00:00
private static final String DEFAULT_FILE = "src/main/resources/models/cube.obj";
private final FileChooser fileChooser = new FileChooser();
private final BlockingQueue<List<Shape>> frameQueue = new ArrayBlockingQueue<>(BUFFER_SIZE);
private final AudioPlayer player = new AudioPlayer(frameQueue);
private final FrameProducer producer = new FrameProducer(frameQueue);
private Stage stage;
@FXML
private Button chooseFileButton;
@FXML
2020-11-25 21:28:37 +00:00
private Label fileLabel;
@FXML
2020-11-25 21:28:37 +00:00
private TextField translationXTextField;
@FXML
2020-11-25 21:28:37 +00:00
private TextField translationYTextField;
@FXML
2020-11-25 21:28:37 +00:00
private Slider weightSlider;
@FXML
2020-11-25 21:28:37 +00:00
private Label weightLabel;
@FXML
2020-11-25 21:28:37 +00:00
private Slider rotateSpeedSlider;
@FXML
2020-11-25 21:28:37 +00:00
private Label rotateSpeedLabel;
2020-11-22 18:03:20 +00:00
@FXML
2020-11-25 21:28:37 +00:00
private Slider translationSpeedSlider;
2020-11-22 18:03:20 +00:00
@FXML
2020-11-25 21:28:37 +00:00
private Label translationSpeedLabel;
@FXML
2020-11-25 21:28:37 +00:00
private Slider scaleSlider;
@FXML
2020-11-25 21:28:37 +00:00
private Label scaleLabel;
@FXML
2020-11-25 21:28:37 +00:00
private TitledPane objTitledPane;
@FXML
private Slider focalLengthSlider;
@FXML
private Label focalLengthLabel;
2020-11-25 21:28:37 +00:00
@FXML
private TextField cameraXTextField;
@FXML
private TextField cameraYTextField;
@FXML
private TextField cameraZTextField;
2020-11-22 18:03:20 +00:00
private Map<Slider, SliderUpdater<Double>> initializeSliderMap() {
return Map.of(
weightSlider,
new SliderUpdater<>(weightLabel::setText, player::setWeight),
rotateSpeedSlider,
new SliderUpdater<>(rotateSpeedLabel::setText, player::setRotateSpeed),
translationSpeedSlider,
new SliderUpdater<>(translationSpeedLabel::setText, player::setTranslationSpeed),
scaleSlider,
new SliderUpdater<>(scaleLabel::setText, player::setScale),
focalLengthSlider,
new SliderUpdater<>(focalLengthLabel::setText, producer::setFocalLength)
);
}
2020-11-22 18:03:20 +00:00
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
2020-12-04 22:33:41 +00:00
chooseFile(new File(DEFAULT_FILE));
Map<Slider, SliderUpdater<Double>> sliders = initializeSliderMap();
for (Slider slider : sliders.keySet()) {
slider.valueProperty().addListener((source, oldValue, newValue) ->
sliders.get(slider).update(slider.getValue())
);
}
InvalidationListener translationUpdate = observable ->
player.setTranslation(new Vector2(
tryParse(translationXTextField.getText()),
tryParse(translationYTextField.getText())
));
translationXTextField.textProperty().addListener(translationUpdate);
translationYTextField.textProperty().addListener(translationUpdate);
2020-11-25 21:28:37 +00:00
InvalidationListener cameraPosUpdate = observable ->
producer.setCameraPos(new Vector3(
tryParse(cameraXTextField.getText()),
tryParse(cameraYTextField.getText()),
tryParse(cameraZTextField.getText())
));
cameraXTextField.textProperty().addListener(cameraPosUpdate);
cameraYTextField.textProperty().addListener(cameraPosUpdate);
cameraZTextField.textProperty().addListener(cameraPosUpdate);
chooseFileButton.setOnAction(e -> {
File file = null;
while (file == null) {
file = fileChooser.showOpenDialog(stage);
}
2020-11-25 21:28:37 +00:00
chooseFile(file);
});
new Thread(producer).start();
new Thread(player).start();
}
private double tryParse(String value) {
try {
return Double.parseDouble(value);
} catch (NumberFormatException e) {
return 0;
}
}
2020-11-25 21:28:37 +00:00
private void chooseFile(File file) {
try {
2020-11-25 21:28:37 +00:00
String path = file.getAbsolutePath();
producer.setParser(path);
2020-11-25 21:28:37 +00:00
if (file.exists() && !file.isDirectory()) {
fileLabel.setText(path);
objTitledPane.setDisable(!ObjParser.isObjFile(path));
} else {
objTitledPane.setDisable(true);
}
} catch (IOException | ParserConfigurationException | SAXException ioException) {
ioException.printStackTrace();
}
}
public void setStage(Stage stage) {
this.stage = stage;
2020-11-22 18:03:20 +00:00
}
2020-11-22 14:39:38 +00:00
}