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.world.mesh.utils; 7 8 import voxelman.math; 9 import voxelman.geometry.cube; 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.world.storage.arraycopy; 55 import voxelman.geometry.box; 56 57 immutable short[6] sideIndexOffsets = [ 58 -EXTENDED_CHUNK_SIZE, // zneg 59 EXTENDED_CHUNK_SIZE, // zpos 60 1, // xpos 61 -1, // xneg 62 EXTENDED_CHUNK_SIZE_SQR, // ypos 63 -EXTENDED_CHUNK_SIZE_SQR, // yneg 64 ]; 65 private alias sio = sideIndexOffsets; 66 67 immutable short[27] sideIndexOffsets27 = [ 68 // 6 adjacent 69 sio[CubeSide.zneg], // zneg 70 sio[CubeSide.zpos], // zpos 71 sio[CubeSide.xpos], // xpos 72 sio[CubeSide.xneg], // xneg 73 sio[CubeSide.ypos], // ypos 74 sio[CubeSide.yneg], // yneg 75 76 // bottom 8 77 sio[CubeSide.xneg] + sio[CubeSide.yneg] + sio[CubeSide.zneg], // xneg_yneg_zneg 78 sio[CubeSide.yneg] + sio[CubeSide.zneg], // yneg_zneg 79 sio[CubeSide.xpos] + sio[CubeSide.yneg] + sio[CubeSide.zneg], // xpos_yneg_zneg 80 sio[CubeSide.xneg] + sio[CubeSide.yneg] , // xneg_yneg 81 sio[CubeSide.xpos] + sio[CubeSide.yneg] , // xpos_yneg 82 sio[CubeSide.xneg] + sio[CubeSide.yneg] + sio[CubeSide.zpos], // xneg_yneg_zpos 83 sio[CubeSide.yneg] + sio[CubeSide.zpos], // yneg_zpos 84 sio[CubeSide.xpos] + sio[CubeSide.yneg] + sio[CubeSide.zpos], // xpos_yneg_zpos 85 86 // middle 4 87 sio[CubeSide.xneg] + sio[CubeSide.zneg], // xneg_zneg [-1, 0,-1] 88 sio[CubeSide.xpos] + sio[CubeSide.zneg], // xpos_zneg [ 1, 0,-1] 89 sio[CubeSide.xneg] + sio[CubeSide.zpos], // xneg_zpos [-1, 0, 1] 90 sio[CubeSide.xpos] + sio[CubeSide.zpos], // xpos_zpos [ 1, 0, 1] 91 92 // top 8 93 sio[CubeSide.xneg] + sio[CubeSide.ypos] + sio[CubeSide.zneg], // xneg_ypos_zneg [-1, 1,-1] 94 sio[CubeSide.ypos] + sio[CubeSide.zneg], // ypos_zneg [ 0, 1,-1] 95 sio[CubeSide.xpos] + sio[CubeSide.ypos] + sio[CubeSide.zneg], // xpos_ypos_zneg [ 1, 1,-1] 96 sio[CubeSide.xneg] + sio[CubeSide.ypos] , // xneg_ypos [-1, 1, 0] 97 sio[CubeSide.xpos] + sio[CubeSide.ypos] , // xpos_ypos [ 1, 1, 0] 98 sio[CubeSide.xneg] + sio[CubeSide.ypos] + sio[CubeSide.zpos], // xneg_ypos_zpos [-1, 1, 1] 99 sio[CubeSide.ypos] + sio[CubeSide.zpos], // ypos_zpos [ 0, 1, 1] 100 sio[CubeSide.xpos] + sio[CubeSide.ypos] + sio[CubeSide.zpos], // xpos_ypos_zpos [ 1, 1, 1] 101 102 0 // central 103 ]; 104 private alias sio27 = sideIndexOffsets27; 105 106 // on sides top points in ypos dir 107 enum FaceSide : ubyte { 108 top, // zneg dir on horizontal faces (top and bottom) 109 left, 110 bottom, 111 right 112 } 113 114 // for each cube side 115 // 8 index offsets 116 // first four are offsets to 4 adjacent sides, next 4 are for corner 117 // 4 0 7 118 // 1 3 119 // 5 2 6 120 static immutable short[8][6] faceSideIndexOffset = [ 121 /*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 122 /*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 123 /*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 124 /*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 125 126 /*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 127 /*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 128 ]; 129 130 // maps block side to map of 12 corner ids. 3 corners of adjacent cubes for each face corner. 131 // each corner is a corner of cube adjacent to given face (one of 6 sides). Those cube corners will affect AO of face corners. 132 // 1 | 0 11 | 10 133 // --+-------+---- 134 // 2 |* *| 9 135 // | | 136 // 3 |* *| 8 137 // --+-------+---- 138 // 4 | 5 6 | 7 139 // those correspond to 4 face corners (marked as * above) 140 // 0--3 // corner numbering of face verticies 141 // | | 142 // 1--2 143 // where cube corners are from CubeCorner 144 145 static immutable ubyte[12][6] faceSideCorners = [ 146 [3, 2, 6, 2, 6, 7, 6, 7, 3, 7, 3, 2], // zneg 147 [0, 1, 5, 1, 5, 4, 5, 4, 0, 4, 0, 1], // zpos 148 [2, 0, 4, 0, 4, 6, 4, 6, 2, 6, 2, 0], // xpos 149 [1, 3, 7, 3, 7, 5, 7, 5, 1, 5, 1, 3], // xneg 150 [2, 3, 1, 3, 1, 0, 1, 0, 2, 0, 2, 3], // ypos 151 [7, 6, 4, 6, 4, 5, 4, 5, 7, 5, 7, 6], // yneg 152 ]; 153 154 // maps block side to map of 12 corner ids. 3 corners of adjacent cubes for each face corner. 155 // each corner is a corner of cube adjacent to given face (one of 6 sides). Those cube corners will affect AO of face corners. 156 // 2 | 1 15 | 14 157 // --+-------+---- 158 // 3 | 0 12 | 13 159 // | | 160 // 5 | 4 8 | 11 161 // --+-------+---- 162 // 6 | 7 9 | 10 163 // those correspond to 4 face corners (marked as * above) 164 // 0--3 // corner numbering of face verticies 165 // | | 166 // 1--2 167 // where cube corners are from CubeCorner 168 169 static immutable ubyte[16][6] faceSideCorners4 = [ 170 [7,3,2,6, 3,2,6,7, 2,6,7,3, 6,7,3,2], // zneg 171 [4,0,1,5, 0,1,5,4, 1,5,4,0, 5,4,0,1], // zpos 172 [6,2,0,4, 2,0,4,6, 0,4,6,2, 1,6,2,0], // xpos 173 [5,1,3,7, 1,3,7,5, 3,7,5,1, 7,5,1,3], // xneg 174 [0,2,3,1, 2,3,1,0, 3,1,0,2, 1,0,2,3], // ypos 175 [5,7,6,4, 7,6,4,5, 6,4,5,7, 4,5,7,6], // yneg 176 ];