[B3D] Improved Perlin Noise

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

 

Krischan

Betreff: [B3D] Improved Perlin Noise

BeitragFr, Mai 14, 2010 15:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Hier ein Beispiel, wie man aus dem Nichts Landschaften in - naja sagen wir fast - Echtzeit generieren kann, der Ursprungscode ist von "MusicianKool" aus dem BB-Forum, er hat das sogar in eine DLL gepackt, was das Ganze noch mal ca. 45% schneller macht. Shocked

Download seiner DLL: http://www.mediafire.com/?zjw0mzr4ji1

Mein Beispiel erweitert das Ganze um Meshterrain Patches:

user posted image

Beispiel 1: ohne DLL
Code: [AUSKLAPPEN]
Graphics3D 800,600,32,2

Const patches=16
Const scale#=2
Const detail#=128.0
Const octaves%=5
Const patchsize%=32
Const maxcols%=2^16
Const multi#=2.0


Dim p(512)
Dim grayd#(512)
;ms = MilliSecs()
Restore permutation
For i=0 To 256-1
   Read perm
   p(i) = ( perm )
   p(256+i)= ( perm )
   grayd#(i) = Rnd(-0.7,0.7)
   grayd#(256+i) = Rnd(-0.7,0.7)
Next

Global GameSpeed%=60
Global Screenwidth%=GraphicsWidth()
Global Screenheight%=GraphicsHeight()
Global FramePeriod%=1000/GameSpeed
Global FrameTime%=MilliSecs()-FramePeriod
Global DeltaTimeOld%



Global min%,max%

Global PlanetR%[maxcols],PlanetG%[maxcols],PlanetB%[maxcols]
Dim Red%(0),Green%(0),Blue%(0),Percent#(0)
Restore Temperate
CreateGradient(11,maxcols,True,PlanetR,PlanetG,PlanetB)

Dim patch(patches,patches)

xoff=Rand(0,128)
yoff=Rand(0,128)


For x=0 To patches-1
   
   For z=0 To patches-1
      
      patch(x,z)=CreatePatch(patchsize,patchsize,x,z,xoff,yoff,scale,multi)
      EntityFX patch(x,z),2
      
      pt=pt+1
      
      AppTitle "Generating Landscape: "+Int(pt*100.0/(patches^2))+"%"
      
      If KeyHit(1) Then End
      
   Next
   
Next

For x=0 To patches-2
   
   For z=0 To patches-1
      
      AlignMeshVertices(patch(x,z),patch(x+1,z),patchsize,3,1)
      
   Next
   
Next

For x=0 To patches-1
   
   For z=0 To patches-2
      
      AlignMeshVertices(patch(x,z),patch(x,z+1),patchsize,0,2)
      
   Next
   
Next


cam=CreateCamera()
CameraRange cam,0.001*scale,64*scale
PositionEntity cam,scale*patches/2.0,scale/2.0,-scale
CameraClsColor cam,150,200,255
CameraFogColor cam,150,200,255
CameraFogMode cam,1
CameraFogRange cam,1*scale,32*scale

sunpivot=CreatePivot()

sun=CreateSphere(8,sunpivot)
EntityFX sun,1+8
ScaleEntity sun,scale,scale,scale
EntityColor sun,255,255,0
PositionEntity sun,20*scale,20*scale,20*scale

light=CreateLight(2,sun)
PositionEntity light,0,0,0
LightRange light,30*scale
AmbientLight 32,32,32

water=CreateSprite()
SpriteViewMode water,2
PositionEntity water,scale*patches/2.0,0,scale*patches/2.0
RotateEntity water,90,0,0
ScaleSprite water,scale*patches/2.0,scale*patches/2.0
EntityFX water,1+16
EntityColor water,17,82,112
EntityBlend water,3

MoveMouse Screenwidth/2,Screenheight/2

While Not KeyHit(1)
   
   ; Frametween calculation
   Local FrameElapsed%,FrameTicks%,FrameTween#,t%
   Repeat FrameElapsed=MilliSecs()-FrameTime Until FrameElapsed
   FrameTicks=FrameElapsed/FramePeriod
   FrameTween=Float(FrameElapsed Mod FramePeriod)/Float(FramePeriod)
   
   ; Frametween loop
   For t=1 To FrameTicks
      
      ; Frametween Captureworld
      FrameTime=FrameTime+FramePeriod : If t=FrameTicks Then CaptureWorld
      
      If KeyHit(57) Then wf=1-wf : WireFrame wf
      
      FreeCam(cam,85,0.02*scale)
      
      ;TurnEntity sunpivot,0,1,0
      
   Next
   
   RenderWorld
   
   Flip 0
   
Wend

End

; creates a nice color gradient
Function CreateGradient(colors%,steps%,inverse=False,R%[maxcols],G%[maxcols],B%[maxcols])
   
   Dim Percent#(colors),Red%(colors),Green%(colors),Blue%(colors)
   
   Local i%,pos1%,pos2%,pdiff%
   Local rdiff%,gdiff%,bdiff%
   Local rstep#,gstep#,bstep#
   Local counter%=0
   
   If inverse Then
      For i=colors To 1 Step -1
         Read Percent(i),Red(i),Green(i),Blue(i)
         Percent(i)=100.0-Percent(i)
      Next
   Else
      For i=0 To colors-1 : Read Percent(i),Red(i),Green(i),Blue(i) : Next
   EndIf
   
    While counter<colors
      
        pos1=Percent(counter)*steps*1.0/100
      pos2=Percent(counter+1)*steps*1.0/100
      
        pdiff=pos2-pos1
      
        rdiff%=Red(counter)-Red(counter+1)
      gdiff%=Green(counter)-Green(counter+1)
      bdiff%=Blue(counter)-Blue(counter+1)
      
        rstep#=rdiff*1.0/pdiff
      gstep#=gdiff*1.0/pdiff
      bstep#=bdiff*1.0/pdiff
      
      For i=0 To pdiff
         
         R[pos1+i]=Int(Red(counter)-(rstep*i))
         G[pos1+i]=Int(Green(counter)-(gstep*i))
         B[pos1+i]=Int(Blue(counter)-(bstep*i))
         
      Next
      
        counter=counter+1
      
   Wend
   
End Function

Function Normalize#(value#=128.0,value_min#=0.0,value_max#=255.0,norm_min#=0.0,norm_max#=1.0)
   
   Return ((value#-value_min#)/(value_max#-value_min#))*(norm_max#-norm_min#)+norm_min#
   
End Function

Function FreeCam(camera%,maxpitch#=85.0,movespeed#,rotspeed#=16.666,rotfloat#=8.0)
   
   Local movex#,movez#,dx#,dy#,dk#,dt%,t%
   Local pitch#
   
   ; Arrows = Move
   movex=KeyDown(205)-KeyDown(203)
   movez=KeyDown(200)-KeyDown(208)
   
   ; smooth movement
   t=MilliSecs() : dt=t-DeltaTimeOld : DeltaTimeOld=t : dk=Float(dt)/rotspeed
   dx=(Screenwidth/2-MouseX())*0.01*dk : dy=(Screenheight/2-MouseY())*0.01*dk
   TurnEntity camera,-dy,dx*0.1*dk*rotfloat,0
   
   ; limit pitch
   pitch=EntityPitch(camera,1) : If pitch>maxpitch Then pitch=maxpitch Else If pitch<-maxpitch Then pitch=-maxpitch
   
   ; rotate and move
   RotateEntity camera,pitch,EntityYaw(camera,1),0,1   
   MoveEntity camera,movex*movespeed,0,movez*movespeed
   
End Function

Function CreatePatch(size%=32,seed%=1,xstart#=0.0,zstart#=0.0,xoff#=0.0,zoff#=0.0,scale#=1.0,yscale#=1.0)
   
   Local x%,z%,h#,c%
   Local vx#,vz#,u#,v#,vertex%
   Local v0%,v1%,v2%,v3%
   
   Local mesh%=CreateMesh()
   Local surf%=CreateSurface(mesh)
   
   For z=0 To size
      
      For x=0 To size
         
         ; calculate vertex coordinates / texture coordinates
         vx=1.0/size*x
         vz=1.0/size*z
         u=x*1.0/size
         v=z*1.0/size
         
         h=noise((x+((xstart+xoff)*size))*scale,(z+((zstart+zoff)*size))*scale,0,detail,seed,0,octaves)
         
         If h<-1 Then h=-1 Else If h>1 Then h=1
         
         ;If h>-0.05 And h<0.05 Then h=0.01
         
         If Not min Then min=0
         If Not max Then max=maxcols
         
         c=Floor(Normalize(h,-1,1,min,max))
         
         If c<min Then min=c
         If c>max Then max=c
         
         s#=Sqr(size)/(size/4.0)
         
         ; place vertex
         vertex=AddVertex(surf,vx*scale,Normalize(h,-1,1,-s,s)*yscale,vz*scale,u,v)
         
         ; set vertex color and texture coordinates
         VertexColor surf,vertex,PlanetR[Int(c)],PlanetG[Int(c)],PlanetB[Int(c)],1
         
         ; set triangles
         If z<size And x<size Then
            
            v0=x+((size+1)*z)
            v1=x+((size+1)*z)+(size+1)
            v2=(x+1)+((size+1)*z)
            v3=(x+1)+((size+1)*z)+(size+1)
            
            AddTriangle(surf,v0,v1,v2)
            AddTriangle(surf,v2,v1,v3)
            
         EndIf
         
      Next
      
   Next
   
   ;Goto skip
   
   For t=0 To CountTriangles(surf)-1
      
      v0=TriangleVertex(surf,t,0)
      v1=TriangleVertex(surf,t,1)
      v2=TriangleVertex(surf,t,2)
      
      vx0#=VertexX(surf,v0)
      vy0#=VertexY(surf,v0)
      vz0#=VertexZ(surf,v0)
      
      vx1#=VertexX(surf,v1)
      vy1#=VertexY(surf,v1)
      vz1#=VertexZ(surf,v1)
      
      vx2#=VertexX(surf,v2)
      vy2#=VertexY(surf,v2)
      vz2#=VertexZ(surf,v2)
      
      px#=vx1-vx0
      py#=vy1-vy0
      pz#=vz1-vz0
      
      qx#=vx2-vx0
      qy#=vy2-vy0
      qz#=vz2-vz0
      
      nx#=(py*qz)-(pz*qy)
      ny#=(pz*qx)-(px*qz)
      nz#=(px*qy)-(py*qx)
      
      VertexNormal surf,v0,nx,ny,nz
      VertexNormal surf,v1,nx,ny,nz
      VertexNormal surf,v2,nx,ny,nz
      
   Next
   
   .skip
   
   ;UpdateNormals mesh
   
   PositionEntity mesh,xstart*scale,0,zstart*scale
   
   Return mesh
   
End Function

Function SmoothNoise#( x#, y#, z#,Seed = 0)
   x = x + Seed: y = y + Seed: z = z + Seed
   Local x1#,y1#,z1#,u#,v#,w#,a#,aa#,ab#,b#,ba#,bb#
   Local g1#,g2#,g3#,g4#,g5#,g6#,g7#,g8#
   Local l1#,l2#,l3#,l4#,l5#,l6#,l7#
   x1 = ( Floor(x) And 255 );,                  // FIND UNIT CUBE THAT
   y1 = ( Floor(y) And 255 );,                  // CONTAINS POINT.
   z1 = ( Floor(z) And 255 );,
   x = x - Floor( x );                                // FIND RELATIVE X,Y,Z
   y = y - Floor( y );                                // OF POINT IN CUBE.
   z = z - Floor( z );
   u# = fade#(x);,                                // COMPUTE FADE CURVES
   v# = fade#(y);,                                // FOR EACH OF x,y,z.
   w# = fade#(z);
   a# = p(x1)+y1
   aa# = p(a)+z1
   ab# = p(a+1)+z1;,      // HASH COORDINATES OF
   b# = p(x1+1)+y1
   ba# = p(b)+z1
   bb# = p(b+1)+z1;      // THE 8 CUBE CORNERS,
   
   g1# = grayd#(bb+1)
   g2# = grayd#(ab+1)
   g3# = grayd#(ba+1)
   g4# = grayd#(aa+1)
   g5# = grayd#(bb)
   g6# = grayd#(ab)
   g7# = grayd#(ba)
   g8# = grayd#(aa)
   l1# = lerp#(u, g2#, g1#)
   l2# = lerp#(u, g4#, g3#)
   l3# = lerp#(v, l2#, l1#)
   l4# = lerp#(u, g6#, g5#)
   l5# = lerp#(u, g8#, g7#)
   l6# = lerp#(v, l5#, l4#)
   l7# = lerp#(w, l6#, l3#)
   Return l7#
End Function
Function fade#( t# ) : s# = t * t * t * (t * (t * 6 - 15) + 10):Return s#:End Function
Function lerp#( t#, a#, b#): z# = a + t * (b - a): Return z#:End Function

Function noise#(x#,y#,z#,size#=64,seed% = 0, MinOctaves = 0 , MaxOctaves = 9999)
   If seed = 0 Then seed = MilliSecs()
   x# = x# + seed
   y# = y# + seed
   z# = z# + seed
      ;//Set the initial value and initial size
   value# = 0.0: initialSize# = size#;
   
   For i = 1 To MinOctaves
      size = size/2
   Next
      ;//Add finer and finer hues of smoothed noise together
   While(size >= 1.0) And MaxOctaves > MinOctaves
      
      value# = value# + SmoothNoise#(x / size, y / size, z / size, seed) * size
      size = size / 2.0;
      MaxOctaves = MaxOctaves - 1
   Wend
   
      ;//Return the result over the initial size
   Return  (value# / Float initialSize);
   
End Function




Function AlignMeshVertices(mesh1%,mesh2%,size%,side1%=0,side2%=0,colors=True,normals=True,flipped=False,colored=False)
   
   Local surf1%=GetSurface(mesh1,1)
   Local surf2%=GetSurface(mesh2,1)
   
   Local i%,s%,t%,mag#
   Local r%,g%,b%,a#,nx#,ny#,nz#
   
   For i=0 To size
      
      ; 0 = upper side
      ; 1 = left side
      ; 2 = lower side
      ; 3 = right side
      
      If side1=0 Then s=(size^2)+size+i
      If side1=1 Then s=(size*i)+i
      If side1=2 Then s=i
      If side1=3 Then s=(size*i)+size+i
      
      If side2=0 Then t=(size^2)+size+i
      If side2=0 And flipped Then t=(size^2)+(2*size)-i
      
      If side2=1 Then t=(size*i)+i
      If side2=1 And flipped Then t=(size^2)+size-(size*i)-i
      
      If side2=2 Then t=i
      If side2=2 And flipped Then t=size-i
      
      If side2=3 Then t=(size*i)+size+i
      If side2=3 And flipped Then t=(size^2)+(2*size)-(size*i)-i
      
      ; align colors
      If colors Then
         
         r=(VertexRed(surf1,s)+VertexRed(surf2,t))/2
         g=(VertexGreen(surf1,s)+VertexGreen(surf2,t))/2
         b=(VertexBlue(surf1,s)+VertexBlue(surf2,t))/2
         a=(VertexAlpha(surf1,s)+VertexAlpha(surf2,t))/2.0
         
         VertexColor surf1,s,r,g,b,a
         VertexColor surf2,t,r,g,b,a
         
      EndIf
      
      ; draw sides
      If colored Then
         r=255:g=0:b=0:a=1.0
         VertexColor surf1,s,r,g,b,a
         VertexColor surf2,t,r,g,b,a
      EndIf
      
      ; align normals
      If normals Then
         
         nx=VertexNX(surf1,s)+VertexNX(surf2,t)
         ny=VertexNY(surf1,s)+VertexNY(surf2,t)
         nz=VertexNZ(surf1,s)+VertexNZ(surf2,t)
         
         mag=Sqr(nx*nx+ny*ny+nz*nz)
         
         nx=nx/mag
         ny=ny/mag
         nz=nz/mag
         
         VertexNormal surf1,s,nx,ny,nz
         VertexNormal surf2,t,nx,ny,nz
         
      EndIf
      
   Next
   
End Function

.Temperate
Data   0.0,255,255,255   ; icy mountains
Data   5.0,179,179,179   ; transition
Data  10.0,153,143, 92   ; tundra
Data  25.0,115,128, 77   ; high grasslands
Data  40.0, 42,102, 41   ; low grasslands
Data  45.0, 42,102, 41   ; low grasslands
Data  50.0,200,200,118   ; coast / should be a 0 height
Data  55.0, 17, 82,112   ; shallow ocean
Data  70.0, 17, 82,112   ; shallow ocean
Data  75.0,  9, 62, 92   ; ocean
Data 100.0,  9, 62, 92   ; deep ocean

.permutation
Data 151,160,137,91,90,15
Data 131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23
Data 190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33
Data 88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166
Data 77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244
Data 102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196
Data 135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123
Data 5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42
Data 223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9
Data 129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228
Data 251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107
Data 49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254
Data 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180


Beispiel 2: mit DLL (erst die decls und DLL einbinden!)

Code: [AUSKLAPPEN]
Graphics3D 800,600,32,2

InitPerlinNoise()

Const patches=16
Const scale#=2
Const detail#=128.0
Const octaves%=5
Const patchsize%=32
Const maxcols%=2^16
Const multi#=2.0

Global GameSpeed%=60
Global Screenwidth%=GraphicsWidth()
Global Screenheight%=GraphicsHeight()
Global FramePeriod%=1000/GameSpeed
Global FrameTime%=MilliSecs()-FramePeriod
Global DeltaTimeOld%

Global min%,max%

Global PlanetR%[maxcols],PlanetG%[maxcols],PlanetB%[maxcols]
Dim Red%(0),Green%(0),Blue%(0),Percent#(0)
Restore Temperate
CreateGradient(11,maxcols,True,PlanetR,PlanetG,PlanetB)

Dim patch(patches,patches)

xoff=Rand(0,128)
yoff=Rand(0,128)


ms=MilliSecs()

For x=0 To patches-1
   
   For z=0 To patches-1
      
      patch(x,z)=CreatePatch(patchsize,patchsize,x,z,xoff,yoff,scale,multi)
      EntityFX patch(x,z),2
      
      pt=pt+1
      
      AppTitle "Generating Landscape: "+Int(pt*100.0/(patches^2))+"% | "+(MilliSecs()-ms)+"ms"
      
      If KeyHit(1) Then End
      
   Next
   
Next

For x=0 To patches-2
   
   For z=0 To patches-1
      
      AlignMeshVertices(patch(x,z),patch(x+1,z),patchsize,3,1)
      
   Next
   
Next

For x=0 To patches-1
   
   For z=0 To patches-2
      
      AlignMeshVertices(patch(x,z),patch(x,z+1),patchsize,0,2)
      
   Next
   
Next


cam=CreateCamera()
CameraRange cam,0.001*scale,64*scale
PositionEntity cam,scale*patches/2.0,scale/2.0,-scale
CameraClsColor cam,150,200,255
CameraFogColor cam,150,200,255
CameraFogMode cam,1
CameraFogRange cam,1*scale,32*scale

sunpivot=CreatePivot()

sun=CreateSphere(8,sunpivot)
EntityFX sun,1+8
ScaleEntity sun,scale,scale,scale
EntityColor sun,255,255,0
PositionEntity sun,20*scale,20*scale,20*scale

light=CreateLight(2,sun)
PositionEntity light,0,0,0
LightRange light,30*scale
AmbientLight 32,32,32

water=CreateSprite()
SpriteViewMode water,2
PositionEntity water,scale*patches/2.0,0,scale*patches/2.0
RotateEntity water,90,0,0
ScaleSprite water,scale*patches/2.0,scale*patches/2.0
EntityFX water,1+16
EntityColor water,17,82,112
EntityBlend water,3

MoveMouse Screenwidth/2,Screenheight/2

While Not KeyHit(1)
   
   ; Frametween calculation
   Local FrameElapsed%,FrameTicks%,FrameTween#,t%
   Repeat FrameElapsed=MilliSecs()-FrameTime Until FrameElapsed
   FrameTicks=FrameElapsed/FramePeriod
   FrameTween=Float(FrameElapsed Mod FramePeriod)/Float(FramePeriod)
   
   ; Frametween loop
   For t=1 To FrameTicks
      
      ; Frametween Captureworld
      FrameTime=FrameTime+FramePeriod : If t=FrameTicks Then CaptureWorld
      
      If KeyHit(57) Then wf=1-wf : WireFrame wf
      
      FreeCam(cam,85,0.02*scale)
      
      ;TurnEntity sunpivot,0,1,0
      
   Next
   
   RenderWorld
   
   Flip 0
   
Wend

End

; creates a nice color gradient
Function CreateGradient(colors%,steps%,inverse=False,R%[maxcols],G%[maxcols],B%[maxcols])
   
   Dim Percent#(colors),Red%(colors),Green%(colors),Blue%(colors)
   
   Local i%,pos1%,pos2%,pdiff%
   Local rdiff%,gdiff%,bdiff%
   Local rstep#,gstep#,bstep#
   Local counter%=0
   
   If inverse Then
      For i=colors To 1 Step -1
         Read Percent(i),Red(i),Green(i),Blue(i)
         Percent(i)=100.0-Percent(i)
      Next
   Else
      For i=0 To colors-1 : Read Percent(i),Red(i),Green(i),Blue(i) : Next
   EndIf
   
    While counter<colors
      
        pos1=Percent(counter)*steps*1.0/100
      pos2=Percent(counter+1)*steps*1.0/100
      
        pdiff=pos2-pos1
      
        rdiff%=Red(counter)-Red(counter+1)
      gdiff%=Green(counter)-Green(counter+1)
      bdiff%=Blue(counter)-Blue(counter+1)
      
        rstep#=rdiff*1.0/pdiff
      gstep#=gdiff*1.0/pdiff
      bstep#=bdiff*1.0/pdiff
      
      For i=0 To pdiff
         
         R[pos1+i]=Int(Red(counter)-(rstep*i))
         G[pos1+i]=Int(Green(counter)-(gstep*i))
         B[pos1+i]=Int(Blue(counter)-(bstep*i))
         
      Next
      
        counter=counter+1
      
   Wend
   
End Function

Function Normalize#(value#=128.0,value_min#=0.0,value_max#=255.0,norm_min#=0.0,norm_max#=1.0)
   
   Return ((value#-value_min#)/(value_max#-value_min#))*(norm_max#-norm_min#)+norm_min#
   
End Function

Function FreeCam(camera%,maxpitch#=85.0,movespeed#,rotspeed#=16.666,rotfloat#=8.0)
   
   Local movex#,movez#,dx#,dy#,dk#,dt%,t%
   Local pitch#
   
   ; Arrows = Move
   movex=KeyDown(205)-KeyDown(203)
   movez=KeyDown(200)-KeyDown(208)
   
   ; smooth movement
   t=MilliSecs() : dt=t-DeltaTimeOld : DeltaTimeOld=t : dk=Float(dt)/rotspeed
   dx=(Screenwidth/2-MouseX())*0.01*dk : dy=(Screenheight/2-MouseY())*0.01*dk
   TurnEntity camera,-dy,dx*0.1*dk*rotfloat,0
   
   ; limit pitch
   pitch=EntityPitch(camera,1) : If pitch>maxpitch Then pitch=maxpitch Else If pitch<-maxpitch Then pitch=-maxpitch
   
   ; rotate and move
   RotateEntity camera,pitch,EntityYaw(camera,1),0,1   
   MoveEntity camera,movex*movespeed,0,movez*movespeed
   
End Function

Function CreatePatch(size%=32,seed%=1,xstart#=0.0,zstart#=0.0,xoff#=0.0,zoff#=0.0,scale#=1.0,yscale#=1.0)
   
   Local x%,z%,h#,c%
   Local vx#,vz#,u#,v#,vertex%
   Local v0%,v1%,v2%,v3%
   
   Local mesh%=CreateMesh()
   Local surf%=CreateSurface(mesh)
   
   For z=0 To size
      
      For x=0 To size
         
         ; calculate vertex coordinates / texture coordinates
         vx=1.0/size*x
         vz=1.0/size*z
         u=x*1.0/size
         v=z*1.0/size
         
         ;h=0;noise((x+((xstart+xoff)*size))*scale,(z+((zstart+zoff)*size))*scale,0,detail,seed,0,octaves)
         
         h=Perlin3D((x+((xstart+xoff)*size))*scale,(z+((zstart+zoff)*size))*scale,99,detail,seed,0,octaves)
         
         If h<-1 Then h=-1 Else If h>1 Then h=1
         
         ;If h>-0.05 And h<0.05 Then h=0.01
         
         If Not min Then min=0
         If Not max Then max=maxcols
         
         c=Floor(Normalize(h,-1,1,min,max))
         
         If c<min Then min=c
         If c>max Then max=c
         
         s#=Sqr(size)/(size/4.0)
         
         ; place vertex
         vertex=AddVertex(surf,vx*scale,Normalize(h,-1,1,-s,s)*yscale,vz*scale,u,v)
         
         ; set vertex color and texture coordinates
         VertexColor surf,vertex,PlanetR[Int(c)],PlanetG[Int(c)],PlanetB[Int(c)],1
         
         ; set triangles
         If z<size And x<size Then
            
            v0=x+((size+1)*z)
            v1=x+((size+1)*z)+(size+1)
            v2=(x+1)+((size+1)*z)
            v3=(x+1)+((size+1)*z)+(size+1)
            
            AddTriangle(surf,v0,v1,v2)
            AddTriangle(surf,v2,v1,v3)
            
         EndIf
         
      Next
      
   Next
   
   ;Goto skip
   
   For t=0 To CountTriangles(surf)-1
      
      v0=TriangleVertex(surf,t,0)
      v1=TriangleVertex(surf,t,1)
      v2=TriangleVertex(surf,t,2)
      
      vx0#=VertexX(surf,v0)
      vy0#=VertexY(surf,v0)
      vz0#=VertexZ(surf,v0)
      
      vx1#=VertexX(surf,v1)
      vy1#=VertexY(surf,v1)
      vz1#=VertexZ(surf,v1)
      
      vx2#=VertexX(surf,v2)
      vy2#=VertexY(surf,v2)
      vz2#=VertexZ(surf,v2)
      
      px#=vx1-vx0
      py#=vy1-vy0
      pz#=vz1-vz0
      
      qx#=vx2-vx0
      qy#=vy2-vy0
      qz#=vz2-vz0
      
      nx#=(py*qz)-(pz*qy)
      ny#=(pz*qx)-(px*qz)
      nz#=(px*qy)-(py*qx)
      
      VertexNormal surf,v0,nx,ny,nz
      VertexNormal surf,v1,nx,ny,nz
      VertexNormal surf,v2,nx,ny,nz
      
   Next
   
   .skip
   
   ;UpdateNormals mesh
   
   PositionEntity mesh,xstart*scale,0,zstart*scale
   
   Return mesh
   
End Function


Function AlignMeshVertices(mesh1%,mesh2%,size%,side1%=0,side2%=0,colors=True,normals=True,flipped=False,colored=False)
   
   Local surf1%=GetSurface(mesh1,1)
   Local surf2%=GetSurface(mesh2,1)
   
   Local i%,s%,t%,mag#
   Local r%,g%,b%,a#,nx#,ny#,nz#
   
   For i=0 To size
      
      ; 0 = upper side
      ; 1 = left side
      ; 2 = lower side
      ; 3 = right side
      
      If side1=0 Then s=(size^2)+size+i
      If side1=1 Then s=(size*i)+i
      If side1=2 Then s=i
      If side1=3 Then s=(size*i)+size+i
      
      If side2=0 Then t=(size^2)+size+i
      If side2=0 And flipped Then t=(size^2)+(2*size)-i
      
      If side2=1 Then t=(size*i)+i
      If side2=1 And flipped Then t=(size^2)+size-(size*i)-i
      
      If side2=2 Then t=i
      If side2=2 And flipped Then t=size-i
      
      If side2=3 Then t=(size*i)+size+i
      If side2=3 And flipped Then t=(size^2)+(2*size)-(size*i)-i
      
      ; align colors
      If colors Then
         
         r=(VertexRed(surf1,s)+VertexRed(surf2,t))/2
         g=(VertexGreen(surf1,s)+VertexGreen(surf2,t))/2
         b=(VertexBlue(surf1,s)+VertexBlue(surf2,t))/2
         a=(VertexAlpha(surf1,s)+VertexAlpha(surf2,t))/2.0
         
         VertexColor surf1,s,r,g,b,a
         VertexColor surf2,t,r,g,b,a
         
      EndIf
      
      ; draw sides
      If colored Then
         r=255:g=0:b=0:a=1.0
         VertexColor surf1,s,r,g,b,a
         VertexColor surf2,t,r,g,b,a
      EndIf
      
      ; align normals
      If normals Then
         
         nx=VertexNX(surf1,s)+VertexNX(surf2,t)
         ny=VertexNY(surf1,s)+VertexNY(surf2,t)
         nz=VertexNZ(surf1,s)+VertexNZ(surf2,t)
         
         mag=Sqr(nx*nx+ny*ny+nz*nz)
         
         nx=nx/mag
         ny=ny/mag
         nz=nz/mag
         
         VertexNormal surf1,s,nx,ny,nz
         VertexNormal surf2,t,nx,ny,nz
         
      EndIf
      
   Next
   
End Function

.Temperate
Data   0.0,255,255,255   ; icy mountains
Data   5.0,179,179,179   ; transition
Data  10.0,153,143, 92   ; tundra
Data  25.0,115,128, 77   ; high grasslands
Data  40.0, 42,102, 41   ; low grasslands
Data  45.0, 42,102, 41   ; low grasslands
Data  50.0,200,200,118   ; coast / should be a 0 height
Data  55.0, 17, 82,112   ; shallow ocean
Data  70.0, 17, 82,112   ; shallow ocean
Data  75.0,  9, 62, 92   ; ocean
Data 100.0,  9, 62, 92   ; deep ocean

Nibor

BeitragDi, Mai 18, 2010 21:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Beeindruckend.
Das ganze ist wirklich schnell (und ich hab nichteinmal das mit der DLL probiert).
http://www.blitzforum.de/showcase/203/

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group