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;
}
...
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.
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;
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.