Drawing a simple circle in JME3

For debugging purposes I need to draw some simple lines and circles.



While a Line class exists in JME3 there is no corresponding class for a circle. I found a patch on the forums that added a Circle class to JME2 but that seems to work quite differently than in JME3.



Is it planned to add this?

1 Like

Not really, jME3 is really more geared towards an import-pipeline rather than creating visuals with primitives. you can look at the (currently broken) debug sphere mesh to see how you could create circles, if you come up with something, please post it here.

Ok, this is what I got. I’m not really familiar with 3D yet, so I guess the tex-coord buffer is still wrong. But the result looks ok anyhow :wink:

[java]

/**

  • Circle.

    *
  • @author Martin Simons
  • @version $Id$

    */

    public class Circle

    extends Mesh

    {

    /**
  • The center.

    */

    private Vector3f center;



    /**
  • The radius.

    */

    private float radius;



    /**
  • The samples.

    */

    private int samples;



    /**
  • Constructs a new instance of this class.

    *
  • @param radius

    */

    public Circle(float radius)

    {

    this(Vector3f.ZERO, radius, 16);

    }



    /**
  • Constructs a new instance of this class.

    *
  • @param radius
  • @param samples

    */

    public Circle(float radius, int samples)

    {

    this(Vector3f.ZERO, radius, samples);

    }



    /**
  • Constructs a new instance of this class.

    *
  • @param center
  • @param radius
  • @param samples

    */

    public Circle(Vector3f center, float radius, int samples)

    {

    super();

    this.center = center;

    this.radius = radius;

    this.samples = samples;



    setMode(Mode.Lines);

    updateGeometry();

    }



    protected void updateGeometry()

    {

    FloatBuffer positions = BufferUtils.createFloatBuffer(samples * 3);

    FloatBuffer normals = BufferUtils.createFloatBuffer(samples * 3);

    short[] indices = new short[samples * 2];



    float rate = FastMath.TWO_PI / (float) samples;

    float angle = 0;

    for (int i = 0; i < samples; i++)

    {

    float x = FastMath.cos(angle) + center.x;

    float z = FastMath.sin(angle) + center.z;



    positions.put(x * radius).put(center.y).put(z * radius);

    normals.put(new float[] { 0, 1, 0 });

    indices = (short) i;

    if (i < samples - 1)

    indices = (short) (i + 1);

    else

    indices = 0;



    angle += rate;

    }



    setBuffer(Type.Position, 3, positions);

    setBuffer(Type.Normal, 3, normals);

    setBuffer(Type.Index, 2, indices);



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



    updateBound();

    }

    [/java]
8 Likes

Thanks!

You needed something, you did it and then share with people.

I’d like there were more people “unfamiliar with 3D” like you!!

Thank you very much

2 Likes

Lunikon thanks for the code.

Another thank you for the code :slight_smile:

Is this going to be added to the engine? Would be really useful I think!

I’m a complete idiot - can someone be kind enough to explain at least the general idea behind that beautiful thing, because I’m getting some errors plus my mongoloid brain do not know simple thing like initiate that class.

On top of that, can I draw lines equal to circle radius?

To be maybe more specific, what I do with:
[java]indices = (short) i;
if (i < samples – 1)
indices
= (short) (i + 1);
else
indices
= 0;
[/java]

And can I initiate that class like that:
[java]
Circle c1 = new Circle(Vector3f.ZERO, 10, 10);
Geometry c1Geometry = new Geometry(“kolo”, c1);
Material mat1 = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);
mat1.setColor(“GlowColor”,ColorRGBA.White);
c1Geometry.setMaterial(mat1);
[/java]

Sorry for stupidity. Thanks for any helpful words. : )

also this using java2D

http://hub.jmonkeyengine.org/forum/topic/drawing-simple-circle-using-java-2d/

@MrParticle said: I'm a complete idiot - can someone be kind enough to explain at least the general idea behind that beautiful thing, because I'm getting some errors plus my mongoloid brain do not know simple thing like initiate that class.

replace all instances of
[java]
indices < /i > < i >
[/java]
with
[java]
indices[ i ]
[/java]

Either op mistyped or forum mangled the square brackets to an italicize tag… or some such combination of mistyping and forum mangling. For example, i used &lt; to keep the forum from monkeying with the brackets, but if I hit edit, my character entity is gone, and the actual brackets are there. If I hit submit without putting the character entities back, it’s treated like html <i> tags.

@MrParticle said: And can I initiate that class like that:

Yes, that’s precisely how to initiate it.

Hopefully you’ve already figured this out on your own, but in case you haven’t, better late than never, eh?

@lunikon - Thanks for sharing!!

Hello @lunikon @new-Thrall . Thank you for sharing this cool thing. I’m trying to put your example to SimpleExamples project.
But it seems i did something wrong. Here is my screenshot:

Here are my classes:
https://code.google.com/p/jme-simple-examples/source/browse/JMESimpleExamples/src/com/intermediate/Circle3d.java
https://code.google.com/p/jme-simple-examples/source/browse/JMESimpleExamples/src/com/intermediate/Circle3dTest.java

I think i did a mistake with indices (lines 82-87). Can you help me?

Thanks.

You have to use each vertex twice. It looks like right now your indices array is something like this:
{1,2,3,4,5,6,7,8,9,10,1}
While it should contain each index twice, like this:
{1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,1}

I hope you understand what I mean.

@beniboy said: You have to use each vertex twice. It looks like right now your indices array is something like this: {1,2,3,4,5,6,7,8,9,10,1} While it should contain each index twice, like this: {1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,1}

I hope you understand what I mean.

Sorry i missunderstand you. Can you just put some code with fixes?

What he means is that the line segment vertices are not connected correctly. To fix do something like this:

[java]
int idc = 0;
for (int i = 0; i < segments; i++)
{
float x = FastMath.cos(angle) + center.x;
float y = FastMath.sin(angle) + center.y;

        positions.put(x * radius).put(y * radius).put(center.z);
        normals.put(new float[]{0, 0, 1});
        indices[idc++] = (short) i;
        if (i&lt;segments-1)
            indices[idc++] = (short)(i+1);
        else
            indices[idc++] = 0;
        angle += rate ;
    }

[/java]

and give the indices array the proper size:

[java]short[] indices = new short[segments * 2];[/java]

@dasbenni said: What he means is that the line segment vertices are not connected correctly. To fix do something like this:

Thank you a lot! It seems your fix is cool!
http://code.google.com/p/jme-simple-examples/source/detail?r=537926cbc8f4723eb281358aa8c2d74d45427854

The only question:
if i set 32 samples
[java]Circle3d circle = new Circle3d(Vector3f.ZERO, 3f, 32);
[/java]

I have 1032 vertices in a scene with the circle. And i have 996 vertices without the circle (empty scene). difference between 1032 and 996 is 36 vertices. Is it ok?

You’re welcome :slight_smile:

I checked with a new Project (BasicGame); Without the Circle displayed its 920 vertices, with it displayed its 952 for me; which sounds about right. Maybe your 4 extra vertices come from something else?

Edit: I checked by adding the Circle to the rootnode and then looking at it, looking away from it. Now I repeated that using your code and removing the rootNode.attachChild call from the source results in the same behaviour as you reported, thus I checked if it happens with the Box too, and it does, so it seems to be tied to the adding itself, not to the actual mesh.
You can get the vertex count for the mesh with circle.getVertexCount() and it should show 32, as it should for rootNode.getVertexCount().

Pretty long shot guess: May be its just the additional number when going from =1000 vertices in the stats view.

Anyways: In conclusion, all good.

If your test shows that it’s ok. Then it’s ok. :slight_smile:

Conclusion is good. :slight_smile:

Hi, I just searched for a Circle Class and found this. I’m sorry to pull this old thread out, but I want to fix a bug.
You should replace this code
[java]
float x = FastMath.cos(angle) + center.x;
float z = FastMath.sin(angle) + center.z;

positions.put(x * radius).put(center.y).put(z * radius);

[/java]

with this one

[java]
float x = FastMath.cos(angle)*radius + center.x;
float z = FastMath.sin(angle)*radius + center.z;

positions.put(x).put(center.y).put(z);

[/java]

If you make a circle with 7 radius and center point (10,10), your code would result with a circle whose right border is at 77 (far away from 17)

@asdfgh4xx0r said: Hi, I just searched for a Circle Class and found this. I'm sorry to pull this old thread out, but I want to fix a bug.

If you make a circle with 7 radius and center point (10,10), your code would result with a circle whose right border is at 77 (far away from 17)

Thanks a lot! Fixed.
https://code.google.com/p/jme-simple-examples/source/detail?r=70c895b90d59ad50e3284413920c8cc4c5eb325d

Another simple solution(i suppose not optimal though) is to create a Torus with very small outer radius
e.g.


float R=1f;
Torus tor=new Torus(32,2,0.001f,R);

1 Like