Javafx: применение изображения к сетке не работает

Я пытаюсь применить изображение к моему кубу meshview с помощью phongmaterial, но на экране отображается только черный куб без цвета. Раньше с коробкой и кубом работало, а теперь и с ними не работает.

А также, может ли кто-нибудь сказать мне, как получить грани конкретного куба ??

Вот мой код:

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

}

}

Вот изображение, которое я хочу использовать.


person Manik Shakya    schedule 22.12.2017    source источник


Ответы (1)


Вы на правильном пути, но вам необходимо:

  • Используйте нормализованные координаты текстуры от 0.0f до 1.0f
  • Не устанавливайте диффузный цвет прозрачным, просто установите изображение диффузной карты.

Для первой части просто определите общую длину и высоту изображения сети:

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

а затем нормализовать координаты текстуры:

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};    

Для второй части просто используйте сеттер:

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

И у вас есть текстурированный куб (с включением групп сглаживания):

Текстурированный куб

ИЗМЕНИТЬ

Чтобы узнать верхнюю грань после любого возможного поворота, это можно легко сделать, если вы определите текущие цвета и нормали на основе сетевого изображения и порядка определения граней:

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,
};

Затем вы хотите отследить верхнюю грань, которая соответствует нормальному {0, -1, 0} в координатах сцены.

Итак, в основном вам нужно выразить эту нормаль в координатах сетки:

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

и, наконец, вы должны сопоставить эту нормаль с любой из тех, что определены в normals. Индекс этого даст вам цвет:

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";
}
person José Pereda    schedule 22.12.2017
comment
Привет Хосе, изображение теперь работает нормально. но когда я бросаю кости случайным образом, я хочу распечатать цвет, который находится сверху. Я пытался вернуть лицо, но он возвращает общее количество лиц. - person Manik Shakya; 22.12.2017
comment
Если вы правильно масштабируете координаты текстуры (между 0-1), вы должны получить изображение, которое я разместил. Вы получите сетку по каждой грани, если разделите координаты текстуры на 100, а не на L (400) или H (300). - person José Pereda; 22.12.2017
comment
Как использовать faceSmoothingGroups, чтобы отслеживать, какая сторона находится сверху? - person Manik Shakya; 22.12.2017
comment
Для этого используйте PickResult. Из события мыши, такого как щелчок или нажатие, вы можете получить, например, event.getPickResult().getIntersectedFace(). Для этого не нужны группы сглаживания. Просто сделай: m.setOnMouseClicked(e -> System.out.println("e " + e.getPickResult().getIntersectedFace())); - person José Pereda; 23.12.2017
comment
Отлично, подумайте о том, чтобы принять ответ, чтобы он мог быть полезен и другим. - person José Pereda; 23.12.2017
comment
Привет, Хосе, у меня последний вопрос. Как мы отследим верхнюю часть грани куба без события мыши. с камерой или когда кости брошены и лежат на 180 градусов внизу. Я хочу вернуть цвет кубика, который находится сверху. Не могли бы вы помочь мне с этим, пожалуйста? Спасибо - person Manik Shakya; 23.12.2017
comment
как мне вернуть, какой цвет на вершине кости? - person Manik Shakya; 23.12.2017