Проблема с добавлением нескольких треугольных сеток к сцене в javafx

Я надеюсь, что кто-то может помочь мне с этой проблемой.

Я использую javafx и треугольную сетку для создания сферического объекта из треугольников (например, футбольный мяч). Различные плитки формы различаются по цвету, но я хочу добавить линии между плитками. Как в этом футболе:

Предоставленные 2D-линии javafx приносят ужасную производительность в 3D-пространстве. Поэтому я нашел FXyzLib, который обеспечивает PolyLine 3D. На самом деле это просто еще одна треугольная сетка, которая создает линию в трехмерном пространстве.

С этим я могу создавать 3D линии. Но если я хочу добавить их в мою исходную сетку треугольника, все остальное становится черным. Это также наоборот. Я экспериментировал с приведенным здесь примером библиотеки. Он создает причудливую трехмерную линию, но когда я попытался добавить простую красную сферу к сцене, сфера была просто черной, вот так:

этот,

Я не эксперт в этом и новичок в javafx и не смог найти проблему в коде PolyLine 3D. Это не должно быть проблемой, чтобы добавить Mutliple треугольник сетки к сцене. Существуют ли какие-либо эффекты освещения или камеры, о которых я не знаю?

РЕДАКТИРОВАТЬ: Я решил проблему. Окружающий свет, используемый в Polyline 3D, вызвал проблему. Если вы добавите свет для других ваших объектов, все будет хорошо.

1 ответ

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

Это может быть сделано с PolygonMesh который принимает любой действительный близкий многоугольник как лицо.

Эта реализация уже существует в проекте 3DViewer с открытым исходным кодом, который можно найти здесь. E сть PolygonMeshView контроль, который может сделать PolygonMesh,

Обратите внимание, что если вы используете эти два класса только в своем проекте, вам придется пока пропустить сетку подразделения.

Этот ответ уже использует четырехугольную сетку для визуализации Box без диагональных краев треугольной сетки.

Под капотом сетка Polygon использует треугольную сетку и внутренне преобразует предоставленные вами полигоны в треугольники.

Сетка усеченного икосаэдра

Таким образом, мы можем сделать нечто подобное, чтобы сгенерировать сетку усеченного икосаэдра, который является именем геометрической фигуры, которую мы можем использовать для создания упрощенной футбольной модели.

Он имеет 12 правильных пятиугольных граней, 20 правильных шестиугольных граней и 60 вершин.

Нам нужны трехмерные координаты этих вершин, двухмерные координаты текстур, а также индексы вершин и текстур для каждой из 32 граней.

Я использовал бесплатный онлайн- ресурс WolframCloud для песочницы, чтобы получить эти значения.

Например, вы можете запустить:

Flatten[PolyhedronData["TruncatedIcosahedron","VertexCoordinates"]//N]

чтобы получить список координат вершин:

Out[1]= {-0.16246,-2.11803,1.27598,-0.16246,2.11803,...}

и вы можете получить лица:

PolyhedronData["TruncatedIcosahedron","FaceIndices"]
Out[2]= {{53,11,24,23,9},{51,39,40,52,30},...}

Наконец, вам нужны координаты и индексы текстур, которые можно получить через Сеть икосаэдра:

PolyhedronData["TruncatedIcosahedron","Net"]
PolyhedronData["TruncatedIcosahedron","NetCoordinates"]

В этом случае вы получите 2D координаты 32 граней. Учитывая, что мы хотим иметь одинаковую текстуру для всех пятиугольников и одинаковую для всех шестиугольников, я привел некоторые манипуляции с этими координатами, чтобы получить это изображение текстуры:

только 9 вершин и их координаты (в системе координат JavaFX).

Этот метод содержит необходимую информацию для создания сетки:

private PolygonMesh getTruncatedIcosahedron() {
    float[] points = new float[]{
        -0.16246f,-2.11803f,1.27598f,       -0.16246f,2.11803f,1.27598f, 
        0.16246f,-2.11803f,-1.27598f,       0.16246f,2.11803f,-1.27598f,
        -0.262866f,-0.809017f,-2.32744f,    -0.262866f,-2.42705f,-0.425325f,
        -0.262866f,0.809017f,-2.32744f,     -0.262866f,2.42705f,-0.425325f,
        0.262866f,-0.809017f,2.32744f,      0.262866f,-2.42705f,0.425325f, 
        0.262866f,0.809017f,2.32744f,       0.262866f,2.42705f,0.425325f,
        0.688191f,-0.5f,-2.32744f,          0.688191f,0.5f,-2.32744f,
        1.21392f,-2.11803f,0.425325f,       1.21392f,2.11803f,0.425325f,
        -2.06457f,-0.5f,1.27598f,           -2.06457f,0.5f,1.27598f,
        -1.37638f,-1.f,1.80171f,            -1.37638f,1.f,1.80171f,
        -1.37638f,-1.61803f,-1.27598f,      -1.37638f,1.61803f,-1.27598f,
        -0.688191f,-0.5f,2.32744f,          -0.688191f,0.5f,2.32744f,
        1.37638f,-1.f,-1.80171f,            1.37638f,1.f,-1.80171f,
        1.37638f,-1.61803f,1.27598f,        1.37638f,1.61803f,1.27598f,
        -1.7013f,0.f,-1.80171f,             1.7013f,0.f,1.80171f,
        -1.21392f,-2.11803f,-0.425325f,     -1.21392f,2.11803f,-0.425325f,
        -1.96417f,-0.809017f,-1.27598f,     -1.96417f,0.809017f,-1.27598f,
        2.06457f,-0.5f,-1.27598f,           2.06457f,0.5f,-1.27598f,
        2.22703f,-1.f,-0.425325f,           2.22703f,1.f,-0.425325f,
        2.38949f,-0.5f,0.425325f,           2.38949f,0.5f,0.425325f,
        -1.11352f,-1.80902f,1.27598f,       -1.11352f,1.80902f,1.27598f,
        1.11352f,-1.80902f,-1.27598f,       1.11352f,1.80902f,-1.27598f,
        -2.38949f,-0.5f,-0.425325f,         -2.38949f,0.5f,-0.425325f,
        -1.63925f,-1.80902f,0.425325f,      -1.63925f,1.80902f,0.425325f,
        1.63925f,-1.80902f,-0.425325f,      1.63925f,1.80902f,-0.425325f,
        1.96417f,-0.809017f,1.27598f,       1.96417f,0.809017f,1.27598f,
        0.850651f,0.f,2.32744f,             -2.22703f,-1.f,0.425325f,
        -2.22703f,1.f,0.425325f,            -0.850651f,0.f,-2.32744f,
        -0.525731f,-1.61803f,-1.80171f,     -0.525731f,1.61803f,-1.80171f,
        0.525731f,-1.61803f,1.80171f,       0.525731f,1.61803f,1.80171f};

    float[] texCoords = new float[]{0.904508f,0.820298f, 0.75f,0.529535f, 0.25f,0.529535f, 0.0954915f,0.820298f, 0.5f,1f, 
                                    1f,0.264767f, 0.75f,0f, 0.25f,0f, 0f,0.264767f};

    int faces[][] = new int[][]{{52,0,10,1,23,2,22,3,8,4},
                        {50,0,38,1,39,2,51,3,29,4},
                        {59,0,27,1,15,2,11,3,1,4},
                        {19,0,41,1,47,2,54,3,17,4},
                        {18,0,16,1,53,2,46,3,40,4},
                        {0,0,9,1,14,2,26,3,58,4},
                        {35,0,25,1,43,2,49,3,37,4},
                        {3,0,57,1,21,2,31,3,7,4},
                        {33,0,28,1,32,2,44,3,45,4},
                        {20,0,56,1,2,2,5,3,30,4},
                        {36,0,48,1,42,2,24,3,34,4},
                        {12,0,4,1,55,2,6,3,13,4},
                        {8,1,58,5,26,6,50,7,29,8,52,2},
                        {52,1,29,5,51,6,27,7,59,8,10,2},
                        {10,1,59,5,1,6,41,7,19,8,23,2},
                        {23,1,19,5,17,6,16,7,18,8,22,2},
                        {22,1,18,5,40,6,0,7,58,8,8,2},
                        {12,1,24,5,42,6,2,7,56,8,4,2},
                        {4,1,56,5,20,6,32,7,28,8,55,2},
                        {55,1,28,5,33,6,21,7,57,8,6,2},
                        {6,1,57,5,3,6,43,7,25,8,13,2},
                        {13,1,25,5,35,6,34,7,24,8,12,2},
                        {39,1,37,5,49,6,15,7,27,8,51,2},
                        {15,1,49,5,43,6,3,7,7,8,11,2},
                        {11,1,7,5,31,6,47,7,41,8,1,2},
                        {47,1,31,5,21,6,33,7,45,8,54,2},
                        {54,1,45,5,44,6,53,7,16,8,17,2},
                        {53,1,44,5,32,6,20,7,30,8,46,2},
                        {46,1,30,5,5,6,9,7,0,8,40,2},
                        {9,1,5,5,2,6,42,7,48,8,14,2},
                        {14,1,48,5,36,6,38,7,50,8,26,2},
                        {38,1,36,5,34,6,35,7,37,8,39,2}};

    int[] smooth = new int[] {
        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
        11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 
        21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 
        31, 32
    };

    PolygonMesh mesh = new PolygonMesh(points, texCoords, faces);
    mesh.getFaceSmoothingGroups().addAll(smooth);
    return mesh;
}

Теперь вы можете легко добавить его в сцену:

private double mouseOldX, mouseOldY = 0;
private final Rotate rotateX = new Rotate(0, Rotate.X_AXIS);
private final Rotate rotateY = new Rotate(0, Rotate.Y_AXIS);

@Override
public void start(Stage primaryStage) {

    PolygonMeshView meshView = new PolygonMeshView(getTruncatedIcosahedron());

    final PhongMaterial phongMaterial = new PhongMaterial();
    meshView.setDrawMode(DrawMode.LINE);
    meshView.setMaterial(phongMaterial);
    final Group group = new Group(meshView);
    group.getTransforms().add(new Scale(50, 50, 50));
    Scene scene = new Scene(group, 500, 300, true, SceneAntialiasing.BALANCED);
    scene.setOnMousePressed(event -> {
        mouseOldX = event.getSceneX();
        mouseOldY = event.getSceneY();
    });

    scene.setOnMouseDragged(event -> {
        rotateX.setAngle(rotateX.getAngle() - (event.getSceneY() - mouseOldY));
        rotateY.setAngle(rotateY.getAngle() + (event.getSceneX() - mouseOldX));
        mouseOldX = event.getSceneX();
        mouseOldY = event.getSceneY();
    });

    PerspectiveCamera camera = new PerspectiveCamera(false);
    camera.setNearClip(0.1);
    camera.setFarClip(1000.0);
    camera.getTransforms().addAll(rotateX, rotateY, new Translate(-250, -150, 0));
    scene.setCamera(camera);

    primaryStage.setTitle("JavaFX 3D - Truncated Icosahedron");
    primaryStage.setScene(scene);
    primaryStage.show();
}

Дадим вам каркас:

каркасные

И если вы добавите изображение текстуры, вы получите свой футбол:

phongMaterial.setDiffuseMap(new Image(getClass().getResourceAsStream("net3.png")));
meshView.setDrawMode(DrawMode.FILL);       

футбол

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

Другие вопросы по тегам