当前位置:   article > 正文

unity模型任意无限切割插件_unity模型无限切割插件

unity模型无限切割插件

前面几篇文章都是关于3d模型切割的原理,经过3天奋战,完成了整个流程的制作,包括了滑动屏幕,切割模型的整个过程,因为这个版本目前切割出来的切口处纹理统一使用uv坐标我设定为红色,已经亲测了无限切割(只要你的机器跟得上),本文难度其实挺大的,能理解的可以将他运用到其他平台上,比如虚幻之类的,不能理解就只能直接在unity上使用了,希望使用的朋友能保留我的名字以及博客地址。如需下载完整插件,请到http://www.demodashi.com/demo/11343.html 。效果图如下



想知道原理的可以查看这篇文章前面几篇的内容,下面是完整代码,可以直接在unity中运用的,

  1. /*
  2. * @authors: liangjian
  3. * @desc:
  4. */
  5. using UnityEngine;
  6. using System.Collections.Generic;
  7. using UnityEngine.EventSystems;
  8. public class TouchToPlane : MonoBehaviour {
  9. private bool m_IsClearSamePoint = false;
  10. private Vector3 m_TouchBeganPos;
  11. private Vector3 m_ClipPlaneNormal;
  12. private Vector3 m_ClipPlanePoint;
  13. // Use this for initialization
  14. void Start () {
  15. }
  16. void Update()
  17. {
  18. if (Input.GetMouseButtonDown(0))
  19. {
  20. m_TouchBeganPos = Input.mousePosition;
  21. }
  22. else if (Input.GetMouseButtonUp(0))
  23. {
  24. Vector3 touchBeganPoint_screen = new Vector3(m_TouchBeganPos.x, m_TouchBeganPos.y, Camera.main.nearClipPlane);
  25. Vector3 touchEndPoint_screen = new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.nearClipPlane);
  26. Vector3 normalEndPoint_screen = new Vector3(m_TouchBeganPos.x, m_TouchBeganPos.y, Camera.main.nearClipPlane + 10);
  27. if(UpdateClipPlane(touchBeganPoint_screen, touchEndPoint_screen, normalEndPoint_screen))
  28. {
  29. ClipMesh();
  30. }
  31. }
  32. }
  33. bool UpdateClipPlane(Vector3 touchBeganPoint_sceen, Vector3 touchEndPoint_sceen, Vector3 normalEndPoint_screen)
  34. {
  35. if(Vector3.Distance(touchBeganPoint_sceen, touchEndPoint_sceen) == 0.0f)
  36. {
  37. return false;
  38. }
  39. //转世界坐标
  40. Vector3 touchBeganPoint_world = Camera.main.ScreenToWorldPoint(touchBeganPoint_sceen);
  41. Vector3 touchEndPoint_world = Camera.main.ScreenToWorldPoint(touchEndPoint_sceen);
  42. Vector3 noramlEndPoint_world = Camera.main.ScreenToWorldPoint(normalEndPoint_screen);
  43. //世界坐标转本地坐标
  44. Vector3 touchBeginPoint_local = transform.worldToLocalMatrix.MultiplyPoint(touchBeganPoint_world);
  45. Vector3 touchEndPoint_local = transform.worldToLocalMatrix.MultiplyPoint(touchEndPoint_world);
  46. Vector3 normalEngPoint_local = transform.worldToLocalMatrix.MultiplyPoint(noramlEndPoint_world);
  47. m_ClipPlaneNormal = Vector3.Cross(normalEngPoint_local - touchBeginPoint_local, touchEndPoint_local - touchBeginPoint_local).normalized;
  48. m_ClipPlanePoint = touchEndPoint_local;
  49. return true;
  50. }
  51. void ClipMesh()
  52. {
  53. MeshFilter mf = this.gameObject.GetComponent<MeshFilter>();
  54. //顶点数组转顶点容器
  55. List<Vector3> verticeList = new List<Vector3>();
  56. int verticeCount = mf.mesh.vertices.Length;
  57. for (int verticeIndex = 0; verticeIndex < verticeCount; ++verticeIndex)
  58. {
  59. verticeList.Add(mf.mesh.vertices[verticeIndex]);
  60. }
  61. //三角形数组转三角形容器
  62. List<int> triangleList = new List<int>();
  63. int triangleCount = mf.mesh.triangles.Length;
  64. for (int triangleIndex = 0; triangleIndex < triangleCount; ++triangleIndex)
  65. {
  66. triangleList.Add(mf.mesh.triangles[triangleIndex]);
  67. }
  68. //uv坐标数组转uv坐标容器
  69. List<Vector2> uvList = new List<Vector2>();
  70. int uvCount = mf.mesh.uv.Length;
  71. for (int uvIndex = 0; uvIndex < uvCount; ++uvIndex)
  72. {
  73. uvList.Add(mf.mesh.uv[uvIndex]);
  74. }
  75. //顶点颜色数组转顶点颜色容器
  76. List<Vector3> normalList = new List<Vector3>();
  77. int normalCount = mf.mesh.normals.Length;
  78. for (int normalIndex = 0; normalIndex < normalCount; ++normalIndex)
  79. {
  80. normalList.Add(mf.mesh.normals[normalIndex]);
  81. }
  82. //Debug.Log("顶点数" + verticeList.Count);
  83. //Debug.Log("顶点索引数" + triangleList.Count);
  84. //检查每个三角面,是否存在两个顶点连接正好在直线上
  85. for (int triangleIndex = 0; triangleIndex < triangleList.Count;)
  86. {
  87. //Debug.Log("次数记录");
  88. int trianglePointIndex0 = triangleList[triangleIndex];
  89. int trianglePointIndex1 = triangleList[triangleIndex + 1];
  90. int trianglePointIndex2 = triangleList[triangleIndex + 2];
  91. Vector3 trianglePointCoord0 = verticeList[trianglePointIndex0];
  92. Vector3 trianglePointCoord1 = verticeList[trianglePointIndex1];
  93. Vector3 trianglePointCoord2 = verticeList[trianglePointIndex2];
  94. //0-1,1-2相连线段被切割
  95. if(GetPointToClipPlaneDis(trianglePointCoord0)* GetPointToClipPlaneDis(trianglePointCoord1) < 0 &&
  96. GetPointToClipPlaneDis(trianglePointCoord1) * GetPointToClipPlaneDis(trianglePointCoord2) < 0)
  97. {
  98. //求得0-1与切平面的交点
  99. Vector3 newVertice01 = GetLinePlaneCrossPoint(trianglePointCoord0, trianglePointCoord1);
  100. int index01 = IsContainsVertice(verticeList, newVertice01);
  101. if (index01 == -1 || !m_IsClearSamePoint)
  102. {
  103. verticeList.Add(newVertice01);
  104. index01 = verticeList.Count - 1;
  105. float k01 = 0;
  106. if (!IsEqual(newVertice01.x, trianglePointCoord0.x) && !IsEqual(trianglePointCoord1.x, trianglePointCoord0.x))
  107. {
  108. k01 = (newVertice01.x - trianglePointCoord0.x) / (trianglePointCoord1.x - trianglePointCoord0.x);
  109. }
  110. else if (!IsEqual(newVertice01.y, trianglePointCoord0.y) && !IsEqual(trianglePointCoord1.y, trianglePointCoord0.y))
  111. {
  112. k01 = (newVertice01.y - trianglePointCoord0.y) / (trianglePointCoord1.y - trianglePointCoord0.y);
  113. }
  114. else
  115. {
  116. k01 = (newVertice01.z - trianglePointCoord0.z) / (trianglePointCoord1.z - trianglePointCoord0.z);
  117. }
  118. if (uvList.Count > 0)
  119. {
  120. Vector2 uv0 = uvList[trianglePointIndex0];
  121. Vector2 uv1 = uvList[trianglePointIndex1];
  122. float newUV_x = (uv1.x - uv0.x) * k01 + uv0.x;
  123. float newUV_y = (uv1.y - uv0.y) * k01 + uv0.y;
  124. uvList.Add(new Vector2(newUV_x, newUV_y));
  125. //Debug.Log("纹理坐标" + uvList[uvList.Count - 1]);
  126. }
  127. //法向量
  128. Vector3 normalX0 = normalList[trianglePointIndex0];
  129. Vector3 normalX1 = normalList[trianglePointIndex1];
  130. float newNoramlX01 = (normalX1.x - normalX0.x) * k01 + normalX0.x;
  131. float newNoramlY01 = (normalX1.y - normalX0.y) * k01 + normalX0.y;
  132. float newNoramlZ01 = (normalX1.z - normalX0.z) * k01 + normalX0.z;
  133. normalList.Add(new Vector3(newNoramlX01, newNoramlY01, newNoramlZ01));
  134. }
  135. //求得1-2与切平面的交点
  136. Vector3 newVertice12 = GetLinePlaneCrossPoint(trianglePointCoord1, trianglePointCoord2);
  137. int index12 = IsContainsVertice(verticeList, newVertice12);
  138. if (index12 == -1 || !m_IsClearSamePoint)
  139. {
  140. verticeList.Add(newVertice12);
  141. index12 = verticeList.Count - 1;
  142. float k12 = 0;
  143. if (!IsEqual(newVertice12.x, trianglePointCoord1.x) && !IsEqual(trianglePointCoord2.x, trianglePointCoord1.x))
  144. {
  145. k12 = (newVertice12.x - trianglePointCoord1.x) / (trianglePointCoord2.x - trianglePointCoord1.x);
  146. }
  147. else if (!IsEqual(newVertice12.y, trianglePointCoord1.y) && !IsEqual(trianglePointCoord2.y, trianglePointCoord1.y))
  148. {
  149. k12 = (newVertice12.y - trianglePointCoord1.y) / (trianglePointCoord2.y - trianglePointCoord1.y);
  150. }
  151. else
  152. {
  153. k12 = (newVertice12.z - trianglePointCoord1.z) / (trianglePointCoord2.z - trianglePointCoord1.z);
  154. }
  155. if (uvList.Count > 0)
  156. {
  157. Vector2 uv1 = uvList[trianglePointIndex1];
  158. Vector2 uv2 = uvList[trianglePointIndex2];
  159. float newUV_x = (uv2.x - uv1.x) * k12 + uv1.x;
  160. float newUV_y = (uv2.y - uv1.y) * k12 + uv1.y;
  161. uvList.Add(new Vector2(newUV_x, newUV_y));
  162. //Debug.Log("纹理坐标" + uvList[uvList.Count - 1]);
  163. }
  164. //法向量
  165. Vector3 normalX1 = normalList[trianglePointIndex1];
  166. Vector3 normalX2 = normalList[trianglePointIndex2];
  167. float newNoramlX12 = (normalX2.x - normalX1.x) * k12 + normalX1.x;
  168. float newNoramlY12 = (normalX2.y - normalX1.y) * k12 + normalX1.y;
  169. float newNoramlZ12 = (normalX2.z - normalX1.z) * k12 + normalX1.z;
  170. normalList.Add(new Vector3(newNoramlX12, newNoramlY12, newNoramlZ12));
  171. }
  172. //插入顶点索引,以此构建新三角形
  173. triangleList.Insert(triangleIndex + 1, index01);
  174. triangleList.Insert(triangleIndex + 2, index12);
  175. triangleList.Insert(triangleIndex + 3, index12);
  176. triangleList.Insert(triangleIndex + 4, index01);
  177. triangleList.Insert(triangleIndex + 6, trianglePointIndex0);
  178. triangleList.Insert(triangleIndex + 7, index12);
  179. triangleIndex += 9;
  180. }
  181. //1-2,2-0相连线段被切割
  182. else if (GetPointToClipPlaneDis(trianglePointCoord1) * GetPointToClipPlaneDis(trianglePointCoord2) < 0 &&
  183. GetPointToClipPlaneDis(trianglePointCoord2) * GetPointToClipPlaneDis(trianglePointCoord0) < 0)
  184. {
  185. //求得1-2与切平面的交点
  186. Vector3 newVertice12 = GetLinePlaneCrossPoint(trianglePointCoord1, trianglePointCoord2);
  187. int index12 = IsContainsVertice(verticeList, newVertice12);
  188. if (index12 == -1 || !m_IsClearSamePoint)
  189. {
  190. verticeList.Add(newVertice12);
  191. index12 = verticeList.Count - 1;
  192. float k12 = 0;
  193. if(!IsEqual(newVertice12.x, trianglePointCoord1.x) && !IsEqual(trianglePointCoord2.x, trianglePointCoord1.x))
  194. {
  195. k12 = (newVertice12.x - trianglePointCoord1.x) / (trianglePointCoord2.x - trianglePointCoord1.x);
  196. }
  197. else if (!IsEqual(newVertice12.y, trianglePointCoord1.y) && !IsEqual(trianglePointCoord2.y, trianglePointCoord1.y))
  198. {
  199. k12 = (newVertice12.y - trianglePointCoord1.y) / (trianglePointCoord2.y - trianglePointCoord1.y);
  200. }
  201. else
  202. {
  203. k12 = (newVertice12.z - trianglePointCoord1.z) / (trianglePointCoord2.z - trianglePointCoord1.z);
  204. }
  205. if (uvList.Count > 0)
  206. {
  207. Vector2 uv1 = uvList[trianglePointIndex1];
  208. Vector2 uv2 = uvList[trianglePointIndex2];
  209. float newUV_x = (uv2.x - uv1.x) * k12 + uv1.x;
  210. float newUV_y = (uv2.y - uv1.y) * k12 + uv1.y;
  211. uvList.Add(new Vector2(newUV_x, newUV_y));
  212. //Debug.Log("纹理坐标" + uvList[uvList.Count - 1]);
  213. }
  214. //法向量
  215. Vector3 normalX1 = normalList[trianglePointIndex1];
  216. Vector3 normalX2 = normalList[trianglePointIndex2];
  217. float newNoramlX12 = (normalX2.x - normalX1.x) * k12 + normalX1.x;
  218. float newNoramlY12 = (normalX2.y - normalX1.y) * k12 + normalX1.y;
  219. float newNoramlZ12 = (normalX2.z - normalX1.z) * k12 + normalX1.z;
  220. normalList.Add(new Vector3(newNoramlX12, newNoramlY12, newNoramlZ12));
  221. }
  222. //求得0-2与切平面的交点
  223. Vector3 newVertice02 = GetLinePlaneCrossPoint(trianglePointCoord0, trianglePointCoord2);
  224. int index02 = IsContainsVertice(verticeList, newVertice02);
  225. if (index02 == -1 || !m_IsClearSamePoint)
  226. {
  227. verticeList.Add(newVertice02);
  228. index02 = verticeList.Count - 1;
  229. float k02 = 0;
  230. if (!IsEqual(newVertice02.x, trianglePointCoord0.x) && !IsEqual(trianglePointCoord2.x, trianglePointCoord0.x))
  231. {
  232. k02 = (newVertice02.x - trianglePointCoord0.x) / (trianglePointCoord2.x - trianglePointCoord0.x);
  233. }
  234. else if (!IsEqual(newVertice02.y, trianglePointCoord0.y) && !IsEqual(trianglePointCoord2.y, trianglePointCoord0.y))
  235. {
  236. k02 = (newVertice02.y - trianglePointCoord0.y) / (trianglePointCoord2.y - trianglePointCoord0.y);
  237. }
  238. else
  239. {
  240. k02 = (newVertice02.z - trianglePointCoord0.z) / (trianglePointCoord2.z - trianglePointCoord0.z);
  241. }
  242. if (uvList.Count > 0)
  243. {
  244. Vector2 uv0 = uvList[trianglePointIndex0];
  245. Vector2 uv2 = uvList[trianglePointIndex2];
  246. float newUV_x = (uv2.x - uv0.x) * k02 + uv0.x;
  247. float newUV_y = (uv2.y - uv0.y) * k02 + uv0.y;
  248. uvList.Add(new Vector2(newUV_x, newUV_y));
  249. //Debug.Log("纹理坐标" + uvList[uvList.Count - 1]);
  250. }
  251. //法向量
  252. Vector3 normalX0 = normalList[trianglePointIndex0];
  253. Vector3 normalX2 = normalList[trianglePointIndex2];
  254. float newNoramlX02 = (normalX2.x - normalX0.x) * k02 + normalX0.x;
  255. float newNoramlY02 = (normalX2.y - normalX0.y) * k02 + normalX0.y;
  256. float newNoramlZ02 = (normalX2.z - normalX0.z) * k02 + normalX0.z;
  257. normalList.Add(new Vector3(newNoramlX02, newNoramlY02, newNoramlZ02));
  258. }
  259. //插入顶点索引,以此构建新三角形
  260. //{0}
  261. //{1}
  262. triangleList.Insert(triangleIndex + 2, index12);
  263. triangleList.Insert(triangleIndex + 3, index02);
  264. triangleList.Insert(triangleIndex + 4, index12);
  265. //{2}
  266. triangleList.Insert(triangleIndex + 6, index02);
  267. triangleList.Insert(triangleIndex + 7, trianglePointIndex0);
  268. triangleList.Insert(triangleIndex + 8, index12);
  269. triangleIndex += 9;
  270. }
  271. //0-1,2-0相连线段被切割
  272. else if (GetPointToClipPlaneDis(trianglePointCoord0) * GetPointToClipPlaneDis(trianglePointCoord1) < 0 &&
  273. GetPointToClipPlaneDis(trianglePointCoord2) * GetPointToClipPlaneDis(trianglePointCoord0) < 0)
  274. {
  275. //求得0-1与切平面的交点
  276. Vector3 newVertice01 = GetLinePlaneCrossPoint(trianglePointCoord0, trianglePointCoord1);
  277. int index01 = IsContainsVertice(verticeList, newVertice01);
  278. if (index01 == -1 || !m_IsClearSamePoint)
  279. {
  280. verticeList.Add(newVertice01);
  281. index01 = verticeList.Count - 1;
  282. float k01 = 0;
  283. if (!IsEqual(newVertice01.x, trianglePointCoord0.x) && !IsEqual(trianglePointCoord1.x, trianglePointCoord0.x))
  284. {
  285. k01 = (newVertice01.x - trianglePointCoord0.x) / (trianglePointCoord1.x - trianglePointCoord0.x);
  286. }
  287. else if(!IsEqual(newVertice01.y, trianglePointCoord0.y) && !IsEqual(trianglePointCoord1.y, trianglePointCoord0.y))
  288. {
  289. k01 = (newVertice01.y - trianglePointCoord0.y) / (trianglePointCoord1.y - trianglePointCoord0.y);
  290. }
  291. else
  292. {
  293. k01 = (newVertice01.z - trianglePointCoord0.z) / (trianglePointCoord1.z - trianglePointCoord0.z);
  294. }
  295. if (uvList.Count > 0)
  296. {
  297. Vector2 uv0 = uvList[trianglePointIndex0];
  298. Vector2 uv1 = uvList[trianglePointIndex1];
  299. float newUV_x = (uv1.x - uv0.x) * k01 + uv0.x;
  300. float newUV_y = (uv1.y - uv0.y) * k01 + uv0.y;
  301. uvList.Add(new Vector2(newUV_x, newUV_y));
  302. Debug.Log("纹理坐标" + uvList[uvList.Count - 1]);
  303. }
  304. //法向量
  305. Vector3 normalX0 = normalList[trianglePointIndex0];
  306. Vector3 normalX1 = normalList[trianglePointIndex1];
  307. float newNoramlX01 = (normalX1.x - normalX0.x) * k01 + normalX0.x;
  308. float newNoramlY01 = (normalX1.y - normalX0.y) * k01 + normalX0.y;
  309. float newNoramlZ01 = (normalX1.z - normalX0.z) * k01 + normalX0.z;
  310. normalList.Add(new Vector3(newNoramlX01, newNoramlY01, newNoramlZ01));
  311. }
  312. //求得0-2与切平面的交点
  313. Vector3 newVertice02 = GetLinePlaneCrossPoint(trianglePointCoord0, trianglePointCoord2);
  314. int index02 = IsContainsVertice(verticeList, newVertice02);
  315. if (index02 == -1 || !m_IsClearSamePoint)
  316. {
  317. verticeList.Add(newVertice02);
  318. index02 = verticeList.Count - 1;
  319. float k02 = 0;
  320. if (!IsEqual(newVertice02.x, trianglePointCoord0.x) && !IsEqual(trianglePointCoord2.x, trianglePointCoord0.x))
  321. {
  322. k02 = (newVertice02.x - trianglePointCoord0.x) / (trianglePointCoord2.x - trianglePointCoord0.x);
  323. }
  324. else if(!IsEqual(newVertice02.y, trianglePointCoord0.y) && !IsEqual(trianglePointCoord2.y, trianglePointCoord0.y))
  325. {
  326. k02 = (newVertice02.y - trianglePointCoord0.y) / (trianglePointCoord2.y - trianglePointCoord0.y);
  327. }
  328. else
  329. {
  330. k02 = (newVertice02.z - trianglePointCoord0.z) / (trianglePointCoord2.z - trianglePointCoord0.z);
  331. }
  332. if (uvList.Count > 0)
  333. {
  334. Vector2 uv0 = uvList[trianglePointIndex0];
  335. Vector2 uv2 = uvList[trianglePointIndex2];
  336. float newUV_x = (uv2.x - uv0.x) * k02 + uv0.x;
  337. float newUV_y = (uv2.y - uv0.y) * k02 + uv0.y;
  338. uvList.Add(new Vector2(newUV_x, newUV_y));
  339. Debug.Log("纹理坐标" + uvList[uvList.Count - 1]);
  340. }
  341. //法向量
  342. Vector3 normalX0 = normalList[trianglePointIndex0];
  343. Vector3 normalX2 = normalList[trianglePointIndex2];
  344. float newNoramlX02 = (normalX2.x - normalX0.x) * k02 + normalX0.x;
  345. float newNoramlY02 = (normalX2.y - normalX0.y) * k02 + normalX0.y;
  346. float newNoramlZ02 = (normalX2.z - normalX0.z) * k02 + normalX0.z;
  347. normalList.Add(new Vector3(newNoramlX02, newNoramlY02, newNoramlZ02));
  348. }
  349. //插入顶点索引,以此构建新三角形
  350. //{0}
  351. triangleList.Insert(triangleIndex + 1, index01);
  352. triangleList.Insert(triangleIndex + 2, index02);
  353. triangleList.Insert(triangleIndex + 3, index01);
  354. //{1}
  355. //{2}
  356. triangleList.Insert(triangleIndex + 6, trianglePointIndex2);
  357. triangleList.Insert(triangleIndex + 7, index02);
  358. triangleList.Insert(triangleIndex + 8, index01);
  359. triangleIndex += 9;
  360. }
  361. else
  362. {
  363. triangleIndex += 3;
  364. }
  365. }
  366. //Debug.Log("顶点数" + verticeList.Count);
  367. //Debug.Log("顶点索引数" + triangleList.Count);
  368. //筛选出切割面两侧的顶点索引
  369. List<int> triangles1 = new List<int>();
  370. List<int> triangles2 = new List<int>();
  371. for (int triangleIndex = 0; triangleIndex < triangleList.Count; triangleIndex += 3)
  372. {
  373. int trianglePoint0 = triangleList[triangleIndex];
  374. int trianglePoint1 = triangleList[triangleIndex + 1];
  375. int trianglePoint2 = triangleList[triangleIndex + 2];
  376. Vector3 point0 = verticeList[trianglePoint0];
  377. Vector3 point1 = verticeList[trianglePoint1];
  378. Vector3 point2 = verticeList[trianglePoint2];
  379. //切割面
  380. float dis0 = GetPointToClipPlaneDis(point0);
  381. float dis1 = GetPointToClipPlaneDis(point1);
  382. float dis2 = GetPointToClipPlaneDis(point2);
  383. if ((dis0 < 0 || IsEqual(dis0, 0)) && (dis1 < 0 || IsEqual(dis1, 0)) && (dis2 < 0 || IsEqual(dis2, 0)))
  384. {
  385. triangles1.Add(trianglePoint0);
  386. triangles1.Add(trianglePoint1);
  387. triangles1.Add(trianglePoint2);
  388. }
  389. else
  390. {
  391. triangles2.Add(trianglePoint0);
  392. triangles2.Add(trianglePoint1);
  393. triangles2.Add(trianglePoint2);
  394. }
  395. }
  396. //新生顶点数
  397. int newVerticeCount = verticeList.Count - verticeCount;
  398. //再次添加一遍新增顶点,用于缝合切口
  399. for (int newVerticeIndex = 0; newVerticeIndex < newVerticeCount; ++newVerticeIndex)
  400. {
  401. Vector3 newVertice = verticeList[verticeCount + newVerticeIndex];
  402. Vector3 qiekouVertice = new Vector3(newVertice.x, newVertice.y, newVertice.z);
  403. verticeList.Add(qiekouVertice);
  404. //uv
  405. if (uvList.Count > 0)
  406. {
  407. Vector2 newUv = uvList[verticeCount + newVerticeIndex];
  408. Vector2 qiekouUv = new Vector3(0.99f, 0.99f);
  409. uvList.Add(qiekouUv);
  410. }
  411. //法线
  412. Vector3 newNormal = normalList[verticeCount + newVerticeIndex];
  413. Vector3 qiekouNormal = new Vector3(newNormal.x, newNormal.y, newNormal.z);
  414. normalList.Add(qiekouNormal);
  415. }
  416. verticeCount = verticeCount + newVerticeCount;
  417. //重新排序新生成的顶点,按照角度
  418. List<SortAngle> SortAngleList = new List<SortAngle>();
  419. for (int verticeIndex = verticeCount + 1; verticeIndex < verticeList.Count; verticeIndex++)
  420. {
  421. //计算角度,以0-1为参照
  422. Vector3 vec1to0 = verticeList[verticeCount + 1] - verticeList[verticeCount];
  423. Vector3 indexTo0 = verticeList[verticeIndex] - verticeList[verticeCount];
  424. float moIndexto0 = indexTo0.magnitude;
  425. float mo1to0 = vec1to0.magnitude;
  426. float dotRes = Vector3.Dot(indexTo0, vec1to0);
  427. if (moIndexto0 == 0.0f)
  428. {
  429. continue;
  430. }
  431. float angle = Mathf.Acos(dotRes / (mo1to0 * moIndexto0)); //Vector3.Angle(indexTo0.normalized, vec1to0.normalized);
  432. bool isExis = false;
  433. for (int i = 0; i < SortAngleList.Count; ++i)
  434. {
  435. //同样角度,距离近的被剔除
  436. if (Mathf.Abs(SortAngleList[i].Angle * 180.0f / Mathf.PI - angle * 180.0f / Mathf.PI) < 0.1f)
  437. {
  438. float dis1 = Vector3.Distance(verticeList[SortAngleList[i].Index], verticeList[verticeCount]);
  439. float dis2 = Vector3.Distance(verticeList[verticeIndex], verticeList[verticeCount]);
  440. if (dis2 >= dis1)
  441. {
  442. SortAngleList[i].Index = verticeIndex;
  443. }
  444. isExis = true;
  445. break;
  446. }
  447. }
  448. if (!isExis)
  449. {
  450. //Debug.Log(angle);
  451. SortAngle sortAngle = new SortAngle();
  452. sortAngle.Index = verticeIndex;
  453. sortAngle.Angle = angle;
  454. SortAngleList.Add(sortAngle);
  455. }
  456. }
  457. SortAngleList.Sort();
  458. //缝合切口
  459. for (int verticeIndex = 0; verticeIndex < SortAngleList.Count - 1;)
  460. {
  461. triangles1.Add(SortAngleList[verticeIndex + 1].Index);
  462. triangles1.Add(SortAngleList[verticeIndex].Index);
  463. triangles1.Add(verticeCount);
  464. triangles2.Add(verticeCount);
  465. triangles2.Add(SortAngleList[verticeIndex].Index);
  466. triangles2.Add(SortAngleList[verticeIndex + 1].Index);
  467. verticeIndex++;
  468. }
  469. mf.mesh.vertices = verticeList.ToArray();
  470. mf.mesh.triangles = triangles1.ToArray();
  471. if (uvList.Count > 0)
  472. {
  473. mf.mesh.uv = uvList.ToArray();
  474. }
  475. mf.mesh.normals = normalList.ToArray();
  476. //分割模型
  477. GameObject newModel = new GameObject("New Model");
  478. MeshFilter meshFilter = newModel.AddComponent<MeshFilter>();
  479. meshFilter.mesh.vertices = mf.mesh.vertices;
  480. meshFilter.mesh.triangles = triangles2.ToArray();
  481. meshFilter.mesh.uv = mf.mesh.uv;
  482. meshFilter.mesh.normals = mf.mesh.normals;
  483. Renderer newRenderer = newModel.AddComponent<MeshRenderer>();
  484. newRenderer.material = this.gameObject.GetComponent<MeshRenderer>().material;
  485. newModel.transform.localPosition = transform.localPosition;
  486. newModel.AddComponent<TouchToPlane>();
  487. }
  488. float GetPointToClipPlaneDis(Vector3 point)
  489. {
  490. return Vector3.Dot((point - m_ClipPlanePoint), m_ClipPlaneNormal);
  491. }
  492. Vector3 GetLinePlaneCrossPoint(Vector3 lineBegin, Vector3 lineEnd)
  493. {
  494. //Debug.Log("起点:" + lineBegin + "," + "终点:" + lineEnd);
  495. float x = 0;
  496. float y = 0;
  497. float z = 0;
  498. float offsetZ = lineEnd.z - lineBegin.z;
  499. float offsetY = lineEnd.y - lineBegin.y;
  500. if (offsetZ != 0)
  501. {
  502. float k1 = (m_ClipPlaneNormal.x * (lineEnd.x - lineBegin.x) + m_ClipPlaneNormal.y * (lineEnd.y - lineBegin.y)) / offsetZ + m_ClipPlaneNormal.z;
  503. float k2 = (m_ClipPlaneNormal.x * lineBegin.z * (lineEnd.x - lineBegin.x) + m_ClipPlaneNormal.y * lineBegin.z * (lineEnd.y - lineBegin.y)) / offsetZ;
  504. float k3 = m_ClipPlaneNormal.x * lineBegin.x - m_ClipPlaneNormal.x * m_ClipPlanePoint.x + m_ClipPlaneNormal.y * lineBegin.y - m_ClipPlaneNormal.y * m_ClipPlanePoint.y - m_ClipPlaneNormal.z * m_ClipPlanePoint.z;
  505. z = (k2 - k3) / k1;
  506. x = (z - lineBegin.z) * (lineEnd.x - lineBegin.x) / offsetZ + lineBegin.x;
  507. y = (z - lineBegin.z) * (lineEnd.y - lineBegin.y) / offsetZ + lineBegin.y;
  508. }
  509. else if(offsetY != 0)
  510. {
  511. z = lineBegin.z;
  512. float k1 = m_ClipPlaneNormal.y + m_ClipPlaneNormal.x * (lineEnd.x - lineBegin.x) / (lineEnd.y - lineBegin.y);
  513. float k2 = m_ClipPlaneNormal.x * lineBegin.y * (lineEnd.x - lineBegin.x) / (lineEnd.y - lineBegin.y);
  514. float k3 = lineBegin.x* m_ClipPlaneNormal.x - m_ClipPlanePoint.x * m_ClipPlaneNormal.x - m_ClipPlaneNormal.y * m_ClipPlanePoint.y + m_ClipPlaneNormal.z * z - m_ClipPlaneNormal.z * m_ClipPlanePoint.z;
  515. y = (k2 - k3) / k1;
  516. x = (y - lineBegin.y) * (lineEnd.x - lineBegin.x) / (lineEnd.y - lineBegin.y) + lineBegin.x;
  517. }
  518. else
  519. {
  520. z = lineBegin.z;
  521. y = lineBegin.y;
  522. x = (m_ClipPlaneNormal.x * m_ClipPlanePoint.x - m_ClipPlaneNormal.y * (y - m_ClipPlanePoint.y) - m_ClipPlaneNormal.z * (z - m_ClipPlanePoint.z)) / m_ClipPlaneNormal.x;
  523. }
  524. // Debug.Log(x + "," + y + "," + z);
  525. return new Vector3(x, y, z);
  526. }
  527. int IsContainsVertice(List<Vector3> list, Vector3 vertice)
  528. {
  529. int count = list.Count;
  530. for(int i = 0; i < count; ++i)
  531. {
  532. Vector3 ii = list[i];
  533. if (IsEqual(ii.x, vertice.x) && IsEqual(ii.y, vertice.y) && IsEqual(ii.z, vertice.z))
  534. {
  535. return i;
  536. }
  537. }
  538. return -1;
  539. }
  540. bool IsEqual(float num1, float num2)
  541. {
  542. float absX = Mathf.Abs(num1 - num2);
  543. return absX < 0.00001f;
  544. }
  545. }
  1. /*
  2. * @authors: liangjian
  3. * @desc:
  4. */
  5. using UnityEngine;
  6. using System.Collections;
  7. using System;
  8. public class SortAngle : IComparable<SortAngle> {
  9. public int Index;
  10. public float Angle;
  11. public int CompareTo(SortAngle item)
  12. {
  13. return item.Angle.CompareTo(Angle);
  14. }
  15. }




声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/98013
推荐阅读
相关标签
  

闽ICP备14008679号