unity多边形uv地图

我曾经写过一篇文章,不规则图形uv地图。(http://blog.csdn.net/itolfn/article/details/17240131)我用三角算法。但是,这种方法已经不完全,有一个指明:最优:假设任意两个凸四边形对角线三角附近形成假字。两个三角形六个内角中最小的角度不会变大。就是取四变形的最大化三角形内角去连接对角线,分组两个三角形。可是有时候不是自己想要的那一个图形,如图:


三角剖分算法会算出ABC和ACD这两个三角形,可是我们须要ABD和BCD。这时候就不能用了。我研究三角剖分不深,按他的定律去算出就是取的第二个图形,有哪位大侠知道请告诉小弟,后来我就摒弃了这个算法,重写了一套,使用面积划分的算法,这样攻克了我全部的问题,不论什么不规则多边形都会使uv贴的正好


using System.Collections;
using System.Collections.Generic;

public class TriangleSubdivision  :MonoBehaviour{
	///三角划分原理
	///每划分一个三角形后。推断切割成新三角形与切割后剩余多边形的面积和是否等于切割前多边形的面积。假设等于,则表示切割有效,继续划分。否则跳过一个顶点继续推断下一个三角形,循环到剩余多边形是三角形为止。
	public static int[] TriangulatePolygon (Vector2[] XZofVertices , bool is3D) {
		int VertexCount = XZofVertices.Length;
		List<TriangleObj> TriangleList = new List<TriangleObj>();
		List<Vector2> VerticesList = new List<Vector2>();
		for(int i=0;i<VertexCount;i++)
		{
			VerticesList.Add(new Vector2(XZofVertices[i].x,XZofVertices[i].y));
		}  
		if(VertexCount<3) return null;
		int testindex=0;
		while (VerticesList.Count>=3&&testindex<100)
		{
			for (int i = 0; i < VerticesList.Count; i++)
			{
				testindex++;
				//假设数组仅仅剩余3个节点。
				if(VerticesList.Count==3){
					TriangleObj nobj = new TriangleObj(VerticesList[0], VerticesList[1], VerticesList[2]);
					TriangleList.Add(nobj);
					VerticesList.RemoveAt(1);
					break;
				}
				//全部角点暂存数组
				List<Vector2> surplusVerticesList = new List<Vector2>();
				surplusVerticesList.AddRange(VerticesList);
				if(i+2<VerticesList.Count){
					//获取3个点组成一个3角形
					Vector2[] trianglePoint = new Vector2[3];
					trianglePoint[0] = VerticesList[i];
					trianglePoint[1] = VerticesList[i+1];
					trianglePoint[2] = VerticesList[i+2];
					//移除三角形用到的中间点,剩余的多边形点集合.
					surplusVerticesList.RemoveAt(i+1);
					Vector2[] surplusPoints = new Vector2[surplusVerticesList.Count];
					for(int m=0;m<surplusVerticesList.Count;m++){
						surplusPoints[m]=surplusVerticesList[m];
					}
					//移除前多边形点集合
					Vector2[] allPoints = new Vector2[VerticesList.Count];
					for (int n = 0; n < VerticesList.Count; n++)
					{
						allPoints[n]=VerticesList[n];
					}
					bool isCrose = false;//推断该多边形的两条边是否相交
					for(int ii_1 = 0;ii_1<surplusPoints.Length;ii_1++)
					{
						for(int ii_2 = 0;ii_2<surplusPoints.Length;ii_2++)
						{
						   
						    if(ii_1 < surplusPoints.Length - 1 && ii_2 < surplusPoints.Length - 1)
						    {
							    if((surplusPoints[ii_1].x == surplusPoints[ii_2].x && surplusPoints[ii_1].y == surplusPoints[ii_2].y)
									||(surplusPoints[ii_1+1].x == surplusPoints[ii_2].x && surplusPoints[ii_1+1].y == surplusPoints[ii_2].y)
									||(surplusPoints[ii_1].x == surplusPoints[ii_2+1].x && surplusPoints[ii_1].y == surplusPoints[ii_2+1].y)
									||(surplusPoints[ii_1+1].x == surplusPoints[ii_2+1].x && surplusPoints[ii_1+1].y == surplusPoints[ii_2+1].y))
							    {
							        continue;
							    }
								if(GameObject.Find("Initial").GetComponent<ShareMethods>().CheckCrose(surplusPoints[ii_1],surplusPoints[ii_1+1],surplusPoints[ii_2],surplusPoints[ii_2+1])
								 &&GameObject.Find("Initial").GetComponent<ShareMethods>().CheckCrose(surplusPoints[ii_2],surplusPoints[ii_2+1],surplusPoints[ii_1],surplusPoints[ii_1+1]))
                                {
									isCrose = true;
                                    break;
                                }
						    }
						}
                        if(isCrose)
                        {
                            break;
                        }
					}
					//推断切割成新三角形与切割后剩余多边形的面积和是否等于切割前多边形的面积?
					if(Mathf.Abs(trPolygonArea(trianglePoint,is3D)+trPolygonArea(surplusPoints,is3D)-trPolygonArea(allPoints,is3D))<=0.001f&&!isCrose){
					     
						//则表示切割有效,继续划分
						TriangleObj tobj = new TriangleObj(VerticesList[i], VerticesList[i+1], VerticesList[i+2]);
						TriangleList.Add(tobj);
						VerticesList.RemoveAt(i+1);
						i--;
						break;
					}else{
						//否则跳过一个顶点继续推断下一个三角形.把第一个点放到数组末尾.
						Vector2 zeropoint = new Vector2(VerticesList[i].x,VerticesList[i].y);
						VerticesList.RemoveAt(i);
						VerticesList.Add(zeropoint);
						break;
					}
				}
			}
		}
		int[] Triangles = new int[3 * TriangleList.Count];
		for (int ii1 = 0; ii1 < TriangleList.Count; ii1++)
		{
			TriangleObj tempobj = TriangleList[ii1];

			Triangles[3 * ii1 + 1] = indexofobjfromList(tempobj.p2,XZofVertices);
			if(is3D)
			{
				Triangles[3 * ii1+2] = indexofobjfromList(tempobj.p1,XZofVertices);
				Triangles[3 * ii1] = indexofobjfromList(tempobj.p3,XZofVertices);
			}
			else
			{
				Triangles[3 * ii1] = indexofobjfromList(tempobj.p1,XZofVertices);
				Triangles[3 * ii1+2] = indexofobjfromList(tempobj.p3,XZofVertices);
			}
		}
		return Triangles;

	}
  
	///
	//依据点获取多边形面积
	static float trPolygonArea(Vector2[] points,bool is3D)
	{ 
		float area = 0;
	    if(is3D)
	    {
			area = GameObject.Find("Initial").GetComponent<ShareMethods>().PolygonArea(null,points);//面积公式算法
	    }
	    else
	    {
			area = GameObject.Find("Initial").GetComponent<ShareMethods>().PolygonArea(null,points)/1000000;
	    }
		return area;
	}
	static int indexofobjfromList(Vector2 point,Vector2[] points)
	{
		int index = 0;
		for(int i=0;i<points.Length;i++){
			Vector2 temp=points[i];
			if(Mathf.Abs(point.x-temp.x)<0.001f&&Mathf.Abs(point.y-temp.y)<0.001f){
				index=i;
				break;
			}
		}
		return index;
	}
}
struct TriangleObj
{
	public Vector2 p1;
	public Vector2 p2;
	public Vector2 p3;
	public TriangleObj(Vector2 point1, Vector2 point2, Vector2 point3)
	{
		p1 = point1; p2 = point2; p3 = point3;
	}
}
这种方法没什么修改,仅仅是算法我改了一下。还是这个类。还是传你全部的点。会返回你的 Mesh.triangles,这样就就完美的使自己的mesh依据点贴上自己想要的图形状uv该

版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值