How to draw a line

Hello everyone!



I am facing quite silly question about jme3 - how to draw a simple line? Somehow my efforts with creating Mesh and setting the VertexBuffer did not work. Can anyone help?



Wojciech

1 Like

[edit]My bad, i was thinking to JME2[/edit]

1 Like

Mesh m = new Mesh();
m.setMode(Mesh.Mode.Lines);

// Line from 0,0,0 to 0,1,0
m.setBuffer(VertexBuffer.Type.Position, 3, new float[]{ 0, 0, 0, 0, 1, 0});
m.setBuffer(VertexBuffer.Type.Index, 2, new short[]{ 0, 1 });


That's the basic concept. To edit the points of the line just edit the position float buffer.
1 Like

Thank you Momoko_Fan for your help. I added this code to my application:


Mesh mesh = new Mesh();
mesh.setMode(Mesh.Mode.Lines);
mesh.setBuffer(VertexBuffer.Type.Position, 3, new float[]{ 0, 0, 0, 0, 1, 0});
mesh.setBuffer(VertexBuffer.Type.Index, 2, new short[]{ 0, 1 });
rootNode.attachChild(new Geometry("line", mesh));


and after running the application i got NullPointerException at com.jme3.renderer.queue.OpaqueComparator.compare(OpaqueComparator.java:59)
I suspect it might have something to do with materials, but I am not sure. Is there a solution for this?
2 Likes

yes, add a material to it, see the test package, there are some examples

1 Like

If you create a mesh manually like that, you must update the bound and counts, I forgot to include that. m.updateBound() and m.updateCounts() should do it.

1 Like

Thank you very much for your help! Below is the code that renders red line, from point [0,0,0] to point [0,1,0].



Mesh lineMesh = new Mesh();
lineMesh.setMode(Mesh.Mode.Lines);
lineMesh.setBuffer(VertexBuffer.Type.Position, 3, new float[]{ 0, 0, 0, 0, 1, 0});
lineMesh.setBuffer(VertexBuffer.Type.Index, 2, new short[]{ 0, 1 });
//lineMesh.updateBound();
//lineMesh.updateCounts();
Geometry lineGeometry = new Geometry("line", lineMesh);
Material lineMaterial = getAssetManager().loadMaterial("red_color.j3m");
lineGeometry.setMaterial(lineMaterial);
rootNode.attachChild(lineGeometry);



What I noticed is that two method calls:


lineMesh.updateBound();
lineMesh.updateCounts();


were not required to properly draw a line, so it seems that it is not necessary to call them (or not?).

What wonders me now is that if it is possible to draw a line, triangle or anything without need to set material to it? And I would like to ask if specification of *.j3m and *.j3md files is available somewhere?
3 Likes

You might still want to call these methods, especially updateBound() since the line might get culled when it is actually visible.

1 Like

Well i just tried to create a single Triangle, but failed miserably,



my idea is:



Mesh lineMesh = new Mesh();
//guess this mode then
lineMesh.setMode(Mesh.Mode.Triangles);

//what to put in place of the 3 ? and why was it a 3 anyways isn't a line only consisting of 2 points?
lineMesh.setBuffer(VertexBuffer.Type.Position, 3, new float[]{ 0,0,0, 0,1,0 0,1,1});

//well i think just adding a 2 is correct, nothing complicated here?
lineMesh.setBuffer(VertexBuffer.Type.Index, 3, new short[]{ 0, 1,2 });

lineMesh.updateBound();
lineMesh.updateCounts();

Geometry lineGeometry = new Geometry("line", lineMesh);

//jsut a hack/fix for the Absolut loading, copy pased out of some example
Material lineMaterial = manager.loadMaterial("Textures/Terrain/Pond/Pond.j3m");

lineGeometry.setMaterial(lineMaterial);

rootNode.attachChild(lineGeometry);



1 Like

That looks fine, but you gotta have texture coordinates if you want texture mapping to work correctly.

1 Like

I hope it's the texture, because i'm unable to see it(however the debug obj count increases when lookin in that direction.)

Well how can I set Texture coordinates?



lineMesh.setBuffer(VertexBuffer.Type.TexCoord,3, new short[]{0,0, 1,1, 0,1});

3 points to give texture coordinates, some 2d vectors between 0 and 1 in each component. does that make sense?

1 Like

Well ok it seems to work fine as said above, but i today came to the conclusion that it would be far more effective, if I could create a convex object directly without having to create each single triangle, However i kinda miss any example on how I could do this… As well the implementation of the box is not really healpfull if you try to understand something…



        fpb.put(new float[] {
                v[0].x, v[0].y, v[0].z, v[1].x, v[1].y, v[1].z, v[2].x, v[2].y, v[2].z, v[3].x, v[3].y, v[3].z, // back
                v[1].x, v[1].y, v[1].z, v[4].x, v[4].y, v[4].z, v[6].x, v[6].y, v[6].z, v[2].x, v[2].y, v[2].z, // right
                v[4].x, v[4].y, v[4].z, v[5].x, v[5].y, v[5].z, v[7].x, v[7].y, v[7].z, v[6].x, v[6].y, v[6].z, // front
                v[5].x, v[5].y, v[5].z, v[0].x, v[0].y, v[0].z, v[3].x, v[3].y, v[3].z, v[7].x, v[7].y, v[7].z, // left
                v[2].x, v[2].y, v[2].z, v[6].x, v[6].y, v[6].z, v[7].x, v[7].y, v[7].z, v[3].x, v[3].y, v[3].z, // top
                v[0].x, v[0].y, v[0].z, v[5].x, v[5].y, v[5].z, v[4].x, v[4].y, v[4].z, v[1].x, v[1].y, v[1].z  // bottom
        });



As far as I understand it just passes each corner for each side, and thats it, ok, but what should I set here then?
lineMesh.setMode(Mesh.Mode.Triangles);
As triangles (at least for me) does not seem to fit anymore.
1 Like

The 2nd integer argument to the setbuffer calls is the number of components per vertex, there are two components for texture coordinates, U and V, then you should specify 2 instead of 3.

Also, using shorts for texcoords is not recommended, you should use floats instead



lineMesh.setBuffer(VertexBuffer.Type.TexCoord, 2[tt], new float[]{0,0, 1,1, 0,1});

1 Like

Yes that fixed a few missing textures, depending on orientation of the triangle.



I'm still stuck however to think of an efficient way to create a triangleshape out of a array of Vector3fs that form a convex shape :confused:

1 Like

What exactly are you trying to create? Did you look at how the shape classes work? It is not supposed to be very simple to create "triangleshapes"… Usually you would create them in a modeling tool and then import them into jME3.

1 Like

A vmf to jme compiler, however the vmf format specifies only convex objects, and gives all points for each corner :confused:

1 Like

Well, this isn't jME3's problem is it? My job is just to provide an interface so you could create vertex buffers using whether method you choose. Importing VMF files is a whole different story then.

1 Like

Yes, never said it's your job ^^



I'm just thought there may be a way to set the mode to a convex type, so i don't have to  calculate those triangles… But well seems like there is no such thing, so I have to think about how to calculate all those triangles manually…

1 Like

found a tut where everything is explained!



http://test.hub.jmonkeyengine.org/wiki/doku.php/jme3:advanced:custom_meshes

1 Like

sorry for bumping,

i am fairly new to jME3 and Java

i am trying to draw a route from an array of points (preferably in a 2D view as well) in a route editor for a train game. The player must be able to add/edit routes with a point and click method, had this working in a jFrame with AWT but poor frame rates made me experiment with jME3 and now i would like to have this working in jME3.

I could draw a single line using the above method in my function:

private void add2DLine( Position A, Position B, Node myNode ) {

    Mesh lineMesh = new Mesh();

    lineMesh.setMode(Mesh.Mode.Lines);

    lineMesh.setBuffer(VertexBuffer.Type.Position, 3, new float[]{ (float) A.getXPos(), (float) A.getYPos(), (float) A.getZPos(), (float) B.getXPos(), (float) B.getYPos(), (float) B.getZPos()});

    lineMesh.setBuffer(VertexBuffer.Type.Index, 2, new short[]{ 0, 1 });

    lineMesh.updateBound();

    lineMesh.updateCounts();

    Geometry lineGeometry = new Geometry("line", lineMesh);

    Material lineMaterial = assetManager.loadMaterial("Common/Materials/RedColor.j3m");
    
    lineGeometry.setMaterial(lineMaterial);

    myNode.attachChild(lineGeometry);

};

but when i init my world:

add2DLine( new Position ( 0.0, 0.0, 0.0), new Position (0.0, 1.0, 0.0), View2D );
add2DLine( new Position ( 0.0, 1.0, 0.0), new Position (0.0, 1.0, 1.0), View2D );
add2DLine( new Position ( 0.0, 1.0, 1.0), new Position (0.0, 2.0, 1.0), View2D );

i only see one line, where i expected to see 3 connected lines
(View2D is a Node which gets attached to rootNode upon entering edit mode, default mu View3D node is displayed)

1 Like