1 /** 2 Copyright: Copyright (c) 2016-2018 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 module voxelman.world.mesh.utils; 7 8 import voxelman.math; 9 import voxelman.geometry; 10 import voxelman.core.config; 11 import voxelman.world.block; 12 13 enum EXTENDED_CHUNK_SIZE = CHUNK_SIZE + 2; 14 enum EXTENDED_CHUNK_SIZE_SQR = EXTENDED_CHUNK_SIZE * EXTENDED_CHUNK_SIZE; 15 enum EXTENDED_CHUNK_SIZE_CUBE = EXTENDED_CHUNK_SIZE * EXTENDED_CHUNK_SIZE * EXTENDED_CHUNK_SIZE; 16 enum EXTENDED_SIZE_VECTOR = ivec3(EXTENDED_CHUNK_SIZE, EXTENDED_CHUNK_SIZE, EXTENDED_CHUNK_SIZE); 17 18 size_t extendedChunkIndex(int x, int y, int z) { 19 return x + y * EXTENDED_CHUNK_SIZE_SQR + z * EXTENDED_CHUNK_SIZE; 20 } 21 22 size_t chunkFromExtIndex(size_t index) 23 { 24 int x = index % EXTENDED_CHUNK_SIZE; 25 int y = (index / EXTENDED_CHUNK_SIZE_SQR) % EXTENDED_CHUNK_SIZE; 26 int z = (index / EXTENDED_CHUNK_SIZE) % EXTENDED_CHUNK_SIZE; 27 28 ubyte cx = target_chunk[x]; 29 ubyte cy = target_chunk[y]; 30 ubyte cz = target_chunk[z]; 31 32 return dirs3by3[cx + cz * 3 + cy * 9]; 33 } 34 35 ChunkAndBlockAt chunkAndBlockAt27FromExt(ushort index) 36 { 37 int x = index % EXTENDED_CHUNK_SIZE; 38 int y = (index / EXTENDED_CHUNK_SIZE_SQR) % EXTENDED_CHUNK_SIZE; 39 int z = (index / EXTENDED_CHUNK_SIZE) % EXTENDED_CHUNK_SIZE; 40 41 ubyte bx = position_in_target_chunk[x]; 42 ubyte by = position_in_target_chunk[y]; 43 ubyte bz = position_in_target_chunk[z]; 44 45 ubyte cx = target_chunk[x]; 46 ubyte cy = target_chunk[y]; 47 ubyte cz = target_chunk[z]; 48 49 ubyte chunk_index = dirs3by3[cx + cz * 3 + cy * 9]; 50 51 return ChunkAndBlockAt(chunk_index, bx, by, bz); 52 } 53 54 import voxelman.algorithm.arraycopy3d; 55 56 immutable short[6] sideIndexOffsets = [ 57 -EXTENDED_CHUNK_SIZE, // zneg 58 EXTENDED_CHUNK_SIZE, // zpos 59 1, // xpos 60 -1, // xneg 61 EXTENDED_CHUNK_SIZE_SQR, // ypos 62 -EXTENDED_CHUNK_SIZE_SQR, // yneg 63 ]; 64 private alias sio = sideIndexOffsets; 65 66 immutable short[27] sideIndexOffsets27 = [ 67 // 6 adjacent 68 sio[CubeSide.zneg], // zneg 69 sio[CubeSide.zpos], // zpos 70 sio[CubeSide.xpos], // xpos 71 sio[CubeSide.xneg], // xneg 72 sio[CubeSide.ypos], // ypos 73 sio[CubeSide.yneg], // yneg 74 75 // bottom 8 76 sio[CubeSide.xneg] + sio[CubeSide.yneg] + sio[CubeSide.zneg], // xneg_yneg_zneg 77 sio[CubeSide.yneg] + sio[CubeSide.zneg], // yneg_zneg 78 sio[CubeSide.xpos] + sio[CubeSide.yneg] + sio[CubeSide.zneg], // xpos_yneg_zneg 79 sio[CubeSide.xneg] + sio[CubeSide.yneg] , // xneg_yneg 80 sio[CubeSide.xpos] + sio[CubeSide.yneg] , // xpos_yneg 81 sio[CubeSide.xneg] + sio[CubeSide.yneg] + sio[CubeSide.zpos], // xneg_yneg_zpos 82 sio[CubeSide.yneg] + sio[CubeSide.zpos], // yneg_zpos 83 sio[CubeSide.xpos] + sio[CubeSide.yneg] + sio[CubeSide.zpos], // xpos_yneg_zpos 84 85 // middle 4 86 sio[CubeSide.xneg] + sio[CubeSide.zneg], // xneg_zneg [-1, 0,-1] 87 sio[CubeSide.xpos] + sio[CubeSide.zneg], // xpos_zneg [ 1, 0,-1] 88 sio[CubeSide.xneg] + sio[CubeSide.zpos], // xneg_zpos [-1, 0, 1] 89 sio[CubeSide.xpos] + sio[CubeSide.zpos], // xpos_zpos [ 1, 0, 1] 90 91 // top 8 92 sio[CubeSide.xneg] + sio[CubeSide.ypos] + sio[CubeSide.zneg], // xneg_ypos_zneg [-1, 1,-1] 93 sio[CubeSide.ypos] + sio[CubeSide.zneg], // ypos_zneg [ 0, 1,-1] 94 sio[CubeSide.xpos] + sio[CubeSide.ypos] + sio[CubeSide.zneg], // xpos_ypos_zneg [ 1, 1,-1] 95 sio[CubeSide.xneg] + sio[CubeSide.ypos] , // xneg_ypos [-1, 1, 0] 96 sio[CubeSide.xpos] + sio[CubeSide.ypos] , // xpos_ypos [ 1, 1, 0] 97 sio[CubeSide.xneg] + sio[CubeSide.ypos] + sio[CubeSide.zpos], // xneg_ypos_zpos [-1, 1, 1] 98 sio[CubeSide.ypos] + sio[CubeSide.zpos], // ypos_zpos [ 0, 1, 1] 99 sio[CubeSide.xpos] + sio[CubeSide.ypos] + sio[CubeSide.zpos], // xpos_ypos_zpos [ 1, 1, 1] 100 101 0 // central 102 ]; 103 private alias sio27 = sideIndexOffsets27; 104 105 // on sides top points in ypos dir 106 enum FaceSide : ubyte { 107 top, // zneg dir on horizontal faces (top and bottom) 108 left, 109 bottom, 110 right 111 } 112 113 FaceSide[4] oppFaceSides = [ 114 FaceSide.bottom, 115 FaceSide.right, 116 FaceSide.top, 117 FaceSide.left, 118 ]; 119 120 // for each cube side 121 // 8 index offsets 122 // first four are offsets to 4 adjacent sides, next 4 are for corner 123 // 4 0 7 124 // 1 3 125 // 5 2 6 126 static immutable short[8][6] faceSideIndexOffset = [ 127 /*0-3*/ [sio27[Dir27.ypos], sio27[Dir27.xpos], sio27[Dir27.yneg], sio27[Dir27.xneg], /*4-7*/ sio27[Dir27.xpos_ypos], sio27[Dir27.xpos_yneg], sio27[Dir27.xneg_yneg], sio27[Dir27.xneg_ypos]], // zneg 128 /*0-3*/ [sio27[Dir27.ypos], sio27[Dir27.xneg], sio27[Dir27.yneg], sio27[Dir27.xpos], /*4-7*/ sio27[Dir27.xneg_ypos], sio27[Dir27.xneg_yneg], sio27[Dir27.xpos_yneg], sio27[Dir27.xpos_ypos]], // zpos 129 /*0-3*/ [sio27[Dir27.ypos], sio27[Dir27.zpos], sio27[Dir27.yneg], sio27[Dir27.zneg], /*4-7*/ sio27[Dir27.ypos_zpos], sio27[Dir27.yneg_zpos], sio27[Dir27.yneg_zneg], sio27[Dir27.ypos_zneg]], // xpos 130 /*0-3*/ [sio27[Dir27.ypos], sio27[Dir27.zneg], sio27[Dir27.yneg], sio27[Dir27.zpos], /*4-7*/ sio27[Dir27.ypos_zneg], sio27[Dir27.yneg_zneg], sio27[Dir27.yneg_zpos], sio27[Dir27.ypos_zpos]], // xneg 131 132 /*0-3*/ [sio27[Dir27.zneg], sio27[Dir27.xneg], sio27[Dir27.zpos], sio27[Dir27.xpos], /*4-7*/ sio27[Dir27.xneg_zneg], sio27[Dir27.xneg_zpos], sio27[Dir27.xpos_zpos], sio27[Dir27.xpos_zneg]], // ypos 133 /*0-3*/ [sio27[Dir27.zneg], sio27[Dir27.xpos], sio27[Dir27.zpos], sio27[Dir27.xneg], /*4-7*/ sio27[Dir27.xpos_zneg], sio27[Dir27.xpos_zpos], sio27[Dir27.xneg_zpos], sio27[Dir27.xneg_zneg]], // yneg 134 ]; 135 136 // maps block side to map of 12 corner ids. 3 corners of adjacent cubes for each face corner. 137 // each corner is a corner of cube adjacent to given face (one of 6 sides). Those cube corners will affect AO of face corners. 138 // 1 | 0 11 | 10 139 // --+-------+---- 140 // 2 |* *| 9 141 // | | 142 // 3 |* *| 8 143 // --+-------+---- 144 // 4 | 5 6 | 7 145 // those correspond to 4 face corners (marked as * above) 146 // 0--3 // corner numbering of face verticies 147 // | | 148 // 1--2 149 // where cube corners are from CubeCorner 150 151 static immutable ubyte[12][6] faceSideCorners = [ 152 [3, 2, 6, 2, 6, 7, 6, 7, 3, 7, 3, 2], // zneg 153 [0, 1, 5, 1, 5, 4, 5, 4, 0, 4, 0, 1], // zpos 154 [2, 0, 4, 0, 4, 6, 4, 6, 2, 6, 2, 0], // xpos 155 [1, 3, 7, 3, 7, 5, 7, 5, 1, 5, 1, 3], // xneg 156 [2, 3, 1, 3, 1, 0, 1, 0, 2, 0, 2, 3], // ypos 157 [7, 6, 4, 6, 4, 5, 4, 5, 7, 5, 7, 6], // yneg 158 ]; 159 160 // maps block side to map of 12 corner ids. 3 corners of adjacent cubes for each face corner. 161 // each corner is a corner of cube adjacent to given face (one of 6 sides). Those cube corners will affect AO of face corners. 162 // 2 | 1 15 | 14 163 // --+-------+---- 164 // 3 | 0 12 | 13 165 // | | 166 // 5 | 4 8 | 11 167 // --+-------+---- 168 // 6 | 7 9 | 10 169 // those correspond to 4 face corners (marked as * above) 170 // 0--3 // corner numbering of face verticies 171 // | | 172 // 1--2 173 // where cube corners are from CubeCorner 174 175 static immutable ubyte[16][6] faceSideCorners4 = [ 176 [7,3,2,6, 3,2,6,7, 2,6,7,3, 6,7,3,2], // zneg 177 [4,0,1,5, 0,1,5,4, 1,5,4,0, 5,4,0,1], // zpos 178 [6,2,0,4, 2,0,4,6, 0,4,6,2, 1,6,2,0], // xpos 179 [5,1,3,7, 1,3,7,5, 3,7,5,1, 7,5,1,3], // xneg 180 [0,2,3,1, 2,3,1,0, 3,1,0,2, 1,0,2,3], // ypos 181 [5,7,6,4, 7,6,4,5, 6,4,5,7, 4,5,7,6], // yneg 182 ];