private void OnDeleteClick() { var selected = EventSystem.current.currentSelectedGameObject; if (selected && selected.TryGetComponent(out Button _)) { string btnName = selected.name; if (int.TryParse(btnName.Substring(btnName.Length - 1), out int i)) { if (deletedIndex != -1) { CVSPUIManager.PostMessage("#LOC_CVSP_WRN_AtLeastThreeVertices"); vertexInfos[deletedIndex].EnableUIElements(); } deletedIndex = i; vertexInfos[i].DisableUIElements(); Vector3 pos = deletedHighlight.transform.position; deletedHighlight.transform.position = new Vector3(pos.x, vertexInfos[i].parentObject.position.y, pos.z); deletedHighlight.SetActive(true); } } }
private void OnConfirm() { if (pickingVertex) { FinishPick(); } else { int deletedIndexTemp = deletedIndex; Vector3 v0, v1, v2, v3 = Vector3.zero; //Main axis (part local Y axis) Vector3 mainAxis; Vector3 position; Vector3 zAxis; Quaternion orientation; float height0, height1; float length; float tilt0; float tilt1; Vector3 normal; if (!float.TryParse(thicknessInput.text, out float thickness)) { thickness = 0; } float width = thickness; #region Check if there are vertices at the same position bool hasOverlap = false; for (int i = 0; i < vertexInfos.Length; i++) { if (i != deletedIndexTemp) { var v = vertexInfos[i].currentCoords; for (int j = i + 1; j < vertexInfos.Length - i; j++) { if (j != deletedIndexTemp && vertexInfos[j].currentCoords == v) { if (!hasOverlap) { deletedIndexTemp = j; hasOverlap = true; } else { CVSPUIManager.PostMessage("#LOC_CVSP_WRN_AtLeastThreeVertices"); return; } } } } } #endregion Vector3 v01, v32; #region Re-organize vertices order to make sure thickness is applied on correct side #region Calculate normal if (deletedIndexTemp < 0) { v0 = vertexInfos[0].currentCoords; v1 = vertexInfos[1].currentCoords; v2 = vertexInfos[2].currentCoords; v3 = vertexInfos[3].currentCoords; v01 = v1 - v0; v32 = v2 - v3; var norm012 = Vector3.Cross(v01, v2 - v1); var norm230 = Vector3.Cross(-v32, v0 - v3); #region Fix abnormal normals if (Vector3.Dot(norm012, norm230) < 0) { var temp = v3; v3 = v2; v2 = temp; v32 = v2 - v3; norm230 = Vector3.Cross(-v32, v0 - v3); } #endregion normal = (norm012 + norm230) / 2; } else { int i = 0; if (i == deletedIndexTemp) { i++; } v0 = vertexInfos[i++].currentCoords; if (i == deletedIndexTemp) { i++; } v1 = vertexInfos[i++].currentCoords; if (i == deletedIndexTemp) { i++; } v2 = vertexInfos[i].currentCoords; v01 = v1 - v0; normal = Vector3.Cross(v01, v2 - v1); } #endregion #region Flip if (Vector3.Dot(CapsuleRay.editorCamera.transform.forward, normal) > 0) { normal = -normal; var temp = v1; v1 = v0; v0 = temp; if (deletedIndexTemp < 0) { temp = v3; v3 = v2; v2 = temp; } } #endregion #endregion var offsetDistance = thickness / 2; float twist = 0; if (deletedIndexTemp < 0) { v01 = v1 - v0; v32 = v2 - v3; #region Apply thickness (by offseting vertices) var norm012 = Vector3.Cross(v01, v2 - v1).normalized; var norm230 = Vector3.Cross(-v32, v0 - v3).normalized; Vector3 offset012 = -norm012 * offsetDistance; v0 += offset012; v1 += offset012; Vector3 offset230 = -norm230 * offsetDistance; v2 += offset230; v3 += offset230; v01 = v1 - v0; v32 = v2 - v3; #endregion var mid01 = (v0 + v1) / 2; var mid32 = (v2 + v3) / 2; mainAxis = mid32 - mid01; position = (mid01 + mid32) / 2; Vector3 v01prj = v01 - Vector3.Project(v01, mainAxis); Vector3 v32prj = v32 - Vector3.Project(v32, mainAxis); zAxis = v01prj; #region Clamp twist to +/-45 deg twist = -Vector3.SignedAngle(v01prj, v32prj, mainAxis); if (Mathf.Abs(twist) > 45f) { var limit = Mathf.Sign(twist) * 45f; CVSPUIManager.PostMessage($"#LOC_CVSP_Twist {twist.ToString("#0.#")} #LOC_CVSP_OutOfLimit +/-45"); var correction = limit - twist; twist = limit; //减去偏移,以免它造成旋转后位置不正确 Quaternion q = Quaternion.AngleAxis(correction, mainAxis); v2 -= offset230; v3 -= offset230; v2 = q * v2; v3 = q * v3; offset230 = q * offset230; v2 += offset230; v3 += offset230; vertexInfos[2].SetCoordinates(v2); vertexInfos[3].SetCoordinates(v3); vertexInfos[2].UpdateInputField(); vertexInfos[3].UpdateInputField(); } #endregion #region Calculate shape tilt0 = Vector3.SignedAngle(v01, mainAxis, Vector3.Cross(v01, mainAxis)) + -90f; tilt1 = Vector3.SignedAngle(v32, mainAxis, Vector3.Cross(v32, mainAxis)) + -90f; height0 = v01.magnitude; height1 = v32.magnitude; #endregion } else { v01 = v1 - v0; #region Apply thickness (by offseting vertices) var norm012 = Vector3.Cross(v01, v2 - v1).normalized; v0 -= norm012 * offsetDistance; v1 -= norm012 * offsetDistance; v2 -= norm012 * offsetDistance; #endregion var mid01 = (v0 + v1) / 2; mainAxis = v2 - mid01; Vector3 v01prj = v01 - Vector3.Project(v01, mainAxis); zAxis = v01prj; #region Calculate shape position = (mid01 + v2) / 2; height0 = v01.magnitude; height1 = 0; tilt0 = Vector3.SignedAngle(v01, mainAxis, Vector3.Cross(v01, mainAxis)) + -90f; tilt1 = 0; #endregion } length = mainAxis.magnitude; orientation = Quaternion.LookRotation(-zAxis, -mainAxis); if (Mathf.Abs(tilt0) > 45f) { CVSPUIManager.PostMessage($"#LOC_CVSP_Tilt {tilt0.ToString("#0.#")} #LOC_CVSP_OutOfLimit #LOC_CVSP_NeedHelp"); } if (Mathf.Abs(tilt1) > 45f) { CVSPUIManager.PostMessage($"#LOC_CVSP_Tilt {tilt1.ToString("#0.#")} #LOC_CVSP_OutOfLimit #LOC_CVSP_NeedHelp"); } if (height0 > 20f) { CVSPUIManager.PostMessage($"#LOC_CVSP_Height 0 {height0.ToString("#0.#")} #LOC_CVSP_OutOfLimit #LOC_CVSP_NeedHelp"); } if (height1 > 20f) { CVSPUIManager.PostMessage($"#LOC_CVSP_Height 1 {height1.ToString("#0.#")} #LOC_CVSP_OutOfLimit #LOC_CVSP_NeedHelp"); } if (length > 20f) { CVSPUIManager.PostMessage($"#LOC_CVSP_Length {length.ToString("#0.#")} #LOC_CVSP_OutOfLimit #LOC_CVSP_NeedHelp"); } #region Send Parameters to create part CVSPPartInfo info = new CVSPPartInfo() { height0 = height0, height1 = height1, width = width, length = length, position = position, orientation = orientation, twist = twist, tilt0 = tilt0, tilt1 = tilt1 }; CVSPUIManager.CreateCVSPPart(info); #endregion } }