Example #1
0
    /// <summary>
    /// 对贴花的模型重新映射UV
    /// </summary>
    /// <param name="decalMesh"></param>
    /// <param name="decalNormal"></param>
    /// <returns></returns>
    /// <remarks>UV展开算法需要进一步研究,这里使用最基本的算法</remarks>
    private Mesh RemapDecalMapUV(Mesh decalMesh, Vector3 decalNormal)
    {
        List <Mapped2DVector> vertexMappedTo2DList = new List <Mapped2DVector>();
        float xMin = float.MaxValue;
        float yMin = float.MaxValue;
        float xMax = float.MinValue;
        float yMax = float.MinValue;

        Vector2[] mappedUV = new Vector2[decalMesh.uv.Length];

        for (int i = 0; i < decalMesh.vertexCount; ++i)
        {
            Vector3        vertexPosition = decalMesh.vertices[i];
            Mapped2DVector posMapTo2D     = Mapped2DVector.MapVector3ToVector2(vertexPosition, decalNormal);

            xMin = Mathf.Min(xMin, posMapTo2D.MappedVector2.x);
            xMax = Mathf.Max(xMax, posMapTo2D.MappedVector2.x);

            yMin = Mathf.Min(yMin, posMapTo2D.MappedVector2.y);
            yMax = Mathf.Max(yMax, posMapTo2D.MappedVector2.y);

            vertexMappedTo2DList.Add(posMapTo2D);
        }

        float uSize = xMax - xMin;
        float vSize = yMax - yMin;

        for (int i = 0; i < vertexMappedTo2DList.Count; ++i)
        {
            Mapped2DVector mapped2DVector = vertexMappedTo2DList[i];
            float          u = (mapped2DVector.MappedVector2.x - xMin) / uSize;
            float          v = 1 - (mapped2DVector.MappedVector2.y - yMin) / vSize; //MapVector3ToVector2里的y坐标系是向下的,与正常uv的相反

            mappedUV[i] = new Vector2(u, v);
        }

        decalMesh.uv = mappedUV;

        return(decalMesh);
    }
Example #2
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);
    }