Codesnippets > 3D-snippets

3D Darstellung eines Höhen-Felds (Height Map)

(1/6) > >>

Kitty Hello:
Wenn man ein Feld mit Höhenkoten in 3D hat (z.B. height[x][y]), dann kann man mit dem Code anbei das Ganze weich darstellen. Die Übergänge werden dabei interpoliert:

--- Code: (glbasic) ---DIM world[15][10]

// Dummy Data
FOR x=0 TO 14
FOR y=0 TO 9
world[x][y]=RND(15)/10
NEXT
NEXT

// Create World Object
X_OBJSTART 0
X_AUTONORMALS 2
FOR x=0 TO 14
FOR y=0 TO 9
MakeTile(world[], x,y, -15/2, -10/2, 1.0)
NEXT
NEXT
X_OBJEND

// some dummy texture:
FILLRECT 0,0,128,128, RGB(0,0,255)
FILLRECT 4,4,124,124, RGB(255,255,255)
FILLRECT 5,62,123,66, RGB(0,255,0)
FILLRECT 62,5,66,123, RGB(0,255,0)
FILLRECT 62,62,66,66, RGB(255,0,0)
PRINT "GLBasic", 8,8
GRABSPRITE 0, 0,0,128,128
BLACKSCREEN

WHILE TRUE
X_MAKE3D 1,100, 45
X_CAMERA 1,12,10, 0,0,0
X_SETTEXTURE 0,-1
X_ROTATION GETTIMERALL()/100, 0,1,0
X_DRAWOBJ 0,0
SHOWSCREEN
WEND

FUNCTION MakeTile: heights[], x,y, offsetx, offsety, width_per_tile
// Triangle Strip is:
// 0--2--4-.
// | /| /| .
// |/ |/ |/
// 1--3--5-.

// We need:
// 0-1-2
// |\|/|
// 3-4-5
// |/|\|
// 6-7-8
LOCAL pts[]
LOCAL i, px, py, mx, my
DIM pts[9][3] // 9 points[x,y,z]
pts[0][0]=-1; pts[0][1]=-1
pts[1][0]=.0; pts[1][1]=-1
pts[2][0]= 1; pts[2][1]=-1
pts[3][0]=-1; pts[3][1]=.0
pts[4][0]=.0; pts[4][1]=.0
pts[5][0]= 1; pts[5][1]=.0
pts[6][0]=-1; pts[6][1]= 1
pts[7][0]=.0; pts[7][1]= 1
pts[8][0]= 1; pts[8][1]= 1

// now calculate Z for each point
mx = BOUNDS(heights[], 0)-1
my = BOUNDS(heights[], 1)-1

FOR i=0 TO 8
// Get neighbour point
// but stop at array border
px = MIN(mx, MAX(0, x+pts[i][0]))
py = MIN(my, MAX(0, y+pts[i][1]))
pts[i][2] = ( heights[px][py]+ _
heights[ x][ y]+ _
heights[px][ y]+ _
heights[ x][py])/4
NEXT

// Next a function to create 2 triangles:
INC x, offsetx
INC y, offsety

ENDFUNCTION

// here we build a triangle stripped quad
// for the points a,b,c,d
// we divide coordinates by 2, so we get a
// rectangle of size 1x1 (-0.5 -> 0.5)
// for the texture we divide by 2 and add 0.5
// (0.0 -> 1.0)
// [edit:] finally scale that by the width_per_tile factor
// last: we swap y and z, since y is vertical in GLBasic
LOCAL cl
cl =RGB(255,255,255)
X_OBJNEWGROUP
ENDFUNCTION
--- End code ---
Und so sieht's aus:

Die roten Punkte sind, wo die HeightMap ihre Werte hat. Blau sind die einzelnen Felder und grün, wo ich Knicke gemahct habe, damit es weich interpoliert wird.

Mal ganz eine dumme Frage, aber gibt es da irgendwie die Möglichkeit über das ganze Ding eine einzige Textur drüber zu machen?

Oder muß man quasi wirklich alle Felder einzeln behandeln?

x-tra:
Ich mach das ganze ganz easy mit T.ED, is echt kinderleicht, importiere es dann und kann nachbearbeiten wie ich mag, aber eben nicht als
Terrain(mit Heighmap), sondern als Mesh ala .x .b3d. Wobei ich mit dem export erst klarkommen musste.

Nicht ganz einfach es nach .3ds zu bekommen, aber jetzt wo ichs weiß.

Kann ich nur empfehlen.

Ich hab mir T.Ed inzwischen mal angesehen, aber so ganz klar kommen tue ich damit noch nicht...  =(

x-tra:
doch ist total einfach gibt sogar ein deutsches handbuch auf deren seite.
das aber getrost als tutorial sehen kann.

da ist nicht viel falsch zu machen, ich finds für Außenlandschaften perfekt.
Wenns wo hängt, einfach sagen.

Wenns mal der export nach .3ds sein soll, oder so, helf ich dir.Denn das hab ich im moment nur über Gile(s) hinbekommen, weil dies das .b3d mit supertexture richtig liest.

Aber probier bisschen rum, ist echt klasse.
Mach ja sonst alles mit ac3d oder cinema4d, und sonstigen tools zum texturieren, aber für Terrains 1A.

Wenn sich jemand hinsetzen könnte, wäre sicherlich drin, alles zu exportieren, und einen loader dafür zu schreiben, aber dazu fehlts mir momentan noch an kenntnissen, aber wer weiß.......irgendwann vielleicht, wenn mir jemand erstmal grundlegend erklärt, wie sowas geht?