diff options
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | assets/images/atlas.png | bin | 3102 -> 3705 bytes | |||
| -rw-r--r-- | assets/images/atlas.ppm | 10492 | ||||
| -rw-r--r-- | src/Math/Common.hpp | 3 | ||||
| -rw-r--r-- | src/Math/Constants.hpp | 8 | ||||
| -rw-r--r-- | src/Math/Perlin.hpp | 3 | ||||
| -rw-r--r-- | src/Math/Sigmoid.hpp | 13 | ||||
| -rw-r--r-- | src/Math/Trig.hpp | 4 | ||||
| -rw-r--r-- | src/World/BiomeType.hpp | 22 | ||||
| -rw-r--r-- | src/World/BlockType.hpp | 6 | ||||
| -rw-r--r-- | src/World/Chunk.cpp | 64 | ||||
| -rw-r--r-- | src/World/Chunk.hpp | 25 | ||||
| -rw-r--r-- | src/World/Generator.cpp | 314 | ||||
| -rw-r--r-- | src/World/Generator.hpp | 59 | ||||
| -rw-r--r-- | src/World/World.cpp | 12 | ||||
| -rw-r--r-- | src/World/World.hpp | 3 |
16 files changed, 9558 insertions, 1472 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index af96c71..61fa09b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -43,6 +43,8 @@ add_executable(meowcraft src/Math/Grid.cpp src/Math/Perlin.cpp src/Compute/Queue.hpp + src/Math/Constants.hpp + src/Math/Sigmoid.hpp ) target_link_libraries(meowcraft glfw GLEW::GLEW) diff --git a/assets/images/atlas.png b/assets/images/atlas.png index 1189fb6..b8b9dd7 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 3e5ca88..df8dce7 100644 --- a/assets/images/atlas.ppm +++ b/assets/images/atlas.ppm @@ -1,6 +1,6 @@ P3 # Meowcraft atlas.ppm -32 48 +64 64 255 129 151 @@ -101,6 +101,102 @@ P3 129 151 53 +129 +151 +53 +127 +149 +51 +109 +133 +36 +124 +147 +49 +124 +147 +49 +129 +151 +53 +129 +151 +53 +109 +133 +36 +129 +151 +53 +129 +151 +53 +129 +151 +53 +109 +133 +36 +129 +151 +53 +129 +151 +53 +129 +151 +53 +145 +140 +133 +118 +112 +104 +118 +112 +104 +145 +140 +133 +145 +140 +133 +145 +140 +133 +145 +140 +133 +145 +140 +133 +128 +122 +113 +118 +112 +104 +118 +112 +104 +125 +121 +113 +125 +121 +113 +136 +131 +123 +145 +140 +133 +145 +140 +133 +129 +151 +53 124 147 49 @@ -197,6 +293,102 @@ P3 129 151 53 +129 +151 +53 +113 +138 +40 +109 +133 +36 +113 +136 +39 +110 +133 +37 +124 +146 +48 +129 +151 +53 +109 +133 +36 +129 +151 +53 +129 +151 +53 +129 +151 +53 +109 +133 +36 +125 +148 +50 +129 +151 +53 +129 +151 +53 +145 +140 +133 +128 +122 +113 +118 +112 +104 +118 +112 +104 +128 +122 +113 +145 +140 +133 +145 +140 +133 +145 +140 +133 +145 +140 +133 +128 +122 +113 +128 +122 +113 +145 +140 +133 +145 +140 +133 +136 +131 +123 +136 +131 +123 +145 +140 +133 +129 +151 +53 124 147 49 @@ -290,6 +482,102 @@ P3 80 46 27 +129 +151 +53 +127 +149 +51 +111 +134 +38 +97 +122 +28 +113 +136 +38 +99 +123 +28 +107 +129 +35 +129 +151 +53 +109 +133 +36 +122 +146 +48 +128 +150 +52 +125 +148 +50 +128 +150 +52 +115 +138 +42 +121 +143 +45 +129 +151 +53 +145 +140 +133 +145 +140 +133 +145 +140 +133 +118 +112 +104 +118 +112 +104 +128 +122 +113 +145 +140 +133 +145 +140 +133 +145 +140 +133 +128 +122 +113 +128 +122 +113 +145 +140 +133 +145 +140 +133 +136 +131 +123 +136 +131 +123 +145 +140 +133 124 146 48 @@ -386,6 +674,102 @@ P3 93 54 35 +129 +151 +53 +129 +151 +53 +114 +137 +40 +95 +121 +27 +108 +132 +36 +65 +29 +15 +86 +109 +22 +119 +142 +45 +91 +115 +25 +102 +126 +32 +120 +142 +44 +109 +134 +36 +124 +146 +48 +88 +113 +23 +106 +131 +34 +129 +151 +53 +145 +140 +133 +157 +152 +144 +145 +140 +133 +145 +140 +133 +118 +112 +104 +118 +112 +104 +128 +122 +113 +136 +131 +123 +136 +131 +123 +136 +131 +123 +128 +122 +113 +128 +122 +113 +128 +122 +113 +136 +131 +123 +136 +131 +123 +145 +140 +133 123 146 48 @@ -485,6 +869,102 @@ P3 129 151 53 +123 +146 +48 +111 +135 +38 +79 +102 +17 +91 +117 +25 +65 +32 +18 +64 +89 +12 +85 +110 +21 +67 +92 +13 +93 +117 +27 +102 +126 +32 +97 +124 +28 +109 +134 +37 +85 +108 +21 +82 +108 +19 +125 +147 +49 +136 +131 +123 +157 +152 +144 +157 +152 +144 +145 +140 +133 +145 +140 +133 +118 +112 +104 +118 +112 +104 +136 +131 +123 +151 +146 +137 +157 +152 +144 +157 +152 +144 +145 +140 +133 +128 +122 +113 +128 +122 +113 +128 +122 +113 +136 +131 +123 +129 +151 +53 124 146 48 @@ -578,6 +1058,102 @@ P3 107 62 42 +123 +146 +48 +118 +141 +44 +101 +127 +33 +77 +102 +17 +51 +25 +11 +49 +23 +11 +62 +25 +14 +64 +90 +12 +37 +59 +3 +72 +97 +14 +74 +100 +15 +65 +32 +18 +88 +112 +22 +61 +86 +11 +74 +100 +15 +109 +133 +37 +136 +131 +123 +136 +131 +123 +145 +140 +133 +145 +140 +133 +145 +140 +133 +136 +131 +123 +118 +112 +104 +118 +112 +104 +136 +131 +123 +145 +140 +133 +157 +152 +144 +157 +152 +144 +145 +140 +133 +128 +122 +113 +128 +122 +113 +128 +122 +113 108 133 35 @@ -674,6 +1250,102 @@ P3 105 60 40 +100 +124 +30 +91 +115 +25 +80 +104 +19 +55 +27 +14 +56 +27 +14 +98 +54 +34 +95 +49 +32 +66 +28 +17 +79 +38 +21 +52 +23 +11 +42 +18 +7 +63 +30 +18 +63 +28 +16 +38 +58 +3 +77 +101 +17 +92 +118 +25 +128 +122 +113 +136 +131 +123 +136 +131 +123 +136 +131 +123 +136 +131 +123 +136 +131 +123 +128 +122 +113 +118 +112 +104 +118 +112 +104 +125 +121 +113 +145 +140 +133 +145 +140 +133 +145 +140 +133 +145 +140 +133 +145 +140 +133 +128 +122 +113 125 148 50 @@ -770,6 +1442,102 @@ P3 93 54 35 +83 +108 +20 +87 +112 +22 +64 +31 +17 +82 +45 +28 +87 +49 +31 +105 +60 +40 +105 +60 +40 +105 +60 +40 +105 +60 +40 +91 +52 +34 +78 +44 +26 +99 +55 +35 +87 +45 +26 +69 +35 +20 +84 +109 +21 +82 +107 +19 +128 +122 +113 +128 +122 +113 +136 +131 +123 +136 +131 +123 +136 +131 +123 +128 +122 +113 +157 +152 +144 +145 +140 +133 +128 +122 +113 +118 +112 +104 +125 +121 +113 +145 +140 +133 +145 +140 +133 +145 +140 +133 +145 +140 +133 +145 +140 +133 129 151 53 @@ -866,6 +1634,102 @@ P3 87 49 31 +55 +27 +13 +78 +38 +22 +97 +54 +34 +103 +58 +39 +93 +54 +35 +93 +54 +35 +105 +60 +40 +105 +60 +40 +93 +54 +35 +93 +54 +35 +105 +60 +40 +111 +66 +45 +109 +64 +43 +94 +50 +32 +65 +33 +19 +55 +25 +13 +145 +140 +133 +145 +140 +133 +128 +122 +113 +136 +131 +123 +136 +131 +123 +128 +122 +113 +157 +152 +144 +157 +152 +144 +145 +140 +133 +128 +122 +113 +118 +112 +104 +118 +112 +104 +136 +131 +123 +145 +140 +133 +145 +140 +133 +145 +140 +133 129 151 53 @@ -962,6 +1826,102 @@ P3 60 31 16 +72 +40 +22 +113 +67 +46 +117 +71 +50 +105 +60 +40 +93 +54 +35 +93 +54 +35 +93 +54 +35 +71 +38 +21 +91 +52 +34 +93 +54 +35 +109 +64 +44 +118 +72 +51 +105 +60 +40 +105 +60 +40 +93 +54 +35 +66 +35 +19 +145 +140 +133 +145 +140 +133 +145 +140 +133 +128 +122 +113 +136 +131 +123 +136 +131 +123 +145 +140 +133 +157 +152 +144 +157 +152 +144 +145 +140 +133 +128 +122 +113 +118 +112 +104 +118 +112 +104 +136 +131 +123 +145 +140 +133 +145 +140 +133 129 151 53 @@ -1058,6 +2018,102 @@ P3 66 35 19 +71 +38 +21 +100 +56 +37 +105 +60 +40 +95 +56 +37 +107 +62 +42 +105 +60 +40 +80 +46 +27 +66 +35 +19 +87 +49 +31 +93 +54 +35 +93 +54 +35 +105 +60 +40 +105 +60 +40 +105 +60 +40 +66 +35 +19 +66 +35 +19 +145 +140 +133 +145 +140 +133 +145 +140 +133 +128 +122 +113 +136 +131 +123 +136 +131 +123 +136 +131 +123 +145 +140 +133 +157 +152 +144 +157 +152 +144 +145 +140 +133 +145 +140 +133 +136 +131 +123 +128 +122 +113 +128 +122 +113 +128 +122 +113 129 151 53 @@ -1154,279 +2210,36 @@ P3 93 54 35 -109 -134 -36 -107 -132 -35 -124 -147 -49 -123 -146 -48 -100 -126 -31 -108 -132 -34 -107 -132 -34 -94 -119 -26 -91 -115 -25 -91 -115 -25 -88 -113 -22 -112 -137 -39 -117 -141 -43 -158 -184 -60 -117 -141 -43 -97 -123 -28 -81 -44 -27 -68 -36 -20 -117 71 -50 -118 -72 -51 -105 -60 -40 -105 -60 -40 -80 -46 -27 -68 -36 -20 -68 -36 -20 -79 -42 -25 -93 -54 -35 -93 -54 -35 -81 -44 -27 +38 +21 66 35 19 -93 -54 -35 -93 -54 -35 -123 -146 -48 -123 -146 -48 -123 -146 +80 +46 +27 +114 +69 48 -103 -129 -32 -113 -138 -40 114 -138 -40 -109 -134 -36 -124 -147 -49 -109 -134 -36 -107 -132 -35 -103 -129 -32 -102 -127 -31 -101 -127 -31 -101 -127 -31 -107 -132 -35 -107 -132 -35 -93 -54 -35 -84 -46 -28 -118 -72 -51 +69 +48 105 60 40 105 60 40 -93 -54 -35 -81 -44 -27 -79 -42 -25 -76 -43 -24 66 35 19 -66 -35 -19 -66 -35 -19 -66 -35 -19 -68 -36 -20 -105 -60 -40 -105 -60 -40 -129 -151 -53 -129 -151 -53 -125 -148 -50 -95 -121 +80 +43 26 -103 -128 -31 -129 -151 -53 -129 -151 -53 -124 -147 -49 -107 -132 -34 -129 -151 -53 -129 -151 -53 -109 -134 -36 -107 -132 -35 -107 -132 -35 -123 -146 -48 -129 -151 -53 -105 -60 -40 -79 -42 -25 -100 -56 -37 -105 -60 -40 -105 -60 -40 93 54 35 -79 -42 -25 -100 -56 -37 -118 -72 -51 -105 -60 -40 -76 -43 -24 93 54 35 @@ -1436,195 +2249,15 @@ P3 105 60 40 -117 -71 -50 -105 -60 -40 -129 -151 -53 -129 -151 -53 -119 -143 -44 -98 -124 -28 -128 -150 -52 -129 -151 -53 -129 -151 -53 -107 -132 -34 -107 -132 -34 -129 -151 -53 -129 -151 -53 -129 -151 -53 -107 -132 -34 -129 -151 -53 -129 -151 -53 -129 -151 -53 -105 -60 -40 66 35 19 -76 +80 43 -24 -93 -54 -35 -93 -54 -35 -88 -50 -32 -79 -42 -25 -105 -60 -40 -116 -71 -49 -105 -60 -40 -105 -60 -40 -93 -54 -35 +26 93 54 35 -105 -60 -40 -105 -60 -40 -105 -60 -40 -129 -151 -53 -129 -151 -53 -127 -149 -51 -109 -133 -36 -124 -147 -49 -124 -147 -49 -129 -151 -53 -129 -151 -53 -109 -133 -36 -129 -151 -53 -129 -151 -53 -129 -151 -53 -109 -133 -36 -129 -151 -53 -129 -151 -53 -129 -151 -53 -145 -140 -133 -118 -112 -104 -118 -112 -104 -145 -140 -133 -145 -140 -133 -145 -140 -133 -145 -140 -133 -145 -140 -133 -128 -122 -113 -118 -112 -104 -118 -112 -104 -125 -121 -113 -125 -121 -113 136 131 123 @@ -1634,807 +2267,102 @@ P3 145 140 133 -129 -151 -53 -129 -151 -53 -113 -138 -40 -109 -133 -36 -113 -136 -39 -110 -133 -37 -124 -146 -48 -129 -151 -53 -109 -133 -36 -129 -151 -53 -129 -151 -53 -129 -151 -53 -109 -133 -36 -125 -148 -50 -129 -151 -53 -129 -151 -53 -145 -140 -133 -128 -122 -113 -118 -112 -104 -118 -112 -104 -128 -122 -113 -145 -140 -133 -145 -140 -133 -145 -140 -133 -145 -140 -133 128 122 113 -128 -122 -113 -145 -140 -133 -145 -140 -133 136 131 123 136 131 123 -145 -140 -133 -129 -151 -53 -127 -149 -51 -111 -134 -38 -97 -122 -28 -113 -136 -38 -99 -123 -28 -107 -129 -35 -129 -151 -53 -109 -133 -36 -122 -146 -48 -128 -150 -52 -125 -148 -50 -128 -150 -52 -115 -138 -42 -121 -143 -45 -129 -151 -53 -145 -140 -133 -145 -140 -133 -145 -140 -133 -118 -112 -104 -118 -112 -104 -128 -122 -113 -145 -140 -133 -145 -140 -133 -145 -140 -133 -128 -122 -113 -128 -122 -113 -145 -140 -133 -145 -140 -133 136 131 123 136 131 123 -145 -140 -133 -129 -151 -53 -129 -151 -53 -114 -137 -40 -95 -121 -27 -108 -132 -36 -65 -29 -15 -86 -109 -22 -119 -142 -45 -91 -115 -25 -102 -126 -32 -120 -142 -44 -109 -134 -36 -124 -146 -48 -88 +128 +122 113 -23 -106 -131 -34 -129 -151 -53 145 140 133 -157 -152 -144 145 140 133 145 140 133 -118 -112 -104 -118 -112 -104 -128 -122 -113 136 131 123 136 131 123 -136 -131 -123 -128 -122 -113 128 122 113 128 122 113 -136 -131 -123 -136 -131 -123 -145 -140 -133 -129 -151 -53 -123 -146 -48 -111 -135 -38 -79 -102 -17 -91 -117 -25 -65 -32 -18 -64 -89 -12 -85 -110 -21 -67 -92 -13 -93 -117 -27 -102 -126 -32 -97 -124 -28 109 134 -37 -85 -108 -21 -82 -108 -19 -125 +36 +107 +132 +35 +124 147 49 -136 -131 -123 -157 -152 -144 -157 -152 -144 -145 -140 -133 -145 -140 -133 -118 -112 -104 -118 -112 -104 -136 -131 -123 -151 -146 -137 -157 -152 -144 -157 -152 -144 -145 -140 -133 -128 -122 -113 -128 -122 -113 -128 -122 -113 -136 -131 -123 123 146 48 -118 -141 -44 -101 -127 -33 -77 -102 -17 -51 -25 -11 -49 -23 -11 -62 -25 -14 -64 -90 -12 -37 -59 -3 -72 -97 -14 -74 -100 -15 -65 -32 -18 -88 -112 -22 -61 -86 -11 -74 100 -15 -109 -133 -37 -136 -131 -123 -136 -131 -123 -145 -140 -133 -145 -140 -133 -145 -140 -133 -136 -131 -123 -118 -112 -104 -118 -112 -104 -136 -131 -123 -145 -140 -133 -157 -152 -144 -157 -152 -144 -145 -140 -133 -128 -122 -113 -128 -122 -113 -128 -122 -113 -100 -124 -30 +126 +31 +108 +132 +34 +107 +132 +34 +94 +119 +26 91 115 25 -80 -104 -19 -55 -27 -14 -56 -27 -14 -98 -54 -34 -95 -49 -32 -66 -28 -17 -79 -38 -21 -52 -23 -11 -42 -18 -7 -63 -30 -18 -63 -28 -16 -38 -58 -3 -77 -101 -17 -92 -118 +91 +115 25 -128 -122 -113 -136 -131 -123 -136 -131 -123 -136 -131 -123 -136 -131 -123 -136 -131 -123 -128 -122 -113 -118 -112 -104 -118 -112 -104 -125 -121 -113 -145 -140 -133 -145 -140 -133 -145 -140 -133 -145 -140 -133 -145 -140 -133 -128 -122 +88 113 -83 -108 -20 -87 -112 22 -64 -31 -17 -82 -45 -28 -87 -49 -31 -105 -60 -40 -105 -60 -40 -105 -60 -40 -105 -60 -40 -91 -52 -34 -78 -44 -26 -99 -55 -35 -87 -45 -26 -69 -35 -20 -84 -109 -21 -82 -107 -19 -128 -122 -113 -128 -122 -113 -136 -131 -123 -136 -131 -123 -136 -131 -123 -128 -122 -113 -157 -152 -144 -145 -140 -133 -128 -122 -113 -118 112 -104 -125 -121 -113 -145 -140 -133 -145 -140 -133 -145 -140 -133 -145 -140 -133 -145 -140 -133 -55 -27 -13 -78 -38 -22 -97 -54 -34 -103 -58 +137 39 -93 -54 -35 -93 -54 -35 -105 -60 -40 -105 -60 -40 -93 -54 -35 -93 -54 -35 -105 +117 +141 +43 +158 +184 60 -40 -111 -66 -45 -109 -64 +117 +141 43 -94 -50 -32 -65 -33 -19 -55 -25 -13 -145 -140 -133 -145 -140 -133 -128 -122 -113 -136 -131 -123 -136 -131 -123 -128 -122 -113 -157 -152 -144 -157 -152 -144 -145 -140 -133 -128 -122 -113 -118 -112 -104 -118 -112 -104 -136 -131 +97 123 -145 -140 -133 -145 -140 -133 -145 -140 -133 -72 -40 -22 -113 -67 -46 +28 +81 +44 +27 +68 +36 +20 117 71 50 -105 -60 -40 -93 -54 -35 -93 -54 -35 -93 -54 -35 -71 -38 -21 -91 -52 -34 -93 -54 -35 -109 -64 -44 118 72 51 @@ -2444,252 +2372,36 @@ P3 105 60 40 -93 -54 -35 -66 -35 -19 -145 -140 -133 -145 -140 -133 -145 -140 -133 -128 -122 -113 -136 -131 -123 -136 -131 -123 -145 -140 -133 -157 -152 -144 -157 -152 -144 -145 -140 -133 -128 -122 -113 -118 -112 -104 -118 -112 -104 -136 -131 -123 -145 -140 -133 -145 -140 -133 -71 -38 -21 -100 -56 -37 -105 -60 -40 -95 -56 -37 -107 -62 -42 -105 -60 -40 80 46 27 -66 -35 -19 -87 -49 -31 +68 +36 +20 +68 +36 +20 +79 +42 +25 93 54 35 93 54 35 -105 -60 -40 -105 -60 -40 -105 -60 -40 -66 -35 -19 -66 -35 -19 -145 -140 -133 -145 -140 -133 -145 -140 -133 -128 -122 -113 -136 -131 -123 -136 -131 -123 -136 -131 -123 -145 -140 -133 -157 -152 -144 -157 -152 -144 -145 -140 -133 -145 -140 -133 -136 -131 -123 -128 -122 -113 -128 -122 -113 -128 -122 -113 -71 -38 -21 -66 -35 -19 -80 -46 +81 +44 27 -114 -69 -48 -114 -69 -48 -105 -60 -40 -105 -60 -40 66 35 19 -80 -43 -26 -93 -54 -35 93 54 35 93 54 35 -105 -60 -40 -66 -35 -19 -80 -43 -26 -93 -54 -35 -136 -131 -123 -145 -140 -133 -145 -140 -133 -128 -122 -113 -136 -131 -123 -136 -131 -123 -136 -131 -123 -136 -131 -123 -128 -122 -113 -145 -140 -133 -145 -140 -133 -145 -140 -133 -136 -131 -123 -136 -131 -123 -128 -122 -113 -128 -122 -113 81 44 27 @@ -2786,6 +2498,102 @@ P3 128 122 113 +123 +146 +48 +123 +146 +48 +123 +146 +48 +103 +129 +32 +113 +138 +40 +114 +138 +40 +109 +134 +36 +124 +147 +49 +109 +134 +36 +107 +132 +35 +103 +129 +32 +102 +127 +31 +101 +127 +31 +101 +127 +31 +107 +132 +35 +107 +132 +35 +93 +54 +35 +84 +46 +28 +118 +72 +51 +105 +60 +40 +105 +60 +40 +93 +54 +35 +81 +44 +27 +79 +42 +25 +76 +43 +24 +66 +35 +19 +66 +35 +19 +66 +35 +19 +66 +35 +19 +68 +36 +20 +105 +60 +40 +105 +60 +40 93 54 35 @@ -2882,6 +2690,102 @@ P3 128 122 113 +129 +151 +53 +129 +151 +53 +125 +148 +50 +95 +121 +26 +103 +128 +31 +129 +151 +53 +129 +151 +53 +124 +147 +49 +107 +132 +34 +129 +151 +53 +129 +151 +53 +109 +134 +36 +107 +132 +35 +107 +132 +35 +123 +146 +48 +129 +151 +53 +105 +60 +40 +79 +42 +25 +100 +56 +37 +105 +60 +40 +105 +60 +40 +93 +54 +35 +79 +42 +25 +100 +56 +37 +118 +72 +51 +105 +60 +40 +76 +43 +24 +93 +54 +35 +93 +54 +35 +105 +60 +40 +117 +71 +50 +105 +60 +40 105 60 40 @@ -2978,6 +2882,102 @@ P3 134 129 123 +129 +151 +53 +129 +151 +53 +119 +143 +44 +98 +124 +28 +128 +150 +52 +129 +151 +53 +129 +151 +53 +107 +132 +34 +107 +132 +34 +129 +151 +53 +129 +151 +53 +129 +151 +53 +107 +132 +34 +129 +151 +53 +129 +151 +53 +129 +151 +53 +105 +60 +40 +66 +35 +19 +76 +43 +24 +93 +54 +35 +93 +54 +35 +88 +50 +32 +79 +42 +25 +105 +60 +40 +116 +71 +49 +105 +60 +40 +105 +60 +40 +93 +54 +35 +93 +54 +35 +105 +60 +40 +105 +60 +40 +105 +60 +40 105 60 40 @@ -3170,6 +3170,102 @@ P3 93 191 225 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +225 +230 +236 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +236 +241 +247 +249 +250 +252 255 208 144 @@ -3266,6 +3362,102 @@ P3 120 232 236 +236 +241 +247 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +236 +241 +247 +249 +250 +252 255 208 144 @@ -3362,6 +3554,102 @@ P3 120 232 236 +249 +250 +252 +249 +250 +252 +236 +241 +247 +225 +230 +236 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +225 +230 +236 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +236 +241 +247 +249 +250 +252 +249 +250 +252 +236 +241 +247 +236 +241 +247 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +236 +241 +247 +225 +230 +236 251 199 142 @@ -3458,6 +3746,102 @@ P3 95 199 228 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +236 +241 +247 +225 +230 +236 +236 +241 +247 +236 +241 +247 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +225 +230 +236 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 251 199 142 @@ -3554,6 +3938,102 @@ P3 93 191 225 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +225 +230 +236 +225 +230 +236 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +225 +230 +236 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 251 199 142 @@ -3650,6 +4130,102 @@ P3 93 191 225 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +225 +230 +236 +225 +230 +236 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +236 +241 +247 +236 +241 +247 +225 +230 +236 +249 +250 +252 +249 +250 +252 251 199 142 @@ -3746,6 +4322,102 @@ P3 84 166 219 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +236 +241 +247 +249 +250 +252 +249 +250 +252 +225 +230 +236 +225 +230 +236 +55 +27 +14 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +236 +241 +247 +63 +28 +16 +236 +241 +247 +249 +250 +252 +249 +250 +252 251 199 142 @@ -3842,6 +4514,102 @@ P3 80 154 217 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +225 +230 +236 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +225 +230 +236 +225 +230 +236 +236 +241 +247 +236 +241 +247 +225 +230 +236 +64 +31 +17 +79 +42 +25 +80 +43 +26 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +225 +230 +236 +55 +25 +13 +87 +45 +26 +69 +35 +20 +225 +230 +236 +236 +241 +247 251 199 142 @@ -3938,6 +4706,102 @@ P3 88 177 223 +236 +241 +247 +236 +241 +247 +236 +241 +247 +236 +241 +247 +236 +241 +247 +225 +230 +236 +225 +230 +236 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +225 +230 +236 +55 +27 +13 +78 +38 +22 +97 +54 +34 +103 +58 +39 +93 +54 +35 +80 +43 +26 +236 +241 +247 +236 +241 +247 +225 +230 +236 +225 +230 +236 +55 +25 +13 +93 +54 +35 +93 +54 +35 +94 +50 +32 +65 +33 +19 +55 +25 +13 242 185 131 @@ -4034,6 +4898,102 @@ P3 90 184 225 +225 +230 +236 +249 +250 +252 +249 +250 +252 +225 +230 +236 +225 +230 +236 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +72 +40 +22 +113 +67 +46 +117 +71 +50 +105 +60 +40 +93 +54 +35 +93 +54 +35 +80 +43 +26 +66 +35 +19 +55 +25 +13 +55 +25 +13 +118 +72 +51 +118 +72 +51 +105 +60 +40 +105 +60 +40 +93 +54 +35 +66 +35 +19 242 185 131 @@ -4130,6 +5090,102 @@ P3 112 213 232 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +236 +241 +247 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +71 +38 +21 +100 +56 +37 +105 +60 +40 +95 +56 +37 +107 +62 +42 +105 +60 +40 +80 +46 +27 +66 +35 +19 +87 +49 +31 +93 +54 +35 +93 +54 +35 +105 +60 +40 +105 +60 +40 +105 +60 +40 +66 +35 +19 +66 +35 +19 255 224 152 @@ -4226,6 +5282,102 @@ P3 120 232 236 +236 +241 +247 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +225 +230 +236 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +71 +38 +21 +66 +35 +19 +80 +46 +27 +114 +69 +48 +114 +69 +48 +105 +60 +40 +105 +60 +40 +66 +35 +19 +80 +43 +26 +93 +54 +35 +93 +54 +35 +93 +54 +35 +105 +60 +40 +66 +35 +19 +80 +43 +26 +93 +54 +35 255 224 152 @@ -4322,6 +5474,102 @@ P3 93 191 225 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +225 +230 +236 +249 +250 +252 +236 +241 +247 +236 +241 +247 +236 +241 +247 +236 +241 +247 +249 +250 +252 +225 +230 +236 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +81 +44 +27 +68 +36 +20 +117 +71 +50 +118 +72 +51 +105 +60 +40 +105 +60 +40 +80 +46 +27 +68 +36 +20 +68 +36 +20 +79 +42 +25 +93 +54 +35 +93 +54 +35 +81 +44 +27 +66 +35 +19 +93 +54 +35 +93 +54 +35 251 199 142 @@ -4418,6 +5666,102 @@ P3 112 217 232 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +236 +241 +247 +225 +230 +236 +93 +54 +35 +84 +46 +28 +118 +72 +51 +105 +60 +40 +105 +60 +40 +93 +54 +35 +81 +44 +27 +79 +42 +25 +76 +43 +24 +66 +35 +19 +66 +35 +19 +66 +35 +19 +66 +35 +19 +68 +36 +20 +105 +60 +40 +105 +60 +40 255 216 148 @@ -4514,6 +5858,102 @@ P3 112 217 232 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +236 +241 +247 +105 +60 +40 +79 +42 +25 +100 +56 +37 +105 +60 +40 +105 +60 +40 +93 +54 +35 +79 +42 +25 +100 +56 +37 +118 +72 +51 +105 +60 +40 +76 +43 +24 +93 +54 +35 +93 +54 +35 +105 +60 +40 +117 +71 +50 +105 +60 +40 255 216 148 @@ -4610,3 +6050,6243 @@ P3 90 184 223 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +249 +250 +252 +236 +241 +247 +105 +60 +40 +66 +35 +19 +76 +43 +24 +93 +54 +35 +93 +54 +35 +88 +50 +32 +79 +42 +25 +105 +60 +40 +116 +71 +49 +105 +60 +40 +105 +60 +40 +93 +54 +35 +93 +54 +35 +105 +60 +40 +105 +60 +40 +105 +60 +40 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 +192 +0 +255 diff --git a/src/Math/Common.hpp b/src/Math/Common.hpp index 94840b1..1ea75f2 100644 --- a/src/Math/Common.hpp +++ b/src/Math/Common.hpp @@ -3,4 +3,5 @@ #include "Vector.hpp" #include "Matrix.hpp" #include "Rotation.hpp" -#include "Trig.hpp" \ No newline at end of file +#include "Trig.hpp" +#include "Constants.hpp" \ No newline at end of file diff --git a/src/Math/Constants.hpp b/src/Math/Constants.hpp new file mode 100644 index 0000000..9c62e94 --- /dev/null +++ b/src/Math/Constants.hpp @@ -0,0 +1,8 @@ +#pragma once + +namespace Math { + +constexpr double PI = 3.14159265358979323846; +constexpr double E = 2.71828182845904523536; + +} \ No newline at end of file diff --git a/src/Math/Perlin.hpp b/src/Math/Perlin.hpp index c31697b..17d33fd 100644 --- a/src/Math/Perlin.hpp +++ b/src/Math/Perlin.hpp @@ -16,6 +16,7 @@ struct Noise { uint octaves = 3; float persistence = 0.3f; + float lacunarity = 2.0f; float at(Vector<D> pos) const { float result = 0; @@ -27,7 +28,7 @@ struct Noise { result += raw((pos + offset).abs() / scale * frequency) * amplitude; max += amplitude; - frequency *= 2; + frequency *= lacunarity; amplitude *= persistence; } diff --git a/src/Math/Sigmoid.hpp b/src/Math/Sigmoid.hpp new file mode 100644 index 0000000..f2fa009 --- /dev/null +++ b/src/Math/Sigmoid.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include <cmath> +#include "Constants.hpp" + +namespace Math { + +template <typename T> +T sigmoid(T x) { + return 1 / (1 + std::pow(E, -x)); +} + +} diff --git a/src/Math/Trig.hpp b/src/Math/Trig.hpp index c64e2f2..2a415f5 100644 --- a/src/Math/Trig.hpp +++ b/src/Math/Trig.hpp @@ -1,8 +1,8 @@ #pragma once -namespace Math { +#include "Constants.hpp" -constexpr double PI = 3.14159265358979323846; +namespace Math { template<typename T> T radians(T degrees) { diff --git a/src/World/BiomeType.hpp b/src/World/BiomeType.hpp index 026b3ef..2e3d8c6 100644 --- a/src/World/BiomeType.hpp +++ b/src/World/BiomeType.hpp @@ -8,34 +8,32 @@ namespace MC::World { class BiomeType { public: enum Value : uint8_t { - Forest, Plains, + Forest, + Alpine, Desert, + Jungle, + Beach, + River, Ocean, }; - static constexpr const size_t Size = 4; + static constexpr uint8_t Size = Ocean + 1; - BiomeType() = default; - BiomeType(Value biome) : m_biome(biome) {} + BiomeType() : m_biome(Plains) {} + BiomeType(const Value biome) : m_biome(biome) {} operator Value() const { return m_biome; } static std::vector<BiomeType> all() { - return { - Plains, Forest, Desert, Ocean - }; + return { Plains, Forest, Alpine, Desert, Jungle, Beach, River, Ocean }; } static std::vector<BiomeType> all_ground() { - return { - Plains, Forest, Desert - }; + return { Plains, Forest, Alpine, Desert, Jungle, Beach }; } private: - - Value m_biome; }; diff --git a/src/World/BlockType.hpp b/src/World/BlockType.hpp index 65afe0d..dcb8e44 100644 --- a/src/World/BlockType.hpp +++ b/src/World/BlockType.hpp @@ -13,12 +13,13 @@ public: Grass, Stone, Sand, + Snow, Water, }; - static constexpr const size_t Size = 6; + static constexpr uint8_t Size = Water + 1; - BlockType() = default; + BlockType() : m_block(Air) {} BlockType(Value block) : m_block(block) {} operator Value() const { return m_block; } @@ -30,6 +31,7 @@ public: Grass, Stone, Sand, + Snow, Water, }; } diff --git a/src/World/Chunk.cpp b/src/World/Chunk.cpp index 1874950..9642fa9 100644 --- a/src/World/Chunk.cpp +++ b/src/World/Chunk.cpp @@ -4,11 +4,11 @@ namespace MC::World { void Chunk::set(uint32_t x, uint32_t y, uint32_t z, BlockData data) { - m_blocks[pos(x, y, z)] = data; + m_blocks.at(pos(x, y, z)) = data; } -Chunk::BlockData Chunk::get(uint32_t x, uint32_t y, uint32_t z) { - return m_blocks[pos(x, y, z)]; +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() { @@ -17,9 +17,9 @@ GFX::Mesh Chunk::mesh() { std::vector<Vector<2>> tex_coords{}; std::vector<uint32_t> indices{}; - for (int x = 0; x < Chunk::Width; x++) { - for (int y = 0; y < Chunk::Height; y++) { - for (int z = 0; z < Chunk::Width; z++) { + 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; @@ -31,8 +31,8 @@ GFX::Mesh Chunk::mesh() { } auto side_positions = side.face(); - auto side_normals = Chunk::face_normals(side); - auto side_tex_coords = Chunk::face_tex_coords(type, side); + 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)}; @@ -87,9 +87,9 @@ bool Chunk::is_face_visible(uint32_t x, uint32_t y, uint32_t z, BlockSide side) }; if ( - neighbor_pos.x() >= Chunk::Width || neighbor_pos.x() < 0 || - neighbor_pos.y() >= Chunk::Height || neighbor_pos.y() < 0 || - neighbor_pos.z() >= Chunk::Width || neighbor_pos.z() < 0 + 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; } @@ -103,8 +103,8 @@ bool Chunk::is_face_visible(uint32_t x, uint32_t y, uint32_t z, BlockSide side) } std::array<Vector<2>, 4> Chunk::face_tex_coords(BlockType type, BlockSide side) { - uint8_t atlas_width = 2; - uint8_t atlas_height = 3; + uint8_t atlas_width = 4; + uint8_t atlas_height = 4; float width_step = 1.0f / atlas_width; float height_step = 1.0f / atlas_height; @@ -125,22 +125,34 @@ std::array<Vector<2>, 4> Chunk::face_tex_coords(BlockType type, BlockSide side) 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(0, 1); - case BlockSide::Top: - return block_coords(0, 0); - case BlockSide::Bottom: - return block_coords(1, 0); + 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(1, 1); + return block_coords(3, 0); case BlockType::Sand: - return block_coords(0, 2); + return block_coords(0, 1); case BlockType::Water: - return block_coords(1, 2); + 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 {}; } @@ -159,7 +171,7 @@ std::array<Vector<3>, 4> Chunk::face_normals(BlockSide side) { } uint64_t Chunk::pos(uint32_t x, uint32_t y, uint32_t z) { - return x + Chunk::Width * y + Chunk::Width * Chunk::Height * z; + return x + Width * y + Width * Height * z; } } diff --git a/src/World/Chunk.hpp b/src/World/Chunk.hpp index 2b0379c..d200039 100644 --- a/src/World/Chunk.hpp +++ b/src/World/Chunk.hpp @@ -1,29 +1,36 @@ #pragma once #include <cstdint> -#include <optional> +#include "BiomeType.hpp" #include "BlockType.hpp" #include "../GFX/Mesh.hpp" #include "BlockSide.hpp" -#include "../GFX/Binder.hpp" namespace MC::World { class Chunk { public: - static constexpr const uint32_t Width = 16; - static constexpr const uint32_t Height = 128; + static constexpr uint32_t Width = 16; + static constexpr uint32_t Height = 128; Chunk(int64_t x, int64_t y) - : m_blocks{Chunk::Width * Chunk::Height * Chunk::Width, {BlockType::Air}}, - m_position{(float)x * Chunk::Width, 0.0f, (float)y * Chunk::Width} {}; + : m_blocks{Width * Height * Width, {BlockType::Air}}, + m_position{(float)x * Width, 0.0f, (float)y * Width} {} struct BlockData { BlockType type; }; - void set(uint32_t x, uint32_t y, uint32_t z, BlockData type); - BlockData get(uint32_t x, uint32_t y, uint32_t z); + 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; + + struct Details { + Matrix<Width, Width> landmass_values{}; + Matrix<Width, Width> hill_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(); @@ -37,6 +44,8 @@ private: Vector<3> m_position; std::vector<BlockData> m_blocks; + + Details m_details; }; } diff --git a/src/World/Generator.cpp b/src/World/Generator.cpp index e8b3bbd..f528278 100644 --- a/src/World/Generator.cpp +++ b/src/World/Generator.cpp @@ -1,30 +1,320 @@ #include "Generator.hpp" -#include "../Math/Perlin.hpp" +#include "../Math/Interpolation.hpp" +#include "../Math/Sigmoid.hpp" namespace MC::World { Chunk Generator::generate(int64_t chunk_x, int64_t chunk_y) { Chunk chunk(chunk_x, chunk_y); - Math::Perlin::Noise<3> noise{.scale=20.0f, .octaves=2}; + auto landmass_map = generate_landmass_map(chunk_x, 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 terrain_map = generate_terrain(height_map, chunk_x, chunk_y); + + decorate_soil(chunk, biome_map, terrain_map); + + chunk.set_details({{landmass_map.map}, {hill_map.map}, {biome_map.map}}); + + return chunk; +} + +Generator::ChunkMap2D<float> Generator::generate_landmass_map(int64_t chunk_x, int64_t chunk_y) { + ChunkMap2D<float> landmass_map{}; + + for (uint x = 0; x < Chunk::Width; x++) { + for (uint y = 0; y < Chunk::Width; y++) { + landmass_map.set(x, y, get_landmass(chunk_position_to_world_vector(chunk_x, chunk_y, x, y))); + } + } + + return landmass_map; +} + +Generator::ChunkMap2D<float> Generator::generate_hill_map(int64_t chunk_x, int64_t chunk_y) { + ChunkMap2D<float> hill_map{}; + + for (uint x = 0; x < Chunk::Width; x++) { + for (uint y = 0; y < Chunk::Width; y++) { + hill_map.set(x, y, get_hill(chunk_position_to_world_vector(chunk_x, chunk_y, x, y))); + } + } + + return hill_map; +} + +Generator::ChunkMap2D<float> Generator::generate_height_map(ChunkMap2D<float>& landmass_map, ChunkMap2D<float>& hill_map, int64_t chunk_x, int64_t chunk_y) { + ChunkMap2D<float> height_map{}; for (uint x = 0; x < Chunk::Width; x++) { + for (uint y = 0; y < Chunk::Width; y++) { + auto landmass_effect = landmass_map.get(x, y); + auto hill_effect = hill_map.get(x, y); + + auto hill = hill_effect * landmass_effect * 1.4 - 0.4; + auto landmass = landmass_effect * 0.6 + 0.4; + + auto height = (hill + landmass) / 2.0f; + + height_map.set(x, y, height); + } + } + + return height_map; +} + +Generator::ChunkMap2D<BiomeType> Generator::generate_biome_map(ChunkMap2D<float>& landmass_map, ChunkMap2D<float>& hill_map, ChunkMap2D<float>& height_map, int64_t chunk_x, int64_t chunk_y) { + ChunkMap2D<BiomeType> biome_map{}; + + for (uint x = 0; x < Chunk::Width; x++) { + for (uint y = 0; y < Chunk::Width; y++) { + float landmass = landmass_map.get(x, y); + float hill = hill_map.get(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); + + HillSlice hill_slice; + if (hill > 0.9) { hill_slice = HillSlice::Mountain; } + else if (hill > 0.33) { hill_slice = HillSlice::Middle; } + else { hill_slice = HillSlice::Valley; } + + LandmassSlice landmass_slice; + if (landmass > 0.8) { landmass_slice = LandmassSlice::Land; } + else if (landmass > 0.45) { landmass_slice = LandmassSlice::Beach; } + 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; } + else { temparature_zone = TemperatureZone::Cold; } + + HumidityZone humidity_zone; + if (humidity > 0.66) { humidity_zone = HumidityZone::Wet; } + else if (humidity > 0.33) { humidity_zone = HumidityZone::Temperate; } + else { humidity_zone = HumidityZone::Dry; } + + auto biome = lookup_biome(hill_slice, landmass_slice, temparature_zone, humidity_zone); + biome_map.set(x, y, biome); + } + } + + return biome_map; +} + +Generator::ChunkMap3D<bool> Generator::generate_terrain(ChunkMap2D<float>& height_map, int64_t chunk_x, int64_t chunk_y) { + float jaggedness = 0.10f; + + ChunkMap3D<bool> terrain_map{}; + for (uint x = 0; x < Chunk::Width; x++) { for (uint z = 0; z < Chunk::Width; z++) { + auto height = height_map.get(x, z); + for (uint y = 0; y < Chunk::Height; y++) { - auto value = noise.at({ - (float)(chunk_x * Chunk::Width + x), - (float)y, - (float)(chunk_y * Chunk::Width + z), - }); - - if (value > 0.6f && value < 0.7f) { - chunk.set(x, y, z, {BlockType::Stone}); + float density = get_density({Chunk::Width * chunk_x + (float)x, (float)y, Chunk::Width * chunk_y + (float)z}); + float threshold = Math::sigmoid(((float)y / (Chunk::Height * height * 2) - 0.5f) / jaggedness); + + if (density > threshold) { + terrain_map.set(x, y, z, true); } } } } - return chunk; + return terrain_map; } -} \ No newline at end of file +void Generator::decorate_soil(Chunk& chunk, ChunkMap2D<BiomeType>& biome_map, ChunkMap3D<bool>& terrain_map) { + constexpr uint dirt_depth = 4; + constexpr uint water_height = 39; + + for (uint x = 0; x < Chunk::Width; x++) { + for (uint z = 0; z < Chunk::Width; z++) { + auto biome = biome_map.get(x, z); + + BlockType top_block{}; + BlockType soil_block{}; + switch (biome) { + case BiomeType::Beach: + case BiomeType::Desert: + top_block = BlockType::Sand; + soil_block = BlockType::Sand; + break; + case BiomeType::Jungle: + case BiomeType::Forest: + case BiomeType::Plains: + case BiomeType::River: + case BiomeType::Ocean: + top_block = BlockType::Grass; + soil_block = BlockType::Dirt; + break; + case BiomeType::Alpine: + top_block = BlockType::Snow; + soil_block = BlockType::Dirt; + break; + } + + auto column_depth = 0; + for (uint y = Chunk::Height - 1; y > 0; y--) { + auto block = terrain_map.get(x, y, z); + if (block) { + if (column_depth == 0 && y >= water_height - 1) { + chunk.set(x, y, z, {top_block}); + } else if (column_depth < dirt_depth) { + chunk.set(x, y, z, {soil_block}); + } else { + chunk.set(x, y, z, {BlockType::Stone}); + } + column_depth++; + } else { + if (y < water_height) { + chunk.set(x, y, z, {BlockType::Water}); + } + column_depth = 0; + } + } + } + } +} + +#define CURVE_START(y) constexpr auto lerp = Math::linear_interpolation; float _py = y; float _px = 0.0f; +#define CURVE_POINT(x, y) if (v < x) return lerp({_py, y}, _px, x, v); _py = y; _px = x +#define CURVE_END(y) return lerp({_py, y}, _px, 1.0f, v); + +float Generator::get_landmass(Vector<2> pos) const { + auto v = m_landmass_noise.at(pos); + + CURVE_START(1.0f); + CURVE_POINT(0.1f, 0.8f); + CURVE_POINT(0.3f, 0.8f); + CURVE_POINT(0.37f, 0.125f); + CURVE_POINT(0.4f, 0.4f); + CURVE_POINT(0.46f, 0.45f); + CURVE_POINT(0.47f, 0.875f); + CURVE_POINT(0.48f, 0.9f); + CURVE_POINT(0.55f, 0.95f); + CURVE_END(1.0f); +} + +float Generator::get_hill(Vector<2> pos) const { + auto v = m_hill_noise.at(pos); + + CURVE_START(0.33f); + CURVE_POINT(0.25f, 1.0f); + + CURVE_POINT(0.49f, 0.1f); + CURVE_POINT(0.5f, 0.0f); + CURVE_POINT(0.51f, 0.1f); + + CURVE_POINT(0.75f, 1.0f); + CURVE_END(0.33f); +} + +float Generator::get_humidity(Vector<2> pos) const { + auto v = m_humidity_noise.at(pos); + return v; +} + +float Generator::get_temperature(Vector<2> pos) const { + auto v = m_temperature_noise.at(pos); + return v; +} + +float Generator::get_density(Vector<3> pos) const { + auto v = m_density_noise.at(pos); + return v; +} + +Vector<2> Generator::chunk_position_to_world_vector(int64_t chunk_x, int64_t chunk_y, uint x, uint y) { + return {(float)x + chunk_x * Chunk::Width, (float)y + chunk_y * Chunk::Width}; +} + +std::array<BiomeType, Generator::biome_lookup_table_size> Generator::create_biome_lookup_table() { + std::array<BiomeType, biome_lookup_table_size> table{}; + + auto inc = [](auto& x) { x = (std::remove_reference_t<decltype(x)>)((uint)x + 1); }; + auto cmp = [](auto x, auto s) { return (uint)x < (uint)s; }; + + for (HillSlice hill_slice{}; cmp(hill_slice, HillSliceSize); inc(hill_slice)) { + for (LandmassSlice landmass_slice{}; cmp(landmass_slice, LandmassSliceSize); inc(landmass_slice)) { + for (TemperatureZone temperature_zone{}; cmp(temperature_zone, TemperatureZoneSize); inc(temperature_zone)) { + for (HumidityZone humidity_zone{}; cmp(humidity_zone, HumidityZoneSize); inc(humidity_zone)) { + BiomeType biome{}; + if (landmass_slice == LandmassSlice::Ocean) { + biome = BiomeType::Ocean; + goto set; + } + if (landmass_slice == LandmassSlice::Beach) { + biome = BiomeType::Beach; + goto set; + } + + if (hill_slice == HillSlice::Valley) { + biome = BiomeType::River; + goto set; + } + if (hill_slice == HillSlice::Mountain) { + if (temperature_zone == TemperatureZone::Hot) { + biome = BiomeType::Desert; + } else { + biome = BiomeType::Alpine; + } + goto set; + } + + switch (temperature_zone) { + case TemperatureZone::Hot: + biome = BiomeType::Desert; + break; + case TemperatureZone::Fair: + switch (humidity_zone) { + case HumidityZone::Wet: + biome = BiomeType::Jungle; + break; + case HumidityZone::Lush: + biome = BiomeType::Forest; + break; + case HumidityZone::Temperate: + case HumidityZone::Dry: + biome = BiomeType::Plains; + break; + } + break; + case TemperatureZone::Cold: + switch (humidity_zone) { + case HumidityZone::Wet: + case HumidityZone::Lush: + biome = BiomeType::Alpine; + break; + case HumidityZone::Temperate: + case HumidityZone::Dry: + biome = BiomeType::Plains; + break; + } + break; + } + + set: + table[biome_lookup_table_index(hill_slice, landmass_slice, temperature_zone, humidity_zone)] = biome; + } + } + } + } + + return table; +} + +size_t Generator::biome_lookup_table_index(HillSlice hill_slice, LandmassSlice landmass_slice, TemperatureZone temperature_zone, HumidityZone humidity_zone) { + auto hs = (uint8_t)hill_slice; auto ls = (uint8_t)landmass_slice; auto tz = (uint8_t)temperature_zone; auto hz = (uint8_t)humidity_zone; + auto LS_S = (uint8_t)LandmassSliceSize; auto TZ_S = (uint8_t)TemperatureZoneSize; auto HZ_S = (uint8_t)HumidityZoneSize; + return (hs * LS_S * TZ_S * HZ_S) + (ls * TZ_S * HZ_S) + (tz * HZ_S) + hz; +} + +BiomeType Generator::lookup_biome(HillSlice hill_slice, LandmassSlice landmass_slice, TemperatureZone temperature_zone, HumidityZone humidity_zone) { + return biome_lookup_table.at(biome_lookup_table_index(hill_slice, landmass_slice, temperature_zone, humidity_zone)); +} + +} diff --git a/src/World/Generator.hpp b/src/World/Generator.hpp index afe43c6..523136a 100644 --- a/src/World/Generator.hpp +++ b/src/World/Generator.hpp @@ -3,6 +3,7 @@ #include <cstdint> #include "Chunk.hpp" #include "BiomeType.hpp" +#include "../Math/Perlin.hpp" namespace MC::World { @@ -10,6 +11,64 @@ class Generator { public: Generator() = default; Chunk generate(int64_t chunk_x, int64_t chunk_y); +private: + template <typename V> + struct ChunkMap2D { + V map[Chunk::Width * Chunk::Width]; + void set(uint x, uint y, V v) { map[x * Chunk::Width + y] = v; } + V get(uint x, uint y) { return map[x * Chunk::Width + y]; } + }; + + template <typename V> + struct ChunkMap3D { + V map[Chunk::Width * Chunk::Width * Chunk::Height]; + void set(uint x, uint y, uint z, V v) { map[pos(x, y, z)] = v; } + V get(uint x, uint y, uint z) { return map[pos(x, y, z)]; } + static uint pos(uint x, uint y, uint z) { return x + Chunk::Width * y + Chunk::Width * Chunk::Height * z; } + }; + + ChunkMap2D<float> generate_landmass_map(int64_t chunk_x, int64_t chunk_y); + ChunkMap2D<float> generate_hill_map(int64_t chunk_x, int64_t chunk_y); + ChunkMap2D<float> generate_height_map(ChunkMap2D<float>& landmass_map, ChunkMap2D<float>& hill_map, int64_t chunk_x, int64_t chunk_y); + + ChunkMap2D<BiomeType> generate_biome_map(ChunkMap2D<float>& landmass_map, ChunkMap2D<float>& hill_map, ChunkMap2D<float>& height_map, int64_t chunk_x, int64_t chunk_y); + + ChunkMap3D<bool> generate_terrain(ChunkMap2D<float>& height_map, int64_t chunk_x, int64_t chunk_y); + + void decorate_soil(Chunk& chunk, ChunkMap2D<BiomeType>& biome_map, ChunkMap3D<bool>& terrain_map); + + [[nodiscard]] float get_landmass(Vector<2> pos) const; + [[nodiscard]] float get_hill(Vector<2> pos) const; + + [[nodiscard]] float get_humidity(Vector<2> pos) const; + [[nodiscard]] float get_temperature(Vector<2> pos) const; + + [[nodiscard]] float get_density(Vector<3> pos) const; + + static Vector<2> chunk_position_to_world_vector(int64_t chunk_x, int64_t chunk_y, uint x, uint y); + + 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<3> m_density_noise{.scale=30.0f, .octaves=2, .persistence=0.7f, .lacunarity=2.0f}; + + enum class HillSlice { Mountain, Middle, Valley }; + enum class LandmassSlice { Land, Beach, Ocean }; + enum class TemperatureZone { Hot, Fair, Cold }; + enum class HumidityZone { Wet, Lush, Temperate, Dry }; + static constexpr uint HillSliceSize = (uint)HillSlice::Valley + 1; + static constexpr uint LandmassSliceSize = (uint)LandmassSlice::Ocean + 1; + static constexpr uint TemperatureZoneSize = (uint)TemperatureZone::Cold + 1; + static constexpr uint HumidityZoneSize = (uint)HumidityZone::Dry + 1; + + static constexpr size_t biome_lookup_table_size = (size_t)HillSliceSize * (size_t)LandmassSliceSize * (size_t)TemperatureZoneSize * (size_t)HumidityZoneSize; + static std::array<BiomeType, biome_lookup_table_size> create_biome_lookup_table(); + static size_t biome_lookup_table_index(HillSlice hill_slice, LandmassSlice landmass_slice, TemperatureZone temperature_zone, HumidityZone humidity_zone); + static BiomeType lookup_biome(HillSlice hill_slice, LandmassSlice landmass_slice, TemperatureZone temperature_zone, HumidityZone humidity_zone); + static inline std::array<BiomeType, biome_lookup_table_size> biome_lookup_table = create_biome_lookup_table(); }; } diff --git a/src/World/World.cpp b/src/World/World.cpp index 9d88af3..03ce60e 100644 --- a/src/World/World.cpp +++ b/src/World/World.cpp @@ -19,7 +19,7 @@ std::vector<World::ChunkData> World::get_visible_chunks(Vector<3> position) { m_visible_chunks = visible_chunks; } - std::vector<World::ChunkData> chunks{}; + std::vector<ChunkData> chunks{}; chunks.reserve(visible_chunks.size()); for (auto index : visible_chunks) { auto& data = get(index); @@ -31,6 +31,16 @@ std::vector<World::ChunkData> World::get_visible_chunks(Vector<3> position) { return chunks; } +Chunk* World::get_chunk_for_positon(Vector<3> position) { + int32_t x = std::round(position.x() / Chunk::Width); + int32_t y = std::round(position.z() / Chunk::Width); + auto& data = get({x, y}); + if (data.chunk.has_value()) { + return &data.chunk.value(); + } + return nullptr; +} + void World::process_chunk_visibility_updates(std::unordered_set<ChunkIndex>& new_chunks, Vector<3> player) { for (auto new_index: new_chunks) { auto& data = get(new_index); diff --git a/src/World/World.hpp b/src/World/World.hpp index d842600..a5f73ec 100644 --- a/src/World/World.hpp +++ b/src/World/World.hpp @@ -3,9 +3,9 @@ #include <memory> #include <unordered_map> #include <unordered_set> -#include <utility> #include "Generator.hpp" #include "ChunkIndex.hpp" +#include "../GFX/Binder.hpp" #include "../Compute/Queue.hpp" namespace MC::World { @@ -28,6 +28,7 @@ public: }; std::vector<ChunkData> get_visible_chunks(Vector<3> position); + Chunk* get_chunk_for_positon(Vector<3> position); private: std::unordered_set<ChunkIndex> get_visible_chunk_indices(Vector<3> position) const; std::unordered_set<ChunkIndex> load_finished_chunks_from_queue(); |
