示例#1
0
    private List <OrientedPoint> GetPath()
    {
        var path = new List <OrientedPoint>();

        for (float t = 0; t < spline.nodes.Count - 1; t += 1 / 10.0f)
        {
            var point    = spline.GetLocationAlongSpline(t);
            var rotation = CubicBezierCurve.GetRotationFromTangent(spline.GetTangentAlongSpline(t));
            path.Add(new OrientedPoint(point, rotation));
        }
        return(path);
    }
示例#2
0
        public void TestPathDeform()
        {
            IMesh geom  = new TextMesh("Hello World");
            var   curve = new CubicBezierCurve(new Vec3(0, 0, 1), new Vec3(2, 0, 0), new Vec3(9, 0, 0), new Vec3(11, 0, 1));

            geom = new Geometry.Modifiers.PathDeform(Vec3.I, curve, geom);

            MeshGroup group = new MeshGroup();

            group.Add(geom);
            SaveGeometry("pathdeform.modifier", group);
        }
示例#3
0
 /// <summary>
 /// Adds a node at the end of the spline.
 /// </summary>
 /// <param name="node"></param>
 public void AddNode(SplineNode node)
 {
     nodes.Add(node);
     if (nodes.Count != 1)
     {
         SplineNode       previousNode = nodes[nodes.IndexOf(node) - 1];
         CubicBezierCurve curve        = new CubicBezierCurve(previousNode, node);
         curve.Changed.AddListener(() => UpdateAfterCurveChanged());
         curves.Add(curve);
     }
     RaiseNodeCountChanged();
     UpdateAfterCurveChanged();
 }
示例#4
0
 /// <summary>
 /// Set the cubic Bézier curve to use to bend the source mesh, and begin to listen to curve control points for changes.
 /// </summary>
 /// <param name="curve"></param>
 /// <param name="update">If let to true, update the resulting mesh immediatly.</param>
 public void SetCurve(CubicBezierCurve curve, bool update = true)
 {
     if (this.curve != null)
     {
         this.curve.Changed.RemoveListener(() => Compute());
     }
     this.curve = curve;
     curve.Changed.AddListener(() => Compute());
     if (update)
     {
         Compute();
     }
 }
示例#5
0
        public static void Animate(double duration, nfloat delay, CubicBezierCurve curve, Action changes, Action completion = null)
        {
            var propertyAnimator = new UIViewPropertyAnimator(duration, curve.ToCubicTimingParameters());

            propertyAnimator.AddAnimations(changes, delay);

            if (completion != null)
            {
                propertyAnimator.AddCompletion(_ => completion());
            }

            propertyAnimator.StartAnimation();
        }
示例#6
0
    //Высчитывает приблизительную длину кубической кривой Безье
    public float ApproximateLineLength(CubicBezierCurve curve)
    {
        float   length = 0f;
        Vector3 point1 = curve.p0;
        Vector3 point2;

        for (float i = 0.05f; i < 1f; i += 0.05f)
        {
            point2  = CalculateBezierPoint(i, curve);
            length += Vector3.Distance(point1, point2);
            point1  = point2;
        }
        return(length);
    }
示例#7
0
    //Возвращает следующий сегмент кубической кривой Безье,
    //Зависящий от предыдущего
    public CubicBezierCurve NextDots(CubicBezierCurve oldSettings, Vector3 nextPosition, EnemyBoundaries boundaries)
    {
        CubicBezierCurve cubicCurve = new CubicBezierCurve();

        cubicCurve.p0 = oldSettings.p3;
        cubicCurve.p1 = oldSettings.p2;

        cubicCurve.p3 = nextPosition;
        cubicCurve.p2 = GenerationMath.RandomPositionInCylinder(
            cubicCurve.p3,
            Vector3.Distance(cubicCurve.p0, nextPosition),
            boundaries);
        return(cubicCurve);
    }
示例#8
0
    private void OnEnable()
    {
        curves.Clear();
        for (int i = 0; i < nodes.Count - 1; i++)
        {
            SplineNode n    = nodes[i];
            SplineNode next = nodes[i + 1];

            CubicBezierCurve curve = new CubicBezierCurve(n, next);
            curve.Changed.AddListener(() => UpdateAfterCurveChanged());
            curves.Add(curve);
        }
        RaiseNodeCountChanged();
        UpdateAfterCurveChanged();
    }
示例#9
0
        /// <summary>
        /// Initialize the default values.
        /// </summary>
        private void Awake()
        {
            if (m_ControlPoints == null || m_ControlPoints.Length <= 1)
            {
                return;
            }

            m_Curve = new CubicBezierCurve[(m_ControlPoints.Length / 3)];
            for (int i = 0; i < m_Curve.Length; ++i)
            {
                var startIndex = i * 3;
                m_Curve[i] = new CubicBezierCurve(transform.TransformPoint(m_ControlPoints[startIndex]), transform.TransformPoint(m_ControlPoints[startIndex + 1]),
                                                  transform.TransformPoint(m_ControlPoints[startIndex + 2]), transform.TransformPoint(m_ControlPoints[startIndex + 3]));
            }
        }
示例#10
0
		private void InitializeAnimator()
		{
			_animator = new Animator();
			CubicBezierCurve c = new CubicBezierCurve(new PointF(0, 0),
													  new PointF(0.5f, 0f),
													  new PointF(.5f, 1f),
													  new PointF(1, 1));
			_animator.PointFromDistanceFunction = c.GetPointOnCurve;

			_animator.Duration = 200; // 750;
			_animator.FrameRate = 30;
			_animator.SpeedFunction = Animator.SpeedFunctions.SinSpeed;
			_animator.Animate += OnAnimator_Animate;
			_animator.Finished += OnAnimator_Finished;
		}
示例#11
0
    //Возвращает четыре точки, нужные для построения кубической кривой Безье
    public CubicBezierCurve CreateCubicLineDots(Vector3 startPosition, Vector3 finishPosition, EnemyBoundaries boundaries)
    {
        CubicBezierCurve cubicCurve = new CubicBezierCurve();

        cubicCurve.p0 = startPosition;
        cubicCurve.p1 = GenerationMath.RandomPositionInCylinder(
            startPosition,
            Vector3.Distance(startPosition, finishPosition),
            boundaries);
        cubicCurve.p3 = finishPosition;
        cubicCurve.p2 = GenerationMath.RandomPositionInCylinder(
            finishPosition,
            Vector3.Distance(startPosition, finishPosition),
            boundaries);
        return(cubicCurve);
    }
示例#12
0
        private void InitializeAnimator()
        {
            _animator = new Animator();
            CubicBezierCurve c = new CubicBezierCurve(new PointF(0, 0),
                                                      new PointF(0.5f, 0f),
                                                      new PointF(.5f, 1f),
                                                      new PointF(1, 1));

            _animator.PointFromDistanceFunction = c.GetPointOnCurve;

            _animator.Duration      = 200;                // 750;
            _animator.FrameRate     = 30;
            _animator.SpeedFunction = Animator.SpeedFunctions.SinSpeed;
            _animator.Animate      += OnAnimator_Animate;
            _animator.Finished     += OnAnimator_Finished;
        }
示例#13
0
    // Similar to GetPoint but returns the tangent at the specified point on the path. The tangent is not normalized.
    // The longer the tangent the 'more influence' it has pulling the path in that direction.
    public Vector3 GetTangent(float t)
    {
        // Only closed paths accept t values out of range.
        if (type == Type.Closed)
        {
            while (t < 0.0f)
            {
                t += (float)numCurveSegments;
            }

            while (t > (float)numCurveSegments)
            {
                t -= (float)numCurveSegments;
            }
        }
        else
        {
            t = Mathf.Clamp(t, 0.0f, (float)numCurveSegments);
        }

        Assert.IsTrue((t >= 0) && (t <= (float)numCurveSegments));

        // Segment 0 is for t E [0, 1). The last segment is for t E [NumCurveSegments-1, NumCurveSegments].
        // The following 'if' statement deals with the final inclusive bracket on the last segment. The cast must truncate.
        int segment = (int)t;

        if (segment >= numCurveSegments)
        {
            segment = numCurveSegments - 1;
        }

        Vector3[] curveCVs = new Vector3[4];
        curveCVs[0] = controlVerts[3 * segment + 0];
        curveCVs[1] = controlVerts[3 * segment + 1];
        curveCVs[2] = controlVerts[3 * segment + 2];
        curveCVs[3] = controlVerts[3 * segment + 3];

        CubicBezierCurve bc = new CubicBezierCurve(curveCVs);

        return(bc.GetTangent(t - (float)segment));
    }
示例#14
0
    /// <summary>
    /// Insert the given node in the spline at index. Index must be greater than 0 and less than node count.
    /// </summary>
    /// <param name="index"></param>
    /// <param name="node"></param>
    public void InsertNode(int index, SplineNode node)
    {
        if (index == 0)
        {
            throw new Exception("Can't insert a node at index 0");
        }

        SplineNode previousNode = nodes[index - 1];
        SplineNode nextNode     = nodes[index];

        nodes.Insert(index, node);

        curves[index - 1].ConnectEnd(node);

        CubicBezierCurve curve = new CubicBezierCurve(node, nextNode);

        curve.Changed.AddListener(() => UpdateAfterCurveChanged());
        curves.Insert(index, curve);
        RaiseNodeCountChanged();
        UpdateAfterCurveChanged();
    }
示例#15
0
    // This function returns a single closest point. There may be more than one point on the path at the same distance.
    // Use ComputeApproxParamPerUnitLength to determine a good paramThreshold. eg. Say you want a 15cm threshold,
    // use: paramThreshold = ComputeApproxParamPerUnitLength() * 0.15f.
    public float ComputeClosestParam(Vector3 pos, float paramThreshold)
    {
        var minDistSq    = float.MaxValue;
        var closestParam = 0.0f;

        for (var startIndex = 0; startIndex < controlVerts.Length - 1; startIndex += 3)
        {
            var curve             = new CubicBezierCurve(controlVerts[startIndex + 0], controlVerts[startIndex + 1], controlVerts[startIndex + 2], controlVerts[startIndex + 3]);
            var curveClosestParam = curve.GetClosestParam(pos, paramThreshold);

            var curvePos = curve.GetPoint(curveClosestParam);
            var distSq   = (curvePos - pos).sqrMagnitude;
            if (distSq < minDistSq)
            {
                minDistSq = distSq;
                var startParam = ((float)startIndex) / 3.0f;
                closestParam = startParam + curveClosestParam;
            }
        }

        return(closestParam);
    }
        internal static void DoCurveField(Rect position, CubicBezierCurve curve, Color color, SerializedProperty property)
        {
            int   id      = GUIUtility.GetControlID(EditorGUIUtility.native, position);
            Event current = Event.current;

            position.width  = Mathf.Max(position.width, 2f);
            position.height = Mathf.Max(position.height, 2f);

            //TODO - update open curve editor window

            EventType typeForControl = current.GetTypeForControl(id);

            switch (typeForControl)
            {
            case EventType.KeyDown:

                break;

            case EventType.Repaint:
                Rect position1 = position;
                ++position1.y;
                --position1.height;
                SPEditorGUI.DrawCurveSwatch(position1, curve, color, Color.gray);
                //EditorStyles.colorPickerBox.Draw(position1, GUIContent.none, id, false);
                break;

            case EventType.mouseDown:
                if (position.Contains(current.mousePosition))
                {
                    //TODO - show CubicBezierCurveEditorWindow

                    current.Use();
                    GUIUtility.ExitGUI();
                }
                break;
            }
        }
示例#17
0
    /// <summary>
    /// Remove the given node from the spline. The given node must exist and the spline must have more than 2 nodes.
    /// </summary>
    /// <param name="node"></param>
    public void RemoveNode(SplineNode node)
    {
        int index = nodes.IndexOf(node);

        if (nodes.Count <= 2)
        {
            throw new Exception("Can't remove the node because a spline needs at least 2 nodes.");
        }

        CubicBezierCurve toRemove = index == nodes.Count - 1? curves[index - 1] : curves[index];

        if (index != 0 && index != nodes.Count - 1)
        {
            SplineNode nextNode = nodes[index + 1];
            curves[index - 1].ConnectEnd(nextNode);
        }

        nodes.RemoveAt(index);
        toRemove.Changed.RemoveListener(() => UpdateAfterCurveChanged());
        curves.Remove(toRemove);

        RaiseNodeCountChanged();
        UpdateAfterCurveChanged();
    }
示例#18
0
        private void Create()
        {
            RemoveThumbs();

            // Create Move (M) command if this is the first token
            if (!CurrentFigure.Tokens.Any())
            {
                CurrentFigure.Tokens.Add(
                    new Move(
                        Cache.MouseDownPoint.X - 50.0,
                        Cache.MouseDownPoint.Y + 50.0));
            }

            if (StartWithMove && !(CurrentFigure.Tokens.Last() is Move))
            {
                CurrentFigure.Tokens.Add(
                    new Move(
                        Cache.MouseDownPoint.X - 50.0,
                        Cache.MouseDownPoint.Y + 50.0));
            }

            // Token which will be created
            Token token = null;

            // Depending on command create corresponding token
            if (CreateCommand == VDCanvasCommand.CreateLine)
            {
                token = new Line(Cache.MouseDownPoint.X + 50.0, Cache.MouseDownPoint.Y - 50.0);
            }
            else if (CreateCommand == VDCanvasCommand.CreateCubicCurve)
            {
                token = new CubicBezierCurve(
                    Cache.MouseDownPoint.X - 50.0,
                    Cache.MouseDownPoint.Y,
                    Cache.MouseDownPoint.X + 50.0,
                    Cache.MouseDownPoint.Y,
                    Cache.MouseDownPoint.X + 50.0,
                    Cache.MouseDownPoint.Y - 50.0);
            }
            else if (CreateCommand == VDCanvasCommand.CreateQuadraticCurve)
            {
                token = new QuadraticBezierCurve(
                    Cache.MouseDownPoint.X,
                    Cache.MouseDownPoint.Y,
                    Cache.MouseDownPoint.X + 50.0,
                    Cache.MouseDownPoint.Y - 50.0);
            }
            else if (CreateCommand == VDCanvasCommand.CreateSmoothCubicCurve)
            {
                token = new SmoothCubicBezierCurve(
                    Cache.MouseDownPoint.X,
                    Cache.MouseDownPoint.Y,
                    Cache.MouseDownPoint.X + 50.0,
                    Cache.MouseDownPoint.Y - 50.0);
            }
            else if (CreateCommand == VDCanvasCommand.CreateSmoothQuadraticCurve)
            {
                token = new SmoothQuadraticBezierCurve(
                    Cache.MouseDownPoint.X,
                    Cache.MouseDownPoint.Y,
                    Cache.MouseDownPoint.X + 50.0,
                    Cache.MouseDownPoint.Y - 50.0);
            }
            else if (CreateCommand == VDCanvasCommand.CreateClose)
            {
                token = new Close();
            }

            // Add just created token to the figure
            CurrentFigure.Tokens.Add(token);

            // Depending on Shift key status continue to create elements
            if (Keyboard.GetKeyStates(Key.LeftShift) != KeyStates.Down)
            {
                Edit(token);
            }
            else
            {
                GoToCreateMode();
            }

            InvalidateMeasure();
        }
示例#19
0
 public static void Animate(double duration, CubicBezierCurve curve, Action changes, Action completion = null, CancellationToken?cancellationToken = null)
 => Animate(duration, 0.0f, curve, changes, completion, cancellationToken);
示例#20
0
 public static UICubicTimingParameters ToCubicTimingParameters(this CubicBezierCurve self)
 => new UICubicTimingParameters(
     new CGPoint(self.P0, self.P1),
     new CGPoint(self.P2, self.P3)
     );
示例#21
0
 public static CAMediaTimingFunction ToMediaTimingFunction(this CubicBezierCurve self)
 => new CAMediaTimingFunction(self.P0, self.P1, self.P2, self.P3);
 public Vector3 GetPoint(float t)
 {
     return(transform.TransformPoint(CubicBezierCurve.GetPoint(controlPoints[0], controlPoints[1], controlPoints[2], controlPoints[3], t)));
 }
示例#23
0
    private void Compute()
    {
        if (source == null)
        {
            return;
        }
        int nbVert = source.vertices.Length;
        // find the bounds along x
        float minX = float.MaxValue;
        float maxX = float.MinValue;

        foreach (Vertex vert in vertices)
        {
            Vector3 p = vert.v;
            if (sourceRotation != Quaternion.identity)
            {
                p = sourceRotation * p;
            }
            if (sourceTranslation != Vector3.zero)
            {
                p += sourceTranslation;
            }
            maxX = Math.Max(maxX, p.x);
            minX = Math.Min(minX, p.x);
        }
        float length = Math.Abs(maxX - minX);

        List <Vector3> deformedVerts   = new List <Vector3>(nbVert);
        List <Vector3> deformedNormals = new List <Vector3>(nbVert);

        // for each mesh vertex, we found its projection on the curve
        foreach (Vertex vert in vertices)
        {
            Vector3 p = vert.v;
            Vector3 n = vert.n;
            //  application of rotation
            if (sourceRotation != Quaternion.identity)
            {
                p = sourceRotation * p;
                n = sourceRotation * n;
            }
            if (sourceTranslation != Vector3.zero)
            {
                p += sourceTranslation;
            }
            float distanceRate = Math.Abs(p.x - minX) / length;

            Vector3    curvePoint   = curve.GetLocationAtDistance(curve.Length * distanceRate);
            Vector3    curveTangent = curve.GetTangentAtDistance(curve.Length * distanceRate);
            Quaternion q            = CubicBezierCurve.GetRotationFromTangent(curveTangent) * Quaternion.Euler(0, -90, 0);

            // application of scale
            float scaleAtDistance = startScale + (endScale - startScale) * distanceRate;
            p *= scaleAtDistance;

            // application of roll
            float rollAtDistance = startRoll + (endRoll - startRoll) * distanceRate;
            p = Quaternion.AngleAxis(rollAtDistance, Vector3.right) * p;
            n = Quaternion.AngleAxis(rollAtDistance, Vector3.right) * n;

            // reset X value of p
            p = new Vector3(0, p.y, p.z);

            deformedVerts.Add(q * p + curvePoint);
            deformedNormals.Add(q * n);
        }

        result.vertices  = deformedVerts.ToArray();
        result.normals   = deformedNormals.ToArray();
        result.uv        = source.uv;
        result.triangles = source.triangles;
        GetComponent <MeshFilter>().mesh = result;
    }
    void OnSceneGUI()
    {
        Event e = Event.current;

        if (e.type == EventType.MouseDown)
        {
            Undo.RegisterCompleteObjectUndo(se, "change extruded shape");
            // if control key pressed, we will have to create a new vertex if position is changed
            if (e.alt)
            {
                mustCreateNewNode = true;
            }
        }
        if (e.type == EventType.MouseUp)
        {
            mustCreateNewNode = false;
        }

        Vector3    splineStartTangent = se.spline.GetTangentAlongSpline(0);
        Vector3    splineStart        = se.spline.GetLocationAlongSpline(0);
        Quaternion q = CubicBezierCurve.GetRotationFromTangent(splineStartTangent);

        foreach (SplineExtrusion.Vertex v in se.ShapeVertices)
        {
            // we create point and normal relative to the spline start where the shape is drawn
            Vector3 point  = se.transform.TransformPoint(q * v.point + splineStart);
            Vector3 normal = se.transform.TransformPoint(q * (v.point + v.normal) + splineStart);

            if (v == selection)
            {
                // draw the handles for selected vertex position and normal
                float size = HandleUtility.GetHandleSize(point) * 0.3f;
                float snap = 0.1f;

                // create a handle for the vertex position
                Vector3 movedPoint = Handles.Slider2D(0, point, splineStartTangent, Vector3.right, Vector3.up, size, Handles.CircleHandleCap, new Vector2(snap, snap));
                if (movedPoint != point)
                {
                    // position has been moved
                    Vector2 newVertexPoint = Quaternion.Inverse(q) * (se.transform.InverseTransformPoint(movedPoint) - splineStart);
                    if (mustCreateNewNode)
                    {
                        // We must create a new node
                        mustCreateNewNode = false;
                        SplineExtrusion.Vertex newVertex = new SplineExtrusion.Vertex(newVertexPoint, v.normal, v.uCoord);
                        int i = se.ShapeVertices.IndexOf(v);
                        if (i == se.ShapeVertices.Count - 1)
                        {
                            se.ShapeVertices.Add(newVertex);
                        }
                        else
                        {
                            se.ShapeVertices.Insert(i + 1, newVertex);
                        }
                        selection = newVertex;
                    }
                    else
                    {
                        v.point = newVertexPoint;
                        // normal must be updated if point has been moved
                        normal = se.transform.TransformPoint(q * (v.point + v.normal) + splineStart);
                    }
                    se.GenerateMesh();
                }
                else
                {
                    // vertex position handle hasn't been moved
                    // create a handle for normal
                    Vector3 movedNormal = Handles.Slider2D(normal, splineStartTangent, Vector3.right, Vector3.up, size, Handles.CircleHandleCap, snap);
                    if (movedNormal != normal)
                    {
                        // normal has been moved
                        v.normal = (Vector2)(Quaternion.Inverse(q) * (se.transform.InverseTransformPoint(movedNormal) - splineStart)) - v.point;
                        se.GenerateMesh();
                    }
                }

                Handles.BeginGUI();
                DrawQuad(HandleUtility.WorldToGUIPoint(point), CURVE_COLOR);
                DrawQuad(HandleUtility.WorldToGUIPoint(normal), Color.red);
                Handles.EndGUI();
            }
            else
            {
                // we draw a button to allow selection of the vertex
                Handles.BeginGUI();
                Vector2 p = HandleUtility.WorldToGUIPoint(point);
                if (GUI.Button(new Rect(p - new Vector2(QUAD_SIZE / 2, QUAD_SIZE / 2), new Vector2(QUAD_SIZE, QUAD_SIZE)), GUIContent.none))
                {
                    selection = v;
                }
                Handles.EndGUI();
            }

            // draw an arrow from the vertex location to the normal
            Handles.color = Color.red;
            Handles.DrawLine(point, normal);

            // draw a line between that vertex and the next one
            int index     = se.ShapeVertices.IndexOf(v);
            int nextIndex = index == se.ShapeVertices.Count - 1 ? 0 : index + 1;
            SplineExtrusion.Vertex next = se.ShapeVertices[nextIndex];
            Handles.color = CURVE_COLOR;
            Vector3 vAtSplineEnd = se.transform.TransformPoint(q * next.point + splineStart);
            Handles.DrawLine(point, vAtSplineEnd);
        }
    }
示例#25
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginProperty(position, label, property);

            FieldInfo controllerFieldInfo = fieldInfo.DeclaringType.GetField(fieldInfo.Name + "Controller", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

            bool                       bIsDirty      = false;
            int                        indentLevel   = EditorGUI.indentLevel;
            CubicBezierCurve           obj           = (CubicBezierCurve)fieldInfo.GetValue(property.serializedObject.targetObject);
            CubicBezierCurveController objController = null;

            if (controllerFieldInfo != null)
            {
                objController   = (CubicBezierCurveController)controllerFieldInfo.GetValue(property.serializedObject.targetObject);
                objController.c = obj;
            }

            Rect contentPosition = EditorGUI.PrefixLabel(position, label);

            contentPosition.width      *= .25f;
            EditorGUIUtility.labelWidth = 40f;
            EditorGUI.BeginChangeCheck();
            bool newLoop = EditorGUI.Toggle(contentPosition, "Loop:", obj.loop);

            if (EditorGUI.EndChangeCheck())
            {
                bIsDirty = true;
                Undo.RecordObject(property.serializedObject.targetObject, "Curve Loop Flag Changed");

                obj.loop = newLoop;
            }
            contentPosition.x          += contentPosition.width;
            EditorGUIUtility.labelWidth = 14f;
            EditorGUI.SelectableLabel(contentPosition, "l: " + obj.numberOfNodes.ToString());
            contentPosition.y += contentPosition.height;
            EditorGUILayout.BeginVertical();
            pointsFoldoutState = EditorGUILayout.Foldout(pointsFoldoutState, "Curve Points:");
            if (pointsFoldoutState)
            {
                EditorGUI.indentLevel++;

                int buttonPanelWidth = 40 + (objController != null ? 40 : 0);

                for (int i = 0; i < obj.p.Length; i++)
                {
                    Rect dataRect  = GUILayoutUtility.GetRect(0, float.MaxValue, EditorGUIUtility.singleLineHeight, EditorGUIUtility.singleLineHeight);
                    Rect leftRect  = dataRect;
                    Rect rightRect = dataRect;

                    leftRect.xMax  = leftRect.xMin + 48f;
                    dataRect.xMin += 48f;
                    dataRect.xMax -= buttonPanelWidth;
                    rightRect.xMin = rightRect.xMax - buttonPanelWidth;

                    if (i % (obj.chunkSize - 1) == 0)
                    {
                        GUIStyle s = EditorStyles.label;
                        EditorGUI.LabelField(leftRect, "Node");
                    }

                    vec3 p = MathExGUI.vec3Field(dataRect, null, obj.p[i], false);
                    if (obj.p[i] != p)
                    {
                        if (!bIsDirty)
                        {
                            Undo.RecordObject(property.serializedObject.targetObject, "Curve Point Modified");
                        }

                        obj.p[i] = p;
                        bIsDirty = true;
                    }

                    Rect addRect    = rightRect;
                    Rect removeRect = rightRect;
                    addRect.xMax    = addRect.xMax - 20;
                    addRect.xMin    = addRect.xMax - 20;
                    removeRect.xMin = removeRect.xMax - 20;

                    if (i % (obj.chunkSize - 1) == 0)
                    {
                        if (objController != null)
                        {
                            Rect modeRect = rightRect;
                            modeRect.xMax  = modeRect.xMin + 40;
                            modeRect.xMin -= 10;

                            int currentMode = (int)objController.modes[i / (obj.chunkSize - 1)];
                            int newMode     = EditorGUI.Popup(modeRect, currentMode, modeOptions);
                            if (newMode != currentMode)
                            {
                                bIsDirty = true;
                                Undo.RecordObject(property.serializedObject.targetObject, "Curve Point Mode Changed");

                                objController.modes[i / (obj.chunkSize - 1)] = (CubicBezierCurveController.CurveMode)newMode;
                            }
                        }

                        if (GUI.Button(addRect, "+"))
                        {
                            bIsDirty = true;
                            Undo.RecordObject(property.serializedObject.targetObject, "Curve Point Added");

                            int   nni   = obj.getIndexNode(i);
                            float nnit  = obj.getNodeTime(nni);
                            vec3  nni0v = obj.velocity(nnit);
                            int   ni    = nni - 1;
                            float nit   = ni < 0 ? 0 : obj.getNodeTime(ni);
                            vec3  ni1v  = obj.velocity(nit);

                            float init = (nit + nnit) / 2f;
                            float dt   = (nnit - nit) / 2f;
                            vec3  inv  = obj.value(init);
                            vec3  in0v = inv - obj.velocity(init) * dt;
                            vec3  in1v = inv + obj.velocity(init) * dt;

                            obj.p[obj.getNodeIndex(ni) + 1]  = obj.value(nit) + ni1v * dt;
                            obj.p[obj.getNodeIndex(nni) - 1] = obj.value(nnit) - nni0v * dt;
                            if (objController != null)
                            {
                                objController.insert(nni, in0v, inv, in1v);
                            }
                            else
                            {
                                obj.insert(nni, in0v, inv, in1v);
                            }
                        }
                        if (GUI.Button(removeRect, "-"))
                        {
                            bIsDirty = true;
                            Undo.RecordObject(property.serializedObject.targetObject, "Curve Point Removed");

                            if (objController != null)
                            {
                                objController.remove(i / (obj.chunkSize - 1));
                            }
                            else
                            {
                                obj.remove(i / (obj.chunkSize - 1));
                            }
                        }
                    }
                }

                EditorGUI.indentLevel--;
            }
            EditorGUILayout.EndVertical();

            EditorGUI.indentLevel = indentLevel;
            if (bIsDirty)
            {
                fieldInfo.SetValue(property.serializedObject.targetObject, obj);
                property.serializedObject.ApplyModifiedProperties();
            }

            EditorGUI.EndProperty();
        }
示例#26
0
 protected void calculateMovementParameters(CubicBezierCurve curve)
 {
     uniformMotion.Distance = bezierLines.ApproximateLineLength(curve);
     uniformMotion.Speed    = thisEnemy.Speed;
     uniformMotion.GetTime();
 }
示例#27
0
    /// <summary>
    /// Smesh goes brrr
    /// </summary>
    /// <param name="uv"></param>
    private void GenerateMesh(Vector2 uv)
    {
        // On vide nos listes
        Mesh.Clear();
        vertices.Clear();
        triangles.Clear();
        normals.Clear();
        uv0.Clear();
        uv1.Clear();

        CubicBezierCurve bezier = GetBezierRepresentation(Space.Self);

        float curveArcLegth = bezier.GetArcLength();
        float tiling        = GetTextureAspectRatio();
        int   edgeCount     = Mathf.Max(2, Mathf.RoundToInt(curveArcLegth * RoadChain.trianglesPerSegment)); // 2 triangles minimum sinon kaboom

        // Generation vertices normales & map texture
        for (int i = 0; i < edgeCount; ++i)
        {
            float         t  = i / (edgeCount - 1f);
            OrientedPoint op = bezier.GetOrientedPoint(t);

            float uv0V = t * tiling;
            float uv1U = Mathf.Lerp(uv.x, uv.y, t);

            for (int j = 0; j < RoadChain.mesh2D.VertexCount; ++j)
            {
                vertices.Add(op.LocalToWorldPos(RoadChain.mesh2D.vertices[j].point));
                normals.Add(op.LocalToWorldVec(RoadChain.mesh2D.vertices[j].normal));
                uv0.Add(new Vector2(RoadChain.mesh2D.vertices[j].u, uv0V));
                uv1.Add(new Vector2(uv1U, 0));
            }
        }

        // Generation des triangles
        for (int i = 0; i < edgeCount - 1; ++i)
        {
            int ifv   = i * RoadChain.mesh2D.VertexCount;
            int ipofv = (i + 1) * RoadChain.mesh2D.VertexCount;

            for (int j = 0; j < RoadChain.mesh2D.LineCount; j += 2)
            {
                int t   = RoadChain.mesh2D.triangles[j];
                int tpo = RoadChain.mesh2D.triangles[j + 1];
                triangles.Add(ifv + t);
                triangles.Add(ipofv + t);
                triangles.Add(ipofv + tpo);
                triangles.Add(ifv + t);
                triangles.Add(ipofv + tpo);
                triangles.Add(ifv + tpo);
            }
        }

        Mesh.SetVertices(vertices);
        Mesh.SetTriangles(triangles, 0);
        Mesh.SetNormals(normals);
        Mesh.SetUVs(0, uv0);
        Mesh.SetUVs(1, uv1);

        Mesh.RecalculateBounds();
        MeshCollider collider = GetComponent <MeshCollider>();

        collider.sharedMesh = Mesh;
    }
示例#28
0
            /// <summary>
            ///     Changes the type of the selected line.
            /// </summary>
            /// <param name="value">The value.</param>
            private void ChangeLineType(object value)
            {
                Type type = value as Type;

                if (type == null)
                {
                    throw new ArgumentException();
                }

                SelectedLine selectedLine = _selectedLine;

                if (selectedLine == null)
                {
                    return;
                }

                ILine currLine     = selectedLine.Line;
                Type  currLineType = currLine.GetType();

                if (type == currLineType)
                {
                    return;
                }

                ILine newLine;

                if (type == typeof(Line))
                {
                    newLine = new Line(currLine.Start, currLine.End);
                }
                else if (type == typeof(QuadraticBezierCurve))
                {
                    if (currLineType == typeof(Line))
                    {
                        newLine = new QuadraticBezierCurve(
                            currLine.Start,
                            new LineVector((currLine.Start.Vector + currLine.End.Vector) / 2),
                            currLine.End);
                    }
                    else if (currLineType == typeof(CubicBezierCurve))
                    {
                        CubicBezierCurve cubic = (CubicBezierCurve)currLine;

                        Vector2 vec = currLine.Start.Vector + (currLine.End.Vector - currLine.Start.Vector) / 2;
                        newLine = new QuadraticBezierCurve(
                            cubic.Start,
                            new LineVector(vec),
                            cubic.End);
                    }
                    else
                    {
                        throw new NotSupportedException(
                                  $"Cannot change a line of type '{currLineType.FullName}' to a line of type '{type.FullName}'.");
                    }
                }
                else if (type == typeof(CubicBezierCurve))
                {
                    if (currLineType == typeof(Line))
                    {
                        Vector2 vec = (currLine.End.Vector - currLine.Start.Vector) / 3;
                        newLine = new CubicBezierCurve(
                            currLine.Start,
                            new LineVector(currLine.Start.Vector + vec),
                            new LineVector(currLine.Start.Vector + vec + vec),
                            currLine.End);
                    }
                    else if (currLineType == typeof(QuadraticBezierCurve))
                    {
                        QuadraticBezierCurve quad = (QuadraticBezierCurve)currLine;

                        Vector2 start   = quad.Start.Vector;
                        Vector2 end     = quad.End.Vector;
                        Vector2 control = quad.ControlPoint.Vector;

                        newLine = new CubicBezierCurve(
                            quad.Start,
                            new LineVector(start + (2f / 3f * (control - start))),
                            new LineVector(end + (2f / 3f * (control - end))),
                            quad.End);
                    }
                    else
                    {
                        throw new NotSupportedException(
                                  $"Cannot change a line of type '{currLineType.FullName}' to a line of type '{type.FullName}'.");
                    }
                }
                else
                {
                    throw new NotSupportedException(
                              $"Cannot change a line of type '{currLineType.FullName}' to a line of type '{type.FullName}'.");
                }

                Debug.Assert(newLine.GetType() == type, "newLine.GetType() == type");

                selectedLine.EdgePart.Lines.Replace(currLine, newLine);

                _selectedLine = new SelectedLine(
                    selectedLine.Tile,
                    selectedLine.EdgePart,
                    newLine,
                    selectedLine.LineTransform);
            }
示例#29
0
 /// <summary>
 /// Get local point from center curve of pipe at time.
 /// </summary>
 /// <param name="time">Time of pipe center curve.</param>
 /// <returns>Local point on pipe curve at time.</returns>
 protected override Vector3 GetLocalPoint(float time)
 {
     return(CubicBezierCurve.GetPoint(anchor, time));
 }
示例#30
0
            /// <summary>
            ///     Changes the type of the selected line.
            /// </summary>
            /// <param name="value">The value.</param>
            private void ChangeLineType(object value)
            {
                Type type = value as Type;
                if (type == null) throw new ArgumentException();

                SelectedLine selectedLine = _selectedLine;
                if (selectedLine == null) return;

                ILine currLine = selectedLine.Line;
                Type currLineType = currLine.GetType();
                if (type == currLineType) return;

                ILine newLine;

                if (type == typeof(Line))
                    newLine = new Line(currLine.Start, currLine.End);
                else if (type == typeof(QuadraticBezierCurve))
                {
                    if (currLineType == typeof(Line))
                    {
                        newLine = new QuadraticBezierCurve(
                            currLine.Start,
                            new LineVector((currLine.Start.Vector + currLine.End.Vector) / 2),
                            currLine.End);
                    }
                    else if (currLineType == typeof(CubicBezierCurve))
                    {
                        CubicBezierCurve cubic = (CubicBezierCurve) currLine;

                        Vector2 vec = currLine.Start.Vector + (currLine.End.Vector - currLine.Start.Vector) / 2;
                        newLine = new QuadraticBezierCurve(
                            cubic.Start,
                            new LineVector(vec),
                            cubic.End);
                    }
                    else
                    {
                        throw new NotSupportedException(
                            $"Cannot change a line of type '{currLineType.FullName}' to a line of type '{type.FullName}'.");
                    }
                }
                else if (type == typeof(CubicBezierCurve))
                {
                    if (currLineType == typeof(Line))
                    {
                        Vector2 vec = (currLine.End.Vector - currLine.Start.Vector) / 3;
                        newLine = new CubicBezierCurve(
                            currLine.Start,
                            new LineVector(currLine.Start.Vector + vec),
                            new LineVector(currLine.Start.Vector + vec + vec),
                            currLine.End);
                    }
                    else if (currLineType == typeof(QuadraticBezierCurve))
                    {
                        QuadraticBezierCurve quad = (QuadraticBezierCurve) currLine;

                        Vector2 start = quad.Start.Vector;
                        Vector2 end = quad.End.Vector;
                        Vector2 control = quad.ControlPoint.Vector;

                        newLine = new CubicBezierCurve(
                            quad.Start,
                            new LineVector(start + (2f / 3f * (control - start))),
                            new LineVector(end + (2f / 3f * (control - end))),
                            quad.End);
                    }
                    else
                    {
                        throw new NotSupportedException(
                            $"Cannot change a line of type '{currLineType.FullName}' to a line of type '{type.FullName}'.");
                    }
                }
                else
                {
                    throw new NotSupportedException(
                        $"Cannot change a line of type '{currLineType.FullName}' to a line of type '{type.FullName}'.");
                }

                Debug.Assert(newLine.GetType() == type, "newLine.GetType() == type");

                selectedLine.EdgePart.Lines.Replace(currLine, newLine);

                _selectedLine = new SelectedLine(
                    selectedLine.Tile,
                    selectedLine.EdgePart,
                    newLine,
                    selectedLine.LineTransform);
            }
 public Vector3 GetCurveVelocity(float t)
 {
     return(transform.TransformPoint(CubicBezierCurve.GetCurveRateOfChange(controlPoints[0], controlPoints[1], controlPoints[2], controlPoints[3], t)) - transform.position);
 }
示例#32
0
 /// <summary>
 /// Get point on path curve at time.
 /// </summary>
 /// <param name="time">Time of curve.</param>
 /// <returns>The point on path curve at time.</returns>
 public override Vector3 GetPoint(float time)
 {
     return(transform.TransformPoint(CubicBezierCurve.GetPoint(anchor, time)));
 }