Trying extrude a 2d polygon to create a mesh

I am trying to figure out how to go from a 2d polygon (stored as an array of Vector2) to an extruded mesh, but I am not sure if I am doing things correctly, because I do not see my object in the scene editor when I attempt to add it using test methods. I am unsure if the problem is how I am creating the mesh, or if it is related to my creating the corresponding gameobject. I am, at the moment, only interested in seeing a wireframe of the mesh in the editor… nothing more.

I am using csharp for scripting… if anyone can help me figure out what I am doing wrong, it would be greatly appreciated. The source code for the Triangulator class that I am using can be found here.

Thanks in advance.

....
	static Mesh CreateMesh(Vector2 [] poly)
	{
		// convert polygon to triangles
		Triangulator triangulator = new Triangulator(poly);
		int[] triangles = triangulator.Triangulate();
		Mesh m = new Mesh();
		m.vertices = new Vector3[poly.Length*2];
		for(int i=0;i<poly.Length;i++)
		{
			m.vertices[i].x = poly[i].x;
			m.vertices[i].y = poly[i].y;
			m.vertices[i].z = -10; // front vertex
			m.vertices[i+poly.Length].x = poly[i].x;
			m.vertices[i+poly.Length].y = poly[i].y;
			m.vertices[i+poly.Length].z = 10;	 // back vertex		
		}
		m.triangles = new int[triangles.Length*2+poly.Length*6];
		int count_tris = 0;
		for(int i=0;i<triangles.Length;i+=3)
		{
			m.triangles[i] = triangles[i];
			m.triangles[i+1] = triangles[i+1];
			m.triangles[i+2] = triangles[i+2];
		} // front vertices
		co/unt_tris+=triangles.Length;
		for(int i=0;i<triangles.Length;i+=3)
		{
			m.triangles[count_tris+i] = triangles[i+2]+poly.Length;
			m.triangles[count_tris+i+1] = triangles[i+1]+poly.Length;
			m.triangles[count_tris+i+2] = triangles[i]+poly.Length;
		} // back vertices
		count_tris+=triangles.Length;
		for(int i=0;i<poly.Length;i++)
		{
                       // triangles around the perimeter of the object
			int n = (i+1)%poly.Length;
			m.triangles[count_tris] = i;
			m.triangles[count_tris+1] = i + poly.Length;
			m.triangles[count_tris+2] = n;
			m.triangles[count_tris+3] = n;
			m.triangles[count_tris+4] = n + poly.Length;
			m.triangles[count_tris+5] = i + poly.Length;
			count_tris += 6;
		}
		m.RecalculateNormals();
		m.RecalculateBounds();
		m.Optimize();
		return m;
	}

        static void test()
        {
	        Mesh m = CreateMesh(polygon);
		GameObject gameObject = new GameObject();
	        gameObject.AddComponent(typeof(MeshRenderer));
	        MeshFilter filter = gameObject.AddComponent(typeof(MeshFilter)) as MeshFilter;
	        filter.mesh = m;
        }
...
1 Like

looks correct to me.
Does a new gameobject appear in the editor?
you can also try GameObject gameObject = new GameObject(“test”);
You can also try creating a prefab that already has the mesh renderer and the mesh filter. Then use Instantiate() to create the prefab and assign the mesh with GetComponent().mesh = m.

Thank you for your response. When I run my test function, although a new game object appears in the Hierarchy window, I cannot actually see it anything in the Scene window (which is currently set to Wireframe mode). It is evidently really there, because clicking on the object in the hierarchy window shows a tiny square and 3 axes in the Scene window, presumably where the object is situated, and which I can manipulate graphically, but I cannot actually see any of the object itself. The original polygon has units in the range of about ±100 in both the x and y axes.

Thanks again… any further assistance would be greatly appreciated.

try

static Mesh CreateMesh(Vector2 [] poly)
	{
		// convert polygon to triangles
		Triangulator triangulator = new Triangulator(poly);
		int[] tris = triangulator.Triangulate();
		Mesh m = new Mesh();
		Vector3[] vertices = new Vector3[poly.Length*2];
		
		for(int i=0;i<poly.Length;i++)
		{
			vertices[i].x = poly[i].x;
			vertices[i].y = poly[i].y;
			vertices[i].z = -10; // front vertex
			vertices[i+poly.Length].x = poly[i].x;
			vertices[i+poly.Length].y = poly[i].y;
			vertices[i+poly.Length].z = 10;	 // back vertex		
		}
		int[] triangles = new int[tris.Length*2+poly.Length*6];
		int count_tris = 0;
		for(int i=0;i<tris.Length;i+=3)
		{
			triangles[i] = tris[i];
			triangles[i+1] = tris[i+1];
			triangles[i+2] = tris[i+2];
		} // front vertices
		count_tris+=tris.Length;
		for(int i=0;i<tris.Length;i+=3)
		{
			triangles[count_tris+i] = tris[i+2]+poly.Length;
			triangles[count_tris+i+1] = tris[i+1]+poly.Length;
			triangles[count_tris+i+2] = tris[i]+poly.Length;
		} // back vertices
		count_tris+=tris.Length;
		for(int i=0;i<poly.Length;i++)
		{
          // triangles around the perimeter of the object
			int n = (i+1)%poly.Length;
			triangles[count_tris] = i;
			triangles[count_tris+1] = i + poly.Length;
			triangles[count_tris+2] = n;
			triangles[count_tris+3] = n;
			triangles[count_tris+4] = n + poly.Length;
			triangles[count_tris+5] = i + poly.Length;
			count_tris += 6;
		}
		m.vertices = vertices;
		m.triangles = triangles;
		m.RecalculateNormals();
		m.RecalculateBounds();
		m.Optimize();
		return m;
	}
1 Like

Thank you! That worked perfectly!

For anyone else who happens to stumble upon this code, there is an error that will give you only every other triangle around the perimeter. Just replace

          // triangles around the perimeter of the object
            int n = (i+1)%poly.Length;
            triangles[count_tris] = i;
            triangles[count_tris+1] = i + poly.Length;
            triangles[count_tris+2] = n;
            triangles[count_tris+3] = n;
            triangles[count_tris+4] = n + poly.Length;
            triangles[count_tris+5] = i + poly.Length;
            count_tris += 6;

with

            // triangles around the perimeter of the object
            int n = (i+1)%poly.Length;
            triangles[count_tris] = i;
            triangles[count_tris+1] = n;
            triangles[count_tris+2] = i + poly.Length;
            triangles[count_tris+3] = n;
            triangles[count_tris+4] = n + poly.Length;
            triangles[count_tris+5] = i + poly.Length;
            count_tris += 6;
2 Likes

What is polygon in line 55?

for me the normals were flipped on the sides but this worked

            // triangles around the perimeter of the object
            int n = (i+1)%poly.Length;
            triangles[count_tris] = i;
            triangles[count_tris+1] = n;
            triangles[count_tris+2] = i + poly.Length;
            triangles[count_tris+3] = n;
            triangles[count_tris+4] = i + poly.Length;
            triangles[count_tris+5] = n + poly.Length;
            count_tris += 6;

EDIT: ok now the other code works for this new shape… no clue whats going on…

“EDIT: ok now the other code works for this new shape… no clue whats going on…”

Guys, the reason that makes you all have “different” behaviour with the same code (and thus, make you all have a different version of the code to work for your mesh) is simple:

It is dependant of the way you defined your points. If the points in your Vector2 array are listed clockwise (or anti-clockwise) the sides of the mesh will have a normal pointing inside (or outside) of the mesh.

To find out if a list of polygon points are listed clockwise or not, you need to sum the angle between each point.
There is a simple geometric rule that says: The sum of all the N interior angle of any polygon is equal to (n-2) × 180°
Thus, you can deduce if the list is in clockwise order or anti-clockwise.

Thanks for the code, it works great – but how do I flip the bridging triangle normals, as seemingly every second is wrong for me? (Also asked at StackOverflow.)

Edit: The answer is now provided in above-mentioned StackOverflow, and works great.

Hello, newbie question.
Is there a way of modify this to use as sprite mask?
my basic idea is use the 2d polygon to generate a sprite mask.
I need to create a lot of shapes for use as mask, but the “photoshop” way is really slower because of the quantity.