user3616468
user3616468

Reputation: 79

Mouse Rotation along Z axis in javafx

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

Answers (2)

Zydar
Zydar

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

Luke
Luke

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

Related Questions