Force Field Effect

All,

I am in the process of creating a force field effect and I have come across a problem that I’m not entirely sure how to approach.

I am displacing the location of each vert in the force field to make it look like its distorting. However, each selectable vert in blender is 4 vert locations in python.

So I need a fancy way of getting all verts that occupy the same location and then applying the same displacement.

Any ideas on how this could be implemented in an efficient manner would be greatly appreciated.


import bge, random, sys, GameLogic

sys.path.append(bge.logic.expandPath("//..//scripts"))
sys.path.append(bge.logic.expandPath("//.."))
sys.path.append(bge.logic.expandPath("//effects_script"))

import Game

class forceField():
    
    def __init__(self):
        self.x = 0
        self.co = GameLogic.getCurrentController()
        self.obj = self.co.owner
        self.mesh = self.obj.meshes[0]
        self.xpos = []
        self.ypos = []
        self.zpos = []
        for vert in range(self.mesh.getVertexArrayLength(0)):
            vert = self.mesh.getVertex(0, vert)
            self.xpos.append(vert.x)
            self.ypos.append(vert.y)
            self.zpos.append(vert.z)
    
    def applyDistortion(self):
        i = 0
        
        for vert in range(self.mesh.getVertexArrayLength(0)):
            # Need to change all verts by the same amount that occupy 
            distort = random.random()*bge.logic.getCurrentController().owner['distortion']
            vert = self.mesh.getVertex(0, vert)
            vert.setXYZ([self.xpos[i]+distort, self.ypos[i]+distort, self.zpos[i]])
            i += 1
            
    def main(self):
        if self.x < bge.logic.getCurrentController().owner['period']:
            self.x += 1
        else:
            self.x = 0
            self.applyDistortion()

def init(cont):
    cont.owner['time'] += Game.time
    Game.main()
    cont.owner['scene'] = forceField()
    cont.script = 'forceField.main'           

def main(cont):
    Game.main()
    cont.owner['scene'].main()

Below are my files. The first is the .blend and the second the python script (posted above)

https://www.box.com/s/bdubzj90fa0367m0f0b1
https://www.box.com/s/rkcutppl911dye1s9tp9

There is also a second issues I am having when trying to call python as a module. My file structure is follows:

Game
GameMainStub.blend
-> effects
ForceField.blend
-> scripts
Game.py
ForceField.py

GameMainStub.blend calls Game.py Module which then adds all the folders to the python path and then opens ForceField.blend

However, the only way i can get blender to be able to find the python module is to have the python file in the same folder. You can see my attempts at trying to add the correct folders to the python path.

If anyone know how to get blender to detect python modules in different folders it would be a great help.

Thanks

I work a lot with vertices, so the way I’ve done works of this kind is to create a dict with all the positions of the field, append all vertices belonging to that space to a list in the dict…
Then use the hit position as a dict key to access the vertices in the mesh. This is the fastest way I found, you wont have to loop through all vertices in the mesh. Also that make your script smaller. You can also avoid real collisions, by stopping the projectiles if their position is similar to one in the vertex dict.