public static void CalculateMatch(TrackNode trackNode,Vector3 position)
        {
            var nextSegment = trackNode.trackSegmentModify.GetNextSegment (true);
            var previousSegment = trackNode.trackSegmentModify.GetPreviousSegment (true);

            switch (trackNode.nodePoint) {
            case TrackNode.NodeType.PO:
                break;
            case TrackNode.NodeType.P1:
                trackNode.SetPoint (position);

                if (previousSegment != null) {

                    float magnitude = Mathf.Abs((previousSegment.GetLastCurve.P2.GetGlobal () - previousSegment.GetLastCurve.P3.GetGlobal ()).magnitude);
                    previousSegment.GetLastCurve.P2.SetPoint (previousSegment.GetLastCurve.P3.GetGlobal() + (trackNode.trackSegmentModify.TrackSegment.getTangentPoint(0f) *-1f* magnitude));
                    previousSegment.invalidate = true;

                    trackNode.CalculateLenghtAndNormals ();
                    trackNode.trackSegmentModify.CalculateStartBinormal (true);
                }


                break;
            case TrackNode.NodeType.P2:

                trackNode.SetPoint (position);

                if (nextSegment != null) {
                    float magnitude = Mathf.Abs((nextSegment.GetFirstCurve.P0.GetGlobal () - nextSegment.GetFirstCurve.P1.GetGlobal ()).magnitude);
                    nextSegment.GetFirstCurve.P1.SetPoint (nextSegment.GetFirstCurve.P0.GetGlobal () + (trackNode.trackSegmentModify.TrackSegment.getTangentPoint(1f) * magnitude));
                    nextSegment.invalidate = true;

                    trackNode.CalculateLenghtAndNormals ();
                    nextSegment.CalculateStartBinormal (true);

                }


                break;
            case TrackNode.NodeType.P3:

                if (trackNode.trackCurve.Group == TrackNodeCurve.Grouping.End || trackNode.trackCurve.Group == TrackNodeCurve.Grouping.Both ) {

                    var P2Offset = trackNode.trackCurve.P2.GetGlobal () - trackNode.GetGlobal ();
                    trackNode.trackCurve.P2.SetPoint(position+ P2Offset);

                    if (nextSegment != null) {

                        var nextP1Offset = nextSegment.GetFirstCurve.P1.GetGlobal() -trackNode.GetGlobal();

                        nextSegment.GetFirstCurve.P0.SetPoint (position);
                        nextSegment.GetFirstCurve.P1.SetPoint (position+ nextP1Offset);

                        nextSegment.invalidate = true;
                    }

                }
                trackNode.SetPoint (position);

                break;
            }

            trackNode.CalculateLenghtAndNormals ();
            trackNode.trackSegmentModify.invalidate = true;
        }
 void Start()
 {
     AttachedNode = this.transform.parent.parent.GetComponent<TrackNode> ();
     this.transform.parent.gameObject.SetActive (false);
 }
		private TrackNode AddTrackCurveNode(Vector3 position, TrackNode.NodeType type)
		{
			
            GameObject nodeGameObject = UnityEngine.Object.Instantiate( Main.AssetBundleManager.nodeGo);
			nodeGameObject.layer = LayerMasks.COASTER_TRACKS;
			nodeGameObject.transform.transform.position = position;
			nodeGameObject.name = "BezierNode";

            var trackNode = nodeGameObject.AddComponent< TrackNode>();

			if (type == TrackNode.NodeType.P3)
				trackNode.activeState = TrackNode.Activestate.AlwaysActive;
			if (type == TrackNode.NodeType.PO)
				trackNode.activeState = TrackNode.Activestate.NeverActive;

            if (type == TrackNode.NodeType.P3) {
                GameObject nodeRotate = UnityEngine.Object.Instantiate (Main.AssetBundleManager.nodeRotateGo);
                nodeRotate.name = "MainRotate";
                nodeRotate.transform.SetParent (nodeGameObject.transform);
                nodeRotate.transform.position = nodeGameObject.transform.position;

                //add a roation ring
                GameObject mainRotate = nodeRotate.transform.Find ("Rotate").gameObject;
                mainRotate.layer = LayerMasks.ID_COASTER_TRACKS;
                trackNode.rotate =  mainRotate.AddComponent<RotationNode> ();

            }

			var previousSegment = SegmentModify.GetPreviousSegment (true);
			var nextSegment = SegmentModify.GetNextSegment (true);

			if (this.SegmentModify.TrackSegment is Station)
				trackNode.activeState = TrackNode.Activestate.NeverActive;
			else {

				if (nextSegment != null) {
					if (nextSegment.TrackSegment is Station && type == TrackNode.NodeType.P3)
						trackNode.activeState = TrackNode.Activestate.NeverActive;
					if (nextSegment.TrackSegment is Station && type == TrackNode.NodeType.P2)
						trackNode.activeState = TrackNode.Activestate.AlwaysActive;
				}
				if (previousSegment != null) {
					if (previousSegment.TrackSegment is Station && type == TrackNode.NodeType.P1) {
						trackNode.activeState = TrackNode.Activestate.AlwaysActive;
					}
				}
			}
           

			trackNode.SetActiveState (false);
			trackNode.trackSegmentModify = SegmentModify;
			trackNode.curve = cubicBezier;
			trackNode.nodePoint = type;
			trackNode.gameObject.layer = LayerMasks.ID_COASTER_TRACKS;
			trackNode.trackCurve = this;
			return trackNode;
		}