Esempio n. 1
0
        /// <summary>
        /// 求曲线上与给定点最近的点
        /// </summary>
        public float GetClosestLocation(Vector3 point, int segments)
        {
            Vector3 last = _f0;
            Vector3 current;
            float closest01;
            float sqrMagnitude;
            float bestSqrMagnitude = float.MaxValue;
            float bestT = 0f;

            for (int i = 1; i <= segments; i++)
            {
                current = GetPoint((float)i / segments);
                closest01 = MathKit.ClosestPointOnSegmentFactor(point, last, current);
                sqrMagnitude = (last + (current - last) * closest01 - point).sqrMagnitude;

                if (sqrMagnitude < bestSqrMagnitude)
                {
                    bestSqrMagnitude = sqrMagnitude;
                    bestT = (i - 1f + closest01) / segments;
                }

                last = current;
            }

            return bestT;
        }
Esempio n. 2
0
            protected override void OnMoveToolSceneGUI(T path)
            {
                if (_showTension)
                {
                    for (int i = 0; i < path.segmentCount; i++)
                    {
                        float tension = path.GetSegmentTension(i);

                        var point1 = path.GetNodePosition(i);
                        var point2 = path.GetNodePosition((i + 1) % path.nodeCount);
                        point1 = point1 * 0.75f + point2 * 0.25f;
                        point2 = point1 / 3f + point2 * (2f / 3f);

                        var point = (point2 - point1) * tension + point1;

                        Handles.color = new Color(1f, 1f, 1f, 0.5f);
                        HandlesKit.DrawAALine(point1, point2, 4);

                        float capSize = HandleUtility.GetHandleSize(point) * FloatingWindow.capSize;

                        using (var scope = new ChangeCheckScope(path))
                        {
                            Handles.color = capNormalColor;
                            point         = Handles.FreeMoveHandle(point, Quaternion.identity, capSize, snap, Handles.CircleHandleCap);

                            tension = MathKit.ClosestPointOnSegmentFactor(point, point1, point2);
                            //tension = (float)Math.Round(tension, 2);

                            //using (new HandlesGUIScope(0))
                            //{
                            //    var pos2D = HandleUtility.WorldToGUIPoint(point);
                            //    var rect = new Rect(pos2D.x + 12, pos2D.y - 9, 32, 18);
                            //    EditorGUI.DrawRect(rect, new Color(0, 0, 0, 0.5f));
                            //    using (new GUIContentColorScope(Color.white))
                            //    {
                            //        EditorGUI.LabelField(rect, tension.ToString(), EditorStyles.whiteLabel);
                            //    }
                            //}

                            if (scope.changed)
                            {
                                path.SetSegmentTension(i, tension);
                            }
                        }
                    }
                }

                int count = path.nodeCount;

                for (int i = 0; i < count; i++)
                {
                    var position = path.GetNodePosition(i);

                    float capSize = HandleUtility.GetHandleSize(position) * FloatingWindow.capSize;

                    if (selectedNode == i)
                    {
                        using (var scope = new ChangeCheckScope(path))
                        {
                            Handles.color = capSelectedColor;
                            if (selectedTool == 0)
                            {
                                position = Handles.FreeMoveHandle(position, Quaternion.identity, capSize * 2, snap, Handles.RectangleHandleCap);
                            }
                            else
                            {
                                position = Handles.PositionHandle(position, path.transform.rotation);
                            }
                            if (scope.changed)
                            {
                                path.SetNodePosition(i, position);
                            }
                        }
                    }
                    else
                    {
                        Handles.color = capNormalColor;
                        if (Handles.Button(position, Quaternion.identity, capSize, capSize, Handles.DotHandleCap))
                        {
                            selectedNode = i;
                        }
                    }
                }
            }