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 }