summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt10
-rw-r--r--assets/images/atlas.pngbin3705 -> 4653 bytes
-rw-r--r--assets/images/atlas.ppm6190
-rw-r--r--src/Math/Matrix.hpp21
-rw-r--r--src/Math/Random.cpp31
-rw-r--r--src/Math/Random.hpp31
-rw-r--r--src/Math/Vector.hpp79
-rw-r--r--src/World/BlockType.hpp2
-rw-r--r--src/World/Chunk.cpp155
-rw-r--r--src/World/Chunk.hpp15
-rw-r--r--src/World/Generation/ChunkMeshing.cpp (renamed from src/World/ChunkMeshing.cpp)19
-rw-r--r--src/World/Generation/ChunkMeshing.hpp (renamed from src/World/ChunkMeshing.hpp)6
-rw-r--r--src/World/Generation/Decoration.cpp97
-rw-r--r--src/World/Generation/Decoration.hpp34
-rw-r--r--src/World/Generation/Generator.cpp (renamed from src/World/Generator.cpp)92
-rw-r--r--src/World/Generation/Generator.hpp (renamed from src/World/Generator.hpp)29
-rw-r--r--src/World/World.cpp4
-rw-r--r--src/World/World.hpp4
18 files changed, 3477 insertions, 3342 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 61b6c34..7f8bfff 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,7 +33,7 @@ add_executable(meowcraft
     src/GFX/Image/PPMParser.cpp src/GFX/Image/PPMParser.hpp
     src/World/Chunk.cpp src/World/Chunk.hpp
     src/World/BlockType.hpp
-    src/World/Generator.cpp src/World/Generator.hpp
+    src/World/Generation/Generator.cpp src/World/Generation/Generator.hpp
     src/World/BlockSide.hpp
     src/World/World.cpp src/World/World.hpp
     src/World/ChunkIndex.hpp
@@ -45,10 +45,14 @@ add_executable(meowcraft
     src/Compute/Queue.hpp
     src/Math/Constants.hpp
     src/Math/Sigmoid.hpp
-    src/World/ChunkMeshing.cpp
-    src/World/ChunkMeshing.hpp
+    src/World/Generation/ChunkMeshing.cpp
+    src/World/Generation/ChunkMeshing.hpp
     src/Math/Tensor.hpp
     src/Math/MatrixZoom.hpp
+    src/World/Generation/Decoration.cpp
+    src/World/Generation/Decoration.hpp
+    src/Math/Random.cpp
+    src/Math/Random.hpp
 )
 target_link_libraries(meowcraft glfw GLEW::GLEW)
 
diff --git a/assets/images/atlas.png b/assets/images/atlas.png
index b8b9dd7..72ff329 100644
--- a/assets/images/atlas.png
+++ b/assets/images/atlas.png
Binary files differdiff --git a/assets/images/atlas.ppm b/assets/images/atlas.ppm
index df8dce7..bf31022 100644
--- a/assets/images/atlas.ppm
+++ b/assets/images/atlas.ppm
@@ -3074,54 +3074,6 @@ P3
 145
 140
 133
-251
-199
-142
-255
-208
-144
-255
-208
-144
-255
-208
-144
-248
-199
-136
-255
-216
-148
-248
-199
-136
-251
-199
-142
-251
-199
-142
-251
-199
-142
-251
-199
-142
-255
-224
-152
-255
-224
-152
-251
-199
-142
-251
-199
-142
-251
-199
-142
 93
 191
 225
@@ -3170,6 +3122,54 @@ P3
 93
 191
 225
+251
+199
+142
+255
+208
+144
+255
+208
+144
+255
+208
+144
+248
+199
+136
+255
+216
+148
+248
+199
+136
+251
+199
+142
+251
+199
+142
+251
+199
+142
+251
+199
+142
+255
+224
+152
+255
+224
+152
+251
+199
+142
+251
+199
+142
+251
+199
+142
 249
 250
 252
@@ -3266,54 +3266,6 @@ P3
 249
 250
 252
-255
-208
-144
-255
-208
-144
-255
-208
-144
-255
-216
-148
-255
-208
-144
-248
-199
-136
-248
-199
-136
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
-251
-199
-142
-251
-199
-142
-251
-199
-142
 120
 232
 236
@@ -3362,6 +3314,54 @@ P3
 120
 232
 236
+255
+208
+144
+255
+208
+144
+255
+208
+144
+255
+216
+148
+255
+208
+144
+248
+199
+136
+248
+199
+136
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
+251
+199
+142
+251
+199
+142
+251
+199
+142
 236
 241
 247
@@ -3458,54 +3458,6 @@ P3
 249
 250
 252
-255
-208
-144
-255
-208
-144
-255
-208
-144
-255
-208
-144
-251
-199
-142
-251
-199
-142
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
-251
-199
-142
-251
-199
-142
-251
-199
-142
-255
-208
-144
 120
 232
 236
@@ -3554,6 +3506,54 @@ P3
 120
 232
 236
+255
+208
+144
+255
+208
+144
+255
+208
+144
+255
+208
+144
+251
+199
+142
+251
+199
+142
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
+251
+199
+142
+251
+199
+142
+251
+199
+142
+255
+208
+144
 249
 250
 252
@@ -3650,54 +3650,6 @@ P3
 225
 230
 236
-251
-199
-142
-255
-208
-144
-251
-199
-142
-255
-208
-144
-251
-199
-142
-251
-199
-142
-255
-224
-152
-255
-224
-152
-251
-199
-142
-255
-216
-148
-255
-216
-148
-255
-216
-148
-251
-199
-142
-251
-199
-142
-251
-199
-142
-255
-230
-157
 120
 232
 236
@@ -3746,6 +3698,54 @@ P3
 95
 199
 228
+251
+199
+142
+255
+208
+144
+251
+199
+142
+255
+208
+144
+251
+199
+142
+251
+199
+142
+255
+224
+152
+255
+224
+152
+251
+199
+142
+255
+216
+148
+255
+216
+148
+255
+216
+148
+251
+199
+142
+251
+199
+142
+251
+199
+142
+255
+230
+157
 249
 250
 252
@@ -3842,54 +3842,6 @@ P3
 236
 241
 247
-251
-199
-142
-255
-208
-144
-255
-208
-144
-255
-208
-144
-242
-185
-131
-242
-185
-131
-255
-224
-152
-255
-224
-152
-251
-199
-142
-251
-199
-142
-251
-199
-142
-251
-199
-142
-251
-199
-142
-251
-199
-142
-251
-199
-142
-251
-199
-142
 95
 199
 228
@@ -3938,6 +3890,54 @@ P3
 93
 191
 225
+251
+199
+142
+255
+208
+144
+255
+208
+144
+255
+208
+144
+242
+185
+131
+242
+185
+131
+255
+224
+152
+255
+224
+152
+251
+199
+142
+251
+199
+142
+251
+199
+142
+251
+199
+142
+251
+199
+142
+251
+199
+142
+251
+199
+142
+251
+199
+142
 249
 250
 252
@@ -4034,54 +4034,6 @@ P3
 236
 241
 247
-251
-199
-142
-251
-199
-142
-251
-199
-142
-255
-216
-148
-248
-199
-136
-242
-185
-131
-255
-224
-152
-255
-224
-152
-255
-216
-148
-255
-216
-148
-255
-216
-148
-255
-208
-144
-251
-199
-142
-251
-199
-142
-251
-199
-142
-255
-230
-157
 93
 191
 225
@@ -4130,6 +4082,54 @@ P3
 93
 191
 225
+251
+199
+142
+251
+199
+142
+251
+199
+142
+255
+216
+148
+248
+199
+136
+242
+185
+131
+255
+224
+152
+255
+224
+152
+255
+216
+148
+255
+216
+148
+255
+216
+148
+255
+208
+144
+251
+199
+142
+251
+199
+142
+251
+199
+142
+255
+230
+157
 249
 250
 252
@@ -4226,54 +4226,6 @@ P3
 249
 250
 252
-251
-199
-142
-251
-199
-142
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-216
-148
-255
-216
-148
-255
-208
-144
-255
-208
-144
-251
-199
-142
-255
-221
-148
-251
-199
-142
-251
-199
-142
 90
 184
 223
@@ -4322,6 +4274,54 @@ P3
 84
 166
 219
+251
+199
+142
+251
+199
+142
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+216
+148
+255
+216
+148
+255
+208
+144
+255
+208
+144
+251
+199
+142
+255
+221
+148
+251
+199
+142
+251
+199
+142
 249
 250
 252
@@ -4418,54 +4418,6 @@ P3
 249
 250
 252
-251
-199
-142
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
-251
-199
-142
-251
-199
-142
-251
-199
-142
-251
-199
-142
-242
-185
-131
-242
-185
-131
-242
-185
-131
-251
-199
-142
-251
-199
-142
 85
 170
 221
@@ -4514,6 +4466,54 @@ P3
 80
 154
 217
+251
+199
+142
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
+251
+199
+142
+251
+199
+142
+251
+199
+142
+251
+199
+142
+242
+185
+131
+242
+185
+131
+242
+185
+131
+251
+199
+142
+251
+199
+142
 249
 250
 252
@@ -4610,54 +4610,6 @@ P3
 236
 241
 247
-251
-199
-142
-255
-224
-152
-255
-224
-152
-251
-199
-142
-251
-199
-142
-251
-199
-142
-251
-199
-142
-255
-216
-148
-255
-216
-148
-255
-208
-144
-251
-199
-142
-242
-185
-131
-251
-199
-142
-242
-185
-131
-251
-199
-142
-251
-199
-142
 90
 184
 225
@@ -4706,6 +4658,54 @@ P3
 88
 177
 223
+251
+199
+142
+255
+224
+152
+255
+224
+152
+251
+199
+142
+251
+199
+142
+251
+199
+142
+251
+199
+142
+255
+216
+148
+255
+216
+148
+255
+208
+144
+251
+199
+142
+242
+185
+131
+251
+199
+142
+242
+185
+131
+251
+199
+142
+251
+199
+142
 236
 241
 247
@@ -4802,54 +4802,6 @@ P3
 55
 25
 13
-242
-185
-131
-255
-224
-152
-255
-224
-152
-251
-199
-142
-251
-199
-142
-251
-199
-142
-251
-199
-142
-255
-216
-148
-255
-221
-148
-255
-208
-144
-251
-199
-142
-242
-185
-131
-242
-185
-131
-242
-185
-131
-255
-216
-148
-242
-185
-131
 90
 184
 225
@@ -4898,6 +4850,54 @@ P3
 90
 184
 225
+242
+185
+131
+255
+224
+152
+255
+224
+152
+251
+199
+142
+251
+199
+142
+251
+199
+142
+251
+199
+142
+255
+216
+148
+255
+221
+148
+255
+208
+144
+251
+199
+142
+242
+185
+131
+242
+185
+131
+242
+185
+131
+255
+216
+148
+242
+185
+131
 225
 230
 236
@@ -4955,12 +4955,12 @@ P3
 117
 71
 50
-105
-60
-40
-93
-54
+66
 35
+19
+66
+35
+19
 93
 54
 35
@@ -4994,54 +4994,6 @@ P3
 66
 35
 19
-242
-185
-131
-255
-224
-152
-255
-224
-152
-251
-199
-142
-251
-199
-142
-251
-199
-142
-251
-199
-142
-255
-208
-144
-255
-208
-144
-255
-208
-144
-255
-208
-144
-255
-208
-144
-251
-199
-142
-255
-216
-148
-255
-216
-148
-242
-185
-131
 112
 213
 232
@@ -5090,6 +5042,54 @@ P3
 112
 213
 232
+242
+185
+131
+255
+224
+152
+255
+224
+152
+251
+199
+142
+251
+199
+142
+251
+199
+142
+251
+199
+142
+255
+208
+144
+255
+208
+144
+255
+208
+144
+255
+208
+144
+255
+208
+144
+251
+199
+142
+255
+216
+148
+255
+216
+148
+242
+185
+131
 249
 250
 252
@@ -5141,18 +5141,18 @@ P3
 71
 38
 21
-100
-56
-37
-105
-60
-40
-95
-56
-37
-107
-62
-42
+66
+35
+19
+66
+35
+19
+66
+35
+19
+66
+35
+19
 105
 60
 40
@@ -5186,54 +5186,6 @@ P3
 66
 35
 19
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-216
-148
-255
-216
-148
-251
-199
-142
-255
-208
-144
-251
-199
-142
-255
-208
-144
-255
-208
-144
-251
-199
-142
-251
-199
-142
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
 105
 200
 229
@@ -5282,6 +5234,54 @@ P3
 120
 232
 236
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+216
+148
+255
+216
+148
+251
+199
+142
+255
+208
+144
+251
+199
+142
+255
+208
+144
+255
+208
+144
+251
+199
+142
+251
+199
+142
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
 236
 241
 247
@@ -5330,15 +5330,15 @@ P3
 249
 250
 252
-71
-38
-21
 66
 35
 19
-80
-46
-27
+66
+35
+19
+66
+35
+19
 114
 69
 48
@@ -5378,54 +5378,6 @@ P3
 93
 54
 35
-255
-224
-152
-255
-224
-152
-255
-216
-148
-255
-216
-148
-255
-216
-148
-255
-221
-148
-251
-199
-142
-255
-208
-144
-255
-216
-148
-255
-216
-148
-251
-199
-142
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
-255
-224
-152
 105
 200
 229
@@ -5474,6 +5426,54 @@ P3
 93
 191
 225
+255
+224
+152
+255
+224
+152
+255
+216
+148
+255
+216
+148
+255
+216
+148
+255
+221
+148
+251
+199
+142
+255
+208
+144
+255
+216
+148
+255
+216
+148
+251
+199
+142
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
+255
+224
+152
 249
 250
 252
@@ -5570,54 +5570,6 @@ P3
 93
 54
 35
-251
-199
-142
-251
-199
-142
-255
-216
-148
-255
-216
-148
-255
-221
-148
-255
-208
-144
-251
-199
-142
-251
-199
-142
-251
-199
-142
-255
-216
-148
-255
-216
-148
-255
-224
-152
-255
-224
-152
-242
-185
-131
-242
-185
-131
-251
-199
-142
 105
 200
 229
@@ -5666,6 +5618,54 @@ P3
 112
 217
 232
+251
+199
+142
+251
+199
+142
+255
+216
+148
+255
+216
+148
+255
+221
+148
+255
+208
+144
+251
+199
+142
+251
+199
+142
+251
+199
+142
+255
+216
+148
+255
+216
+148
+255
+224
+152
+255
+224
+152
+242
+185
+131
+242
+185
+131
+251
+199
+142
 249
 250
 252
@@ -5762,54 +5762,6 @@ P3
 105
 60
 40
-255
-216
-148
-251
-199
-142
-251
-199
-142
-255
-208
-144
-255
-221
-148
-255
-208
-144
-251
-199
-142
-251
-199
-142
-251
-199
-142
-251
-199
-142
-255
-216
-148
-255
-224
-152
-255
-224
-152
-242
-185
-131
-242
-185
-131
-255
-216
-148
 88
 177
 223
@@ -5858,6 +5810,54 @@ P3
 112
 217
 232
+255
+216
+148
+251
+199
+142
+251
+199
+142
+255
+208
+144
+255
+221
+148
+255
+208
+144
+251
+199
+142
+251
+199
+142
+251
+199
+142
+251
+199
+142
+255
+216
+148
+255
+224
+152
+255
+224
+152
+242
+185
+131
+242
+185
+131
+255
+216
+148
 249
 250
 252
@@ -5954,54 +5954,6 @@ P3
 105
 60
 40
-255
-216
-148
-251
-199
-142
-255
-208
-144
-255
-221
-148
-255
-221
-148
-251
-199
-142
-251
-199
-142
-251
-199
-142
-251
-199
-142
-251
-199
-142
-251
-199
-142
-255
-224
-152
-255
-224
-152
-251
-199
-142
-251
-199
-142
-255
-216
-148
 88
 177
 223
@@ -6050,6 +6002,54 @@ P3
 90
 184
 223
+255
+216
+148
+251
+199
+142
+255
+208
+144
+255
+221
+148
+255
+221
+148
+251
+199
+142
+251
+199
+142
+251
+199
+142
+251
+199
+142
+251
+199
+142
+251
+199
+142
+255
+224
+152
+255
+224
+152
+251
+199
+142
+251
+199
+142
+255
+216
+148
 249
 250
 252
@@ -6146,6 +6146,150 @@ P3
 105
 60
 40
+71
+39
+32
+115
+73
+55
+112
+66
+55
+89
+51
+43
+125
+79
+59
+125
+79
+59
+99
+60
+50
+136
+87
+65
+125
+79
+59
+99
+60
+50
+125
+79
+59
+125
+79
+59
+99
+60
+50
+99
+60
+50
+115
+73
+55
+71
+39
+32
+71
+39
+32
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+71
+39
+32
+44
+113
+68
+39
+92
+67
+44
+113
+68
+44
+113
+68
+44
+113
+68
+39
+92
+67
+44
+113
+68
+44
+113
+68
+44
+113
+68
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+92
+67
+44
+113
+68
+44
+113
+68
 192
 0
 255
@@ -6194,6 +6338,150 @@ P3
 192
 0
 255
+71
+39
+32
+89
+51
+43
+89
+51
+43
+89
+51
+43
+125
+79
+59
+125
+79
+59
+99
+60
+50
+125
+79
+59
+136
+87
+65
+99
+60
+50
+125
+79
+59
+125
+79
+59
+89
+51
+43
+125
+79
+59
+115
+73
+55
+71
+39
+32
+89
+51
+43
+89
+51
+43
+99
+60
+50
+99
+60
+50
+99
+60
+50
+99
+60
+50
+115
+73
+55
+115
+73
+55
+136
+87
+65
+136
+87
+65
+136
+87
+65
+99
+60
+50
+115
+73
+55
+115
+73
+55
+89
+51
+43
+89
+51
+43
+39
+92
+67
+39
+92
+67
+39
+128
+70
+44
+113
+68
+39
+92
+67
+39
+92
+67
+39
+92
+67
+44
+113
+68
+39
+92
+67
+39
+128
+70
+39
+92
+67
+39
+92
+67
+44
+113
+68
+44
+113
+68
+39
+92
+67
+44
+113
+68
 192
 0
 255
@@ -6242,6 +6530,150 @@ P3
 192
 0
 255
+71
+39
+32
+115
+73
+55
+125
+79
+59
+89
+51
+43
+89
+51
+43
+99
+60
+50
+99
+60
+50
+125
+79
+59
+125
+79
+59
+99
+60
+50
+89
+51
+43
+99
+60
+50
+99
+60
+50
+125
+79
+59
+105
+64
+51
+71
+39
+32
+89
+51
+43
+115
+73
+55
+136
+87
+65
+99
+60
+50
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+136
+87
+65
+99
+60
+50
+105
+64
+51
+89
+51
+43
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+128
+70
+39
+92
+67
+44
+113
+68
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+128
+70
+39
+92
+67
+44
+113
+68
+44
+113
+68
+39
+92
+67
+39
+92
+67
 192
 0
 255
@@ -6290,6 +6722,150 @@ P3
 192
 0
 255
+71
+39
+32
+115
+73
+55
+112
+66
+55
+89
+51
+43
+136
+87
+65
+136
+87
+65
+99
+60
+50
+125
+79
+59
+125
+79
+59
+99
+60
+50
+136
+87
+65
+125
+79
+59
+99
+60
+50
+112
+66
+55
+115
+73
+55
+71
+39
+32
+89
+51
+43
+115
+73
+55
+147
+101
+72
+89
+51
+43
+135
+81
+53
+163
+119
+85
+163
+119
+85
+163
+119
+85
+163
+119
+85
+163
+119
+85
+163
+119
+85
+135
+81
+53
+89
+51
+43
+136
+87
+65
+115
+73
+55
+89
+51
+43
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+128
+70
+44
+113
+68
+44
+113
+68
+44
+113
+68
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+128
+70
+39
+128
+70
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
 192
 0
 255
@@ -6338,6 +6914,150 @@ P3
 192
 0
 255
+71
+39
+32
+105
+64
+51
+125
+79
+59
+89
+51
+43
+125
+79
+59
+125
+79
+59
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+136
+87
+65
+136
+87
+65
+99
+60
+50
+125
+79
+59
+105
+64
+51
+71
+39
+32
+89
+51
+43
+105
+64
+51
+89
+51
+43
+135
+81
+53
+163
+119
+85
+163
+119
+85
+147
+101
+72
+147
+101
+72
+147
+101
+72
+147
+101
+72
+147
+101
+72
+163
+119
+85
+135
+81
+53
+89
+51
+43
+105
+64
+51
+89
+51
+43
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+44
+113
+68
+44
+113
+68
+44
+113
+68
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+128
+70
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
 192
 0
 255
@@ -6386,6 +7106,150 @@ P3
 192
 0
 255
+71
+39
+32
+115
+73
+55
+112
+66
+55
+89
+51
+43
+99
+60
+50
+99
+60
+50
+99
+60
+50
+147
+101
+72
+136
+87
+65
+89
+51
+43
+136
+87
+65
+125
+79
+59
+89
+51
+43
+112
+66
+55
+105
+64
+51
+71
+39
+32
+89
+51
+43
+136
+87
+65
+89
+51
+43
+163
+119
+85
+163
+119
+85
+147
+101
+72
+163
+119
+85
+163
+119
+85
+163
+119
+85
+163
+119
+85
+163
+119
+85
+163
+119
+85
+163
+119
+85
+89
+51
+43
+105
+64
+51
+89
+51
+43
+44
+113
+68
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+92
+67
+44
+113
+68
+44
+113
+68
+39
+92
+67
+44
+113
+68
+44
+113
+68
+39
+128
+70
+44
+113
+68
+44
+113
+68
+39
+92
+67
+39
+92
+67
+44
+113
+68
 192
 0
 255
@@ -6434,6 +7298,150 @@ P3
 192
 0
 255
+71
+39
+32
+105
+64
+51
+112
+66
+55
+89
+51
+43
+147
+101
+72
+125
+79
+59
+99
+60
+50
+136
+87
+65
+125
+79
+59
+99
+60
+50
+125
+79
+59
+136
+87
+65
+99
+60
+50
+112
+66
+55
+105
+64
+51
+71
+39
+32
+89
+51
+43
+136
+87
+65
+89
+51
+43
+163
+119
+85
+147
+101
+72
+163
+119
+85
+163
+119
+85
+147
+101
+72
+147
+101
+72
+147
+101
+72
+147
+101
+72
+163
+119
+85
+163
+119
+85
+89
+51
+43
+105
+64
+51
+89
+51
+43
+44
+113
+68
+44
+113
+68
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+44
+113
+68
+39
+92
+67
+44
+113
+68
+44
+113
+68
+44
+113
+68
+39
+92
+67
+44
+113
+68
 192
 0
 255
@@ -6482,6 +7490,150 @@ P3
 192
 0
 255
+71
+39
+32
+99
+60
+50
+99
+60
+50
+89
+51
+43
+136
+87
+65
+125
+79
+59
+99
+60
+50
+125
+79
+59
+136
+87
+65
+99
+60
+50
+99
+60
+50
+99
+60
+50
+99
+60
+50
+89
+51
+43
+99
+60
+50
+71
+39
+32
+89
+51
+43
+136
+87
+65
+89
+51
+43
+163
+119
+85
+147
+101
+72
+163
+119
+85
+147
+101
+72
+163
+119
+85
+163
+119
+85
+163
+119
+85
+163
+119
+85
+135
+81
+53
+163
+119
+85
+89
+51
+43
+99
+60
+50
+89
+51
+43
+44
+113
+68
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+128
+70
+39
+92
+67
+39
+92
+67
+44
+113
+68
+44
+113
+68
+39
+92
+67
+39
+92
+67
 192
 0
 255
@@ -6530,6 +7682,150 @@ P3
 192
 0
 255
+71
+39
+32
+115
+73
+55
+125
+79
+59
+89
+51
+43
+125
+79
+59
+136
+87
+65
+89
+51
+43
+125
+79
+59
+125
+79
+59
+99
+60
+50
+125
+79
+59
+125
+79
+59
+99
+60
+50
+125
+79
+59
+115
+73
+55
+71
+39
+32
+89
+51
+43
+136
+87
+65
+89
+51
+43
+163
+119
+85
+147
+101
+72
+163
+119
+85
+135
+81
+53
+163
+119
+85
+163
+119
+85
+135
+81
+53
+163
+119
+85
+147
+101
+72
+163
+119
+85
+89
+51
+43
+115
+73
+55
+89
+51
+43
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+128
+70
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+92
+67
 192
 0
 255
@@ -6578,6 +7874,150 @@ P3
 192
 0
 255
+71
+39
+32
+115
+73
+55
+112
+66
+55
+89
+51
+43
+136
+87
+65
+125
+79
+59
+99
+60
+50
+125
+79
+59
+125
+79
+59
+99
+60
+50
+136
+87
+65
+136
+87
+65
+99
+60
+50
+125
+79
+59
+105
+64
+51
+71
+39
+32
+89
+51
+43
+136
+87
+65
+89
+51
+43
+163
+119
+85
+135
+81
+53
+163
+119
+85
+163
+119
+85
+135
+81
+53
+147
+101
+72
+163
+119
+85
+163
+119
+85
+147
+101
+72
+163
+119
+85
+89
+51
+43
+136
+87
+65
+89
+51
+43
+44
+113
+68
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+92
+67
+39
+92
+67
+39
+92
+67
+44
+113
+68
+44
+113
+68
+44
+113
+68
+44
+113
+68
+39
+92
+67
+44
+113
+68
 192
 0
 255
@@ -6626,6 +8066,150 @@ P3
 192
 0
 255
+71
+39
+32
+115
+73
+55
+112
+66
+55
+89
+51
+43
+125
+79
+59
+125
+79
+59
+99
+60
+50
+125
+79
+59
+125
+79
+59
+89
+51
+43
+136
+87
+65
+125
+79
+59
+89
+51
+43
+112
+66
+55
+105
+64
+51
+71
+39
+32
+89
+51
+43
+136
+87
+65
+89
+51
+43
+163
+119
+85
+163
+119
+85
+147
+101
+72
+163
+119
+85
+163
+119
+85
+163
+119
+85
+163
+119
+85
+147
+101
+72
+163
+119
+85
+163
+119
+85
+89
+51
+43
+136
+87
+65
+89
+51
+43
+44
+113
+68
+44
+113
+68
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+128
+70
+39
+92
+67
+44
+113
+68
+44
+113
+68
+44
+113
+68
+44
+113
+68
+39
+92
+67
+39
+92
+67
+44
+113
+68
 192
 0
 255
@@ -6674,6 +8258,150 @@ P3
 192
 0
 255
+71
+39
+32
+115
+73
+55
+112
+66
+55
+89
+51
+43
+125
+79
+59
+125
+79
+59
+99
+60
+50
+125
+79
+59
+125
+79
+59
+99
+60
+50
+125
+79
+59
+125
+79
+59
+89
+51
+43
+89
+51
+43
+89
+51
+43
+71
+39
+32
+89
+51
+43
+115
+73
+55
+89
+51
+43
+135
+81
+53
+163
+119
+85
+163
+119
+85
+135
+81
+53
+147
+101
+72
+147
+101
+72
+147
+101
+72
+163
+119
+85
+163
+119
+85
+135
+81
+53
+89
+51
+43
+136
+87
+65
+89
+51
+43
+44
+113
+68
+39
+92
+67
+39
+128
+70
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+128
+70
+44
+113
+68
+44
+113
+68
+44
+113
+68
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+92
+67
 192
 0
 255
@@ -6722,6 +8450,150 @@ P3
 192
 0
 255
+71
+39
+32
+105
+64
+51
+125
+79
+59
+89
+51
+43
+99
+60
+50
+99
+60
+50
+99
+60
+50
+125
+79
+59
+125
+79
+59
+99
+60
+50
+99
+60
+50
+99
+60
+50
+89
+51
+43
+125
+79
+59
+105
+64
+51
+71
+39
+32
+89
+51
+43
+105
+64
+51
+136
+87
+65
+89
+51
+43
+135
+81
+53
+163
+119
+85
+163
+119
+85
+163
+119
+85
+163
+119
+85
+163
+119
+85
+163
+119
+85
+135
+81
+53
+89
+51
+43
+147
+101
+72
+105
+64
+51
+89
+51
+43
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+128
+70
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+128
+70
 192
 0
 255
@@ -6770,6 +8642,150 @@ P3
 192
 0
 255
+71
+39
+32
+89
+51
+43
+89
+51
+43
+89
+51
+43
+147
+101
+72
+136
+87
+65
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+147
+101
+72
+136
+87
+65
+89
+51
+43
+125
+79
+59
+105
+64
+51
+71
+39
+32
+89
+51
+43
+89
+51
+43
+99
+60
+50
+147
+101
+72
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+136
+87
+65
+136
+87
+65
+105
+64
+51
+89
+51
+43
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+128
+70
+39
+128
+70
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+92
+67
 192
 0
 255
@@ -6818,6 +8834,150 @@ P3
 192
 0
 255
+71
+39
+32
+115
+73
+55
+125
+79
+59
+89
+51
+43
+147
+101
+72
+136
+87
+65
+89
+51
+43
+125
+79
+59
+136
+87
+65
+89
+51
+43
+147
+101
+72
+125
+79
+59
+99
+60
+50
+112
+66
+55
+105
+64
+51
+71
+39
+32
+89
+51
+43
+89
+51
+43
+125
+79
+59
+99
+60
+50
+147
+101
+72
+136
+87
+65
+99
+60
+50
+125
+79
+59
+136
+87
+65
+147
+101
+72
+147
+101
+72
+99
+60
+50
+136
+87
+65
+136
+87
+65
+89
+51
+43
+89
+51
+43
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+128
+70
+39
+92
+67
+44
+113
+68
+44
+113
+68
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+128
+70
+39
+92
+67
+39
+92
+67
+39
+92
+67
 192
 0
 255
@@ -6866,2310 +9026,150 @@ P3
 192
 0
 255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
-192
-0
-255
+71
+39
+32
+105
+64
+51
+125
+79
+59
+89
+51
+43
+136
+87
+65
+125
+79
+59
+89
+51
+43
+147
+101
+72
+125
+79
+59
+89
+51
+43
+136
+87
+65
+125
+79
+59
+99
+60
+50
+112
+66
+55
+105
+64
+51
+71
+39
+32
+71
+39
+32
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+89
+51
+43
+71
+39
+32
+39
+92
+67
+39
+92
+67
+44
+113
+68
+39
+128
+70
+39
+92
+67
+39
+92
+67
+44
+113
+68
+44
+113
+68
+44
+113
+68
+39
+92
+67
+39
+92
+67
+39
+128
+70
+39
+128
+70
+39
+92
+67
+44
+113
+68
+44
+113
+68
 192
 0
 255
diff --git a/src/Math/Matrix.hpp b/src/Math/Matrix.hpp
index 69241d3..d467f72 100644
--- a/src/Math/Matrix.hpp
+++ b/src/Math/Matrix.hpp
@@ -9,14 +9,14 @@ template <size_t R, size_t C, typename T = float>
 struct Matrix {
     Matrix() : elements{} {};
 
-    explicit Matrix(T scalar) {
+    explicit Matrix(const T scalar) {
         std::fill(elements, elements + R * C, scalar);
     };
 
     template<typename ...Args, typename std::enable_if_t<sizeof...(Args) == R * C, int> = 0>
     Matrix(Args... args): elements{ args... } {};
 
-    explicit Matrix(T values[R * C]) {
+    explicit Matrix(const T values[R * C]) {
         std::copy(values, values + R * C, elements);
     };
 
@@ -67,11 +67,11 @@ struct Matrix {
         return rotation_x * rotation_y * rotation_z;
     }
 
-    Vector<C, T> row(size_t index) {
+    Vector<C, T> row(size_t index) const {
         return { &elements[index * C] };
     }
 
-    Vector<R, T> col(size_t index) {
+    Vector<R, T> col(size_t index) const {
         Vector<R, T> result{};
         for (int i = 0; i < R; i++) {
             result[i] = this->operator()(index, i);
@@ -79,7 +79,7 @@ struct Matrix {
         return result;
     }
 
-    Matrix transpose() {
+    Matrix transpose() const {
         Matrix result{};
         for (int y = 0; y < R; y++) {
             for (int x = 0; x < C; x++) {
@@ -89,7 +89,7 @@ struct Matrix {
         return result;
     }
 
-    Matrix operator+(Matrix other) {
+    Matrix operator+(const Matrix other) const {
         Matrix result{};
         for (int i = 0; i < R * C; i++) {
             result.elements[i] = elements[i] + other.elements[i];
@@ -106,7 +106,7 @@ struct Matrix {
     }
 
     template<size_t N>
-    Matrix<R, N, T> operator*(Matrix<C, N, T> other) {
+    Matrix<R, N, T> operator*(const Matrix<C, N, T> other) const {
         Matrix<R, N, T> result{};
         for (int y = 0; y < R; y++) {
             for (int x = 0; x < N; x++) {
@@ -121,13 +121,16 @@ struct Matrix {
         return result;
     }
 
-    Vector<R, T> operator*(Vector<R, T> vector) {
+    Vector<R, T> operator*(const Vector<R, T> vector) const {
         Matrix<R, 1, T> matrix(vector.elements);
         matrix = this->operator*(matrix);
         return { matrix.elements };
     }
 
-    auto& operator()(size_t x, size_t y) {
+    const T& operator()(const size_t x, const size_t y) const {
+        return elements[y * C + x];
+    }
+    T& operator()(const size_t x, const size_t y) {
         return elements[y * C + x];
     }
 
diff --git a/src/Math/Random.cpp b/src/Math/Random.cpp
new file mode 100644
index 0000000..e35cda7
--- /dev/null
+++ b/src/Math/Random.cpp
@@ -0,0 +1,31 @@
+#include "Random.hpp"
+
+namespace Math::Random {
+
+std::array<uint8_t, 4> break_float(const float f) {
+    static_assert(sizeof(float) == 4);
+
+    union { float f; uint8_t u[4]; } t{};
+    t.f = f;
+
+    return {
+        t.u[0], t.u[1], t.u[2], t.u[3]
+    };
+}
+
+float to_float(uint8_t u) {
+    return (float)u / (float)255;
+}
+
+uint8_t hash(uint8_t x) {
+    auto o = ((x ^ 0xAA) * 5);
+    auto rot = o % 8;
+    return o << rot | o >> (8 - rot);
+}
+
+float random() {
+    uint8_t r = std::rand() % 255;
+    return to_float(hash(r));
+}
+
+}
\ No newline at end of file
diff --git a/src/Math/Random.hpp b/src/Math/Random.hpp
new file mode 100644
index 0000000..ab94871
--- /dev/null
+++ b/src/Math/Random.hpp
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "array"
+#include "Common.hpp"
+
+namespace Math::Random {
+
+std::array<uint8_t, 4> break_float(float f);
+float to_float(uint8_t u);
+
+uint8_t hash(uint8_t x);
+
+float random();
+
+template <size_t D>
+struct Noise {
+    float at(Vector<D> pos) const {
+        uint8_t to_hash[D * 4];
+        for (int i = 0; i < D; i++) {
+            auto b = break_float(pos[i]);
+            to_hash[i*4] = b[0]; to_hash[i*4+1] = b[1]; to_hash[i*4+2] = b[2]; to_hash[i*4+3] = b[3];
+        }
+        uint8_t h = 0;
+        for (int i = 0; i < D * 4; i++) {
+            h = hash(h) + to_hash[i];
+        }
+        return to_float(h);
+    }
+};
+
+}
\ No newline at end of file
diff --git a/src/Math/Vector.hpp b/src/Math/Vector.hpp
index 260891d..54207f0 100644
--- a/src/Math/Vector.hpp
+++ b/src/Math/Vector.hpp
@@ -10,31 +10,36 @@ struct Vector {
     Vector(): elements{} {};
 
     template<typename ...Args, std::enable_if_t<sizeof...(Args) == S, int> = 0>
-    Vector<S, T>(Args... args) : elements{ args... } {};
+    Vector(Args... args) : elements{ args... } {};
 
-    Vector<S, T>(T values[S]) {
+    Vector(const T values[S]) {
         std::copy(values, values + S, elements);
     };
 
-    Vector<S, T>(T scalar) {
+    explicit Vector(const T scalar) {
         std::fill(elements, elements + S, scalar);
     };
 
-    Vector<S, T>(Vector<S - 1, T> vector, T scalar) {
+    Vector(const Vector<S - 1, T> vector, const T scalar) {
         std::copy(vector.elements, vector.elements + S - 1, elements);
         elements[S - 1] = scalar;
     }
 
-    Vector<S, T> map(std::function<T(T)> f) const {
-        Vector<S, T> result{};
+    template<size_t N, std::enable_if_t<(N > S), int> = 0>
+    explicit Vector(const Vector<N, T> vector) {
+        std::copy(vector.elements, vector.elements + S, elements);
+    }
+
+    Vector map(std::function<T(T)> f) const {
+        Vector result{};
         for (int i = 0; i < S; i++) {
             result[i] = f(elements[i]);
         }
         return result;
     }
 
-    Vector<S, T> map(std::function<T(size_t, T)> f) const {
-        Vector<S, T> result{};
+    Vector map(std::function<T(size_t, T)> f) const {
+        Vector result{};
         for (int i = 0; i < S; i++) {
             result[i] = f(i, elements[i]);
         }
@@ -57,20 +62,27 @@ struct Vector {
         return sqrt(map([](auto x) { return x * x;}).sum());
     }
 
-    Vector<S, T> normalize() const {
+    Vector normalize() const {
         auto m = magnitude();
         return map([=](auto x) { return x / m; });
     }
 
-    T distance(Vector<S, T> other) const {
+    T distance(const Vector other) const {
         return (*this - other).magnitude();
     }
 
-    Vector<S, T> abs() const {
+    Vector<3, T> any_orthogonal() {
+        if (Vector a{y(), -x(), 0.0f}; a != zero()) return a;
+        if (Vector b{z(), 0.0f, -x()}; b != zero()) return b;
+        if (Vector c{0.0f, z(), -y()}; c != zero()) return c;
+        return zero();
+    }
+
+    Vector abs() const {
         return map([=](auto x) { return std::abs(x); });
     }
 
-    Vector<3, T> cross(Vector<3, T> other) const {
+    Vector<3, T> cross(const Vector<3, T> other) const {
         return {
             y() * other.z() - z() * other.y(),
             z() * other.x() - x() * other.z(),
@@ -86,34 +98,52 @@ struct Vector {
         return elements[index];
     }
 
-    Vector<S, T> operator+(Vector<S, T> other) const {
+    Vector operator+(const Vector other) const {
         return map([&](auto i, auto x) { return x + other[i]; });
     }
 
-    Vector<S, T> operator+(T scalar) const {
+    Vector operator+(T scalar) const {
         return map([=](auto x) { return x + scalar; });
     }
 
-    Vector<S, T> operator*(T scalar) const {
+    Vector operator*(T scalar) const {
         return map([=](auto x) { return x * scalar; });
     }
 
-    T operator*(Vector<S, T> other) const {
+    T operator*(const Vector other) const {
         return map([&](auto i, auto x) { return x * other[i]; }).sum();
     }
 
-    Vector<S, T> operator-(Vector<S, T> other) const {
+    Vector operator-(const Vector other) const {
         return map([&](auto i, auto x) { return x - other[i]; });
     }
 
-    Vector<S, T> operator-() const {
+    Vector operator-() const {
         return map([](T x) -> T { return -x; });
     }
 
-    Vector<S, T> operator/(T scalar) const {
+    Vector operator/(T scalar) const {
         return map([=](auto x) { return x / scalar; });
     }
 
+    bool operator==(const Vector& other) {
+        for (int i = 0; i < S; i++) {
+            if (elements[i] != other[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    bool operator!=(const Vector& other) {
+        return !this->operator==(other);
+    }
+
+    Vector& operator+=(const Vector& other) {
+        *this = *this + other;
+        return *this;
+    }
+
     T& x() { static_assert(S > 0); return elements[0]; }
     const T& x() const { static_assert(S > 0); return elements[0]; }
 
@@ -138,5 +168,16 @@ struct Vector {
         return str.str();
     }
 
+    static Vector<3, T> up() { return {(T)0, (T)1, (T)0}; }
+    static Vector<3, T> down() { return {(T)0, (T)-1, (T)0}; }
+    static Vector<3, T> forward() { return {(T)0, (T)0, (T)1}; }
+    static Vector<3, T> back() { return {(T)0, (T)0, (T)-1}; }
+    static Vector<3, T> right() { return {(T)1, (T)0, (T)0}; }
+    static Vector<3, T> left() { return {(T)-1, (T)0, (T)0}; }
+
+    static Vector<3, T> one() { return Vector{(T)1}; }
+    static Vector<3, T> zero() { return Vector{(T)0}; }
+    static Vector<3, T> max() { return Vector{(T)std::numeric_limits<T>::max()}; }
+
     T elements[S];
 };
diff --git a/src/World/BlockType.hpp b/src/World/BlockType.hpp
index dcb8e44..472523f 100644
--- a/src/World/BlockType.hpp
+++ b/src/World/BlockType.hpp
@@ -14,6 +14,8 @@ public:
         Stone,
         Sand,
         Snow,
+        Wood,
+        Leaves,
         Water,
     };
 
diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp
index 9642fa9..b75516f 100644
--- a/src/World/Chunk.cpp
+++ b/src/World/Chunk.cpp
@@ -11,163 +11,16 @@ Chunk::BlockData Chunk::get(uint32_t x, uint32_t y, uint32_t z) const {
     return m_blocks.at(pos(x, y, z));
 }
 
-GFX::Mesh Chunk::mesh() {
-    std::vector<Vector<3>> positions{};
-    std::vector<Vector<3>> normals{};
-    std::vector<Vector<2>> tex_coords{};
-    std::vector<uint32_t> indices{};
-
-    for (int x = 0; x < Width; x++) {
-        for (int y = 0; y < Height; y++) {
-            for (int z = 0; z < Width; z++) {
-                auto type = get(x, y, z).type;
-                if (type == BlockType::Air) {
-                    continue;
-                }
-
-                for (auto side: BlockSide::all()) {
-                    if (!is_face_visible(x, y, z, side)) {
-                        continue;
-                    }
-
-                    auto side_positions = side.face();
-                    auto side_normals = face_normals(side);
-                    auto side_tex_coords = face_tex_coords(type, side);
-
-                    for (auto& position : side_positions) {
-                        position = position + Vector<3>{static_cast<float>(x), static_cast<float>(y), static_cast<float>(z)};
-                    }
-
-                    uint32_t s = positions.size();
-
-                    positions.insert(positions.end(), side_positions.begin(), side_positions.end());
-                    normals.insert(normals.end(), side_normals.begin(), side_normals.end());
-                    tex_coords.insert(tex_coords.end(), side_tex_coords.begin(), side_tex_coords.end());
-                    indices.insert(indices.end(), {s, s + 1, s + 3, s + 1, s + 2, s + 3});
-                }
-            }
-        }
-    }
-
-    return {
-        {positions, normals, tex_coords},
-        indices,
-    };
+bool Chunk::is_empty(uint32_t x, uint32_t y, uint32_t z) const {
+    return get(x, y, z).empty();
 }
 
 Vector<3> Chunk::position() {
     return m_position;
 }
 
-bool Chunk::is_face_visible(uint32_t x, uint32_t y, uint32_t z, BlockSide side) {
-    Vector<3, int32_t> offset{};
-    switch (side) {
-        case BlockSide::Front:
-            offset[2] = 1;
-            break;
-        case BlockSide::Back:
-            offset[2] = -1;
-            break;
-        case BlockSide::Top:
-            offset[1] = 1;
-            break;
-        case BlockSide::Bottom:
-            offset[1] = -1;
-            break;
-        case BlockSide::Left:
-            offset[0] = -1;
-            break;
-        case BlockSide::Right:
-            offset[0] = 1;
-            break;
-    }
-
-    Vector<3, uint32_t> neighbor_pos{
-        x + offset.x(), y + offset.y(), z + offset.z(),
-    };
-
-    if (
-        neighbor_pos.x() >= Width || neighbor_pos.x() < 0 ||
-        neighbor_pos.y() >= Height || neighbor_pos.y() < 0 ||
-        neighbor_pos.z() >= Width || neighbor_pos.z() < 0
-    ) {
-        return true;
-    }
-
-    auto neighbor = get(neighbor_pos.x(), neighbor_pos.y(), neighbor_pos.z());
-    if (neighbor.type == BlockType::Air) {
-        return true;
-    }
-
-    return false;
-}
-
-std::array<Vector<2>, 4> Chunk::face_tex_coords(BlockType type, BlockSide side) {
-    uint8_t atlas_width = 4;
-    uint8_t atlas_height = 4;
-
-    float width_step = 1.0f / atlas_width;
-    float height_step = 1.0f / atlas_height;
-
-    auto block_coords = [=](uint8_t x, uint8_t y) {
-        auto t = y * height_step;
-        auto l = x * width_step;
-        auto b = t + height_step;
-        auto r = l + width_step;
-
-        return std::array<Vector<2>, 4>{{
-            {l, b}, {r, b}, {r, t}, {l, t},
-        }};
-    };
-
-    switch (type) {
-        case BlockType::Dirt:
-            return block_coords(1, 0);
-        case BlockType::Grass:
-            switch (side) {
-            case BlockSide::Front:
-            case BlockSide::Back:
-            case BlockSide::Left:
-            case BlockSide::Right:
-                return block_coords(2, 0);
-            case BlockSide::Bottom:
-                return block_coords(1, 0);
-            case BlockSide::Top:
-                return block_coords(0, 0);
-            }
-        case BlockType::Stone:
-            return block_coords(3, 0);
-        case BlockType::Sand:
-            return block_coords(0, 1);
-        case BlockType::Water:
-            return block_coords(1, 1);
-        case BlockType::Snow:
-            switch (side) {
-            case BlockSide::Front:
-            case BlockSide::Back:
-            case BlockSide::Left:
-            case BlockSide::Right:
-                return block_coords(3, 1);
-            case BlockSide::Bottom:
-                return block_coords(1, 0);
-            case BlockSide::Top:
-                return block_coords(2, 1);
-            }
-        case BlockType::Air:
-            return {};
-    }
-}
-
-std::array<Vector<3>, 4> Chunk::face_normals(BlockSide side) {
-    auto is_side = [=](BlockSide s) -> float { return s == side; };
-
-    Vector<3> normal = {
-        is_side(BlockSide::Right) - is_side(BlockSide::Left),
-        is_side(BlockSide::Top) - is_side(BlockSide::Bottom),
-        is_side(BlockSide::Front) - is_side(BlockSide::Back),
-    };
-
-    return {normal, normal, normal, normal};
+bool Chunk::is_valid_position(uint32_t x, uint32_t y, uint32_t z) {
+    return x < Width && y < Height && z < Width;
 }
 
 uint64_t Chunk::pos(uint32_t x, uint32_t y, uint32_t z) {
diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp
index d200039..8780700 100644
--- a/src/World/Chunk.hpp
+++ b/src/World/Chunk.hpp
@@ -19,27 +19,30 @@ public:
 
     struct BlockData {
         BlockType type;
+
+        bool empty() const { return type == BlockType::Air; }
     };
 
     void set(uint32_t x, uint32_t y, uint32_t z, BlockData data);
     BlockData get(uint32_t x, uint32_t y, uint32_t z) const;
+    bool is_empty(uint32_t x, uint32_t y, uint32_t z) const;
 
     struct Details {
         Matrix<Width, Width> landmass_values{};
         Matrix<Width, Width> hill_values{};
+
+        Matrix<Width, Width> temperature_values{};
+        Matrix<Width, Width> humidity_values{};
+
         Matrix<Width, Width, BiomeType> biome_values{};
     };
     void set_details(const Details& details) { m_details = details; }
     Details& details(){ return m_details; }
 
     Vector<3> position();
-    GFX::Mesh mesh();
-private:
-    bool is_face_visible(uint32_t x, uint32_t y, uint32_t z, BlockSide side);
-
-    static std::array<Vector<2>, 4> face_tex_coords(BlockType type, BlockSide side);
-    static std::array<Vector<3>, 4> face_normals(BlockSide side);
 
+    static bool is_valid_position(uint32_t x, uint32_t y, uint32_t z);
+private:
     static uint64_t pos(uint32_t x, uint32_t y, uint32_t z);
 
     Vector<3> m_position;
diff --git a/src/World/ChunkMeshing.cpp b/src/World/Generation/ChunkMeshing.cpp
index 3e50427..54abc85 100644
--- a/src/World/ChunkMeshing.cpp
+++ b/src/World/Generation/ChunkMeshing.cpp
@@ -1,6 +1,6 @@
 #include "ChunkMeshing.hpp"
 
-namespace MC::World {
+namespace MC::World::Generation {
 
 std::array<Vector<2>, 4> face_tex_coords(BlockType type, BlockSide side) {
     uint8_t atlas_width = 4;
@@ -38,9 +38,9 @@ std::array<Vector<2>, 4> face_tex_coords(BlockType type, BlockSide side) {
         case BlockType::Stone:
             return block_coords(3, 0);
         case BlockType::Sand:
-            return block_coords(0, 1);
-        case BlockType::Water:
             return block_coords(1, 1);
+        case BlockType::Water:
+            return block_coords(0, 1);
         case BlockType::Snow:
             switch (side) {
                 case BlockSide::Front:
@@ -53,6 +53,19 @@ std::array<Vector<2>, 4> face_tex_coords(BlockType type, BlockSide side) {
                 case BlockSide::Top:
                     return block_coords(2, 1);
             }
+        case BlockType::Wood:
+            switch (side) {
+                case BlockSide::Front:
+                case BlockSide::Back:
+                case BlockSide::Right:
+                case BlockSide::Left:
+                    return block_coords(0, 2);
+                case BlockSide::Bottom:
+                case BlockSide::Top:
+                    return block_coords(1, 2);
+            }
+        case BlockType::Leaves:
+            return block_coords(2, 2);
         case BlockType::Air:
             return {};
     }
diff --git a/src/World/ChunkMeshing.hpp b/src/World/Generation/ChunkMeshing.hpp
index 1348817..a4fed25 100644
--- a/src/World/ChunkMeshing.hpp
+++ b/src/World/Generation/ChunkMeshing.hpp
@@ -1,9 +1,9 @@
 #pragma once
 
-#include "../GFX/Mesh.hpp"
-#include "Chunk.hpp"
+#include "../../GFX/Mesh.hpp"
+#include "../Chunk.hpp"
 
-namespace MC::World::ChunkMeshing {
+namespace MC::World::Generation::ChunkMeshing {
 
 struct ChunkNeighbors { Chunk &north, &east, &south, &west; };
 GFX::Mesh create_mesh_for_chunk(Chunk& chunk, ChunkNeighbors neighbors);
diff --git a/src/World/Generation/Decoration.cpp b/src/World/Generation/Decoration.cpp
new file mode 100644
index 0000000..26eb397
--- /dev/null
+++ b/src/World/Generation/Decoration.cpp
@@ -0,0 +1,97 @@
+#include "Decoration.hpp"
+
+#include <iostream>
+
+namespace MC::World::Generation {
+void Decorator::put_block(Chunk& chunk, Pos pos, BlockType block) {
+    if (!Chunk::is_valid_position(pos.x(), pos.y(), pos.z())) {
+        return;
+    }
+    if (chunk.is_empty(pos.x(), pos.y(), pos.z())) {
+        chunk.set(pos.x(), pos.y(), pos.z(), {block});
+    }
+}
+
+void Decorator::draw_column(Chunk& chunk, Pos pos, uint height, BlockType block) {
+    Pos current_pos = pos;
+    for (uint i = 0; i < height; i++) {
+        put_block(chunk, current_pos, block);
+        current_pos += Pos::up();
+    }
+}
+
+void Decorator::draw_circle(Chunk& chunk, Pos pos, Vector<3> axis, float radius, BlockType block) {
+    auto normalized_axis = axis.normalize();
+
+    auto ortho1 = normalized_axis.any_orthogonal();
+    auto ortho2 = normalized_axis.cross(ortho1);
+
+    auto r = [](const float x) { return static_cast<uint>(std::round(x)); };
+
+    int radius_round = std::round(radius);
+    for (int32_t d1 = -radius_round; d1 <= radius_round; d1++) {
+        float height = std::sqrt(radius * radius - d1 * d1);
+        for (int32_t d2 = -height; d2 <= (int)height; d2++) {
+            auto p = ortho1 * d1 + ortho2 * d2;
+            Pos block_pos = pos + Pos{r(p.x()), r(p.y()), r(p.z())};
+            put_block(chunk, block_pos, block);
+        }
+    }
+}
+
+void TreeDecorator::decorate_chunk(Chunk& chunk) {
+    Pos last_tree = Pos::max();
+    for (uint x = 0; x < Chunk::Width; x++) {
+        for (uint z = 0; z < Chunk::Width; z++) {
+            for (uint y = Chunk::Height; y > 1; y--) {
+                Pos pos{x, y, z};
+                if (!is_valid_position(pos))
+                    continue;
+
+                auto block_below = chunk.get(x, y-1, z);
+                if (block_below.empty())
+                    continue;
+
+                auto type = block_below.type;
+                if (type != BlockType::Snow && type != BlockType::Grass && type != BlockType::Dirt)
+                    break;
+
+                auto noise = m_tree_noise.at({(float)x, (float)z});
+                if (noise < 0.8f)
+                    continue;
+
+                if (last_tree.distance(pos) < s_tree_radius * 3)
+                    continue;
+
+                draw_tree(chunk, pos);
+                chunk.set(x, y-1, z, {BlockType::Dirt});
+                last_tree = pos;
+                break;
+            }
+        }
+    }
+}
+
+void TreeDecorator::draw_tree(Chunk& chunk, Pos pos) const {
+    auto noise = m_tree_noise.at({(float)pos.x(), (float)pos.z()});
+    uint height = std::round(10 * noise - 4.75f);
+
+    draw_column(chunk, pos, height, BlockType::Wood);
+
+    uint max_leaf_height = 4;
+    for (int x = 0; x < max_leaf_height; x++) {
+        Pos p{pos.x(), pos.y() + height + x - 2, pos.z()};
+        float radius = s_tree_radius - 0.5f + x * ((0.3f * x - 1.45f) * x + 1.25f);
+        draw_circle(chunk, p, Vector<3>::up(), radius, BlockType::Leaves);
+    }
+}
+
+bool TreeDecorator::is_valid_position(Vector<3, uint> pos) {
+    int tree_radius = s_tree_radius;
+    return (int)pos.x() - tree_radius >= 0
+        && pos.x() + tree_radius <= Chunk::Width
+        && (int)pos.z() - tree_radius >= 0
+        && pos.z() + tree_radius <= Chunk::Width;
+}
+
+}
diff --git a/src/World/Generation/Decoration.hpp b/src/World/Generation/Decoration.hpp
new file mode 100644
index 0000000..a592e72
--- /dev/null
+++ b/src/World/Generation/Decoration.hpp
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "../Chunk.hpp"
+#include "../../Math/Random.hpp"
+
+namespace MC::World::Generation {
+
+class Decorator {
+public:
+    using Pos = Vector<3, uint>;
+
+    virtual ~Decorator() = default;
+
+    virtual void decorate_chunk(Chunk& chunk) = 0;
+
+    static void put_block(Chunk& chunk, Pos pos, BlockType block);
+    static void draw_column(Chunk& chunk, Pos pos, uint height, BlockType block);
+    static void draw_circle(Chunk& chunk, Pos pos, Vector<3> axis, float radius, BlockType block);
+};
+
+class TreeDecorator final : public Decorator {
+public:
+    void decorate_chunk(Chunk& chunk) override;
+private:
+    void draw_tree(Chunk& chunk, Pos pos) const;
+
+    static bool is_valid_position(Pos pos);
+
+    static constexpr uint s_tree_radius = 3;
+
+    Math::Random::Noise<2> m_tree_noise;
+};
+
+}
diff --git a/src/World/Generator.cpp b/src/World/Generation/Generator.cpp
index ada2b7b..af3c54d 100644
--- a/src/World/Generator.cpp
+++ b/src/World/Generation/Generator.cpp
@@ -1,8 +1,8 @@
 #include "Generator.hpp"
-#include "../Math/Interpolation.hpp"
-#include "../Math/Sigmoid.hpp"
+#include "../../Math/Interpolation.hpp"
+#include "../../Math/Sigmoid.hpp"
 
-namespace MC::World {
+namespace MC::World::Generation {
 
 Chunk Generator::generate(int64_t chunk_x, int64_t chunk_y) {
     Chunk chunk(chunk_x, chunk_y);
@@ -11,40 +11,32 @@ Chunk Generator::generate(int64_t chunk_x, int64_t chunk_y) {
     auto hill_map = generate_hill_map(chunk_x, chunk_y);
     auto height_map = generate_height_map(landmass_map, hill_map, chunk_x, chunk_y);
 
-    auto biome_map = generate_biome_map(landmass_map, hill_map, height_map, chunk_x, chunk_y);
+    auto temperature_map = generate_temperature_map(chunk_x, chunk_y);
+    auto humidity_map = generate_humidity_map(chunk_x, chunk_y);
+    auto biome_map = generate_biome_map(landmass_map, hill_map, temperature_map, humidity_map, chunk_x, chunk_y);
     auto terrain_map = generate_terrain(height_map, chunk_x, chunk_y);
 
     decorate_soil(chunk, biome_map, terrain_map);
 
-    chunk.set_details({{landmass_map}, {hill_map}, {biome_map}});
+    chunk.set_details({landmass_map, hill_map, temperature_map, humidity_map, biome_map});
 
     return chunk;
 }
 
-Generator::Map2D<float> Generator::generate_landmass_map(int64_t chunk_x, int64_t chunk_y) {
-    Matrix<Chunk::Width, Chunk::Width> landmass_map{};
-
-    for (uint x = 0; x < Chunk::Width; x++) {
-        for (uint y = 0; y < Chunk::Width; y++) {
-            auto world_pos = chunk_position_to_world_vector(chunk_x, chunk_y, x, y);
-            landmass_map(x, y) = get_landmass(world_pos);
-        }
-    }
-
-    return landmass_map;
+#define SIMPLE_MAP_GENERATOR(name, getter)                                      \
+Generator::Map2D<float> Generator::name(int64_t chunk_x, int64_t chunk_y) {     \
+    Matrix<Chunk::Width, Chunk::Width> map{};                                   \
+    for (uint x = 0; x < Chunk::Width; x++) {                                   \
+        for (uint y = 0; y < Chunk::Width; y++) {                               \
+            auto pos = chunk_position_to_world_vector(chunk_x, chunk_y, x, y);  \
+            map(x, y) = getter(pos);                                            \
+        }                                                                       \
+    }                                                                           \
+    return map;                                                                 \
 }
 
-Generator::Map2D<float> Generator::generate_hill_map(int64_t chunk_x, int64_t chunk_y) {
-    Map2D<float> hill_map{};
-
-    for (uint x = 0; x < Chunk::Width; x++) {
-        for (uint y = 0; y < Chunk::Width; y++) {
-            hill_map(x, y) = get_hill(chunk_position_to_world_vector(chunk_x, chunk_y, x, y));
-        }
-    }
-
-    return hill_map;
-}
+SIMPLE_MAP_GENERATOR(generate_landmass_map, get_landmass)
+SIMPLE_MAP_GENERATOR(generate_hill_map, get_hill)
 
 Generator::Map2D<float> Generator::generate_height_map(Map2D<float>& landmass_map, Map2D<float>& hill_map, int64_t chunk_x, int64_t chunk_y) {
     Map2D<float> height_map{};
@@ -66,7 +58,14 @@ Generator::Map2D<float> Generator::generate_height_map(Map2D<float>& landmass_ma
     return height_map;
 }
 
-Generator::Map2D<BiomeType> Generator::generate_biome_map(Map2D<float>& landmass_map, Map2D<float>& hill_map, Map2D<float>& height_map, int64_t chunk_x, int64_t chunk_y) {
+SIMPLE_MAP_GENERATOR(generate_temperature_map, get_temperature)
+SIMPLE_MAP_GENERATOR(generate_humidity_map, get_humidity)
+
+Generator::Map2D<BiomeType> Generator::generate_biome_map(
+    Map2D<float>& landmass_map, Map2D<float>& hill_map,
+    Map2D<float>& temperature_map, Map2D<float>& humidity_map,
+    int64_t chunk_x, int64_t chunk_y
+) {
     Map2D<BiomeType> biome_map{};
 
     for (uint x = 0; x < Chunk::Width; x++) {
@@ -74,13 +73,12 @@ Generator::Map2D<BiomeType> Generator::generate_biome_map(Map2D<float>& landmass
             float landmass = landmass_map(x, y);
             float hill = hill_map(x, y);
 
-            auto world_pos = chunk_position_to_world_vector(chunk_x, chunk_y, x, y);
-            float temperature = get_temperature(world_pos);
-            float humidity = get_humidity(world_pos);
+            float temperature = temperature_map(x, y);
+            float humidity = humidity_map(x, y);
 
             HillSlice hill_slice;
-            if (hill > 0.9) { hill_slice = HillSlice::Mountain; }
-            else if (hill > 0.33) { hill_slice = HillSlice::Middle; }
+            if (hill > 0.55) { hill_slice = HillSlice::Mountain; }
+            else if (hill > 0.03) { hill_slice = HillSlice::Middle; }
             else { hill_slice = HillSlice::Valley; }
 
             LandmassSlice landmass_slice;
@@ -89,8 +87,8 @@ Generator::Map2D<BiomeType> Generator::generate_biome_map(Map2D<float>& landmass
             else { landmass_slice = LandmassSlice::Ocean; }
 
             TemperatureZone temparature_zone;
-            if (temperature > 0.66) { temparature_zone = TemperatureZone::Hot; }
-            else if (temperature > 0.33) { temparature_zone = TemperatureZone::Fair; }
+            if (temperature > 0.6) { temparature_zone = TemperatureZone::Hot; }
+            else if (temperature > 0.4) { temparature_zone = TemperatureZone::Fair; }
             else { temparature_zone = TemperatureZone::Cold; }
 
             HumidityZone humidity_zone;
@@ -130,7 +128,7 @@ Generator::Map3D<bool> Generator::generate_terrain(Map2D<float>& height_map, int
 
 void Generator::decorate_soil(Chunk& chunk, Map2D<BiomeType>& biome_map, Map3D<bool>& terrain_map) {
     constexpr uint dirt_depth = 4;
-    constexpr uint water_height = 39;
+    constexpr uint water_height = 40;
 
     for (uint x = 0; x < Chunk::Width; x++) {
         for (uint z = 0; z < Chunk::Width; z++) {
@@ -147,8 +145,8 @@ void Generator::decorate_soil(Chunk& chunk, Map2D<BiomeType>& biome_map, Map3D<b
             case BiomeType::Jungle:
             case BiomeType::Forest:
             case BiomeType::Plains:
-            case BiomeType::River:
             case BiomeType::Ocean:
+            case BiomeType::River:
                 top_block = BlockType::Grass;
                 soil_block = BlockType::Dirt;
                 break;
@@ -156,6 +154,10 @@ void Generator::decorate_soil(Chunk& chunk, Map2D<BiomeType>& biome_map, Map3D<b
                 top_block = BlockType::Snow;
                 soil_block = BlockType::Dirt;
                 break;
+            case BiomeType::Shore:
+            case BiomeType::RockyPeaks:
+                top_block = BlockType::Stone;
+                soil_block = BlockType::Stone;
             }
 
             auto column_depth = 0;
@@ -179,6 +181,10 @@ void Generator::decorate_soil(Chunk& chunk, Map2D<BiomeType>& biome_map, Map3D<b
             }
         }
     }
+
+    for (auto& decorator : s_decorators) {
+        decorator->decorate_chunk(chunk);
+    }
 }
 
 #define CURVE_START(y) constexpr auto lerp = Math::linear_interpolation; float _py = y; float _px = 0.0f;
@@ -249,7 +255,11 @@ std::array<BiomeType, Generator::biome_lookup_table_size> Generator::create_biom
                         goto set;
                     }
                     if (landmass_slice == LandmassSlice::Beach) {
-                        biome = BiomeType::Beach;
+                        if (temperature_zone == TemperatureZone::Cold) {
+                            biome = BiomeType::Shore;
+                        } else {
+                            biome = BiomeType::Beach;
+                        }
                         goto set;
                     }
 
@@ -258,10 +268,10 @@ std::array<BiomeType, Generator::biome_lookup_table_size> Generator::create_biom
                         goto set;
                     }
                     if (hill_slice == HillSlice::Mountain) {
-                        if (temperature_zone == TemperatureZone::Hot) {
-                            biome = BiomeType::Desert;
-                        } else {
+                        if (temperature_zone == TemperatureZone::Cold) {
                             biome = BiomeType::Alpine;
+                        } else {
+                            biome = BiomeType::RockyPeaks;
                         }
                         goto set;
                     }
diff --git a/src/World/Generator.hpp b/src/World/Generation/Generator.hpp
index a90d1bc..464e36f 100644
--- a/src/World/Generator.hpp
+++ b/src/World/Generation/Generator.hpp
@@ -1,12 +1,14 @@
 #pragma once
 
 #include <cstdint>
-#include "Chunk.hpp"
-#include "BiomeType.hpp"
-#include "../Math/Perlin.hpp"
-#include "../Math/Tensor.hpp"
 
-namespace MC::World {
+#include "Decoration.hpp"
+#include "../Chunk.hpp"
+#include "../BiomeType.hpp"
+#include "../../Math/Perlin.hpp"
+#include "../../Math/Tensor.hpp"
+
+namespace MC::World::Generation {
 
 class Generator {
 public:
@@ -20,7 +22,14 @@ private:
     Map2D<float> generate_hill_map(int64_t chunk_x, int64_t chunk_y);
     Map2D<float> generate_height_map(Map2D<float>& landmass_map, Map2D<float>& hill_map, int64_t chunk_x, int64_t chunk_y);
 
-    Map2D<BiomeType> generate_biome_map(Map2D<float>& landmass_map, Map2D<float>& hill_map, Map2D<float>& height_map, int64_t chunk_x, int64_t chunk_y);
+    Map2D<float> generate_temperature_map(int64_t chunk_x, int64_t chunk_y);
+    Map2D<float> generate_humidity_map(int64_t chunk_x, int64_t chunk_y);
+
+    Map2D<BiomeType> generate_biome_map(
+        Map2D<float>& landmass_map, Map2D<float>& hill_map,
+        Map2D<float>& temperature_map, Map2D<float>& humidity_map,
+        int64_t chunk_x, int64_t chunk_y
+    );
 
     Map3D<bool> generate_terrain(Map2D<float>& height_map, int64_t chunk_x, int64_t chunk_y);
 
@@ -36,11 +45,15 @@ private:
 
     static Vector<2> chunk_position_to_world_vector(int64_t chunk_x, int64_t chunk_y, uint x, uint y);
 
+    static inline std::vector<Decorator*> s_decorators = {
+        new TreeDecorator(),
+    };
+
     Math::Perlin::Noise<2> m_landmass_noise{.scale=800.0f, .octaves=4, .persistence=0.3f, .lacunarity=3.5f};
     Math::Perlin::Noise<2> m_hill_noise{.scale=400.0f, .octaves=3, .persistence=0.5f, .lacunarity=2.0f};
 
-    Math::Perlin::Noise<2> m_temperature_noise{.scale=700.0f, .octaves=3, .persistence=0.5f, .lacunarity=2.0f};
-    Math::Perlin::Noise<2> m_humidity_noise{.scale=400.0f, .octaves=2, .persistence=0.5f, .lacunarity=2.0f};
+    Math::Perlin::Noise<2> m_temperature_noise{.scale=700.0f, .octaves=4, .persistence=0.4f, .lacunarity=3.0f};
+    Math::Perlin::Noise<2> m_humidity_noise{.scale=400.0f, .octaves=2, .persistence=0.4f, .lacunarity=3.0f};
 
     Math::Perlin::Noise<3> m_density_noise{.scale=30.0f, .octaves=2, .persistence=0.7f, .lacunarity=2.0f};
 
diff --git a/src/World/World.cpp b/src/World/World.cpp
index 289d86b..6e8489a 100644
--- a/src/World/World.cpp
+++ b/src/World/World.cpp
@@ -1,5 +1,5 @@
 #include "World.hpp"
-#include "ChunkMeshing.hpp"
+#include "Generation/ChunkMeshing.hpp"
 
 namespace MC::World {
 
@@ -127,7 +127,7 @@ void World::try_to_create_mesh_for_chunk(ChunkData& data) {
         return;
     }
 
-    data.mesh_data = ChunkMeshing::create_mesh_for_chunk(
+    data.mesh_data = Generation::ChunkMeshing::create_mesh_for_chunk(
         data.chunk.value(),
         {north.chunk.value(), east.chunk.value(), south.chunk.value(), west.chunk.value()}
     );
diff --git a/src/World/World.hpp b/src/World/World.hpp
index e6b3cd2..ae8b37f 100644
--- a/src/World/World.hpp
+++ b/src/World/World.hpp
@@ -3,7 +3,7 @@
 #include <memory>
 #include <unordered_map>
 #include <unordered_set>
-#include "Generator.hpp"
+#include "Generation/Generator.hpp"
 #include "ChunkIndex.hpp"
 #include "../GFX/Binder.hpp"
 #include "../Compute/Queue.hpp"
@@ -53,7 +53,7 @@ private:
         uint64_t generation_duration;
     };
     Compute::Queue<GenerationResult, ChunkIndex> m_queue;
-    Generator m_generator;
+    Generation::Generator m_generator;
 
     std::unordered_map<ChunkIndex, ChunkData> m_chunks;
     std::unordered_set<ChunkIndex> m_visible_chunks;