Exemplo n.º 1
0
        private Mesh GeneratePathMesh(PathData path)
        {
            Shape section;

            if (_crossSectionAsset != null)
            {
                section = _crossSectionAsset.shape;
            }
            else
            {
                section = Shape.defaultShape;
            }

            int sectionVertexCount = section.PointCount;

            if (sectionVertexCount < 2)
            {
                //Debug.LogWarning("Path cannot being generated, minimum 2 points are required");
                return(new Mesh());
            }

            int points = path.Length + (_loopCurve ? 1 : 0);

            Vector3[] vertices = new Vector3[sectionVertexCount * (points + (_subdivisions - 1) * (points - 1))];
            Vector2[] uvs      = new Vector2[vertices.Length];

            int shapeClosure = 1;

            int[] triangles = new int[((points - 1) * _subdivisions) * (6 * (sectionVertexCount - shapeClosure))];

            for (int p = 0, s = 0, t = 0; p < points - 1; p++)
            {
                for (int i = p > 0 ? 1 : 0; i <= _subdivisions; i++)
                {
                    //Calculates vertices
                    float curveT = (float)i / (float)_subdivisions;

                    Vector3 bezierPos  = path.GetBezierPosition(p, curveT);                    //Gets the positionon the bezier curve at t
                    Vector3 derivative = path.GetDerivativeDirection(p, curveT).normalized;    //Gets the derivative on the bézier curve at t

                    float   blendT = path[p].blend.Evaluate(curveT);
                    float   angle  = Mathf.Lerp(path[p].normalAngle, path[p + 1].normalAngle, blendT); //Gets the normal angle
                    Vector3 normal = Quaternion.AngleAxis(angle, Vector3.back) * path[p].normal;       //Calculates the normal
                    normal = Quaternion.LookRotation(derivative) * normal;                             //Applys derivative rotation to the normal

                    Quaternion secRotation = Quaternion.LookRotation(derivative, normal);
                    Vector2    pointScale  = Vector2.Lerp(path[p].scale, path[p + 1].scale, blendT);
                    pointScale = new Vector2(pointScale.x * _scale.x, pointScale.y * _scale.y);

                    //Debug.DrawRay(transform.position + path.GetBezierPosition(p, curveT), normal, Color.yellow);

                    float uvRes = ((float)s * _uvResolution) / _subdivisions;

                    //Vertices and Uvs
                    for (int vert = 0; vert < sectionVertexCount; vert++)
                    {
                        Vector2 pointPos = (Vector3)section.GetVerticePosition(vert);
                        pointPos.x *= pointScale.x;
                        pointPos.y *= pointScale.y;
                        vertices[s * sectionVertexCount + vert] = bezierPos + secRotation * (pointPos);
                        uvs[s * sectionVertexCount + vert]      = new Vector2(vert, uvRes);
                    }

                    //Draws triangle
                    if (s > 0)
                    {
                        int subdivIndex = (s - 1) * (sectionVertexCount);

                        for (int vert = 0; vert < sectionVertexCount - shapeClosure; vert++)
                        {
                            for (int tri = 0; tri < TRIS_DRAW_ORDER.Length; tri++)
                            {
                                int targetVert = TRIS_DRAW_ORDER[tri];

                                if (targetVert >= 2)
                                {
                                    targetVert += sectionVertexCount - 2;
                                }

                                if (vert != sectionVertexCount - 1 || (TRIS_DRAW_ORDER[tri] == 0 || TRIS_DRAW_ORDER[tri] == 2))
                                {
                                    targetVert = subdivIndex + targetVert + vert;
                                }
                                else if (vert == sectionVertexCount - 1 && (TRIS_DRAW_ORDER[tri] == 1 || TRIS_DRAW_ORDER[tri] == 3))
                                {
                                    targetVert = subdivIndex + targetVert - 1;
                                }

                                //if(vert == sectionVertexCount - 1) Debug.Log("Loop vertice to : " + (subdivIndex + targetVert) + " at order " + tri);
                                triangles[t] = targetVert;

                                t++;
                            }
                        }
                    }

                    s++;
                }
            }

            Mesh finalMesh = new Mesh();

            finalMesh.name = "Generated_Path_" + gameObject.GetInstanceID();

            finalMesh.vertices  = vertices;
            finalMesh.uv        = uvs;
            finalMesh.triangles = triangles;

            finalMesh.RecalculateNormals();
            finalMesh.RecalculateBounds();

            return(finalMesh);
        }