void SetPolyEditMode(PolyShape.PolyEditMode mode) { if (polygon == null) { return; } PolyShape.PolyEditMode old = polygon.polyEditMode; if (mode != old) { GUIUtility.hotControl = 0; // Entering edit mode after the shape has been finalized once before, which means // possibly reverting manual changes. Store undo state so that if this was // not intentional user can revert. if (old == PolyShape.PolyEditMode.None && polygon.m_Points.Count > 2) { if (ProBuilderEditor.instance != null) { ProBuilderEditor.instance.ClearElementSelection(); } UndoUtility.RecordComponents <ProBuilderMesh, PolyShape>(polygon.GetComponents(typeof(Component)), "Edit Polygon Shape"); } polygon.polyEditMode = mode; // If coming from Path -> Height set the mouse / origin offset if (old == PolyShape.PolyEditMode.Path && mode == PolyShape.PolyEditMode.Height && Event.current != null) { Vector3 up = polygon.transform.up; Vector3 origin = polygon.transform.TransformPoint(Math.Average(polygon.m_Points)); Ray r = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); Vector3 p = Math.GetNearestPointRayRay(origin, up, r.origin, r.direction); float extrude = Vector3.Distance(origin, p) * Mathf.Sign(Vector3.Dot(p - origin, up)); s_HeightMouseOffset = polygon.extrude - EditorSnapping.MoveSnap(extrude); } else if (old == PolyShape.PolyEditMode.Path && mode == PolyShape.PolyEditMode.None) { var go = polygon.gameObject; EditorApplication.delayCall += () => DestroyImmediate(go); return; } RebuildPolyShapeMesh(polygon); //Dirty the polygon for serialization (fix for transition between prefab and scene mode) if (polygon != null) { UnityEditor.EditorUtility.SetDirty(polygon); } } }
void BeginDrag() { if (m_DragState.active) { return; } m_DragState.active = true; var trs = m_Selection.mesh.transform; // The constraint ray is stored in world space var origin = trs.TransformPoint(PMath.Average(m_Selection.mesh.positions, m_Selection.face.indexes)); var direction = trs.TransformDirection(PMath.Normal(m_Selection.mesh, m_Selection.face)); m_DragState.constraint = new Ray(origin, direction); m_DragState.meshState = new MeshState(m_Selection.mesh, m_Selection.face.distinctIndexes); m_DragState.offset = GetDragDistance(); }
bool CheckFaceVertexAttributes(ProBuilderMesh mesh, Face face, out InvalidFaceInfo info) { info = default; var positions = mesh.positionsInternal; var normals = mesh.normalsInternal; var tangents = mesh.tangentsInternal; var textures = mesh.texturesInternal; var indices = face.indexesInternal; var distinct = face.distinctIndexesInternal; for (int i = 0, c = indices.Length; i < c; i += 3) { if (Math.TriangleArea(positions[indices[i]], positions[indices[i + 1]], positions[indices[i + 2]]) < float.Epsilon) { info.problems += $"Degenerate Triangle {indices[i]} {indices[i+1]} {indices[i+2]}"; } } for (int i = 0, c = distinct.Length; i < c; ++i) { if (normals != null && !Math.IsNumber(normals[i])) { info.problems += $"normals [{i}] is NaN"; } if (textures != null && !Math.IsNumber(textures[i])) { info.problems += $"uv0 [{i}] is NaN"; } if (tangents != null && !Math.IsNumber(tangents[i])) { info.problems += $"tangents [{i}] is NaN"; } } info.position = Math.Average(positions, distinct); return(!string.IsNullOrEmpty(info.problems)); }
void DoExistingPointsGUI() { Transform trs = polygon.transform; int len = polygon.m_Points.Count; Vector3 up = trs.up; Vector3 right = trs.right; Vector3 forward = trs.forward; Vector3 center = Vector3.zero; Event evt = Event.current; bool used = evt.type == EventType.Used; if (!used && (evt.type == EventType.MouseDown && evt.button == 0 && !EditorHandleUtility.IsAppendModifier(evt.modifiers))) { m_SelectedIndex = -1; } if (evt.type == EventType.Repaint && polygon.polyEditMode == PolyShape.PolyEditMode.Path) { Vector3 currentPos = polygon.transform.TransformPoint(m_CurrentPosition); Handles.color = k_HandleColor; Handles.DotHandleCap(-1, currentPos, Quaternion.identity, HandleUtility.GetHandleSize(currentPos) * k_HandleSize, evt.type); Handles.color = Color.white; } if (polygon.polyEditMode == PolyShape.PolyEditMode.Height) { if (!used && evt.type == EventType.MouseUp && evt.button == 0 && !EditorHandleUtility.IsAppendModifier(evt.modifiers)) { evt.Use(); SetPolyEditMode(PolyShape.PolyEditMode.Edit); } bool sceneInUse = EditorHandleUtility.SceneViewInUse(evt); Ray r = HandleUtility.GUIPointToWorldRay(evt.mousePosition); Vector3 origin = polygon.transform.TransformPoint(Math.Average(polygon.m_Points)); float extrude = polygon.extrude; if (evt.type == EventType.MouseMove && !sceneInUse) { Vector3 p = Math.GetNearestPointRayRay(origin, up, r.origin, r.direction); extrude = EditorSnapping.MoveSnap(s_HeightMouseOffset + Vector3.Distance(origin, p) * Mathf.Sign(Vector3.Dot(p - origin, up))); } Vector3 extrudePoint = origin + (extrude * up); if (m_DrawHeightHandles) { Handles.color = k_HandleColor; Handles.DotHandleCap(-1, origin, Quaternion.identity, HandleUtility.GetHandleSize(origin) * k_HandleSize, evt.type); Handles.color = k_HandleColorGreen; Handles.DrawLine(origin, extrudePoint); Handles.DotHandleCap(-1, extrudePoint, Quaternion.identity, HandleUtility.GetHandleSize(extrudePoint) * k_HandleSize, evt.type); Handles.color = Color.white; } if (!sceneInUse && polygon.extrude != extrude) { OnBeginVertexMovement(); polygon.extrude = extrude; RebuildPolyShapeMesh(false); } } else { // vertex dots for (int ii = 0; ii < len; ii++) { Vector3 point = trs.TransformPoint(polygon.m_Points[ii]); center.x += point.x; center.y += point.y; center.z += point.z; float size = HandleUtility.GetHandleSize(point) * k_HandleSize; Handles.color = ii == m_SelectedIndex ? k_HandleSelectedColor : k_HandleColor; EditorGUI.BeginChangeCheck(); point = Handles.Slider2D(point, up, right, forward, size, Handles.DotHandleCap, Vector2.zero, true); if (EditorGUI.EndChangeCheck()) { UndoUtility.RecordObject(polygon, "Move Polygon Shape Point"); polygon.m_Points[ii] = GetPointInLocalSpace(point); OnBeginVertexMovement(); RebuildPolyShapeMesh(false); } // "clicked" a button if (!used && evt.type == EventType.Used) { if (ii == 0 && polygon.m_Points.Count > 2 && polygon.polyEditMode == PolyShape.PolyEditMode.Path) { m_NextMouseUpAdvancesMode = true; return; } else { used = true; m_SelectedIndex = ii; } } } Handles.color = Color.white; // height setting if (polygon.polyEditMode != PolyShape.PolyEditMode.Path && polygon.m_Points.Count > 2) { center.x /= (float)len; center.y /= (float)len; center.z /= (float)len; Vector3 extrude = center + (up * polygon.extrude); m_DistanceFromHeightHandle = Vector2.Distance(HandleUtility.WorldToGUIPoint(extrude), evt.mousePosition); EditorGUI.BeginChangeCheck(); if (m_DrawHeightHandles) { Handles.color = k_HandleColor; Handles.DotHandleCap(-1, center, Quaternion.identity, HandleUtility.GetHandleSize(center) * k_HandleSize, evt.type); Handles.DrawLine(center, extrude); Handles.color = k_HandleColorGreen; extrude = Handles.Slider(extrude, up, HandleUtility.GetHandleSize(extrude) * k_HandleSize, Handles.DotHandleCap, 0f); Handles.color = Color.white; } if (EditorGUI.EndChangeCheck()) { UndoUtility.RecordObject(polygon, "Set Polygon Shape Height"); polygon.extrude = EditorSnapping.MoveSnap(Vector3.Distance(extrude, center) * Mathf.Sign(Vector3.Dot(up, extrude - center))); OnBeginVertexMovement(); RebuildPolyShapeMesh(false); } } } }