Раскраска отдельных треугольников в треугольной сетке на javafx
У меня есть объект сетки треугольника в JAVAFX и хотел бы либо
- цвет отдельных треугольников треугольника сетки
или
- цвет отдельных вершин каждого треугольника и треугольник должны быть окрашены в соответствии с интерполяцией цветов каждой вершины (скажем, например, с затенением Gouraud).
конкретный объект сетки треугольника-это икосфера с миллионами граней (вот почему я я использую треугольную сетку: мне нужна скорость).
Я не использовал координаты текстуры, так как я не смог найти четкое объяснение этому с помощью JAVAFX, плюс я надеюсь, что есть более простой способ.
1 ответов
способ окраски работает в 3D-сетках JavaFX по материалу, который вы им назначаете. Для одной сетки есть один материал, и невозможно использовать разные материалы для разных треугольников одной и той же сетки.
поэтому, если вы хотите избежать текстур, я боюсь, что единственный способ-группировать треугольники с тем же цветом в той же сетке и создавать столько сеток, сколько цветов.
напротив, с текстурами относительно легко..., так как у вас есть только одна сетка, одна материал и одно изображение со всей окраской.
Я сделал пример икосаэдра, построил треугольник сетки для него и добавлена одна текстура для окраски всех граней.
для этого нам понадобится:
- 3D координаты 12 вершин,
- 2D нормализованные координаты УФ-отображения для текстур.
-
и 20 граней. Каждая грань определяется 6 индексами p0, t0, p1, t1, p3, t3, где p0, p1, p2 и p3-индексы в массиве точек, а t0, t1, t2 и t3-индексы в массиве texCoords.
публичный класс IcosahedronMesh расширяет MeshView {
public IcosahedronMesh(){ setMesh(createCube()); } private TriangleMesh createCube() { TriangleMesh m = new TriangleMesh(); // POINTS m.getPoints().addAll( 0f, 0f, -0.951057f, 0f, 0f, 0.951057f, -0.850651f, 0f, -0.425325f, 0.850651f, 0f, 0.425325f, 0.688191f, -0.5f, -0.425325f, 0.688191f, 0.5f, -0.425325f, -0.688191f, -0.5f, 0.425325f, -0.688191f, 0.5f, 0.425325f, -0.262866f, -0.809017f, -0.425325f, -0.262866f, 0.809017f, -0.425325f, 0.262866f, -0.809017f, 0.425325f, 0.262866f, 0.809017f, 0.425325f ); // TEXTURES m.getTexCoords().addAll( 0.181818f, 0f, 0.363636f, 0f, 0.545455f, 0f, 0.727273f, 0f, 0.909091f, 0f, 0.0909091f, 0.333333f, 0.272727f, 0.333333f, 0.454545f, 0.333333f, 0.636364f, 0.333333f, 0.818182f, 0.333333f, 1f, 0.333333f, 0f, 0.666667f, 0.181818f, 0.666667f, 0.363636f, 0.666667f, 0.545455f, 0.666667f, 0.727273f, 0.666667f, 0.909091f, 0.666667f, 0.0909091f, 1f, 0.272727f, 1f, 0.454545f, 1f, 0.636364f, 1f, 0.818182f, 1f ); // FACES m.getFaces().addAll( 1, 6, 11, 5, 7, 0, 1, 12, 7, 11, 6, 5, 1, 7, 6, 6, 10, 1, 1, 13, 10, 12, 3, 6, 1, 8, 3, 7, 11, 2, 4, 14, 8, 13, 0, 7, 5, 9, 4, 8, 0, 3, 9, 15, 5, 14, 0, 8, 2, 10, 9, 9, 0, 4, 8, 16, 2, 15, 0, 9, 11, 5, 9, 6, 7, 12, 7, 11, 2, 12, 6, 17, 6, 6, 8, 7, 10, 13, 10, 12, 4, 13, 3, 18, 3, 7, 5, 8, 11, 14, 4, 13, 10, 14, 8, 19, 5, 8, 3, 9, 4, 15, 9, 14, 11, 15, 5, 20, 2, 9, 7, 10, 9, 16, 8, 15, 6, 16, 2, 21 ); return m; }
}
теперь нам нужно изображение с раскраской для каждого лица, на основе сети икосаэдра, как это:
(изображение нашел здесь)
обратите внимание, что отображение выполняется от (0,0) до (1,1) нормализованные координаты к изображению (слева,сверху) - (справа, снизу) пикселей.
давайте, наконец, создадим сцену, загрузим сетку и добавим текстуру к ее материалу:
@Override
public void start(Stage primaryStage) throws Exception {
Group sceneRoot = new Group();
Scene scene = new Scene(sceneRoot, 600, 600, true, SceneAntialiasing.BALANCED);
scene.setFill(Color.BLACK);
PerspectiveCamera camera = new PerspectiveCamera(true);
camera.setNearClip(0.1);
camera.setFarClip(10000.0);
camera.setTranslateZ(-4);
scene.setCamera(camera);
IcosahedronMesh mesh = new IcosahedronMesh();
mesh.setCullFace(CullFace.FRONT);
PhongMaterial mat = new PhongMaterial();
mat.setDiffuseMap(new Image(getClass().getResourceAsStream("icosah_net.png")));
mesh.setMaterial(mat);
Rotate rotateY = new Rotate(0, 0, 0, 0, Rotate.Y_AXIS);
mesh.getTransforms().addAll(new Rotate(30,Rotate.X_AXIS),rotateY);
sceneRoot.getChildren().addAll(mesh, new AmbientLight(Color.WHITE));
primaryStage.setTitle("JavaFX 3D - Icosahedron");
primaryStage.setScene(scene);
primaryStage.show();
}
вот как это выглядит:
редактировать
теперь, если вы думаете о том, как применять текстуры, вы могли бы упростить изображение до нескольких квадратов, с палитрой цветов вы нужно:
и координаты текстуры могут быть очень упрощены:
m.getTexCoords().addAll(
0.1f, 0.5f, // 0 red
0.3f, 0.5f, // 1 green
0.5f, 0.5f, // 2 blue
0.7f, 0.5f, // 3 yellow
0.9f, 0.5f // 4 orange
);
наконец, мы должны сопоставить эти точки в наших лицах. Следуя той же схеме, что и сетевое изображение:
m.getFaces().addAll(
1, 0, 11, 0, 7, 0,
1, 4, 7, 4, 6, 4,
1, 4, 6, 4, 10, 4,
1, 2, 10, 2, 3, 2,
1, 2, 3, 2, 11, 2,
4, 3, 8, 3, 0, 3,
5, 3, 4, 3, 0, 3,
9, 1, 5, 1, 0, 1,
2, 1, 9, 1, 0, 1,
8, 0, 2, 0, 0, 0,
11, 3, 9, 3, 7, 3,
7, 1, 2, 1, 6, 1,
6, 1, 8, 1, 10, 1,
10, 0, 4, 0, 3, 0,
3, 0, 5, 0, 11, 0,
4, 4, 10, 4, 8, 4,
5, 4, 3, 4, 4, 4,
9, 2, 11, 2, 5, 2,
2, 2, 7, 2, 9, 2,
8, 3, 6, 3, 2, 3
);
теперь у нас будет очень аккуратный икосаэдр, так как мы избавимся от границ и плохого разрешения изображения:
это может быть расширено до любой треугольной сетки или использовать любой алгоритм для уточнения треугольники.