Application strange behavior

Hi,



I’m from Chile and this is my first post so I wish to share a little details of my project and ask you one question about my problem.



I’m developing an application (not game) that will display DXF (autocad) map and put over this map some icons showing specific details of real world sensors (temperature, earth movement, etc.). This product aims the mining sector and will be a very useful tool to some mining workers. Right now the product is almost done, but we now need to build a 3d map to replace an old 2d map engine (google maps like). So we choose JME3 to build this 3d map stuff because we are java developers and we have a short time to finish it.



The problem is that I’m not a game developer and I have a little experience on 3d programming (little apps for fun on the past using Ogre). So right now I have this problem:



Over my loaded dxf im trying to display some 3d meshes, but they are acting in a strange way, its flickering and i can see through it. I will post some code snippets here and please, if anyone can help me I appreciate.



Youtube video:

http://www.youtube.com/watch?v=J3rskt-_mxM



Map loading:
[java]
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
mat.setBoolean("VertexColor", true);

...

Iterator<DXFLayer> iLayer = doc.getDXFLayerIterator();
while (iLayer.hasNext()) {


DXFLayer layer = iLayer.next();

CustomMesh mesh = new CustomMesh(50000, 1000);
mesh.setMode(Mesh.Mode.Lines);

if (!layer.isVisible())
continue;

List<DXFPolyline> polyLines = layer
.getDXFEntities(DXFConstants.ENTITY_TYPE_POLYLINE);

if (polyLines != null) {

for (DXFPolyline polyline : polyLines) {

if (polyline.getVertexCount() <= 1) {
continue;
}

mesh.setColor(ColorHelper.fromColorIndex(polyline
.getColor()));

Iterator<DXFVertex> iVertex = polyline.getVertexIterator();

boolean isFirst = true;
Vector3f buffer = null;
Vector3f firstVertex = null;
Vector3f currentVertex = null;

while (iVertex.hasNext()) {
DXFVertex vertex = iVertex.next();

points++;

currentVertex = new Vector3f(
(float) vertex.getPoint().getX(),
(float) vertex.getPoint().getY(),
(float) vertex.getPoint().getZ());

if (buffer != null && currentVertex.distance(buffer) < minFactor*0.001 && iVertex.hasNext()) {
ignoredPoints++;
continue;
}

if (isFirst) {
firstVertex = currentVertex;
}

mesh.addVertex(currentVertex);

if (!isFirst && iVertex.hasNext()) {
mesh.addVertex(currentVertex);
}

buffer = currentVertex;
isFirst = false;
}

if (polyline.isClosed()) {
mesh.addVertex(currentVertex);
mesh.addVertex(firstVertex);
}
}
}

mesh.finish();
Geometry geom = new Geometry("map", mesh);
geom.setMaterial(mat);
app.getRootNode().attachChild(geom);
[/java]

Box creation:
[java]
Box b = new Box(new Vector3f(0, 0, 0), 100f, 100f, 100f);
Geometry g2 = new Geometry("Box", b);
g2.setMaterial(mat);
g2.setLocalTranslation(20f, 20f, -250f);
attachChild(g2);
[/java]


Thanks,

Solved, this line was causing problem:



[java]

cam.setFrustumPerspective(45f,

(float) cam.getWidth() / cam.getHeight(), 0.0001f, 1000000f);

[/java]



Correction:



[java]

cam.setFrustumPerspective(45f,

(float) cam.getWidth() / cam.getHeight(), 1f, 999999999);

[/java]





The near value lower than 1f was causing this problems. I dont know why, but its woking now.



Thanks,

1 Like
@tiago156 said:
Solved, this line was causing problem:

[java]
cam.setFrustumPerspective(45f,
(float) cam.getWidth() / cam.getHeight(), 0.0001f, 1000000f);
[/java]

Correction:

[java]
cam.setFrustumPerspective(45f,
(float) cam.getWidth() / cam.getHeight(), 1f, 999999999);
[/java]


The near value lower than 1f was causing this problems. I dont know why, but its woking now.

Thanks,


The z-buffer only has so much resolution. When you set it to near of 0.0001 and far of 1000000 then the zbuffer cannot accommodate the full range. Pixels relatively near each other (but not near the near plane) will end up with the same z value... then first writer wins. The wider the range, the worse this is.

And it's not a range like "far - near". It's a range resolution more like "far / near".
2 Likes

Thanks @pspeed, good to know that.

I just had class about problems with high near far values a couple of weeks ago, lol! I recommend that if you don’t use a such high distance (999,999,999 world units) you should reduce that far value to avoid this problem again with different distances (zoom levels). You may probally find this again with such a high value.

What I don’t understand is that when I use the combination of near:1f/far:999999999f I get better results than using near:10f/far:999999999f. Am I missing something?



About the 999.999.999 i will get the autocad dxf map bounds and try to get some magical number to set the far distance.



Thanks,

@tiago156 because you are setting the buffer to be too big, way too big, bigger than anything.



Take a look at your map, you think is it that big? When you zoom in, do you need all that terrain to show up (think in meters. The near plane is 1 meter away from your eye, and the far plane is at 1 thousand kilometers away). The problem is that when the rounding occurs, depending on the size of your buffer, and the implementation of the z-buffer, you will get different results. The rounding is not better at 1 then at 10, it’s just luck that for the objects that you are drawing, their sizes and their distances are getting correctly rounded.



I suggest you do the following: reduce the far distance to something way smaller. Check out your maps and their sizes. Do you need to be looking at the horizon and see 1000km away? Remember that if you are using perspective projection (and you are) those objects, unless they are HUGE, they will be shown as a pixel because of the distance. You can easily scale your far plane down. And if you want somehow to zoom out (I mean really zoom out a lot), you could then calculate the distance to the terrain, and then use this to set the near and far plane to contain the terrain.

@shirkit said:
@tiago156 because you are setting the buffer to be too big, way too big, bigger than anything.

Take a look at your map, you think is it that big? When you zoom in, do you need all that terrain to show up (think in meters. The near plane is 1 meter away from your eye, and the far plane is at 1 thousand kilometers away). The problem is that when the rounding occurs, depending on the size of your buffer, and the implementation of the z-buffer, you will get different results. The rounding is not better at 1 then at 10, it's just luck that for the objects that you are drawing, their sizes and their distances are getting correctly rounded.

I suggest you do the following: reduce the far distance to something way smaller. Check out your maps and their sizes. Do you need to be looking at the horizon and see 1000km away? Remember that if you are using perspective projection (and you are) those objects, unless they are HUGE, they will be shown as a pixel because of the distance. You can easily scale your far plane down. And if you want somehow to zoom out (I mean really zoom out a lot), you could then calculate the distance to the terrain, and then use this to set the near and far plane to contain the terrain.


@shirkit now im setting it to near:1f - far: 7400, but now all my billboards are flickering....

http://i.imgur.com/y6ZxH.png

The markers are composed by:

+ Node (With billboard control attached)
- Quad (colored pin)
[java]
Quad q = new Quad(100, 100);
Geometry geom = new Geometry("obj", q);
Material mat = new Material(MapApplication.getInstance()
.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", MapApplication.getInstance()
.getAssetManager().loadTexture("marker.png"));
mat.setColor("Color", ColorRGBA.randomColor());
mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
mat.getAdditionalRenderState().setAlphaTest(true);
geom.setMaterial(mat);
geom.setLocalTranslation(1, 0, 0);
attachChild(geom);
[/java]
- Quad (white circle image)
[java]
Quad q = new Quad(50, 50);
Geometry geom = new Geometry("obj", q);
Material mat = new Material(MapApplication.getInstance()
.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", MapApplication.getInstance()
.getAssetManager().loadTexture("prism.png"));
mat.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
geom.setMaterial(mat);
geom.setLocalTranslation(26, 46, 0.1f);
attachChild(geom);
[/java]
- Bitmap Text (above text)
[java]
BitmapFont fnt = MapApplication.getInstance().getAssetManager()
.loadFont("Interface/Fonts/Default.fnt");
BitmapText txt = new BitmapText(fnt, false);
txt.setBox(new Rectangle(-50, 130, 200, 30));
txt.setQueueBucket(Bucket.Transparent);
txt.setAlignment(Align.Center);

txt.setSize(25f);
txt.setText(state.getName());
attachChild(txt);
[/java]


Thanks,

If you have alpha blending on the quads then make sure to put them in the transparent bucket.



Are they flickering against the terrain, against each other, or is the text/white box/marker flicker against other parts of the marker?

@pspeed said:
If you have alpha blending on the quads then make sure to put them in the transparent bucket.

Are they flickering against the terrain, against each other, or is the text/white box/marker flicker against other parts of the marker?


I've changed the node Bucket to Transparent:

[java]setQueueBucket(Bucket.Transparent);[/java]

But the still flickering. The white quad is flickering against the colored marker billboard.

Note that the distance between the two quads is 0.1f (code previous post).

http://www.youtube.com/watch?v=4sBEUfa1OV8


Thanks,
@tiago156 said:
But the still flickering. The white quad is flickering against the colored marker billboard.


That small distance may not be enough to get them to sort properly. Given that they are billboards, you could probably increase it without affecting the visual look. The only alternative (if it's just a sorting problem) is to add a custom sorter that makes sure the white boxes are always in front of their markers. Increasing the offset is easier, though.
@pspeed said:
That small distance may not be enough to get them to sort properly. Given that they are billboards, you could probably increase it without affecting the visual look. The only alternative (if it's just a sorting problem) is to add a custom sorter that makes sure the white boxes are always in front of their markers. Increasing the offset is easier, though.


I've changed the offset to 1, and then to 10 and some markers still flickering :( , how can I try this custom sorter? Can you please provide some snippet (jme3)?

Thanks,

I have cards flying around 0.1f (or smaller) from other cards all the time with no flickering problems at all. It is in a much smaller scene though. Have you made sure your frustrum far really is as close as it can be without cutting stuff of?



Have you made sure there isn’t a mistake in the positioning meaning the gap isn’t actually 0.1f?



One solution might be to use something like ImagePainter to create merged icons for each point then you only have a single quad there and hence nothing to flicker with.

@zarch said:
I have cards flying around 0.1f (or smaller) from other cards all the time with no flickering problems at all. It is in a much smaller scene though. Have you made sure your frustrum far really is as close as it can be without cutting stuff of?

Have you made sure there isn't a mistake in the positioning meaning the gap isn't actually 0.1f?

One solution might be to use something like ImagePainter to create merged icons for each point then you only have a single quad there and hence nothing to flicker with.


Right now the minimum acceptable value of far distance is 7500, so im using: near:1f - far:7500f. About the gap between the billboards, im sure that is 0.1f. Im trying to not merge the textures because one of them will need to change color.

Thanks.
@zarch said:
I have cards flying around 0.1f (or smaller) from other cards all the time with no flickering problems at all. It is in a much smaller scene though. Have you made sure your frustrum far really is as close as it can be without cutting stuff of?

Have you made sure there isn't a mistake in the positioning meaning the gap isn't actually 0.1f?

One solution might be to use something like ImagePainter to create merged icons for each point then you only have a single quad there and hence nothing to flicker with.


In your case, your cards are relatively small so I'd expect 0.1 to be more than enough... but when the scale is 100s of meters, it might not be enough.

I'm not really sure it's his issue though. I think it's weird that in the pictures it looks like some of the markers are under the terrain.
@tiago156 said:
I've changed the offset to 1, and then to 10 and some markers still flickering :( , how can I try this custom sorter? Can you please provide some snippet (jme3)?

Thanks,


You set your own GeometryComparator for the bucket that you want custom sorted. How you sort is another issue. Personally, I've done things like add a "layer" UserData to the Geometry and only do the default sort of the layers are the same. Mythruna does a pure material based sort and only does the default if the materails are the same. There are many approaches.