Example #1
0
        public static void GenerateRingMesh(
            List <Vector3> ring, MeshPart part, Vector3 normal, bool side, Vector2?innerUV, bool addNormals = false
            )
        {
            bool addUVs = innerUV != null;

            // List<List<Vector3>> reduceHist = new List<List<Vector3>>();
            // reduceHist.Add(ring);

            int indStart = part.vertices.Count;

            part.vertices.AddRange(ring);
            if (addUVs || addNormals)
            {
                foreach (var _ in ring)
                {
                    if (addUVs)
                    {
                        part.uvs.Add(innerUV.Value);
                    }
                    if (addNormals)
                    {
                        part.normals.Add(side ? -normal : normal);
                    }
                }
            }

            List <Tuple <Vector3, int> > set = ring.ConvertAll(v => new Tuple <Vector3, int>(v, indStart++));

            int  i = -1, lsc = set.Count;
            bool didInf = false;

            while (set.Count > 1)
            {
                i++;
                if (i >= set.Count)
                {
                    if (lsc == set.Count)
                    {
                        if (didInf)
                        {
                            // Debug.LogError("ear clipping failed");
                            // DebugRings(reduceHist);
                            // Debug.Log("normal "+(normal*1000));
                            // DebugRing(set.ConvertAll(s=>s.Item1));
                            throw MeshUtilsException.Internal("Ear clipping failed");
                        }
                        didInf = true;
                    }
                    else
                    {
                        didInf = false;
                    }
                    lsc = set.Count;
                }
                i %= set.Count;

                Tuple <Vector3, int> vi0 = set[i],
                                     vi1 = set[(i + 1) % set.Count],
                                     vi2 = set[(i + 2) % set.Count];
                Vector3 d1 = vi1.Item1 - vi0.Item1; // i0 -> i1
                Vector3 d2 = vi2.Item1 - vi0.Item1; // i0 -> i2

                // we assume points do not lie in a line (see SimplifyRing)
                // if they do however, it's just a waste of vertices

                // check convex ear
                float conv = Vector3.Dot(Vector3.Cross(d1.normalized, d2.normalized), normal);
                if (conv > 0)
                {
                    continue;
                }

                // check that there are no other vertices inside this triangle
                if (set.Exists(v => {
                    // note: we must compare the vectors, otherwise coinciding vectors do not
                    // register as being the same
                    if (v.Item1 == vi0.Item1 || v.Item1 == vi1.Item1 || v.Item1 == vi2.Item1)
                    {
                        return(false);
                    }
                    return(VectorUtil.CheckIsInside(d1, d2, v.Item1 - vi0.Item1));
                }))
                {
                    continue;
                }

                // generate indices
                if (side)
                {
                    part.indices.Add(vi0.Item2);
                    part.indices.Add(vi1.Item2);
                    part.indices.Add(vi2.Item2);
                }
                else
                {
                    part.indices.Add(vi0.Item2);
                    part.indices.Add(vi2.Item2);
                    part.indices.Add(vi1.Item2);
                }

                // eliminate vertex
                set.RemoveAt((++i) % set.Count);
                i++;

                // reduceHist.Add(set.ConvertAll(s=>s.Item1));
            }
        }