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)
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 *
# AN EXTREMELY SIMPLE TERAIN GENERATOR USING THE NOISE MODULE
# PARAMETERS TO CHANGE:
# QUADS: 1=YES OR 0=NO
# tsize: SQUAREROOT OF NUMBER OF VERTICES USED
# 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)
me.verts.append(v)
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
if QUADS:
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
me.faces.append(fc)
if (y & 31)==0: pbar(prg_cnt, 'FACES')
prg_cnt += prg_tl
else:
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
me.faces.append(fc)
# 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
me.faces.append(fc)
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
print
sys.stdout.flush()
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.
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.
Guys,
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.
Well,
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])