ProceduralPrimitives

From Unify Community Wiki
Revision as of 17:33, 23 January 2013 by Berenger (Talk | contribs)

Jump to: navigation, search

Author: Bérenger.

Contents

Description

Use those scripts to procedurally create primitive meshes, with custom parameters. More to come later. If anyone has the code for a teapot, that'd be great. I guess it's a tiny bit more complicated though.

Usage

The entry point of those script must be a reference to a meshfilter's mesh. The return value is that mesh filled up.


C# - Plane

// You can change that line to provide another MeshFilter
MeshFilter filter = gameObject.AddComponent< MeshFilter >();
Mesh mesh = filter.mesh;
mesh.Clear();
 
float length = 1f;
float width = 1f;
int resX = 2; // 2 minimum
int resZ = 2;
 
#region Vertices		
Vector3[] vertices = new Vector3[ resX * resZ ];
for(int z = 0; z < resZ; z++)
{
	// [ -length / 2, length / 2 ]
	float zPos = ((float)z / (resZ - 1) - .5f) * length;
	for(int x = 0; x < resX; x++)
	{
		// [ -width / 2, width / 2 ]
		float xPos = ((float)x / (resX - 1) - .5f) * width;
		vertices[ x + z * resX ] = new Vector3( xPos, 0f, zPos );
	}
}
#endregion
 
#region Normals		
Vector3[] normals = new Vector3[ vertices.Length ];
{
	for(int i = 0; i < normals.Length; i++)
		normals[i] = Vector3.up;
};
#endregion		
 
#region UVs		
Vector2[] uvs = new Vector2[ vertices.Length ];
for(int v = 0; v < resZ; v++)
{
	for(int u = 0; u < resX; u++)
	{
		uvs[ u + v * resX ] = new Vector2( (float)u / (resX - 1), (float)v / (resZ - 1) );
	}
}
#endregion
 
#region Triangles
int nbFaces = (resX - 1) * (resZ - 1);
int[] triangles = new int[ nbFaces * 6 ];
int t = 0;
for(int face = 0; face < nbFaces; n++ )
{
	// Retrieve lower left corner from face ind
	int i = face % (resX - 1) + (face / (resZ - 1) * resX);
 
	triangles[t++] = i + resX;
	triangles[t++] = i + 1;
	triangles[t++] = i;
 
	triangles[t++] = i + resX;	
	triangles[t++] = i + resX + 1;
	triangles[t++] = i + 1; 
}
#endregion
 
mesh.vertices = vertices;
mesh.normals = normals;
mesh.uv = uvs;
mesh.triangles = triangles;
 
mesh.RecalculateNormals();
mesh.RecalculateBounds();
mesh.Optimize();


C# - Box

// You can change that line to provide another MeshFilter
MeshFilter filter = gameObject.AddComponent< MeshFilter >();
Mesh mesh = filter.mesh;
mesh.Clear();
 
float length = 1f;
float width = 1f;
float height = 1f;
 
#region Vertices
Vector3 p0 = new Vector3( -length * .5f,	-width * .5f, height * .5f );
Vector3 p1 = new Vector3( length * .5f, 	-width * .5f, height * .5f );
Vector3 p2 = new Vector3( length * .5f, 	-width * .5f, -height * .5f );
Vector3 p3 = new Vector3( -length * .5f,	-width * .5f, -height * .5f );	
 
Vector3 p4 = new Vector3( -length * .5f,	width * .5f,  height * .5f );
Vector3 p5 = new Vector3( length * .5f, 	width * .5f,  height * .5f );
Vector3 p6 = new Vector3( length * .5f, 	width * .5f,  -height * .5f );
Vector3 p7 = new Vector3( -length * .5f,	width * .5f,  -height * .5f );
 
Vector3[] vertices = new Vector3[]
{
	// Bottom
	p0, p1, p2, p3,
 
	// Left
	p7, p4, p0, p3,
 
	// Front
	p4, p5, p1, p0,
 
	// Back
	p6, p7, p3, p2,
 
	// Right
	p5, p6, p2, p1,
 
	// Top
	p7, p6, p5, p4
};
#endregion
 
#region Normals
Vector3 up 	= Vector3.up;
Vector3 down 	= Vector3.down;
Vector3 front 	= Vector3.forward;
Vector3 back 	= Vector3.back;
Vector3 left 	= Vector3.left;
Vector3 right 	= Vector3.right;
 
Vector3[] normals = new Vector3[]
{
	// Bottom
	down, down, down, down,
 
	// Left
	left, left, left, left,
 
	// Front
	front, front, front, front,
 
	// Back
	back, back, back, back,
 
	// Right
	right, right, right, right,
 
	// Top
	up, up, up, up
};
#endregion		
 
#region UVs
Vector2 _00 = new Vector2( 0f, 0f );
Vector2 _10 = new Vector2( 1f, 0f );
Vector2 _01 = new Vector2( 0f, 1f );
Vector2 _11 = new Vector2( 1f, 1f );
 
Vector2[] uvs = new Vector2[]
{
	// Bottom
	_11, _01, _00, _10,
 
	// Left
	_11, _01, _00, _10,
 
	// Front
	_11, _01, _00, _10,
 
	// Back
	_11, _01, _00, _10,
 
	// Right
	_11, _01, _00, _10,
 
	// Top
	_11, _01, _00, _10,
};
#endregion
 
#region Triangles
int[] triangles = new int[]
{
	// Bottom
	3, 1, 0,
	3, 2, 1,			
 
	// Left
	3 + 4 * 1, 1 + 4 * 1, 0 + 4 * 1,
	3 + 4 * 1, 2 + 4 * 1, 1 + 4 * 1,
 
	// Front
	3 + 4 * 2, 1 + 4 * 2, 0 + 4 * 2,
	3 + 4 * 2, 2 + 4 * 2, 1 + 4 * 2,
 
	// Back
	3 + 4 * 3, 1 + 4 * 3, 0 + 4 * 3,
	3 + 4 * 3, 2 + 4 * 3, 1 + 4 * 3,
 
	// Right
	3 + 4 * 4, 1 + 4 * 4, 0 + 4 * 4,
	3 + 4 * 4, 2 + 4 * 4, 1 + 4 * 4,
 
	// Top
	3 + 4 * 5, 1 + 4 * 5, 0 + 4 * 5,
	3 + 4 * 5, 2 + 4 * 5, 1 + 4 * 5,
 
};
#endregion
 
mesh.vertices = vertices;
mesh.normals = normals;
mesh.uv = uvs;
mesh.triangles = triangles;
 
mesh.RecalculateNormals();
mesh.RecalculateBounds();
mesh.Optimize();


C# - Cone (in progress)

MeshFilter filter = gameObject.AddComponent<MeshFilter>();
Mesh mesh = filter.mesh;
mesh.Clear();
 
float height = 1f;
float bottomRadius = .25f;
float topRadius = .05f;
int nbSides = 18;
int nbHeightSeg = 1;
 
#region Vertices
 
// bottom + top + sides
Vector3[] vertices = new Vector3[(nbSides+1) + (nbSides+1) + nbSides * nbHeightSeg * 2];
int vert = 0;
float _2pi = Mathf.PI * 2f;
 
// Bottom cap
vertices[vert++] = new Vector3(0f, 0f, 0f);
while( vert <= nbSides )
{
    float rad = (float)vert / nbSides * _2pi;
    vertices[vert] = new Vector3(Mathf.Cos(rad) * bottomRadius, 0f, Mathf.Sin(rad) * bottomRadius);
    vert++;
}
 
// Top cap
vertices[vert++] = new Vector3(0f, height, 0f);
while (vert <= nbSides * 2 + 1)
{
    float rad = (float)(vert - nbSides - 1)  / nbSides * _2pi;
    vertices[vert] = new Vector3(Mathf.Cos(rad) * topRadius, height, Mathf.Sin(rad) * topRadius);
    vert++;
}
 
// Sides
int v = 0;
while (vert <= nbSides * 2 + nbSides * 2 + 1)
{
    float rad = (float)v / nbSides * _2pi;
    vertices[vert] = new Vector3(Mathf.Cos(rad) * topRadius, height, Mathf.Sin(rad) * topRadius);
    vertices[vert + 1] = new Vector3(Mathf.Cos(rad) * bottomRadius, 0, Mathf.Sin(rad) * bottomRadius);
    vert+=2;
    v++;
}
#endregion
 
vert = 0;
foreach (Vector3 pos in vertices)
    new GameObject((vert++).ToString()).transform.position = pos;
 
/*#region Normals
Vector3 up = Vector3.up;
Vector3 down = Vector3.down;
Vector3 front = Vector3.forward;
Vector3 back = Vector3.back;
Vector3 left = Vector3.left;
Vector3 right = Vector3.right;
 
Vector3[] normals = new Vector3[]
{
};
#endregion
 
#region UVs
Vector2 _00 = new Vector2(0f, 0f);
Vector2 _10 = new Vector2(1f, 0f);
Vector2 _01 = new Vector2(0f, 1f);
Vector2 _11 = new Vector2(1f, 1f);
 
Vector2[] uvs = new Vector2[]
{
};
#endregion*/
 
#region Triangles
int nbTriangles = nbSides + nbSides + nbSides*2;
int[] triangles = new int[nbTriangles * 3];
 
// Bottom cap
int tri = 0;
int i = 0;
while (tri < nbSides - 1)
{
    triangles[ i ] = 0;
    triangles[ i+1 ] = tri + 1;
    triangles[ i+2 ] = tri + 2;
    tri++;
    i += 3;
}
triangles[i] = 0;
triangles[i + 1] = tri + 1;
triangles[i + 2] = 1;
tri++;
i += 3;
 
// Top cap
//tri++;
while (tri < nbSides*2)
{
    triangles[ i ] = tri + 2;
    triangles[i + 1] = tri + 1;
    triangles[i + 2] = nbSides+1;
    tri++;
    i += 3;
}
triangles[i] = nbSides + 2;
triangles[i + 1] = tri + 1;
triangles[i + 2] = nbSides + 1;
tri++;
i += 3;
 
// Sides
while (tri < nbTriangles - 1)
{
    triangles[ i ] = tri;
    triangles[ i+1 ] = tri + 1;
    triangles[ i+2 ] = tri + 2;
    tri++;
    i += 3;
 
    triangles[ i ] = tri;
    triangles[ i+1 ] = tri + 2;
    triangles[ i+2 ] = tri + 1;
    tri++;
    i += 3;
}
UnityEngine.Debug.Log(tri);
UnityEngine.Debug.Log(i);
triangles[i] = tri;
triangles[i + 1] = tri+1;
triangles[i + 2] = tri + 2;
tri++;
i += 3;
 
// Array out of bounds, TODO
//triangles[i] = tri;
//triangles[i + 1] = tri + 2;
//triangles[i + 2] = tri + 1;
//tri++;
#endregion
 
mesh.vertices = vertices;
//mesh.normals = normals;
//mesh.uv = uvs;
mesh.triangles = triangles;
 
mesh.RecalculateNormals();
mesh.RecalculateBounds();
mesh.Optimize();
Personal tools
Namespaces

Variants
Actions
Navigation
Extras
Toolbox