SafetyPlaneMono.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. using SC.XR.Unity.Module_InputSystem;
  2. using SC.XR.Unity.Module_InputSystem.InputDeviceHand;
  3. using System;
  4. using System.Collections;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using UnityEngine;
  8. using UnityEngine.EventSystems;
  9. public class SafetyPlaneMono : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerEnterHandler, IPointerExitHandler
  10. {
  11. private bool isFreeze = false;
  12. private bool isHover = false;
  13. private bool canFill = false;
  14. private int lastPaintIndex = -1;
  15. private PointerEventData currentPointerEventData;
  16. private PointerEventData hoverPointerEventData;
  17. private Mesh mesh;
  18. private MeshRenderer meshRenderer;
  19. //private Mesh hoverMesh;
  20. private MeshRenderer hoverMeshRenderer;
  21. //private Mesh largerMesh;
  22. //private MeshRenderer largerMeshRenderer;
  23. private Color[] colors;
  24. //private Color[] hoverColors;
  25. //private Color[] largerColors;
  26. private GroundHeightStep groundHeightStep;
  27. private float animationTime;
  28. private bool isPlayAnimation = false;
  29. private Action<PointerEventData> OnPointerClickDown
  30. {
  31. get;
  32. set;
  33. }
  34. private Action<PointerEventData> OnPointerClickUp
  35. {
  36. get;
  37. set;
  38. }
  39. private void Awake()
  40. {
  41. DontDestroyOnLoad(this.gameObject);
  42. }
  43. public void Init()
  44. {
  45. if (groundHeightStep == null)
  46. {
  47. groundHeightStep = SafetyAreaManager.Instance.GetStep<GroundHeightStep>(SafetyAreaStepEnum.GroundHeight);
  48. }
  49. MeshFilter meshFilter = this.gameObject.AddComponent<MeshFilter>();
  50. meshFilter.mesh = SafetyAreaVertexHelper.GeneratePlaneMesh();
  51. mesh = meshFilter.mesh;
  52. meshRenderer = this.gameObject.AddComponent<MeshRenderer>();
  53. meshRenderer.material = Resources.Load<Material>("Material/SafetyPlaneMat");
  54. BoxCollider boxCollider = this.gameObject.AddComponent<BoxCollider>();
  55. //boxCollider.size = new Vector3();
  56. //MeshCollider meshCollider = this.gameObject.AddComponent<MeshCollider>();
  57. //meshCollider.sharedMesh = mesh;
  58. GameObject hoverObject = GameObject.Instantiate(this.gameObject);
  59. hoverMeshRenderer = hoverObject.GetComponent<MeshRenderer>();
  60. GameObject.Destroy(hoverObject.GetComponent<SafetyPlaneMono>());
  61. //GameObject.Destroy(hoverObject.GetComponent<MeshCollider>());
  62. GameObject.Destroy(hoverObject.GetComponent<BoxCollider>());
  63. //hoverMesh = hoverObject.GetComponent<MeshFilter>().mesh;
  64. hoverObject.transform.SetParent(this.gameObject.transform);
  65. ClearAllMeshColor();
  66. }
  67. public void DisableRenderer()
  68. {
  69. meshRenderer.enabled = false;
  70. hoverMeshRenderer.enabled = false;
  71. }
  72. public void EnableRenderer()
  73. {
  74. meshRenderer.enabled = true;
  75. hoverMeshRenderer.enabled = true;
  76. }
  77. float bias = -6.3f;
  78. // Update is called once per frame
  79. void Update()
  80. {
  81. if (!isFreeze)
  82. {
  83. ContinueSetPlaneHeight();
  84. meshRenderer.sharedMaterial.SetVector("_MainTex_ST", new Vector4(30f, 30f, Camera.main.transform.position.x * PlayAreaConstant.CELL_SIZE * (PlayAreaConstant.GRID_SIZE + bias) / 2f, Camera.main.transform.position.z * PlayAreaConstant.CELL_SIZE * (PlayAreaConstant.GRID_SIZE + bias) / 2f));
  85. }
  86. else
  87. {
  88. if (canFill)
  89. {
  90. FillNearest(currentPointerEventData);
  91. }
  92. //ClearHoverMesh();
  93. if (isHover)
  94. {
  95. FillHoverNearest(hoverPointerEventData);
  96. }
  97. }
  98. if (isPlayAnimation)
  99. {
  100. animationTime += Time.deltaTime;
  101. meshRenderer.sharedMaterial.SetFloat("_Mtime", animationTime / 15f);
  102. }
  103. }
  104. public void FreezePlaneHeight()
  105. {
  106. Transform headTransform = GetHeadTransform();
  107. this.gameObject.transform.position = new Vector3(headTransform.position.x, 0, headTransform.position.z);
  108. isFreeze = true;
  109. }
  110. public void UnFreezePlaneHeight()
  111. {
  112. ContinueSetPlaneHeight();
  113. isFreeze = false;
  114. }
  115. public void ContinueSetPlaneHeight()
  116. {
  117. GameObject interactiveObject = GetInteractiveGameObject();
  118. if (interactiveObject != null)
  119. {
  120. groundHeightStep.SetPlaneHeight(interactiveObject.transform.position.y - 0.1f);
  121. }
  122. Transform headTransform = GetHeadTransform();
  123. groundHeightStep.SetHeadPosition(headTransform.position);
  124. this.gameObject.transform.position = new Vector3(headTransform.position.x, groundHeightStep.GetPlaneHeight(), headTransform.position.z);
  125. Vector3 localHeadPosition = this.transform.InverseTransformPoint(Camera.main.transform.position);
  126. meshRenderer.sharedMaterial.SetVector("headPosition", new Vector4(localHeadPosition.x, localHeadPosition.y, localHeadPosition.z, 1));
  127. }
  128. private void EnableFill(PointerEventData eventData)
  129. {
  130. canFill = true;
  131. }
  132. private void DisableFill(PointerEventData eventData)
  133. {
  134. canFill = false;
  135. }
  136. private GameObject GetInteractiveGameObject()
  137. {
  138. if (Module_InputSystem.instance == null) return null;
  139. if (Module_InputSystem.instance.IsSomeDeviceActiveWithoutHead)
  140. {
  141. if (Module_InputSystem.instance.GetInputDeviceStatus(InputDeviceType.GGT26Dof))
  142. {
  143. InputDeviceBase inputDevice = Module_InputSystem.instance.GetInputDevice<InputDeviceBase>(InputDeviceType.GGT26Dof);
  144. GameObject handModel = null;
  145. foreach (var part in inputDevice.inputDevicePartList)
  146. {
  147. if (part.inputDataBase.isVaild == true)
  148. {
  149. GameObject handModlePart = (part as InputDeviceHandPart).inputDeviceHandPartUI.modelHand.ActiveHandModel.GetJointTransform(FINGER.forefinger, JOINT.One).gameObject;
  150. if (handModel == null || handModel.transform.position.y > handModlePart.transform.position.y)
  151. {
  152. handModel = handModlePart;
  153. }
  154. }
  155. }
  156. //Debug.Log(handModel.name);
  157. return handModel;
  158. }
  159. else if (Module_InputSystem.instance.GetInputDeviceStatus(InputDeviceType.KS))
  160. {
  161. InputDeviceBase inputDevice = Module_InputSystem.instance.GetInputDevice<InputDeviceBase>(InputDeviceType.KS);
  162. GameObject KSModel = null;
  163. foreach (var part in inputDevice.inputDevicePartList)
  164. {
  165. if (part.inputDataBase.isVaild == true)
  166. {
  167. GameObject KSPart = part.inputDevicePartUIBase.gameObject;
  168. if (KSModel == null || KSModel.transform.position.y > KSPart.transform.position.y)
  169. {
  170. KSModel = KSPart;
  171. }
  172. }
  173. }
  174. return KSModel;
  175. }
  176. else if (Module_InputSystem.instance.GetInputDeviceStatus(InputDeviceType.BT3Dof))
  177. {
  178. InputDeviceBase inputDevice = Module_InputSystem.instance.GetInputDevice<InputDeviceBase>(InputDeviceType.BT3Dof);
  179. GameObject BT3DofModel = null;
  180. foreach (var part in inputDevice.inputDevicePartList)
  181. {
  182. if (part.inputDataBase.isVaild == true)
  183. {
  184. GameObject BT3DofPart = part.inputDevicePartUIBase.gameObject;
  185. if (BT3DofModel == null || BT3DofModel.transform.position.y > BT3DofPart.transform.position.y)
  186. {
  187. BT3DofModel = BT3DofPart;
  188. }
  189. }
  190. }
  191. return BT3DofModel;
  192. }
  193. }
  194. else
  195. {
  196. return Camera.main.transform.gameObject;
  197. }
  198. return null;
  199. }
  200. private Transform GetHeadTransform()
  201. {
  202. return Camera.main.transform.transform;
  203. }
  204. public void OnPointerDown(PointerEventData eventData)
  205. {
  206. currentPointerEventData = eventData;
  207. OnPointerClickDown?.Invoke(eventData);
  208. }
  209. public void OnPointerUp(PointerEventData eventData)
  210. {
  211. currentPointerEventData = null;
  212. OnPointerClickUp?.Invoke(eventData);
  213. }
  214. public void OnPointerEnter(PointerEventData eventData)
  215. {
  216. hoverPointerEventData = eventData;
  217. isHover = true;
  218. }
  219. public void OnPointerExit(PointerEventData eventData)
  220. {
  221. hoverPointerEventData = null;
  222. isHover = false;
  223. }
  224. public void RegistPointerDownFillEvent()
  225. {
  226. OnPointerClickDown += EnableFill;
  227. }
  228. public void UnRegistPointerDownFillEvent()
  229. {
  230. OnPointerClickDown -= EnableFill;
  231. }
  232. public void RegistPointerUpFillEvent()
  233. {
  234. OnPointerClickUp += DisableFill;
  235. }
  236. public void UnRegistPointerUpFillEvent()
  237. {
  238. OnPointerClickUp -= DisableFill;
  239. }
  240. public void RegistPointerUpEvent(Action<PointerEventData> callback)
  241. {
  242. OnPointerClickUp += callback;
  243. }
  244. public void UnRegistPointerUpEvent(Action<PointerEventData> callback)
  245. {
  246. OnPointerClickUp -= callback;
  247. }
  248. public void FillNearest(PointerEventData pointerEventData)
  249. {
  250. if (pointerEventData == null)
  251. {
  252. Debug.LogError("currentPointerEventData == null");
  253. return;
  254. }
  255. Vector3 raycastPosition = pointerEventData.pointerCurrentRaycast.worldPosition;
  256. Vector3 pointerLocalPosition = transform.InverseTransformPoint(raycastPosition);
  257. List<int> effectIndices = SafetyAreaVertexHelper.CaculateEffectVerticeIndices(pointerLocalPosition, PlayAreaConstant.BRUSH_SIZE);
  258. for (int i = 0; i < effectIndices.Count; i++)
  259. {
  260. int index = effectIndices[i];
  261. colors[index] = Color.white;
  262. lastPaintIndex = index;
  263. }
  264. mesh.colors = colors;
  265. }
  266. public void FillHoverNearest(PointerEventData pointerEventData)
  267. {
  268. if (pointerEventData == null)
  269. {
  270. //Debug.LogError("hoverPointerEventData == null");
  271. return;
  272. }
  273. Vector3 raycastPosition = pointerEventData.pointerCurrentRaycast.worldPosition;
  274. Vector3 pointerLocalPosition = transform.InverseTransformPoint(raycastPosition);
  275. hoverMeshRenderer.sharedMaterial.SetFloat("brushSize", PlayAreaConstant.BRUSH_SIZE);
  276. hoverMeshRenderer.sharedMaterial.SetVector("pointerLocalPosition", new Vector4(pointerLocalPosition.x, pointerLocalPosition.y, pointerLocalPosition.z, 1.0f));
  277. //List<int> effectHoverIndices = SafetyAreaVertexHelper.CaculateEffectVerticeIndices(pointerLocalPosition, PlayAreaConstant.BRUSH_SIZE);
  278. //for (int i = 0; i < effectHoverIndices.Count; i++)
  279. //{
  280. // int index = effectHoverIndices[i];
  281. // hoverColors[index] = new Color(1f, 1f, 1f, 1f);
  282. // //lastPaintIndex = index;
  283. //}
  284. //hoverMesh.colors = hoverColors;
  285. }
  286. public void GenerateEdgeMesh(Action<Mesh, float> onGenerateMesh)
  287. {
  288. if (lastPaintIndex == -1)
  289. {
  290. Debug.LogError("lastPaintIndex == -1");
  291. return;
  292. }
  293. SafetyAreaEightNeighbourHelper.EightNeighbours(lastPaintIndex, (index) =>
  294. {
  295. return colors[index] == Color.white;
  296. }, (edgeIndices) =>
  297. {
  298. float planeHeight = 0f;//groundHeightStep.GetPlaneHeight();
  299. float perimeter = 0f;
  300. Mesh edgeMesh = SafetyAreaVertexHelper.GenerateEdgeMesh(mesh, edgeIndices, planeHeight + PlayAreaConstant.SAFETY_AREA_HEIGHT, planeHeight, ref perimeter);
  301. onGenerateMesh?.Invoke(edgeMesh, perimeter);
  302. });
  303. }
  304. //填充中间
  305. public void FillIndices()
  306. {
  307. if (lastPaintIndex == -1)
  308. {
  309. Debug.LogError("lastPaintIndex == -1");
  310. return;
  311. }
  312. SafetyAreaEightNeighbourHelper.EightNeighbours(lastPaintIndex, (index) =>
  313. {
  314. return colors[index] == Color.white;
  315. }, (edgeIndices) =>
  316. {
  317. List<int> fillIndices = ScanLineFillHelper.ScaneLine((index) =>
  318. {
  319. return colors[index] == Color.white;
  320. }, edgeIndices);
  321. for (int i = 0; i < fillIndices.Count; i++)
  322. {
  323. colors[fillIndices[i]] = Color.white;
  324. }
  325. mesh.colors = colors;
  326. });
  327. }
  328. public bool CheckIndicesEnough()
  329. {
  330. int count = 0;
  331. for (int i = 0; i < (PlayAreaConstant.GRID_SIZE + 1); i++)
  332. {
  333. for (int j = 0; j < (PlayAreaConstant.GRID_SIZE + 1); j++)
  334. {
  335. int index = i * (PlayAreaConstant.GRID_SIZE + 1) + j;
  336. if (colors[index] == Color.white)
  337. {
  338. count++;
  339. }
  340. }
  341. }
  342. Debug.Log("fillCount=" + count);
  343. int oneSquareMeterIndexCount = (int)Mathf.Pow(Mathf.CeilToInt(1f / PlayAreaConstant.CELL_SIZE), 2);
  344. Debug.Log("oneSquareMeterIndexCount:" + oneSquareMeterIndexCount);
  345. return count > oneSquareMeterIndexCount;
  346. }
  347. public void ClearAllMeshColor()
  348. {
  349. ClearMeshColor();
  350. //ClearHoverMesh();
  351. }
  352. private void ClearMeshColor()
  353. {
  354. colors = Enumerable.Repeat(Color.clear, mesh.vertexCount).ToArray();
  355. mesh.colors = colors;
  356. }
  357. //private void ClearHoverMesh()
  358. //{
  359. // hoverColors = Enumerable.Repeat(Color.clear, hoverMesh.vertexCount).ToArray();
  360. // hoverMesh.colors = hoverColors;
  361. //}
  362. public void SetPlaneMat(Material mat)
  363. {
  364. meshRenderer.sharedMaterial = mat;
  365. }
  366. public void SetHoverPlaneMat(Material mat)
  367. {
  368. hoverMeshRenderer.sharedMaterial = mat;
  369. }
  370. public void StartPlaneAnimation()
  371. {
  372. animationTime = 0.3f;
  373. meshRenderer.sharedMaterial.SetFloat("_AniUVScale", 1f);
  374. isPlayAnimation = true;
  375. }
  376. public void StopPlaneAnimation()
  377. {
  378. meshRenderer.sharedMaterial.SetFloat("_AniUVScale", 0f);
  379. isPlayAnimation = false;
  380. }
  381. public Color[] GetColorArray()
  382. {
  383. return colors;
  384. }
  385. }