Understanding dynoise


How can one create mountains that look similar to the one on http://eeshlo.stormpages.com/gallery.html? If I use RidgedMF, the terrain always looks hilly, know matter how many hours I play around with the arguments. Maybe it is simply due to my incompetence or to linguistic problems, but probably to the fact that I am not very familiar with discete mathematics. Anyway I did not understand the hole function nor its arguements. Maybe someone could help me a little.
BTW I use this code to play arround:

from Blender import *
import dynoise

mesh = NMesh.GetRaw('Plane')
v = mesh.verts
length = len(v)

i = 0
while i < length:
	coor = v[i].co
	offset = dynoise.RidgedMF(coor, 10, 9, 4 , 0, 0)
	v[i].co[2] = v[i].co[2] + offset
	i = i+1

NMesh.PutRaw(mesh, 'Plane', 1)

Thank you,

Maybe this is of some use to you, this is the script that I used to create that landscape:

import Blender, sys
from Blender import NMesh
from dynoise import *


# quads look better with subsurf, but tri's are more accurate
QUADS = 0	# use quads or triangle's?
tsize = 250		#x*x vertices

name = 'LANDSCAPE'
me = NMesh.GetRaw()

center = tsize * 0.5
# progressbar total = verticesYlines + facesYlines
prg_tl = tsize + (tsize-1)
if prg_tl>0.0: prg_tl = 1.0/prg_tl

prg_cnt = 0.0
pbar = Blender.Window.draw_progressbar
# vertices
for y in range(tsize):
	yf = y - center
	yf2 = yf * 0.0025 + 123.456
	for x in range(tsize):
		xf = x - center
		xf2 = xf * 0.0025 - 13.397486
		zf = 150.0*RidgedMF((xf2, yf2, 7.531), 0.9, 2.1, 16, 0.875, 2.0)
		#zf = 150.0*fBm((xf2, yf2, 7.531), 0.9, 2.1, 16)
		#zf = 150.0*FTurbulence((xf2, yf2, 7.531), 16, 0)
		#if zf<0.0: zf=0.0	#uncomment this to get a flat 'sealevel'
		v = NMesh.Vert(xf, yf, zf)
	if (y & 31)==0: pbar(prg_cnt, 'VERTICES')
	prg_cnt += prg_tl
#faces, two triangles or quad:
#xy  x1y
# +---+
# |t1/|
# | / |
# |/t2|
# +---+
# xy1  x1y1
vts = me.verts
	for y in range(tsize-1):
		for x in range(tsize-1):
			fc = NMesh.Face()
			fc.v.append(vts[tsize*y + x])
			fc.v.append(vts[tsize*y + (x+1)])
			fc.v.append(vts[tsize*(y+1) + (x+1)])
			fc.v.append(vts[tsize*(y+1) + x])
			fc.smooth = 1
		if (y & 31)==0: pbar(prg_cnt, 'FACES')
		prg_cnt += prg_tl
	for y in range(tsize-1):
		for x in range(tsize-1):
			# t1
			fc = NMesh.Face()
			fc.v.append(vts[tsize*y + x])
			fc.v.append(vts[tsize*y + (x+1)])
			fc.v.append(vts[tsize*(y+1) + x])
			fc.smooth = 1
			# t2
			fc = NMesh.Face()
			fc.v.append(vts[tsize*y + (x+1)])
			fc.v.append(vts[tsize*(y+1) + (x+1)])
			fc.v.append(vts[tsize*(y+1) + x])
			fc.smooth = 1
		if (y & 31)==0: pbar(prg_cnt, 'FACES')
		prg_cnt += prg_tl

pbar(1.0, '')

NMesh.PutRaw(me, name)
# rename the object to the mesh name
ob = Blender.Object.GetSelected()[0]
ob.name = name


Of course, you won’t get the exact same landscape, as the noise module uses the computer date and time to initialize the random number generator. Try to change the settings in small ranges, not more than +/-1.
The landscape can be quite offset from the origin.
The moonscapes demo included with the original zipfile might also be helpful.
Just using a uniformly divided grid like here is probably not a very optimal solution, an algorithm that would only create faces/vertices where it is needed might make a better looking landscape.

ok eeshlo,
here’s a dynoise quesyion from me:

is it feasable to use a frameChanged script to slightly randomise the vetices in a mesh on every frame?

for example: get mesh, slightly shift each vert on XYZ, replace mesh, render, advance to next frame, get mesh, etc…

i haven’t really investigated this, so it may be extremely simple.
thanks for any help you can give.


Of course that is possible, RipSting did exactly that with his wave script. The original dynoise module actually had a function to do exactly that, so it was al reduced to a single function call on framechanged, but I only did that to learn more about extension programming, it didn’t seem useful to me at the time so I removed it again.

i’ve been on vacation and thus couldn’t check the forum.
Thank you for this script. I thought mine was much too simple …
It works very well.

Guys, :expressionless:
I don’t know if this is the right place for such a question, but I’m really confused about just how RipSting’s script or yours (Eeshlo) can work with FrameChange. I’m new to Python but I think I can figure it out with the right hints from you.

I can get the script to run in P225 and trigger it using FrameChange, but it just keeps creating new meshes. That’s problem #1. Problem #2 is that the script isn’t called when you render the animation, only when you navigate through the frames.

What about those meshes that never work to generate grass or terrain, isn’t that weird, does anyone have a clue as to what is causing this ?
It seems to be related to the number of points per face, but I’m not sure.


I figured out why my imported meshes didn’t generate any faces. RipSting, I’m not sure why you didn’t use the transformed points v1,v2,v3 for the area calculations. In some cases the area is so small it doesn’t add up to enough to seed any grass.
I changed my routine fncArea to use the transformed points and it works fine for imported meshes now.

def fncArea(f,mat):
if len(f.v) > 2:
#Finds the area of a face
v1 = multmat(mat,f.v[0])
v2 = multmat(mat,f.v[1])
v3 = multmat(mat,f.v[2])

	adist =	pow(pow(v1.co[0] - v2.co[0],2)+	pow(v1.co[1] - v2.co[1],2)+ pow(v1.co[2] - v2.co[2],2),.5)
	bdist =	pow(pow(v2.co[0] - v3.co[0],2)+ pow(v2.co[1] - v3.co[1],2)+ pow(v2.co[2] - v3.co[2],2),.5)
	cdist =	pow(pow(v3.co[0] - v1.co[0],2)+ pow(v3.co[1] - v1.co[1],2)+ pow(v3.co[2] - v1.co[2],2),.5)	

	semi = (adist+bdist+cdist)/2
	area = pow(semi*(semi-adist)*(semi-bdist)*(semi-cdist),.5)

	if len(f.v) == 4: #Add area of adjacent triangle
		v4 = multmat(mat,f.v[3])
		adist =	pow(pow(v1.co[0] - v3.co[0],2)+ pow(v1.co[1] - v3.co[1],2)+ pow(v1.co[2] - v3.co[2],2),.5)
		bdist =	pow(pow(v3.co[0] - v4.co[0],2)+ pow(v3.co[1] - v4.co[1],2)+ pow(v3.co[2] - v4.co[2],2),.5)	
		cdist =	pow(pow(v4.co[0] - v1.co[0],2)+ pow(v4.co[1] - v1.co[1],2)+ pow(v4.co[2] - v1.co[2],2),.5)	

		semi = (adist+bdist+cdist)/2
		area += pow(semi*(semi-adist)*(semi-bdist)*(semi-cdist),.5)
	return area
	return 0


This would be so great if it worked in the Game engine…