Search Unity

Procedural path generating, advice on merging geometry where paths intersect? (lofting)

Discussion in 'Scripting' started by FisherM, Aug 29, 2015.

  1. FisherM

    FisherM

    Joined:
    Dec 28, 2013
    Posts:
    366
    So take a look at this post, should give you the ruff idea of what I'm up to.
    http://forum.unity3d.com/threads/generate-mesh-along-a-curved-line.199693/

    Much like the person making that post, you can see I am generating geometry along a spline.
    http://prntscr.com/8a82rz
    http://i.imgur.com/22iYDjL.png

    Which I apply further vert connections rules to get this
    http://prntscr.com/8a85jh
    (fyi it will end up being a train tunnel)

    Now my issue would be where these paths overlap and converge.
    I have a few thoughts on how to approach this, but does anyone have any helpful suggestions about making the geometry connect?
     
  2. MyIsaak

    MyIsaak

    Joined:
    May 23, 2013
    Posts:
    49
    Well a common method for mesh optimization is to weld nearby verticies by a threshold. But normally the problem arrises when the normals of the welded verticies aren't updated and can look weird, but luckily Unity has built in functions to fix this. Here is an example, similar to Blenders python wield script:
    Code (CSharp):
    1. public static void AutoWeld (Mesh mesh, float threshold, float bucketStep) {
    2.      Vector3[] oldVertices = mesh.vertices;
    3.      Vector3[] newVertices = new Vector3[oldVertices.Length];
    4.      int[] old2new = new int[oldVertices.Length];
    5.      int newSize = 0;
    6.      // Find AABB
    7.      Vector3 min = new Vector3 (float.MaxValue, float.MaxValue, float.MaxValue);
    8.      Vector3 max = new Vector3 (float.MinValue, float.MinValue, float.MinValue);
    9.      for (int i = 0; i < oldVertices.Length; i++) {
    10.        if (oldVertices[i].x < min.x) min.x = oldVertices[i].x;
    11.        if (oldVertices[i].y < min.y) min.y = oldVertices[i].y;
    12.        if (oldVertices[i].z < min.z) min.z = oldVertices[i].z;
    13.        if (oldVertices[i].x > max.x) max.x = oldVertices[i].x;
    14.        if (oldVertices[i].y > max.y) max.y = oldVertices[i].y;
    15.        if (oldVertices[i].z > max.z) max.z = oldVertices[i].z;
    16.      }
    17.      // Make cubic buckets, each with dimensions "bucketStep"
    18.      int bucketSizeX = Mathf.FloorToInt ((max.x - min.x) / bucketStep) + 1;
    19.      int bucketSizeY = Mathf.FloorToInt ((max.y - min.y) / bucketStep) + 1;
    20.      int bucketSizeZ = Mathf.FloorToInt ((max.z - min.z) / bucketStep) + 1;
    21.      List<int>[,,] buckets = new List<int>[bucketSizeX, bucketSizeY, bucketSizeZ];
    22.      // Make new vertices
    23.      for (int i = 0; i < oldVertices.Length; i++) {
    24.        // Determine which bucket it belongs to
    25.        int x = Mathf.FloorToInt ((oldVertices[i].x - min.x) / bucketStep);
    26.        int y = Mathf.FloorToInt ((oldVertices[i].y - min.y) / bucketStep);
    27.        int z = Mathf.FloorToInt ((oldVertices[i].z - min.z) / bucketStep);
    28.        // Check to see if it's already been added
    29.        if (buckets[x, y, z] == null)
    30.          buckets[x, y, z] = new List<int> (); // Make buckets lazily
    31.        for (int j = 0; j < buckets[x, y, z].Count; j++) {
    32.          Vector3 to = newVertices[buckets[x, y, z][j]] - oldVertices[i];
    33.          if (Vector3.SqrMagnitude (to) < threshold) {
    34.            old2new[i] = buckets[x, y, z][j];
    35.            goto skip; // Skip to next old vertex if this one is already there
    36.          }
    37.        }
    38.        // Add new vertex
    39.        newVertices[newSize] = oldVertices[i];
    40.        buckets[x, y, z].Add (newSize);
    41.        old2new[i] = newSize;
    42.        newSize++;
    43.      skip:;
    44.      }
    45.      // Make new triangles
    46.      int[] oldTris = mesh.triangles;
    47.      int[] newTris = new int[oldTris.Length];
    48.      for (int i = 0; i < oldTris.Length; i++) {
    49.        newTris[i] = old2new[oldTris[i]];
    50.      }
    51.    
    52.      Vector3[] finalVertices = new Vector3[newSize];
    53.      for (int i = 0; i < newSize; i++)
    54.        finalVertices[i] = newVertices[i];
    55.      mesh.Clear();
    56.      mesh.vertices = finalVertices;
    57.      mesh.triangles = newTris;
    58.      mesh.RecalculateNormals ();
    59.      mesh.Optimize ();
    60.    }
    Note I haven't tested this yet, since I wrote it on my phone. It's can be optimized obviously. Here you can see I used a 3D array that you can change the way the verticies are scanned with bucketSteps.