Reputation: 79
I want to rotate 3D object using mouse in javafx. I am able to calculate the rotation angle for x-axis rotation and y-axis rotation from mouse x,y position and able to rotate it around x-axis and y-axis. But I want to rotate the object around z-axis also.
How to calculate the rotation angle for z-axis rotation from mouse x,y positions?
Below is the sample code used for rotating the object around x and y-axis.
private void handleMouseEvents() {
setOnMousePressed((MouseEvent me) -> {
setActivated(true);
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
mouseOldX = me.getSceneX();
mouseOldY = me.getSceneY();
});
setOnMouseDragged((MouseEvent me) -> {
mousePosX = me.getSceneX();
mouseOldY = me.getSceneY();
double dx = (mousePosX - mouseOldX) ;
double dy = (mouseOldY - mouseOldY);
mouseOldX = mousePosX;
mouseOldY = mouseOldY;
if (me.isPrimaryButtonDown()) {
rotateY.setAngle(rotateY.getAngle() - dx);
rotateX.setAngle(rotateX.getAngle() + dy);
}
});
}
Upvotes: 3
Views: 3192
Reputation: 167
You could try something like that in your dragged event:
double dx = (mousePosX - me.getSceneX());
double dy = (mousePosY - me.getSceneY());
rotateX((dy / 'Your 3D-object'.getHeight() * -360) * (Math.PI / 180));
rotateY((dx / 'Your 3D-object'.getWidth() * -360) * (Math.PI / 180));
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
Maybe your calculation could be right but I guess you are setting your Y
values wrong. Especially dy
will always be 0 because you calculate mouseOldY - mouseOldY
Upvotes: 1
Reputation: 770
I used the formula of Zydar to create a ready-to-run example. testBox is the 3D object which is being rotated.
If this isn't the desired behaviour, please elaborate on your question.
The important part:
private void handleMouseEvents() {
scene.setOnMousePressed((MouseEvent me) -> {
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
});
scene.setOnMouseDragged((MouseEvent me) -> {
double dx = (mousePosX - me.getSceneX()) ;
double dy = (mousePosY - me.getSceneY());
if (me.isPrimaryButtonDown()) {
rotateX.setAngle(rotateX.getAngle() -
(dy / testBox.getHeight() * 360) * (Math.PI / 180));
rotateY.setAngle(rotateY.getAngle() -
(dx / testBox.getWidth() * -360) * (Math.PI / 180));
}
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
});
}
The whole SSCCE:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.SceneAntialiasing;
import javafx.scene.SubScene;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
public class SampleApp extends Application {
private Box testBox;
private Scene scene;
private Rotate rotateX = new Rotate(0, Rotate.X_AXIS);
private Rotate rotateY = new Rotate(0, Rotate.Y_AXIS);
private Rotate rotateZ = new Rotate(0, Rotate.Z_AXIS);
private final double TURN_FACTOR = 0.5;
public Parent createContent() throws Exception {
// Box
testBox = new Box(5, 5, 5);
testBox.getTransforms().addAll(rotateZ, rotateY, rotateX);
// Create and position camera
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.getTransforms().addAll(
new Rotate(-20, Rotate.Y_AXIS),
new Rotate(-20, Rotate.X_AXIS),
new Translate(0, 0, -50));
// Build the Scene Graph
Group root = new Group();
root.getChildren().add(camera);
root.getChildren().add(testBox);
// Use a SubScene
SubScene subScene = new SubScene(root, 300, 300, true,
SceneAntialiasing.BALANCED);
subScene.setFill(Color.TRANSPARENT);
subScene.setCamera(camera);
return new Group(subScene);
}
private double mousePosX, mousePosY = 0;
private void handleMouseEvents() {
scene.setOnMousePressed((MouseEvent me) -> {
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
});
scene.setOnMouseDragged((MouseEvent me) -> {
double dx = (mousePosX - me.getSceneX()) ;
double dy = (mousePosY - me.getSceneY());
if (me.isPrimaryButtonDown()) {
rotateX.setAngle(rotateX.getAngle() -
(dy / testBox.getHeight() * 360) * (Math.PI / 180));
rotateY.setAngle(rotateY.getAngle() -
(dx / testBox.getWidth() * -360) * (Math.PI / 180));
}
mousePosX = me.getSceneX();
mousePosY = me.getSceneY();
});
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setResizable(false);
scene = new Scene(createContent());
handleMouseEvents();
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Upvotes: 5