Advertisement
Baldeagle22

ohmy

Sep 26th, 2018
376
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.88 KB | None | 0 0
  1. --[[
  2. Diamond-Square Terrain Generator
  3.  
  4. This terrain generator uses a 3d midpoint displacement algorithm to produce realistic-looking terrain using wedges.
  5.  
  6. The function Build takes 7 arguments, which are provided at the top of the script as variables for ease of editing:
  7.  
  8.  
  9. Scale (Number): This is the size of the piece of terrain that will be generated. Terrain is always generated in squares. The value provided,
  10. 100, will produce a 100x100 area of terrain.
  11.  
  12. Pos (Vector3): This is the position that the terrain is roughly centered at. The terrain won't always be exactly vertically centered over this position,
  13. however, depending on the values that you provide for the table "Table", which will be described below.
  14.  
  15. Iterations (Number): The midpoint displacement algorithm essentially works by dividing a large square into four smaller squares, down the middle.
  16. For each iteration, the new squares will themselves be divided. Basically, this value determines how complex the terrain will be.
  17. A value of 1, for example, will produce terrain with four "tiles", composed of four wedges each. Increasing this number by one will quadruple the number of squares (doubled on both axes).
  18.  
  19. Error (Number): This is the degree of "randomness" that the terrain will have. If you set it to 0, for example, the terrain will be completely smooth.
  20.  
  21. Wait (Number): The terrain generator will wait at times by this amount while generating terrain, unless this number is 0. The smallest amont you can wait is generally around
  22. 0.03s. For small pieces of terrain with a low number of iterations, you may be able to safely set Wait to 0. However, with larger pieces of terrain, your game may crash. Generally,
  23. the minimum amount of waiting time (any number above 0) is enough to prevent this.
  24.  
  25. Table (Table): This argument may be the hardest to understand, especially if you don't already know how the midpoint-displacement algorithm works. For starters, you should
  26. look up "diamond square algorithm" on wikipedia. Essentially, this table allows you to the verticle value of nodes within the algorithm. It is a 2-dimensional table (a set of tables within a table)
  27. where indices of the main table are vertical coordinates, and indices of the sub-tables are horizontal coordinates. Values of the sub-tables are the vertical height of the node represented by the
  28. coordinates. Coordinates must be multiples of 1/(2^iterations).
  29.  
  30. Colors (Table): This is a set of tables within a table that tells the script how to color the terrain, based on height.
  31. Each table inside Table provides a single "layer". The first number in each table is the upper boundary of that layer.
  32. terrain whose position along the y-axis in between this value and the first number of the table before it will be given a
  33. specific color: the second value in each table. A coloring table is provided as an example.
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40. ]]
  41.  
  42.  
  43.  
  44. local Scale = 1000
  45. local Pos = Vector3.new(0,0,0)
  46. local Iterations = 4
  47. local Error = 40
  48. local Wait = 0.01
  49. local Table = {
  50. [0]={[0] =math.random(-Error,Error), [1] = math.random(-Error,Error)},
  51. [.5]={[.5] = 50},
  52. [1]={[0] = math.random(-Error,Error), [1] = math.random(-Error,Error)}
  53. }
  54.  
  55. local Colors = {
  56. {0,BrickColor.new("Toothpaste")},
  57. {6,BrickColor.new("Bright red")},
  58. {10,BrickColor.new("Bright Yellow")},
  59. {14,BrickColor.new("Bright red")},
  60. {30,BrickColor.new("Black")},
  61. {math.huge, BrickColor.new("Bright red")}
  62. }
  63.  
  64.  
  65. function Triangle(A,B,C,Color)
  66. local M = Instance.new("Model")
  67. M.archivable = false
  68. local Base1 = (C-A)*((B-A):Dot(C-A)/((C-A).magnitude)^2)
  69. local Base2 = ((C-A) - Base1)
  70. local Height = (B-A) - Base1
  71. local Pos1 = (A + (B-A)/2)
  72. local Pos2 = (C + (B-C)/2)
  73. local Normal1 = Base1:Cross(Height).unit
  74. local Normal2 = Base2:Cross(Height).unit
  75. local Cf1 = CFrame.new(0,0,0,Normal1.x,-Base1.unit.x,-Height.unit.x, Normal1.y,-Base1.unit.y,-Height.unit.y,Normal1.z, -Base1.unit.z,-Height.unit.z) + Pos1
  76. local Cf2 = CFrame.new(0,0,0,Normal2.x,-Base2.unit.x,-Height.unit.x, Normal2.y,-Base2.unit.y,-Height.unit.y,Normal2.z, -Base2.unit.z,-Height.unit.z) * CFrame.Angles(0,0,math.pi)+ Pos2
  77. local P1 = Instance.new("WedgePart")
  78. P1.FormFactor = 0
  79.  
  80. P1.Size = Vector3.new(1,math.floor(Base1.magnitude),math.floor(Height.magnitude))
  81. local M1 = Instance.new("SpecialMesh")
  82. M1.archivable = false
  83. M1.MeshType = "Wedge"
  84. M1.Scale = Vector3.new(1, Base1.magnitude, Height.magnitude)/P1.Size
  85. M1.Parent = P1
  86. P1.Anchored = true
  87. P1.CFrame = Cf1 + (Cf1 - Cf1.p) * Vector3.new(.5,0,0)
  88. P1.TopSurface = 0
  89. P1.BottomSurface = 0
  90.  
  91. for i = 1, #Color do
  92. if P1.Position.y >= (((i == 1) and -math.huge) or Color[i-1][1]) and P1.Position.y < Color[i][1] then
  93. P1.BrickColor = Color[i][2]
  94. break
  95. end
  96. end
  97.  
  98.  
  99.  
  100.  
  101. P1.Parent = M
  102. P1.archivable = false
  103. local P2 = Instance.new("WedgePart")
  104. P2.FormFactor = 0
  105. P2.Size = Vector3.new(1,math.floor(Base2.magnitude),math.floor(Height.magnitude))
  106.  
  107. local M2 = Instance.new("SpecialMesh")
  108. M2.archivable = false
  109. M2.MeshType = "Wedge"
  110. M2.Scale = Vector3.new(1, Base2.magnitude, Height.magnitude)/P2.Size
  111. M2.Parent = P2
  112.  
  113.  
  114. P2.Anchored = true
  115. P2.CFrame = Cf2 +(Cf2 - Cf2.p) * Vector3.new(-.5,0,0)
  116. P2.TopSurface = 0
  117. P2.BottomSurface = 0
  118. for i = 1, #Color do
  119. if P2.Position.y >= (((i == 1) and -math.huge) or Color[i-1][1]) and P2.Position.y < Color[i][1] then
  120. P2.BrickColor = Color[i][2]
  121. break
  122. end
  123. end
  124.  
  125. P2.Parent = M
  126. P2.archivable = false
  127. return M
  128. end
  129.  
  130. function Generate(MainTable, Reps, Error)
  131. function DiamondSquare(Vs, Ve, Hs, He, I, E)
  132. local Va = (Vs + Ve)/2
  133. local Ha = (Hs + He)/2
  134. if MainTable[Vs][Ha] == nil then
  135. MainTable[Vs][Ha] = (MainTable[Vs][Hs] + MainTable[Vs][He])/2
  136. end
  137. if MainTable[Va] == nil then
  138. MainTable[Va] = {}
  139. end
  140. if MainTable[Va][Hs] == nil then
  141. MainTable[Va][Hs] = (MainTable[Vs][Hs] + MainTable[Ve][Hs])/2 + (math.random() - .5) * E
  142. end
  143. if MainTable[Va][Ha] == nil then
  144. MainTable[Va][Ha] = (MainTable[Vs][Hs] + MainTable[Vs][He] + MainTable[Ve][Hs] + MainTable[Ve][He])/4+ (math.random() - .5) * E
  145. end
  146. if MainTable[Va][He] == nil then
  147. MainTable[Va][He] = (MainTable[Vs][He] + MainTable[Ve][He])/2+ (math.random() - .5) * E
  148. end
  149. if MainTable[Ve][Ha] == nil then
  150. MainTable[Ve][Ha] = (MainTable[Ve][Hs] + MainTable[Ve][He])/2+ (math.random() - .5) * E
  151. end
  152. E = E/2
  153. I = I - 1
  154. if I > 0 then
  155. DiamondSquare(Vs, (Vs + Ve)/2, Hs, (Hs + He)/2, I, E)
  156. DiamondSquare((Vs + Ve)/2, Ve, Hs, (Hs + He)/2, I, E)
  157. DiamondSquare(Vs, (Vs + Ve)/2, (Hs + He)/2, He, I, E)
  158. DiamondSquare((Vs + Ve)/2, Ve, (Hs + He)/2, He, I, E)
  159. end
  160. end
  161. DiamondSquare(0,1,0,1,Reps, Error)
  162. return MainTable, (2^Reps + 1)
  163. end
  164.  
  165. function Build(Scale, Pos, Iterations, Error, Wait, Table,Colors)
  166. local G, Length = Generate(Table,Iterations, Error)
  167. local M = Instance.new("Model")
  168. M.archivable = false
  169. M.Parent = workspace
  170. for a, b in pairs(G) do
  171. for c, d in pairs(b) do
  172. if Wait > 0 then
  173. wait(Wait)
  174. end
  175. local Pos1 = Pos + Vector3.new((a-.5) * Scale, d , (c-.5) * Scale)
  176. local Int = 1/(2^Iterations)
  177. local Other = G[(a - Int)]
  178. local Other2 = G[a][c + Int]
  179. if Other ~= nil and Other2 ~= nil then
  180. local Other3 = Other[c]
  181. local Pos2 = Pos + Vector3.new((a - .5) * Scale, Other2, (c + Int - .5) * Scale)
  182. local Pos3 = Pos + Vector3.new((a - Int - .5) * Scale, Other3, (c - .5) * Scale)
  183. local T1 = Triangle(Pos2,Pos1, Pos3,Colors)
  184. T1.Parent = M
  185. end
  186. local Other4 = G[a + Int]
  187. local Other5 = G[a][c - Int]
  188. if Other4 ~= nil and Other5 ~= nil then
  189. local Other6 = Other4[c]
  190. local Pos5 = Pos + Vector3.new((a - .5) * Scale, Other5, (c - Int - .5) * Scale)
  191. local Pos6 = Pos + Vector3.new((a +Int - .5) * Scale, Other6, (c - .5) * Scale)
  192. local T1 = Triangle(Pos5, Pos1, Pos6,Colors)
  193. T1.Parent = M
  194. end
  195. end
  196. end
  197. return G
  198. end
  199.  
  200.  
  201. Build(Scale, Pos, Iterations, Error, Wait, Table,Colors)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement