Coloring individual triangles in a triangular grid on javafx

I have a triangular mesh object in JAVAFX and would like to either

  • colored individual triangles of a triangular grid

or

  1. color the individual vertices of each triangle and have the color of the triangle in accordance with the interpolation of the colors of each vertex (for example, with Gouraud shading).

The specific triangle mesh object is an isosphere with millions of faces (so I use a triangular mesh: I need speed).

I have NOT used texture coordinates, since I could not find a clear explanation for this using JAVAFX, and I hope there is an easier way.

+6
source share
1 answer

The coloring method works in JavaFX 3D networks based on the material that you assigned to them. There is one material for one grid, and it is impossible to imagine different materials for different triangles of the same grid.

So, if you want to avoid textures, I’m afraid that the only way is to group triangles with the same color in the same grid and create as many grids as colors.

Conversely, with textures is relatively easy ... since you only have one grid, one material and one image with all the coloring.

I gave an example of an icosahedron, built a mesh triangle for it, and added one texture to color all faces.

For this we need:

  • three-dimensional coordinates of 12 vertices,
  • 2D-normalized coordinates for uv mapping for textures.
  • and 20 persons. Each face is defined by 6 indices p0, t0, p1, t1, p3, t3, where p0, p1, p2 and p3 are indices in the points array, and t0, t1, t2 and t3 are indices in the texCoords array.

    Public class IcosahedronMesh extends 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; } 

    }

Now we need a coloring image for each face based on the icosahedron network, for example:

Net of an icosahedron

(Image found here )

Note that the mapping is performed from (0,0) to (1,1) normalized coordinates on the image (left, top) in (right, bottom) pixels.

Let's finally create a scene, load the mesh and add a texture to its material:

 @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(); } 

Here's what it looks like:

Icosahedron

EDIT

Now, if you are thinking about how texture is applied, you can simplify the image to a few squares with the color palette you need:

Palette of colors

And texture coordinates can be really simplified:

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

Finally, we must match these points on our faces. Following the same pattern as the network image:

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

Now we will have a very neat icosahedron, since we will get rid of borders and poor image resolution:

Improved icosahedron

This can be expanded to any triangular grid or use any algorithm to refine triangles.

+11
source

Source: https://habr.com/ru/post/977948/


All Articles