Texture only the top of a cylinder

Hi guys,

I want add a texture, this is an image(png), on the top of a cylinder. Unfortunately I have no idea about texturing.
Can anyone help me? This is my code:

        turnTable = new Cylinder(100, 100, TABLERADIUS, 1, true);
        Geometry turnTableGeo = new Geometry("turn-table", turnTable);
        Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
        mat.setColor("Diffuse", ColorRGBA.White);
        mat.setColor("Specular", ColorRGBA.White);
        Texture texture = assetManager.loadTexture("wood.jpg");
        mat.setTexture("DiffuseMap", texture);
        turnTableGeo.setMaterial(mat);
        turnTableGeo.setLocalTranslation(0, -0.5f * TABLEHEIGHT, 0);
        turnTableGeo.rotateUpTo(Vector3f.UNIT_Y);

And the result is the following:

But I want only the texture on the top or botton of the cylinder.

thanks in advanced.

You have to do this in a 3D modelling software like Blender! Best would be you combine both textures (the black one and the one which you want to add) to one new texture file. In Blender you will have to apply the texture coordinates to that cylinder model.

However, it seems like you are not familiar with 3D modelling at all, so I recommend you to watch some tutorials on YouTube or search the wiki.
https://jmonkeyengine.github.io/wiki/jme3/external/blender.html#uv-mapped-textures

You think is not possible do it with jme? It can be an image which lay over of the top of the cylinder.

Well, if you really want to do it in JME (for whatever reason), which is way more complicated you could use a plane, move it so that it fits the top and then apply a texture with alpha channel.

This is not proper though!!! Really, do it in Blender!

I thought there are any example code for this case. I have no idea about blender and no time to learn it.

Not that I know! You will have to spend some time though whether you work with blender or not.

Learning blender is a time investment with an amazing return if you do a lot of related stuff. I can’t believe how useful it’s been to me, I can literally make nice looking animated icons for anything in less then 2 minutes.

1 Like

No example code could possibly fix that issue (well, unless you want solid colors). If you can’t learn a tool like Blender, you’ll have to obtain ready-made 3D assets that jME can work with.

You could try one of those low-poly graphics themes like this…

Interestingly, that picture was from an article about how to do this w/Blender…

And before you say it, yes I know, using Blender feels like putting your brain in a Blender. But we can’t deny that it’s damn powerful, at the best possible (monetary) price.

2 Likes

Game engines are just that, engines. Not a 3d modeling tool. Modeling tools are very complex beasts that have a huge number of features to do such things as UV texturing.

In every game engine out there. You import models + textures from a modeling tool. Personally i think blender is a very good tool for the modeling part.

You will need to learn about texturing and you wouldn’t go wrong with a quick UV texture blender tutorial. There are many. Then you can just import it directly.

I know 3D stuff is really cool but I need just once then never again.
I’ve created a cylinder in blender and added texture but in blender the texture is only on the top and in jmonkey on both side and the edges, too.

Its about texture coordinates and then maths. You want to map a texture to a bunch of triangles that are arranged in a pie-like formation. You have to assign the correct coordinates in the texture (from 0,0 to 1,1) to the vertices that make up these triangles.

Can you tell where I can find this option in blender or must it set in jme?
I don’t find this option.

Of course I searched in goolge and I found good video but it seemed very complicated. But I will try it.
Every beginning is hard :slight_smile:

1 Like

My solution to this problem:

public static Geometry setUVPlanaerProject(Geometry geometry, Vector3f projectionNormal) {
    VertexBuffer position = geometry.getMesh().getBuffer(VertexBuffer.Type.Position);
    VertexBuffer texcoord = geometry.getMesh().getBuffer(VertexBuffer.Type.TexCoord);

    // Calculate the transform vectors
    projectionNormal = projectionNormal.normalize();
    float b = 0.0f != projectionNormal.x ? projectionNormal.x : projectionNormal.z;
    float a = 0.0f != projectionNormal.y ? projectionNormal.y : projectionNormal.z;

    Vector3f uVect = new Vector3f(a, -b, 0).normalize();
    Vector3f vVect = projectionNormal.cross(uVect);

    for (int i = 0; i < position.getNumElements(); i++) {
        // Read from vertex buffer
        Vector3f vector = new Vector3f();
        vector.x = ((Float) position.getElementComponent(i, 0));
        vector.y = ((Float) position.getElementComponent(i, 1));
        vector.z = ((Float) position.getElementComponent(i, 2));
        vector = vector.normalize();
    
        // Calculate uv coordinates
        float u = uVect.dot(vector);
        float v = vVect.dot(vector);
    
        // Write to the uv coords the the Texcoord buffer.
        texcoord.setElementComponent(i, 0, u);
        texcoord.setElementComponent(i, 1, v);
    }

    return geometry;
}

Now I call this method on my cylinder, and pass Vector3f.UNIT_Z, as the second argument.

3 Likes