1
\$\begingroup\$

I actually wanted to build a 2x2 rubiks cube. As the Box class in javafx doesn't provide the feature of building a cube with different colours on different faces, I chose to build the cubes using RectangleBuilder to build rectangles with different colours and then applied transformations to build the cubes. But while testing the code I saw that the entire display was coming in a broken manner with the edges overlapping as shown in the picture.Here's the snap Here is my source code:

package helloworld;


import javafx.scene.transform.Rotate;
import javafx.scene.PerspectiveCamera;
import javafx.scene.transform.Translate;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.SceneAntialiasing;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.RectangleBuilder;
import javafx.scene.transform.Rotate;
import javafx.util.Duration;


    public class NewFXMain1 extends Application {


    public class Cube extends Group {
    final Rotate rx = new Rotate(0,Rotate.X_AXIS);
    final Rotate ry = new Rotate(0,Rotate.Y_AXIS);
    final Rotate rz = new Rotate(0,Rotate.Z_AXIS);
    public Cube(double size, Color back,Color bottom,Color right,Color left,Color top,Color front, double shade) {
        getTransforms().addAll(rz, ry, rx);
        getChildren().addAll(
            RectangleBuilder.create() // back face
                .width(size).height(size)
                .fill(back.deriveColor(0.0, 1.0, (1 - 0.5*shade), 1.0))
                .translateX(-0.5*size)
                .translateY(-0.5*size)
                .translateZ(0.5*size)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // bottom face
                .width(size).height(size)
                .fill(bottom.deriveColor(0.0, 1.0, (1 - 0.4*shade), 1.0))
                .translateX(-0.5*size)
                .translateY(0)
                .rotationAxis(Rotate.X_AXIS)
                .rotate(90)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // right face
                .width(size).height(size)
                .fill(right.deriveColor(0.0, 1.0, (1 - 0.3*shade), 1.0))
                .translateX(-1*size)
                .translateY(-0.5*size)
                .rotationAxis(Rotate.Y_AXIS)
                .rotate(90)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // left face
                .width(size).height(size)
                .fill(left.deriveColor(0.0, 1.0, (1 - 0.2*shade), 1.0))
                .translateX(0)
                .translateY(-0.5*size)
                .rotationAxis(Rotate.Y_AXIS)
                .rotate(90)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // top face
                .width(size).height(size)
                .fill(top.deriveColor(0.0, 1.0, (1 - 0.1*shade), 1.0))
                .translateX(-0.5*size)
                .translateY(-1*size)
                .rotationAxis(Rotate.X_AXIS)
                .rotate(90)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build(),
            RectangleBuilder.create() // front face
                .width(size).height(size)
                .fill(front)
                .translateX(-0.5*size)
                .translateY(-0.5*size)
                .translateZ(-0.5*size)
                    .smooth(true)
                    .stroke(Color.BLACK)
                .build()
        );
    }
    }



    PerspectiveCamera camera = new PerspectiveCamera(true);
    @Override public void start(Stage primaryStage) throws Exception {

    Group root = new Group();
    Scene scene=new Scene(root,600,600,true);

    camera.setNearClip(0.00001);
    camera.setFarClip(10000000.0);

    camera.getTransforms().addAll (
            new Rotate(0, Rotate.Y_AXIS),
            new Rotate(0, Rotate.X_AXIS),

            new Translate(0, 0, -1000));
    scene.setCamera(camera);
    Cube c1 = new Cube(50,Color.BLUE.darker(),Color.BLUE.darker(),Color.ORANGE.darker(),Color.BLUE.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
     c1.setTranslateX(100);

    Cube c2 = new Cube(50,Color.GREEN.darker(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c2.setTranslateX(50);

    Cube c3 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c3.setTranslateX(50);
    c3.setTranslateZ(50);

    Cube c4 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c4.setTranslateX(100);
    c4.setTranslateZ(50);

    Cube c5 = new Cube(50,Color.BLUE.darker(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.BLUE.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
     c5.setTranslateX(100);
     c5.setTranslateY(50);

    Cube c6 = new Cube(50,Color.GREEN.darker(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c6.setTranslateX(50);
    c6.setTranslateY(50);

    Cube c7 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.GREEN.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c7.setTranslateX(50);
    c7.setTranslateZ(50);
    c7.setTranslateY(50);

    Cube c8 = new Cube(50,Color.CYAN.brighter(),Color.GREEN.darker(),Color.ORANGE.darker(),Color.YELLOW.darker(),Color.BLUE.darker(),Color.RED.darker(),1);
    c8.setTranslateX(100);
    c8.setTranslateZ(50);
    c8.setTranslateY(50);
    handleMouse(scene,root);
    Group k=new Group(c1,c2,c3,c4,c5,c6,c7,c8);
    root.getChildren().addAll(k);
    primaryStage.setScene(scene);
    primaryStage.show();
    }
    public static void main(String[] args) { launch(args); }
    private static final double CONTROL_MULTIPLIER = 0.1;   
    private static final double SHIFT_MULTIPLIER = 10.0;   
    private static final double MOUSE_SPEED = 0.1;    
  private static final double ROTATION_SPEED = 2.0; 
  double mousePosX,mousePosY,mouseOldX,mouseOldY,mouseDeltaX,mouseDeltaY;
  private void handleMouse(Scene scene, final Node root) {


    scene.setOnMousePressed(new EventHandler<MouseEvent>() {
        @Override public void handle(MouseEvent me) {
             mousePosX = me.getSceneX();
             mousePosY = me.getSceneY();
             mouseOldX = me.getSceneX();
             mouseOldY = me.getSceneY();
        }
    });
    scene.setOnMouseDragged(new EventHandler<MouseEvent>() {
        @Override public void handle(MouseEvent me) {
            mouseOldX = mousePosX;
            mouseOldY = mousePosY;
            mousePosX = me.getSceneX();
            mousePosY = me.getSceneY();
            mouseDeltaX = (mousePosX - mouseOldX); 
            mouseDeltaY = (mousePosY - mouseOldY);

           double modifier = 1.0;

           if (me.isControlDown()) {
                modifier = CONTROL_MULTIPLIER;
            } 
            if (me.isShiftDown()) {
                modifier = SHIFT_MULTIPLIER;
            }     
            if (me.isPrimaryButtonDown()) {
                camera.setRotationAxis(Rotate.Y_AXIS);camera.setRotate(camera.getRotate() -
                   mouseDeltaX*modifier*ROTATION_SPEED);  // 
               camera.setRotationAxis(Rotate.X_AXIS);camera.setRotate(camera.getRotate() +
                   mouseDeltaY*modifier*ROTATION_SPEED);  // -

            }
            else if (me.isSecondaryButtonDown()) {
                double z = camera.getTranslateZ();
                double newZ = z + mouseDeltaX*MOUSE_SPEED*modifier;
                camera.setTranslateZ(newZ);
            }

       }
   }); // setOnMouseDragged
 } //handleMouse
}
\$\endgroup\$
  • 1
    \$\begingroup\$ Could you narrow down the example further? For example, does 1 cube render OK? I'm guessing this is an issue with the order in which the rectangles are rendered. \$\endgroup\$ – Anko Nov 21 '15 at 19:45
  • \$\begingroup\$ The same problem with one cube rendered. The opposite and adjacent faces gets overlapped. \$\endgroup\$ – Debarun Mukherjee Nov 21 '15 at 19:49
  • \$\begingroup\$ Is there any alternate way to create the cube in which i will not encounter such problems? \$\endgroup\$ – Debarun Mukherjee Nov 21 '15 at 20:23
1
\$\begingroup\$

I would recommend that you create a custom mesh for your cube utilising TriangleMesh. This should help...

https://stackoverflow.com/questions/19459012/how-to-create-custom-3d-model-in-javafx-8

You should also look at the JDK 8 JavaFX examples (http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html), as there are also importers for .obj file format models. It would then be very simple to import a custom cube created in .obj format with separate materials for each face. Or you could just create a simple billboard object with two triangles representing each face of each cube. And simply group 6 of these to form a cube, rather than using the RectangleBuilder approach. The depth buffer will then work correctly with the approach I've detailed here.

Also, http://docs.oracle.com/javafx/8/3d_graphics/shapes_3d.htm

\$\endgroup\$
  • 1
    \$\begingroup\$ +1, but I had figured out the problem. The problem was related to my faulty setting of the near and far clips of my perspective camera. \$\endgroup\$ – Debarun Mukherjee Apr 4 '16 at 18:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.