Exemplo n.º 1
0
        void DrawVertexPathSceneEditor()
        {
            Color bezierCol = GlobalDisplaySettings.BezierPath;

            bezierCol.a *= .5f;

            if (Data.showBezierPathInVertexMode)
            {
                for (int i = 0; i < BezierPath.NumSegments; i++)
                {
                    Vector3[] points = BezierPath.GetPointsInSegment(i);
                    for (int j = 0; j < points.Length; j++)
                    {
                        points[j] = MathUtility.TransformPoint(points[j], creator.transform, BezierPath.Space);
                    }

                    Handles.DrawBezier(points[0], points[3], points[1], points[2], bezierCol, null, 2);
                }
            }

            Handles.color = GlobalDisplaySettings.vertexPath;

            for (int i = 0; i < creator.VertexPath.NumPoints; i++)
            {
                int nextIndex = (i + 1) % creator.VertexPath.NumPoints;
                if (nextIndex != 0 || BezierPath.IsClosed)
                {
                    Handles.DrawLine(creator.VertexPath.GetPoint(i), creator.VertexPath.GetPoint(nextIndex));
                }
            }

            if (Data.showNormalsInVertexMode)
            {
                Handles.color = GlobalDisplaySettings.normals;
                Vector3[] normalLines = new Vector3[creator.VertexPath.NumPoints * 2];
                for (int i = 0; i < creator.VertexPath.NumPoints; i++)
                {
                    normalLines[i * 2]     = creator.VertexPath.GetPoint(i);
                    normalLines[i * 2 + 1] = creator.VertexPath.GetPoint(i) + creator.VertexPath.localNormals[i] * GlobalDisplaySettings.normalsLength;
                }
                Handles.DrawLines(normalLines);
            }
        }
Exemplo n.º 2
0
        void DrawBezierPathSceneEditor()
        {
            bool   displayControlPoints = Data.displayControlPoints && (BezierPath.ControlPointMode != BezierPath.ControlMode.Automatic || !GlobalDisplaySettings.hideAutoControls);
            Bounds bounds = BezierPath.CalculateBoundsWithTransform(creator.transform);

            if (Event.current.type == EventType.Repaint)
            {
                for (int i = 0; i < BezierPath.NumSegments; i++)
                {
                    Vector3[] points = BezierPath.GetPointsInSegment(i);
                    for (int j = 0; j < points.Length; j++)
                    {
                        points[j] = MathUtility.TransformPoint(points[j], creator.transform, BezierPath.Space);
                    }

                    if (Data.showPerSegmentBounds)
                    {
                        Bounds segmentBounds = PathUtility.CalculateSegmentBounds(points[0], points[1], points[2], points[3]);
                        Handles.color = GlobalDisplaySettings.segmentBounds;
                        Handles.DrawWireCube(segmentBounds.center, segmentBounds.size);
                    }

                    // Draw lines between control points
                    if (displayControlPoints)
                    {
                        Handles.color = (BezierPath.ControlPointMode == BezierPath.ControlMode.Automatic) ? GlobalDisplaySettings.handleDisabled : GlobalDisplaySettings.controlLine;
                        Handles.DrawLine(points[1], points[0]);
                        Handles.DrawLine(points[2], points[3]);
                    }

                    // Draw VertexPath
                    bool  highlightSegment = (i == selectedSegmentIndex && Event.current.shift && draggingHandleIndex == -1 && mouseOverHandleIndex == -1);
                    Color segmentCol       = (highlightSegment) ? GlobalDisplaySettings.highlightedPath : GlobalDisplaySettings.BezierPath;
                    Handles.DrawBezier(points[0], points[3], points[1], points[2], segmentCol, null, 2);
                }

                if (Data.showPathBounds)
                {
                    Handles.color = GlobalDisplaySettings.bounds;
                    Handles.DrawWireCube(bounds.center, bounds.size);
                }

                // Draw normals
                if (Data.showNormals)
                {
                    if (!hasUpdatedNormalsVertexPath)
                    {
                        normalsVertexPath           = new VertexPath(BezierPath, creator.transform, normalsSpacing);
                        hasUpdatedNormalsVertexPath = true;
                    }

                    if (editingNormalsOld != Data.showNormals)
                    {
                        editingNormalsOld = Data.showNormals;
                        Repaint();
                    }

                    Vector3[] normalLines = new Vector3[normalsVertexPath.NumPoints * 2];
                    Handles.color = GlobalDisplaySettings.normals;
                    for (int i = 0; i < normalsVertexPath.NumPoints; i++)
                    {
                        normalLines[i * 2]     = normalsVertexPath.GetPoint(i);
                        normalLines[i * 2 + 1] = normalsVertexPath.GetPoint(i) + normalsVertexPath.GetNormal(i) * GlobalDisplaySettings.normalsLength;
                    }
                    Handles.DrawLines(normalLines);
                }
            }

            if (Data.displayAnchorPoints)
            {
                for (int i = 0; i < BezierPath.NumPoints; i += 3)
                {
                    DrawHandle(i);
                }
            }
            if (displayControlPoints)
            {
                for (int i = 1; i < BezierPath.NumPoints - 1; i += 3)
                {
                    DrawHandle(i);
                    DrawHandle(i + 1);
                }
            }
        }
Exemplo n.º 3
0
        public ScreenSpacePolyLine(BezierPath BezierPath, Transform transform, float maxAngleError, float minVertexDst, float accuracy = 1)
        {
            this.transform    = transform;
            transformPosition = transform.position;
            transformRotation = transform.rotation;
            transformScale    = transform.localScale;

            // Split path in vertices based on angle error
            verticesWorld          = new List <Vector3>();
            vertexToPathSegmentMap = new List <int>();
            segmentStartIndices    = new int[BezierPath.NumSegments + 1];

            verticesWorld.Add(BezierPath[0]);
            vertexToPathSegmentMap.Add(0);
            Vector3 prevPointOnPath          = BezierPath[0];
            float   dstSinceLastVertex       = 0;
            Vector3 lastAddedPoint           = prevPointOnPath;
            float   dstSinceLastIntermediary = 0;

            for (int segmentIndex = 0; segmentIndex < BezierPath.NumSegments; segmentIndex++)
            {
                Vector3[] segmentPoints = BezierPath.GetPointsInSegment(segmentIndex);
                verticesWorld.Add(segmentPoints[0]);
                vertexToPathSegmentMap.Add(segmentIndex);
                segmentStartIndices[segmentIndex] = verticesWorld.Count - 1;

                prevPointOnPath          = segmentPoints[0];
                lastAddedPoint           = prevPointOnPath;
                dstSinceLastVertex       = 0;
                dstSinceLastIntermediary = 0;

                float estimatedSegmentLength = MathUtility.EstimateCurveLength(segmentPoints[0], segmentPoints[1], segmentPoints[2], segmentPoints[3]);
                int   divisions = Mathf.CeilToInt(estimatedSegmentLength * accuracy * accuracyMultiplier);
                float increment = 1f / divisions;

                for (float t = increment; t <= 1; t += increment)
                {
                    Vector3 pointOnPath     = MathUtility.CubicBezier(segmentPoints[0], segmentPoints[1], segmentPoints[2], segmentPoints[3], t);
                    Vector3 nextPointOnPath = MathUtility.CubicBezier(segmentPoints[0], segmentPoints[1], segmentPoints[2], segmentPoints[3], t + increment);

                    // angle at current point on path
                    float localAngle = 180 - MathUtility.MinAngle(prevPointOnPath, pointOnPath, nextPointOnPath);
                    // angle between the last added vertex, the current point on the path, and the next point on the path
                    float angleFromPrevVertex = 180 - MathUtility.MinAngle(lastAddedPoint, pointOnPath, nextPointOnPath);
                    float angleError          = Mathf.Max(localAngle, angleFromPrevVertex);


                    if (angleError > maxAngleError && dstSinceLastVertex >= minVertexDst)
                    {
                        dstSinceLastVertex       = 0;
                        dstSinceLastIntermediary = 0;
                        verticesWorld.Add(pointOnPath);
                        vertexToPathSegmentMap.Add(segmentIndex);
                        lastAddedPoint = pointOnPath;
                    }
                    else
                    {
                        if (dstSinceLastIntermediary > intermediaryThreshold)
                        {
                            verticesWorld.Add(pointOnPath);
                            vertexToPathSegmentMap.Add(segmentIndex);
                            dstSinceLastIntermediary = 0;
                        }
                        else
                        {
                            dstSinceLastIntermediary += (pointOnPath - prevPointOnPath).magnitude;
                        }

                        dstSinceLastVertex += (pointOnPath - prevPointOnPath).magnitude;
                    }
                    prevPointOnPath = pointOnPath;
                }
            }

            segmentStartIndices[BezierPath.NumSegments] = verticesWorld.Count;

            // ensure final point gets added (unless path is closed loop)
            verticesWorld.Add(!BezierPath.IsClosed ? BezierPath[BezierPath.NumPoints - 1] : BezierPath[0]);

            // Calculate length
            cumululativeLengthWorld = new float[verticesWorld.Count];
            for (int i = 0; i < verticesWorld.Count; i++)
            {
                verticesWorld[i] = MathUtility.TransformPoint(verticesWorld[i], transform, BezierPath.Space);
                if (i > 0)
                {
                    pathLengthWorld           += (verticesWorld[i - 1] - verticesWorld[i]).magnitude;
                    cumululativeLengthWorld[i] = pathLengthWorld;
                }
            }
        }