# Custom Mesh Shapes

Use the Mesh class to create custom shapes that go beyond Quad, Box, Cylinder, and Sphere, even procedural shapes are possible. Thank you to KayTrance for providing the sample code! In this tutorial, we (re)create a very simple rectangular mesh, and we have a look at different ways of coloring it. A flat rectangle may not look useful because it's exactly the same as a `com.jme3.scene.shape.Quad`. We choose this simple example in order to show you how to build any shape out of triangles ??? without the distractions of more complex shapes.

- Full code sample:

## Polygon Meshes

Polygon meshes are made up of triangles. The corners of the triangles are vertices. So, when ever you create a new shape, you break it down into triangles. Let's look at a cube. A cube is made up of 6 rectangles. Each rectangle can be broken down into two triangles. This means you need 12 triangles to create a cube mesh. You also need to know the 8 corner coordinates (vertices). The trick is that you have to specify the vertices in a certain order: Each triangle separately, counter-clockwise. Sounds worse than it is ??? here is an example:

## Creating a Quad Mesh

Okay, we want to create a Quad. A quad has four vertices, and is made up of two triangles. The base class for creating meshes is `com.jme3.scene.Mesh`.

    Mesh mesh = new Mesh();

If you create your own Mesh-based class, replace `mesh` by `this` in the following examples:

    public class MyMesh extends Mesh {  }

### Vertices

To define your own shape, determine its vertex positions in space. Store them in an array using com.jme3.math.Vector3f. For a Quad, we need four vertices: Bottom left, bottom right, top left, top right. We name the array `vertices[]`.

    Vector3f [] vertices = new Vector3f[4];
    vertices[0] = new Vector3f(0,0,0);
    vertices[1] = new Vector3f(3,0,0);
    vertices[2] = new Vector3f(0,3,0);
    vertices[3] = new Vector3f(3,3,0);

### Texture Coordinates

Next, define the Quad's 2D texture coordinates for each vertex, in the same order: Bottom left, bottom right, top left, top right. We name this array `texCoord[]`

    Vector2f[] texCoord = new Vector2f[4];
    texCoord[0] = new Vector2f(0,0);
    texCoord[1] = new Vector2f(1,0);
    texCoord[2] = new Vector2f(0,1);
    texCoord[3] = new Vector2f(1,1);

### Connecting the Dots

Next we turn the unrelated coordinates into triangles ??? We define the order in which the mesh is constructed. Think of these indexes as coming in groups of three. Each group of indexes describes one triangle. Note that you must specify the vertices counter-clockwise!

    int [] indexes = { 2,0,1, 1,3,2 };

- The 2,0,1 triangle starts at top left, continues bottom left, and ends at bottom right.
- The 1,3,2 triangle start at bottom right, continues top right, and ends at top left.

    2\2--3
    | \  | Counter-clockwise
    |  \ |
    0--1\1

### Setting the Mesh Buffer

The Mesh data is stored in a buffer.

1. Using `com.jme3.util.BufferUtils`, we create three buffers for the three types of information we have:
   - vertex positions,
   - texture coordinates,
   - indices.
2. We assign the data to the appropriate type of buffer inside the mesh object. The three buffer types are taken from an enum in `com.jme3.scene.VertexBuffer.Type`.
3. The third parameter describes the number of components of the values. Vertex postions are 3 float values, texture coordinates are 2 float values, and the indices are 3 ints representing 3 vertices in a triangle.
4. In order for jMonkey to correctly show the mesh in the scene, it needs to know the bounds of our new mesh. This can easily be achieved by calling the updateBound() method on it.

    mesh.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
    mesh.setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoord));
    mesh.setBuffer(Type.Index,    3, BufferUtils.createIntBuffer(indexes));
    mesh.updateBound();

Our Mesh is ready! Now we want to see it.

## Using the Mesh in a Scene

We create a `com.jme3.scene.Geometry`, apply a simple color material to it, and attach it to the rootNode to make it appear in the scene.

    Geometry geo = new Geometry("OurMesh", mesh);
    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    mat.setColor("Color", ColorRGBA.Blue);
    geo.setMaterial(mat);
    rootNode.attachChild(geo);

Ta-daa!

## Dynamic Meshes

If modifying a mesh dynamically in a way which would change the model's bounds then you need to call updateModelBound() on the Geometry object containing the mesh after calling updateBounds() on the mesh object. There is a warning on updateModelBounds about not usually needing to use it but that can be ignored in this special case.

## Optional Mesh Features

There are more vertex buffers in a Mesh than the three shown above. For an overview, see also mesh.

### Example: Vertex Colors

Vertex coloring is a simple way of coloring meshes. Instead of just assigning one solid color, each vertex (corner) has a color assigned. The faces between the vertices are then colored with a gradient. You can use the same mesh `mesh` object that you defined above.

    Geometry geo = new Geometry ("ColoredMesh", mesh);
    Material matVC = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
    matVC.setBoolean("VertexColor", true);

You create a float array color buffer:

- Assign 4 color values, RGBA, to each vertex.
  - To loop over the 4 color values, use a color index

        int colorIndex = 0;

- The color buffer contains four color values for each vertex.
  - The Quad in this example has 4 vertices.

        float[] colorArray = new float[4*4];

  - Tip: If your mesh has a different number of vertices, you would write:

        float[] colorArray = new float[yourVertexCount * 4]

Loop over the colorArray buffer to quickly set some RGBA value for each vertex. As usual, RGBA color values range from 0.0f to 1.0f. Note that the color values in this example are arbitrarily chosen. It's just a quick loop to give every vertex a different RGBA value (a purplish gray, purple, a greenish gray, green, see screenshot), without writing too much code. For your own mesh, you'd assign meaningful values for the color buffer depending on which color you want your mesh to have.

    for(int i = 0; i < 4; i++){
       // Red value (is increased by .2 on each next vertex here)
       colorArray[colorIndex++]= 0.1f+(.2f*i);
       // Green value (is reduced by .2 on each next vertex)
       colorArray[colorIndex++]= 0.9f-(0.2f*i);
       // Blue value (remains the same in our case)
       colorArray[colorIndex++]= 0.5f;
       // Alpha value (no transparency set here)
       colorArray[colorIndex++]= 1.0f;
    }

Next, set the color buffer. An RGBA color value contains four float components, thus the parameter `4`.

    mesh.setBuffer(Type.Color, 4, colorArray);
    geo.setMaterial(matVC);

Now you see a gradient color extending from each vertex.

### Example: Shaded Mesh with Normals

The examples used the mesh together with the Unshaded.j3md material. If you want to use the Mesh with a Phong illuminated material (such as Lighting.j3md), the mesh needs to include information about its normals. (The Normals encode in which direction a mesh polygon is facing, which is important for calculating light and shadow.)

    float[] normals = new float[12];
    normals = new float[]{0,0,1, 0,0,1, 0,0,1, 0,0,1};
    mesh.setBuffer(Type.Normal, 3, BufferUtils.createFloatBuffer(normals));

You need as many normals as the polygon has vertices. For a flat quad, they point all in the same direction. In this case, the direction is the Z unit vector (Vector3f.UNIT_Z), this means the quad is facing the camera.

### Example: Point Mode

Alternatively, you can show the vertices as colored points instead of coloring the faces.

    Geometry coloredMesh = new Geometry ("ColoredMesh", cMesh);
    ...
    mesh.setMode(Mesh.Mode.Points);
    mesh.setPointSize(10f);
    mesh.updateBound();
    mesh.setStatic();
    Geometry points = new Geometry("Points", mesh);
    points.setMaterial(mat);
    rootNode.attachChild(points);
    rootNode.attachChild(geo);

This will result in a 10 px dot being rendered for each of the four vertices. The dot has the vertex color you specified above. The Quad's faces are not rendered at all. This can be used for a special debugging or editing mode.

## Debugging Tip: Culling

By default, jME3 optimizes a mesh by culling (not drawing) its backfaces. It determines which side the front or backface of a mesh is by the order of the vertices: The frontface is the one where the vertices are specified counter-clockwise.

This means for you that your custom mesh is invisible when seen from "behind" or from the inside. This may not be a problem, often this is even intended because it's faster. The player will not look at the inside of most things anyway. For example, if your custom mesh is a closed polyhedron, or a flat wallpaper-like object, then rendering the backfaces (the inside of the pillar, the back of the painting, etc) would indeed be a waste of resources.

In case however that your usecase requires the backfaces to be visible, you have two options:

- If you have a very simple scene, you can just deactivate backface culling for this one mesh's material.
  `mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);`
- The recommended solution is to specify each triangle twice, the second time with the opposite order of vertices. The second, reversed triangle is a second frontface that replaces the culled backface.
  `int[] indexes = { 2,0,1, 1,3,2, 2,3,1, 1,0,2 };`

See also: Spatial ??? contains more info about how to debug custom meshes (that do not render as expected) by changing the default culling behaviour.

spatial, node, mesh, geometry, scenegraph

view online version