Unity3D Building Damage Tutorial- Part V b - Thick Mesh in diffrent way

Well, I was wandering how to implement damage in thick mesh, and i realized that making mesh thick can be implemented much easier. In previous part  I manually edited the Aliases List, Triangle LIst, VTAA, and then mesh.triangles and mesh.verticles. But really, we can just edit the last two, and than re-construct our mesh using methods in constructor. Some parts of previous tutorials will be used, some not.

To have "thick"  meshes we will have to: Thats all.
 * 1) Add "twin" verticles
 * 2) Add "twin" triangles
 * 3) Update lists and VerticleToAliasArray (VTAA)

Twins
When i was writing this tutorial, I named some certain things "twins". My idea is that we will make, internal, inverted mesh. It will have the same amount of triangles and vertices. The "twin" verticle will be a verticle "made of" original verticle and than moved. Its number will be number of original + offset. Similarly "twin" triangles and Aliases are made.

Offseting
So, when i was thinking about this, i realised of something. Lets say, that we have a simple cube, like than in  that picture. It has 8 Aliases. Lets say of numbers 1-8. '''In fact, they would have numbers 0-7, but i have made a mistake. '''

In addition 12 triangles and 36 verticles. Than, we add inside "twin cube". An offset of Aliases would be its number in pervious cube, in this case 8. An twin of Alias number 2 would be 2 + 8 = 10. In that way we can easily calculate numbers of every twin. A twin of triangle number 10 would be 10+12 = 22. etc. 



MakeMeshThick Method
Well, the starting method. It will be called lets say in StartFire, so when player clicks on the building. public void MakeMeshThick{ AddTwinsToVerticleArray; AddTwinsToTriangleAlias; Initialise; ManageVerticles(mesh.vertices); ManageTriangles(mesh.triangles); CalcualateMinimumHeight; for(int i=Aliases.Count/2; i<Aliases.Count; i++){ Aliases[i].IsATwin = true; } 		IsMeshThick = true; }

AddTwinsToVerticleArray method
private void AddTwinsToVerticleArray{ Vector3[] OldVerticleList = mesh.vertices; Vector3[] NewVerticleList = new Vector3[OldVerticleList.Length]; float Wall_Thickness = 0.005f; Vector3 TargetPosition; Vector3 NewPosition ; for(int i=0; i<OldVerticleList.Length; i++){ TargetPosition = mesh.vertices[i] - mesh.normals[i]; NewPosition = Vector3.MoveTowards(mesh.vertices[i], TargetPosition, Wall_Thickness); NewVerticleList[i] = NewPosition; } 		Vector3[] final = new Vector3[OldVerticleList.Length + NewVerticleList.Length]; OldVerticleList.CopyTo(final, 0); NewVerticleList.CopyTo(final, OldVerticleList.Length); mesh.vertices = final; } Okay, the this method will just copy  things from mesh.vertices, than change the position (as mesh.vertices in a Vector3 array with vertices position) 		Vector3[] OldVerticleList = mesh.vertices; 		Vector3[] NewVerticleList = new Vector3[OldVerticleList.Length]; float Wall_Thickness = 0.005f; Vector3 TargetPosition; Vector3 NewPosition ; NewPosition = Vector3.MoveTowards(mesh.vertices[i], TargetPosition, Wall_Thickness); NewVerticleList[i] = NewPosition; Two lines, two intresting things. First, i count TargetPosition, by decreasing the relativePosition of verticle by the normal value. (Decreasing!. We want a point inside the mesh, not outside.)
 * here we just make two arrays, of the same lenght. OldVerticleList will just store the original position of vertices
 * Hard coded distance between an Alias and its twin. Later, I'll change it, and will not be hard coded of course.
 * Two Vector3. Will be used later.
 * Here I just count the offset.
 * This is Vertex_normals.pngsting. But before I am going to explain this, simple question. How we are going to know, which way we should move the Alias, for it to be "in" the mesh. First, i thought about scaling, but that was working well only with simple meshes with its "center" position in absolute inside. Than, I found out about vertex normals. More specific data can be found on wiki. What is intresting for us, is that in mesh.normals there are some specific vector3 for every variable. This are vectors pointing outside from the mesh, like in the picture. Using then, we can easily count the twin position.

Vector3[] final = new Vector3[OldVerticleList.Length + NewVerticleList.Length]; Vector3[] final = new Vector3[OldVerticleList.Length + NewVerticleList.Length]; OldVerticleList.CopyTo(final, 0); NewVerticleList.CopyTo(final, OldVerticleList.Length); mesh.vertices = final; Merging two arrays and setting the result as vertices. AddTwinsToTriangleArray method	private void AddTwinsToTriangleAlias{ int[] OldTriangleList = mesh.triangles; int[] NewTriangleList = new int [OldTriangleList.Length]; int offset = (mesh.vertices.Length/2); for(int i=0; i<OldTriangleList.Length; i+=3){ NewTriangleList[i] = OldTriangleList[ i + 2 ] + offset; NewTriangleList[i+1] = OldTriangleList[ i + 1 ] + offset; NewTriangleList[i+2] = OldTriangleList[ i ] + offset; } 		int[] final = new int[OldTriangleList.Length + NewTriangleList.Length]; OldTriangleList.CopyTo(final, 0); NewTriangleList.CopyTo(final, OldTriangleList.Length); mesh.triangles = final; } Okay, here we will add the twin trinagles to array and invert them. int offset = (mesh.vertices.Length/2); You know what offset is, but why here the lenght of array is divided by 2? Becouse we have arleady added the twin vertices! for(int i=0; i<OldTriangleList.Length; i+=3){ NewTriangleList[i] = OldTriangleList[ i + 2 ] + offset; NewTriangleList[i+1] = OldTriangleList[ i + 1 ] + offset; NewTriangleList[i+2] = OldTriangleList[ i ] + offset; } Before I'll go to code, it is how had I inverted triangles. Well, apparently one way to invertthem is to invert the order of verticles in mesh.triangles. From mesh.triangles = new int[] {0,1,3 , 1,2,5 ....} to {3,1,0  ,  5,2,1,  ....}. It works and by doing that we preserve the original numbers of triangles. (The twin triangle of triangle number 3 would be 3 + offset(the original number of triangles), but it would face other direction.)

int[] final = new int[OldTriangleList.Length + NewTriangleList.Length];                                 int[] final = new int[OldTriangleList.Length + NewTriangleList.Length]; OldTriangleList.CopyTo(final, 0); NewTriangleList.CopyTo(final, OldTriangleList.Length); mesh.triangles = final; Merging two arrays and updating mesh.triangles.

Back to MakeMeshThick method
Now, we have edited mesh. Our custom list have to be updated. Initialise; ManageVerticles(mesh.vertices); ManageTriangles(mesh.triangles); CalcualateMinimumHeight; Starting the methods from constructor. This Initialise and  CalculateMinimumHeight are not really necessary, but i put them here. for(int i=Aliases.Count/2; iEnding
Now, if we look into a mesh there will be untextured area, as uv has not been yet changed. For files, go to Github .