MeshCenterSelect.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. using Sirenix.OdinInspector;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using UnityEngine;
  6. public class MeshCenterSelect : MonoBehaviour
  7. {
  8. public GameObject modelA;
  9. public GameObject modelB;
  10. // 模型A的层级树对象
  11. public objTree ObjATree;
  12. public objTree ObjBTree;
  13. [DictionaryDrawerSettings]
  14. public Dictionary<Vector3, objTree> objADic;
  15. [DictionaryDrawerSettings]
  16. public Dictionary<Vector3, objTree> objBDic;
  17. [Button("测试")]
  18. void CreateTree()
  19. {
  20. ObjATree = new objTree(modelA);
  21. ObjBTree = new objTree(modelB);
  22. objADic = new Dictionary<Vector3, objTree>();
  23. objBDic = new Dictionary<Vector3, objTree>();
  24. FindChild(ObjATree, objADic);
  25. FindChild(ObjBTree, objBDic);
  26. GameObject newFenzumubiao = new GameObject("分组目标");
  27. HierarchicalMatching(ObjATree, newFenzumubiao);
  28. modelB.transform.SetParent(newFenzumubiao.transform, newFenzumubiao);
  29. modelB.name = "没配对上的";
  30. }
  31. void FindChild(objTree child, Dictionary<Vector3, objTree> pairs) //收集未分组的mesh
  32. {
  33. if(child.meshRenderer != null)
  34. {
  35. if (!pairs.ContainsKey(child.CenterV3))
  36. pairs.Add(child.CenterV3, child);
  37. else Debug.LogError(child.nodeObj.name);
  38. }
  39. // 递归遍历所有子物体
  40. for (int i = 0; i < child.children.Count; i++)
  41. FindChild(child.children[i], pairs);
  42. }
  43. void HierarchicalMatching(objTree tree, GameObject NowPoint) //按层级匹配
  44. {
  45. GameObject matchTmpObj;
  46. if (tree.meshRenderer != null && objBDic.TryGetValue(tree.CenterV3, out objTree tmpObj))
  47. matchTmpObj = tmpObj.nodeObj;
  48. else
  49. {
  50. matchTmpObj = new GameObject();
  51. matchTmpObj.name = tree.nodeObj.name;
  52. }
  53. matchTmpObj.transform.SetParent(NowPoint.transform);
  54. foreach (objTree tmp in tree.children)
  55. HierarchicalMatching(tmp, matchTmpObj);
  56. }
  57. [Serializable]
  58. public class objTree
  59. {
  60. public MeshRenderer meshRenderer;
  61. public GameObject nodeObj;
  62. public List<objTree> children = new List<objTree>();
  63. public Vector3 CenterV3;
  64. public objTree(GameObject gameObj)
  65. {
  66. nodeObj = gameObj;//节点
  67. if(nodeObj.GetComponent<MeshRenderer>()!= null)
  68. {
  69. meshRenderer = nodeObj.GetComponent<MeshRenderer>();
  70. Vector3 tmpV3 = meshRenderer.bounds.center;
  71. CenterV3 = new Vector3(float.Parse(tmpV3.x.ToString("F2")),
  72. float.Parse(tmpV3.y.ToString("F2")),
  73. float.Parse(tmpV3.z.ToString("F2")));
  74. }
  75. addObjNode();
  76. }
  77. public void addObjNode()
  78. {
  79. for (int i = 0; i < nodeObj.transform.childCount; i++)
  80. {
  81. children.Add(new objTree(nodeObj.transform.GetChild(i).gameObject));
  82. }
  83. }
  84. }
  85. public struct Vector3Double
  86. {
  87. public double x, y, z;
  88. public Vector3Double(double x, double y, double z)
  89. {
  90. this.x = x;
  91. this.y = y;
  92. this.z = z;
  93. }
  94. // 转换为 Unity 的 Vector3(会损失精度)
  95. public Vector3 ToVector3()
  96. {
  97. return new Vector3((float)x, (float)y, (float)z);
  98. }
  99. // 从 Vector3 转换
  100. public static Vector3Double FromVector3(Vector3 v)
  101. {
  102. return new Vector3Double(v.x, v.y, v.z);
  103. }
  104. }
  105. }