def setupHeightfield( self ): # Prep terrain textures #coverTextureFile = "data/textures/ground/green.jpg" #self.mCoverTexture = loader.loadTexture(coverTextureFile) # Setup heightfield self.mHeightFieldTesselator = HeightfieldTesselator("Heightfield") #fName = "data/textures/ground/heightfield.png" #self.mHeightFieldTesselator.setPolyCount(10000) #fileObj = Filename(fName) self.mTerrainVScale = self.mTerrainUScale = 1.0/1024.0 myImage=PNMImage(256,256) myImage.makeGrayscale() p = Perlin(numberOfOctaves = 10, persistance = 0.65, smooth = False) for y in range(0,256): for x in range(0,256): i = p.noise2D(float(x)/256.0,float(y)/256.0) myImage.setGray(x, y, abs(i)) bigImage=PNMImage(1024, 1024) bigImage.gaussianFilterFrom(1.0, myImage) fileObj = Filename("data/textures/ground/myHeightfield.png") bigImage.write(fileObj) #myTexture = Texture() #myTexture.load(bigImage) self.mHeightFieldTesselator.setHeightfield(fileObj) self.mTerrainHeight = MAPSIZE/10 self.mHeightFieldTesselator.setVerticalScale(self.mTerrainHeight) self.mHorizontalScale = MAPSIZE/1024.0 self.mHeightFieldTesselator.setHorizontalScale(self.mHorizontalScale) self.mHeightFieldNode = None # self.tex0 = loader.loadTexture( 'models/textures/ground/schachbrett.png' ) self.tex0 = loader.loadTexture( 'data/textures/ground/mud-tile.png' ) #self.tex1 = loader.loadTexture( 'data/models/textures/ground/green.jpg' ) #self.tex2 = loader.loadTexture( 'data/models/textures/ground/grey-green-leaves.jpg' ) #self.ts0 = TextureStage( 'dirt' ) #self.ts1 = TextureStage( 'fungus' ) #self.ts2 = TextureStage( 'grass' ) self.updateHeightField()
def imgNoise2D(self, size = 512, autoOctave = False): myImage=PNMImage(1,1) myImage.makeGrayscale() myImage.setMaxval( (2<<16)-1 ) myImage.fill(0.5) octaves = self.numberOfOctaves if autoOctave == True: octaves = int(math.log(size,2)) self.pNoise = range(0,octaves) random.seed(self.seed) for i in range(1,octaves): self.pNoise[i] = PerlinNoise2( 1, 1, 256, random.randint(1,10000)) for o in range(1,octaves): freq = 2**o oldImage = myImage myImage = PNMImage(freq+1,freq+1) myImage.makeGrayscale() myImage.setMaxval( (2<<16)-1 ) myImage.gaussianFilterFrom(1.0, oldImage) for x in range(0,freq): for y in range(0,freq): newNoise = (self.pNoise[o].noise( x, y)*(self.persistance**o)) / 2 myImage.setGray(x,y, myImage.getGray(x,y) + newNoise)#*32) for i in range(0,freq+1): myImage.setGray(i,freq, myImage.getGray(i%freq,0)) myImage.setGray(freq,i, myImage.getGray(0,i%freq)) oldImage = myImage myImage = PNMImage(size,size) myImage.makeGrayscale() myImage.setMaxval( (2<<16)-1 ) myImage.gaussianFilterFrom(1.0, oldImage) return myImage
def flattenArea( self ): tilePos = (500,500) tileSize = (4000,4000) imgTilePos = self.world2MapPos(tilePos) imgTileSize = self.world2MapPos( (tilePos[0] + tileSize[0], tilePos[1] + tileSize[1]) ) imgTileSize = (imgTileSize[0] - imgTilePos[0], imgTileSize[1] - imgTilePos[1]) tileSquare = PNMImage(Filename("tile.png")) tileStamp = PNMImage(int(imgTileSize[0] * (5/3)),int(imgTileSize[1] * (5/3))) tileStamp.makeGrayscale() tileStamp.addAlpha() tileStamp.gaussianFilterFrom(1, tileSquare) count = 4 total = 0.0 selectXLow = int(imgTilePos[0] + imgTileSize[0] * 0.25) selectXHigh = int(imgTilePos[0] + imgTileSize[0] * 0.75) selectYLow = int(imgTilePos[1] + imgTileSize[1] * 0.25) selectYHigh = int(imgTilePos[1] + imgTileSize[1] * 0.75) total += self.myImage.getGray(selectXLow,selectYLow) total += self.myImage.getGray(selectXLow,selectYLow) total += self.myImage.getGray(selectXHigh,selectYHigh) total += self.myImage.getGray(selectXHigh,selectYHigh) average = total/count tileStamp.fill(average) edgeWidth = imgTilePos[0]*(1/3) self.myImage.blendSubImage(tileStamp, int( imgTilePos[0]-edgeWidth), int( imgTilePos[1]-edgeWidth), 0, 0, int(imgTileSize[0]*( 5/3 ) ), int(imgTileSize[1]*( 5/3 ) ), 1)
class PerlinTest(DirectObject): def __init__(self): self.size = 64 self.p = Perlin.Perlin(numberOfOctaves=10, persistance=0.75, smooth=False) self.myImage = PNMImage(self.size, self.size) self.myImage.makeGrayscale() self.myTexture = Texture() self.myImage.fill(0.5) self.myTexture.load(self.myImage) self.imageObject = OnscreenImage(image=self.myTexture, pos=(0, 0, 0)) self.myList = [None] * (self.size) for a in range(self.size): self.myList[a] = [0.5] * (self.size) taskMgr.add(self.noiseTaskVerySmart, "perlinNoiseTask") self.startTime = time() self.noiseTaskVerySmart() self.accept("arrow_up", self.run) self.i = [None] * (self.size + 1) for x in range(0, self.size + 1): self.i[x] = [None] * (self.size + 1) def run(self): for a in range(self.size): self.myList[a] = [0.5] * (self.size) self.startTime = time() taskMgr.add(self.noiseTaskVerySmart, "perlinNoiseTask") def noiseTask(self, Task=None): numLines = 8 if Task == None: y = 0 else: y = Task.frame * numLines for yNum in range(0, numLines): for x in range(0, self.size): i = self.p.noise2D(float(x) / self.size, float(y + yNum) / self.size) self.myImage.setGray(x, y + yNum, (i + 1.0) / 2) self.myTexture.load(self.myImage) if Task != None: if self.size >= y + numLines: return Task.cont else: self.myTexture.load(self.myImage) print time() - self.startTime return Task.done def noiseTaskSmart(self, Task=None): if Task == None: o = 0 else: o = Task.frame p = Perlin.Perlin(numberOfOctaves=1, smooth=False, seed=0) freq = 2 ** o for x in range(0, freq + 1): for y in range(0, freq + 1): self.i[x][y] = p.intNoise2D(x * freq, y * freq) for y in range(0, self.size): for x in range(0, self.size): intX = (x * freq) / self.size fraX = (float(x) * freq) / self.size - intX intY = (y * freq) / self.size i1 = p.linearInterpolate(self.i[intX][intY], self.i[intX + 1][intY], fraX) i2 = p.linearInterpolate(self.i[intX][intY + 1], self.i[intX + 1][intY + 1], fraX) interNoise = p.linearInterpolate(i1, i2, (float(y) * freq) / self.size - intY) self.myList[x][y] += interNoise * (0.75 ** o) / 2 self.myImage.setGray(x, y, self.myList[x][y]) self.myTexture.load(self.myImage) if Task != None: if freq < self.size: return Task.cont else: print time() - self.startTime return Task.done def noiseTaskVerySmart(self, Task=None): if Task == None: o = 0 else: o = Task.frame p = Perlin.Perlin(numberOfOctaves=1, smooth=False, seed=0) freq = 2 ** o self.oldImage = self.myImage self.myImage = PNMImage(freq + 1, freq + 1) self.myImage.makeGrayscale() self.myImage.gaussianFilterFrom(1.0, self.oldImage) for x in range(0, freq + 1): for y in range(0, freq + 1): self.myImage.setGray( x, y, self.myImage.getGray(x, y) + p.intNoise2D(x * freq, y * freq) * (0.75 ** o) / 2 ) self.myTexture.load(self.myImage) if Task != None: if freq < self.size: return Task.cont else: print time() - self.startTime return Task.done