Editing vertex positions from GE is a mess

Hello again,
I want to plot in “real-time” a function related to the position of some objects in my application. So after a bit of googling and headaches I now know that I have manipulate individual vertex of an existing mesh. The problem is that, even though the order of vertex in “Edit Mode” tells me: 1,2,3,4… that order seems to be completely wrong in “Game Mode”.
I don’t know how to explain better so I created a simple example trying to plot a math.sin function in one side of my mesh. I have included a script to retrieve the vertex index inside “Edit Mode”. You have to press the Space Bar to see the plotting.

Attachments

badMesh.blend (663 KB)

The order of the vertices is not wrong. There is simply no order. A mesh consists of a bunch of faces. Each face consists of 3 or 4 vertices, which define the dimensions and the orientation of the face.

It is like a circle. Where does a circle start? and where does it end?

The “natural” order in the BGE is the creation order. This means the face build first comes first. You should never rely on that, as it can quickly change.

If you need an order you need to project the bunch of faces, to whatever you define your order. For example, you can sort them by direction. If you compare two faces, the one that has a vertex more north than all vertices of the other face is sorted before the other. You can even sort by size, color, material, neighbors, whatever.

Just apply a projection and you get what you want. Without a projection, treat them as an un-ordered bunch of faces. Any order you might discover is more or less random and not guarantied.

bunch of faces --> projection --> sorted list of faces

or in python:


facesBySize= sortBySize(bunchOfFaces)

Hi again Monster and sorry for not replying before, I’ve been pretty busy.
I understand your explanation about how the BGE works with meshes and faces… unfortunately I don’t get your explanation on how to solve my problem. When I have a grid with all square faces of the same size, there won’t be a property to order them with, right? and that’s what I have… it’s a square grid with all the faces of the same size.
I’m seriously thinking about forgetting this since even when I can not get the shape that I want, my simulations get sooooo slow when trying to edit the positions of all vertices in a mesh. Any suggestion about how to accelerate this process will be much appreciated as well.

I believe Monster’s point was just that the BGE’s vertex indices are separate from Blender’s indices, so you’ll have to sort them yourself (i.e. vertex 0 may or may not be the same in the BGE as in Blender). So, you’ll have to get the indices and sort the vertices yourself from within the engine to get info about them reliably.

I would just loop through the vertices once, and append them to different object property lists (or a single list, with different lists within) for different axes. You have sets of vertices, all on separate rows, so each row, or pairs of rows (for faces) could be a list. Once you add the vertices to a list, you can use the list’s sort() function to sort it by the vertices’ X-position, or so on. At the end, you’d get a manageable list that allows you to get a vertex at a specific point on the grid; it’d basically be a coordinate map (finding a vertex by going to the first column, second vertex, for example). You can also easily extend this out to be both the vertex as well as it’s coordinate pair (column / row), if you need it.

You could also just loop through the faces if you’re using faces rather than vertices. The advantage of this would be dealing with one of the visible squares of the grid if the vertices are supposed to be connected to each other, rather than dealing with individual points. The disadvantage is that you can’t modify faces really; you just can get the vertices making up the faces that you modify to move / alter the faces.

If this doesn’t help, it might be more useful to specify exactly what you’re trying to achieve.

Agoose77 made a Python module to help you with that, try the forum search

the code of vertex is pure **.

you can see immediately there :

for vidx in range(mesh.getVertexArrayLenght()))
vert = mesh.getVertex(0,vidx)

not was yet invented the list ?_? how old is ?? 50 years?

of couse to get polygons is worse

it should be simply:

for v in mesh.verts:

for p in mesh.polys:

a poly should/can return:

normal : poly.normal(1) = local; (0) = global
position : poly.position(1) = local; (0) = global

end. this is waht can do the code in this age.

plus the ability to read vertex group will be a lot useful

As everyone mentioned, make your own list. I use dicts to give a coordinate for each group of vertices. In blender, you can order the vertices, because they are grouped for editing purposes, so what seems to be 1 vertices is in fact 1,2,3 or 4 vertices. In the BGE, all 4 are present and can be accessed, so there’s no way to order them the way blender does.
So you can loop through the mesh and make so that for all vertices in position (x,y,z) append vertex. Once you get a dict, you can access the vertices way faster, since you wont have to loop through the mesh any longer!
Good luck!

LOD? you can’t add or remove faces. You can only replace the complete mesh. Which finally is faster then editing the mesh with Python.

There is currently no dynamic mesh generating/manipulating LOD implemented in the BGE. I saw a demo of a terrain shader. But this will be a visible terrain only (no physics, no logic).

[edit]
Here is a modified version of your file. It shows you how you can arrange the vertices and form a sinus curve.

Indeed you could do that without the lookup as the curve depends on the vertices coordinates. This means the same coordinates result in the same deformation ;).

If you really need you can sort the lookup by the key (= X axis value).

maybe this helps

Attachments

badMesh_revized.blend (606 KB)

Hi everybody, thanks for the discussion and the suggestions.
Thanks Monster for taking your time and helping me with the revised version of my example. Sorry it took some time to reply but it seems I still have a long way to walk down the Python road. I was lost in your implementation of function “retrieveVerticesByX(mesh)”. Now I’ve learned a bit more about dictionaries :slight_smile:
If I understood it right, you are collecting all vertices that share the same X coordinate in one group and then assigning the same Y bias from the Sine function. That is already a huge improvement of what I had before, but what I’m really aiming is at assigning a different Y value for each X row. I hope you understand what I mean, for example what if I want the first row of my mesh to plot a sine wave of magnitude 1, the following rows to plot decreasing magnitudes of the same sine wave until the last row where the deviation from Y is 0.
My plan in the end is to use this method to plot the time behavior of a mathematical function… so each row plots the history, maybe the last 10 or 20 previous time-steps of the behavior of my mathematical function.
Thanks again

So after playing a bit more with your code I realized that vertices are also sorted in the Y direction… at least that’s how they appear in the simulation when I create a variable “deformation” in your deformSinAlongXY() function:


def deformSinAlongXY(verticesLookup):
    for key, vertices in verticesLookup.items():
        deform = math.sin(math.pi*key)
        gain = 1.0
        for vertex in vertices:
            vertex.z += gain*deform
            gain -= 0.1

Thanks for all the help, now it’s doing what I want. I just hope this is still a good solution when I run several of these meshes in real time… I wish there was a way of multi-threading my whole application so I can send the plotting part to a different process and not slow down the rest of the game engine.
Still I think this thread is solved :slight_smile:

Be aware that the Y-sort is accidentally. This will be different with other meshes. Better no rely on that.

Nevertheless you still have the coordinates (x,y,z) and the above formula do not require a specific order.