1 /**
2 Copyright: Copyright (c) 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.extendedchunk;
7 
8 import voxelman.math;
9 import voxelman.geometry.cube;
10 import voxelman.geometry.box;
11 import voxelman.core.config;
12 import voxelman.world.mesh.utils;
13 import voxelman.world.storage;
14 
15 void setExtendedArray(
16 	BlockId[] dest,
17 	ivec3 destPos,
18 	ChunkLayerItem source,
19 	Box sourceBox)
20 {
21 	if (source.isUniform)
22 		setSubArray(dest, EXTENDED_SIZE_VECTOR, Box(destPos, sourceBox.size), source.getUniform!BlockId);
23 	else
24 		setSubArray(dest, EXTENDED_SIZE_VECTOR, destPos, source.getArray!BlockId, CHUNK_SIZE_VECTOR, sourceBox);
25 }
26 
27 struct ExtendedChunk
28 {
29 	BlockId[EXTENDED_CHUNK_SIZE_CUBE] allBlocks = void;
30 
31 	// fill extended chunk with blocks from 27 chunks
32 	void create(ref ChunkLayerItem[27] blockLayers)
33 	{
34 		enum LAST_POS = CHUNK_SIZE - 1;
35 		enum EX_LAST_POS = EXTENDED_CHUNK_SIZE - 1;
36 
37 		// bottom 9
38 		allBlocks[extendedChunkIndex(0, 0, 0)] = blockLayers[dirs3by3[0]].getBlockId(LAST_POS, LAST_POS, LAST_POS);
39 		allBlocks.setExtendedArray(ivec3(1, 0, 0), blockLayers[dirs3by3[1]], Box(ivec3(0, LAST_POS, LAST_POS), ivec3(CHUNK_SIZE, 1, 1)));
40 		allBlocks[extendedChunkIndex(EX_LAST_POS, 0, 0)] = blockLayers[dirs3by3[2]].getBlockId(0, LAST_POS, LAST_POS);
41 		allBlocks.setExtendedArray(ivec3(0, 0, 1), blockLayers[dirs3by3[3]], Box(ivec3(LAST_POS, LAST_POS, 0), ivec3(1, 1, CHUNK_SIZE)));
42 		allBlocks.setExtendedArray(ivec3(1, 0, 1), blockLayers[dirs3by3[4]], Box(ivec3(0, LAST_POS, 0), ivec3(CHUNK_SIZE, 1, CHUNK_SIZE)));
43 		allBlocks.setExtendedArray(ivec3(EX_LAST_POS, 0, 1), blockLayers[dirs3by3[5]], Box(ivec3(0, LAST_POS, 0), ivec3(1, 1, CHUNK_SIZE)));
44 		allBlocks[extendedChunkIndex(0, 0, EX_LAST_POS)] = blockLayers[dirs3by3[6]].getBlockId(LAST_POS, LAST_POS, 0);
45 		allBlocks.setExtendedArray(ivec3(1, 0, EX_LAST_POS), blockLayers[dirs3by3[7]], Box(ivec3(0, LAST_POS, 0), ivec3(CHUNK_SIZE, 1, 1)));
46 		allBlocks[extendedChunkIndex(EX_LAST_POS, 0, EX_LAST_POS)] = blockLayers[dirs3by3[8]].getBlockId(0, LAST_POS, 0);
47 
48 		// middle 9
49 		allBlocks.setExtendedArray(ivec3(0, 1, 0), blockLayers[dirs3by3[9]], Box(ivec3(LAST_POS, 0, LAST_POS), ivec3(1, CHUNK_SIZE, 1)));
50 		allBlocks.setExtendedArray(ivec3(1, 1, 0), blockLayers[dirs3by3[10]], Box(ivec3(0, 0, LAST_POS), ivec3(CHUNK_SIZE, CHUNK_SIZE, 1)));
51 		allBlocks.setExtendedArray(ivec3(EX_LAST_POS, 1, 0), blockLayers[dirs3by3[11]], Box(ivec3(0, 0, LAST_POS), ivec3(1, CHUNK_SIZE, 1)));
52 		allBlocks.setExtendedArray(ivec3(0, 1, 1), blockLayers[dirs3by3[12]], Box(ivec3(LAST_POS, 0, 0), ivec3(1, CHUNK_SIZE, CHUNK_SIZE)));
53 
54 		allBlocks.setExtendedArray(ivec3(1,1,1), blockLayers[26], Box(ivec3(0, 0, 0), CHUNK_SIZE_VECTOR));
55 
56 		allBlocks.setExtendedArray(ivec3(EX_LAST_POS, 1, 1), blockLayers[dirs3by3[14]], Box(ivec3(0, 0, 0), ivec3(1, CHUNK_SIZE, CHUNK_SIZE)));
57 		allBlocks.setExtendedArray(ivec3(0, 1, EX_LAST_POS), blockLayers[dirs3by3[15]], Box(ivec3(LAST_POS, 0, 0), ivec3(1, CHUNK_SIZE, 1)));
58 		allBlocks.setExtendedArray(ivec3(1, 1, EX_LAST_POS), blockLayers[dirs3by3[16]], Box(ivec3(0, 0, 0), ivec3(CHUNK_SIZE, CHUNK_SIZE, 1)));
59 		allBlocks.setExtendedArray(ivec3(EX_LAST_POS, 1, EX_LAST_POS), blockLayers[dirs3by3[17]], Box(ivec3(0, 0, 0), ivec3(1, CHUNK_SIZE, 1)));
60 
61 		// top 9
62 		allBlocks[extendedChunkIndex(0, EX_LAST_POS, 0)] = blockLayers[dirs3by3[18]].getBlockId(LAST_POS, 0, LAST_POS);
63 		allBlocks.setExtendedArray(ivec3(1, EX_LAST_POS, 0), blockLayers[dirs3by3[19]], Box(ivec3(0, 0, LAST_POS), ivec3(CHUNK_SIZE, 1, 1)));
64 		allBlocks[extendedChunkIndex(EX_LAST_POS, EX_LAST_POS, 0)] = blockLayers[dirs3by3[20]].getBlockId(0, 0, LAST_POS);
65 		allBlocks.setExtendedArray(ivec3(0, EX_LAST_POS, 1), blockLayers[dirs3by3[21]], Box(ivec3(LAST_POS, 0, 0), ivec3(1, 1, CHUNK_SIZE)));
66 		allBlocks.setExtendedArray(ivec3(1, EX_LAST_POS, 1), blockLayers[dirs3by3[22]], Box(ivec3(0, 0, 0), ivec3(CHUNK_SIZE, 1, CHUNK_SIZE)));
67 		allBlocks.setExtendedArray(ivec3(EX_LAST_POS, EX_LAST_POS, 1), blockLayers[dirs3by3[23]], Box(ivec3(0, 0, 0), ivec3(1, 1, CHUNK_SIZE)));
68 		allBlocks[extendedChunkIndex(0, EX_LAST_POS, EX_LAST_POS)] = blockLayers[dirs3by3[24]].getBlockId(LAST_POS, 0, 0);
69 		allBlocks.setExtendedArray(ivec3(1, EX_LAST_POS, EX_LAST_POS), blockLayers[dirs3by3[25]], Box(ivec3(0, 0, 0), ivec3(CHUNK_SIZE, 1, 1)));
70 		allBlocks[extendedChunkIndex(EX_LAST_POS, EX_LAST_POS, EX_LAST_POS)] = blockLayers[dirs3by3[26]].getBlockId(0, 0, 0);
71 	}
72 }