1 /** 2 Copyright: Copyright (c) 2015-2016 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 module voxelman.storage.coordinates; 7 8 import voxelman.core.config; 9 import voxelman.storage.region; 10 import voxelman.storage.utils; 11 import voxelman.utils.math; 12 13 struct BlockChunkIndex 14 { 15 this(BlockChunkPos blockChunkPos) 16 { 17 index = cast(ushort)(blockChunkPos.x + 18 blockChunkPos.y * CHUNK_SIZE_SQR + 19 blockChunkPos.z * CHUNK_SIZE); 20 } 21 22 this(BlockWorldPos blockWorldPos) 23 { 24 this(BlockChunkPos(blockWorldPos)); 25 } 26 27 this(ushort index) 28 { 29 this.index = index; 30 } 31 32 this(int x, int y, int z) 33 { 34 index = cast(ushort)(x + y * CHUNK_SIZE_SQR + z * CHUNK_SIZE); 35 } 36 37 ushort index; 38 39 size_t getIndex() @property { return index; } 40 alias getIndex this; 41 } 42 43 // Position of block in world space. -int.max..int.max 44 struct BlockWorldPos 45 { 46 this(ivec3 blockWorldPos) 47 { 48 vector = blockWorldPos; 49 } 50 51 this(vec3 blockWorldPos) 52 { 53 vector = blockWorldPos; 54 } 55 56 ivec3 vector; 57 auto opDispatch(string s)() 58 { 59 return mixin("vector." ~ s); 60 } 61 } 62 63 static assert(!is(typeof({ 64 ChunkRegionPos vector = ChunkRegionPos(BlockWorldPos()); 65 }))); 66 static assert(!is(typeof({ 67 ChunkRegionPos vector = BlockWorldPos(); 68 }))); 69 static assert(!is(typeof({ 70 BlockWorldPos vector = BlockWorldPos(BlockWorldPos()); 71 }))); 72 73 // Position of block in chunk space. 0..ChunkSize 74 struct BlockChunkPos 75 { 76 this(BlockWorldPos blockWorldPos) 77 { 78 vector.x = blockWorldPos.x % CHUNK_SIZE; 79 vector.y = blockWorldPos.y % CHUNK_SIZE; 80 vector.z = blockWorldPos.z % CHUNK_SIZE; 81 if (vector.x < 0) vector.x += CHUNK_SIZE; 82 if (vector.y < 0) vector.y += CHUNK_SIZE; 83 if (vector.z < 0) vector.z += CHUNK_SIZE; 84 } 85 86 this(ivec3 blockWorldPos) 87 { 88 vector = blockWorldPos; 89 } 90 91 ivec3 vector; 92 auto opDispatch(string s)() 93 { 94 return mixin("vector." ~ s); 95 } 96 } 97 98 struct ChunkRegionIndex 99 { 100 this(ChunkRegionPos chunkRegionPos) 101 { 102 index = chunkRegionPos.x + 103 chunkRegionPos.y * REGION_SIZE + 104 chunkRegionPos.z * REGION_SIZE_SQR; 105 } 106 107 size_t index; 108 109 size_t getIndex() @property { return index; } 110 alias getIndex this; 111 } 112 113 // Position of chunk in world space. -int.max..int.max 114 struct ChunkWorldPos 115 { 116 this(BlockWorldPos blockWorldPos) 117 { 118 vector = ivec3( 119 floor(cast(float)blockWorldPos.x / CHUNK_SIZE), 120 floor(cast(float)blockWorldPos.y / CHUNK_SIZE), 121 floor(cast(float)blockWorldPos.z / CHUNK_SIZE),); 122 } 123 124 this(ivec3 blockWorldPos) 125 { 126 vector = blockWorldPos; 127 } 128 129 ivec3 vector; 130 auto opDispatch(string s)() 131 { 132 return mixin("vector." ~ s); 133 } 134 } 135 136 // Position of chunk in region space. 0..RegionSize 137 struct ChunkRegionPos 138 { 139 this(ChunkWorldPos chunkWorldPos) 140 { 141 vector.x = chunkWorldPos.x % REGION_SIZE; 142 vector.y = chunkWorldPos.y % REGION_SIZE; 143 vector.z = chunkWorldPos.z % REGION_SIZE; 144 if (vector.x < 0) vector.x += REGION_SIZE; 145 if (vector.y < 0) vector.y += REGION_SIZE; 146 if (vector.z < 0) vector.z += REGION_SIZE; 147 } 148 149 this(ivec3 blockWorldPos) 150 { 151 vector = blockWorldPos; 152 } 153 154 ivec3 vector; 155 auto opDispatch(string s)() 156 { 157 return mixin("vector." ~ s); 158 } 159 } 160 161 // Position of region in world space. -int.max..int.max 162 struct RegionWorldPos 163 { 164 this(ChunkWorldPos chunkWorldPos) 165 { 166 vector = ivec3( 167 floor(cast(float)chunkWorldPos.x / REGION_SIZE), 168 floor(cast(float)chunkWorldPos.y / REGION_SIZE), 169 floor(cast(float)chunkWorldPos.z / REGION_SIZE),); 170 } 171 172 this(ivec3 blockWorldPos) 173 { 174 vector = blockWorldPos; 175 } 176 177 ivec3 vector; 178 auto opDispatch(string s)() 179 { 180 return mixin("vector." ~ s); 181 } 182 }