josemorval

Ear clipping generate polygon mesh collider from points

Apr 10th, 2016
186
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 2.86 KB | None | 0 0
  1. public void CreateMeshCollider(){
  2.  
  3.     meshCollider = new Mesh();
  4.     List<PosIndPolygon> posInPolygon = new List<PosIndPolygon>();
  5.     List<int> triIndex = new List<int>();
  6.  
  7.     //In the next loop we use shoelace formula to know the orientation of the polygon
  8.     //https://en.wikipedia.org/wiki/Shoelace_formula
  9.  
  10.     float s = 0f;
  11.     for(int i=0;i<verts.Length-1;i++){
  12.         PosIndPolygon aux;
  13.         aux.pos = verts[i];
  14.         aux.ind = i;
  15.         posInPolygon.Add(aux);
  16.         s+=verts[i].x*(verts[(i+1)%(verts.Length-1)].z-verts[(i-1+verts.Length-1)%(verts.Length-1)].z);
  17.     }
  18.        
  19.     while(posInPolygon.Count>threshold){
  20.  
  21.         int k = Random.Range(0,posInPolygon.Count);
  22.         bool triangleObtained = false;
  23.  
  24.         while(!triangleObtained){
  25.  
  26.  
  27.             int ind1 = (k-(int)Mathf.Sign(s)*1+posInPolygon.Count)%posInPolygon.Count;
  28.             int ind2 = (k+posInPolygon.Count)%posInPolygon.Count;
  29.             int ind3 = (k+(int)Mathf.Sign(s)*1+posInPolygon.Count)%posInPolygon.Count;
  30.  
  31.             //Asumimos que los vectores se encuentran en el plano XZ
  32.             Vector3 v1 = posInPolygon[ind2].pos-posInPolygon[ind1].pos;
  33.             Vector3 v2 = posInPolygon[ind3].pos-posInPolygon[ind2].pos;
  34.            
  35.             float f = Mathf.Atan2(v2.z,v2.x)-Mathf.Atan2(v1.z,v1.x);
  36.             if(f<0f) f+= 2F*Mathf.PI;
  37.  
  38.             triangleObtained = true;
  39.  
  40.             if(f<=Mathf.PI && f>0f){
  41.  
  42.                 for(int i=0;i<posInPolygon.Count;i++){
  43.                     if(i!=ind1 && i!=ind2 && i!=ind3){
  44.                         if(CheckIfPointInTriangle(posInPolygon[ind1].pos,posInPolygon[ind2].pos,posInPolygon[ind3].pos,posInPolygon[i].pos)){
  45.                             triangleObtained = false;
  46.                             break;
  47.                         }
  48.                     }
  49.                 }
  50.  
  51.             }else{
  52.                
  53.                 triangleObtained = false;
  54.             }
  55.  
  56.             if(triangleObtained){
  57.  
  58.                 triIndex.Add(posInPolygon[ind1].ind);
  59.                 triIndex.Add(posInPolygon[ind2].ind);
  60.                 triIndex.Add(posInPolygon[ind3].ind);
  61.  
  62.                 posInPolygon.RemoveAt(ind2);
  63.  
  64.             }else{
  65.                 k++;
  66.                 k%=posInPolygon.Count;
  67.             }
  68.                                    
  69.         }
  70.  
  71.     }
  72.  
  73.     meshCollider.vertices = verts;
  74.     meshCollider.SetIndices(triIndex.ToArray(),MeshTopology.Triangles,0);
  75.     collider.sharedMesh = meshCollider;
  76.  
  77. }
  78.  
  79.  
  80. //https://blogs.msdn.microsoft.com/rezanour/2011/08/07/barycentric-coordinates-and-point-in-triangle-tests/
  81. public bool CheckIfPointInTriangle(Vector3 A, Vector3 B, Vector3 C, Vector3 P)
  82. {
  83.     // Prepare our barycentric variables
  84.     Vector3 u = B-A;
  85.     Vector3 v = C-A;
  86.     Vector3 w = P-A;
  87.  
  88.     Vector3 vCrossW = Vector3.Cross(v, w);
  89.     Vector3 vCrossU = Vector3.Cross(v, u);
  90.  
  91.     // Test sign of r
  92.     if (Vector3.Dot(vCrossW, vCrossU) < 0)
  93.         return false;
  94.  
  95.     Vector3 uCrossW = Vector3.Cross(u, w);
  96.     Vector3 uCrossV = Vector3.Cross(u, v);
  97.  
  98.     // Test sign of t
  99.     if (Vector3.Dot(uCrossW, uCrossV) < 0)
  100.         return false;
  101.  
  102.     // At this point, we know that r and t and both > 0.
  103.     // Therefore, as long as their sum is <= 1, each must be less <= 1
  104.     float denom = uCrossV.magnitude;
  105.     float r = vCrossW.magnitude / denom;
  106.     float t = uCrossW.magnitude / denom;
  107.  
  108.  
  109.     return (r + t <= 1);
  110. }
Advertisement
Add Comment
Please, Sign In to add comment