/// <summary> /// The Editing handles are used to manipulate and resize ProBuilderShapes /// These handles are used in 2 tools : EditShapeTool and DrawShapeTool. In this second tool, /// these handles allow to modified the last created shape. /// </summary> /// <param name="proBuilderShape">The Shape on which to attach the handles</param> /// <param name="updatePrefs">Parameter used to update the DrawShapeTool when needed</param> internal static void DoEditingHandles(ProBuilderShape proBuilderShape, bool updatePrefs = false) { if (proBuilderShape == null) { return; } var scale = proBuilderShape.transform.lossyScale; var position = proBuilderShape.transform.position + Vector3.Scale(proBuilderShape.transform.TransformDirection(proBuilderShape.shapeBox.center), scale); var matrix = Matrix4x4.TRS(position, proBuilderShape.transform.rotation, Vector3.one); using (new Handles.DrawingScope(matrix)) { EditorShapeUtility.UpdateFaces(proBuilderShape.editionBounds, scale, faces); for (int i = 0; i < 4; ++i) { k_OrientationControlIDs[i] = GUIUtility.GetControlID(FocusType.Passive); } for (int i = 0; i < faces.Length; ++i) { s_FaceControlIDs[i] = GUIUtility.GetControlID(FocusType.Passive); } var absSize = Math.Abs(proBuilderShape.editionBounds.size); if (absSize.x > Mathf.Epsilon && absSize.y > Mathf.Epsilon && absSize.z > Mathf.Epsilon) { DoOrientationHandles(proBuilderShape, updatePrefs); } DoSizeHandles(proBuilderShape, updatePrefs); } }
internal void RebuildShape() { RecalculateBounds(); if (m_Bounds.size.sqrMagnitude < .01f || Mathf.Abs(m_Bounds.extents.x) < 0.001f || Mathf.Abs(m_Bounds.extents.z) < 0.001f) { if (m_ProBuilderShape != null && m_ProBuilderShape.mesh.vertexCount > 0) { m_ProBuilderShape.mesh.Clear(); m_ProBuilderShape.mesh.Rebuild(); ProBuilderEditor.Refresh(true); } return; } if (!m_IsShapeInit) { var shapeComponent = currentShapeInOverlay; EditorShapeUtility.CopyLastParams(shapeComponent.shape, shapeComponent.shape.GetType()); shapeComponent.gameObject.hideFlags = HideFlags.HideInHierarchy; shapeComponent.mesh.renderer.sharedMaterial = EditorMaterialUtility.GetUserMaterial(); UndoUtility.RegisterCreatedObjectUndo(shapeComponent.gameObject, "Draw Shape"); m_IsShapeInit = true; } m_ProBuilderShape.Rebuild(m_Bounds, m_PlaneRotation); ProBuilderEditor.Refresh(false); SceneView.RepaintAll(); }
public void CreateLastShape() { var shape = ShapeFactory.Instantiate(DrawShapeTool.activeShapeType, (PivotLocation)DrawShapeTool.s_LastPivotLocation.value).GetComponent <ProBuilderShape>(); shape.gameObject.name = shape.gameObject.name + "-Copy"; EditorUtility.InitObject(shape.mesh); DrawShapeTool.ApplyPrefsSettings(shape); UndoUtility.RegisterCreatedObjectUndo(shape.gameObject, "Create Shape Copy"); EditorShapeUtility.CopyLastParams(shape.shape, shape.shape.GetType()); shape.Rebuild(tool.m_Bounds, tool.m_PlaneRotation); //Finish initializing object and collider once it's completed ProBuilderEditor.Refresh(false); tool.m_ProBuilderShape = null; tool.m_LastShapeCreated = shape; if (tool.m_DuplicateGO != null) { GameObject.DestroyImmediate(tool.m_DuplicateGO); } MeshSelection.SetSelection(shape.gameObject); }
internal void RebuildShape() { RecalculateBounds(); if (m_Bounds.size.sqrMagnitude < .01f || Mathf.Abs(m_Bounds.extents.x) < 0.001f || Mathf.Abs(m_Bounds.extents.z) < 0.001f) { if (m_ShapeComponent.mesh.vertexCount > 0) { m_ShapeComponent.mesh.Clear(); m_ShapeComponent.mesh.Rebuild(); ProBuilderEditor.Refresh(true); } return; } if (!m_IsShapeInit) { EditorShapeUtility.CopyLastParams(m_ShapeComponent.shape, m_ShapeComponent.shape.GetType()); m_ShapeComponent.gameObject.hideFlags = HideFlags.None; UndoUtility.RegisterCreatedObjectUndo(m_ShapeComponent.gameObject, "Draw Shape"); } m_ShapeComponent.Rebuild(m_Bounds, m_PlaneRotation); ProBuilderEditor.Refresh(false); if (!m_IsShapeInit) { EditorUtility.InitObject(m_ShapeComponent.mesh); m_IsShapeInit = true; } SceneView.RepaintAll(); }
static void DoOrientationHandles(ProBuilderShape proBuilderShape, bool updatePrefs) { if (GUIUtility.hotControl != 0 && !k_OrientationControlIDs.Contains(GUIUtility.hotControl)) { return; } foreach (var f in faces) { if (f.IsVisible && EditorShapeUtility.PointerIsInFace(f)) { if (DoOrientationHandle(f, proBuilderShape)) { UndoUtility.RecordComponents <Transform, ProBuilderMesh, ProBuilderShape>(proBuilderShape.GetComponents(typeof(Component)), "Rotate Shape"); proBuilderShape.RotateInsideBounds(s_ShapeRotation); ProBuilderEditor.Refresh(); if (updatePrefs) { DrawShapeTool.SaveShapeParams(proBuilderShape); } } } } }
internal void DuplicatePreview(Vector3 position) { if (position.Equals(Vector3.positiveInfinity) || !Event.current.isMouse) { return; } var pivotLocation = (PivotLocation)s_LastPivotLocation.value; var size = currentShapeInOverlay.size; m_Bounds.size = size; Vector3 cornerPosition; switch (pivotLocation) { case PivotLocation.FirstCorner: cornerPosition = GetPoint(position); m_PlaneRotation = Quaternion.LookRotation(m_PlaneForward, m_Plane.normal); m_Bounds.center = cornerPosition + m_PlaneRotation * size / 2f; m_BB_Origin = cornerPosition; m_BB_HeightCorner = m_Bounds.center + m_PlaneRotation * (size / 2f); m_BB_OppositeCorner = m_BB_HeightCorner - m_PlaneRotation * new Vector3(0, size.y, 0); break; case PivotLocation.Center: default: position = GetPoint(position); cornerPosition = position - size / 2f; cornerPosition.y = position.y; m_Bounds.center = cornerPosition + new Vector3(size.x / 2f, 0, size.z / 2f) + (size.y / 2f) * m_Plane.normal; m_PlaneRotation = Quaternion.LookRotation(m_PlaneForward, m_Plane.normal); m_BB_Origin = m_Bounds.center - m_PlaneRotation * (size / 2f); m_BB_HeightCorner = m_Bounds.center + m_PlaneRotation * (size / 2f); m_BB_OppositeCorner = m_BB_HeightCorner - m_PlaneRotation * new Vector3(0, size.y, 0); break; } ProBuilderShape proBuilderShape; if (m_DuplicateGO == null) { var instantiated = ShapeFactory.Instantiate(activeShapeType, ((PivotLocation)s_LastPivotLocation.value)); proBuilderShape = instantiated.GetComponent <ProBuilderShape>(); m_DuplicateGO = proBuilderShape.gameObject; m_DuplicateGO.hideFlags = HideFlags.DontSave | HideFlags.HideInHierarchy; ApplyPrefsSettings(proBuilderShape); proBuilderShape.GetComponent <MeshRenderer>().sharedMaterial = m_ShapePreviewMaterial; } else { proBuilderShape = m_DuplicateGO.GetComponent <ProBuilderShape>(); } EditorShapeUtility.CopyLastParams(proBuilderShape.shape, proBuilderShape.shape.GetType()); proBuilderShape.Rebuild(m_Bounds, m_PlaneRotation); ProBuilderEditor.Refresh(false); }
internal static void SaveShapeParams(ProBuilderShape proBuilderShape) { s_LastPivotLocation.value = (int)proBuilderShape.pivotLocation; s_LastPivotPosition.value = proBuilderShape.pivotLocalPosition; s_LastSize.value = proBuilderShape.size; s_LastRotation.value = proBuilderShape.rotation; EditorShapeUtility.SaveParams(proBuilderShape.shape); }
internal static void SaveShapeParams(ShapeComponent shapeComponent) { s_LastPivotLocation.value = (int)shapeComponent.pivotLocation; s_LastPivotPosition.value = shapeComponent.pivotLocalPosition; s_LastSize.value = shapeComponent.size; s_LastRotation.value = shapeComponent.rotation; EditorShapeUtility.SaveParams(shapeComponent.shape); }
static bool DoFaceSizeHandle(FaceData face, int controlID) { if (k_OrientationControlIDs.Contains(HandleUtility.nearestControl) && !EditorShapeUtility.PointerIsInFace(face)) { return(false); } Event evt = Event.current; float handleSize = HandleUtility.GetHandleSize(face.CenterPosition) * s_DefaultMidpointHandleSize; bool isSelected = (HandleUtility.nearestControl == controlID && s_CurrentId == -1) || s_CurrentId == controlID; switch (evt.GetTypeForControl(controlID)) { case EventType.MouseDown: if (HandleUtility.nearestControl == controlID && evt.button == 0) { s_CurrentId = controlID; GUIUtility.hotControl = controlID; s_StartMousePosition = evt.mousePosition; s_SizeManipulationInit = false; evt.Use(); SceneView.RepaintAll(); } break; case EventType.MouseUp: if (GUIUtility.hotControl == controlID && evt.button == 0) { GUIUtility.hotControl = 0; evt.Use(); s_CurrentId = -1; s_SizeManipulationInit = false; } break; case EventType.Layout: HandleUtility.AddControl(controlID, HandleUtility.DistanceToLine(face.CenterPosition, face.CenterPosition) / 2f); break; case EventType.Repaint: Color color = isSelected ? EditorHandleDrawing.edgeSelectedColor : k_BoundsHandleColor; color.a *= face.IsVisible ? 1f : 0.25f; using (new Handles.DrawingScope(color)) Handles.DotHandleCap(controlID, face.CenterPosition, Quaternion.identity, handleSize, EventType.Repaint); break; case EventType.MouseDrag: if (s_CurrentId == controlID) { s_SizeDelta = HandleUtility.CalcLineTranslation(s_StartMousePosition, evt.mousePosition, s_StartPositionLocal, face.Normal); return(true); } break; } return(false); }
void DrawShapeGUI() { if (m_BoldCenteredStyle == null) { m_BoldCenteredStyle = new GUIStyle("BoldLabel") { alignment = TextAnchor.MiddleCenter } } ; EditorGUILayout.LabelField(EditorShapeUtility.shapeTypes[s_ActiveShapeIndex.value], m_BoldCenteredStyle, GUILayout.ExpandWidth(true)); if (EditorShapeUtility.s_ResetUserPrefs.value) { ResetPrefs(); } var shape = currentShapeInOverlay.shape; int groupCount = EditorShapeUtility.shapeTypesGUI.Count; for (int i = 0; i < groupCount; i++) { EditorGUI.BeginChangeCheck(); EditorGUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); int index = GUILayout.Toolbar(s_ActiveShapeIndex.value - +i * EditorShapeUtility.MaxContentPerGroup, EditorShapeUtility.shapeTypesGUI[i], Styles.command); GUILayout.FlexibleSpace(); EditorGUILayout.EndHorizontal(); if (EditorGUI.EndChangeCheck()) { s_ActiveShapeIndex.value = index + i * EditorShapeUtility.MaxContentPerGroup; var type = EditorShapeUtility.availableShapeTypes[s_ActiveShapeIndex]; if (shape.GetType() != type) { if (currentShapeInOverlay == m_LastShapeCreated) { m_LastShapeCreated = null; } UndoUtility.RegisterCompleteObjectUndo(currentShapeInOverlay, "Change Shape"); Selection.activeObject = null; currentShapeInOverlay.SetShape(EditorShapeUtility.CreateShape(type), currentShapeInOverlay.pivotLocation); SetBounds(currentShapeInOverlay.size); ProBuilderEditor.Refresh(); } } } } }
void ResetPrefs() { var type = EditorShapeUtility.availableShapeTypes[s_ActiveShapeIndex]; if (currentShapeInOverlay == m_LastShapeCreated) { m_LastShapeCreated = null; } UndoUtility.RegisterCompleteObjectUndo(currentShapeInOverlay, "Change Shape"); currentShapeInOverlay.SetShape(EditorShapeUtility.CreateShape(type), currentShapeInOverlay.pivotLocation); SetBounds(currentShapeInOverlay.size); ProBuilderEditor.Refresh(); }
public void DrawShapeParametersGUI(DrawShapeTool tool = null) { if (target == null || serializedObject == null) { return; } serializedObject.Update(); var foldoutEnabled = tool == null ? s_foldoutEnabled : DrawShapeTool.s_SettingsEnabled.value; foldoutEnabled = EditorGUILayout.Foldout(foldoutEnabled, m_ShapePropertyLabel, true); if (tool == null) { s_foldoutEnabled = foldoutEnabled; } else { DrawShapeTool.s_SettingsEnabled.value = foldoutEnabled; } if (foldoutEnabled) { EditorGUI.indentLevel++; EditorGUI.BeginChangeCheck(); m_ActiveShapeIndex = HasMultipleShapeTypes ? -1 : Mathf.Max(-1, Array.IndexOf(EditorShapeUtility.availableShapeTypes, m_CurrentShapeType)); m_ActiveShapeIndex = EditorGUILayout.Popup(m_ActiveShapeIndex, EditorShapeUtility.shapeTypes); if (EditorGUI.EndChangeCheck()) { var type = EditorShapeUtility.availableShapeTypes[m_ActiveShapeIndex]; foreach (var comp in targets) { ShapeComponent shapeComponent = ((ShapeComponent)comp); Shape shape = shapeComponent.shape; if (shape.GetType() != type) { if (tool != null) { DrawShapeTool.s_ActiveShapeIndex.value = m_ActiveShapeIndex; } UndoUtility.RecordComponents <Transform, ProBuilderMesh, ShapeComponent>(shapeComponent.GetComponents(typeof(Component)), "Change Shape"); shapeComponent.SetShape(EditorShapeUtility.CreateShape(type), shapeComponent.pivotLocation); ProBuilderEditor.Refresh(); } } } if (tool) { EditorGUILayout.PropertyField(m_ShapePivotProperty, k_ShapePivotLabel); } EditorGUILayout.PropertyField(m_ShapeSizeXProperty, k_ShapeSizeXLabel); if (HasMultipleShapeTypes || (m_CurrentShapeType != typeof(Plane) && m_CurrentShapeType != typeof(Sprite))) { EditorGUILayout.PropertyField(m_ShapeSizeYProperty, k_ShapeSizeYLabel); } EditorGUILayout.PropertyField(m_ShapeSizeZProperty, k_ShapeSizeZLabel); EditorGUI.indentLevel--; } if (!HasMultipleShapeTypes) { EditorGUILayout.PropertyField(m_ShapeProperty, new GUIContent("Shape Properties"), true); } if (serializedObject.ApplyModifiedProperties()) { foreach (var comp in targets) { var shapeComponent = comp as ShapeComponent; if (shapeComponent.isEditable) { UndoUtility.RecordComponents <Transform, ProBuilderMesh, ShapeComponent>(shapeComponent.GetComponents(typeof(Component)), "Resize Shape"); shapeComponent.UpdateComponent(); if (tool != null) { tool.SetBounds(shapeComponent.size); DrawShapeTool.SaveShapeParams(shapeComponent); } ProBuilderEditor.Refresh(); } } } GUI.enabled = true; }
internal void DoDuplicateShapePreviewHandle(Vector3 position) { var evt = Event.current; if (evt.type != EventType.Repaint) { return; } bool previewShortcutActive = evt.shift && !(evt.control || evt.command); if (HandleUtility.nearestControl != m_ControlID || !previewShortcutActive) { DestroyImmediate(m_DuplicateGO); return; } var pivotLocation = (PivotLocation)s_LastPivotLocation.value; var size = currentShapeInOverlay.size; m_Bounds.size = size; Vector3 cornerPosition; switch (pivotLocation) { case PivotLocation.FirstCorner: cornerPosition = GetPoint(position); m_PlaneRotation = Quaternion.LookRotation(m_PlaneForward, m_Plane.normal); m_Bounds.center = cornerPosition + m_PlaneRotation * size / 2f; m_BB_Origin = cornerPosition; m_BB_HeightCorner = m_Bounds.center + m_PlaneRotation * (size / 2f); m_BB_OppositeCorner = m_BB_HeightCorner - m_PlaneRotation * new Vector3(0, size.y, 0); break; case PivotLocation.Center: default: position = GetPoint(position); cornerPosition = position - size / 2f; cornerPosition.y = position.y; m_Bounds.center = cornerPosition + new Vector3(size.x / 2f, 0, size.z / 2f) + (size.y / 2f) * m_Plane.normal; m_PlaneRotation = Quaternion.LookRotation(m_PlaneForward, m_Plane.normal); m_BB_Origin = m_Bounds.center - m_PlaneRotation * (size / 2f); m_BB_HeightCorner = m_Bounds.center + m_PlaneRotation * (size / 2f); m_BB_OppositeCorner = m_BB_HeightCorner - m_PlaneRotation * new Vector3(0, size.y, 0); break; } if (m_DuplicateGO == null) { var instantiated = ShapeFactory.Instantiate(activeShapeType, ((PivotLocation)s_LastPivotLocation.value)); var shape = instantiated.GetComponent <ProBuilderShape>(); m_DuplicateGO = shape.gameObject; m_DuplicateGO.hideFlags = HideFlags.DontSave | HideFlags.HideInHierarchy; ApplyPrefsSettings(shape); shape.GetComponent <MeshRenderer>().sharedMaterial = m_ShapePreviewMaterial; EditorShapeUtility.CopyLastParams(shape.shape, shape.shape.GetType()); shape.Rebuild(m_Bounds, m_PlaneRotation, m_BB_Origin); ProBuilderEditor.Refresh(false); } var pivot = GetPoint(position); if (pivotLocation == PivotLocation.Center) { pivot += m_Plane.normal * size.y * .5f; } m_DuplicateGO.transform.position = pivot; m_DuplicateGO.transform.rotation = Quaternion.LookRotation(m_PlaneForward, m_Plane.normal); DrawBoundingBox(false); }