Terrain generator - Initial groundwork

(BluePrintRandom) #1

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] } )
    # 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'])
            mesh = bge.logic.LibNew(meshName,"Mesh",[added.meshes[0].name])
        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)

        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)

        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    
                    dat = overlap[key]
        own['Overlap']= overlap    
        print('Created overlap list')
    #Apply Noise    
    elif 'Noise' not in own:
        print('Creating noise')
        for key in own['Overlap']:
            data = own['Overlap'][key]
            pos = eval(key)
            pos = Vector([pos[0],pos[1],0])
            Noise = mathutils.noise.fractal(pos, .25, .1 , 4, mathutils.noise.types.STDPERLIN)
            for vertexDat in data:
                host = vertexDat[1]
                vertex = vertexDat[0]
                pos1 = vertex.XYZ
                pos1.z = Noise
                vertex.XYZ = pos1       


I use a kdtree to calculate the overlapping vertex,


Kd_terrain_Gen.blend (535 KB)

(BluePrintRandom) #2

just noticed I forgot to erase many prints.

much faster now


Kd_terrain_Gen_2.blend (535 KB)

(BluePrintRandom) #3

Here is a ‘over time’ version that

  1. generates world
  2. builds trees and overlap dictionary
  3. applies noise over time, occasionally repairing border normals
  4. applies erosion
  5. fixes normals 1 last time


Kd_terrain_Gen_over_time.blend (606 KB)

(BluePrintRandom) #4

played with vertex color,

next up is editing the vertex in a radius of a agent,

and finally stream to / from disk once BP_Player - bidirectional communication protocol is in.


Kd_terrain_Gen_over_time_2.blend (769 KB)

(BluePrintRandom) #5

ok this is actually super useful now :smiley:



Kd_terrain_Gen_over_time_islands.blend (903 KB)

(Lostscience) #6

what about dynamic terrain loading?

(BluePrintRandom) #7

once BP_Player bi-directional streaming lands :smiley:

(Lostscience) #8

okay I will wait

(BluePrintRandom) #9

for now when the terrain loads in all the way, you should be able to batch it all to 1 render in upbge

this should allow a considerable terrain size.

found a second noise method.

D = vertex xy distance from center of under monkey.

subtracting D from vertex.z makes a slope away from the center(aka mountain)

applying a cos to this value as it slopes + the terrain perlin noise makes really nice islands.

(BluePrintRandom) #10

now terrain object push themselves in a unused state
obj.state = 2

also just before turning off logic meshes are batched.

also added mouse orbit

edit: forgot to mention it also sets up reinstancePhysicsMesh() unique for each tile


Kd_terrain_Gen_over_time_islands_2.blend (844 KB)

(Lostscience) #11

what is your framerate?i get a framerate of 8 on our hewletpackard desktop.

(BluePrintRandom) #12

60 - Nvidia 850_ish

however I need to do some testing, batching does not appear to be helping the framerate.

any errors or anything in the console?

(Lostscience) #13

let us know when you have done that.

(BluePrintRandom) #14

your video card may not support batching, or your system may just not be able to handle this many unique meshes in the memory.

it’s hit and miss with integrated gpu unless its nvidia (from my experience)
intel and amd may be catching up soon though from what I hear.

is your console printing any errors ?

grab suzzane ?

the property length determine how many meshes are used.

12x12 and bigger work without adjusting the equations

(Lostscience) #15

what do you mean by by grab suzzane or terrain monkey?

Read prefs: C:\Users\barbara\AppData\Roaming\Blender Foundation\Blender\2.78\config\userpref.blend
found bundled python: C:\Users\barbara\Desktop\Release\2.78\python
addon not found: 'import_runtime_mhx2'
Read blend: C:\Users\barbara\Desktop\Kd_terrain_Gen_over_time_islands_2.blend
Blender Game Engine Started
Created world
Building vertex set
intialize tree
created tree
Created overlap list
Blender Game Engine Finished