View difference between Paste ID: xvGb8qk3 and WzmKLFnM
SHOW: | | - or go back to the newest paste.
1
// in the snippet following variables will be needed:
2
// chunkSizeX/Y/Z - the size of one chunk in the x/y/z-direction
3
// sectionHeight - the height of one section inside a chunk, e.g.: sectionHeight = 16 and chunkSizeY=256 makes 16 sections
4
// currentChunk - reference to a Chunk structure
5
6
7
enum Face
8
{
9
	North	= 1,
10
	East	= 2,
11
	South	= 4,
12
	West	= 8,
13
	Top	= 16,
14
	Bottom	= 32
15
};
16
17
struct Block
18
{
19
	int Type;
20
	Face VisibleFaces;
21
};
22
23
struct Chunk
24
{
25
	float x, y, z;
26
	Block blockData[];
27
};
28
29
30
int numBlocksPerSection = chunkSizeX * sectionHeight * chunkSizeZ;
31
bool handled[] = new bool[numBlocksPerSection];
32
Face activeFace = (Face)1;
33
34
// iterate over all 6 faces
35
for (int f = 0; f < 6; ++f)
36
{
37
	// reset all blocks not to be handled
38
	memset(handled, FALSE, numBlocksPerSection);
39
40
	for(int x = 0; x < chunkSizeX; ++x)
41
	{
42
		for(int y = 0; y < sectionHeight; ++y)
43
		{
44
			for(int z = 0; z < chunkSizeZ; ++z)
45
			{
46
				// global and relative indices
47
				int iGlobal = x + chunkSizeX * ((y + currentSection * sectionHeight) + chunkSizeY * z);
48
				int iRelative = x + chunkSizeX * (y + sectionHeight * z);
49
50
				Face faces = currentChunk.blockData[iGlobal].VisibleFaces;
51
52
				// continue if face is not visible or was handled already
53
				if(!(faces & activeFace) || handled[iRelative])
54
				{
55
					handled[iRelative] = true;
56
					continue;
57
				}
58
59
				int width = 1, height = 1, depth = 1;
60
61
				// skip width check if activeFace is East or West -> no width
62
				if(!(activeFace & East || activeFace & West))
63
				{
64
					// calculate width for same faces being adjacent to current block
65
					for(; width < chunkSizeX - x && 
66
						currentChunk.blockData[SHIFT_INDEX_X(iGlobal, width)].VisibleFaces & tmp &&
67
						currentChunk.blockData[iGlobal].Type == currentChunk.blockData[SHIFT_INDEX_X(iGlobal, width)].Type &&
68
						&& !handled[SHIFT_SECTIONINDEX_X(iRelative, width)]; ++width);
69
				}
70
71
				bool done = false;
72
73
				// skip depth check if activeFace is North or South -> no depth
74
				if(!(activeFace & North || activeFace & South))
75
				{
76
					// calculate depth for same faces being adjacent to current block
77
					for(; depth < chunkSizeZ - z; ++depth)
78
					{
79
						// this time add another loop, to make sure, only increment depth if all blocks inside the width range are same
80
						for(int u = 0; u < width; ++u)
81
						{
82
							int indexGlobal = SHIFT_INDEX_X(SHIFT_INDEX_Z(iGlobal, depth), u);
83
							int indexRelative = SHIFT_RELATIVEINDEX_X(SHIFT_RELATIVEINDEX_Z(iRelative, depth), u);
84
							if(!(currentChunk.blockData[indexGlobal].VisibleFaces & activeFace && 
85
								currentChunk.blockData[iGlobal].Type == currentChunk.blockData[indexGlobal].Type) ||
86
								handled[indexRelative])
87
							{
88
								done = true;
89
								break;
90
							}
91
						}
92
						if(done)
93
							break;
94
					}
95
				}
96
97
				done = false;
98
99
				// skip height check if activeFace is Top or Bottom -> no height
100
				if(!(activeFace & Top || activeFace & Bottom))
101
				{
102
					// calculate height
103
					for(; height < sectionHeight - y; ++height)
104
					{
105
						// add loops for width and depth
106
						for(int u = 0; u < width; ++u)
107
						{
108
							for(int v = 0; v < depth; ++v)
109
							{
110
								int indexGlobal = SHIFT_INDEX_X(SHIFT_INDEX_Y(SHIFT_INDEX_Z(iGlobal, v), height), u);
111
								int indexRelative = SHIFT_RELATIVEINDEX_X(SHIFT_RELATIVEINDEX_Y(SHIFT_RELATIVEINDEX_Z(iRelative, v), height), u);
112
								if(!(currentChunk.blockData[indexGlobal].VisibleFaces & activeFace ||
113
									currentChunk.blockData[iGlobal].Type == currentChunk.blockData[indexGlobal].Type) ||
114
									handled[indexRelative])
115
								{
116
									done = true;
117
									break;
118
								}
119
							}
120
							if(done)	break;
121
						}
122
						if(done)	break;
123
					}
124
				}
125
126
				// make sure we add the calculated face range to the handled array
127
				for(int a = 0; a < width; ++a)
128
					for(int b = 0; b < height; ++b)
129
						for(int c = 0; c < depth; ++c)
130
							handled[SHIFT_RELATIVEINDEX_X(SHIFT_RELATIVEINDEX_Y(SHIFT_RELATIVEINDEX_Z(iRelative, c), b), a)] = true;
131
132
				// add the quad's vertices here, dependent on the activeFace, 
133
				// e.g. for North and a counter-clockwise ordering:
134
				// position1 = vector3(width + x + currentChunk.x, y + currentChunk.y, depth + z + currentChunk.z);
135
				// position2 = vector3(width + x + currentChunk.x, y + height + currentChunk.y, depth + z + currentChunk.z);
136
				// position3 = vector3(x + currentChunk.x, y + height + currentChunk.y, depth + z + currentChunk.z);
137
				// position4 = vector3(x + currentChunk.x, y + currentChunk.y, depth + z + currentChunk.z);
138
			}
139
		}
140
	}
141
142
	activeFace = (Face)(activeFace * 2);		
143
}