private void HandleSelectedSegmentModifications()
        {
            if (selectedSegmentIndex < 0 || selectedSegmentIndex >= instance.Spline.Segments.Count)
            {
                return;
            }
            if (!instance.Spline.IsSegmentValid(selectedSegmentIndex))
            {
                return;
            }
            GSplineSegment segment           = instance.Spline.Segments[selectedSegmentIndex];
            GSplineAnchor  startAnchor       = instance.Spline.Anchors[segment.StartIndex];
            GSplineAnchor  endAnchor         = instance.Spline.Anchors[segment.EndIndex];
            Vector3        worldStartTangent = startAnchor.Position + segment.StartTangent;
            Vector3        worldEndTangent   = endAnchor.Position + segment.EndTangent;

            Handles.zTest     = UnityEngine.Rendering.CompareFunction.Always;
            worldStartTangent = Handles.PositionHandle(worldStartTangent, Quaternion.identity);
            worldEndTangent   = Handles.PositionHandle(worldEndTangent, Quaternion.identity);

            segment.StartTangent = worldStartTangent - startAnchor.Position;
            segment.EndTangent   = worldEndTangent - endAnchor.Position;

            Handles.color = Color.white;
            Handles.DrawLine(startAnchor.Position, worldStartTangent);
            Handles.DrawLine(endAnchor.Position, worldEndTangent);

            instance.transform.position = (startAnchor.Position + endAnchor.Position) * 0.5f;
        }
        private void HandleSelectedSegmentModifications()
        {
            if (selectedSegmentIndex < 0 || selectedSegmentIndex >= splineCreator.Spline.Segments.Count)
            {
                return;
            }
            if (!splineCreator.Spline.IsSegmentValid(selectedSegmentIndex))
            {
                return;
            }
            GSplineSegment segment     = splineCreator.Spline.Segments[selectedSegmentIndex];
            GSplineAnchor  startAnchor = splineCreator.Spline.Anchors[segment.StartIndex];
            GSplineAnchor  endAnchor   = splineCreator.Spline.Anchors[segment.EndIndex];

            Vector3 worldStartPosition = splineCreator.transform.TransformPoint(startAnchor.Position);
            Vector3 worldEndPosition   = splineCreator.transform.TransformPoint(endAnchor.Position);
            Vector3 worldStartTangent  = splineCreator.transform.TransformPoint(segment.StartTangent);
            Vector3 worldEndTangent    = splineCreator.transform.TransformPoint(segment.EndTangent);

            EditorGUI.BeginChangeCheck();
            Handles.zTest     = UnityEngine.Rendering.CompareFunction.Always;
            worldStartTangent = Handles.PositionHandle(worldStartTangent, Quaternion.identity);
            worldEndTangent   = Handles.PositionHandle(worldEndTangent, Quaternion.identity);

            segment.StartTangent = splineCreator.transform.InverseTransformPoint(worldStartTangent);
            segment.EndTangent   = splineCreator.transform.InverseTransformPoint(worldEndTangent);
            if (EditorGUI.EndChangeCheck())
            {
                GUI.changed = true;
            }

            Handles.color = Color.white;
            Handles.DrawLine(worldStartPosition, worldStartTangent);
            Handles.DrawLine(worldEndPosition, worldEndTangent);
        }
예제 #3
0
        public Vector3 EvaluateScale(int segmentIndex, float t)
        {
            GSplineSegment s           = Segments[segmentIndex];
            GSplineAnchor  startAnchor = Anchors[s.StartIndex];
            GSplineAnchor  endAnchor   = Anchors[s.EndIndex];

            return(Vector3.Lerp(startAnchor.Scale, endAnchor.Scale, t));
        }
예제 #4
0
        public Quaternion EvaluateRotation(int segmentIndex, float t)
        {
            GSplineSegment s           = Segments[segmentIndex];
            GSplineAnchor  startAnchor = Anchors[s.StartIndex];
            GSplineAnchor  endAnchor   = Anchors[s.EndIndex];

            return(Quaternion.Lerp(startAnchor.Rotation, endAnchor.Rotation, t));
        }
        private void DrawSelectedSegmentGUI()
        {
            string label = "Selected Segment";
            string id    = "selectedsegment" + instance.GetInstanceID().ToString();

            GEditorCommon.Foldout(label, true, id, () =>
            {
                if (selectedSegmentIndex >= 0 && selectedSegmentIndex < instance.Spline.Segments.Count)
                {
                    GSplineSegment s = instance.Spline.Segments[selectedSegmentIndex];
                    GSplineSegmentInspectorDrawer.Create(s).DrawGUI();
                }
                else
                {
                    EditorGUILayout.LabelField("No Segment selected!", GEditorCommon.ItalicLabel);
                }
            });
        }
예제 #6
0
        public bool IsSegmentValid(int segmentIndex)
        {
            GSplineSegment s = Segments[segmentIndex];

            if (s == null)
            {
                return(false);
            }
            bool startIndexValid =
                s.StartIndex >= 0 &&
                s.StartIndex < Anchors.Count &&
                Anchors[s.StartIndex] != null;
            bool endIndexValid =
                s.EndIndex >= 0 &&
                s.EndIndex < Anchors.Count &&
                Anchors[s.EndIndex] != null;

            return(startIndexValid && endIndexValid);
        }
예제 #7
0
        private bool CheckHasBranch()
        {
            int[] count = new int[Anchors.Count];
            for (int i = 0; i < Segments.Count; ++i)
            {
                if (!IsSegmentValid(i))
                {
                    continue;
                }
                GSplineSegment s = Segments[i];
                count[s.StartIndex] += 1;
                count[s.EndIndex]   += 1;
                if (count[s.StartIndex] > 2 || count[s.EndIndex] > 2)
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #8
0
        public Vector3 EvaluatePosition(int segmentIndex, float t)
        {
            GSplineSegment s           = Segments[segmentIndex];
            GSplineAnchor  startAnchor = Anchors[s.StartIndex];
            GSplineAnchor  endAnchor   = Anchors[s.EndIndex];

            Vector3 p0 = startAnchor.Position;
            Vector3 p1 = s.StartTangent;
            Vector3 p2 = s.EndTangent;
            Vector3 p3 = endAnchor.Position;

            t = Mathf.Clamp01(t);
            float   oneMinusT = 1 - t;
            Vector3 p         =
                oneMinusT * oneMinusT * oneMinusT * p0 +
                3 * oneMinusT * oneMinusT * t * p1 +
                3 * oneMinusT * t * t * p2 +
                t * t * t * p3;

            return(p);
        }
예제 #9
0
        private void DrawSelectedSegmentGUI()
        {
            string label = "Selected Segment";
            string id    = "selectedsegment" + instance.GetInstanceID().ToString();

            GEditorCommon.Foldout(label, true, id, () =>
            {
                selectedSegmentIndex = splineEditingDrawer.selectedSegmentIndex;
                if (selectedSegmentIndex >= 0 && selectedSegmentIndex < instance.Spline.Segments.Count)
                {
                    GSplineSegment s = instance.Spline.Segments[selectedSegmentIndex];
                    GUI.enabled      = !GEditorSettings.Instance.splineTools.autoTangent;
                    s.StartTangent   = GEditorCommon.InlineVector3Field("Start Tangent", s.StartTangent);
                    s.EndTangent     = GEditorCommon.InlineVector3Field("End Tangent", s.EndTangent);
                    GUI.enabled      = true;
                }
                else
                {
                    EditorGUILayout.LabelField("No Segment selected!", GEditorCommon.ItalicLabel);
                }
            });
        }
예제 #10
0
        public GSplineSegment AddSegment(int startIndex, int endIndex)
        {
            GSplineSegment s = Segments.Find(s0 =>
                                             (s0.StartIndex == startIndex && s0.EndIndex == endIndex) ||
                                             (s0.StartIndex == endIndex && s0.EndIndex == startIndex));

            if (s != null)
            {
                return(s);
            }
            GSplineSegment newSegment = new GSplineSegment();

            newSegment.StartIndex = startIndex;
            newSegment.EndIndex   = endIndex;
            Segments.Add(newSegment);
            GSplineAnchor startAnchor = Anchors[newSegment.StartIndex];
            GSplineAnchor endAnchor   = Anchors[newSegment.EndIndex];

            newSegment.StartTangent = (endAnchor.Position - startAnchor.Position) / 3f;
            newSegment.EndTangent   = -newSegment.StartTangent;
            return(newSegment);
        }
예제 #11
0
        public GSplineSegment AddSegment(int startIndex, int endIndex)
        {
            GSplineSegment s = Segments.Find(s0 =>
                                             (s0.StartIndex == startIndex && s0.EndIndex == endIndex) ||
                                             (s0.StartIndex == endIndex && s0.EndIndex == startIndex));

            if (s != null)
            {
                return(s);
            }
            GSplineSegment newSegment = new GSplineSegment();

            newSegment.StartIndex = startIndex;
            newSegment.EndIndex   = endIndex;
            Segments.Add(newSegment);
            GSplineAnchor startAnchor = Anchors[newSegment.StartIndex];
            GSplineAnchor endAnchor   = Anchors[newSegment.EndIndex];
            Vector3       direction   = (endAnchor.Position - startAnchor.Position).normalized;
            float         length      = (endAnchor.Position - startAnchor.Position).magnitude / 3;

            newSegment.StartTangent = startAnchor.Position + direction * length;
            newSegment.EndTangent   = endAnchor.Position - direction * length;
            return(newSegment);
        }
예제 #12
0
        public int[] SmoothTangents(params int[] anchorIndices)
        {
            int[]     anchorRanks    = new int[Anchors.Count];
            Vector3[] directions     = new Vector3[Anchors.Count];
            float[]   segmentLengths = new float[Segments.Count];

            for (int i = 0; i < Segments.Count; ++i)
            {
                GSplineSegment s = Segments[i];
                anchorRanks[s.StartIndex] += 1;
                anchorRanks[s.EndIndex]   += 1;

                GSplineAnchor aStart = Anchors[s.StartIndex];
                GSplineAnchor aEnd   = Anchors[s.EndIndex];

                Vector3 startToEnd = aEnd.Position - aStart.Position;
                Vector3 d          = Vector3.Normalize(startToEnd);
                directions[s.StartIndex] += d;
                directions[s.EndIndex]   += d;

                segmentLengths[i] = startToEnd.magnitude;
            }

            for (int i = 0; i < directions.Length; ++i)
            {
                if (anchorRanks[i] == 0)
                {
                    continue;
                }
                directions[i] = Vector3.Normalize(directions[i] / anchorRanks[i]);
            }

            if (anchorIndices == null || anchorIndices.Length == 0)
            {
                anchorIndices = GUtilities.GetIndicesArray(Anchors.Count);
            }

            for (int i = 0; i < anchorIndices.Length; ++i)
            {
                int index = anchorIndices[i];
                if (anchorRanks[index] > 0)
                {
                    Quaternion rot = Quaternion.LookRotation(directions[index], Vector3.up);
                    Anchors[index].Rotation = rot;
                }
            }

            List <int> segmentIndices = new List <int>();

            for (int i = 0; i < Segments.Count; ++i)
            {
                GSplineSegment s = Segments[i];
                for (int j = 0; j < anchorIndices.Length; ++j)
                {
                    int anchorIndex = anchorIndices[j];
                    if (s.StartIndex == anchorIndex || s.EndIndex == anchorIndex)
                    {
                        segmentIndices.Add(i);
                    }
                }
            }

            for (int i = 0; i < segmentIndices.Count; ++i)
            {
                int            index  = segmentIndices[i];
                GSplineSegment s      = Segments[index];
                GSplineAnchor  aStart = Anchors[s.StartIndex];
                GSplineAnchor  aEnd   = Anchors[s.EndIndex];

                float   sLength       = segmentLengths[index];
                float   tangentLength = sLength * 0.33f;
                Vector3 dirStart      = directions[s.StartIndex];
                Vector3 dirEnd        = directions[s.EndIndex];
                s.StartTangent = aStart.Position + dirStart * tangentLength;
                s.EndTangent   = aEnd.Position - dirEnd * tangentLength;
            }
            return(segmentIndices.ToArray());
        }
 public GSplineSegmentInspectorDrawer(GSplineSegment s)
 {
     instance = s;
 }
 public static GSplineSegmentInspectorDrawer Create(GSplineSegment s)
 {
     return(new GSplineSegmentInspectorDrawer(s));
 }
        public void AdjustTangent(int segmentIndex)
        {
            GSplineSegment s               = Spline.Segments[segmentIndex];
            int            startCount      = 0;
            Vector3        startAvgTangent = Vector3.zero;
            int            endCount        = 0;
            Vector3        endAvgTangent   = Vector3.zero;

            for (int i = 0; i < Spline.Segments.Count; ++i)
            {
                GSplineSegment s0 = Spline.Segments[i];
                if (s0 == s)
                {
                    continue;
                }
                if (s0.StartIndex == s.StartIndex)
                {
                    startAvgTangent += s0.StartTangent;
                    startCount      += 1;
                }
                if (s0.EndIndex == s.StartIndex)
                {
                    startAvgTangent += s0.EndTangent;
                    startCount      += 1;
                }
                if (s0.StartIndex == s.EndIndex)
                {
                    endAvgTangent += s0.StartTangent;
                    endCount      += 1;
                }
                if (s0.EndIndex == s.EndIndex)
                {
                    endAvgTangent += s0.EndTangent;
                    endCount      += 1;
                }
            }

            if (startAvgTangent == Vector3.zero)
            {
                startCount = 0;
            }
            if (endAvgTangent == Vector3.zero)
            {
                endCount = 0;
            }

            if (startCount == 0 && endCount == 0)
            {
                GSplineAnchor startAnchor = Spline.Anchors[s.StartIndex];
                GSplineAnchor endAnchor   = Spline.Anchors[s.EndIndex];
                s.StartTangent = (endAnchor.Position - startAnchor.Position) / 3f;
                s.EndTangent   = -s.StartTangent;
            }
            else if (startCount == 0 && endCount > 0)
            {
                s.EndTangent   = -endAvgTangent / endCount;
                s.StartTangent = s.EndTangent;
            }
            else if (startCount > 0 && endCount == 0)
            {
                s.StartTangent = -startAvgTangent / startCount;
                s.EndTangent   = s.StartTangent;
            }
            else
            {
                s.StartTangent = -startAvgTangent / startCount;
                s.EndTangent   = -endAvgTangent / endCount;
            }
        }