Пример #1
0
        /// <summary>
        /// Generate a mesh for a spline according to the parallel transport algorithm.
        /// </summary>
        /// <param name="points">Points of the spline.</param>
        /// <param name="crossSectionShape">Vertices of the mesh cross section to be placed at each point.</param>
        /// <param name="crossSectionNormals">Normals of the cross section.</param>
        /// <param name="crossSectionScale">Vector to scale the cross section by. Can be used to control the diameter of the tube mesh.</param>
        /// <param name="generateCaps">Should the ends of the mesh be closed with planar meshes?</param>
        /// <returns></returns>
        public static Mesh GetMesh(List <Vector3> points, List <Vector3> crossSectionShape, List <Vector3> crossSectionNormals, Vector3 crossSectionScale, bool generateCaps)
        {
            List <Vector3> tangents      = GetTangents(points);
            Vector3        initialNormal = Vector3.Cross(tangents[0], Vector3.right);

            if (initialNormal.magnitude == 0)
            {
                initialNormal = Vector3.Cross(tangents[0], Vector3.forward);
            }
            List <Vector3> normals = GetSplineNormals(initialNormal, tangents);

            List <Vector3> meshVertices = new List <Vector3>();
            List <Vector3> meshNormals  = new List <Vector3>();

            for (int i = 0; i < points.Count; i++)
            {
                List <Vector3> transformedCrossSection        = TransformPoints(crossSectionShape, points[i], tangents[i], normals[i], crossSectionScale);
                List <Vector3> transformedCrossSectionNormals = TransformNormals(crossSectionNormals, tangents[i], normals[i]);
                meshVertices.AddRange(transformedCrossSection);
                meshNormals.AddRange(transformedCrossSectionNormals);
            }

            //update triangles
            List <int> meshTriangles = new List <int>(Triangles.GenerateTrianglesCounterclockwise((meshVertices.Count / crossSectionShape.Count), crossSectionShape.Count));

            //mesh is empty or there is just a single cross section left because second to last control point or last control point was removed
            if (meshVertices.Count <= crossSectionShape.Count && meshNormals.Count <= crossSectionShape.Count)
            {
                return(new Mesh());
            }

            Mesh mesh;

            if (generateCaps)
            {
                (List <Vector3> capVertices, List <Vector3> capNormals, List <int> capTriangles) = TubeMesh.GenerateCapsMesh(meshVertices.GetRange(0, crossSectionShape.Count),
                                                                                                                             meshVertices.GetRange(meshVertices.Count - crossSectionShape.Count, crossSectionShape.Count),
                                                                                                                             meshVertices.Count);
                mesh = TubeMesh.GetMeshWithCaps(meshVertices, meshNormals, meshTriangles, capVertices, capNormals, capTriangles, crossSectionShape.Count);
            }
            else
            {
                mesh = new Mesh();
                mesh.SetVertices(meshVertices);
                mesh.SetNormals(meshNormals);
                mesh.subMeshCount = 1;
                mesh.SetTriangles(meshTriangles.ToArray(), 0);
                mesh.SetUVs(0, TextureCoordinates.GenerateQuadrilateralUVsStretchU(meshVertices.Count, crossSectionShape.Count));
            }
            mesh.RecalculateTangents();
            return(mesh);
        }
Пример #2
0
        /// <summary>
        /// Generates a patch surface mesh from a grid of control points.
        /// </summary>
        /// <param name="controlPoints">Flattened list of control points grid.</param>
        /// <param name="width">Number of control points horizontally.</param>
        /// <param name="height">Number of control points vertically.</param>
        /// <param name="resolutionWidth">Vertices between two control points horizontally.</param>
        /// <param name="resolutionHeight">Vertices between two control points vertically.</param>
        /// <returns></returns>
        public static Mesh GeneratePatchMesh(List <Vector3> controlPoints, int width, int height, int resolutionWidth, int resolutionHeight)
        {
            Vector3[] vertices = GenerateVerticesOfPatch(controlPoints, width, height, resolutionWidth, resolutionHeight);

            int[] trianglesArray = Triangles.GenerateTrianglesClockwise((width - 1) * resolutionWidth, (height - 1) * resolutionHeight);

            Mesh patchMesh = new Mesh();

            patchMesh.SetVertices(vertices);
            patchMesh.SetTriangles(trianglesArray, 0);
            patchMesh.SetUVs(0, TextureCoordinates.GenerateQuadrilateralUVs(vertices.Length, (height - 1) * (resolutionHeight)));

            patchMesh.RecalculateNormals();
            patchMesh.RecalculateTangents();

            return(patchMesh);
        }