예제 #1
0
        /// <summary>
        /// Construct & display the curve from DragPointsHandler control points
        /// Find the curve traveller position along the curve
        /// </summary>
        ///
        /// <remarks>
        /// Will use the DragPointExposure from the handler's item to display slingshot segments accordingly
        /// Will update handler's curve traveller position and control point base index for point insertion
        /// </remarks>
        private void DisplayCurve()
        {
            List <Vector3>[] controlPointsSegments = new List <Vector3> [_handler.ControlPoints.Count].Select(item => new List <Vector3>()).ToArray();

            // Display Curve & handle curve traveller
            if (_handler.ControlPoints.Count > 1)
            {
                var transformedDPoints = new List <DragPointData>();
                foreach (var controlPoint in _handler.ControlPoints)
                {
                    var newDp = new DragPointData(controlPoint.DragPoint)
                    {
                        Vertex = controlPoint.WorldPos.ToVertex3D()
                    };
                    transformedDPoints.Add(newDp);
                }

                var vAccuracy = Vector3.one;
                vAccuracy = _handler.Transform.localToWorldMatrix.MultiplyVector(vAccuracy);
                var accuracy = Mathf.Abs(vAccuracy.x * vAccuracy.y * vAccuracy.z);
                accuracy *= HandleUtility.GetHandleSize(_handler.CurveTravellerPosition) * ControlPoint.ScreenRadius;
                var vVertex = Engine.Math.DragPoint.GetRgVertex <RenderVertex3D, CatmullCurve3DCatmullCurveFactory>(
                    transformedDPoints.ToArray(), _handler.DragPointEditable.PointsAreLooping(), accuracy
                    );

                if (vVertex.Length > 0)
                {
                    // Fill Control points paths
                    ControlPoint currentControlPoint = null;
                    foreach (var v in vVertex)
                    {
                        if (v.IsControlPoint)
                        {
                            if (currentControlPoint != null)
                            {
                                controlPointsSegments[currentControlPoint.Index].Add(v.ToUnityVector3());
                            }
                            currentControlPoint = _handler.ControlPoints.Find(cp => cp.WorldPos == v.ToUnityVector3());
                        }
                        if (currentControlPoint != null)
                        {
                            controlPointsSegments[currentControlPoint.Index].Add(v.ToUnityVector3());
                        }
                    }

                    // close loop if needed
                    if (_handler.DragPointEditable.PointsAreLooping())
                    {
                        controlPointsSegments[_handler.ControlPoints.Count - 1].Add(controlPointsSegments[0][0]);
                    }

                    // construct full path
                    _pathPoints.Clear();
                    const float splitRatio = 0.05f;
                    foreach (var controlPoint in _handler.ControlPoints)
                    {
                        // Split straight segments to avoid HandleUtility.ClosestPointToPolyLine issues
                        var segments = controlPointsSegments[controlPoint.Index];
                        if (!controlPoint.DragPoint.IsSmooth && segments.Count == 2)
                        {
                            var dir  = segments[1] - segments[0];
                            var dist = dir.magnitude;
                            dir = Vector3.Normalize(dir);
                            var newPath = new List <Vector3> {
                                segments[0]
                            };
                            for (var splitDist = dist * splitRatio; splitDist < dist; splitDist += dist * splitRatio)
                            {
                                newPath.Add(newPath[0] + dir * splitDist);
                            }
                            newPath.Add(segments[1]);
                            segments = newPath;
                        }
                        _pathPoints.AddRange(segments);
                    }

                    _handler.CurveTravellerPosition = HandleUtility.ClosestPointToPolyLine(_pathPoints.ToArray());

                    // Render Curve with correct color regarding drag point properties & find curve section where the curve traveller is
                    _handler.CurveTravellerControlPointIdx = -1;
                    foreach (var controlPoint in _handler.ControlPoints)
                    {
                        var segments = controlPointsSegments[controlPoint.Index].ToArray();
                        if (segments.Length > 1)
                        {
                            Handles.color = _handler.DragPointEditable.GetDragPointExposition().Contains(DragPointExposure.SlingShot) && controlPoint.DragPoint.IsSlingshot ? CurveSlingShotColor : CurveColor;
                            Handles.DrawAAPolyLine(CurveWidth, segments);
                            var closestToPath = HandleUtility.ClosestPointToPolyLine(segments);
                            if (_handler.CurveTravellerControlPointIdx == -1 && closestToPath == _handler.CurveTravellerPosition)
                            {
                                _handler.CurveTravellerControlPointIdx = controlPoint.Index;
                            }
                        }
                    }
                }
            }
        }