1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
Planet Topography Code: sc2code/planets/gentopo.c
----------------------------------------------------
This text covers only topography generation code. It does NOT cover the
craters (blemishes) nor the smoothing. Variables names are the same in
"sc2code/planets/gentopo.c".
A brief overview:
The algorithm works by applying several elevation/lowering steps on the
same terrain. Each step works by randomly generating two non-intersecting
lines, LineDDA0 and LineDDA1. That delimits two regions. Each region is
then displaced by a certain height delta (depth_delta). That step is
repeated several times.
There's a pseudocode below, with detailed information about it in the next
section.
The DeltaTopography() function works as follows:
Function parameters:
COUNT num_iterations // Number of height displacements on the
// planet's surface
PSBYTE DepthArray // Target surface, receives topography data
PRECT pRect // Surface dimensions
SIZE depth_delta // The amount of height units to raise/lower
// on each displacement
for i from 1 to num_iterations
randomly either negates depth_delta's or not, influencing
the displacement direction
randomly pick two line segments, LineDDA0 and LineDDA1
increase the height of the region between LineDDA0 and
LineDDA1 by depth_delta
decrease the height of the region between LineDDA1 and
LineDDA0 by depth_delta (by wrapping around the surface)
end for
Detailed information about the algorithm's steps:
First, in half the steps (randomly) depth_delta is negated.
That influences on the direction of the displacements.
Note that in each step exactly two height displacements occur:
a lifting and a lowering.
Next, it sets both w1 and w2 to different random WORD values. Those are
used in the line segment generation process.
LineDDA0 starts on a random position on the top of the surface, and ends
at another random position on the bottom of the surface.
LineDDA0 never wraps around the surface, since their X coordinates are
generated in the range 0..width-1:
LineDDA0.x_top = LOBYTE (w1) % width;
LineDDA0.x_bot = HIBYTE (w1) % width;
LineDDA1 is generated much like the way LineDDA0 is, the difference being
LineDDA1's x coordinates are displaced by LineDDA0 ones:
LineDDA1.x_top = (LOBYTE (w2) % (width - 1)) + LineDDA0.x_top + 1;
LineDDA1.x_bot = (HIBYTE (w2) % (width - 1)) + LineDDA0.x_bot + 1;
Y coordinates are 0 for top, and 'height' for bottom in both line
segments.
This delimits basically two regions. One delimited by LineDDA0 on the left
side, and LineDDA1 on the right right, which we call "0->1". The other is
delimited by LineDDA1 on the left, and LineDDA0 on the right, which we call
"1->0".
Note that, since we're talking about a planet, the rightmost side of the
surface if "connected" to the leftmost side. At least one of those regions
"wrap around" the surface.
The final step in the iteration is to increase the height of the region
0->1 by depth_delta, and decreasing 1->0 by the same value. Note that since
delta_depth may be negative, raising part of the surface by delta_depth
may result in the surface being lowered.
This step is repeated num_iteration times.
About the terrain generation algorithm: This method of displacing
line-delimited subsets of a surface is commonly known as Fault Formation.
The DDA acronym stands for "Digital Differential Analyzer". Hence the names
LineDDA0 and LineDDA1.
The first version of this document was written by:
Daniel Ribeiro Maciel <daniel.maciel@gmail.com>
on 2006-11-24
|