4
$\begingroup$

I want to set up a script that randomly changes the shape of an object. What I have so far is:

from bge import logic
import random

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)
         vertex.setXYZ([ random.random(), random.random(), random.random()])

This works pretty well. However, since every single vertex gets its own random location, the cube turns out something like this:

random shape 1

what I want is something like this:

random shape 2

My question is: how can I achieve something like that?

I think the "broken" shapes happen because 3 vertices are connected to each other and if they all get a different random position, the shape "breaks"?

I assume, that I have to give the vertices 1-3 the same random position, then the vertices 4-6 the same random position and so on?

If that is true, how could I write that down in python?

$\endgroup$
4
$\begingroup$

I have modified the code as follows :

  • added a dictionary that stores the vertex position and the generated offset by random.uniform()
  • for each vertex check if there is already an offset for this position , if so we add this offset to the old position
  • if there is no offset calculated for this position we generate a new one and store it in the dictionary, we also add it to the old position

this method gives the vertices that has the same position the same offseet


from bge import logic
import random
from mathutils import Vector

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

for mesh in object.meshes:
   print(mesh)
   verts_shift = dict()
   for m_index in range(len(mesh.materials)):
      print(m_index)
      for v_index in range(mesh.getVertexArrayLength(m_index)):
         print(v_index)
         vertex = mesh.getVertex(m_index, v_index)
         xyz_old= vertex.getXYZ().freeze()
         xyz_shift = verts_shift.get(xyz_old, None) 
         if xyz_shift :
             vertex.setXYZ(xyz_old+xyz_shift)
         else :
             xyz_shift = Vector(( random.uniform(-0.5,0.5), random.uniform(-0.5,0.5), random.uniform(-0.5,0.5) ))
             verts_shift[xyz_old] = xyz_shift
             vertex.setXYZ(xyz_old+xyz_shift)           

         print(xyz_old, xyz_shift)

enter image description here

$\endgroup$
  • $\begingroup$ this is a very good solution, thank you! Only thing left is that the cube's size grows and grows... is there something one can do to prevent that from happening? Something like a limiter which says that it shouldnt get bigger than two times its size or something like that? $\endgroup$ – Sputi May 3 '15 at 14:30
  • $\begingroup$ @Sputi the cube is not supposed to grow ( the random var is negative/positive -0.5 to 0.5 ) so it grow and shrink randomly, also apply the scale because this is in the local coordinates, to prevent it from growing you can test xyz+offset > limit : generete new offset $\endgroup$ – Chebhou May 3 '15 at 14:34
  • $\begingroup$ Well this makes sense. Still, the object grows eventualy ( put sensor freuq. to 0 and it happens very fast. Even though the random var is negative/positive -0.5 to 0.5 and scale is applyied. Very strange... $\endgroup$ – Sputi May 3 '15 at 16:35
  • $\begingroup$ I will take a look later and update the answer $\endgroup$ – Chebhou May 3 '15 at 16:36
  • $\begingroup$ How does one know in which order the vertices are stored? For example if I only want to alter the top left corner of the cube (all three vertices at once)? Its not 0,1,2 but 23, 40, 48...? $\endgroup$ – Sputi Sep 23 '15 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.