public static void DrawLength(UnityEngine.Vector3 from, UnityEngine.Vector3 to, float forceValue)
        {
            var prevColor = SceneHandles.color;

            SceneHandles.color = SceneHandles.StateColor(SceneHandles.measureColor);
            var invMatrix = SceneHandles.inverseMatrix;

            var camera   = UnityEngine.Camera.current;
            var camPos   = invMatrix.MultiplyPoint(camera.transform.position);
            var camDir   = (SceneHandleUtility.ProjectPointLine(camPos, from, to) - camPos).normalized;
            var delta    = (to - from);
            var length   = delta.magnitude;
            var forward  = delta / length;
            var right    = Vector3.Cross(forward, camDir);
            var fromSize = UnityEditor.HandleUtility.GetHandleSize(from);
            var toSize   = UnityEditor.HandleUtility.GetHandleSize(to);
            var center   = (to + from) * 0.5f;

            SceneHandles.DrawLine(from, to);
            DrawFlatArrow(from, forward, camDir, fromSize * 0.2f);
            DrawFlatArrow(to, -forward, camDir, toSize * 0.2f);
            //	SceneHandles.DrawLine(from - right, from + right);
            //	SceneHandles.DrawLine(to   - right, to   + right);

            DrawUnitLabel(center, right, 2, forceValue);
            SceneHandles.color = prevColor;
        }
Beispiel #2
0
        public static void RenderDistance(Matrix4x4 transformation, Vector3 from, Vector3 to)
        {
            var distance = from - to;

            if (distance.sqrMagnitude == 0)
            {
                return;
            }

            using (new SceneHandles.DrawingScope(transformation))
            {
                SceneHandles.DrawLine(from, to);
                SceneHandles.RenderBorderedDot(from, UnityEditor.HandleUtility.GetHandleSize(from) * HandleRendering.kPointScale);
                SceneHandles.RenderBorderedDot(to, UnityEditor.HandleUtility.GetHandleSize(to) * HandleRendering.kPointScale);
            }
        }
Beispiel #3
0
        public static bool Radius2DHandle(Vector3 center, Vector3 up, ref Vector3 radius1, ref Vector3 radius2, float minRadius1 = 0, float minRadius2 = 0, float maxRadius1 = float.PositiveInfinity, float maxRadius2 = float.PositiveInfinity, bool renderDisc = true)
        {
            var positionId0 = GUIUtility.GetControlID(s_Radius2DHash, FocusType.Keyboard);
            var positionId1 = GUIUtility.GetControlID(s_Radius2DHash, FocusType.Keyboard);
            var positionId2 = GUIUtility.GetControlID(s_Radius2DHash, FocusType.Keyboard);
            var positionId3 = GUIUtility.GetControlID(s_Radius2DHash, FocusType.Keyboard);

            minRadius1 = Mathf.Abs(minRadius1);
            minRadius2 = Mathf.Abs(minRadius2);
            maxRadius1 = Mathf.Abs(maxRadius1); if (maxRadius1 < minRadius1)
            {
                maxRadius1 = minRadius1;
            }
            maxRadius2 = Mathf.Abs(maxRadius2); if (maxRadius2 < minRadius2)
            {
                maxRadius2 = minRadius2;
            }

            var isStatic     = (!Tools.hidden && EditorApplication.isPlaying && GameObjectUtility.ContainsStatic(Selection.gameObjects));
            var prevColor    = SceneHandles.color;
            var prevMatrix   = SceneHandles.matrix;
            var prevDisabled = SceneHandles.disabled;
            var prevChanged  = GUI.changed;

            float   size;
            Vector3 forward;
            Vector3 right;

            GeometryUtility.CalculateTangents(up, out right, out forward);

            var plane = new Plane(up, Vector3.zero);

            var delta1 = GeometryUtility.ProjectPointPlane(radius1 - center, plane);
            var delta2 = GeometryUtility.ProjectPointPlane(radius2 - center, plane);

            var delta1Magnitude = delta1.magnitude;
            var delta2Magnitude = delta2.magnitude;

            var delta1Normalized = (delta1Magnitude < Vector3.kEpsilon) ? Vector3.zero : (delta1 / delta1Magnitude);
            var delta2Normalized = (delta2Magnitude < Vector3.kEpsilon) ? Vector3.zero : (delta2 / delta2Magnitude);

            // useful to have when modifying the 'other' one
            var rotatedDelta1 = Quaternion.AngleAxis(-90, up) * delta1Normalized;
            var rotatedDelta2 = Quaternion.AngleAxis(90, up) * delta2Normalized;


            var position0 = center + delta1;
            var position1 = center - delta1;
            var position2 = center + delta2;
            var position3 = center - delta2;

            var isDisabled = isStatic || prevDisabled;

            SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false);

            bool noRotation = Event.current.shift;

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position0);
            position0   = Slider2DHandle(positionId0, position0, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                var     moveDelta = (position0 - center);
                Vector3 newRadius;
                if (noRotation)
                {
                    newRadius = GeometryUtility.ProjectPointRay(center + moveDelta, center, rotatedDelta2);
                }
                else
                {
                    newRadius = center + moveDelta;
                }

                var newDelta = GeometryUtility.ProjectPointPlane(newRadius - center, plane);
                delta1Magnitude = newDelta.magnitude;

                if (!noRotation && delta1Magnitude > Vector3.kEpsilon)
                {
                    radius2 = center + ((Quaternion.AngleAxis(-90, up) * (newDelta / delta1Magnitude)) * delta2Magnitude);
                }

                // set this after setting radius2 since both may lead to same variable
                delta1      = newDelta;
                radius1     = newRadius;
                prevChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position1);
            position1   = Slider2DHandle(positionId1, position1, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                var     moveDelta = (position1 - center);
                Vector3 newRadius;
                if (noRotation)
                {
                    newRadius = GeometryUtility.ProjectPointRay(center - moveDelta, center, rotatedDelta2);
                }
                else
                {
                    newRadius = center - moveDelta;
                }

                var newDelta = GeometryUtility.ProjectPointPlane(newRadius - center, plane);
                delta1Magnitude = newDelta.magnitude;

                if (!noRotation && delta1Magnitude > Vector3.kEpsilon)
                {
                    radius2 = center + ((Quaternion.AngleAxis(-90, up) * (newDelta / delta1Magnitude)) * delta2Magnitude);
                }

                // set this after setting radius2 since both may lead to same variable
                delta1      = newDelta;
                radius1     = newRadius;
                prevChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position2);
            position2   = Slider2DHandle(positionId2, position2, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                var     moveDelta = (position2 - center);
                Vector3 newRadius;
                if (noRotation)
                {
                    newRadius = GeometryUtility.ProjectPointRay(center + moveDelta, center, rotatedDelta1);
                }
                else
                {
                    newRadius = center + moveDelta;
                }

                var newDelta = GeometryUtility.ProjectPointPlane(newRadius - center, plane);
                delta2Magnitude = newDelta.magnitude;

                if (!noRotation && delta2Magnitude > Vector3.kEpsilon)
                {
                    radius1 = center + ((Quaternion.AngleAxis(90, up) * (newDelta / delta2Magnitude)) * delta1Magnitude);
                }

                // set this after setting radius1 since both may lead to same variable
                delta2      = newDelta;
                radius2     = newRadius;
                prevChanged = true;
            }

            GUI.changed = false;
            size        = UnityEditor.HandleUtility.GetHandleSize(position3);
            position3   = Slider2DHandle(positionId3, position3, Vector3.zero, up, forward, right, size * 0.05f, OutlinedDotHandleCap);
            if (GUI.changed)
            {
                var     moveDelta = (position3 - center);
                Vector3 newRadius;
                if (noRotation)
                {
                    newRadius = GeometryUtility.ProjectPointRay(center - moveDelta, center, rotatedDelta1);
                }
                else
                {
                    newRadius = center - moveDelta;
                }

                var newDelta = GeometryUtility.ProjectPointPlane(newRadius - center, plane);
                delta2Magnitude = newDelta.magnitude;

                if (!noRotation && delta2Magnitude > Vector3.kEpsilon)
                {
                    radius1 = center + ((Quaternion.AngleAxis(90, up) * (newDelta / delta2Magnitude)) * delta1Magnitude);
                }

                // set this after setting radius1 since both may lead to same variable
                delta2      = newDelta;
                radius2     = newRadius;
                prevChanged = true;
            }

            GUI.changed |= prevChanged;

            if (delta1Magnitude < minRadius1 || delta1Magnitude > maxRadius1)
            {
                if (delta2Magnitude < minRadius2 || delta2Magnitude > maxRadius2)
                {
                    delta1Magnitude = Mathf.Max(minRadius1, Mathf.Min(delta1Magnitude, maxRadius1));
                    delta2Magnitude = Mathf.Max(minRadius2, Mathf.Min(delta2Magnitude, maxRadius2));

                    delta1Normalized = right;
                    delta2Normalized = up;

                    delta1 = GeometryUtility.ProjectPointPlane(delta1Normalized * delta1Magnitude, plane);
                    delta2 = GeometryUtility.ProjectPointPlane(delta2Normalized * delta2Magnitude, plane);

                    rotatedDelta2 = delta2Normalized;
                    rotatedDelta1 = delta1Normalized;

                    radius1     = center + delta1;
                    radius2     = center + delta2;
                    GUI.changed = true;
                }
                else
                {
                    delta1Magnitude  = Mathf.Max(minRadius1, Mathf.Min(delta1Magnitude, maxRadius1));
                    delta1Normalized = rotatedDelta2;
                    delta1           = GeometryUtility.ProjectPointPlane(delta1Normalized * delta1Magnitude, plane);
                    radius1          = center + delta1;
                    GUI.changed      = true;
                }
            }
            else
            if (delta2Magnitude < minRadius2 || delta2Magnitude > maxRadius2)
            {
                delta2Magnitude  = Mathf.Max(minRadius2, Mathf.Min(delta2Magnitude, maxRadius2));
                delta2Normalized = rotatedDelta1;
                delta2           = delta2Normalized * delta2Magnitude;
                radius2          = center + delta2;
                GUI.changed      = true;
            }


            if (Event.current.type == EventType.Repaint)
            {
                isDisabled         = isStatic || prevDisabled || (Snapping.AxisLocking[0] && Snapping.AxisLocking[1]);
                SceneHandles.color = SceneHandles.StateColor(prevColor, isDisabled, false);


                if (delta1Magnitude > Vector3.kEpsilon && delta2Magnitude > Vector3.kEpsilon)
                {
                    var ellipsis = Matrix4x4.TRS(center, Quaternion.identity, Vector3.one);

                    ellipsis.m00 = delta1.x;
                    ellipsis.m10 = delta1.y;
                    ellipsis.m20 = delta1.z;

                    ellipsis.m01 = delta2.x;
                    ellipsis.m11 = delta2.y;
                    ellipsis.m21 = delta2.z;

                    ellipsis.m02 = up.x;
                    ellipsis.m12 = up.y;
                    ellipsis.m22 = up.z;

                    ellipsis *= Matrix4x4.TRS(-center, Quaternion.identity, Vector3.one);

                    var newMatrix = prevMatrix * ellipsis;

                    SceneHandles.matrix = newMatrix;
                    if (renderDisc)
                    {
                        SceneHandles.DrawWireDisc(center, Vector3.forward, 1.0f);
                    }
                }
                else
                if (delta1Magnitude > Vector3.kEpsilon)
                {
                    SceneHandles.DrawLine(position0, position1);
                }
                else
                if (delta2Magnitude > Vector3.kEpsilon)
                {
                    SceneHandles.DrawLine(position2, position3);
                }
            }

            SceneHandles.disabled = prevDisabled;
            SceneHandles.matrix   = prevMatrix;
            SceneHandles.color    = prevColor;

            var focus = SceneHandleUtility.focusControl;

            return((focus == positionId0) ||
                   (focus == positionId1) ||
                   (focus == positionId2) ||
                   (focus == positionId3));
        }
        public static void DrawLengths(Bounds bounds, Axes activeAxes = Axes.XYZ, Axes visibleAxes = Axes.XYZ, Axes selectedAxes = Axes.None)
        {
            // TODO: what if camera is inside of bounds?
            // TODO: what if length is outside of camera, but other option is inside of camera view?
            // TODO: don't make the side lines move around when resizing, be smarter about handlesize
            //			-> maybe limit the projected line to the screen?

            var invMatrix = SceneHandles.inverseMatrix;
            var prevColor = SceneHandles.color;
            var color     = prevColor;
            var color2    = color;

            color2.a *= 0.5f;

            var camera = UnityEngine.Camera.current;
            var camPos = invMatrix.MultiplyPoint(camera.transform.position);

            var lengthX = bounds.size.x;
            var lengthY = bounds.size.y;
            var lengthZ = bounds.size.z;

            var absLengthX = Mathf.Abs(lengthX);
            var absLengthY = Mathf.Abs(lengthY);
            var absLengthZ = Mathf.Abs(lengthZ);

            var delta = (bounds.center - camPos) * 2;
            var dotX  = delta.x < 0 ? -1 : 1;
            var dotY  = delta.y < 0 ? -1 : 1;
            var dotZ  = delta.z < 0 ? -1 : 1;

            var insideX = (delta.x >= -absLengthX && delta.x <= absLengthX);
            var insideY = (delta.y >= -absLengthY && delta.y <= absLengthY);
            var insideZ = (delta.z >= -absLengthZ && delta.z <= absLengthZ);

            bool showX = !(insideY && insideZ);
            bool showY = !(insideX && insideZ);
            bool showZ = !(insideX && insideY);


            Vector3 fromX, toX;
            Vector3 fromY, toY;
            Vector3 fromZ, toZ;

            var min = bounds.min;
            var max = bounds.max;

            // min/max of bounds can potentially be inverted
            min.x = Mathf.Min(min.x, max.x);
            min.y = Mathf.Min(min.y, max.y);
            min.z = Mathf.Min(min.z, max.z);

            fromX = min; toX = fromX + new Vector3(absLengthX, 0, 0);
            fromY = min; toY = fromY + new Vector3(0, absLengthY, 0);
            fromZ = min; toZ = fromZ + new Vector3(0, 0, absLengthZ);

            var signZ = Vector3.one;

            if (showZ)
            {
                bool swapX = (dotX > 0) ^ insideY;
                bool swapY = (dotY < 0) ^ insideY;

                signZ.x = swapX ? 1 : -1; signZ.y = swapY ? 1 : -1;
                var ofsX = swapX ? absLengthX : 0; fromZ.x += ofsX; toZ.x += ofsX;
                var ofsY = swapY ? absLengthY : 0; fromZ.y += ofsY; toZ.y += ofsY;
            }

            var signY = Vector3.one;

            if (showY)
            {
                bool swapX = (dotX > 0) ^ insideZ;
                bool swapZ = (dotZ < 0);

                signY.x = swapX ? 1 : -1; signY.z = swapZ ? 1 : -1;
                var ofsX = swapX ? absLengthX : 0; fromY.x += ofsX; toY.x += ofsX;
                var ofsZ = swapZ ? absLengthZ : 0; fromY.z += ofsZ; toY.z += ofsZ;
            }

            var signX = Vector3.one;

            if (showX)
            {
                bool swapY = (dotY > 0) ^ insideZ;
                bool swapZ = (dotZ < 0);

                signX.y = swapY ? 1 : -1; signX.z = swapZ ? 1 : -1;
                var ofsY = swapY ? absLengthY : 0; fromX.y += ofsY; toX.y += ofsY;
                var ofsZ = swapZ ? absLengthZ : 0; fromX.z += ofsZ; toX.z += ofsZ;
            }

            var lineHandleX = SceneHandleUtility.ProjectPointLine(camPos, fromX, toX);
            var lineHandleY = SceneHandleUtility.ProjectPointLine(camPos, fromY, toY);
            var lineHandleZ = SceneHandleUtility.ProjectPointLine(camPos, fromZ, toZ);
            var lineOfsX    = (UnityEditor.HandleUtility.GetHandleSize(lineHandleX) * 0.25f);
            var lineOfsY    = (UnityEditor.HandleUtility.GetHandleSize(lineHandleY) * 0.25f);
            var lineOfsZ    = (UnityEditor.HandleUtility.GetHandleSize(lineHandleZ) * 0.25f);

            var angleX     = lineHandleX - camPos;
            var angleY     = lineHandleY - camPos;
            var angleZ     = lineHandleZ - camPos;
            var directionX = Mathf.Abs(angleX.y) <= Mathf.Abs(angleX.z);
            var directionY = Mathf.Abs(angleY.x) <= Mathf.Abs(angleY.z);
            var directionZ = Mathf.Abs(angleZ.y) <= Mathf.Abs(angleZ.x);

            var disabled = SceneHandles.disabled;

            const int labelPadding = 2;

            if (showX && ((visibleAxes & Axes.X) == Axes.X))
            {
                var axisDisabled = ((activeAxes & Axes.X) != Axes.X) || disabled;
                var selected     = ((selectedAxes & Axes.X) == Axes.X) && !axisDisabled;

                var offsetY = new Vector3(0, (lineOfsY * signX.y), 0);
                var offsetZ = new Vector3(0, 0, (lineOfsZ * signX.z));

                var offset  = directionX ? offsetY : offsetZ;
                var fromOfs = fromX + offset;
                var toOfs   = toX + offset;

                var camDir   = SceneHandleUtility.ProjectPointLine(camPos, fromOfs, toOfs) - camPos;
                var fromSize = Mathf.Min(absLengthX / 3.0f, UnityEditor.HandleUtility.GetHandleSize(fromOfs) * 0.2f);
                var toSize   = Mathf.Min(absLengthX / 3.0f, UnityEditor.HandleUtility.GetHandleSize(toOfs) * 0.2f);
                var center   = (toOfs + fromOfs) * 0.5f;

                SceneHandles.color = SceneHandles.StateColor(color2, axisDisabled, selected);
                SceneHandles.DrawLine(fromX, fromOfs);
                SceneHandles.DrawLine(toX, toOfs);

                SceneHandles.color = SceneHandles.StateColor(color, axisDisabled, selected);
                SceneHandles.DrawLine(fromOfs, toOfs);
                DrawFlatArrow(fromOfs, Vector3.right, camDir, fromSize);
                DrawFlatArrow(toOfs, -Vector3.right, camDir, toSize);
                DrawUnitLabel(center, offset, labelPadding, lengthX, "X");
            }

            if (showY && ((visibleAxes & Axes.Y) == Axes.Y))
            {
                var axisDisabled = ((activeAxes & Axes.Y) != Axes.Y) || disabled;
                var selected     = ((selectedAxes & Axes.Y) == Axes.Y) && !axisDisabled;

                var offsetX = new Vector3((lineOfsX * signY.x), 0, 0);
                var offsetZ = new Vector3(0, 0, (lineOfsZ * signY.z));

                var offset  = directionY ? offsetX : offsetZ;
                var fromOfs = fromY + offset;
                var toOfs   = toY + offset;

                var camDir   = SceneHandleUtility.ProjectPointLine(camPos, fromOfs, toOfs) - camPos;
                var fromSize = Mathf.Min(absLengthY / 3.0f, UnityEditor.HandleUtility.GetHandleSize(fromOfs) * 0.2f);
                var toSize   = Mathf.Min(absLengthY / 3.0f, UnityEditor.HandleUtility.GetHandleSize(toOfs) * 0.2f);
                var center   = (toOfs + fromOfs) * 0.5f;

                SceneHandles.color = SceneHandles.StateColor(color2, axisDisabled, selected);
                SceneHandles.DrawLine(fromY, fromOfs);
                SceneHandles.DrawLine(toY, toOfs);

                SceneHandles.color = SceneHandles.StateColor(color, axisDisabled, selected);
                SceneHandles.DrawLine(fromOfs, toOfs);
                DrawFlatArrow(fromOfs, Vector3.up, camDir, fromSize);
                DrawFlatArrow(toOfs, -Vector3.up, camDir, toSize);
                DrawUnitLabel(center, offset, labelPadding, lengthY, "Y");
            }

            if (showZ && ((visibleAxes & Axes.Z) == Axes.Z))
            {
                var axisDisabled = ((activeAxes & Axes.Z) != Axes.Z) || disabled;
                var selected     = ((selectedAxes & Axes.Z) == Axes.Z) && !axisDisabled;

                var offsetX = new Vector3((lineOfsX * signZ.x), 0, 0);
                var offsetY = new Vector3(0, (lineOfsY * signZ.y), 0);

                var offset  = directionZ ? offsetY : offsetX;
                var fromOfs = fromZ + offset;
                var toOfs   = toZ + offset;

                var camDir   = SceneHandleUtility.ProjectPointLine(camPos, fromOfs, toOfs) - camPos;
                var fromSize = Mathf.Min(absLengthZ / 3.0f, UnityEditor.HandleUtility.GetHandleSize(fromOfs) * 0.2f);
                var toSize   = Mathf.Min(absLengthZ / 3.0f, UnityEditor.HandleUtility.GetHandleSize(toOfs) * 0.2f);
                var center   = (toOfs + fromOfs) * 0.5f;

                SceneHandles.color = SceneHandles.StateColor(color2, axisDisabled, selected);
                SceneHandles.DrawLine(fromZ, fromOfs);
                SceneHandles.DrawLine(toZ, toOfs);

                SceneHandles.color = SceneHandles.StateColor(color, axisDisabled, selected);
                SceneHandles.DrawLine(fromOfs, toOfs);
                DrawFlatArrow(fromOfs, Vector3.forward, camDir, fromSize);
                DrawFlatArrow(toOfs, -Vector3.forward, camDir, toSize);
                DrawUnitLabel(center, offset, labelPadding, lengthZ, "Z");
            }
            SceneHandles.color = prevColor;
        }