Advertisement
Bunny83

MeshHelper.cs

Jan 11th, 2023
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.65 KB | Source Code | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4.  
  5. public static class MeshHelper
  6. {
  7.     static List<Vector3> vertices;
  8.     static List<Vector3> normals;
  9.     static List<Color> colors;
  10.     static List<Vector2> uv;
  11.     static List<Vector2> uv1;
  12.     static List<Vector2> uv2;
  13.  
  14.     static List<int> indices;
  15.     static Dictionary<uint,int> newVectices;
  16.  
  17.     static void InitArrays(Mesh mesh)
  18.     {
  19.         vertices = new List<Vector3>(mesh.vertices);
  20.         normals = new List<Vector3>(mesh.normals);
  21.         colors = new List<Color>(mesh.colors);
  22.         uv  = new List<Vector2>(mesh.uv);
  23.         uv1 = new List<Vector2>(mesh.uv1);
  24.         uv2 = new List<Vector2>(mesh.uv2);
  25.         indices = new List<int>();
  26.     }
  27.     static void CleanUp()
  28.     {
  29.         vertices = null;
  30.         normals = null;
  31.         colors = null;
  32.         uv  = null;
  33.         uv1 = null;
  34.         uv2 = null;
  35.         indices = null;
  36.     }
  37.  
  38.     #region Subdivide4 (2x2)
  39.     static int GetNewVertex4(int i1, int i2)
  40.     {
  41.         int newIndex = vertices.Count;
  42.         uint t1 = ((uint)i1 << 16) | (uint)i2;
  43.         uint t2 = ((uint)i2 << 16) | (uint)i1;
  44.         if (newVectices.ContainsKey(t2))
  45.             return newVectices[t2];
  46.         if (newVectices.ContainsKey(t1))
  47.             return newVectices[t1];
  48.  
  49.         newVectices.Add(t1,newIndex);
  50.  
  51.         vertices.Add((vertices[i1] + vertices[i2]) * 0.5f);
  52.         if (normals.Count>0)
  53.             normals.Add((normals[i1] + normals[i2]).normalized);
  54.         if (colors.Count>0)
  55.             colors.Add((colors[i1] + colors[i2]) * 0.5f);
  56.         if (uv.Count>0)
  57.             uv.Add((uv[i1] + uv[i2])*0.5f);
  58.         if (uv1.Count>0)
  59.             uv1.Add((uv1[i1] + uv1[i2])*0.5f);
  60.         if (uv2.Count>0)
  61.             uv2.Add((uv2[i1] + uv2[i2])*0.5f);
  62.  
  63.         return newIndex;
  64.     }
  65.  
  66.  
  67.     /// <summary>
  68.     /// Devides each triangles into 4. A quad(2 tris) will be splitted into 2x2 quads( 8 tris )
  69.     /// </summary>
  70.     /// <param name="mesh"></param>
  71.     public static void Subdivide4(Mesh mesh)
  72.     {
  73.         newVectices = new Dictionary<uint,int>();
  74.  
  75.         InitArrays(mesh);
  76.  
  77.         int[] triangles = mesh.triangles;
  78.         for (int i = 0; i < triangles.Length; i += 3)
  79.         {
  80.             int i1 = triangles[i + 0];
  81.             int i2 = triangles[i + 1];
  82.             int i3 = triangles[i + 2];
  83.  
  84.             int a = GetNewVertex4(i1, i2);
  85.             int b = GetNewVertex4(i2, i3);
  86.             int c = GetNewVertex4(i3, i1);
  87.             indices.Add(i1);   indices.Add(a);   indices.Add(c);
  88.             indices.Add(i2);   indices.Add(b);   indices.Add(a);
  89.             indices.Add(i3);   indices.Add(c);   indices.Add(b);
  90.             indices.Add(a );   indices.Add(b);   indices.Add(c); // center triangle
  91.         }
  92.         mesh.vertices = vertices.ToArray();
  93.         if (normals.Count > 0)
  94.             mesh.normals = normals.ToArray();
  95.         if (colors.Count>0)
  96.             mesh.colors = colors.ToArray();
  97.         if (uv.Count>0)
  98.             mesh.uv = uv.ToArray();
  99.         if (uv1.Count>0)
  100.             mesh.uv1 = uv1.ToArray();
  101.         if (uv2.Count>0)
  102.             mesh.uv2 = uv2.ToArray();
  103.  
  104.         mesh.triangles = indices.ToArray();
  105.  
  106.         CleanUp();
  107.     }
  108.     #endregion Subdivide4 (2x2)
  109.  
  110.     #region Subdivide9 (3x3)
  111.     static int GetNewVertex9(int i1, int i2, int i3)
  112.     {
  113.         int newIndex = vertices.Count;
  114.  
  115.         // center points don't go into the edge list
  116.         if (i3 == i1 || i3 == i2)
  117.         {
  118.             uint t1 = ((uint)i1 << 16) | (uint)i2;
  119.             if (newVectices.ContainsKey(t1))
  120.                 return newVectices[t1];
  121.             newVectices.Add(t1,newIndex);
  122.         }
  123.  
  124.         // calculate new vertex
  125.         vertices.Add((vertices[i1] + vertices[i2] + vertices[i3]) / 3.0f);
  126.         if (normals.Count>0)
  127.             normals.Add((normals[i1] + normals[i2] + normals [i3]).normalized);
  128.         if (colors.Count>0)
  129.             colors.Add((colors[i1] + colors[i2] + colors[i3]) / 3.0f);
  130.         if (uv.Count>0)
  131.             uv.Add((uv[i1] + uv[i2] + uv[i3]) / 3.0f);
  132.         if (uv1.Count>0)
  133.             uv1.Add((uv1[i1] + uv1[i2] + uv1[i3]) / 3.0f);
  134.         if (uv2.Count>0)
  135.             uv2.Add((uv2[i1] + uv2[i2] + uv2[i3]) / 3.0f);
  136.         return newIndex;
  137.     }
  138.  
  139.  
  140.     /// <summary>
  141.     /// Devides each triangles into 9. A quad(2 tris) will be splitted into 3x3 quads( 18 tris )
  142.     /// </summary>
  143.     /// <param name="mesh"></param>
  144.     public static void Subdivide9(Mesh mesh)
  145.     {
  146.         newVectices = new Dictionary<uint,int>();
  147.  
  148.         InitArrays(mesh);
  149.  
  150.         int[] triangles = mesh.triangles;
  151.         for (int i = 0; i < triangles.Length; i += 3)
  152.         {
  153.             int i1 = triangles[i + 0];
  154.             int i2 = triangles[i + 1];
  155.             int i3 = triangles[i + 2];
  156.  
  157.             int a1 = GetNewVertex9(i1, i2, i1);
  158.             int a2 = GetNewVertex9(i2, i1, i2);
  159.             int b1 = GetNewVertex9(i2, i3, i2);
  160.             int b2 = GetNewVertex9(i3, i2, i3);
  161.             int c1 = GetNewVertex9(i3, i1, i3);
  162.             int c2 = GetNewVertex9(i1, i3, i1);
  163.  
  164.             int d  = GetNewVertex9(i1, i2, i3);
  165.  
  166.             indices.Add(i1);   indices.Add(a1);   indices.Add(c2);
  167.             indices.Add(i2);   indices.Add(b1);   indices.Add(a2);
  168.             indices.Add(i3);   indices.Add(c1);   indices.Add(b2);
  169.             indices.Add(d );   indices.Add(a1);   indices.Add(a2);
  170.             indices.Add(d );   indices.Add(b1);   indices.Add(b2);
  171.             indices.Add(d );   indices.Add(c1);   indices.Add(c2);
  172.             indices.Add(d );   indices.Add(c2);   indices.Add(a1);
  173.             indices.Add(d );   indices.Add(a2);   indices.Add(b1);
  174.             indices.Add(d );   indices.Add(b2);   indices.Add(c1);
  175.         }
  176.  
  177.         mesh.vertices = vertices.ToArray();
  178.         if (normals.Count > 0)
  179.             mesh.normals = normals.ToArray();
  180.         if (colors.Count>0)
  181.             mesh.colors = colors.ToArray();
  182.         if (uv.Count>0)
  183.             mesh.uv = uv.ToArray();
  184.         if (uv1.Count>0)
  185.             mesh.uv1 = uv1.ToArray();
  186.         if (uv2.Count>0)
  187.             mesh.uv2 = uv2.ToArray();
  188.  
  189.         mesh.triangles = indices.ToArray();
  190.  
  191.         CleanUp();
  192.     }
  193.     #endregion Subdivide9 (3x3)
  194.  
  195.  
  196.     #region Subdivide
  197.     /// <summary>
  198.     /// This functions subdivides the mesh based on the level parameter
  199.     /// Note that only the 4 and 9 subdivides are supported so only those divides
  200.     /// are possible. [2,3,4,6,8,9,12,16,18,24,27,32,36,48,64, ...]
  201.     /// The function tried to approximate the desired level
  202.     /// </summary>
  203.     /// <param name="mesh"></param>
  204.     /// <param name="level">Should be a number made up of (2^x * 3^y)
  205.     /// [2,3,4,6,8,9,12,16,18,24,27,32,36,48,64, ...]
  206.     /// </param>
  207.     public static void Subdivide(Mesh mesh, int level)
  208.     {
  209.         if (level < 2)
  210.             return;
  211.         while (level > 1)
  212.         {
  213.             // remove prime factor 3
  214.             while (level % 3 == 0)
  215.             {
  216.                 Subdivide9(mesh);
  217.                 level /= 3;
  218.             }
  219.             // remove prime factor 2
  220.             while (level % 2 == 0)
  221.             {
  222.                 Subdivide4(mesh);
  223.                 level /= 2;
  224.             }
  225.             // try to approximate. All other primes are increased by one
  226.             // so they can be processed
  227.             if (level > 3)
  228.                 level++;
  229.         }
  230.     }
  231.     #endregion Subdivide
  232.  
  233.     public static Mesh DuplicateMesh(Mesh mesh)
  234.     {
  235.         return (Mesh)UnityEngine.Object.Instantiate(mesh);
  236.     }
  237. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement