I remade my terrain editor from scratch, and commented it out a bit, here it is so far.
import bge
from mathutils import Vector
import mathutils
def main():
cont = bge.logic.getCurrentController()
own = cont.owner
# create empty entry for each grid pos
if 'TerrainDict' not in own:
TerrainDict = {}
for x in range(10):
for y in range(10):
pos = [x,y]
key = str(pos)
TerrainDict.update( { key:[pos] } )
own['TerrainDict']=TerrainDict
# create a tile for each entry and libnew the mesh
elif 'World' not in own:
world = []
for key in own['TerrainDict']:
added = own.scene.addObject('Tile',own,0)
Pos = own['TerrainDict'][key][0]
added.worldPosition =[ Pos[0]-5,Pos[1]-5,0]
meshName = "Tile_"+str(own['Tiles'])
own['Tiles']+=1
added['NewMeshName']=meshName
mesh = bge.logic.LibNew(meshName,"Mesh",[added.meshes[0].name])
print(mesh)
added.replaceMesh(mesh[0],1,0)
world.append([key,added])
own['World'] = world
print('Created world')
# build kd tree used to get all overlapping vertex
elif 'KdTree' not in own:
print('Building vertex set')
Master = []
for object in own['World']:
mesh = object[1].meshes[0]
for index in range(mesh.getVertexArrayLength(0)):
vertex = mesh.getVertex(0, index)
Master.append([vertex,object[1]])
print('intialize tree')
kd = mathutils.kdtree.KDTree(len(Master))
for index in range(len(Master)):
owner = Master[index][1]
vertexLocal = Master[index][0].XYZ
worldVector = owner.worldPosition+owner.worldOrientation*vertexLocal
kd.insert( worldVector , index)
kd.balance()
own['KdTree']=kd
own['Master']=Master
print('created tree')
#generate a list of vertex for each point in space
elif 'Overlap' not in own:
overlap = {}
#get overlapping vertex list
# Find points within a radius of the 3d cursor
for data in own['Master']:
pos = data[0].XYZ
owner = data[1]
pos = owner.worldTransform*Vector(pos)
#min must be smaller than dist between vertex
min = .005
for (co, index, dist) in own['KdTree'].find_range(pos, min):
key = str([pos[0],pos[1]])
owner = own['Master'][index][1]
vertex = own['Master'][index][0]
#if you don't have a entry make one
if key not in overlap:
overlap.update({ key:[[vertex,owner]] } )
#if you do have a entry just add to it
else:
dat = overlap[key]
dat.append([vertex,owner])
overlap[key]=dat
own['Overlap']= overlap
print('Created overlap list')
#Apply Noise
elif 'Noise' not in own:
own['Noise']=True
print('Creating noise')
for key in own['Overlap']:
data = own['Overlap'][key]
pos = eval(key)
pos = Vector([pos[0],pos[1],0])
print(pos)
Noise = mathutils.noise.fractal(pos, .25, .1 , 4, mathutils.noise.types.STDPERLIN)
for vertexDat in data:
print(vertexDat)
host = vertexDat[1]
vertex = vertexDat[0]
pos1 = vertex.XYZ
pos1.z = Noise
vertex.XYZ = pos1
main()
I use a kdtree to calculate the overlapping vertex,
Attachments
Kd_terrain_Gen.blend (535 KB)