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