简体   繁体   中英

JavaFX- Rotating my cube moves it off camera, how do I prevent this from happening?

I just started learning 3D graphics with javaFX not too long ago, I am currently working on rotating the model. While it does rotate, the way that it rotates is not exactly what I had in mind...For example if I press the key to rotate left the model moves towards the left hand side of the screen while it is rotating and eventually goes off screen.

Here's some of the code to construct the box and scene:

   Box box = new Box(100,20,50);
   SmartGroup group = new SmartGroup();
     group.getChildren().add(box);
 
 Camera camera = new PerspectiveCamera();
 
Scene scene = new Scene(group,WIDTH,HEIGHT);
 scene.setFill(Color.SILVER);
 scene.setCamera(camera);
    
 box.translateXProperty().set(WIDTH/2);
 box.translateYProperty().set(HEIGHT/2);
 box.translateZProperty().set(-1000); 

//Here's the wrapper class I made to make the box move:

   class SmartGroup extends Group{
Rotate r;
Transform t = new Rotate();
void rotateByX(double ang){
r = new Rotate(ang, Rotate.X_AXIS);
t = t.createConcatenation(r);
this.getTransforms().clear();
this.getTransforms().addAll(t);
}
void rotateByY(double ang){
r = new Rotate(ang, Rotate.Y_AXIS);
t = t.createConcatenation(r);
this.getTransforms().clear();
this.getTransforms().addAll(t);
}
void rotateByZ(double ang){
r = new Rotate(ang, Rotate.Z_AXIS);
t = t.createConcatenation(r);
this.getTransforms().clear();
this.getTransforms().addAll(t);
}
} 

So basically my model is rotating but also moving off screen. I want it to stay in place and rotate on a set axis. How would I go about doing

Here is an example which rotates a box about the Y axis.

The example uses a RotateTransition for the rotation.

The rotate transition is applied on the box being rotated, not an enclosing group.

There are other ways to achieve rotation, for instance you could manually create transforms and apply them in an animation timer or a timeline.

Generally, if you are trying to rotate something in 3D and it is not rotating about its center but instead some distant origin point, it will look like it is moving away or toward from the camera, because it is not rotating around its center but, instead, around somewhere else.

To fix that, what you can do is apply a series of transforms, one to translate the object to an origin point (0,0,0) then a second to actually rotate the object, and finally a third to translate the rotated object back to the position it was in before. A similar technique can be applied to scale an object as well.

I didn't do all that because I could just make use of the higher level RotateTransition to rotate the object about a Y axis running through the object's center. The RotateTransition takes care of all the necessary transforms for you, so that you don't need to worry about formulating and applying them. However, in some other use model, the alternate approach using multiple transforms could be used.

qube1 qube2

import javafx.animation.Interpolator;
import javafx.animation.RotateTransition;
import javafx.animation.Transition;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
import javafx.util.Duration;

public class RotatingBoxApp extends Application {

    public Parent createContent() {
        // Box
        Box testBox = new Box(5, 5, 5);
        testBox.setMaterial(new PhongMaterial(Color.LIMEGREEN));

        // 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, -20)
        );

        // Build the Scene Graph
        Group root = new Group();
        root.getChildren().add(camera);
        root.getChildren().add(testBox);

        RotateTransition rotator = new RotateTransition(Duration.seconds(5), testBox);
        rotator.setAxis(Rotate.Y_AXIS);
        rotator.setFromAngle(0);
        rotator.setToAngle(360);
        rotator.setCycleCount(Transition.INDEFINITE);
        rotator.setInterpolator(Interpolator.LINEAR);
        rotator.play();

        // Use a SubScene       
        SubScene subScene = new SubScene(root, 300, 300);
        subScene.setFill(Color.web("#4a4f59"));
        subScene.setCamera(camera);
        Group group = new Group();
        group.getChildren().add(subScene);

        return group;
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setResizable(false);
        Scene scene = new Scene(createContent());
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

In general if you want further help with issues like this, you usually need to provide an mcve (minimal code which somebody could copy and paste to run unchanged and reproduce the issue). Without an mcve, you will tend to get less help. For example, from the code you supplied, I couldn't really tell you exactly what you are doing wrong in your implementation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM