I have been trying to implement marching cubes in unity with c# but the meshes that are being created all have a rotation that is off by 90 degrees.
in this example I am trying to create a cube.
this is my current code that I have if any one can figure out what the problem is that would be great thanks.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(MeshFilter))]
public class train : MonoBehaviour
{
//setup e.g varables and lists
//----------------------------------------------------------------------------------------------------
//size of the chunk
public int size = 10;
//binary stuff
public List<int> binary = new List<int>();
int bitewisenum = 0;
//posithions
public static Vector3 xyz = new Vector3();
public Vector3 list_edges = new Vector3();
//how much air the cut off point bettween air and solid 0.45 - 0.55 works best
public float dencity = 0.4f;
//mesh
public Vector3[] vertices;
public List<Vector3> vertices_list = new List<Vector3>();
public List<Vector3> vertices_list_store = new List<Vector3>();
public List<Vector3> inverlist = new List<Vector3>();
//we can convert it back to an array later
public List<int> tri = new List<int>();
Mesh mesh;
private int[] num;
private float airsolid_test;
public float cutoff; // 11 works best
//perlin noise
//---------------------------------------------------------------------------------------------------
public static float Perlin3D(float x, float y, float z, float cut)
{
//float AB = Mathf.PerlinNoise(x, y);
//float BC = Mathf.PerlinNoise(y, z);
//float AC = Mathf.PerlinNoise(x, z);
//
//
//float BA = Mathf.PerlinNoise(y, x);
//float CB = Mathf.PerlinNoise(z, y);
//float CA = Mathf.PerlinNoise(z, x);
//
////get the avarge
//float ABC = AB + BC + AC + BA + CB + CA;
//float per = ABC / 6f;
//if (y > cut)
//{
// per = Mathf.Pow(per * (y / 8.5f), 2.718f) + 0.3f;
//}
//testing
float per;
if (x >= cut)
{
per = 0f;
} else if (y >= cut)
{
per = 0f;
}
else if (z <= 0)
{
per = 0f;
}
else if (x <= 0)
{
per = 0f;
}
else if (z >= cut)
{
per = 0f;
}
else if (y <= 0)
{
per = 0f;
}else
{
per = 10f;
}
//testing ends
return per;
}
//----------------------------------------------------------------------------------------
private void Start()
{
//set up binary
binary.Add(1);
binary.Add(2);
binary.Add(4);
binary.Add(8);
binary.Add(16);
binary.Add(32);
binary.Add(64);
binary.Add(128);
//setup mesh
mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
tri.Clear();
//testing --------------------------------------
airsolid_test = dencity;
//0.1 is because of the perlin noise
for (float x = 0.1f; x < 16; x++)
{
for (int y = 0; y < 15; y++)
{
for (int z = 0; z < 15; z++)
{
//airsolid_test = dencity;
//if (y >= cutoff)
//{//mountans
// airsolid_test += 0.0f;//0.2f
//}
//else
//{//caves
// airsolid_test -= 0.005f;//0.005
//}
xyz.x = x;
xyz.y = y;
xyz.z = z;
createshape(x, y, z);
upmesh();
}
}
}
}
//xyz.x = x;
// xyz.y = y;
// xyz.z = z;
// createshape(x, y, z);
//upmesh();
//upmesh stands for update mesh
void upmesh()
{
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = tri.ToArray();
mesh.RecalculateNormals();
}
//-------------------------------------------------------------------------------------
// this is the main function and you give it an xyz cordanit and it sets the mesh's triangles and veticeys
void createshape(float x, float y, float z)
{
//list for the binary
List<int> bite = new List<int>();
bite.Clear();
bitewisenum = 0;
//this is getting the binay representation for each point on the cube if the point is > the density value store it as a 1 else as a 0
// so we end up with a binary number like 10011101
//position 7
if (Perlin3D(x + 1, y, z + 1, cutoff) > airsolid_test)
{
bite.Add(1);
//these store the value for intertopilation later but im not using it yet
float Pose_7 = Perlin3D(x + 1, y, z + 1,cutoff);
}
else
{
bite.Add(0);
}
//position 6
if (Perlin3D(x + 1, y + 1, z + 1, cutoff) > airsolid_test)
{
bite.Add(1);
float Pose_6 = Perlin3D(x + 1, y + 1, z + 1, cutoff);
}
else
{
bite.Add(0);
}
//position 5
if (Perlin3D(x, y + 1, z + 1, cutoff) > airsolid_test)
{
bite.Add(1);
float Pose_5 = Perlin3D(x, y + 1, z + 1, cutoff);
}
else
{
bite.Add(0);
}
//position 4
if (Perlin3D(x, y, z + 1, cutoff) > airsolid_test)
{
bite.Add(1);
float Pose_4 = Perlin3D(x, y, z + 1, cutoff);
}
else
{
bite.Add(0);
}
//position 3
if (Perlin3D(x + 1, y, z, cutoff) > airsolid_test)
{
bite.Add(1);
float Pose_3 = Perlin3D(x + 1, y, z, cutoff);
}
else
{
bite.Add(0);
}
//position 2
if (Perlin3D(x + 1, y + 1, z, cutoff) > airsolid_test)
{
bite.Add(1);
float Pose_2 = Perlin3D(x + 1, y + 1, z, cutoff);
}
else
{
bite.Add(0);
}
//position 1
if (Perlin3D(x, y + 1, z, cutoff) > airsolid_test)
{
bite.Add(1);
float Pose_1 = Perlin3D(x, y + 1, z, cutoff);
}
else
{
bite.Add(0);
}
//position 0
if (Perlin3D(x, y, z, cutoff) > airsolid_test)
{
bite.Add(1);
float Pose_0 = Perlin3D(x, y, z, cutoff);
}
else
{
bite.Add(0);
}
//convert binary in to decimal because i dont know an easy way to do this but
//loop throught all items in the binary list and change them
for (int i = 0; i <= 7; i++)
{
if (bite[i] == 1)
{
bitewisenum += binary[i];
}
}
//print(bitewisenum);
//check if its not all air or inside an object
//this means that we check if its 0 or 255
//now we need to make the mesh and show it
if (bitewisenum != 0 && bitewisenum != 255)
{
//Debug.Log("made a mesh");
//store the int array for easyer use
int[] trian = table.TriangleTable[bitewisenum];
/*
* at this point the int array describes edges not postions
* and we need to change that so what we do is loop through ever item in the list and
* parce it through a function(table.transform_to_postion) this returns a Vector 3
* which we then add to a list
*/
vertices_list.Clear();
for (int num = 0; num < trian.Length; num++)
{
//get the actule postions
//we give the function a edge index as an int which represents a edge index and it gives you the actule postion back as a vector 3
list_edges = transform_to_postion(trian[num]);
//add them to the list
vertices_list.Add(list_edges);
vertices_list_store.Add(list_edges);
//end of the for loop
}
// set vetaceys
vertices = vertices_list_store.ToArray();
//
//setting the triangles based off how many items there are on the verticeys list
if (vertices_list.Count / 3 == 1)
{
for (int i = 1; i < 4; i++)
{
tri.Add(tri.Count);
}
}
else if (vertices_list.Count / 3 == 2)
{
for (int i = 1; i < 7; i++)
{
tri.Add(tri.Count);
}
}
else if (vertices_list.Count / 3 == 3)
{
for (int i = 1; i < 10; i++)
{
tri.Add(tri.Count);
}
}
else if (vertices_list.Count / 3 == 4)
{
for (int i = 1; i < 13; i++)
{
tri.Add(tri.Count);
}
}
else if (vertices_list.Count / 3 == 5)
{
for (int i = 1; i < 16; i++)
{
tri.Add(tri.Count);
}
}
/*
Debug.Log("the legnth of verticys: "+vertices.Length);
Debug.Log("the legnth of tri: "+tri.Length);
Debug.Log("tri legnth " + tri.Length);
end of the if loop
*/
}
//end of the function
}
public static Vector3 transform_to_postion(int number_edge)
{
Vector3 xyz_of_edge = new Vector3();
//check which one it is and then set the xyz
if (number_edge == 0)
{
xyz_of_edge.x = xyz.x + 0.5f;
xyz_of_edge.y = xyz.y;
xyz_of_edge.z = xyz.z + 1f;
}
else if (number_edge == 1)
{
xyz_of_edge.x = xyz.x + 1f;
xyz_of_edge.y = xyz.y;
xyz_of_edge.z = xyz.z + 0.5f;
}
else if (number_edge == 2)
{
xyz_of_edge.x = xyz.x + 0.5f;
xyz_of_edge.y = xyz.y;
xyz_of_edge.z = xyz.z;
}
else if (number_edge == 3)
{
xyz_of_edge.x = xyz.x;
xyz_of_edge.y = xyz.y;
xyz_of_edge.z = xyz.z + 0.5f;
}
else if (number_edge == 4)
{
xyz_of_edge.x = xyz.x + 0.5f;
xyz_of_edge.y = xyz.y + 1f;
xyz_of_edge.z = xyz.z + 1f;
}
else if (number_edge == 5)
{
xyz_of_edge.x = xyz.x + 1f;
xyz_of_edge.y = xyz.y + 1f;
xyz_of_edge.z = xyz.z + 0.5f;
}
else if (number_edge == 6)
{
xyz_of_edge.x = xyz.x + 0.5f;
xyz_of_edge.y = xyz.y + 1f;
xyz_of_edge.z = xyz.z;
}
else if (number_edge == 7)
{
xyz_of_edge.x = xyz.x;
xyz_of_edge.y = xyz.y + 1;
xyz_of_edge.z = xyz.z + 0.5f;
}
else if (number_edge == 8)
{
xyz_of_edge.x = xyz.x;
xyz_of_edge.y = xyz.y + 0.5f;
xyz_of_edge.z = xyz.z + 1f;
}
else if (number_edge == 9)
{
xyz_of_edge.x = xyz.x + 1f;
xyz_of_edge.y = xyz.y + 0.5f;
xyz_of_edge.z = xyz.z + 1f;
}
else if (number_edge == 10)
{
xyz_of_edge.x = xyz.x + 1f;
xyz_of_edge.y = xyz.y + 0.5f;
xyz_of_edge.z = xyz.z;
}
else if (number_edge == 11)
{
xyz_of_edge.x = xyz.x;
xyz_of_edge.y = xyz.y + 0.5f;
xyz_of_edge.z = xyz.z;
}
//Debug.Log("edge index " + number_edge);
//Debug.Log("edges "+xyz_of_edge);
//Debug.Log(xyz_of_edge);
return xyz_of_edge;
}
}
I figured out that the problem was the way that I was labeling the points of the cube. I had had them wrong for the triangulation table this was causing the orientation error. to fix it all I did was in my code I redefined the points to there actual value.