Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javafx: applying image to meshview not working

I am trying to apply the image to my meshview cube with phongmaterial but only the black cube with no colour is showing up on the screen. It used to work with the Box and a cube, but now its not working with them too.

And also, Can anyone tell me how to get the specific cube's faces??

Here is my code:

Rotate rxBox = new Rotate(30, 0, 0, 0, Rotate.X_AXIS);
Rotate ryBox = new Rotate(50, 0, 0, 0, Rotate.Y_AXIS);
Rotate rzBox = new Rotate(30, 0, 0, 0, Rotate.Z_AXIS);

@Override
public void start(Stage primaryStage) {


    float hw = 100/2f;
    float hh = 100/2f;
    float hd = 100/2f;

    float points[] = {
            hw, hh, hd,
            hw, hh, -hd,
            hw, -hh, hd,
            hw, -hh, -hd,
            -hw, hh, hd,
            -hw, hh, -hd,
            -hw, -hh, hd,
            -hw, -hh, -hd};

    float tex[] = {
            100, 0,
            200, 0,
            0, 100,
            100, 100,
            200, 100,
            300, 100,
            400, 100,
            0, 200,
            100, 200,
            200, 200,
            300, 200,
            400, 200,
            100, 300,
            200, 300};

    int faces[] = {
            0, 10, 2, 5, 1, 9,
            2, 5, 3, 4, 1, 9,
            4, 7, 5, 8, 6, 2,
            6, 2, 5, 8, 7, 3,
            0, 13, 1, 9, 4, 12,
            4, 12, 1, 9, 5, 8,
            2, 1, 6, 0, 3, 4,
            3, 4, 6, 0, 7, 3,
            0, 10, 4, 11, 2, 5,
            2, 5, 4, 11, 6, 6,
            1, 9, 3, 4, 5, 8,
            5, 8, 3, 4, 7, 3};

    int[] facesSmoothingGroups = {0,0,1,1,2,2,3,3,4,4,5,5};

   // URL resource = Main.class.getResource("DFv8z.png");
    Image diffuseMap = new Image(Main.class.getResource("PCmIW.png").toExternalForm());

    TriangleMesh mesh = new TriangleMesh();
    mesh.getPoints().addAll(points);
    mesh.getTexCoords().addAll(tex);
    mesh.getFaces().addAll(faces);
   // mesh.getFaceSmoothingGroups().addAll(facesSmoothingGroups);

    Material cubeMaterial = new PhongMaterial(Color.TRANSPARENT, diffuseMap, null, null, null);

    MeshView m = new MeshView(mesh);
    m.getTransforms().addAll(rxBox, ryBox, rzBox);
    m.setMaterial(cubeMaterial);

    final Group g = new Group(m);

    g.setTranslateX(400/2);
    g.setTranslateY(400/2);
    //g.setTranslateZ(400/2);
    g.setRotationAxis(Rotate.Y_AXIS);
    g.setRotationAxis(Rotate.X_AXIS);
    //g.setRotationAxis(Rotate.Z_AXIS);




    Scene scene = new Scene(g, 400, 400, Color.SKYBLUE);


    primaryStage.setTitle("Hello World");
    primaryStage.setScene(scene);
    primaryStage.show();

}

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

@Override
public void handle(MouseEvent event) {
    // TODO Auto-generated method stub

}

}

Here is the image i want to use.

like image 998
Manik Shakya Avatar asked Oct 20 '25 03:10

Manik Shakya


1 Answers

You are on the right track but you need to:

  • Use normalized texture coordinates, between 0.0f and 1.0f
  • Don't set the diffuse color to transparent, just set the diffuse map image.

For the first part, just define the total length and height of the net image:

float L = 400f;
float H = 300f;

and then normalize the texture coordinates:

float tex[] = {
        100f / L,   0f / H,
        200f / L,   0f / H,
          0f / L, 100f / H,
        100f / L, 100f / H,
        200f / L, 100f / H,
        300f / L, 100f / H,
        400f / L, 100f / H,
          0f / L, 200f / H,
        100f / L, 200f / H,
        200f / L, 200f / H,
        300f / L, 200f / H,
        400f / L, 200f / H,
        100f / L, 300f / H,
        200f / L, 300f / H};    

For the second part, just use the setter:

PhongMaterial cubeMaterial = new PhongMaterial();
cubeMaterial.setDiffuseMap(diffuseMap);

And you have your textured cube (enabling the smoothing groups):

Textured cube

EDIT

In order to find out the top face, after any possible rotation, this can be done easily if you define the current colors and normals, based on the net image and the order of how faces are defined:

final String[] colors = {"Blue", "Red", "White", "Yellow", "Cyan", "Green"};

float normals[] = {
     1f,  0f,  0f,
    -1f,  0f,  0f,
     0f,  1f,  0f,
     0f, -1f,  0f,
     0f,  0f,  1f,
     0f,  0f, -1f,
};

Then, you want to track the top face, which corresponds to the normal {0, -1, 0} in scene coordinates.

So basically you need to express that normal in the mesh coordinates:

Point3D normal = m.sceneToLocal(0, -1, 0);

and finally you have to match this normal to any of those defined in normals. The index of that one will give you the color:

private String getColor(MeshView m, float[] normals) {

    Point3D normal = m.sceneToLocal(0, -1, 0);

    for (int i = 0; i < normals.length; i += 3) {
        if (normals[i] * normal.getX() + normals[i+1] * normal.getY() + normals[i+2] * normal.getZ() > 0.99) {
            return colors[i / 3];
        }
    }
    return "no color found";
}
like image 79
José Pereda Avatar answered Oct 24 '25 10:10

José Pereda



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!