示例#1
0
        /// <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);
            }
        }
示例#2
0
        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();
        }
示例#3
0
        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();
        }
示例#5
0
        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);
                        }
                    }
                }
            }
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#9
0
        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);
        }
示例#10
0
        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();
                    }
                }
            }
        }
    }
示例#11
0
        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;
        }
示例#13
0
        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);
        }