Rounding position of vertices in a mesh?

I am trying to covert the float positions of vertices to integer positions. So, instead of a vertex being located at 2.057356, it would just be located at 2. I’ve looked at the Blender API, and it seems there is an array of Mesh.Vertices that will give you all of the vertices in a mesh. I am thinking I could use a for loop convert all of the float locations to integers? Could somebody help me out with writing the python for this?

i dont know about this ‘verticles’ but you can use the int() option to convert float or even strings to int or use the round() option to round it of.
so if you managed to get all vertexes, you can do something like


vertex_list = [your list]

for vertex in vertex_list:
    int_vertex = int(vertex)

there is a nice example how to get vertices in
https://www.blender.org/api/blender_python_api_2_73_5/bge.types.KX_MeshProxy.html#bge.types.KX_MeshProxy

once you have the vertex, you have the functions getXYZ and setXYZ.
https://www.blender.org/api/blender_python_api_2_73_5/bge.types.KX_VertexProxy.html#bge.types.KX_VertexProxy

so you could

vertex.setXYZ([int(i) for i in vertex.getXYZ()])

also figure out what you need, round, int or floor
try what they do

int(-1.1)
int(-1.7)
int(1.7)
int(1.1)

round(-1.1)
round(-1.7)
round(1.7)
round(1.1)

Math.floor(-1.1)
Math.floor(-1.7)
Math.floor(1.7)
Math.floor(1.1)

Short explanation:


float a = 1.8
float b = 1.1
float c = -0.4
float d = -4.6

print(int(a))
>>1

print(round(a))
>>2

print(math.floor(a))
>>1

print(int(b))
>>1

print(round(b))
>>1

print(math.floor(b))
>>1

print(int(c))
>>0

print(round(c))
>>0

print(math.floor(c))
>>-1

print(int(d))
>>-4

print(round(d))
>>-5

print(math.floor(d))
>>-5

As you can see, int() truncates and always tends to get closer to zero.
round() does what you understand by round - n.0 - n.4999999… will return n, but n.5 - n.999999… will return n+1.
math,floor() will always reduce. This is good for puttings things in integer grid.

Well, I got the first part working, but now I have a new issue. The vertex coordinates I get are in local, not global space. I need the vertices to snap to global coordinates. Anybody know how?

Just add the object’s position.

Multiply by object’s worldTransform. World transform is a 4x4 matrix that holds player’s position, rotation and scaling. It’s used in order to get object from local space to global space. It’s very important part of vertex shader as it moves the vertex to the object’s position in world rather than fixing it on screen.

This is what I have so far. It seems to more-or-less work, but it completely breaks when I try to use a motion actuator. I have this script attached to a delay sensor that goes off every frame.

Basically, what I’m trying to simulate is the polygon jittering that the PS1 had.

from bge import logicfrom mathutils import Vector


cont = logic.getCurrentController()
object = cont.owner


for mesh in object.meshes:
   for m_index in range(len(mesh.materials)):
      for v_index in range(mesh.getVertexArrayLength(m_index)):
         vertex = mesh.getVertex(m_index, v_index)   
         nx = round(vertex.XYZ[0] + object.worldPosition[0])
         ny = round(vertex.XYZ[1] + object.worldPosition[1])
         nz = round(vertex.XYZ[2] + object.worldPosition[2])
            
         vertex.XYZ = [ nx, ny, nz]

Adding the object position will only be valid unless you never turn the object. (see the post with transformation matrix).

You need to run the code at each frame when the position changed (the mesh update will get a visible one frame delay!).

Would it be possible to do this using a vertex shader to prevent having the 1 frame delay?

Yes, it is. I’m sure this is more efficient. Be aware both methods influence the render only. They have no influence on physics.