Get closest vertex

Hi all,

I’m using a GeomVertexRewriter to deform terrain:

``````    geomNodeCollection=self.node.findAllMatches('**/+GeomNode')
for child in geomNodeCollection.asList():
for i in range(child.node().getNumGeoms()):
rewriter=GeomVertexRewriter(child.node().getGeom(i).getVertexData(),'vertex')
while not rewriter.isAtEnd():
v=rewriter.getData3f()
print v``````

where self.node is the terrain.
This loops through all the vertices and prints out their positions.
But, I do not want all the vertices, just the vertex closes to the player, to be deformed (e.g. when digging)
How to get the vertex closest to a certain point? Do I need to loop through all the vertices and compare them to the player’s position? And how shall get I the right vertex back afterwards?

Any help/ideas/suggestions/comment is welcome.

EDIT: Why, if I make the Z position of all vertices 0.0, the terrain starts to flicker and some parts disappear/appear?

Unless you do some other trick on your own, like storing all the vertex indices in an octree or something, right–Panda doesn’t provide an easier way to reverse-index into a GeomVertexData. These things are designed for fast rendering, not for fast editing.

Sorry, I don’t understand your question here.

This is called Z-fighting, and happens whenever you have two or more polygons that are exactly coplanar and occupy the same space. Since the depth equation evaluates exactly the same for both polygons, in practice one or the other of them will appear to be in front at random, dependent on your viewing angle and according to the limits of numerical precision in the graphics card. So they will appear to flicker as you look at them from different angles.

David

Perhaps you can create a “convex hull” data structure for your models. I mean a list of all vertices who are on the “surface” (I know this might not be the right term, but I don’t know a better). A vertex who is “inside” the model will never be the closest one. This way you won’t need to check all vertices.

If you really like to experiment you could have a look at the Newton library, collision.closestPoint( … ). It is wrapped, but I never tested it.

enn0x

EDIT: Please forget what I have written. I missed you are talking about terrain. What I have written works for convex meshes, but terrain is not convex. Sorry.

How to solve that problem?

Ah, one way is not to set all the Z coordinates to 0.0

For instance, if your goal is just to make the terrain look completely flat, you could simply scale all the Z coordinates by a tiny value, for instance, 0.01 or 0.001. This would allow for some numerical variation in the Z coordinates, which may be enough to avoid the Z-fighting, but it would still look pretty darn flat visually.

Otherwise, you have to play games with disabling depth test or depth write, and that’s usually tricky business.

David

You could try render your terrain first and then render your stuff over it. Imposing an explicit order to the terrain to always render on the background.

Not an option, because I have roaming characters…