/*
 * MarchingTetrahedon.h
 *
 *  Created on: 20.10.2017
 *      Author: gmueller
 */

#ifndef MARCHINGTETRAHEDON_H_
#define MARCHINGTETRAHEDON_H_

using namespace std;

struct Voxel {
	Voxel() :
			density(rand() % 20 + 40), material(0) {
	}
	int density; /*1..100*/
	int material; /*id's will be given*/
	float x, y, z;
};

int width = 1366, height = 768;
float moving = 0;
float* dispArr;
int dispArrSize;
int frame = 0;
int i = 0, j = 0, k = 0;
Voxel*** field;
GLuint texture;
bool running = true;

cameraT cam(Vector3D(__MAPSIZE__ - 2, __MAPSIZE__ - 2, __MAPSIZE__ - 2),
		Vector3D(0, 0, 0));
int ghostX, ghostY;

/*GL_N3F_V3F*/
/*[Nx][Ny][Nz][Vx][Vy][Vz]*/
float* vertices;



/*The coordinates, the nubered tetrahedrons and the description are in the blender file named  tetrahedrons.blend*/
void marchingTetrahedrons(Voxel v0, Voxel v1, Voxel v2, Voxel v3, float **verts,
		int size, int* current, int tetrahedron) {
	/*to be precise: the verts array currently is: [vertices][coordinates] = [n][6]
	 so the size represents the number of vertices*/
	/*first we find out how many lands are in this tetrahedron(max is 4)*/
	int count = 0;
	if (v0.material != 0)
		count++;
	if (v1.material != 0)
		count++;
	if (v2.material != 0)
		count++;
	if (v3.material != 0)
		count++;

	/*let's decide the density of each material*/
	float v0d = 1 - (float) v0.density / 100;
	float v1d = 1 - (float) v1.density / 100;
	float v2d = 1 - (float) v2.density / 100;
	float v3d = 1 - (float) v3.density / 100;
	/*depending on the number we extract the cases*/
	switch (count) {
	case 0:
	case 4:
		break;

	case 1:
		/*One voxel has material*/
		if (v0.material != 0) { /*03,02,01*/
			if (tetrahedron == 1 || tetrahedron == 3 || tetrahedron == 4
					|| tetrahedron == 6) {
				/*correct tetrahedrons for this winding: 1,3,4,6*/
				/*wrong tetrahedrons for this winding: 2,5*/
				verts[(*current)][3] = (v0.x * v0d + v3.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v3.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v3.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v2.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v2.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v2.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v1.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v1.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v1.z * (1 - v0d));
				(*current) = (*current) + 1;/**/
			}
			if (tetrahedron == 2 || tetrahedron == 5) {
				verts[(*current)][3] = (v0.x * v0d + v1.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v1.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v1.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v2.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v2.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v2.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v3.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v3.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v3.z * (1 - v0d));
				(*current) = (*current) + 1;/**/
			}
		} else if (v1.material != 0) { /*01,13,12*/
			if (tetrahedron == 2 || tetrahedron == 5) {
				/*correct tetrahedrons for this winding: 2,5*/
				/*wrong tetrahedrons for this winding: 1,3,4,6*/
				verts[(*current)][3] = (v0.x * (1 - v1d) + v1.x * v1d);
				verts[(*current)][4] = (v0.y * (1 - v1d) + v1.y * v1d);
				verts[(*current)][5] = (v0.z * (1 - v1d) + v1.z * v1d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * v1d + v3.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v3.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v3.z * (1 - v1d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * v1d + v2.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v2.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v2.z * (1 - v1d));
				(*current) = (*current) + 1;/**/
			} else if (tetrahedron == 1 || tetrahedron == 3 || tetrahedron == 4
					|| tetrahedron == 6) {
				verts[(*current)][3] = (v1.x * v1d + v2.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v2.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v2.z * (1 - v1d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * v1d + v3.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v3.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v3.z * (1 - v1d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v1d) + v1.x * v1d);
				verts[(*current)][4] = (v0.y * (1 - v1d) + v1.y * v1d);
				verts[(*current)][5] = (v0.z * (1 - v1d) + v1.z * v1d);
				(*current) = (*current) + 1;/**/
			}
		} else if (v2.material != 0) { /*02,12,23*/
			if (tetrahedron == 2 || tetrahedron == 5) {
				/*correct tetrahedrons for this winding: 2,5*/
				/*wrong tetrahedrons for this winding: 1,3,4,6*/
				verts[(*current)][3] = (v0.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v0.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v0.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v1.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v1.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v2.x * v2d + v3.x * (1 - v2d));
				verts[(*current)][4] = (v2.y * v2d + v3.y * (1 - v2d));
				verts[(*current)][5] = (v2.z * v2d + v3.z * (1 - v2d));
				(*current) = (*current) + 1;/**/
			} else if (tetrahedron == 3 || tetrahedron == 1 || tetrahedron == 4
					|| tetrahedron == 6) {
				verts[(*current)][3] = (v2.x * v2d + v3.x * (1 - v2d));
				verts[(*current)][4] = (v2.y * v2d + v3.y * (1 - v2d));
				verts[(*current)][5] = (v2.z * v2d + v3.z * (1 - v2d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v1.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v1.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v0.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v0.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;/**/
			}
		} else if (v3.material != 0) { /*03,32,31*/
			if (tetrahedron == 2 || tetrahedron == 5) {
				/*correct tetrahedrons for this winding: 2,5*/
				/*wrong tetrahedrons for this winding: 1,3,4,6*/
				verts[(*current)][3] = (v0.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v0.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v0.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v3.x * v3d + v2.x * (1 - v3d));
				verts[(*current)][4] = (v3.y * v3d + v2.y * (1 - v3d));
				verts[(*current)][5] = (v3.z * v3d + v2.z * (1 - v3d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v3.x * v3d + v1.x * (1 - v3d));
				verts[(*current)][4] = (v3.y * v3d + v1.y * (1 - v3d));
				verts[(*current)][5] = (v3.z * v3d + v1.z * (1 - v3d));
				(*current) = (*current) + 1;/**/
			} else if (tetrahedron == 1 || tetrahedron == 3 || tetrahedron == 4
					|| tetrahedron == 6) {
				verts[(*current)][3] = (v3.x * v3d + v1.x * (1 - v3d));
				verts[(*current)][4] = (v3.y * v3d + v1.y * (1 - v3d));
				verts[(*current)][5] = (v3.z * v3d + v1.z * (1 - v3d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v3.x * v3d + v2.x * (1 - v3d));
				verts[(*current)][4] = (v3.y * v3d + v2.y * (1 - v3d));
				verts[(*current)][5] = (v3.z * v3d + v2.z * (1 - v3d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v0.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v0.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;/**/
			}
		}
		break;

	case 2:
		/*two voxels have material*/
		if (v0.material != 0 && v3.material != 0) { /*01,02,31;31,02,32*/
			if (tetrahedron == 2 || tetrahedron == 5) {
				/*correct tetrahedrons for this winding: 2,5*/
				/*wrong tetrahedrons for this winding: 1,3,4,6*/
				verts[(*current)][3] = (v0.x * v0d + v1.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v1.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v1.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v2.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v2.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v2.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v3.x * v3d + v1.x * (1 - v3d));
				verts[(*current)][4] = (v3.y * v3d + v1.y * (1 - v3d));
				verts[(*current)][5] = (v3.z * v3d + v1.z * (1 - v3d));
				(*current) = (*current) + 1;

				verts[(*current)][3] = (v1.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v1.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v1.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v2.x * (1 - v0d) + v0.x * v0d);
				verts[(*current)][4] = (v2.y * (1 - v0d) + v0.y * v0d);
				verts[(*current)][5] = (v2.z * (1 - v0d) + v0.z * v0d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v3.x * v3d + v2.x * (1 - v3d));
				verts[(*current)][4] = (v3.y * v3d + v2.y * (1 - v3d));
				verts[(*current)][5] = (v3.z * v3d + v2.z * (1 - v3d));
				(*current) = (*current) + 1;/**/
			} else if (tetrahedron == 4 || tetrahedron == 1 || tetrahedron == 3
					|| tetrahedron == 6) {
				verts[(*current)][3] = (v3.x * v3d + v1.x * (1 - v3d));
				verts[(*current)][4] = (v3.y * v3d + v1.y * (1 - v3d));
				verts[(*current)][5] = (v3.z * v3d + v1.z * (1 - v3d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v2.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v2.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v2.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v1.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v1.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v1.z * (1 - v0d));
				(*current) = (*current) + 1;

				verts[(*current)][3] = (v3.x * v3d + v2.x * (1 - v3d));
				verts[(*current)][4] = (v3.y * v3d + v2.y * (1 - v3d));
				verts[(*current)][5] = (v3.z * v3d + v2.z * (1 - v3d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v2.x * (1 - v0d) + v0.x * v0d);
				verts[(*current)][4] = (v2.y * (1 - v0d) + v0.y * v0d);
				verts[(*current)][5] = (v2.z * (1 - v0d) + v0.z * v0d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v1.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v1.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;/**/
			}
		} else if (v1.material != 0 && v2.material != 0) { /*13,32,02;02,01,13*/
			if (tetrahedron == 1 || tetrahedron == 4 || tetrahedron == 6
					|| tetrahedron == 3) {
				/*correct tetrahedrons for this winding: 1,3,4,6*/
				/*wrong tetrahedrons for this winding: 2,5*/
				verts[(*current)][3] = (v0.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v0.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v0.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v3.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v3.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v3.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * v1d + v3.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v3.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v3.z * (1 - v1d));
				(*current) = (*current) + 1;

				verts[(*current)][3] = (v1.x * v1d + v3.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v3.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v3.z * (1 - v1d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v1d) + v1.x * v1d);
				verts[(*current)][4] = (v0.y * (1 - v1d) + v1.y * v1d);
				verts[(*current)][5] = (v0.z * (1 - v1d) + v1.z * v1d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v0.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v0.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;/**/
			} else if (tetrahedron == 2 || tetrahedron == 5) {
				verts[(*current)][3] = (v1.x * v1d + v3.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v3.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v3.z * (1 - v1d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v3.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v3.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v3.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v0.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v0.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;

				verts[(*current)][3] = (v0.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v0.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v0.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v1d) + v1.x * v1d);
				verts[(*current)][4] = (v0.y * (1 - v1d) + v1.y * v1d);
				verts[(*current)][5] = (v0.z * (1 - v1d) + v1.z * v1d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * v1d + v3.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v3.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v3.z * (1 - v1d));
				(*current) = (*current) + 1;/**/
			}
		} else if (v2.material != 0 && v3.material != 0) { /*03,02,13;13,02,12*/
			if (tetrahedron == 2 || tetrahedron == 5) {
				/*correct tetrahedrons for this winding: 2,5*/
				/*wrong tetrahedrons for this winding: 1,3,4,6*/
				verts[(*current)][3] = (v0.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v0.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v0.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v0.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v0.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v1.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v1.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;

				verts[(*current)][3] = (v1.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v1.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v1.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v0.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v0.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v1.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v1.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;/**/
			} else if (tetrahedron == 1 || tetrahedron == 3 || tetrahedron == 4
					|| tetrahedron == 6) {
				verts[(*current)][3] = (v1.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v1.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v1.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v0.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v0.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v0.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v0.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;

				verts[(*current)][3] = (v1.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v1.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v1.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v0.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v0.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v1.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v1.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;/**/
			}
		} else if (v0.material != 0 && v1.material != 0) { /*03,02,13;13,02,12*/
			if (tetrahedron == 3 || tetrahedron == 6 || tetrahedron == 1
					|| tetrahedron == 4) {
				/*correct tetrahedrons for this winding: 1,3,4,6*/
				/*wrong tetrahedrons for this winding: 2,5*/
				verts[(*current)][3] = (v0.x * v0d + v3.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v3.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v3.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v2.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v2.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v2.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * v1d + v3.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v3.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v3.z * (1 - v1d));
				(*current) = (*current) + 1;

				verts[(*current)][3] = (v1.x * v1d + v3.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v3.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v3.z * (1 - v1d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v2.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v2.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v2.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * v1d + v2.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v2.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v2.z * (1 - v1d));
				(*current) = (*current) + 1;/**/
			} else if (tetrahedron == 2 || tetrahedron == 5) {
				verts[(*current)][3] = (v1.x * v1d + v3.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v3.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v3.z * (1 - v1d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v2.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v2.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v2.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v3.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v3.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v3.z * (1 - v0d));
				(*current) = (*current) + 1;

				verts[(*current)][3] = (v1.x * v1d + v2.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v2.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v2.z * (1 - v1d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v2.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v2.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v2.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * v1d + v3.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v3.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v3.z * (1 - v1d));
				(*current) = (*current) + 1;/**/
			}
		} else if (v1.material != 0 && v3.material != 0) { /*01,12,32;32,30,01*/
			if (tetrahedron == 1 || tetrahedron == 3 || tetrahedron == 4
					|| tetrahedron == 6) {
				/*correct tetrahedrons for this winding: 1,3,4,6*/
				/*wrong tetrahedrons for this winding: 2,5*/
				verts[(*current)][3] = (v0.x * (1 - v1d) + v1.x * v1d);
				verts[(*current)][4] = (v0.y * (1 - v1d) + v1.y * v1d);
				verts[(*current)][5] = (v0.z * (1 - v1d) + v1.z * v1d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * v1d + v2.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v2.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v2.z * (1 - v1d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v2.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v2.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v2.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;

				verts[(*current)][3] = (v2.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v2.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v2.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v3.x * v3d + v0.x * (1 - v3d));
				verts[(*current)][4] = (v3.y * v3d + v0.y * (1 - v3d));
				verts[(*current)][5] = (v3.z * v3d + v0.z * (1 - v3d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v1d) + v1.x * v1d);
				verts[(*current)][4] = (v0.y * (1 - v1d) + v1.y * v1d);
				verts[(*current)][5] = (v0.z * (1 - v1d) + v1.z * v1d);
				(*current) = (*current) + 1;/**/
			} else if (tetrahedron == 2 || tetrahedron == 5) {
				verts[(*current)][3] = (v2.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v2.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v2.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * v1d + v2.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v2.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v2.z * (1 - v1d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v1d) + v1.x * v1d);
				verts[(*current)][4] = (v0.y * (1 - v1d) + v1.y * v1d);
				verts[(*current)][5] = (v0.z * (1 - v1d) + v1.z * v1d);
				(*current) = (*current) + 1;

				verts[(*current)][3] = (v0.x * (1 - v1d) + v1.x * v1d);
				verts[(*current)][4] = (v0.y * (1 - v1d) + v1.y * v1d);
				verts[(*current)][5] = (v0.z * (1 - v1d) + v1.z * v1d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v3.x * v3d + v0.x * (1 - v3d));
				verts[(*current)][4] = (v3.y * v3d + v0.y * (1 - v3d));
				verts[(*current)][5] = (v3.z * v3d + v0.z * (1 - v3d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v2.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v2.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v2.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;/**/
			}
		} else if (v0.material != 0 && v2.material != 0) { /*01,03,32;32,12,01*/
			if (tetrahedron == 1 || tetrahedron == 3 || tetrahedron == 4
					|| tetrahedron == 6) {
				/*correct tetrahedrons for this winding: 1,3,4,6*/
				/*wrong tetrahedrons for this winding: 2,5*/
				verts[(*current)][3] = (v0.x * v0d + v1.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v1.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v1.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v3.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v3.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v3.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v2.x * v2d + v3.x * (1 - v2d));
				verts[(*current)][4] = (v2.y * v2d + v3.y * (1 - v2d));
				verts[(*current)][5] = (v2.z * v2d + v3.z * (1 - v2d));
				(*current) = (*current) + 1;

				verts[(*current)][3] = (v2.x * v2d + v3.x * (1 - v2d));
				verts[(*current)][4] = (v2.y * v2d + v3.y * (1 - v2d));
				verts[(*current)][5] = (v2.z * v2d + v3.z * (1 - v2d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v1.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v1.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v1.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v1.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v1.z * (1 - v0d));
				(*current) = (*current) + 1;/**/
			} else if (tetrahedron == 5 || tetrahedron == 2) {
				verts[(*current)][3] = (v2.x * v2d + v3.x * (1 - v2d));
				verts[(*current)][4] = (v2.y * v2d + v3.y * (1 - v2d));
				verts[(*current)][5] = (v2.z * v2d + v3.z * (1 - v2d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v3.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v3.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v3.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v1.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v1.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v1.z * (1 - v0d));
				(*current) = (*current) + 1;

				verts[(*current)][3] = (v0.x * v0d + v1.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v1.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v1.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v1.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v1.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v2.x * v2d + v3.x * (1 - v2d));
				verts[(*current)][4] = (v2.y * v2d + v3.y * (1 - v2d));
				verts[(*current)][5] = (v2.z * v2d + v3.z * (1 - v2d));
				(*current) = (*current) + 1;/**/
			}
		}
		break;

	case 3:
		/*three voxels have material*/
		if (v0.material == 0) { /*03,01,02*/
			if (tetrahedron == 1 || tetrahedron == 3 || tetrahedron == 4
					|| tetrahedron == 6) {
				/*correct tetrahedrons for this winding: 1,3,4,6*/
				/*wrong tetrahedrons for this winding: 2,5*/
				verts[(*current)][3] = (v0.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v0.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v0.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v1d) + v1.x * v1d);
				verts[(*current)][4] = (v0.y * (1 - v1d) + v1.y * v1d);
				verts[(*current)][5] = (v0.z * (1 - v1d) + v1.z * v1d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v0.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v0.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;/**/
			} else if (tetrahedron == 2 || tetrahedron == 5) {
				verts[(*current)][3] = (v0.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v0.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v0.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v1d) + v1.x * v1d);
				verts[(*current)][4] = (v0.y * (1 - v1d) + v1.y * v1d);
				verts[(*current)][5] = (v0.z * (1 - v1d) + v1.z * v1d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v0.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v0.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;/**/
			}
		} else if (v1.material == 0) { /*10,12,13*/
			if (tetrahedron == 2 || tetrahedron == 5) {
				/*correct tetrahedrons for this winding: 2,5*/
				/*wrong tetrahedrons for this winding: 1,3,4,6*/
				verts[(*current)][3] = (v0.x * v0d + v1.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v1.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v1.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v1.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v1.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v1.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v1.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;/**/
			} else if (tetrahedron == 1 || tetrahedron == 3 || tetrahedron == 4
					|| tetrahedron == 6) {
				verts[(*current)][3] = (v1.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v1.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v1.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * (1 - v2d) + v2.x * v2d);
				verts[(*current)][4] = (v1.y * (1 - v2d) + v2.y * v2d);
				verts[(*current)][5] = (v1.z * (1 - v2d) + v2.z * v2d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v1.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v1.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v1.z * (1 - v0d));
				(*current) = (*current) + 1;/**/
			}
		} else if (v2.material == 0) { /*20,23,21*/
			if (tetrahedron == 2 || tetrahedron == 5) {
				/*correct tetrahedrons for this winding: 2,5*/
				/*wrong tetrahedrons for this winding: 1,3,4,6*/
				verts[(*current)][3] = (v0.x * v0d + v2.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v2.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v2.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v2.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v2.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v2.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v2.x * (1 - v1d) + v1.x * v1d);
				verts[(*current)][4] = (v2.y * (1 - v1d) + v1.y * v1d);
				verts[(*current)][5] = (v2.z * (1 - v1d) + v1.z * v1d);
				(*current) = (*current) + 1;/**/
			} else if (tetrahedron == 1 || tetrahedron == 3 || tetrahedron == 4
					|| tetrahedron == 6) {
				verts[(*current)][3] = (v2.x * (1 - v1d) + v1.x * v1d);
				verts[(*current)][4] = (v2.y * (1 - v1d) + v1.y * v1d);
				verts[(*current)][5] = (v2.z * (1 - v1d) + v1.z * v1d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v2.x * (1 - v3d) + v3.x * v3d);
				verts[(*current)][4] = (v2.y * (1 - v3d) + v3.y * v3d);
				verts[(*current)][5] = (v2.z * (1 - v3d) + v3.z * v3d);
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v2.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v2.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v2.z * (1 - v0d));
				(*current) = (*current) + 1;/**/
			}
		} else if (v3.material == 0) { /*30,31,32*/
			if (tetrahedron == 2 || tetrahedron == 5) {
				/*correct tetrahedrons for this winding: 2,5*/
				/*wrong tetrahedrons for this winding: 1,3,4,6*/
				verts[(*current)][3] = (v0.x * v0d + v3.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v3.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v3.z * (1 - v0d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * v1d + v3.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v3.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v3.z * (1 - v1d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v2.x * v2d + v3.x * (1 - v2d));
				verts[(*current)][4] = (v2.y * v2d + v3.y * (1 - v2d));
				verts[(*current)][5] = (v2.z * v2d + v3.z * (1 - v2d));
				(*current) = (*current) + 1;/**/
			} else if (tetrahedron == 3 || tetrahedron == 1 || tetrahedron == 4
					|| tetrahedron == 6) {
				verts[(*current)][3] = (v2.x * v2d + v3.x * (1 - v2d));
				verts[(*current)][4] = (v2.y * v2d + v3.y * (1 - v2d));
				verts[(*current)][5] = (v2.z * v2d + v3.z * (1 - v2d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v1.x * v1d + v3.x * (1 - v1d));
				verts[(*current)][4] = (v1.y * v1d + v3.y * (1 - v1d));
				verts[(*current)][5] = (v1.z * v1d + v3.z * (1 - v1d));
				(*current) = (*current) + 1;
				verts[(*current)][3] = (v0.x * v0d + v3.x * (1 - v0d));
				verts[(*current)][4] = (v0.y * v0d + v3.y * (1 - v0d));
				verts[(*current)][5] = (v0.z * v0d + v3.z * (1 - v0d));
				(*current) = (*current) + 1;/**/
			}
		}
		break;
	}
}

float** generateVertices(Voxel*** inField, int* size) {
	/*size means how many vertices are going to be in the array*/
	/*testdata will be just squares, so there will be n*3*2 vertices */
	int count = 0;
	int current = 0;
	float** verts;
	float** tverts;

	/*at maximum we have (roughly) __MAPSIZE__*__MAPSIZE__*__MAPSIZE__ cubes, all of which can use
	 (roughly) 6 tetrahedrons, and every tetrahedrons maximum triangle count is 2. every tringle has 3 vertices.
	 Every vertex will have 6 coordinates(3 space coordinates, 3 normal vector coordinates)
	 Considering all this, an estimated maximum we will have __MAPSIZE__*__MAPSIZE__*__MAPSIZE__*6*2*3*6.
	 That's 27000000. Holy shit.
	 Here we will use [__MAPSIZE__*__MAPSIZE__*__MAPSIZE__*6*2*3] elements as vertices, and [6] for coordinates
	 */

	/*reserve memory for the array*/
	count = __MAPSIZE__ * __MAPSIZE__ * __MAPSIZE__ * 6 * 2 * 3;
	tverts = new float*[count];
	for (i = 0; i < count; i++)
		tverts[i] = new float[6];

	/*go through the field cube to cube. A cube will have an edge of 1.*/
	for (i = 0; i < __MAPSIZE__ - 1; i++)
		for (j = 0; j < __MAPSIZE__ - 1; j++)
			for (k = 0; k < __MAPSIZE__ - 1; k++) {
				/*and we call the tetrahedrons to the 8 vertices of the cube*/
				/*!Thank you paul Burke! (work needed in the booklet)
				 PolygoniseTri(grid,iso,triangles,0,2,3,7);
				 PolygoniseTri(grid,iso,triangles,0,2,6,7);
				 PolygoniseTri(grid,iso,triangles,0,4,6,7);

				 PolygoniseTri(grid,iso,triangles,0,6,1,2);
				 PolygoniseTri(grid,iso,triangles,0,6,1,4);
				 PolygoniseTri(grid,iso,triangles,5,6,1,4);
				 */
				/*1*/marchingTetrahedrons(inField[i][j][k + 1],
						inField[i + 1][j][k], inField[i][j][k],
						inField[i][j + 1][k], tverts, count, &current, 1);/**/
				/*2*/marchingTetrahedrons(inField[i][j][k + 1],
						inField[i + 1][j][k], inField[i + 1][j + 1][k],
						inField[i][j + 1][k], tverts, count, &current, 2);/**/
				/*3*/marchingTetrahedrons(inField[i][j][k + 1],
						inField[i][j + 1][k + 1], inField[i + 1][j + 1][k],
						inField[i][j + 1][k], tverts, count, &current, 3);/**/
				/*4*/marchingTetrahedrons(inField[i][j][k + 1],
						inField[i + 1][j + 1][k], inField[i + 1][j][k + 1],
						inField[i + 1][j][k], tverts, count, &current, 4);/**/
				/*5*/marchingTetrahedrons(inField[i][j][k + 1],
						inField[i + 1][j + 1][k], inField[i + 1][j][k + 1],
						inField[i][j + 1][k + 1], tverts, count, &current, 5);/**/
				/*6*/marchingTetrahedrons(inField[i + 1][j + 1][k + 1],
						inField[i + 1][j + 1][k], inField[i + 1][j][k + 1],
						inField[i][j + 1][k + 1], tverts, count, &current, 6);/**/
			}

	/*After the algorithm, I copy every triangle to the appropriate sized result array(verts)*/
	verts = new float*[current];
	for (i = 0; i < current; i++)
		verts[i] = new float[6];

	for (i = 0; i < current; i++) {
		verts[i][3] = tverts[i][3];
		verts[i][4] = tverts[i][4];
		verts[i][5] = tverts[i][5];
	}

	delete[] tverts;

	/*and give the algorithm the number of the vertices*/
	(*size) = current;

	return verts;
}

void normalizeVertices(float** inverts, int size) {
	Vector3D tempV[3];
	Vector3D tNormal;
	for (i = 0; i < size; i += 3) {

		tempV[0] = Vector3D(inverts[i][3], inverts[i][4], inverts[i][5]);
		tempV[1] = Vector3D(inverts[i + 1][3], inverts[i + 1][4],
				inverts[i + 1][5]);
		tempV[2] = Vector3D(inverts[i + 2][3], inverts[i + 2][4],
				inverts[i + 2][5]);
		tNormal = calcNormal(tempV);

		inverts[i][0] = tNormal.x;
		inverts[i][1] = tNormal.y;
		inverts[i][2] = tNormal.z;

		inverts[i + 1][0] = tNormal.x;
		inverts[i + 1][1] = tNormal.y;
		inverts[i + 1][2] = tNormal.z;

		inverts[i + 2][0] = tNormal.x;
		inverts[i + 2][1] = tNormal.y;
		inverts[i + 2][2] = tNormal.z;
	}
}

float* arrayizeVertices(float** inverts, int size) {
	float* verts;
	int count = 0;

	verts = new float[size * 6];

	for (i = 0; i < size; i++) {
		verts[count] = inverts[i][0];
		verts[count + 1] = inverts[i][1];
		verts[count + 2] = inverts[i][2];
		verts[count + 3] = inverts[i][3];
		verts[count + 4] = inverts[i][4];
		verts[count + 5] = inverts[i][5];
		count += 6;
	}
	return verts;
}

#endif /* MARCHINGTETRAHEDON_H_ */
