1 /** 2 Copyright: Copyright (c) 2016-2017 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 module voxelman.geometry.cube; 7 8 enum CubeSide : ubyte 9 { 10 zneg = 0, 11 zpos = 1, 12 13 xpos = 2, 14 xneg = 3, 15 16 ypos = 4, 17 yneg = 5, 18 } 19 20 enum SideMask : ubyte 21 { 22 zneg = 0b_00_0001, 23 zpos = 0b_00_0010, 24 25 xpos = 0b_00_0100, 26 xneg = 0b_00_1000, 27 28 ypos = 0b_01_0000, 29 yneg = 0b_10_0000, 30 } 31 32 enum CubeCorner : ubyte 33 { 34 xneg_yneg_zneg, 35 xpos_yneg_zneg, 36 xneg_yneg_zpos, 37 xpos_yneg_zpos, 38 39 xneg_ypos_zneg, 40 xpos_ypos_zneg, 41 xneg_ypos_zpos, 42 xpos_ypos_zpos, 43 } 44 45 // In the same order as CubeSide, sideOffsets26 46 enum Dir27 : ubyte 47 { 48 // 6 adjacent 49 zneg, // [ 0, 0,-1] 50 zpos, // [ 0, 0, 1] 51 xpos, // [ 1, 0, 0] 52 xneg, // [-1, 0, 0] 53 ypos, // [ 0, 1, 0] 54 yneg, // [ 0,-1, 0] 55 56 // bottom 8 57 xneg_yneg_zneg, // [-1,-1,-1] 58 yneg_zneg, // [ 0,-1,-1] 59 xpos_yneg_zneg, // [ 1,-1,-1] 60 xneg_yneg , // [-1,-1, 0] 61 xpos_yneg , // [ 1,-1, 0] 62 xneg_yneg_zpos, // [-1,-1, 1] 63 yneg_zpos, // [ 0,-1, 1] 64 xpos_yneg_zpos, // [ 1,-1, 1] 65 66 // middle 4 67 xneg_zneg, // [-1, 0,-1] 68 xpos_zneg, // [ 1, 0,-1] 69 xneg_zpos, // [-1, 0, 1] 70 xpos_zpos, // [ 1, 0, 1] 71 72 // top 8 73 xneg_ypos_zneg, // [-1, 1,-1] 74 ypos_zneg, // [ 0, 1,-1] 75 xpos_ypos_zneg, // [ 1, 1,-1] 76 xneg_ypos , // [-1, 1, 0] 77 xpos_ypos , // [ 1, 1, 0] 78 xneg_ypos_zpos, // [-1, 1, 1] 79 ypos_zpos, // [ 0, 1, 1] 80 xpos_ypos_zpos, // [ 1, 1, 1] 81 82 central 83 } 84 85 immutable Dir27[27] dirs3by3 = [ 86 // bottom 9 87 Dir27.xneg_yneg_zneg, // [-1,-1,-1] 88 Dir27.yneg_zneg , // [ 0,-1,-1] 89 Dir27.xpos_yneg_zneg, // [ 1,-1,-1] 90 91 Dir27.xneg_yneg , // [-1,-1, 0] 92 Dir27. yneg , // [ 0,-1, 0] 93 Dir27.xpos_yneg , // [ 1,-1, 0] 94 95 Dir27.xneg_yneg_zpos, // [-1,-1, 1] 96 Dir27. yneg_zpos, // [ 0,-1, 1] 97 Dir27.xpos_yneg_zpos, // [ 1,-1, 1] 98 99 // middle 9 100 Dir27.xneg_zneg , // [-1, 0,-1] 101 Dir27. zneg, // [ 0, 0,-1] 102 Dir27.xpos_zneg , // [ 1, 0,-1] 103 104 Dir27.xneg , // [-1, 0, 0] 105 Dir27. central , // [ 0, 0, 0] 106 Dir27.xpos , // [ 1, 0, 0] 107 108 Dir27.xneg_zpos , // [-1, 0, 1] 109 Dir27. zpos, // [ 0, 0, 1] 110 Dir27.xpos_zpos , // [ 1, 0, 1] 111 112 // top 9 113 Dir27.xneg_ypos_zneg, // [-1, 1,-1] 114 Dir27. ypos_zneg, // [ 0, 1,-1] 115 Dir27.xpos_ypos_zneg, // [ 1, 1,-1] 116 117 Dir27.xneg_ypos , // [-1, 1, 0] 118 Dir27. ypos , // [ 0, 1, 0] 119 Dir27.xpos_ypos , // [ 1, 1, 0] 120 121 Dir27.xneg_ypos_zpos, // [-1, 1, 1] 122 Dir27. ypos_zpos, // [ 0, 1, 1] 123 Dir27.xpos_ypos_zpos, // [ 1, 1, 1] 124 ]; 125 126 immutable CubeSide[6] oppSide = [ 127 CubeSide.zpos, 128 CubeSide.zneg, 129 CubeSide.xneg, 130 CubeSide.xpos, 131 CubeSide.yneg, 132 CubeSide.ypos]; 133 134 template sideOffsets(size_t numAdjacent) { 135 static if (numAdjacent == 6) 136 alias sideOffsets = sideOffsets6; 137 else static if (numAdjacent == 26) 138 alias sideOffsets = sideOffsets26; 139 } 140 141 // does not include center 142 immutable byte[3][26] sideOffsets26 = [ 143 // 6 adjacent 144 [ 0, 0,-1], 145 [ 0, 0, 1], 146 [ 1, 0, 0], 147 [-1, 0, 0], 148 [ 0, 1, 0], 149 [ 0,-1, 0], 150 151 // bottom 8 152 [-1,-1,-1], 153 [ 0,-1,-1], 154 [ 1,-1,-1], 155 [-1,-1, 0], 156 [ 1,-1, 0], 157 [-1,-1, 1], 158 [ 0,-1, 1], 159 [ 1,-1, 1], 160 161 // middle 4 162 [-1, 0,-1], 163 [ 1, 0,-1], 164 [-1, 0, 1], 165 [ 1, 0, 1], 166 167 // top 8 168 [-1, 1,-1], 169 [ 0, 1,-1], 170 [ 1, 1,-1], 171 [-1, 1, 0], 172 [ 1, 1, 0], 173 [-1, 1, 1], 174 [ 0, 1, 1], 175 [ 1, 1, 1], 176 ]; 177 178 immutable byte[3][27] offsets3by3 = [ 179 // bottom 9 180 [-1,-1,-1], 181 [ 0,-1,-1], 182 [ 1,-1,-1], 183 184 [-1,-1, 0], 185 [ 0,-1, 0], 186 [ 1,-1, 0], 187 188 [-1,-1, 1], 189 [ 0,-1, 1], 190 [ 1,-1, 1], 191 192 // middle 9 193 [-1, 0,-1], 194 [ 0, 0,-1], 195 [ 1, 0,-1], 196 197 [-1, 0, 0], 198 [ 0, 0, 0], 199 [ 1, 0, 0], 200 201 [-1, 0, 1], 202 [ 0, 0, 1], 203 [ 1, 0, 1], 204 205 // top 9 206 [-1, 1,-1], 207 [ 0, 1,-1], 208 [ 1, 1,-1], 209 210 [-1, 1, 0], 211 [ 0, 1, 0], 212 [ 1, 1, 0], 213 214 [-1, 1, 1], 215 [ 0, 1, 1], 216 [ 1, 1, 1], 217 ]; 218 219 // does not include center and other 20 adjacent 220 immutable byte[3][6] sideOffsets6 = sideOffsets26[0..6]; 221 immutable byte[3][20] sideOffsets20 = sideOffsets26[6..26]; 222 223 // mesh for single block 224 immutable ubyte[18 * 6] cubeFaces = 225 [ 226 1, 0, 0, // triangle 1 : begin // zneg 227 0, 1, 0, 228 1, 1, 0, // triangle 1 : end 229 1, 0, 0, // triangle 2 : begin 230 0, 0, 0, 231 0, 1, 0, // triangle 2 : end 232 233 0, 0, 1, // zpos 234 1, 1, 1, 235 0, 1, 1, 236 0, 0, 1, 237 1, 0, 1, 238 1, 1, 1, 239 240 1, 0, 1, // xpos 241 1, 1, 0, 242 1, 1, 1, 243 1, 0, 1, 244 1, 0, 0, 245 1, 1, 0, 246 247 0, 0, 0, // xneg 248 0, 1, 1, 249 0, 1, 0, 250 0, 0, 0, 251 0, 0, 1, 252 0, 1, 1, 253 254 0, 1, 1, // ypos 255 1, 1, 0, 256 0, 1, 0, 257 0, 1, 1, 258 1, 1, 1, 259 1, 1, 0, 260 261 1, 0, 1, // yneg 262 0, 0, 0, 263 1, 0, 0, 264 1, 0, 1, 265 0, 0, 1, 266 0, 0, 0, 267 ]; 268 269 immutable ubyte[6] faceCornerIndexes = [1, 3, 0, 1, 2, 3]; 270 immutable ubyte[6] flippedFaceCornerIndexes = [1, 2, 0, 0, 2, 3]; 271 272 // the "Y" of 1 and 3 vertex are inversed 273 immutable ubyte[18 * 6] flippedCubeFaces = 274 [ 275 1, 0, 0, // triangle 1 : begin // zneg 276 0, 0, 0, 277 1, 1, 0, // triangle 1 : end 278 1, 1, 0, // triangle 2 : begin 279 0, 0, 0, 280 0, 1, 0, // triangle 2 : end 281 282 0, 0, 1, // zpos 283 1, 0, 1, 284 0, 1, 1, 285 0, 1, 1, 286 1, 0, 1, 287 1, 1, 1, 288 289 1, 0, 1, // xpos 290 1, 0, 0, 291 1, 1, 1, 292 1, 1, 1, 293 1, 0, 0, 294 1, 1, 0, 295 296 0, 0, 0, // xneg 297 0, 0, 1, 298 0, 1, 0, 299 0, 1, 0, 300 0, 0, 1, 301 0, 1, 1, 302 303 0, 1, 1, // ypos 304 1, 1, 1, 305 0, 1, 0, 306 0, 1, 0, 307 1, 1, 1, 308 1, 1, 0, 309 310 1, 0, 1, // yneg 311 0, 0, 1, 312 1, 0, 0, 313 1, 0, 0, 314 0, 0, 1, 315 0, 0, 0, 316 ]; 317 318 immutable ubyte[3][8] cubeVerticies = [ 319 [0,0,0], // 0 320 [1,0,0], // 1 321 [0,0,1], // 2 322 [1,0,1], // 3 323 [0,1,0], // 4 324 [1,1,0], // 5 325 [0,1,1], // 6 326 [1,1,1], // 7 327 ]; 328 329 // 6 sides by 4 indices per side 330 immutable ubyte[4][6] cubeSideVertIndices = [ 331 [5,1,0,4], // zneg 332 [6,2,3,7], // zpos 333 [7,3,1,5], // xpos 334 [4,0,2,6], // xneg 335 [4,6,7,5], // ypos 336 [1,3,2,0], // yneg 337 ];