Пример #1
0
    public void BuildMesh()
    {
        if (path == null)
        {
            path = GetComponent <PathBase>();
        }

        mf = GetComponent <MeshFilter>();

        if (mf && path)
        {
            if (mf.sharedMesh != null)
            {
                DestroyImmediate(mf.sharedMesh);
            }

            if (mesh == null)
            {
                mesh = new Mesh();
            }
            else
            {
                mesh.Clear();
            }

            if (markDynamic)
            {
                mesh.MarkDynamic();
            }

            verts.Clear();
            indices.Clear();
            normals.Clear();
            uvs.Clear();
            colors.Clear();

            Vector3 lastPos = path.GetPoint(0f);

            Vector3 normal = -path.GetDirection(0f);
            verts.Add(transform.InverseTransformPoint(lastPos + normal * path.Radius / 2f));
            normals.Add(transform.InverseTransformVector(normal));
            uvs.Add(new Vector2(0f, 0f));

            if (colorVerts)
            {
                colors.Add(colorGradient.Evaluate(0f));
            }

            pathLength = path.GetLength() * fillAmount;

            dists.Clear();
            iters.Clear();

            iters.Add(0f);
            dists.Add(0f);

            float totalDist = 0f;

            float iter = 0f;
            while (iter < fillAmount)
            {
                float moveDist = spacing;
                while (moveDist > 0f && iter < fillAmount)
                {
                    float prevIter = iter;
                    iter += alphaIter;
                    iter  = Mathf.Clamp(iter, 0f, fillAmount);

                    Vector3 pos       = path.GetPoint(iter);
                    Vector3 toPos     = pos - lastPos;
                    float   toPosDist = toPos.magnitude;

                    if (toPosDist < moveDist)
                    {
                        moveDist  -= toPosDist;
                        totalDist += toPosDist;

                        lastPos = pos;
                    }
                    else
                    {
                        float alpha = moveDist / toPosDist;
                        iter    = Mathf.Lerp(prevIter, iter, alpha);
                        lastPos = Vector3.Lerp(lastPos, pos, alpha);

                        iters.Add(iter);

                        totalDist += moveDist;
                        dists.Add(totalDist);

                        moveDist = 0f;
                    }
                }
            }

            iters.Add(fillAmount);
            dists.Add(totalDist);

            LinePath linePath = path as LinePath;
            if (linePath)
            {
                // THIS IS A BAD ATTEMPT AT MAKING LINEPATHS WORK. NOT OFFICIALLY SUPPORTED
                int   numPoints     = linePath.Loop ? linePath.Points.Length : (linePath.Points.Length - 1);
                float alphaPerPoint = fillAmount / (float)numPoints;

                pointDirs.Clear();
                pointIters.Clear();
                for (int i = 1; i < numPoints; i++)
                {
                    float   alpha   = alphaPerPoint * i;
                    Vector3 preDir  = linePath.GetDirection(alpha - SplineUtils.DefaultTraverseAlphaSpeed);
                    Vector3 postDir = linePath.GetDirection(alpha + SplineUtils.DefaultTraverseAlphaSpeed);

                    Vector3 dir = (preDir + postDir) / 2f;
                    pointDirs.Add(dir);
                    pointIters.Add(alpha);

                    for (int j = 0; j < iters.Count; j++)
                    {
                        if (iters[j] > alpha)
                        {
                            iters.Insert(j, alpha);
                            dists.Insert(j, alpha);                             // Cursed
                            break;
                        }
                    }
                }

                for (int i = 0; i < iters.Count; i++)
                {
                    Vector3 direction = path.GetDirection(iters[i]);

                    float   nearestDist = Mathf.Infinity;
                    Vector3 nearestDir  = direction;
                    for (int j = 0; j < pointIters.Count; j++)
                    {
                        float iterDist = Mathf.Abs(pointIters[j] - iters[i]);
                        if (iterDist < nearestDist && iterDist < lineCornerFalloff)
                        {
                            float alpha = Mathf.InverseLerp(lineCornerFalloff, 0f, iterDist);
                            nearestDir  = Vector3.Lerp(direction, pointDirs[j], alpha);
                            nearestDist = iterDist;
                        }
                    }

                    AddEdgeLoop(iters[i], i, nearestDir);
                }
            }
            else
            {
                for (int i = 0; i < iters.Count; i++)
                {
                    AddEdgeLoop(iters[i], i);
                }
            }

            normal = path.GetDirection(fillAmount);
            verts.Add(transform.InverseTransformPoint(lastPos + normal * path.Radius / 2f));
            uvs.Add(new Vector2(1, pathLength));
            normals.Add(transform.InverseTransformVector(normal));

            if (colorVerts)
            {
                colors.Add(colorGradient.Evaluate(1f));
            }

            mesh.SetVertices(verts);
            mesh.SetTriangles(indices, 0);
            mesh.SetNormals(normals);
            mesh.SetUVs(0, uvs);

            if (colorVerts)
            {
                mesh.SetColors(colors);
            }

            mf.sharedMesh = mesh;

            OnMeshChanged(this);
        }
    }