public Triangle(Vector3 vertexPosition0, Vector3 vertexPosition1, Vector3 vertexPosition2, Vector2 uv0, Vector2 uv1, Vector2 uv2)
        {
            this.m_vertexPos0 = vertexPosition0;
            this.m_vertexPos1 = vertexPosition1;
            this.m_vertexPos2 = vertexPosition2;

            this.m_uv0 = uv0;
            this.m_uv1 = uv1;
            this.m_uv2 = uv2;

            this.m_windingOrder = GeometryUtility.GetTriangleWindingOrder(vertexPosition0, vertexPosition1, vertexPosition2);
        }
Exemplo n.º 2
0
    /// <summary>
    /// 通过triangleList创建Unity的Mesh
    /// </summary>
    /// <param name="triangleList"></param>
    /// <param name="windingOrder"></param>
    /// <returns></returns>
    public static Mesh CreateUnityMeshByTriangleList(List <Triangle> triangleList, TriangleWindingOrder windingOrder = TriangleWindingOrder.CounterClockWise)
    {
        Mesh unityMesh = new Mesh();

        Vector3[] vertices  = new Vector3[triangleList.Count * 3];
        Vector2[] uvs       = new Vector2[triangleList.Count * 3];
        int[]     triangles = new int[triangleList.Count * 3];

        int triangleIndices = 0;

        for (int i = 0; i < triangleList.Count; ++i)
        {
            int index0 = triangleIndices;
            int index1 = triangleIndices + 1;
            int index2 = triangleIndices + 2;

            Triangle triangle = triangleList[i];
            triangle.WindingOrder = windingOrder;

            vertices[index0] = triangle.VertexPosition0;
            vertices[index1] = triangle.VertexPosition1;
            vertices[index2] = triangle.VertexPosition2;

            uvs[index0] = triangle.UV0;
            uvs[index1] = triangle.UV1;
            uvs[index2] = triangle.UV2;

            triangles[index0] = index0;
            triangles[index1] = index1;
            triangles[index2] = index2;

            triangleIndices += 3;
        }

        unityMesh.vertices  = vertices;
        unityMesh.uv        = uvs;
        unityMesh.triangles = triangles;
        unityMesh.RecalculateNormals();
        unityMesh.RecalculateTangents();

        return(unityMesh);
    }
Exemplo n.º 3
0
    /// <summary>
    /// Andrew monotone chain算法,计算凸边形
    /// </summary>
    /// <param name="inVertices">输入的无序3维点</param>
    /// <param name="uAxis">降维x方向</param>
    /// <param name="vAxis">降维y方向</param>
    /// <param name="convexHullVertices">输出凸边形顶点</param>
    /// <param name="triangles">triangle indices</param>
    /// <param name="uvs">输出uv</param>
    /// <returns></returns>
    public static bool CreateConvexHullByMonotoneChain(List <Vector3> inVertices, Vector3 uAxis, Vector3 vAxis, out Vector3[] convexHullVertices, out Vector2[] uvs, out int[] triangles, TriangleWindingOrder triangleWindingOrder = TriangleWindingOrder.CounterClockWise)
    {
        convexHullVertices = new Vector3[0];
        uvs       = new Vector2[0];
        triangles = new int[0];

        if (inVertices.Count < 3)
        {
            return(false);
        }

        float uMax = float.MinValue;
        float uMin = float.MaxValue;
        float vMax = float.MinValue;
        float vMin = float.MaxValue;

        //3D降维到2D
        Dictionary <Vector2, Mapped2DVector> vector2DAndMappedDict = new Dictionary <Vector2, Mapped2DVector>();

        for (int i = 0; i < inVertices.Count; ++i)
        {
            Mapped2DVector mappedVector = new Mapped2DVector(inVertices[i], uAxis, vAxis);
            if (!vector2DAndMappedDict.ContainsKey(mappedVector.MappedVector2))
            {
                vector2DAndMappedDict.Add(mappedVector.MappedVector2, mappedVector);

                uMax = Mathf.Max(uMax, mappedVector.MappedVector2.x);
                uMin = Mathf.Min(uMin, mappedVector.MappedVector2.x);
                vMax = Mathf.Max(vMax, mappedVector.MappedVector2.y);
                vMin = Mathf.Min(vMin, mappedVector.MappedVector2.y);
            }
        }

        List <Vector2> inVertexPoints            = vector2DAndMappedDict.Keys.ToList();
        List <Vector2> convexHullByMonotoneChain = MonotoneChain(inVertexPoints.ToArray()).ToList();

        convexHullVertices = new Vector3[convexHullByMonotoneChain.Count];
        uvs = new Vector2[convexHullByMonotoneChain.Count];

        //计算uv
        for (int i = 0; i < convexHullByMonotoneChain.Count; ++i)
        {
            Vector2 point2D = convexHullByMonotoneChain[i];

            convexHullVertices[i] = vector2DAndMappedDict[point2D].OriginalVector;

            Vector2 pointUV = new Vector2();
            pointUV.x = MathUtils.Remap(point2D.x, uMax, uMin, 1, 0);
            pointUV.y = MathUtils.Remap(point2D.y, vMax, vMin, 1, 0);

            uvs[i] = pointUV;
        }

        //根据WindingOrder计算triangle
        int index = 1;

        triangles = new int[(convexHullByMonotoneChain.Count - 2) * 3];

        for (int i = 0; i < triangles.Length; i += 3)
        {
            triangles[i] = 0;
            if (triangleWindingOrder == TriangleWindingOrder.CounterClockWise)
            {
                triangles[i + 1] = index;
                triangles[i + 2] = index + 1;
            }
            else
            {
                triangles[i + 1] = index + 1;
                triangles[i + 2] = index;
            }

            index++;
        }

        return(true);
    }
Exemplo n.º 4
0
    /// <summary>
    /// 构建凸包模型
    /// </summary>
    /// <param name="points"></param>
    /// <param name="normal">维度方向</param>
    /// <returns></returns>
    /// <remarks>基于Andrew monotone chain 算法,时间复杂度nlogn 在几个凸包算法中表现比较好</remarks>
    public static Mesh CreateConvexhullMeshByMonotoneChain(List <Vector3> points, Vector3 normal, TriangleWindingOrder windingOrder = TriangleWindingOrder.CounterClockWise)
    {
        Vector3 planeRight = Mathf.Abs(normal.x) > Mathf.Abs(normal.y) ? new Vector3(0, 1, 0) : new Vector3(1, 0, 0);
        Vector3 vAxis      = Vector3.Cross(planeRight, normal).normalized;
        Vector3 uAxis      = Vector3.Cross(normal, vAxis).normalized;

        Vector3[] meshVertices;
        Vector2[] meshUVs;
        int[]     meshTriangles;

        bool isValid = CreateConvexHullByMonotoneChain(points, uAxis, vAxis, out meshVertices, out meshUVs, out meshTriangles, windingOrder);

        if (!isValid)
        {
            return(null);
        }

        Mesh convexHullMesh = new Mesh();

        convexHullMesh.vertices  = meshVertices;
        convexHullMesh.uv        = meshUVs;
        convexHullMesh.triangles = meshTriangles;

        convexHullMesh.RecalculateNormals();
        convexHullMesh.RecalculateTangents();

        return(convexHullMesh);
    }