private void RotateTargets()
        {
            var   boundsQConfig  = GetBoundsQConfig();
            float rotationAmount = InputDeviceManager.Get.MouseDelta.x * SharedSettings.RotationSensitivity;

            EditorUndoEx.RecordObjectTransforms(_targetParents);
            foreach (var grabTarget in _grabTargets)
            {
                if (grabTarget == null)
                {
                    continue;
                }

                OOBB targetOOBB = ObjectBounds.CalcHierarchyWorldOOBB(grabTarget.GameObject, boundsQConfig);
                if (!targetOOBB.IsValid)
                {
                    continue;
                }

                var layerGrabSettings = SharedSettings.GetLayerGrabSettings(grabTarget.GameObject.layer);
                if (layerGrabSettings.IsActive)
                {
                    Quaternion rotation = Quaternion.AngleAxis(rotationAmount, layerGrabSettings.AlignAxis ? grabTarget.SittingPlane.normal : Vector3.up);
                    grabTarget.Transform.RotateAroundPivot(rotation, targetOOBB.Center);
                }
                else
                {
                    Quaternion rotation = Quaternion.AngleAxis(rotationAmount, SharedSettings.AlignAxis ? grabTarget.SittingPlane.normal : Vector3.up);
                    grabTarget.Transform.RotateAroundPivot(rotation, targetOOBB.Center);
                }
            }

            CalculateGrabTargetsAnchorVectors();
        }
        private void RotateTargetsAroundAnchor()
        {
            EditorUndoEx.RecordObjectTransforms(_targetParents);
            float rotationAmount = InputDeviceManager.Get.MouseDelta.x * SharedSettings.RotationSensitivity;

            foreach (var grabTarget in _grabTargets)
            {
                if (grabTarget == null)
                {
                    continue;
                }

                var layerGrabSettings = SharedSettings.GetLayerGrabSettings(grabTarget.GameObject.layer);
                if (layerGrabSettings.IsActive)
                {
                    if (layerGrabSettings.AlignAxis)
                    {
                        Quaternion rotation = Quaternion.AngleAxis(rotationAmount, _grabSurfaceInfo.AnchorNormal);
                        grabTarget.Transform.RotateAroundPivot(rotation, _grabSurfaceInfo.AnchorPoint);
                        grabTarget.AnchorVector = rotation * grabTarget.AnchorVector;
                    }
                    else
                    {
                        Quaternion rotation = Quaternion.AngleAxis(rotationAmount, Vector3.up);
                        grabTarget.Transform.RotateAroundPivot(rotation, _grabSurfaceInfo.AnchorPoint);
                        grabTarget.AnchorVector = rotation * grabTarget.AnchorVector;
                    }
                }
                else
                {
                    if (SharedSettings.AlignAxis)
                    {
                        Quaternion rotation = Quaternion.AngleAxis(rotationAmount, _grabSurfaceInfo.AnchorNormal);
                        grabTarget.Transform.RotateAroundPivot(rotation, _grabSurfaceInfo.AnchorPoint);
                        grabTarget.AnchorVector = rotation * grabTarget.AnchorVector;
                    }
                    else
                    {
                        Quaternion rotation = Quaternion.AngleAxis(rotationAmount, Vector3.up);
                        grabTarget.Transform.RotateAroundPivot(rotation, _grabSurfaceInfo.AnchorPoint);
                        grabTarget.AnchorVector = rotation * grabTarget.AnchorVector;
                    }
                }
            }

            SnapTargetsToSurface();
        }
        private void OffsetTargetsFromAnchor()
        {
            EditorUndoEx.RecordObjectTransforms(_targetParents);
            float scaleFactor = 1.0f + InputDeviceManager.Get.GetMouseCaptureDelta(_deltaCaptureId).x *SharedSettings.OffsetFromAnchorSensitivity;

            foreach (var grabTarget in _grabTargets)
            {
                if (grabTarget == null)
                {
                    continue;
                }
                grabTarget.Transform.position = (_grabSurfaceInfo.AnchorPoint + grabTarget.AnchorVectorSnapshot * scaleFactor);
            }

            CalculateGrabTargetsAnchorVectors();
            SnapTargetsToSurface();
        }
        private void ScaleTargets()
        {
            EditorUndoEx.RecordObjectTransforms(_targetParents);
            foreach (var grabTarget in _grabTargets)
            {
                if (grabTarget == null)
                {
                    continue;
                }

                //float maxAbsScaleComp = grabTarget.WorldScaleSnapshot.GetMaxAbsComp();
                //float scaleFactor = 1.0f + inputDevice.GetCaptureDelta(_inputDevScaleDeltaCaptureId).x * (Settings.ScaleDeviceSensitivity / maxAbsScaleComp);
                float scaleFactor = 1.0f + InputDeviceManager.Get.GetMouseCaptureDelta(_deltaCaptureId).x *SharedSettings.ScaleSensitivity;

                Vector3 newScale = grabTarget.WorldScaleSnapshot * scaleFactor;
                grabTarget.GameObject.SetHierarchyWorldScaleByPivot(newScale, grabTarget.SittingPoint + grabTarget.SittingPlane.normal * grabTarget.OffsetFromSurface);
            }

            CalculateGrabTargetsAnchorVectors();
            //SnapTargetsToSurface();
        }
예제 #5
0
        public void RenderEditorGUI(UnityEngine.Object undoRecordObject)
        {
            bool        newBool;
            const float toggleWidth = 65.0f;

            // Shortcut name label
            EditorGUILayout.BeginVertical("Box");
            EditorGUILayoutEx.SectionHeader(Name);

            // Enabled/disabled
            var content = new GUIContent();

            content.text    = "Is enabled";
            content.tooltip = "Allows you to enable/disable a shortcut key.";
            newBool         = EditorGUILayout.ToggleLeft(content, IsEnabled);
            if (newBool != IsEnabled)
            {
                EditorUndoEx.Record(undoRecordObject);
                IsEnabled = newBool;
            }

            // For each possible key, let the user specify its key code
            for (int keyIndex = 0; keyIndex < _maxNumberOfKeys; ++keyIndex)
            {
                int selectedIndex = _availableKeyNames.IndexOf(_keys[keyIndex].ToString());
                int newIndex      = EditorGUILayout.Popup("Key" + keyIndex.ToString(), selectedIndex, _availableKeyNames.ToArray());
                if (newIndex != selectedIndex)
                {
                    EditorUndoEx.Record(undoRecordObject);
                    _keys[keyIndex] = _availableKeys[newIndex];
                }
            }

            // Modifiers
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.BeginVertical("Box");
            newBool = EditorGUILayout.ToggleLeft("LCtrl", _lCtrl, GUILayout.Width(toggleWidth));
            if (newBool != _lCtrl)
            {
                EditorUndoEx.Record(undoRecordObject);
                _lCtrl = newBool;
            }
            EditorGUILayout.EndVertical();

            EditorGUILayout.BeginVertical("Box");
            newBool = EditorGUILayout.ToggleLeft("LCmd", _lCmd, GUILayout.Width(toggleWidth));
            if (newBool != _lCmd)
            {
                EditorUndoEx.Record(undoRecordObject);
                _lCmd = newBool;
            }
            EditorGUILayout.EndVertical();

            EditorGUILayout.BeginVertical("Box");
            newBool = EditorGUILayout.ToggleLeft("LAlt", _lAlt, GUILayout.Width(toggleWidth));
            if (newBool != _lAlt)
            {
                EditorUndoEx.Record(undoRecordObject);
                _lAlt = newBool;
            }
            EditorGUILayout.EndVertical();

            EditorGUILayout.BeginVertical("Box");
            newBool = EditorGUILayout.ToggleLeft("LShift", _lShift, GUILayout.Width(toggleWidth));
            if (newBool != _lShift)
            {
                EditorUndoEx.Record(undoRecordObject);
                _lShift = newBool;
            }
            EditorGUILayout.EndVertical();
            EditorGUILayout.EndHorizontal();
            EditorGUILayout.EndVertical();
        }
        private void SnapTargetsToSurface()
        {
            if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.Invalid)
            {
                return;
            }

            Surface.ObjectSnapConfig snapConfig = new Surface.ObjectSnapConfig();
            snapConfig.SurfaceHitPoint  = _grabSurfaceInfo.AnchorPoint;
            snapConfig.SurfaceHitNormal = _grabSurfaceInfo.AnchorNormal;
            snapConfig.SurfaceHitPlane  = _grabSurfaceInfo.AnchorPlane;
            snapConfig.SurfaceObject    = _grabSurfaceInfo.SceneRaycastHit.WasAnObjectHit ? _grabSurfaceInfo.SceneRaycastHit.ObjectHit.HitObject : null;

            snapConfig.SurfaceType = Surface.Type.UnityTerrain;
            if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.Mesh)
            {
                snapConfig.SurfaceType = Surface.Type.Mesh;
            }
            else if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.Grid)
            {
                snapConfig.SurfaceType = Surface.Type.SceneGrid;
            }
            else if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.SphericalMesh)
            {
                snapConfig.SurfaceType = Surface.Type.SphericalMesh;
            }
            else if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.TerrainMesh)
            {
                snapConfig.SurfaceType = Surface.Type.TerrainMesh;
            }

            EditorUndoEx.RecordObjectTransforms(_targetParents);
            foreach (var grabTarget in _grabTargets)
            {
                if (grabTarget.GameObject == null)
                {
                    continue;
                }
                grabTarget.Transform.position = _grabSurfaceInfo.AnchorPoint + grabTarget.AnchorVector;

                var layerGrabSettings = SharedSettings.GetLayerGrabSettings(grabTarget.GameObject.layer);
                if (layerGrabSettings.IsActive)
                {
                    snapConfig.AlignAxis         = layerGrabSettings.AlignAxis;
                    snapConfig.AlignmentAxis     = layerGrabSettings.AlignmentAxis;
                    snapConfig.OffsetFromSurface = layerGrabSettings.DefaultOffsetFromSurface + grabTarget.OffsetFromSurface;
                }
                else
                {
                    snapConfig.AlignAxis         = SharedSettings.AlignAxis;
                    snapConfig.AlignmentAxis     = SharedSettings.AlignmentAxis;
                    snapConfig.OffsetFromSurface = SharedSettings.DefaultOffsetFromSurface + grabTarget.OffsetFromSurface;
                }

                var snapResult = Surface.SnapHierarchy(grabTarget.GameObject, snapConfig);
                if (snapResult.WasSnapped)
                {
                    grabTarget.SittingPlane = snapResult.SittingPlane;
                    grabTarget.SittingPoint = snapResult.SittingPoint;
                }
            }
        }
예제 #7
0
        protected override void RenderContent(UnityEngine.Object undoRecordObject)
        {
            bool          newBool; float newFloat; int newInt;
            TransformAxis newTransformAxis;

            EditorGUILayoutEx.SectionHeader("Alignment");
            var content = new GUIContent();

            content.text    = "Align axis";
            content.tooltip = "If this is checked, the grabbed objects will have their local axes aligned with the grab surface normal.";
            newBool         = EditorGUILayout.ToggleLeft(content, AlignAxis);
            if (newBool != AlignAxis)
            {
                EditorUndoEx.Record(undoRecordObject);
                AlignAxis = newBool;
            }

            content.text     = "Alignment axis";
            content.tooltip  = "When axis alignment is turned on, this is the axis that will be aligned to the surface normal.";
            newTransformAxis = (TransformAxis)EditorGUILayout.EnumPopup(content, AlignmentAxis);
            if (newTransformAxis != AlignmentAxis)
            {
                EditorUndoEx.Record(undoRecordObject);
                AlignmentAxis = newTransformAxis;
            }

            EditorGUILayout.Separator();
            EditorGUILayoutEx.SectionHeader("Sensitivity");
            content.text    = "Rotation";
            content.tooltip = "Allows you to control how sensitive object rotation is to the input device.";
            newFloat        = EditorGUILayout.FloatField(content, RotationSensitivity);
            if (newFloat != RotationSensitivity)
            {
                EditorUndoEx.Record(undoRecordObject);
                RotationSensitivity = newFloat;
            }

            content.text    = "Scale";
            content.tooltip = "Allows you to control how sensitive object scaling is to the input device.";
            newFloat        = EditorGUILayout.FloatField(content, ScaleSensitivity);
            if (newFloat != ScaleSensitivity)
            {
                EditorUndoEx.Record(undoRecordObject);
                ScaleSensitivity = newFloat;
            }

            content.text    = "Offset from surface";
            content.tooltip = "Sensitivity value used when offseting objects from the surface on which they are sitting.";
            newFloat        = EditorGUILayout.FloatField(content, OffsetFromSurfaceSensitivity);
            if (newFloat != OffsetFromSurfaceSensitivity)
            {
                EditorUndoEx.Record(undoRecordObject);
                OffsetFromSurfaceSensitivity = newFloat;
            }

            content.text    = "Offset from anchor";
            content.tooltip = "Sensitivity value used when offseting objects from the anchor point.";
            newFloat        = EditorGUILayout.FloatField(content, OffsetFromAnchorSensitivity);
            if (newFloat != OffsetFromAnchorSensitivity)
            {
                EditorUndoEx.Record(undoRecordObject);
                OffsetFromAnchorSensitivity = newFloat;
            }

            EditorGUILayout.Separator();
            EditorGUILayoutEx.SectionHeader("Surface");
            content.text    = "Default offset";
            content.tooltip = "A default offset value which controls the distance between the objects and the surface they are sitting on. Negative values can be used to embed objects in the surface.";
            newFloat        = EditorGUILayout.FloatField(content, DefaultOffsetFromSurface);
            if (newFloat != DefaultOffsetFromSurface)
            {
                EditorUndoEx.Record(undoRecordObject);
                DefaultOffsetFromSurface = newFloat;
            }

            content.text    = "Surface flags";
            content.tooltip = "Allows you to specify the types of surfaces that can be used during a grab session.";
            newInt          = (int)((ObjectGrabSurfaceFlags)EditorGUILayout.EnumMaskPopup(content, (ObjectGrabSurfaceFlags)SurfaceFlags));
            if (newInt != (int)SurfaceFlags)
            {
                EditorUndoEx.Record(undoRecordObject);
                SurfaceFlags = (ObjectGrabSurfaceFlags)newInt;
            }

            content.text    = "Surface layers";
            content.tooltip = "Allows you to specify which layers can be used as snap surface during a grab session.";
            newInt          = EditorGUILayoutEx.LayerMaskField(content, SurfaceLayers);
            if (newInt != SurfaceLayers)
            {
                EditorUndoEx.Record(undoRecordObject);
                SurfaceLayers = newInt;
            }

            content.text    = "Spherical mesh layers";
            content.tooltip = "Objects that belong to these layers will be treated as spherical meshes (spheres). This allows the system to make " +
                              "certain assumptions about the surface geometry in order to produce the correct results.";
            newInt = EditorGUILayoutEx.LayerMaskField(content, SphericalMeshLayers);
            if (newInt != SphericalMeshLayers)
            {
                EditorUndoEx.Record(undoRecordObject);
                SphericalMeshLayers = newInt;
            }

            content.text    = "Terrain mesh layers";
            content.tooltip = "Objects that belong to these layers will be treated as terrain meshes (meshes that resemble a terrain but are NOT Unity Terrains). This allows the system to make " +
                              "certain assumptions about the surface geometry in order to produce the correct results.";
            newInt = EditorGUILayoutEx.LayerMaskField(content, TerrainMeshLayers);
            if (newInt != TerrainMeshLayers)
            {
                EditorUndoEx.Record(undoRecordObject);
                TerrainMeshLayers = newInt;
            }

            EditorGUILayout.Separator();
            EditorGUILayoutEx.SectionHeader("Per layer settings");
            EditorGUILayout.BeginHorizontal();
            content.text    = "Add";
            content.tooltip = "Adds grab settings which apply only to the chosen layer. Objects which belong to that layer will use these settings during a grab session.";
            if (GUILayout.Button(content, GUILayout.Width(70.0f)))
            {
                EditorUndoEx.Record(undoRecordObject);
                GetLayerGrabSettings(_newLayer).IsActive = true;
            }

            newInt = EditorGUILayout.LayerField(_newLayer);
            if (newInt != _newLayer)
            {
                EditorUndoEx.Record(undoRecordObject);
                _newLayer = newInt;
            }
            EditorGUILayout.EndHorizontal();

            foreach (var layerGrabSettings in _layerGrabSettings)
            {
                if (layerGrabSettings.IsActive)
                {
                    EditorGUILayout.BeginVertical("Box");
                    EditorGUILayout.HelpBox(LayerMask.LayerToName(layerGrabSettings.Layer), MessageType.None);

                    content.text    = "Align axis";
                    content.tooltip = "If this is checked, the grabbed objects that belong to this layer will have their local axes aligned with the grab surface normal.";
                    newBool         = EditorGUILayout.ToggleLeft(content, layerGrabSettings.AlignAxis);
                    if (newBool != layerGrabSettings.AlignAxis)
                    {
                        EditorUndoEx.Record(undoRecordObject);
                        layerGrabSettings.AlignAxis = newBool;
                    }

                    content.text     = "Alignment axis";
                    content.tooltip  = "When axis alignment is turned on, this is the axis that will be aligned to the surface normal.";
                    newTransformAxis = (TransformAxis)EditorGUILayout.EnumPopup(content, layerGrabSettings.AlignmentAxis);
                    if (newTransformAxis != layerGrabSettings.AlignmentAxis)
                    {
                        EditorUndoEx.Record(undoRecordObject);
                        layerGrabSettings.AlignmentAxis = newTransformAxis;
                    }

                    content.text    = "Default offset from surface";
                    content.tooltip = "A default offset value which controls the distance between the objects and the surface they are sitting on. Negative values can be used to embed objects in the surface.";
                    newFloat        = EditorGUILayout.FloatField(content, layerGrabSettings.DefaultOffsetFromSurface);
                    if (newFloat != layerGrabSettings.DefaultOffsetFromSurface)
                    {
                        EditorUndoEx.Record(undoRecordObject);
                        layerGrabSettings.DefaultOffsetFromSurface = newFloat;
                    }

                    content.text    = "Remove";
                    content.tooltip = "Removes the settings for this layer.";
                    if (GUILayout.Button(content, GUILayout.Width(70.0f)))
                    {
                        EditorUndoEx.Record(undoRecordObject);
                        layerGrabSettings.IsActive = false;
                    }
                    EditorGUILayout.EndVertical();
                }
            }
        }
예제 #8
0
        protected override void RenderContent(UnityEngine.Object undoRecordObject)
        {
            bool newBool; Color newColor; float newFloat;

            var content = new GUIContent();

            content.text    = "Show anchor lines";
            content.tooltip = "If this is checked, a line will be drawn between each object's position and the intersection point between the mouse cursor and the snap surface.";
            newBool         = EditorGUILayout.ToggleLeft(content, ShowAnchorLines);
            if (newBool != ShowAnchorLines)
            {
                EditorUndoEx.Record(undoRecordObject);
                ShowAnchorLines = newBool;
            }

            content.text    = "Show target boxes";
            content.tooltip = "If this is checked, a wire box will be rendered for all hierarchies that are involved in a surface snap session.";
            newBool         = EditorGUILayout.ToggleLeft(content, ShowTargetBoxes);
            if (newBool != ShowTargetBoxes)
            {
                EditorUndoEx.Record(undoRecordObject);
                ShowTargetBoxes = newBool;
            }

            content.text    = "Show anchor line ticks";
            content.tooltip = "If this is checked, ticks will be drawn at the beginning and end points of anchor lines.";
            newBool         = EditorGUILayout.ToggleLeft(content, ShowAnchorLineTicks);
            if (newBool != ShowAnchorLineTicks)
            {
                EditorUndoEx.Record(undoRecordObject);
                ShowAnchorLineTicks = newBool;
            }

            content.text    = "Anchor line color";
            content.tooltip = "Allows you to change the color of the anchor lines. These are the lines that are drawn from the " +
                              "object positions to the intersection point between the mouse cursor and the snap surface.";
            newColor = EditorGUILayout.ColorField(content, AnchorLineColor);
            if (newColor != AnchorLineColor)
            {
                EditorUndoEx.Record(undoRecordObject);
                AnchorLineColor = newColor;
            }

            content.text    = "Target wire box color";
            content.tooltip = "Allows you to change the wire color of target boxes. These are the boxes that are drawn for each hierarchy " +
                              "that is controlled by a snap session.";
            newColor = EditorGUILayout.ColorField(content, TargetWireBoxColor);
            if (newColor != TargetWireBoxColor)
            {
                EditorUndoEx.Record(undoRecordObject);
                TargetWireBoxColor = newColor;
            }

            content.text    = "Anchor line tick color";
            content.tooltip = "Allows you to change the color of the anchor line ticks.";
            newColor        = EditorGUILayout.ColorField(content, AnchorLineTickColor);
            if (newColor != AnchorLineTickColor)
            {
                EditorUndoEx.Record(undoRecordObject);
                AnchorLineTickColor = newColor;
            }

            content.text    = "Anchor line tick size";
            content.tooltip = "Allows you to change the size of the anchor line ticks.";
            newFloat        = EditorGUILayout.FloatField(content, AnchorLineTickSize);
            if (newFloat != AnchorLineTickSize)
            {
                EditorUndoEx.Record(undoRecordObject);
                AnchorLineTickSize = newFloat;
            }
        }